Skip to content

Commit

Permalink
feat: ICRC Index canister next gen (#380)
Browse files Browse the repository at this point in the history
# Motivation

Use the Index canister "next gen", implement `balance` for Index canister and make fetching transactions available as `query`.

# Changes

- use `index-ng/index-ng.did` as source for the Index canister
- update JS accordingly
- implement `balance` for Index canister
- `getTransactions` accept queries
  • Loading branch information
peterpeterparker authored Mar 4, 2024
1 parent dddc6cd commit d2a5294
Show file tree
Hide file tree
Showing 16 changed files with 355 additions and 105 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@

- Add support for `bitcoin_get_utxos` and `bitcoin_get_utxos_query` features to `@dfinity/ic-management` library.

- Add `balance` to ICRC `IndexCanister` which returns the balance for a given account. (1)
- Extend `getTransactions` of the ICRC `IndexCanister` to support `query`. (1)

### Notes

(1) The new features supported `@dfinity/ledger-icrc` requires the related Index canister to be upgraded to the so called `index-ng` WASM.

# 2024.02.21-0835Z

## Overview
Expand Down
46 changes: 15 additions & 31 deletions packages/ledger-icrc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ Parameters:
- [create](#gear-create)
- [metadata](#gear-metadata)
- [transactionFee](#gear-transactionfee)
- [balance](#gear-balance)
- [transfer](#gear-transfer)
- [totalTokensSupply](#gear-totaltokenssupply)
- [transferFrom](#gear-transferfrom)
Expand Down Expand Up @@ -165,20 +164,6 @@ The ledger transaction fees.

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

##### :gear: balance

Returns the balance for a given account provided as owner and with optional subaccount.

| Method | Type |
| --------- | -------------------------------------------- |
| `balance` | `(params: BalanceParams) => Promise<bigint>` |

Parameters:

- `params`: The parameters to get the balance of an account.

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

##### :gear: transfer

Transfers tokens from the sender to the given account.
Expand All @@ -191,7 +176,7 @@ Parameters:

- `params`: The parameters to transfer tokens.

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

##### :gear: totalTokensSupply

Expand All @@ -201,7 +186,7 @@ Returns the total supply of tokens.
| ------------------- | ------------------------------------------ |
| `totalTokensSupply` | `(params: QueryParams) => Promise<bigint>` |

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

##### :gear: transferFrom

Expand All @@ -217,7 +202,7 @@ Parameters:

- `params`: The parameters to transfer tokens from to.

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

##### :gear: approve

Expand All @@ -233,7 +218,7 @@ Parameters:

- `params`: The parameters to approve.

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

##### :gear: allowance

Expand All @@ -249,11 +234,11 @@ Parameters:

- `params`: The parameters to call the allowance.

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

### :factory: IcrcIndexCanister

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

#### Methods

Expand All @@ -266,22 +251,21 @@ Parameters:
| -------- | --------------------------------------------------------------------- |
| `create` | `(options: IcrcLedgerCanisterOptions<_SERVICE>) => IcrcIndexCanister` |

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

##### :gear: getTransactions

Get the transactions of an account
Get the transactions of an account.

| Method | Type |
| ----------------- | ------------------------------------------------------------------------------------ |
| `getTransactions` | `({ certified, ...rest }: GetAccountTransactionsParams) => Promise<GetTransactions>` |

Always certified.
`get_account_transactions` needs to be called with an update
because the index canisters makes a call to the ledger canister to get the transaction data.
Index Canister only holds the transactions ids in state, not the whole transaction data.
Parameters:

| Method | Type |
| ----------------- | -------------------------------------------------------------------- |
| `getTransactions` | `(params: GetAccountTransactionsParams) => Promise<GetTransactions>` |
- `params`: The parameters to get the transactions of an account.

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

<!-- TSDOC_END -->

Expand Down
56 changes: 47 additions & 9 deletions packages/ledger-icrc/candid/icrc_index.certified.idl.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
/* Do not edit. Compiled with ./scripts/compile-idl-js from packages/ledger-icrc/candid/icrc_index.did */
export const idlFactory = ({ IDL }) => {
const InitArgs = IDL.Record({ 'ledger_id' : IDL.Principal });
const TxId = IDL.Nat;
const Value = IDL.Rec();
const UpgradeArg = IDL.Record({ 'ledger_id' : IDL.Opt(IDL.Principal) });
const InitArg = IDL.Record({ 'ledger_id' : IDL.Principal });
const IndexArg = IDL.Variant({ 'Upgrade' : UpgradeArg, 'Init' : InitArg });
const BlockIndex = IDL.Nat;
const SubAccount = IDL.Vec(IDL.Nat8);
const Account = IDL.Record({
'owner' : IDL.Principal,
'subaccount' : IDL.Opt(IDL.Vec(IDL.Nat8)),
'subaccount' : IDL.Opt(SubAccount),
});
const GetAccountTransactionsArgs = IDL.Record({
'max_results' : IDL.Nat,
'start' : IDL.Opt(TxId),
'start' : IDL.Opt(BlockIndex),
'account' : Account,
});
const Tokens = IDL.Nat;
const Burn = IDL.Record({
'from' : Account,
'memo' : IDL.Opt(IDL.Vec(IDL.Nat8)),
Expand Down Expand Up @@ -52,38 +57,71 @@ export const idlFactory = ({ IDL }) => {
'transfer' : IDL.Opt(Transfer),
});
const TransactionWithId = IDL.Record({
'id' : TxId,
'id' : BlockIndex,
'transaction' : Transaction,
});
const GetTransactions = IDL.Record({
'balance' : Tokens,
'transactions' : IDL.Vec(TransactionWithId),
'oldest_tx_id' : IDL.Opt(TxId),
'oldest_tx_id' : IDL.Opt(BlockIndex),
});
const GetTransactionsErr = IDL.Record({ 'message' : IDL.Text });
const GetTransactionsResult = IDL.Variant({
'Ok' : GetTransactions,
'Err' : GetTransactionsErr,
});
const SubAccount = IDL.Vec(IDL.Nat8);
const GetBlocksRequest = IDL.Record({
'start' : IDL.Nat,
'length' : IDL.Nat,
});
const Map = IDL.Vec(IDL.Tuple(IDL.Text, Value));
Value.fill(
IDL.Variant({
'Int' : IDL.Int,
'Map' : Map,
'Nat' : IDL.Nat,
'Nat64' : IDL.Nat64,
'Blob' : IDL.Vec(IDL.Nat8),
'Text' : IDL.Text,
'Array' : IDL.Vec(Value),
})
);
const Block = Value;
const GetBlocksResponse = IDL.Record({
'blocks' : IDL.Vec(Block),
'chain_length' : IDL.Nat64,
});
const FeeCollectorRanges = IDL.Record({
'ranges' : IDL.Vec(
IDL.Tuple(Account, IDL.Vec(IDL.Tuple(BlockIndex, BlockIndex)))
),
});
const ListSubaccountsArgs = IDL.Record({
'owner' : IDL.Principal,
'start' : IDL.Opt(SubAccount),
});
const Status = IDL.Record({ 'num_blocks_synced' : BlockIndex });
return IDL.Service({
'get_account_transactions' : IDL.Func(
[GetAccountTransactionsArgs],
[GetTransactionsResult],
[],
),
'get_blocks' : IDL.Func([GetBlocksRequest], [GetBlocksResponse], []),
'get_fee_collectors_ranges' : IDL.Func([], [FeeCollectorRanges], []),
'icrc1_balance_of' : IDL.Func([Account], [Tokens], []),
'ledger_id' : IDL.Func([], [IDL.Principal], []),
'list_subaccounts' : IDL.Func(
[ListSubaccountsArgs],
[IDL.Vec(SubAccount)],
[],
),
'status' : IDL.Func([], [Status], []),
});
};
export const init = ({ IDL }) => {
const InitArgs = IDL.Record({ 'ledger_id' : IDL.Principal });
return [InitArgs];
const UpgradeArg = IDL.Record({ 'ledger_id' : IDL.Opt(IDL.Principal) });
const InitArg = IDL.Record({ 'ledger_id' : IDL.Principal });
const IndexArg = IDL.Variant({ 'Upgrade' : UpgradeArg, 'Init' : InitArg });
return [IDL.Opt(IndexArg)];
};
46 changes: 40 additions & 6 deletions packages/ledger-icrc/candid/icrc_index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { Principal } from "@dfinity/principal";

export interface Account {
owner: Principal;
subaccount: [] | [Uint8Array | number[]];
subaccount: [] | [SubAccount];
}
export interface Approve {
fee: [] | [bigint];
Expand All @@ -15,42 +15,62 @@ export interface Approve {
expires_at: [] | [bigint];
spender: Account;
}
export type Block = Value;
export type BlockIndex = bigint;
export interface Burn {
from: Account;
memo: [] | [Uint8Array | number[]];
created_at_time: [] | [bigint];
amount: bigint;
spender: [] | [Account];
}
export interface FeeCollectorRanges {
ranges: Array<[Account, Array<[BlockIndex, BlockIndex]>]>;
}
export interface GetAccountTransactionsArgs {
max_results: bigint;
start: [] | [TxId];
start: [] | [BlockIndex];
account: Account;
}
export interface GetBlocksRequest {
start: bigint;
length: bigint;
}
export interface GetBlocksResponse {
blocks: Array<Block>;
chain_length: bigint;
}
export interface GetTransactions {
balance: Tokens;
transactions: Array<TransactionWithId>;
oldest_tx_id: [] | [TxId];
oldest_tx_id: [] | [BlockIndex];
}
export interface GetTransactionsErr {
message: string;
}
export type GetTransactionsResult =
| { Ok: GetTransactions }
| { Err: GetTransactionsErr };
export interface InitArgs {
export type IndexArg = { Upgrade: UpgradeArg } | { Init: InitArg };
export interface InitArg {
ledger_id: Principal;
}
export interface ListSubaccountsArgs {
owner: Principal;
start: [] | [SubAccount];
}
export type Map = Array<[string, Value]>;
export interface Mint {
to: Account;
memo: [] | [Uint8Array | number[]];
created_at_time: [] | [bigint];
amount: bigint;
}
export interface Status {
num_blocks_synced: BlockIndex;
}
export type SubAccount = Uint8Array | number[];
export type Tokens = bigint;
export interface Transaction {
burn: [] | [Burn];
kind: string;
Expand All @@ -60,7 +80,7 @@ export interface Transaction {
transfer: [] | [Transfer];
}
export interface TransactionWithId {
id: TxId;
id: BlockIndex;
transaction: Transaction;
}
export interface Transfer {
Expand All @@ -72,12 +92,26 @@ export interface Transfer {
amount: bigint;
spender: [] | [Account];
}
export type TxId = bigint;
export interface UpgradeArg {
ledger_id: [] | [Principal];
}
export type Value =
| { Int: bigint }
| { Map: Map }
| { Nat: bigint }
| { Nat64: bigint }
| { Blob: Uint8Array | number[] }
| { Text: string }
| { Array: Array<Value> };
export interface _SERVICE {
get_account_transactions: ActorMethod<
[GetAccountTransactionsArgs],
GetTransactionsResult
>;
get_blocks: ActorMethod<[GetBlocksRequest], GetBlocksResponse>;
get_fee_collectors_ranges: ActorMethod<[], FeeCollectorRanges>;
icrc1_balance_of: ActorMethod<[Account], Tokens>;
ledger_id: ActorMethod<[], Principal>;
list_subaccounts: ActorMethod<[ListSubaccountsArgs], Array<SubAccount>>;
status: ActorMethod<[], Status>;
}
Loading

0 comments on commit d2a5294

Please sign in to comment.