Skip to content

Latest commit

 

History

History
178 lines (144 loc) · 4.83 KB

README.md

File metadata and controls

178 lines (144 loc) · 4.83 KB

ICP.NET Agent

  • Library to communicate to and from the Internet Computer
  • PreGenerated ICRC1 Client
  • Nuget: EdjCase.ICP.Agent

Usage (Manual)

  • Dont define any types and use CandidValue and CandidType
  • Call functions using Candid objects
// Create http agent with anonymous identity
IAgent agent = new HttpAgent();

// Create Candid arg to send in request
ulong proposalId = 1234;
CandidArg arg = CandidArg.FromCandid(
	CandidTypedValue.Nat64(proposalId) // Candid type with no conversion
);

// Make request to IC
string method = "get_proposal_info";
Principal governanceCanisterId = Principal.FromText("rrkah-fqaaa-aaaaa-aaaaq-cai");
QueryResponse response = await agent.QueryAsync(governanceCanisterId, method, arg);

CandidArg reply = response.ThrowOrGetReply();
List<CandidTypedValue> values = reply.Values;

Usage (Self Defined Types)

  • Declare types of api models
  • Call functions and use custom object converters
// Create http agent with anonymous identity
IAgent agent = new HttpAgent();

// Create Candid arg to send in request
ulong proposalId = 1234;
CandidArg arg = CandidArg.FromCandid(
	CandidTypedValue.FromObject(proposalId) // Conversion can be C# or custom types
);

// Make request to IC
string method = "get_proposal_info";
Principal governanceCanisterId = Principal.FromText("rrkah-fqaaa-aaaaa-aaaaq-cai");
QueryResponse response = await agent.QueryAsync(governanceCanisterId, method, arg);

CandidArg reply = response.ThrowOrGetReply();
// Convert to custom class
OptionalValue<ProposalInfo> info = reply.ToObjects<OptionalValue<ProposalInfo>>(); // Conversion to custom or C# types

Usage (w/ Client Generator)

  • Run Client Generator on *.did file (see Client Generator below)
  • Use generated client and models to call function
// Create http agent with anonymous identity
IAgent agent = new HttpAgent();

Principal governanceCanisterId = Principal.FromText("rrkah-fqaaa-aaaaa-aaaaq-cai");
// Create new instance of client generated by `Client Generator` (this is using Governance.did for the NNS)
var client = new GovernanceApiClient(agent, governanceCanisterId);

// Make request
OptionalValue<ProposalInfo> info = await client.GetProposalInfoAsync(62143);

Using the ICRC1 PreGenerated Client

Instantiate an ICRC1Client by passing the HttpAgent instance and the canister ID of the ICRC1 canister as parameters:

IAgent agent = new HttpAgent(identity);
Principal canisterId = Principal.FromText("<canister_id>");
ICRC1Client client = new ICRC1Client(agent, canisterId);

Use the methods of the ICRC1Client to communicate with the ICRC1 canister:

// Get the name of the token
string name = await client.Name();

// Get the balance of a specific account
Account account = new Account
{
	Id = Principal.FromText("<account_id>")
};
UnboundedUInt balance = await client.BalanceOf(account);

// Transfer tokens from one account to another
TransferArgs transferArgs = new TransferArgs
{
	To = new Account
	{
		Id = Principal.FromText("<to_account_id>")
	},
	Amount = 1,
	Memo = "<memo>"
};
TransferResult transferResult = await client.Transfer(transferArgs);

Identities

Supported identity types:

  • Ed25519/EdDSA
  • Secp256k1/ECDSA
  • Delegated

From PEM file

IIdentity identity;
using (StreamReader pemFile = File.OpenText("C:\\identity.pem"))
{
	identity = IdentityUtil.FromPemFile(pemFile);
}
IAgent agent = new HttpAgent(identity);
...

From private key

Ed25519

byte[] privateKey = ...;
Ed25519Identity identity = IdentityUtil.FromEd25519PrivateKey(privateKey);

Secp256k1

byte[] privateKey = ...;
Secp256k1Identity identity = IdentityUtil.FromSecp256k1PrivateKey(privateKey);

Generate new keys

Ed25519

Ed25519Identity identity = IdentityUtil.GenerateEd25519Identity();

Secp256k1

Secp256k1Identity identity = IdentityUtil.GenerateSecp256k1Identity();

From public/private key pair

Ed25519

Ed25519Identity identity = new Ed25519Identity(publicKey, privateKey);

Secp256k1

Secp256k1Identity identity = new Secp256k1Identity(publicKey, privateKey);

Delegation

This is most commonly used with things like Internet Identity where another identity is delegated to sign requests by the inner identity.

byte[] publicKeyBytes = ...;
byte[] privateKey = ...;
DelegationChain chain = ...;
var innerIdentity = new Ed25519Identity(publicKeyBytes, privateKey);
var delegatedIdentity = new DelegationIdentity(innerIdentity, chain);

WebGL Builds

Due to how WebGL works by converting C# to JS/WASM using IL2CPP there are a few additional steps to avoid incompatibilities.

  • UnityHttpClient - The .NET HttpClient does not work in many cases, so UnityHttpClient is added via Unity C# script.
     var client = new UnityHttpClient();
     var agent = new HttpAgent(client);