Skip to content

Commit

Permalink
feat: init ICP index canister in ledger-icp and add account balance f…
Browse files Browse the repository at this point in the history
…unction (#459)

# Motivation

Add support for ICP index canister in `@dfinity/ledger-icp`.

# Notes

The ledger and the index canisters providing both a way to fetch the balance, the idea is to use the same function name and same parameters in both canister JS code.

# Changes

- add did file to import candid and generate idl scripts
- init `IndexCanister`
- implement `accountBalance` function for the new canister
- refactor type `AccountIdentifier` to `AccountIdentiferHex` to avoid conflicts
- refactor `Ledger.accountBalance` params to support account identifier as hex or class
  • Loading branch information
peterpeterparker authored Nov 6, 2023
1 parent 014e017 commit 01b692e
Show file tree
Hide file tree
Showing 21 changed files with 651 additions and 28 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

## Features

- expose few types - notably `BlockHeight` - for library `@dfinity/ledger-icp`
- add support for ICP Index canister to library `@dfinity/ledger-icp`. New `IndexCanister` functions: `accountBalance`.
- expose few types - notably `BlockHeight` - for library `@dfinity/ledger-icp`.
- support new fields from swap canister response types: `min_direct_participation_icp_e8s`, `max_direct_participation_icp_e8s` and `neurons_fund_participation`.
- support new fields in the `CreateServiceNervousSystem` proposal action `maximum_direct_participation_icp`, `minimum_direct_participation_icp` and `neurons_fund_participation`.
- support new filter field `omit_large_fields` in `list_proposals`.
Expand Down
57 changes: 48 additions & 9 deletions packages/ledger-icp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ const data = await metadata();

### :factory: LedgerCanister

[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ledger-icp/src/ledger.canister.ts#L32)
[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ledger-icp/src/ledger.canister.ts#L34)

#### Methods

Expand All @@ -186,7 +186,7 @@ const data = await metadata();
| -------- | ----------------------------------------------------- |
| `create` | `(options?: LedgerCanisterOptions) => LedgerCanister` |

[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ledger-icp/src/ledger.canister.ts#L43)
[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ledger-icp/src/ledger.canister.ts#L45)

##### :gear: accountBalance

Expand All @@ -195,11 +195,17 @@ Returns the balance of the specified account identifier.
If `certified` is true, the request is fetched as an update call, otherwise
it is fetched using a query call.

| Method | Type |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `accountBalance` | `({ accountIdentifier, certified, }: { accountIdentifier: AccountIdentifier; certified?: boolean; }) => Promise<bigint>` |
| Method | Type |
| ---------------- | ------------------------------------------------------------------------------------------------------ |
| `accountBalance` | `({ accountIdentifier: accountIdentifierParam, certified, }: AccountBalanceParams) => Promise<bigint>` |

[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ledger-icp/src/ledger.canister.ts#L75)
Parameters:

- `params`: The parameters to get the balance of an account.
- `params.accountIdentifier`: The account identifier provided either as hex string or as an AccountIdentifier.
- `params.certified`: query or update call.

[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ledger-icp/src/ledger.canister.ts#L81)

##### :gear: transactionFee

Expand All @@ -209,7 +215,7 @@ Returns the transaction fee of the ledger canister
| ---------------- | ----------------------- |
| `transactionFee` | `() => Promise<bigint>` |

[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ledger-icp/src/ledger.canister.ts#L99)
[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ledger-icp/src/ledger.canister.ts#L104)

##### :gear: transfer

Expand All @@ -220,7 +226,7 @@ Returns the index of the block containing the tx if it was successful.
| ---------- | ----------------------------------------------- |
| `transfer` | `(request: TransferRequest) => Promise<bigint>` |

[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ledger-icp/src/ledger.canister.ts#L112)
[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ledger-icp/src/ledger.canister.ts#L117)

##### :gear: icrc1Transfer

Expand All @@ -231,7 +237,40 @@ Returns the index of the block containing the tx if it was successful.
| --------------- | ---------------------------------------------------- |
| `icrc1Transfer` | `(request: Icrc1TransferRequest) => Promise<bigint>` |

[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ledger-icp/src/ledger.canister.ts#L142)
[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ledger-icp/src/ledger.canister.ts#L147)

### :factory: IndexCanister

[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ledger-icp/src/index.canister.ts#L9)

#### Methods

- [create](#gear-create)
- [accountBalance](#gear-accountbalance)

##### :gear: create

| Method | Type |
| -------- | --------------------------------------------------------------------------------------------- |
| `create` | `({ canisterId: optionsCanisterId, ...options }: CanisterOptions<_SERVICE>) => IndexCanister` |

[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ledger-icp/src/index.canister.ts#L10)

##### :gear: accountBalance

Returns the balance of the specified account identifier.

| Method | Type |
| ---------------- | ------------------------------------------------------------------------------ |
| `accountBalance` | `({ certified, accountIdentifier, }: AccountBalanceParams) => Promise<bigint>` |

Parameters:

- `params`: The parameters to get the balance of an account.
- `params.accountIdentifier`: The account identifier provided either as hex string or as an AccountIdentifier.
- `params.certified`: query or update call.

[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ledger-icp/src/index.canister.ts#L35)

<!-- TSDOC_END -->

Expand Down
2 changes: 2 additions & 0 deletions packages/ledger-icp/candid/index.certified.idl.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import type { IDL } from "@dfinity/candid";
export const idlFactory: IDL.InterfaceFactory;
108 changes: 108 additions & 0 deletions packages/ledger-icp/candid/index.certified.idl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/* Do not edit. Compiled with ./scripts/compile-idl-js from packages/ledger-icp/candid/index.did */
export const idlFactory = ({ IDL }) => {
const InitArg = IDL.Record({ 'ledger_id' : IDL.Principal });
const GetAccountIdentifierTransactionsArgs = IDL.Record({
'max_results' : IDL.Nat64,
'start' : IDL.Opt(IDL.Nat64),
'account_identifier' : IDL.Text,
});
const Tokens = IDL.Record({ 'e8s' : IDL.Nat64 });
const TimeStamp = IDL.Record({ 'timestamp_nanos' : IDL.Nat64 });
const Operation = IDL.Variant({
'Approve' : IDL.Record({
'fee' : Tokens,
'from' : IDL.Text,
'allowance' : Tokens,
'expires_at' : IDL.Opt(TimeStamp),
'spender' : IDL.Text,
}),
'Burn' : IDL.Record({ 'from' : IDL.Text, 'amount' : Tokens }),
'Mint' : IDL.Record({ 'to' : IDL.Text, 'amount' : Tokens }),
'Transfer' : IDL.Record({
'to' : IDL.Text,
'fee' : Tokens,
'from' : IDL.Text,
'amount' : Tokens,
}),
'TransferFrom' : IDL.Record({
'to' : IDL.Text,
'fee' : Tokens,
'from' : IDL.Text,
'amount' : Tokens,
'spender' : IDL.Text,
}),
});
const Transaction = IDL.Record({
'memo' : IDL.Nat64,
'icrc1_memo' : IDL.Opt(IDL.Vec(IDL.Nat8)),
'operation' : Operation,
'created_at_time' : IDL.Opt(TimeStamp),
});
const TransactionWithId = IDL.Record({
'id' : IDL.Nat64,
'transaction' : Transaction,
});
const GetAccountIdentifierTransactionsResponse = IDL.Record({
'balance' : IDL.Nat64,
'transactions' : IDL.Vec(TransactionWithId),
'oldest_tx_id' : IDL.Opt(IDL.Nat64),
});
const GetAccountIdentifierTransactionsError = IDL.Record({
'message' : IDL.Text,
});
const GetAccountIdentifierTransactionsResult = IDL.Variant({
'Ok' : GetAccountIdentifierTransactionsResponse,
'Err' : GetAccountIdentifierTransactionsError,
});
const Account = IDL.Record({
'owner' : IDL.Principal,
'subaccount' : IDL.Opt(IDL.Vec(IDL.Nat8)),
});
const GetAccountTransactionsArgs = IDL.Record({
'max_results' : IDL.Nat,
'start' : IDL.Opt(IDL.Nat),
'account' : Account,
});
const GetBlocksRequest = IDL.Record({
'start' : IDL.Nat,
'length' : IDL.Nat,
});
const GetBlocksResponse = IDL.Record({
'blocks' : IDL.Vec(IDL.Vec(IDL.Nat8)),
'chain_length' : IDL.Nat64,
});
const HttpRequest = IDL.Record({
'url' : IDL.Text,
'method' : IDL.Text,
'body' : IDL.Vec(IDL.Nat8),
'headers' : IDL.Vec(IDL.Tuple(IDL.Text, IDL.Text)),
});
const HttpResponse = IDL.Record({
'body' : IDL.Vec(IDL.Nat8),
'headers' : IDL.Vec(IDL.Tuple(IDL.Text, IDL.Text)),
'status_code' : IDL.Nat16,
});
const Status = IDL.Record({ 'num_blocks_synced' : IDL.Nat64 });
return IDL.Service({
'get_account_identifier_balance' : IDL.Func([IDL.Text], [IDL.Nat64], []),
'get_account_identifier_transactions' : IDL.Func(
[GetAccountIdentifierTransactionsArgs],
[GetAccountIdentifierTransactionsResult],
[],
),
'get_account_transactions' : IDL.Func(
[GetAccountTransactionsArgs],
[GetAccountIdentifierTransactionsResult],
[],
),
'get_blocks' : IDL.Func([GetBlocksRequest], [GetBlocksResponse], []),
'http_request' : IDL.Func([HttpRequest], [HttpResponse], []),
'icrc1_balance_of' : IDL.Func([Account], [IDL.Nat64], []),
'ledger_id' : IDL.Func([], [IDL.Principal], []),
'status' : IDL.Func([], [Status], []),
});
};
export const init = ({ IDL }) => {
const InitArg = IDL.Record({ 'ledger_id' : IDL.Principal });
return [InitArg];
};
116 changes: 116 additions & 0 deletions packages/ledger-icp/candid/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import type { ActorMethod } from "@dfinity/agent";
import type { Principal } from "@dfinity/principal";

export interface Account {
owner: Principal;
subaccount: [] | [Uint8Array];
}
export interface GetAccountIdentifierTransactionsArgs {
max_results: bigint;
start: [] | [bigint];
account_identifier: string;
}
export interface GetAccountIdentifierTransactionsError {
message: string;
}
export interface GetAccountIdentifierTransactionsResponse {
balance: bigint;
transactions: Array<TransactionWithId>;
oldest_tx_id: [] | [bigint];
}
export type GetAccountIdentifierTransactionsResult =
| {
Ok: GetAccountIdentifierTransactionsResponse;
}
| { Err: GetAccountIdentifierTransactionsError };
export interface GetAccountTransactionsArgs {
max_results: bigint;
start: [] | [bigint];
account: Account;
}
export interface GetBlocksRequest {
start: bigint;
length: bigint;
}
export interface GetBlocksResponse {
blocks: Array<Uint8Array>;
chain_length: bigint;
}
export interface HttpRequest {
url: string;
method: string;
body: Uint8Array;
headers: Array<[string, string]>;
}
export interface HttpResponse {
body: Uint8Array;
headers: Array<[string, string]>;
status_code: number;
}
export interface InitArg {
ledger_id: Principal;
}
export type Operation =
| {
Approve: {
fee: Tokens;
from: string;
allowance: Tokens;
expires_at: [] | [TimeStamp];
spender: string;
};
}
| { Burn: { from: string; amount: Tokens } }
| { Mint: { to: string; amount: Tokens } }
| {
Transfer: {
to: string;
fee: Tokens;
from: string;
amount: Tokens;
};
}
| {
TransferFrom: {
to: string;
fee: Tokens;
from: string;
amount: Tokens;
spender: string;
};
};
export interface Status {
num_blocks_synced: bigint;
}
export interface TimeStamp {
timestamp_nanos: bigint;
}
export interface Tokens {
e8s: bigint;
}
export interface Transaction {
memo: bigint;
icrc1_memo: [] | [Uint8Array];
operation: Operation;
created_at_time: [] | [TimeStamp];
}
export interface TransactionWithId {
id: bigint;
transaction: Transaction;
}
export interface _SERVICE {
get_account_identifier_balance: ActorMethod<[string], bigint>;
get_account_identifier_transactions: ActorMethod<
[GetAccountIdentifierTransactionsArgs],
GetAccountIdentifierTransactionsResult
>;
get_account_transactions: ActorMethod<
[GetAccountTransactionsArgs],
GetAccountIdentifierTransactionsResult
>;
get_blocks: ActorMethod<[GetBlocksRequest], GetBlocksResponse>;
http_request: ActorMethod<[HttpRequest], HttpResponse>;
icrc1_balance_of: ActorMethod<[Account], bigint>;
ledger_id: ActorMethod<[], Principal>;
status: ActorMethod<[], Status>;
}
Loading

0 comments on commit 01b692e

Please sign in to comment.