Skip to content

Commit 9e79be0

Browse files
chore: convert tx to hex, ui improvements
1 parent 063f52e commit 9e79be0

File tree

8 files changed

+82
-37
lines changed

8 files changed

+82
-37
lines changed

packages/appkit/src/partials/w3m-swap-input/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ export function SwapInput({
128128
>
129129
<Text variant="small-400" color="fg-200" numberOfLines={1}>
130130
{isMarketValueGreaterThanZero
131-
? `~$${UiUtil.formatNumberToLocalString(marketValue, 2)}`
131+
? `~$${UiUtil.formatNumberToLocalString(marketValue, 6)}`
132132
: ''}
133133
</Text>
134134
{showMax && (

packages/appkit/src/views/w3m-swap-preview-view/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ export function SwapPreviewView() {
8686
Send
8787
</Text>
8888
<Text variant="paragraph-400" color="fg-100">
89-
${UiUtil.formatNumberToLocalString(sourceTokenMarketValue, 2)}
89+
${UiUtil.formatNumberToLocalString(sourceTokenMarketValue, 6)}
9090
</Text>
9191
</FlexView>
9292
<TokenButton
@@ -106,7 +106,7 @@ export function SwapPreviewView() {
106106
Receive
107107
</Text>
108108
<Text variant="paragraph-400" color="fg-100">
109-
${UiUtil.formatNumberToLocalString(toTokenMarketValue, 2)}
109+
${UiUtil.formatNumberToLocalString(toTokenMarketValue, 6)}
110110
</Text>
111111
</FlexView>
112112
<TokenButton

packages/appkit/src/views/w3m-swap-view/index.tsx

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ import { useCallback, useEffect } from 'react';
33
import { Platform, ScrollView } from 'react-native';
44
import {
55
AccountController,
6+
ConnectionsController,
7+
ConstantsUtil,
68
EventsController,
7-
NetworkController,
89
RouterController,
910
SwapController
1011
} from '@reown/appkit-core-react-native';
@@ -91,7 +92,7 @@ export function SwapView() {
9192
type: 'track',
9293
event: 'INITIATE_SWAP',
9394
properties: {
94-
network: NetworkController.state.caipNetwork?.id || '',
95+
network: ConnectionsController.state.activeNetwork?.caipNetworkId || '',
9596
swapFromToken: SwapController.state.sourceToken?.symbol || '',
9697
swapToToken: SwapController.state.toToken?.symbol || '',
9798
swapFromAmount: SwapController.state.sourceTokenAmount || '',
@@ -103,9 +104,12 @@ export function SwapView() {
103104
};
104105

105106
const onSourceMaxPress = () => {
106-
const isNetworkToken =
107-
SwapController.state.sourceToken?.address ===
108-
NetworkController.getActiveNetworkTokenAddress();
107+
const { activeNamespace, activeCaipNetworkId } = ConnectionsController.state;
108+
const networkTokenAddress = activeNamespace
109+
? `${activeCaipNetworkId}:${ConstantsUtil.NATIVE_TOKEN_ADDRESS[activeNamespace]}`
110+
: undefined;
111+
112+
const isNetworkToken = SwapController.state.sourceToken?.address === networkTokenAddress;
109113

110114
const _gasPriceInUSD = SwapController.state.gasPriceInUSD;
111115
const _sourceTokenPriceInUSD = SwapController.state.sourceTokenPriceInUSD;

packages/common/src/adapters/EvmAdapter.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { BlockchainAdapter } from './BlockchainAdapter';
2+
import { NumberUtil } from '../utils/NumberUtil';
23

34
export abstract class EVMAdapter extends BlockchainAdapter {
45
async estimateGas({ address, to, data, chainNamespace }: any): Promise<bigint> {
@@ -49,9 +50,9 @@ export abstract class EVMAdapter extends BlockchainAdapter {
4950
const txParams = {
5051
from: address,
5152
to: data.to,
52-
value: data.value?.toString(), // hex string or decimal string
53-
gas: data.gas?.toString(), // optional
54-
gasPrice: data.gasPrice?.toString(), // optional
53+
value: NumberUtil.convertNumericToHexString(data.value),
54+
gas: NumberUtil.convertNumericToHexString(data.gas),
55+
gasPrice: NumberUtil.convertNumericToHexString(data.gasPrice),
5556
data: data.data, // hex-encoded bytecode
5657
type: '0x0' // optional: legacy transaction type
5758
};

packages/common/src/utils/NumberUtil.ts

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
import * as BigNumber from 'bignumber.js';
22

33
export const NumberUtil = {
4+
/**
5+
* Creates a BigNumber instance from a given value.
6+
* If the value is a string, commas are removed before conversion.
7+
* @param value - The input value (string, number, or BigNumber) to convert to a BigNumber.
8+
* @returns A BigNumber instance.
9+
*/
410
bigNumber(value: BigNumber.BigNumber.Value) {
511
if (typeof value === 'string') {
612
return new BigNumber.BigNumber(value.replace(/,/g, ''));
@@ -10,10 +16,11 @@ export const NumberUtil = {
1016
},
1117

1218
/**
13-
* Multiply two numbers represented as strings with BigNumber to handle decimals correctly
14-
* @param a string
15-
* @param b string
16-
* @returns
19+
* Multiplies two numbers using BigNumber for precision, especially with decimals.
20+
* Handles undefined inputs by returning BigNumber(0).
21+
* @param a - The first multiplicand (string, number, or BigNumber). Commas are removed if it's a string.
22+
* @param b - The second multiplicand (string, number, or BigNumber). Commas are removed if it's a string.
23+
* @returns The product as a BigNumber instance, or BigNumber(0) if either input is undefined.
1724
*/
1825
multiply(a: BigNumber.BigNumber.Value | undefined, b: BigNumber.BigNumber.Value | undefined) {
1926
if (a === undefined || b === undefined) {
@@ -26,24 +33,37 @@ export const NumberUtil = {
2633
return aBigNumber.multipliedBy(bBigNumber);
2734
},
2835

36+
/**
37+
* Rounds a number to a specified number of decimal places if its string representation meets a certain length threshold.
38+
* @param number - The number to potentially round.
39+
* @param threshold - The minimum string length of the number to trigger rounding.
40+
* @param fixed - The number of decimal places to round to.
41+
* @returns The rounded number (as a string if rounded, otherwise the original number) or the original number.
42+
*/
2943
roundNumber(number: number, threshold: number, fixed: number) {
3044
const roundedNumber =
3145
number.toString().length >= threshold ? Number(number).toFixed(fixed) : number;
3246

3347
return roundedNumber;
3448
},
3549

50+
/**
51+
* Calculates the next multiple of ten greater than or equal to the given amount.
52+
* Defaults to 10 if no amount is provided or if the calculated multiple is less than 10.
53+
* @param amount - The number for which to find the next multiple of ten. Optional.
54+
* @returns The next multiple of ten, at least 10.
55+
*/
3656
nextMultipleOfTen(amount?: number) {
3757
if (!amount) return 10;
3858

3959
return Math.max(Math.ceil(amount / 10) * 10, 10);
4060
},
4161

4262
/**
43-
* Format the given number or string to human readable numbers with the given number of decimals
44-
* @param value - The value to format. It could be a number or string. If it's a string, it will be parsed to a float then formatted.
45-
* @param decimals - number of decimals after dot
46-
* @returns
63+
* Formats a number or string to a human-readable string with a specified number of decimal places, using US locale formatting.
64+
* @param value - The value to format (string, number, or undefined). If undefined, returns '0.00'.
65+
* @param decimals - The number of decimal places to display. Defaults to 2.
66+
* @returns A locale-formatted string representation of the number.
4767
*/
4868
formatNumberToLocalString(value: string | number | undefined, decimals = 2) {
4969
if (value === undefined) {
@@ -62,10 +82,11 @@ export const NumberUtil = {
6282
minimumFractionDigits: decimals
6383
});
6484
},
85+
6586
/**
66-
* Parse a formatted local string back to a number
67-
* @param value - The formatted string to parse
68-
* @returns
87+
* Parses a locale-formatted numeric string (e.g., with commas) back into a number.
88+
* @param value - The formatted string to parse. If undefined, returns 0.
89+
* @returns The parsed number, or 0 if the input is undefined.
6990
*/
7091
parseLocalStringToNumber(value: string | undefined) {
7192
if (value === undefined) {
@@ -74,5 +95,27 @@ export const NumberUtil = {
7495

7596
// Remove any commas used as thousand separators and parse the float
7697
return parseFloat(value.replace(/,/gu, ''));
98+
},
99+
100+
/**
101+
* Converts a numeric value (BigInt, number, or string representation of a number) to a 0x-prefixed hexadecimal string.
102+
* This is often required for Ethereum RPC parameters like value, gas, gasPrice.
103+
* @param value - The value to convert. Can be BigInt, number, or a string (decimal or hex).
104+
* @returns A 0x-prefixed hexadecimal string, or undefined if the input is undefined or null.
105+
* @throws Error if the value cannot be converted to BigInt.
106+
*/
107+
convertNumericToHexString: (value: any): string | undefined => {
108+
if (value === undefined || value === null) {
109+
return undefined;
110+
}
111+
try {
112+
// This handles BigInt, number, or string representation of a number (decimal or hex)
113+
const bigIntValue = BigInt(value);
114+
// Ethereum RPC spec requires "0x0" for zero, and other values to be 0x-prefixed hex.
115+
116+
return '0x' + bigIntValue.toString(16);
117+
} catch (error) {
118+
throw new Error(`NumberUtil: Invalid parameter, cannot convert to hex: ${value}`);
119+
}
77120
}
78121
};

packages/core/src/controllers/SwapController.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,8 @@ export const SwapController = {
521521
this.setTransactionDetails();
522522
}
523523
} catch (error) {
524-
console.log('swapTokens error', error);
524+
SnackController.showError('Failed to get swap quote');
525+
state.loadingQuote = false;
525526
}
526527
},
527528

@@ -557,7 +558,6 @@ export const SwapController = {
557558

558559
return transaction;
559560
} catch (error) {
560-
console.log('getTransaction error', error);
561561
RouterController.goBack();
562562
SnackController.showError('Failed to check allowance');
563563
state.loadingBuildTransaction = false;
@@ -737,7 +737,6 @@ export const SwapController = {
737737
if (!data) {
738738
return undefined;
739739
}
740-
741740
const { fromAddress, toTokenAmount, isAuthConnector } = this.getParams();
742741

743742
state.loadingTransaction = true;
@@ -803,7 +802,6 @@ export const SwapController = {
803802

804803
return transactionHash;
805804
} catch (err) {
806-
console.log('sendTransactionForSwap error', err);
807805
const error = err as TransactionError;
808806
state.transactionError = error?.shortMessage;
809807
state.loadingTransaction = false;

packages/core/src/utils/ConstantsUtil.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ export const ConstantsUtil = {
135135
'WNT'
136136
],
137137

138+
//TODO: replace with supported chains from backend
138139
ACTIVITY_SUPPORTED_CHAINS: [
139140
// Arbitrum
140141
'eip155:42161',

packages/ui/src/utils/UiUtil.ts

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -71,20 +71,18 @@ export const UiUtil = {
7171
},
7272

7373
formatNumberToLocalString(value: string | number | undefined, decimals = 2) {
74-
if (value === undefined) {
75-
return '0.00';
76-
}
74+
let numericValue: number;
7775

78-
if (typeof value === 'number') {
79-
return value.toLocaleString('en-US', {
80-
maximumFractionDigits: decimals,
81-
minimumFractionDigits: decimals
82-
});
76+
if (value === undefined) {
77+
numericValue = 0;
78+
} else if (typeof value === 'string') {
79+
numericValue = parseFloat(value);
80+
} else {
81+
numericValue = value;
8382
}
8483

85-
return parseFloat(value).toLocaleString('en-US', {
86-
maximumFractionDigits: decimals,
87-
minimumFractionDigits: decimals
84+
return numericValue.toLocaleString('en-US', {
85+
maximumFractionDigits: decimals
8886
});
8987
}
9088
};

0 commit comments

Comments
 (0)