Skip to content

Commit

Permalink
Adding ICRC1 client (#30)
Browse files Browse the repository at this point in the history
* Adding ICRC1 client

* Fixing tests
  • Loading branch information
Gekctek committed Feb 11, 2023
1 parent 54a7cf7 commit 8511e5a
Show file tree
Hide file tree
Showing 9 changed files with 576 additions and 6 deletions.
131 changes: 131 additions & 0 deletions src/Agent/Standards/ICRC1/ICRC1Client.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
using EdjCase.ICP.Agent.Agents;
using EdjCase.ICP.Agent.Standards.ICRC1.Models;
using EdjCase.ICP.Candid.Mapping;
using EdjCase.ICP.Candid.Models;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace EdjCase.ICP.Agent.Standards.ICRC1
{
public class ICRC1Client
{
public IAgent Agent { get; }

public Principal CanisterId { get; }

public ICRC1Client(IAgent agent, Principal canisterId)
{
this.Agent = agent;
this.CanisterId = canisterId;
}

public async Task<List<MetaData>> MetaData()
{
CandidArg arg = CandidArg.FromCandid();
Responses.QueryResponse response = await this.Agent.QueryAsync(this.CanisterId, "icrc1_meta_data", arg);
CandidArg reply = response.ThrowOrGetReply();
return reply.ToObjects<List<MetaData>>();
}

public async Task<string> Name()
{
CandidArg arg = CandidArg.FromCandid();
Responses.QueryResponse response = await this.Agent.QueryAsync(this.CanisterId, "icrc1_name", arg);
CandidArg reply = response.ThrowOrGetReply();
return reply.ToObjects<string>();
}

public async Task<string> Symbol()
{
CandidArg arg = CandidArg.FromCandid();
Responses.QueryResponse response = await this.Agent.QueryAsync(this.CanisterId, "icrc1_symbol", arg);
CandidArg reply = response.ThrowOrGetReply();
return reply.ToObjects<string>();
}

public async Task<int> Decimals()
{
CandidArg arg = CandidArg.FromCandid();
Responses.QueryResponse response = await this.Agent.QueryAsync(this.CanisterId, "icrc1_decimals", arg);
CandidArg reply = response.ThrowOrGetReply();
return reply.ToObjects<byte>();
}

public async Task<UnboundedUInt> Fee()
{
CandidArg arg = CandidArg.FromCandid();
Responses.QueryResponse response = await this.Agent.QueryAsync(this.CanisterId, "icrc1_fee", arg);
CandidArg reply = response.ThrowOrGetReply();
return reply.ToObjects<UnboundedUInt>();
}

public async Task<UnboundedUInt> TotalSupply()
{
CandidArg arg = CandidArg.FromCandid();
Responses.QueryResponse response = await this.Agent.QueryAsync(this.CanisterId, "icrc1_total_supply", arg);
CandidArg reply = response.ThrowOrGetReply();
return reply.ToObjects<UnboundedUInt>();
}

public async Task<OptionalValue<Account>> MintingAccount()
{
CandidArg arg = CandidArg.FromCandid();
Responses.QueryResponse response = await this.Agent.QueryAsync(this.CanisterId, "icrc1_minting_account", arg);
CandidArg reply = response.ThrowOrGetReply();
return reply.ToObjects<OptionalValue<Account>>();
}

public async Task<UnboundedUInt> BalanceOf(Account arg0)
{
CandidArg arg = CandidArg.FromCandid(CandidTypedValue.FromObject(arg0));
Responses.QueryResponse response = await this.Agent.QueryAsync(this.CanisterId, "icrc1_balance_of", arg);
CandidArg reply = response.ThrowOrGetReply();
return reply.ToObjects<UnboundedUInt>();
}

public async Task<TransferResult> Transfer(TransferArgs arg0)
{
CandidArg arg = CandidArg.FromCandid(CandidTypedValue.FromObject(arg0));
CandidArg reply = await this.Agent.CallAndWaitAsync(this.CanisterId, "icrc1_transfer", arg);
return reply.ToObjects<TransferResult>();
}

public async Task<List<SupportedStandard>> SupportedStandards()
{
CandidArg arg = CandidArg.FromCandid();
Responses.QueryResponse response = await this.Agent.QueryAsync(this.CanisterId, "icrc1_supported_standards", arg);
CandidArg reply = response.ThrowOrGetReply();
return reply.ToObjects<List<SupportedStandard>>();
}
}

public class SupportedStandard
{
[CandidName("name")]
public string Name { get; }

[CandidName("url")]
public string Url { get; }
}

public class MetaData
{
[CandidName("0")]
public string Key { get; set; }

[CandidName("1")]
public MetaDataValue Value { get; set; }

public MetaData(string key, MetaDataValue value)
{
this.Key = key;
this.Value = value;
}
}

public class MetaDataValue
{

}

}
22 changes: 22 additions & 0 deletions src/Agent/Standards/ICRC1/Models/Account.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Timestamp = System.UInt64;
using Duration = System.UInt64;
using Subaccount = System.Collections.Generic.List<byte>;
using EdjCase.ICP.Agent.Agents;

namespace EdjCase.ICP.Agent.Standards.ICRC1.Models
{
public class Account
{
[Candid.Mapping.CandidName("owner")]
public Candid.Models.Principal Owner { get; set; }

[Candid.Mapping.CandidName("subaccount")]
public Candid.Models.OptionalValue<Subaccount> Subaccount { get; set; }

public Account(Candid.Models.Principal owner, Candid.Models.OptionalValue<Subaccount> subaccount)
{
this.Owner = owner;
this.Subaccount = subaccount;
}
}
}
97 changes: 97 additions & 0 deletions src/Agent/Standards/ICRC1/Models/MetaDataValue.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
using Timestamp = System.UInt64;
using Duration = System.UInt64;
using Subaccount = System.Collections.Generic.List<byte>;
using EdjCase.ICP.Agent.Agents;
using EdjCase.ICP.Candid.Mapping;
using EdjCase.ICP.Candid.Models;

namespace EdjCase.ICP.Agent.Standards.ICRC1.Models
{
[Variant(typeof(ValueTag))]
public class MetaDataValue
{
[VariantTagProperty]
public ValueTag Tag { get; set; }

[VariantValueProperty]
private object? Value { get; set; }

public MetaDataValue(ValueTag tag, object? value)
{
this.Tag = tag;
this.Value = value;
}

protected MetaDataValue()
{
}

public static MetaDataValue Nat(UnboundedUInt info)
{
return new MetaDataValue(ValueTag.Nat, info);
}

public static MetaDataValue Int(UnboundedInt info)
{
return new MetaDataValue(ValueTag.Int, info);
}

public static MetaDataValue Text(string info)
{
return new MetaDataValue(ValueTag.Text, info);
}

public static MetaDataValue Blob(Subaccount info)
{
return new MetaDataValue(ValueTag.Blob, info);
}

public UnboundedUInt AsNat()
{
this.ValidateTag(ValueTag.Nat);
return (UnboundedUInt)this.Value!;
}

public UnboundedInt AsInt()
{
this.ValidateTag(ValueTag.Int);
return (UnboundedInt)this.Value!;
}

public string AsText()
{
this.ValidateTag(ValueTag.Text);
return (string)this.Value!;
}

public Subaccount AsBlob()
{
this.ValidateTag(ValueTag.Blob);
return (Subaccount)this.Value!;
}

private void ValidateTag(ValueTag tag)
{
if (!this.Tag.Equals(tag))
{
throw new System.InvalidOperationException($"Cannot cast '{this.Tag}' to type '{tag}'");
}
}
}

public enum ValueTag
{
[CandidName("Nat")]
[VariantOptionType(typeof(UnboundedUInt))]
Nat,
[CandidName("Int")]
[VariantOptionType(typeof(UnboundedInt))]
Int,
[CandidName("Text")]
[VariantOptionType(typeof(string))]
Text,
[CandidName("Blob")]
[VariantOptionType(typeof(Subaccount))]
Blob
}
}
40 changes: 40 additions & 0 deletions src/Agent/Standards/ICRC1/Models/TransferArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using Timestamp = System.UInt64;
using Duration = System.UInt64;
using Subaccount = System.Collections.Generic.List<byte>;
using EdjCase.ICP.Agent.Agents;
using EdjCase.ICP.Candid.Models;
using EdjCase.ICP.Candid.Mapping;

namespace EdjCase.ICP.Agent.Standards.ICRC1.Models
{
public class TransferArgs
{
[CandidName("from_subaccount")]
public OptionalValue<Subaccount> FromSubaccount { get; set; }

[CandidName("to")]
public Account To { get; set; }

[CandidName("amount")]
public UnboundedUInt Amount { get; set; }

[CandidName("fee")]
public OptionalValue<UnboundedUInt> Fee { get; set; }

[CandidName("memo")]
public OptionalValue<Subaccount> Memo { get; set; }

[CandidName("created_at_time")]
public OptionalValue<Timestamp> CreatedAtTime { get; set; }

public TransferArgs(OptionalValue<Subaccount> fromSubaccount, Account to, UnboundedUInt amount, OptionalValue<UnboundedUInt> fee, OptionalValue<Subaccount> memo, OptionalValue<Timestamp> createdAtTime)
{
this.FromSubaccount = fromSubaccount;
this.To = to;
this.Amount = amount;
this.Fee = fee;
this.Memo = memo;
this.CreatedAtTime = createdAtTime;
}
}
}
Loading

0 comments on commit 8511e5a

Please sign in to comment.