Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add retrieveBtcStatusV2ByAccount to ckbtc canister #503

Merged
merged 6 commits into from
Dec 14, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

- Substitute `?` fields with `Option` fields in the converters related to NNS proposals.
- Add retrieveBtcStatus to ckbtc minter canister.
- Add retrieveBtcStatusV2ByAccount to ckbtc minter canister.
- Make uint8ArrayToHexString also accept `number[]` as input.
- Add a new type TokenAmountV2 which supports `decimals !== 8`.
- Fix issue when converting token amount from small numbers with `TokenAmountV2`.
Expand Down
36 changes: 26 additions & 10 deletions packages/ckbtc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ Parameters:

### :factory: CkBTCMinterCanister

[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ckbtc/src/minter.canister.ts#L36)
[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ckbtc/src/minter.canister.ts#L38)

#### Methods

Expand All @@ -89,6 +89,7 @@ Parameters:
- [retrieveBtc](#gear-retrievebtc)
- [retrieveBtcWithApproval](#gear-retrievebtcwithapproval)
- [retrieveBtcStatus](#gear-retrievebtcstatus)
- [retrieveBtcStatusV2ByAccount](#gear-retrievebtcstatusv2byaccount)
- [estimateWithdrawalFee](#gear-estimatewithdrawalfee)
- [getMinterInfo](#gear-getminterinfo)

Expand All @@ -98,7 +99,7 @@ Parameters:
| -------- | ------------------------------------------------------------------------ |
| `create` | `(options: CkBTCMinterCanisterOptions<_SERVICE>) => CkBTCMinterCanister` |

[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ckbtc/src/minter.canister.ts#L37)
[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ckbtc/src/minter.canister.ts#L39)

##### :gear: getBtcAddress

Expand All @@ -116,7 +117,7 @@ Parameters:
- `params.owner`: The owner for which the BTC address should be generated. If not provided, the `caller` will be use instead.
- `params.subaccount`: An optional subaccount to compute the address.

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

##### :gear: updateBalance

Expand All @@ -134,7 +135,7 @@ Parameters:
- `params.owner`: The owner of the address. If not provided, the `caller` will be use instead.
- `params.subaccount`: An optional subaccount of the address.

[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ckbtc/src/minter.canister.ts#L77)
[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ckbtc/src/minter.canister.ts#L79)

##### :gear: getWithdrawalAccount

Expand All @@ -144,7 +145,7 @@ Returns the account to which the caller should deposit ckBTC before withdrawing
| ---------------------- | ------------------------ |
| `getWithdrawalAccount` | `() => Promise<Account>` |

[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ckbtc/src/minter.canister.ts#L100)
[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ckbtc/src/minter.canister.ts#L102)

##### :gear: retrieveBtc

Expand All @@ -168,7 +169,7 @@ Parameters:
- `params.address`: The bitcoin address.
- `params.amount`: The ckBTC amount.

[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ckbtc/src/minter.canister.ts#L119)
[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ckbtc/src/minter.canister.ts#L121)

##### :gear: retrieveBtcWithApproval

Expand All @@ -194,7 +195,7 @@ Parameters:
- `params.fromSubaccount`: An optional subaccount from which
the ckBTC should be transferred.

[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ckbtc/src/minter.canister.ts#L149)
[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ckbtc/src/minter.canister.ts#L151)

##### :gear: retrieveBtcStatus

Expand All @@ -210,7 +211,22 @@ Parameters:
- `transactionId`: The ID of the corresponding burn transaction.
- `certified`: query or update call

[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ckbtc/src/minter.canister.ts#L180)
[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ckbtc/src/minter.canister.ts#L182)

##### :gear: retrieveBtcStatusV2ByAccount

Returns the status of all BTC withdrawals for the user's main account.

| Method | Type |
| ------------------------------ | ----------------------------------------------------------------------------------- |
| `retrieveBtcStatusV2ByAccount` | `({ certified, }: { certified: boolean; }) => Promise<RetrieveBtcStatusV2WithId[]>` |

Parameters:

- `transactionId`: The ID of the corresponding burn transaction.
- `certified`: query or update call

[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ckbtc/src/minter.canister.ts#L199)

##### :gear: estimateWithdrawalFee

Expand All @@ -226,7 +242,7 @@ Parameters:
- `params.certified`: query or update call
- `params.amount`: The optional amount for which the fee should be estimated.

[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ckbtc/src/minter.canister.ts#L198)
[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ckbtc/src/minter.canister.ts#L220)

##### :gear: getMinterInfo

Expand All @@ -241,7 +257,7 @@ Parameters:
- `params`: The parameters to get the deposit fee.
- `params.certified`: query or update call

[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ckbtc/src/minter.canister.ts#L212)
[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ckbtc/src/minter.canister.ts#L234)

<!-- TSDOC_END -->

Expand Down
77 changes: 76 additions & 1 deletion packages/ckbtc/src/minter.canister.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import { ActorSubclass } from "@dfinity/agent";
import { Principal } from "@dfinity/principal";
import { arrayOfNumberToUint8Array, toNullable } from "@dfinity/utils";
import { mock } from "jest-mock-extended";
import type { Account, _SERVICE as CkBTCMinterService } from "../candid/minter";
import type {
Account,
_SERVICE as CkBTCMinterService,
RetrieveBtcStatusV2,
} from "../candid/minter";
import {
RetrieveBtcError,
RetrieveBtcOk,
Expand Down Expand Up @@ -689,6 +693,77 @@ describe("ckBTC minter canister", () => {
});
});

describe("Retrieve BTC status V2 by account", () => {
const owner = Principal.fromHex("4321");
const status1 = {
Submitted: { txid: new Uint8Array([3, 2, 6]) },
} as RetrieveBtcStatusV2;
const status2 = {
Reimbursed: {
account: { owner, subaccount: [] },
mint_block_index: 103n,
amount: 123_000n,
reason: {
CallFailed: null,
},
},
} as RetrieveBtcStatusV2;
const response = [
{
block_index: 101n,
status_v2: [status1],
},
{
block_index: 102n,
status_v2: [status2],
},
] as {
block_index: bigint;
status_v2: [] | [RetrieveBtcStatusV2];
}[];

const expectedResponse = [
{
id: 101n,
status: status1,
},
{
id: 102n,
status: status2,
},
];

it("should return statuses", async () => {
const service = mock<ActorSubclass<CkBTCMinterService>>();
service.retrieve_btc_status_v2_by_account.mockResolvedValue(response);

const canister = minter(service);

const res = await canister.retrieveBtcStatusV2ByAccount({
certified: true,
});

expect(service.retrieve_btc_status_v2_by_account).toBeCalledTimes(1);
expect(service.retrieve_btc_status_v2_by_account).toBeCalledWith([]);
expect(res).toEqual(expectedResponse);
});

it("should use non-certified service", async () => {
const service = mock<ActorSubclass<CkBTCMinterService>>();
service.retrieve_btc_status_v2_by_account.mockResolvedValue(response);

const canister = nonCertifiedMinter(service);

const res = await canister.retrieveBtcStatusV2ByAccount({
certified: false,
});

expect(service.retrieve_btc_status_v2_by_account).toBeCalledTimes(1);
expect(service.retrieve_btc_status_v2_by_account).toBeCalledWith([]);
expect(res).toEqual(expectedResponse);
});
});

describe("Estimate Withdrawal Fee", () => {
it("should return estimated fee", async () => {
const result = { minter_fee: 123n, bitcoin_fee: 456n };
Expand Down
22 changes: 22 additions & 0 deletions packages/ckbtc/src/minter.canister.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
Canister,
createServices,
fromNullable,
toNullable,
type QueryParams,
} from "@dfinity/utils";
Expand Down Expand Up @@ -28,6 +29,7 @@ import type {
import type {
EstimateWithdrawalFee,
RetrieveBtcResponse,
RetrieveBtcStatusV2WithId,
RetrieveBtcWithApprovalResponse,
UpdateBalanceOk,
UpdateBalanceResponse,
Expand Down Expand Up @@ -188,6 +190,26 @@ export class CkBTCMinterCanister extends Canister<CkBTCMinterService> {
certified,
}).retrieve_btc_status({ block_index: transactionId });

/**
* Returns the status of all BTC withdrawals for the user's main account.
*
* @param {bigint} transactionId The ID of the corresponding burn transaction.
* @param {boolean} certified query or update call
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add the return type and a short explanation?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

*/
retrieveBtcStatusV2ByAccount = async ({
certified,
}: {
certified: boolean;
}): Promise<RetrieveBtcStatusV2WithId[]> => {
const statuses = await this.caller({
certified,
}).retrieve_btc_status_v2_by_account([]);
return statuses.map(({ block_index, status_v2 }) => ({
id: block_index,
status: fromNullable(status_v2),
}));
};

/**
* Returns an estimation of the user's fee (in Satoshi) for a retrieve_btc request based on the current status of the Bitcoin network and the fee related to the minter.
*
Expand Down
6 changes: 6 additions & 0 deletions packages/ckbtc/src/types/minter.responses.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type {
RetrieveBtcError,
RetrieveBtcOk,
RetrieveBtcStatusV2,
RetrieveBtcWithApprovalError,
UpdateBalanceError,
UtxoStatus,
Expand All @@ -21,3 +22,8 @@ export type RetrieveBtcWithApprovalResponse =
| { Err: RetrieveBtcWithApprovalError };

export type EstimateWithdrawalFee = { minter_fee: bigint; bitcoin_fee: bigint };

export type RetrieveBtcStatusV2WithId = {
id: bigint;
status: RetrieveBtcStatusV2 | undefined;
};
Loading