Skip to content

Commit d962dde

Browse files
authored
Fix Chainport tokens schema validation (#222)
* Fix chainport tokens schema * Use formatCurrency for receiving amount formatting * Save * Simplify CurrencyUtils.render * Remove added newline * Wrap operands in BigInt for decimal calculation
1 parent 750cf84 commit d962dde

File tree

4 files changed

+45
-91
lines changed

4 files changed

+45
-91
lines changed

renderer/components/BridgeAssetsForm/BridgeConfirmationModal/BridgeConfirmationModal.tsx

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -162,19 +162,17 @@ export function BridgeConfirmationModal({
162162
BigInt(txDetails.bridge_output.amount) -
163163
BigInt(txDetails.bridge_fee.source_token_fee_amount ?? 0);
164164

165-
const convertedAmount = CurrencyUtils.render(
165+
const convertedAmount = CurrencyUtils.formatCurrency(
166166
bridgeAmount,
167-
selectedAsset.asset.id,
168-
selectedAsset.asset.verification,
167+
chainportToken.decimals,
169168
);
170169

171170
return convertedAmount + " " + chainportToken.symbol;
172171
}, [
173-
selectedAsset.asset.id,
174-
selectedAsset.asset.verification,
172+
isTransactionDetailsLoading,
175173
txDetails,
174+
chainportToken.decimals,
176175
chainportToken.symbol,
177-
isTransactionDetailsLoading,
178176
]);
179177

180178
const chainportGasFee = useMemo(() => {
@@ -191,12 +189,9 @@ export function BridgeConfirmationModal({
191189
}
192190

193191
if (txDetails.bridge_fee.is_portx_fee_payment) {
194-
const fee = CurrencyUtils.render(
195-
BigInt(txDetails.bridge_fee.portx_fee_amount),
196-
undefined,
197-
{
198-
decimals: 18,
199-
},
192+
const fee = CurrencyUtils.formatCurrency(
193+
txDetails.bridge_fee.portx_fee_amount,
194+
18,
200195
);
201196
return `${fee} PORTX`;
202197
}

renderer/utils/currency.ts

Lines changed: 36 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -61,34 +61,6 @@ export class CurrencyUtils {
6161
}
6262
}
6363

64-
/**
65-
* Renders a value in a minor denomination as the major denomination:
66-
* - $IRON is always going to have 8 decimal places.
67-
* - If a custom asset, and `decimals` is provided, it will give the value
68-
* followed by a digit for each decimal place
69-
* - If a custom asset, and `decimals` is not provided, it will assume the
70-
* value is already in minor denomination with no decimal places
71-
*
72-
* Examples:
73-
* 100000000 = 1 $IRON
74-
* A custom asset with 2 decimal places: 100 = 1
75-
* A custom asset with no decimal places: 1 = 1
76-
*/
77-
static minorToMajor(
78-
amount: bigint,
79-
assetId?: string,
80-
verifiedAssetMetadata?: {
81-
decimals?: number;
82-
},
83-
): { value: bigint; decimals: number } {
84-
const { decimals } = this.assetMetadataWithDefaults(
85-
assetId,
86-
verifiedAssetMetadata,
87-
);
88-
89-
return DecimalUtils.normalize({ value: amount, decimals: -decimals });
90-
}
91-
9264
/**
9365
* Renders values for human-readable purposes:
9466
* - Renders $IRON in the major denomination, with 8 decimal places
@@ -104,13 +76,46 @@ export class CurrencyUtils {
10476
decimals?: number;
10577
},
10678
): string {
107-
const { value: majorValue, decimals: majorDecimals } = this.minorToMajor(
108-
BigInt(amount),
79+
const { decimals } = this.assetMetadataWithDefaults(
10980
assetId,
11081
verifiedAssetMetadata,
11182
);
11283

113-
return DecimalUtils.render(majorValue, majorDecimals);
84+
return this.formatCurrency(amount, decimals);
85+
}
86+
87+
/**
88+
* Formats a value in the minor denomination as a human-readable currency value with the
89+
* specified number of decimal places.
90+
*
91+
* Min precision is the minimum number of decimal places to include.
92+
*/
93+
static formatCurrency(
94+
value: bigint | number | string,
95+
decimals: number,
96+
minPrecision: number = 0,
97+
): string {
98+
const asBigInt = BigInt(value);
99+
100+
if (asBigInt < 0) {
101+
return `-${this.formatCurrency(
102+
asBigInt * BigInt(-1),
103+
decimals,
104+
minPrecision,
105+
)}`;
106+
}
107+
108+
const decimalsBigInt = BigInt(10) ** BigInt(decimals);
109+
110+
const major = asBigInt / decimalsBigInt;
111+
const remainder = asBigInt % decimalsBigInt;
112+
const remainderString = remainder
113+
.toString()
114+
.padStart(decimals, "0")
115+
.replace(/0+$/, "")
116+
.padEnd(minPrecision, "0");
117+
118+
return remainderString ? `${major}.${remainderString}` : major.toString();
114119
}
115120

116121
static shortSymbol(

renderer/utils/decimalUtils.ts

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -3,52 +3,6 @@
33
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
44

55
export class DecimalUtils {
6-
/**
7-
* Render `value * 10 ^ decimals` as a string. `minPrecision` tells how \
8-
* many decimal places to pad the string with. \
9-
* e.g. 1 * 10 ^ 0 => '1' \
10-
* 1 * 10 ^ 0 with 2 min precision => '1.00' \
11-
*/
12-
static render(
13-
value: bigint | number,
14-
decimals: number,
15-
minPrecision: number = 0,
16-
): string {
17-
const normalized = this.normalize({ value: BigInt(value), decimals });
18-
value = normalized.value;
19-
decimals = normalized.decimals;
20-
21-
if (value < 0) {
22-
return `-${this.render(value * -1n, decimals, minPrecision)}`;
23-
}
24-
25-
if (decimals < 0) {
26-
let decimalPos = value.toString().length;
27-
let stringValue = value.toString();
28-
for (let i = 0; i < -decimals; i++) {
29-
if (decimalPos === 0) {
30-
stringValue = `0${stringValue}`;
31-
} else {
32-
decimalPos--;
33-
}
34-
}
35-
36-
if (decimalPos === 0) {
37-
return `0.${stringValue.padEnd(minPrecision, "0")}`;
38-
}
39-
40-
return `${stringValue.slice(0, decimalPos)}.${stringValue
41-
.slice(decimalPos)
42-
.padEnd(minPrecision, "0")}`;
43-
}
44-
45-
const wholeString = (value * 10n ** BigInt(decimals)).toString();
46-
const decimalString =
47-
minPrecision > 0 ? `.${"".padEnd(minPrecision, "0")}` : "";
48-
49-
return `${wholeString}${decimalString}`;
50-
}
51-
526
/**
537
* Decode a string into a bigint and the number of decimal places \
548
* e.g. '1' => { value: 1n, decimals: 0 } \

shared/chainport.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ const MetadataApiResponseSchema = z.object({
3434
chainport_network_id: z.number(),
3535
shortname: z.string(),
3636
name: z.string(),
37-
utils_contract: z.union([z.string(), z.null()]),
37+
utils_contract: z.string().nullable(),
3838
chain_id: z.number().nullable(),
3939
label: z.string(),
4040
blockchain_type: z.string(),
@@ -95,7 +95,7 @@ const TokensApiResponseSchema = z.object({
9595
symbol: z.string(),
9696
token_image: z.string(),
9797
target_networks: z.array(z.number()),
98-
chain_id: z.null(),
98+
chain_id: z.number().nullable(),
9999
network_name: z.string(),
100100
network_id: z.number(),
101101
blockchain_type: z.string(),

0 commit comments

Comments
 (0)