Skip to content

Commit 488dceb

Browse files
fix(checkout-widgets): resolve checkout stuck in Crunching Numbers when paying with IMX (Issue 3)
When fetching funding balances for native tokens (e.g. tIMX on zkEVM), the primary-sales API returns zero address. The code used ERC20ItemRequirement which calls getTokenContract().decimals() and fails for non-contract addresses, causing CheckoutError and leaving the widget stuck in loading. Use NativeItemRequirement for native tokens instead of ERC20ItemRequirement.
1 parent 9cb8149 commit 488dceb

4 files changed

Lines changed: 23 additions & 7 deletions

File tree

packages/checkout/widgets-lib/src/lib/utils.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,10 @@ describe('utils', () => {
535535
expect(isNativeToken('NATIVE')).toBeTruthy();
536536
});
537537

538+
it('should return true if address is zero address (used by some APIs for native token)', () => {
539+
expect(isNativeToken('0x0000000000000000000000000000000000000000')).toBeTruthy();
540+
});
541+
538542
it('should return false if address is not NATIVE', () => {
539543
expect(isNativeToken('0x123')).toBeFalsy();
540544
});

packages/checkout/widgets-lib/src/lib/utils.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,14 @@ export const isZkEvmChainId = (chainId: ChainId) => chainId === ChainId.IMTBL_ZK
183183
export const isL1EthChainId = (chainId: ChainId) => chainId === ChainId.SEPOLIA
184184
|| chainId === ChainId.ETHEREUM;
185185

186+
/** Zero address used by some APIs (e.g. primary-sales) to denote native token (e.g. tIMX on zkEVM) */
187+
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
188+
186189
export const isNativeToken = (
187190
address: string | undefined,
188-
): boolean => !address || address.toLocaleLowerCase() === NATIVE;
191+
): boolean => !address
192+
|| address.toLocaleLowerCase() === NATIVE
193+
|| address.toLocaleLowerCase() === ZERO_ADDRESS;
189194

190195
export function getRemoteImage(environment: Environment | undefined, path: string) {
191196
return `${CHECKOUT_CDN_BASE_URL[environment ?? Environment.PRODUCTION]}/v1/blob/img${path}`;

packages/checkout/widgets-lib/src/widgets/sale/functions/fetchFundingBalances.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import {
22
Checkout, ItemBalance, WrappedBrowserProvider, TokenBalance, TransactionRequirement,
33
} from '@imtbl/checkout-sdk';
44
import { Environment } from '@imtbl/config';
5-
import { compareStr } from '../../../lib/utils';
5+
import { compareStr, isNativeToken } from '../../../lib/utils';
66
import {
77
OrderQuoteCurrency,
88
FundingBalance,
@@ -11,6 +11,7 @@ import {
1111
import {
1212
getAlternativeFundingSteps,
1313
getERC20ItemRequirement,
14+
getNativeItemRequirement,
1415
getFnToPushAndSortFundingBalances,
1516
getFundingBalances,
1617
getGasEstimate,
@@ -75,11 +76,9 @@ export const fetchFundingBalances = async (
7576
return null;
7677
}
7778

78-
const itemRequirements = getERC20ItemRequirement(
79-
amount,
80-
spenderAddress,
81-
currency.address,
82-
);
79+
const itemRequirements = isNativeToken(currency.address)
80+
? getNativeItemRequirement(amount)
81+
: getERC20ItemRequirement(amount, spenderAddress, currency.address);
8382

8483
const transactionOrGasAmount = getIsGasless()
8584
? undefined

packages/checkout/widgets-lib/src/widgets/sale/functions/fetchFundingBalancesUtils.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
TransactionOrGasType,
88
TokenInfo,
99
ERC20ItemRequirement,
10+
NativeItemRequirement,
1011
FundingRoute,
1112
RoutingOutcomeType,
1213
FundingStep,
@@ -41,6 +42,13 @@ export const getERC20ItemRequirement = (
4142
},
4243
];
4344

45+
export const getNativeItemRequirement = (amount: string): NativeItemRequirement[] => [
46+
{
47+
type: ItemType.NATIVE,
48+
amount,
49+
},
50+
];
51+
4452
export const getGasEstimate = (): GasAmount => ({
4553
type: TransactionOrGasType.GAS,
4654
gasToken: {

0 commit comments

Comments
 (0)