Skip to content

Commit

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

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

# Notes

It annoys me a bit that the close basically duplicates the code of ICP
(provided in PR #709) but, not sure it is worth the effort at this point
to create a util or even lib for that particular topic. We might do so
if more canisters starts implementing consent message but, happy to hear
any thoughts about it.

# Changes

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

---------

Signed-off-by: David Dal Busco <[email protected]>
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
peterpeterparker and github-actions[bot] authored Sep 4, 2024
1 parent 5ff19cc commit 90d1109
Show file tree
Hide file tree
Showing 7 changed files with 524 additions and 14 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Features

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

# 2024.09.02-0830Z

Expand Down
35 changes: 25 additions & 10 deletions packages/ledger-icrc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ Parameters:

### :factory: IcrcLedgerCanister

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

#### Methods

Expand All @@ -158,14 +158,15 @@ Parameters:
- [transferFrom](#gear-transferfrom)
- [approve](#gear-approve)
- [allowance](#gear-allowance)
- [consentMessage](#gear-consentmessage)

##### :gear: create

| Method | Type |
| -------- | ---------------------------------------------------------------------- |
| `create` | `(options: IcrcLedgerCanisterOptions<_SERVICE>) => IcrcLedgerCanister` |

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

##### :gear: metadata

Expand All @@ -175,7 +176,7 @@ The token metadata (name, symbol, etc.).
| ---------- | ------------------------------------------------------------- |
| `metadata` | `(params: QueryParams) => Promise<IcrcTokenMetadataResponse>` |

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

##### :gear: transactionFee

Expand All @@ -185,7 +186,7 @@ The ledger transaction fees.
| ---------------- | ------------------------------------------ |
| `transactionFee` | `(params: QueryParams) => Promise<bigint>` |

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

##### :gear: balance

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

##### :gear: transfer

Expand All @@ -213,7 +214,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#L78)

##### :gear: totalTokensSupply

Expand All @@ -223,7 +224,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#L94)

##### :gear: transferFrom

Expand All @@ -239,7 +240,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#L107)

##### :gear: approve

Expand All @@ -255,7 +256,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#L129)

##### :gear: allowance

Expand All @@ -271,7 +272,21 @@ 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#L151)

##### :gear: consentMessage

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

| Method | Type |
| ---------------- | ---------------------------------------------------------------------- |
| `consentMessage` | `(params: Icrc21ConsentMessageParams) => 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-icrc/src/ledger.canister.ts#L169)

### :factory: IcrcIndexCanister

Expand Down
32 changes: 31 additions & 1 deletion packages/ledger-icrc/src/converters/ledger.converters.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { toNullable } from "@dfinity/utils";
import { isNullish, toNullable } from "@dfinity/utils";
import type {
ApproveArgs,
icrc21_consent_message_request as ConsentMessageArgs,
TransferArg,
TransferFromArgs,
} from "../../candid/icrc_ledger";
import type {
ApproveParams,
Icrc21ConsentMessageParams,
TransferFromParams,
TransferParams,
} from "../types/ledger.params";
Expand Down Expand Up @@ -60,3 +62,31 @@ export const toApproveArgs = ({
expected_allowance: toNullable(expected_allowance),
expires_at: toNullable(expires_at),
});

export const toIcrc21ConsentMessageArgs = ({
userPreferences: {
metadata: { utcOffsetMinutes, language },
deriveSpec,
},
...rest
}: Icrc21ConsentMessageParams): ConsentMessageArgs => ({
...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,
},
},
),
},
});
50 changes: 50 additions & 0 deletions packages/ledger-icrc/src/errors/ledger.errors.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,57 @@
import type { icrc21_error as Icrc21RawError } from "../../candid/icrc_ledger";

export class IcrcTransferError<T> extends Error {
public errorType: T;
constructor({ msg, errorType }: { msg?: string; errorType: T }) {
super(msg);
this.errorType = errorType;
}
}

export class GenericError extends Error {
constructor(
public readonly message: string,
public readonly error_code: bigint,
) {
super();
}
}

export class ConsentMessageError extends Error {}

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

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 90d1109

Please sign in to comment.