Skip to content

Commit

Permalink
feat: icrc21_canister_call_consent_message for ledger-icp (#709)
Browse files Browse the repository at this point in the history
# Motivation

Add support for `icrc21_canister_call_consent_message` to
`@dfinity/ledger-icp`.

# Changes

- Expose and implement new function `icrc21ConsentMessage`.
- Add a new parameter for the request.
- Map the potential error.

---------

Signed-off-by: David Dal Busco <david.dalbusco@dfinity.org>
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
peterpeterparker and github-actions[bot] authored Sep 3, 2024
1 parent 61c633a commit e51ed1d
Show file tree
Hide file tree
Showing 7 changed files with 484 additions and 10 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# Next

## Features

- Add support for `icrc21_canister_call_consent_message` to `@dfinity/ledger-icp`.

# 2024.09.02-0830Z

## Overview
Expand Down
31 changes: 23 additions & 8 deletions packages/ledger-icp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ const data = await metadata();

### :factory: LedgerCanister

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

#### Methods

Expand All @@ -173,14 +173,15 @@ const data = await metadata();
- [transfer](#gear-transfer)
- [icrc1Transfer](#gear-icrc1transfer)
- [icrc2Approve](#gear-icrc2approve)
- [icrc21ConsentMessage](#gear-icrc21consentmessage)

##### :gear: create

| Method | Type |
| -------- | ----------------------------------------------------- |
| `create` | `(options?: LedgerCanisterOptions) => 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#L36)

##### :gear: accountBalance

Expand All @@ -199,7 +200,7 @@ Parameters:
- `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#L60)
[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ledger-icp/src/ledger.canister.ts#L64)

##### :gear: metadata

Expand All @@ -213,7 +214,7 @@ Parameters:

- `params`: - The parameters used to fetch the metadata, notably query or certified call.

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

##### :gear: transactionFee

Expand All @@ -227,7 +228,7 @@ Parameters:

- `params`: - Optional query parameters for the request, defaulting to `{ certified: false }` for backwards compatibility reason.

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

##### :gear: transfer

Expand All @@ -238,7 +239,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#L108)
[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ledger-icp/src/ledger.canister.ts#L112)

##### :gear: icrc1Transfer

Expand All @@ -249,7 +250,7 @@ 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#L128)
[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ledger-icp/src/ledger.canister.ts#L132)

##### :gear: icrc2Approve

Expand All @@ -265,7 +266,21 @@ Parameters:

- `params`: - The parameters to approve.

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

##### :gear: icrc21ConsentMessage

Fetches the consent message for a specified canister call, intended to provide a human-readable message that helps users make informed decisions.

| Method | Type |
| ---------------------- | ----------------------------------------------------------------------- |
| `icrc21ConsentMessage` | `(params: Icrc21ConsentMessageRequest) => Promise<icrc21_consent_info>` |

Parameters:

- `params`: - The request parameters containing the method name, arguments, and consent preferences (e.g., language).

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

### :factory: IndexCanister

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
import { arrayOfNumberToUint8Array, toNullable } from "@dfinity/utils";
import {
arrayOfNumberToUint8Array,
isNullish,
toNullable,
} from "@dfinity/utils";
import type {
TransferArg as Icrc1TransferRawRequest,
icrc21_consent_message_request as Icrc21ConsentMessageRawRequest,
ApproveArgs as Icrc2ApproveRawRequest,
Tokens,
TransferArgs as TransferRawRequest,
} from "../../../candid/ledger";
import { TRANSACTION_FEE } from "../../constants/constants";
import type {
Icrc1TransferRequest,
Icrc21ConsentMessageRequest,
Icrc2ApproveRequest,
TransferRequest,
} from "../../types/ledger_converters";
Expand Down Expand Up @@ -75,3 +81,31 @@ export const toIcrc2ApproveRawRequest = ({
expected_allowance: toNullable(expected_allowance),
expires_at: toNullable(expires_at),
});

export const toIcrc21ConsentMessageRawRequest = ({
userPreferences: {
metadata: { utcOffsetMinutes, language },
deriveSpec,
},
...rest
}: Icrc21ConsentMessageRequest): Icrc21ConsentMessageRawRequest => ({
...rest,
user_preferences: {
metadata: {
language,
utc_offset_minutes: toNullable(utcOffsetMinutes),
},
device_spec: isNullish(deriveSpec)
? toNullable()
: toNullable(
"GenericDisplay" in deriveSpec
? { GenericDisplay: null }
: {
LineDisplay: {
characters_per_line: deriveSpec.LineDisplay.charactersPerLine,
lines_per_page: deriveSpec.LineDisplay.linesPerPage,
},
},
),
},
});
39 changes: 39 additions & 0 deletions packages/ledger-icp/src/errors/ledger.errors.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type {
Icrc1BlockIndex,
Icrc1Tokens,
icrc21_error as Icrc21RawError,
ApproveError as RawApproveError,
Icrc1TransferError as RawIcrc1TransferError,
TransferError as RawTransferError,
Expand All @@ -11,6 +12,7 @@ export class IcrcError extends Error {}

export class TransferError extends IcrcError {}
export class ApproveError extends IcrcError {}
export class ConsentMessageError extends IcrcError {}

export class InvalidSenderError extends TransferError {}

Expand Down Expand Up @@ -74,6 +76,10 @@ export class ExpiredError extends ApproveError {
}
}

export class InsufficientPaymentError extends ConsentMessageError {}
export class UnsupportedCanisterCallError extends ConsentMessageError {}
export class ConsentMessageUnavailableError extends ConsentMessageError {}

export const mapTransferError = (
rawTransferError: RawTransferError,
): TransferError => {
Expand Down Expand Up @@ -184,3 +190,36 @@ export const mapIcrc2ApproveError = (
`Unknown error type ${JSON.stringify(rawApproveError)}`,
);
};

export const mapIcrc21ConsentMessageError = (
rawError: Icrc21RawError,
): ConsentMessageError => {
if ("GenericError" in rawError) {
return new GenericError(
rawError.GenericError.description,
rawError.GenericError.error_code,
);
}

if ("InsufficientPayment" in rawError) {
return new InsufficientPaymentError(
rawError.InsufficientPayment.description,
);
}

if ("UnsupportedCanisterCall" in rawError) {
return new UnsupportedCanisterCallError(
rawError.UnsupportedCanisterCall.description,
);
}
if ("ConsentMessageUnavailable" in rawError) {
return new ConsentMessageUnavailableError(
rawError.ConsentMessageUnavailable.description,
);
}

// Edge case
return new ConsentMessageError(
`Unknown error type ${JSON.stringify(rawError)}`,
);
};
Loading

0 comments on commit e51ed1d

Please sign in to comment.