Skip to content

Commit

Permalink
GIX-2154: Add support for token decimals in TokenAmount (#491)
Browse files Browse the repository at this point in the history
# Motivation

Some tokens (like ckETH) have a precision different than 8 decimals.

In this PR, support decimals precision in the new TokenAmountV2 class.

# Changes

* Add mandatory field `decimals` in `Token` type.
* Add `decimals` to ICPToken.
* `TokenAmount` rejects tokens with `decimals !== 8`
*  New type `TokenAmountV2` which supports `decimals !== 8`

# Tests

* Test that `TokenAmount` does not support different decimals.
* Test that TokenAmountV2 supports different decimals.

# Todos

- [x] Add entry to changelog (if necessary).

---------

Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
dskloetd and github-actions[bot] authored Dec 1, 2023
1 parent de396fa commit 4aac1d7
Show file tree
Hide file tree
Showing 5 changed files with 556 additions and 9 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,17 @@

## Overview

## Breaking changes

- `decimals` mandatory field in `Token`.
- `TokenAmount` rejects tokens with `decimals !== 8`.

## Features

- Substitute `?` fields with `Option` fields in the converters related to NNS proposals.
- Add retrieveBtcStatus to ckbtc minter canister.
- Make uint8ArrayToHexString also accept `number[]` as input.
- Add a new type TokenAmountV2 which supports `decimals !== 8`.

## Operations

Expand Down
86 changes: 80 additions & 6 deletions packages/utils/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -376,13 +376,15 @@ Tags after patch version are ignored, e.g. 1.0.0-beta.1 is considered equal to 1
| ---------- | ------- |
| `ICPToken` | `Token` |

[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/utils/src/parser/token.ts#L62)
[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/utils/src/parser/token.ts#L113)

### :factory: TokenAmount

Deprecated. Use TokenAmountV2 instead which supports decimals !== 8.

Represents an amount of tokens.

[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/utils/src/parser/token.ts#L73)
[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/utils/src/parser/token.ts#L127)

#### Methods

Expand All @@ -404,7 +406,7 @@ Parameters:
- `params.amount`: The amount in bigint format.
- `params.token`: The token type.

[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/utils/src/parser/token.ts#L86)
[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/utils/src/parser/token.ts#L144)

##### :gear: fromString

Expand All @@ -423,7 +425,7 @@ Parameters:
- `params.amount`: The amount in string format.
- `params.token`: The token type.

[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/utils/src/parser/token.ts#L107)
[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/utils/src/parser/token.ts#L165)

##### :gear: fromNumber

Expand All @@ -440,15 +442,87 @@ Parameters:
- `params.amount`: The amount in number format.
- `params.token`: The token type.

[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/utils/src/parser/token.ts#L131)
[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/utils/src/parser/token.ts#L195)

##### :gear: toE8s

| Method | Type |
| ------- | -------------- |
| `toE8s` | `() => bigint` |

[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/utils/src/parser/token.ts#L157)
[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/utils/src/parser/token.ts#L221)

### :factory: TokenAmountV2

Represents an amount of tokens.

[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/utils/src/parser/token.ts#L233)

#### Methods

- [fromE8s](#gear-frome8s)
- [fromString](#gear-fromstring)
- [fromNumber](#gear-fromnumber)
- [toUlps](#gear-toulps)

##### :gear: fromE8s

Initialize from a bigint. Bigint are considered ulps.

| Method | Type |
| --------- | -------------------------------------------------------------------------- |
| `fromE8s` | `({ amount, token, }: { amount: bigint; token: Token; }) => TokenAmountV2` |

Parameters:

- `params.amount`: The amount in bigint format.
- `params.token`: The token type.

[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/utils/src/parser/token.ts#L246)

##### :gear: fromString

Initialize from a string. Accepted formats:

1234567.8901
1'234'567.8901
1,234,567.8901

| Method | Type |
| ------------ | ---------------------------------------------------------------------------------------------------- |
| `fromString` | `({ amount, token, }: { amount: string; token: Token; }) => FromStringToTokenError or TokenAmountV2` |

Parameters:

- `params.amount`: The amount in string format.
- `params.token`: The token type.

[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/utils/src/parser/token.ts#L267)

##### :gear: fromNumber

Initialize from a number.

1 integer is considered 10^{token.decimals} ulps

| Method | Type |
| ------------ | -------------------------------------------------------------------------- |
| `fromNumber` | `({ amount, token, }: { amount: number; token: Token; }) => TokenAmountV2` |

Parameters:

- `params.amount`: The amount in number format.
- `params.token`: The token type.

[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/utils/src/parser/token.ts#L291)

##### :gear: toUlps

| Method | Type |
| -------- | -------------- |
| `toUlps` | `() => bigint` |

[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/utils/src/parser/token.ts#L319)

### :factory: Canister

Expand Down
1 change: 1 addition & 0 deletions packages/utils/src/enums/token.enums.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export enum FromStringToTokenError {
FractionalMoreThan8Decimals,
InvalidFormat,
FractionalTooManyDecimals,
}
Loading

0 comments on commit 4aac1d7

Please sign in to comment.