From 73ec76952edaf62bafa20cb5f5b30fcb2fba23a8 Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Wed, 5 Jul 2023 14:59:58 +0200 Subject: [PATCH] feat: get balance for Index canister as well --- packages/ledger/src/canister.ts | 25 +++++++++++++ packages/ledger/src/index.canister.spec.ts | 42 +++++++++++++++++++++- packages/ledger/src/index.canister.ts | 19 ++++++++-- packages/ledger/src/ledger.canister.ts | 19 +++------- 4 files changed, 87 insertions(+), 18 deletions(-) create mode 100644 packages/ledger/src/canister.ts diff --git a/packages/ledger/src/canister.ts b/packages/ledger/src/canister.ts new file mode 100644 index 00000000..ff887f88 --- /dev/null +++ b/packages/ledger/src/canister.ts @@ -0,0 +1,25 @@ +import { Canister } from "@dfinity/utils"; +import { toNullable } from "@dfinity/utils/src"; +import type { _SERVICE as IcrcIndexService } from "../candid/icrc1_index"; +import type { + Tokens, + _SERVICE as IcrcLedgerService, +} from "../candid/icrc1_ledger"; +import type { BalanceParams } from "./types/ledger.params"; + +export abstract class IcrcCanister< + T extends IcrcLedgerService | IcrcIndexService +> extends Canister { + + /** + * Returns the balance for a given account provided as owner and with optional subaccount. + * + * @param {BalanceParams} params The parameters to get the balance of an account. + * @returns {Promise} The balance of the given account. + */ + balance = (params: BalanceParams): Promise => + this.caller({ certified: params.certified }).icrc1_balance_of({ + owner: params.owner, + subaccount: toNullable(params.subaccount), + }); +} diff --git a/packages/ledger/src/index.canister.spec.ts b/packages/ledger/src/index.canister.spec.ts index 5a3c6af1..3b20bbdc 100644 --- a/packages/ledger/src/index.canister.spec.ts +++ b/packages/ledger/src/index.canister.spec.ts @@ -1,5 +1,6 @@ import type { ActorSubclass } from "@dfinity/agent"; import { Principal } from "@dfinity/principal"; +import { arrayOfNumberToUint8Array } from "@dfinity/utils/src"; import { mock } from "jest-mock-extended"; import type { Account, @@ -8,7 +9,7 @@ import type { } from "../candid/icrc1_index"; import { IndexError } from "./errors/index.errors"; import { IcrcIndexCanister } from "./index.canister"; -import { indexCanisterIdMock } from "./mocks/ledger.mock"; +import { indexCanisterIdMock, ledgerCanisterIdMock } from "./mocks/ledger.mock"; import { IcrcAccount } from "./types/ledger.responses"; describe("Index canister", () => { @@ -85,4 +86,43 @@ describe("Index canister", () => { expect(call).rejects.toThrowError(IndexError); }); }); + + describe("balance", () => { + it("should return the balance of main account", async () => { + const service = mock>(); + const balance = BigInt(100); + service.icrc1_balance_of.mockResolvedValue(balance); + + const canister = IcrcIndexCanister.create({ + canisterId: ledgerCanisterIdMock, + certifiedServiceOverride: service, + }); + + const owner = Principal.fromText("aaaaa-aa"); + const res = await canister.balance({ + owner, + }); + expect(service.icrc1_balance_of).toBeCalled(); + expect(res).toEqual(balance); + }); + + it("should return the balance of subaccount", async () => { + const service = mock>(); + const balance = BigInt(100); + service.icrc1_balance_of.mockResolvedValue(balance); + + const canister = IcrcIndexCanister.create({ + canisterId: ledgerCanisterIdMock, + certifiedServiceOverride: service, + }); + + const owner = Principal.fromText("aaaaa-aa"); + const subaccount = arrayOfNumberToUint8Array([0, 0, 1]); + const res = await canister.balance({ + owner, + subaccount, + }); + expect(res).toEqual(balance); + }); + }); }); diff --git a/packages/ledger/src/index.canister.ts b/packages/ledger/src/index.canister.ts index fa693af1..0f05dff2 100644 --- a/packages/ledger/src/index.canister.ts +++ b/packages/ledger/src/index.canister.ts @@ -1,16 +1,19 @@ -import { Canister, createServices } from "@dfinity/utils"; +import { createServices, toNullable } from "@dfinity/utils"; import type { GetTransactions, + Tokens, _SERVICE as IcrcIndexService, } from "../candid/icrc1_index"; import { idlFactory as certifiedIdlFactory } from "../candid/icrc1_index.certified.idl"; import { idlFactory } from "../candid/icrc1_index.idl"; +import { IcrcCanister } from "./canister"; import { toGetTransactionsArgs } from "./converters/index.converters"; import { IndexError } from "./errors/index.errors"; import type { IcrcLedgerCanisterOptions } from "./types/canister.options"; import type { GetAccountTransactionsParams } from "./types/index.params"; +import type { BalanceParams } from "./types/ledger.params"; -export class IcrcIndexCanister extends Canister { +export class IcrcIndexCanister extends IcrcCanister { static create(options: IcrcLedgerCanisterOptions) { const { service, certifiedService, canisterId } = createServices({ @@ -42,4 +45,16 @@ export class IcrcIndexCanister extends Canister { return response.Ok; }; + + /** + * Returns the balance for a given account provided as owner and with optional subaccount. + * + * @param {BalanceParams} params The parameters to get the balance of an account. + * @returns {Promise} The balance of the given account. + */ + balance = (params: BalanceParams): Promise => + this.caller({ certified: params.certified }).icrc1_balance_of({ + owner: params.owner, + subaccount: toNullable(params.subaccount), + }); } diff --git a/packages/ledger/src/ledger.canister.ts b/packages/ledger/src/ledger.canister.ts index 6e63be16..9d971f6d 100644 --- a/packages/ledger/src/ledger.canister.ts +++ b/packages/ledger/src/ledger.canister.ts @@ -1,5 +1,5 @@ import type { QueryParams } from "@dfinity/utils"; -import { Canister, createServices, toNullable } from "@dfinity/utils"; +import { createServices } from "@dfinity/utils"; import type { BlockIndex, Tokens, @@ -7,13 +7,14 @@ import type { } from "../candid/icrc1_ledger"; import { idlFactory as certifiedIdlFactory } from "../candid/icrc1_ledger.certified.idl"; import { idlFactory } from "../candid/icrc1_ledger.idl"; +import { IcrcCanister } from "./canister"; import { toTransferArg } from "./converters/ledger.converters"; import { IcrcTransferError } from "./errors/ledger.errors"; import type { IcrcLedgerCanisterOptions } from "./types/canister.options"; -import type { BalanceParams, TransferParams } from "./types/ledger.params"; +import type { TransferParams } from "./types/ledger.params"; import type { IcrcTokenMetadataResponse } from "./types/ledger.responses"; -export class IcrcLedgerCanister extends Canister { +export class IcrcLedgerCanister extends IcrcCanister { static create(options: IcrcLedgerCanisterOptions) { const { service, certifiedService, canisterId } = createServices({ @@ -39,18 +40,6 @@ export class IcrcLedgerCanister extends Canister { transactionFee = (params: QueryParams): Promise => this.caller(params).icrc1_fee(); - /** - * Returns the balance for a given account provided as owner and with optional subaccount. - * - * @param {BalanceParams} params The parameters to get the balance of an account. - * @returns {Promise} The balance of the given account. - */ - balance = (params: BalanceParams): Promise => - this.caller({ certified: params.certified }).icrc1_balance_of({ - owner: params.owner, - subaccount: toNullable(params.subaccount), - }); - /** * Transfers tokens from the sender to the given account. *