PactLabs.Sdk.Kernel
0.1.0
dotnet add package PactLabs.Sdk.Kernel --version 0.1.0
NuGet\Install-Package PactLabs.Sdk.Kernel -Version 0.1.0
<PackageReference Include="PactLabs.Sdk.Kernel" Version="0.1.0" />
<PackageVersion Include="PactLabs.Sdk.Kernel" Version="0.1.0" />
<PackageReference Include="PactLabs.Sdk.Kernel" />
paket add PactLabs.Sdk.Kernel --version 0.1.0
#r "nuget: PactLabs.Sdk.Kernel, 0.1.0"
#:package PactLabs.Sdk.Kernel@0.1.0
#addin nuget:?package=PactLabs.Sdk.Kernel&version=0.1.0
#tool nuget:?package=PactLabs.Sdk.Kernel&version=0.1.0
PactLabs.Sdk
C# SDK for EVM blockchain interactions via Pact Labs' account abstraction infrastructure. Build server-side applications that send gasless transactions through ERC-4337 smart accounts powered by Kernel v3.3.
Architecture
┌──────────────────────────────────────────────────────┐
│ Your Application │
├──────────────────────────────────────────────────────┤
│ PactApiClient → IPactWalletClient → PactTransaction │ High-level SDK
├──────────────────────────────────────────────────────┤
│ UserOpPipeline → ABI Encoding → Signing │ UserOp lifecycle
├──────────────────────────────────────────────────────┤
│ Kernel v3.3 Encoding → PackedUserOperation │ ERC-4337 / ERC-7579
├──────────────────────────────────────────────────────┤
│ AA Service (JSON-RPC) → Bundler / Paymaster │ Pact Infrastructure
└──────────────────────────────────────────────────────┘
Four abstraction layers:
- High-level SDK (
PactApiClient,IPactWalletClient) — Pact API access plus Kernel account wallet clients for transfers, contract calls, and token operations with automatic gas management. - UserOp lifecycle (
UserOpPipeline) — orchestrates nonce tracking, paymaster sponsorship, gas estimation, and signing. - Kernel encoding (
KernelEncoder,PackedUserOperation) — ERC-4337 v0.7 UserOp construction with Kernel v3.3 execute/executeBatch encoding. - RPC transport (
AaServiceClient) — JSON-RPC communication with the Pact bundler, paymaster, and public RPC endpoints.
Installation
# Core SDK — transfers, contract calls, account abstraction
dotnet add package PactLabs.Sdk
# AWS KMS signer — sign with AWS Key Management Service keys
dotnet add package PactLabs.Sdk.Signing.Aws
# Kernel — foundational types (chains, token amounts) + Kernel encoding & UserOp building
dotnet add package PactLabs.Sdk.Kernel
# Code generator — generate typed C# contract wrappers from Solidity ABIs
dotnet tool install --global PactLabs.Sdk.CodeGen
Quick Start
Basic Transfer
using PactLabs.Sdk;
using PactLabs.Sdk.Signing;
using PactLabs.Sdk.Tokens;
using PactLabs.Sdk.Models;
// Create a signer (use AwsKmsSigner in production)
var signer = new PrivateKeySigner("0xYourPrivateKey");
// Initialize the platform API client
using var client = new PactApiClient("pk_live_your_api_key", new PactApiClientOptions
{
Chain = Chain.Base,
});
// Create a wallet with the default Kernel ECDSA sudo validator
var wallet = await client.CreateWalletAsync(signer, new PactWalletClientOptions
{
GasPolicy = GasPolicy.Sponsored,
});
Console.WriteLine($"Account: {wallet.Address}");
// Send a gasless ETH transfer
var tx = await wallet.TransferAsync("0xRecipient...", NativeAmount.Ether(0.1m));
var receipt = await tx.WaitForConfirmationAsync();
Console.WriteLine($"Confirmed in block {receipt.BlockNumber}");
Known Kernel Account
For rotated wallets, passkey-controlled wallets, or future session-key validators, keep the account identity separate from the signer:
var validator = new EcdsaSudoValidator("0xCurrentOwner...");
var account = KernelAccount.Deployed("0xKnownKernelAccount...", validator);
var wallet = await client.CreateWalletAsync(account, signer);
KernelAccount.Counterfactual(validator, saltIndex: 0) derives a deployable Kernel account from validator data. KernelAccount.Deployed(address, validator) uses the known address directly.
ERC-20 Token Transfer
// Look up a token
var usdc = await client.Tokens.GetBySlugAsync("usdc");
// Or create token info manually
var token = new TokenInfo("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", Chain.Ethereum, 6);
// Transfer tokens — the amount carries the token and its decimals
var amount = new TokenAmount(token, 100m);
var tx = await wallet.TransferTokenAsync(token, "0xRecipient...", amount);
Contract Call
// Write (sends a UserOp)
var tx = await wallet.ExecuteAsync(
"0xContractAddress",
"approve(address,uint256)",
"0xSpender...",
BigInteger.Parse("1000000"));
// Read (free eth_call)
var balance = await wallet.ReadAsync<BigInteger>(
"0xContractAddress",
"balanceOf(address) returns (uint256)",
wallet.Address);
Protocol Operations
using PactLabs.Sdk.Protocol;
using PactLabs.Sdk.Protocol.Models;
using PactLabs.Sdk.Tokens;
var protocol = wallet.Protocol();
// Address-bound handle for common read/write workflows
var loanBook = protocol.LoanBook("0xLoanBook...");
var tx = await loanBook.OriginateAsync(new LoanOriginationPayload
{
Originator = wallet.Address,
Beneficiary = "0xBorrower...",
Principal = new TokenAmount(usdc, 1000m),
StartDate = DateTimeOffset.UtcNow,
MaturityDate = DateTimeOffset.UtcNow.AddMonths(6),
ExternalId = new ExternalId("loan-001"),
PaymentSchedule = paymentSchedule,
PaymentOrder = LoanPaymentOrder.InterestPrincipalFee(),
});
// Stateless builders for batching or custom submission
var draw = FacilityCalls.ProposeDraw("0xFacility...", new TokenAmount(usdc, 250m));
await wallet.SubmitAsync(draw);
Protocol write APIs take TokenAmount values. The amount carries the token address and decimals, so protocol calls do not require a separate contract registration or context lookup step.
Dependency Injection
builder.Services.AddPact(opts =>
{
opts.ApiKey = "pk_live_your_api_key";
opts.Chain = Chain.Base;
});
builder.Services.AddPactSigner<MyCustomSigner>();
// Inject IPactApiClient for platform APIs and IPactWalletClientFactory for wallets.
public class MyService(IPactApiClient pact, IPactWalletClientFactory wallets)
{
public async Task DoWork()
{
var wallet = await wallets.CreateAsync(new PactWalletClientOptions
{
GasPolicy = GasPolicy.Sponsored,
});
// ...
}
}
// Optional: register a known deployed Kernel account for direct IPactWalletClient injection.
builder.Services.AddPactWallet(
_ => KernelAccount.Deployed(
"0xKnownKernelAccount...",
new EcdsaSudoValidator("0xCurrentOwner...")));
AWS KMS Signer
Use AWS Key Management Service for production signing with HSM-backed keys:
using Amazon.KeyManagementService;
using PactLabs.Sdk.Signing.Aws;
var kmsClient = new AmazonKeyManagementServiceClient();
var signer = new AwsKmsSigner(kmsClient, "alias/my-signing-key");
using var client = new PactApiClient("pk_live_your_api_key", new PactApiClientOptions
{
Chain = Chain.Base,
});
var wallet = await client.CreateWalletAsync(signer, new PactWalletClientOptions
{
GasPolicy = GasPolicy.Sponsored,
});
The KMS key must be an asymmetric signing key with ECC_SECG_P256K1 key spec.
KMS signer construction and DI helpers live in PactLabs.Sdk.Signing.Aws, not the core SDK:
builder.Services.AddPactAwsKmsSigner(opts =>
{
opts.KeyId = "alias/my-signing-key";
});
Code Generator
Generate typed C# contract wrappers from Solidity ABI JSON:
# From a Hardhat artifact
pact-codegen --input artifacts/MyContract.json --output MyContract.cs
# With custom namespace and class name
pact-codegen --input abi.json --output Generated/Erc20.cs --namespace MyApp.Contracts --class Erc20
The generated class extends TypedContractHandle and provides strongly-typed methods for each ABI function.
Configuration
PactApiClientOptions configures Pact platform API access:
| Property | Default | Description |
|---|---|---|
ApiKey |
(required) | Pact API key (pk_live_* or pk_test_*) |
Chain |
Chain.Ethereum |
Target EVM chain |
EnableTokenRegistry |
true |
Enable/disable token registry |
TimeoutMs |
30000 |
HTTP request timeout in milliseconds |
The Pact platform endpoint is fixed to https://api.pactlabs.xyz by default. For local or staging infrastructure, use the explicit testing override:
var options = new PactApiClientOptions
{
Chain = Chain.ArbitrumSepolia,
};
options.UsePlatformUrlOverrideForTesting("http://localhost:8080");
PactWalletClientOptions configures wallet behavior:
| Property | Default | Description |
|---|---|---|
GasPolicy |
GasPolicy.Sponsored |
Gas payment strategy |
Account |
null |
Optional KernelAccount used by DI wallet registration |
NonceLane |
KernelNonceLane.Default |
ECDSA nonce lane used only by the default CreateWalletAsync(signer) path |
Supported Chains
| Chain | Chain ID | Enum |
|---|---|---|
| Ethereum | 1 | Chain.Ethereum |
| Arbitrum One | 42161 | Chain.Arbitrum |
| Avalanche C-Chain | 43114 | Chain.Avalanche |
| Sepolia | 11155111 | Chain.Sepolia |
| Arbitrum Sepolia | 421614 | Chain.ArbitrumSepolia |
| Avalanche Fuji | 43113 | Chain.AvalancheFuji |
License
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- Nethereum.ABI (>= 5.8.0)
-
net9.0
- Nethereum.ABI (>= 5.8.0)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on PactLabs.Sdk.Kernel:
| Package | Downloads |
|---|---|
|
PactLabs.Sdk.Protocol
Protocol-level types and encoders for Pact Labs EVM SDK |
|
|
PactLabs.Sdk
C# SDK for EVM blockchain interactions via Pact Labs account abstraction infrastructure |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.0 | 180 | 5/26/2026 |