- Library to communicate to and from the Internet Computer
- PreGenerated ICRC1 Client
- Nuget:
EdjCase.ICP.Agent
- 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;
- 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
- 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);
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);
Supported identity types:
- Ed25519/EdDSA
- Secp256k1/ECDSA
- Delegated
IIdentity identity;
using (StreamReader pemFile = File.OpenText("C:\\identity.pem"))
{
identity = IdentityUtil.FromPemFile(pemFile);
}
IAgent agent = new HttpAgent(identity);
...
byte[] privateKey = ...;
Ed25519Identity identity = IdentityUtil.FromEd25519PrivateKey(privateKey);
byte[] privateKey = ...;
Secp256k1Identity identity = IdentityUtil.FromSecp256k1PrivateKey(privateKey);
Ed25519Identity identity = IdentityUtil.GenerateEd25519Identity();
Secp256k1Identity identity = IdentityUtil.GenerateSecp256k1Identity();
Ed25519Identity identity = new Ed25519Identity(publicKey, privateKey);
Secp256k1Identity identity = new Secp256k1Identity(publicKey, privateKey);
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);
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, soUnityHttpClient
is added via Unity C# script.var client = new UnityHttpClient(); var agent = new HttpAgent(client);