Интеграция платежей Semantic Kernel.
Пакет Semantic Kernel не нужен. Оберните реальный клиент blockchain0x в KernelFunction (Python или Java) или вызовите REST API из KernelFunction на C#. В любом случае агент перемещает USDC на Base.
Нет пакета Semantic Kernel. В Python вы оборачиваете реальный blockchain0x клиент в метод, украшенный @kernel_function; в C#, где нет поставляемого .NET SDK, [KernelFunction] вызывает REST API напрямую. Зарегистрируйте его в вашем ядре, установите FunctionChoiceBehavior на Auto, и агент сможет перемещать USDC на Base. Поставляемые основные SDK - это Node, Python, Ruby, Go и JVM.
Единственный фреймворк агента .NET уровня предприятия.
Если ваш стек имеет форму Microsoft (Azure, .NET, SQL Server, Teams, Copilot Studio), Semantic Kernel почти наверняка является правильным фреймворком для агентов. Он разработан Microsoft, интегрируется с Azure OpenAI, AKS и Entra, и имеет первоклассную поддержку в .NET, Python и Java так, как ни один другой фреймворк не может. И он уже дает вам то, что вам нужно: KernelFunction - это просто метод, поэтому подключение платежей - это метод, который вы пишете, а не пакет, который вы ждете.
Вот почему нет адаптера Semantic Kernel для установки. В Python и Java вы оборачиваете реальный SDK blockchain0x в KernelFunction; в C#, где пока нет .NET SDK, KernelFunction напрямую вызывает REST API с помощью HttpClient. Вы сохраняете идиоматическую эргономику - декорированные методы, асинхронность, валидацию параметров на основе атрибутов - и нет версии адаптера для отслеживания. Основные SDK, которые существуют сегодня, это Node, Python, Ruby, Go и JVM.
Установите Semantic Kernel и, в Python, основной SDK.
Нет пакета blockchain0x Semantic Kernel для добавления. Python устанавливает Semantic Kernel плюс реальный SDK blockchain0x; C# устанавливает Microsoft.SemanticKernel и вызывает REST API с помощью встроенного HttpClient. Java использует Semantic Kernel для Java плюс SDK com.blockchain0x:sdk-jvm.
pip install semantic-kernel blockchain0xdotnet add package Microsoft.SemanticKernelBLOCKCHAIN0X_API_KEY=sk_test_... # sk_test_ = Base Sepolia, sk_live_ = Base mainnet BLOCKCHAIN0X_API_KEY=sk_test_... # same key, the name the .NET REST example reads OPENAI_API_KEY=sk-...
BLOCKCHAIN0X_API_KEY (его читает Python client) - это ключ sk_test_ для testnet или sk_live_ для mainnet из вашего dashboard; пример C# REST использует то же значение из BLOCKCHAIN0X_API_KEY. OPENAI_API_KEY (или AZURE_OPENAI_* для моделей, размещенных в Azure) - это ваш ключ LLM. Для обработчика webhook дополнительно нужен BLOCKCHAIN0X_WEBHOOK_SECRET.
Функция KernelFunction для кошелька, на Python и C#.
Python оборачивает реальный клиент blockchain0x в метод, декорированный @kernel_function. C#, где нет .NET SDK, предоставляет [KernelFunction], который напрямую вызывает POST /v1/payments с помощью HttpClient. Оба регистрируются на ядре как Wallet.send_usdc; только окружающая церемония отличается.
from semantic_kernel import Kernel from semantic_kernel.functions import kernel_function from blockchain0x import Client blockchain0x = Client() # reads BLOCKCHAIN0X_API_KEY from the environment class WalletPlugin: @kernel_function(description="Send a USDC payment from an agent wallet.") def send_usdc(self, agent_id: str, to: str, amount_wei: str) -> str: # amount_wei is USDC base units (6 decimals): "10000" = 0.01 USDC return str( blockchain0x.payments.create(body={"agentId": agent_id, "to": to, "amountWei": amount_wei}) ) kernel = Kernel() kernel.add_plugin(WalletPlugin(), plugin_name="Wallet") # Add your chat service, then let the model call Wallet.send_usdc.
using System.ComponentModel;
using System.Net.Http.Json;
using Microsoft.SemanticKernel;
// There is no .NET SDK, so a C# KernelFunction calls the REST API directly.
public class WalletPlugin
{
private static readonly HttpClient Http = new()
{
BaseAddress = new Uri("https://api.blockchain0x.com"),
};
[KernelFunction, Description("Send a USDC payment from an agent wallet. amountWei is USDC base units (6 decimals).")]
public async Task<string> SendUsdc(string agentId, string to, string amountWei)
{
Http.DefaultRequestHeaders.Authorization =
new("Bearer", Environment.GetEnvironmentVariable("BLOCKCHAIN0X_API_KEY"));
var res = await Http.PostAsJsonAsync("/v1/payments", new { agentId, to, amountWei });
return await res.Content.ReadAsStringAsync();
}
}
// builder.Plugins.AddFromType<WalletPlugin>("Wallet");Register the function on the kernel, set FunctionChoiceBehavior to Auto, and when the user's message implies a payment the model calls Wallet.send_usdc with the agent id, recipient, and amount. amountWei is base units, so 0.01 USDC is "10000". The Python path returns the SDK result; the C# path returns the REST response body.
Минимальный API ASP.NET Core для получения событий платежей.
Когда платеж завершается, Blockchain0x отправляет подписанное событие на ваш URL вебхука. Нет поставляемого проверщика .NET, поэтому обработчик проверяет вручную по документированному HMAC - что и делает помощник. Пример .NET ниже; Python и Java проверяют так же с помощью своих библиотек HMAC.
using System.Security.Cryptography;
using System.Text;
using Microsoft.AspNetCore.Builder;
var app = WebApplication.CreateBuilder(args).Build();
var secret = Environment.GetEnvironmentVariable("BLOCKCHAIN0X_WEBHOOK_SECRET")!;
app.MapPost("/webhooks/payment", async (HttpRequest req) =>
{
using var reader = new StreamReader(req.Body);
var raw = await reader.ReadToEndAsync(); // RAW body - verify before parsing
var sig = req.Headers["X-Blockchain0x-Signature"].ToString();
var ts = req.Headers["X-Blockchain0x-Timestamp"].ToString();
var parts = sig.Split(',').Select(p => p.Split('=', 2))
.Where(p => p.Length == 2).ToDictionary(p => p[0], p => p[1]);
var t = parts.GetValueOrDefault("t", ts);
var v1 = parts.GetValueOrDefault("v1", sig);
var want = Convert.ToHexString(new HMACSHA256(Encoding.UTF8.GetBytes(secret))
.ComputeHash(Encoding.UTF8.GetBytes($"{t}.{raw}"))).ToLowerInvariant();
var fresh = Math.Abs(DateTimeOffset.UtcNow.ToUnixTimeSeconds() - long.Parse(t)) <= 300;
if (!fresh || !CryptographicOperations.FixedTimeEquals(
Encoding.UTF8.GetBytes(want), Encoding.UTF8.GetBytes(v1)))
return Results.Unauthorized();
if (req.Headers["X-Blockchain0x-Event-Type"] == "payment.received")
await RunFollowupAsync(); // USDC landed - do the next step
return Results.Ok();
});
app.Run();Алгоритм - HMAC-SHA256 над строкой t.rawBody, окно повторного воспроизведения 300 секунд и сравнение с постоянным временем. Читайте необработанное тело через StreamReader, чтобы подпись осталась неизменной; не десериализуйте, а затем повторно сериализуйте. Отправленные события - payment.received, payment.sent, wallet.deployed и webhook.test. В производстве вебхук часто работает как отдельный сервис ASP.NET Core, совместно использующий базу данных с агентом, чтобы оба могли координировать действия.
SDK и REST интерфейс открыты. Читайте их.
Нет starter package для Semantic Kernel, который можно было бы клонировать - рецепты выше и есть интеграция. Основные SDK Blockchain0x (Node, Python, Ruby, Go) открыты в GitHub, а их набор методов плюс REST routes, которые вызывает пример на C#, описаны в docs.
docs.blockchain0x.com/docs/overviewНабор методов SDK и REST routes описаны в the docs. Начните с ключа sk_test_ в Base Sepolia, затем переключитесь на sk_live_, когда KernelFunction начнет работать так, как вы ожидаете.
Пять ловушек, специфичных для Semantic Kernel, которых следует избегать.
Модель плагинов Semantic Kernel чистая, но имеет подводные камни, связанные с кросс-языком и поведением по умолчанию. Знание их заранее экономит время.
Нет пакета Semantic Kernel ни на одном языке.
Нет адаптера NuGet, PyPI или Maven. Поставляемые основные SDK - это Node, Python, Ruby, Go и JVM - не .NET. Поэтому Python-ядро оборачивает клиент blockchain0x на Python в @kernel_function, Java-ядро использует SDK com.blockchain0x:sdk-jvm, а C#-ядро вызывает REST API напрямую из KernelFunction (показано выше). Все три - это несколько строк.
FunctionChoiceBehavior должен быть Auto
Semantic Kernel вызывает функции плагина только тогда, когда FunctionChoiceBehavior установлен на Auto в настройках выполнения подсказки. По умолчанию установлено значение None, поэтому модель никогда не вызывает вашу функцию кошелька, независимо от того, насколько четко пользователь запрашивает. Если агент полностью игнорирует функцию, проверьте это в первую очередь.
Суммы представлены в базовых единицах USDC, как строки
The payments call takes amountWei: a string of USDC base units (6 decimals), so 0.01 USDC is "10000" and 5 USDC is "5000000". Type the function argument as a string in any language. payments.create also does not retry by default and can answer 503 until the chain adapter is wired for your network - return a clear message rather than letting the agent loop.
Область применения плагина для агентов
Зарегистрируйте функцию кошелька только на ядре агента, который должен иметь полномочия на расходы. Плагин не является глобальным - агент, чье ядро не имеет его, не может его вызвать. Дайте агенту-ревьюеру ядро без функции кошелька или ограничьте разрешенные функции для каждого агента, чтобы деньги оставались с одной ролью.
Проверьте вебхуки по необработанному телу.
Читать необработанное тело запроса и проверять перед десериализацией - HMAC охватывает точные байты, поэтому круговой обмен парсинга и повторной сериализации нарушает его. Обработчик .NET ниже реализует задокументированный алгоритм: HMAC-SHA256 по t.rawBody, окно в 300 секунд и сравнение с постоянным временем. Python и Java проверяют аналогичным образом с помощью своих библиотек HMAC.