Skip to content

Commit

Permalink
WT-1971 - allow get balances without connected provider (#1296)
Browse files Browse the repository at this point in the history
Co-authored-by: Deepti Luthra <[email protected]>
  • Loading branch information
andrearampin and deepti-imx authored Dec 19, 2023
1 parent 1d6575b commit 4e3caa8
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 17 deletions.
44 changes: 44 additions & 0 deletions packages/checkout/sdk/src/balances/balances.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,50 @@ describe('balances', () => {
});
});

it('should fail if no wallet address or provider are given', async () => {
let message;
try {
await getAllBalances(
{
remote: {
getTokensConfig: () => ({
blockscout: false,
}),
},
networkMap: testCheckoutConfig.networkMap,
} as unknown as CheckoutConfiguration,
undefined,
undefined,
ChainId.ETHEREUM,
);
} catch (e: any) {
message = e.message;
}
expect(message).toContain('both walletAddress and provider are missing');
});

it('should fail if no provider is given and indexer is disabled', async () => {
let message;
try {
await getAllBalances(
{
remote: {
getTokensConfig: () => ({
blockscout: false,
}),
},
networkMap: testCheckoutConfig.networkMap,
} as unknown as CheckoutConfiguration,
undefined,
'wallet-address',
ChainId.ETHEREUM,
);
} catch (e: any) {
message = e.message;
}
expect(message).toContain('indexer is disabled for this chain, you must provide a provider');
});

it('should call getBalance and getERC20Balance functions with native and ERC20 tokens', async () => {
const getAllBalancesResult = await getAllBalances(
{
Expand Down
28 changes: 21 additions & 7 deletions packages/checkout/sdk/src/balances/balances.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,12 +238,16 @@ export const getBalances = async (

export const getAllBalances = async (
config: CheckoutConfiguration,
web3Provider: Web3Provider,
walletAddress: string,
chainId?: ChainId,
web3Provider: Web3Provider | undefined,
walletAddress: string | undefined,
chainId: ChainId,
): Promise<GetAllBalancesResult> => {
// eslint-disable-next-line no-param-reassign
chainId ||= await web3Provider.getSigner().getChainId();
if (!walletAddress && !web3Provider) {
throw new CheckoutError(
'both walletAddress and provider are missing. At least one must be provided.',
CheckoutErrorType.MISSING_PARAMS,
);
}

const { tokens } = await getTokenAllowList(
config,
Expand All @@ -264,26 +268,36 @@ export const getAllBalances = async (
console.error(err);
}

let address = walletAddress;
if (flag && Blockscout.isChainSupported(chainId)) {
// This is a hack because the widgets are still using the tokens symbol
// to drive the conversions. If we remove all the token symbols from e.g. zkevm
// then we would not have fiat conversions.
// Please remove this hack once https://immutable.atlassian.net/browse/WT-1710
// is done.
const isL1Chain = getL1ChainId(config) === chainId;
if (!address) address = await web3Provider?.getSigner().getAddress();
return await measureAsyncExecution<GetAllBalancesResult>(
config,
`Time to fetch balances using blockscout for ${chainId}`,
getIndexerBalance(walletAddress, chainId, isL1Chain ? tokens : undefined),
getIndexerBalance(address!, chainId, isL1Chain ? tokens : undefined),
);
}

if (!web3Provider) {
throw new CheckoutError(
'indexer is disabled for this chain, you must provide a provider.',
CheckoutErrorType.MISSING_PARAMS,
);
}

// This fallback to use ERC20s calls which is a best effort solution
// Fails in fetching data from the RCP calls might result in some
// missing data.
address ||= await web3Provider.getSigner().getAddress();
return await measureAsyncExecution<GetBalancesResult>(
config,
`Time to fetch balances using RPC for ${chainId}`,
getBalances(config, web3Provider, walletAddress, tokens),
getBalances(config, web3Provider, address, tokens),
);
};
1 change: 1 addition & 0 deletions packages/checkout/sdk/src/errors/checkoutError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* Enum representing different types of errors that can occur during the checkout process.
*/
export enum CheckoutErrorType {
MISSING_PARAMS = 'MISSING_PARAMS',
WEB3_PROVIDER_ERROR = 'WEB3_PROVIDER_ERROR',
PROVIDER_ERROR = 'PROVIDER_ERROR',
DEFAULT_PROVIDER_ERROR = 'DEFAULT_PROVIDER_ERROR',
Expand Down
7 changes: 1 addition & 6 deletions packages/checkout/sdk/src/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,14 +251,9 @@ export class Checkout {
public async getAllBalances(
params: GetAllBalancesParams,
): Promise<GetAllBalancesResult> {
const web3Provider = await provider.validateProvider(
this.config,
params.provider,
);

return balances.getAllBalances(
this.config,
web3Provider,
params.provider,
params.walletAddress,
params.chainId,
);
Expand Down
8 changes: 4 additions & 4 deletions packages/checkout/sdk/src/types/balances.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ export interface GetBalanceResult {

/**
* Interface representing the parameters for {@link Checkout.getAllBalances}.
* @property {Web3Provider} provider - The provider used to get the balances.
* @property {string} walletAddress - The wallet address.
* @property {Web3Provider} provider - The provider used to get the balances, it is a required parameter if no walletAddress is provided.
* @property {string} walletAddress - The wallet address, it is a required parameter if no provider is provided.
* @property {ChainId} chainId - The ID of the network.
*/
export interface GetAllBalancesParams {
provider: Web3Provider;
walletAddress: string;
provider?: Web3Provider;
walletAddress?: string;
chainId: ChainId;
}

Expand Down

0 comments on commit 4e3caa8

Please sign in to comment.