Skip to main content
net8.0

Package Description

Published
Jan 4, 2025
1y ago
Total Downloads
1.5K
1,523

Install

dotnet add package EdjCase.ICP.PocketIC --version 7.0.0-rc.1
ProductVersions
.NET
net8.0

README

PocketIC

Library containing the pocket-ic server runtime and clients for interfacing for canister testing on the internet computer

Supported PocketIC Server Runtimes

The pocket-ic server binary is only compatible with some operating systems:

  • linux-x64
  • osx-x64

Quick Start

Basic usage

// Start server
await using PocketIcServer server = await PocketIcServer.Start();
string pocketIcServerUrl = server.GetUrl();

// Create a new PocketIC instance with a default subnets
await using PocketIc pocketIc = await PocketIc.CreateAsync(pocketIcServerUrl);

// Create a new canister
CreateCanisterResponse response = await pocketIc.CreateCanisterAsync();
Principal canisterId = response.CanisterId;

// Install WASM module
byte[] wasmModule = File.ReadAllBytes("path/to/my_canister.wasm");
await pocketIc.InstallCodeAsync(
    canisterId: canisterId,
    wasmModule: wasmModule,
    arg: CandidArg.FromCandid(),
    mode: InstallCodeMode.Install
);

// Start the canister
await pocketIc.StartCanisterAsync(canisterId);

// Make calls to the canister
UnboundedUInt counter = await pocketIc.QueryCallAsync<UnboundedUInt>(
    Principal.Anonymous(),
    canisterId,
    "my_method"
);

HTTP Gateway usage


await using HttpGateway httpGateway = await pocketIc.RunHttpGatewayAsync()

// Create an HttpAgent to interact with canisters through the gateway
HttpAgent agent = httpGateway.BuildHttpAgent();

// Make calls using the agent
QueryResponse response = await agent.QueryAsync(canisterId, "my_method", CandidArg.Empty());
CandidArg reply = response.ThrowOrGetReply();

Subnet Configuration

PocketIC instances can be created with various subnet configurations:

await PocketIc.CreateAsync(
    pocketIcServerUrl,
    applicationSubnets: [SubnetConfig.New()],  // Application subnets
    nnsSubnet: SubnetConfig.New(),            // Network Nervous System subnet
    iiSubnet: SubnetConfig.New(),             // Internet Identity subnet
    bitcoinSubnet: SubnetConfig.New(),        // Bitcoin subnet
    snsSubnet: SubnetConfig.New(),            // Service Nervous System subnet
    systemSubnets: [SubnetConfig.New()]       // System subnets
);

Auto Time Progression

PocketIC provides control over the IC time for testing:


// Enable automatic time progression
await using (await pocketIc.AutoProgressTimeAsync())
{
    // Time will progress automatically
}
// Disposing will stop auto progress

XUnit usage

// Fixture to create and run server for all the tests, disposing only after all tests are complete
public class PocketIcServerFixture : IDisposable
{
	public PocketIcServer Server { get; private set; }

	public PocketIcServerFixture()
	{
		// Start the server for all tests
		this.Server = PocketIcServer.Start(showRuntimeLogs: true).GetAwaiter().GetResult();
	}

	public void Dispose()
	{
		// Stop the server after all tests
		if (this.Server != null)
		{
			this.Server.DisposeAsync().GetAwaiter().GetResult();
		}
	}
}

// Unit tests injecting the fixture
public class PocketIcTests : IClassFixture<PocketIcServerFixture>
{
	private readonly PocketIcServerFixture fixture;
	private string url => this.fixture.Server.GetUrl();

	public PocketIcTests(PocketIcServerFixture fixture)
	{
		this.fixture = fixture;
	}

	[Fact]
	public async Task Test()
	{
		// Create new pocketic instance for test, then dispose it on completion
		await using (PocketIc pocketIc = await PocketIc.CreateAsync(this.url));

		// run test here

	}
}

Call Types

Query Calls

// No arguments
TResponse result = await pocketIc.QueryCallAsync<TResponse>(
    sender,
    canisterId,
    "method"
);

// With arguments
TResponse result = await pocketIc.QueryCallAsync<T1, TResponse>(
    sender,
    canisterId,
    "method",
    arg1
);

// Raw candid
CandidArg response = await pocketIc.QueryCallRawAsync(
    sender,
    canisterId,
    "method",
    CandidArg.FromCandid()
);

Update Calls

// No arguments
TResponse result = await pocketIc.UpdateCallAsync<TResponse>(
    sender,
    canisterId,
    "method"
);

// With arguments
TResponse result = await pocketIc.UpdateCallAsync<T1, TResponse>(
    sender,
    canisterId,
    "method",
    arg1
);

// No response
await pocketIc.UpdateCallNoResponseAsync(
    sender,
    canisterId,
    "method"
);

// Raw candid
CandidArg response = await pocketIc.UpdateCallRawAsync(
    sender,
    canisterId,
    "method",
    CandidArg.FromCandid()
);

Adoption Assessment

Assess this package against its supported frameworks, license, maintenance signals and dependency graph before making it a project standard.

This version is marked prerelease. Validate its API and upgrade path before production use.No SPDX license expression is published. Review the license text and your organisation's policy before redistribution.Compatibility metadata lists 1 target framework; confirm the exact target used by your application.

Related Guides & Workflows

Learn how to evaluate, integrate, or audit this package in your .NET project.