diff --git a/.changeset/moody-plums-sniff.md b/.changeset/moody-plums-sniff.md new file mode 100644 index 000000000..76168737f --- /dev/null +++ b/.changeset/moody-plums-sniff.md @@ -0,0 +1,5 @@ +--- +'@xchainjs/xchain-cosmos-sdk': patch +--- + +Return balances including native and those that are 0 diff --git a/.changeset/red-dogs-hug.md b/.changeset/red-dogs-hug.md new file mode 100644 index 000000000..fa03d8ef5 --- /dev/null +++ b/.changeset/red-dogs-hug.md @@ -0,0 +1,5 @@ +--- +'@xchainjs/xchain-evm-providers': patch +--- + +Return balances including native and those that are 0 diff --git a/.changeset/small-beds-allow.md b/.changeset/small-beds-allow.md new file mode 100644 index 000000000..584bf5952 --- /dev/null +++ b/.changeset/small-beds-allow.md @@ -0,0 +1,5 @@ +--- +'@xchainjs/xchain-evm': patch +--- + +Change type in roundRobinGetBalance to TokenAsset diff --git a/packages/xchain-base/__e2e__/base.e2e.ts b/packages/xchain-base/__e2e__/base.e2e.ts index 75a6b512a..41da3bbd3 100644 --- a/packages/xchain-base/__e2e__/base.e2e.ts +++ b/packages/xchain-base/__e2e__/base.e2e.ts @@ -1,5 +1,12 @@ import { Balance, FeeOption, Network, TxType } from '@xchainjs/xchain-client' -import { AssetType, TokenAsset, assetAmount, assetToBase, assetToString } from '@xchainjs/xchain-util' +import { + AssetType, + TokenAsset, + assetAmount, + assetFromStringEx, + assetToBase, + assetToString, +} from '@xchainjs/xchain-util' import { BASEChain, defaultBaseParams } from '../src/const' import { Client as BaseClient } from '../src/index' @@ -33,7 +40,15 @@ describe('Base', () => { it('should fetch Base balances', async () => { const address = testnetClient.getAddress(0) console.log(address) - const balances = await testnetClient.getBalance(address) + const balances = await testnetClient.getBalance('0x585142ebBA458B681caea61Bb178E529EdAd23f4') + balances.forEach((bal: Balance) => { + console.log(`${assetToString(bal.asset)} = ${bal.amount.amount()}`) + }) + }) + it('should fetch filter balances', async () => { + const balances = await testnetClient.getBalance('0x585142ebBA458B681caea61Bb178E529EdAd23f4', [ + assetFromStringEx('BASE.WETH-0x4200000000000000000000000000000000000006') as TokenAsset, + ]) balances.forEach((bal: Balance) => { console.log(`${assetToString(bal.asset)} = ${bal.amount.amount()}`) }) diff --git a/packages/xchain-cosmos-sdk/src/client.ts b/packages/xchain-cosmos-sdk/src/client.ts index bdf2b5118..be20a272a 100644 --- a/packages/xchain-cosmos-sdk/src/client.ts +++ b/packages/xchain-cosmos-sdk/src/client.ts @@ -273,18 +273,19 @@ export default abstract class Client extends BaseXChainClient implements XChainC * @param {Asset[] | undefined} _assets An array of assets. Ignored in this implementation. * @returns {Balance[]} A promise that resolves to an array of balances. */ - public async getBalance(address: string, _assets?: CompatibleAsset[]): Promise { - const result = await this.roundRobinGetBalance(address) - // TODO: Filter using assets + public async getBalance(address: string, assets?: CompatibleAsset[]): Promise { + const results = await this.roundRobinGetBalance(address) const balances: Balance[] = [] - result.forEach((balance) => { - const asset = this.assetFromDenom(balance.denom) - if (asset) { - balances.push({ - asset, - amount: baseAmount(balance.amount, this.getAssetDecimals(asset)), - }) - } + const nativeAssetInfo = this.getAssetInfo() + + const allAssets = [nativeAssetInfo.asset, ...(assets || [])] + + allAssets.forEach((asset) => { + const assetBalance = results.find((result) => result.denom === this.getDenom(asset)) + balances.push({ + asset, + amount: baseAmount(assetBalance?.amount || 0, this.getAssetDecimals(asset)), + }) }) return balances } diff --git a/packages/xchain-evm-providers/src/providers/covalent/covalent-data-provider.ts b/packages/xchain-evm-providers/src/providers/covalent/covalent-data-provider.ts index e393106df..deefe5c2e 100644 --- a/packages/xchain-evm-providers/src/providers/covalent/covalent-data-provider.ts +++ b/packages/xchain-evm-providers/src/providers/covalent/covalent-data-provider.ts @@ -74,7 +74,7 @@ export class CovalentProvider implements EvmOnlineDataProvider { if (assets) { finalBalances = balances.filter((balance) => { - return assets.some((asset) => asset.symbol === balance.asset.symbol) + return assets.some((asset) => asset.symbol === balance.asset.symbol || asset.type === AssetType.NATIVE) }) } diff --git a/packages/xchain-evm-providers/src/providers/etherscan/etherscan-data-provider.ts b/packages/xchain-evm-providers/src/providers/etherscan/etherscan-data-provider.ts index 0ca72f90e..ad41ac181 100644 --- a/packages/xchain-evm-providers/src/providers/etherscan/etherscan-data-provider.ts +++ b/packages/xchain-evm-providers/src/providers/etherscan/etherscan-data-provider.ts @@ -44,28 +44,22 @@ export class EtherscanProvider implements EvmOnlineDataProvider { this.nativeAsset this.chain } - async getBalance(address: Address, assets?: CompatibleAsset[]): Promise { //validate assets are for the correct chain assets?.forEach((i) => { if (i.chain !== this.chain) throw Error(`${assetToString(i)} is not an asset of ${this.chain}`) }) const balances: Balance[] = [] + balances.push(await this.getNativeAssetBalance(address)) if (assets) { for (const asset of assets) { - if (asset.symbol === this.nativeAsset.symbol) { - balances.push(await this.getNativeAssetBalance(address)) - } else { - const splitSymbol = asset.symbol.split('-') - const tokenSymbol = splitSymbol[0] - const contractAddress = splitSymbol[1] - balances.push(await this.getTokenBalance(address, contractAddress, tokenSymbol)) - } + const splitSymbol = asset.symbol.split('-') + const tokenSymbol = splitSymbol[0] + const contractAddress = splitSymbol[1] + balances.push(await this.getTokenBalance(address, contractAddress, tokenSymbol)) } } else { - //get nativeAsset - balances.push(await this.getNativeAssetBalance(address)) // Get All Erc-20 txs const response = ( await axios.get( @@ -112,6 +106,7 @@ export class EtherscanProvider implements EvmOnlineDataProvider { amount, } } + private getUniqueContractAddresses(array: ERC20Tx[]): ERC20Tx[] { const mySet = new Set() return array.filter((x) => { diff --git a/packages/xchain-evm/src/clients/client.ts b/packages/xchain-evm/src/clients/client.ts index 6f0893d7a..756e48af2 100644 --- a/packages/xchain-evm/src/clients/client.ts +++ b/packages/xchain-evm/src/clients/client.ts @@ -17,7 +17,16 @@ import { standardFeeRates, } from '@xchainjs/xchain-client' import { EvmOnlineDataProviders } from '@xchainjs/xchain-evm-providers' -import { Address, Asset, CachedValue, Chain, assetToString, baseAmount, eqAsset } from '@xchainjs/xchain-util' +import { + Address, + Asset, + CachedValue, + Chain, + TokenAsset, + assetToString, + baseAmount, + eqAsset, +} from '@xchainjs/xchain-util' import { BigNumber, ethers } from 'ethers' import { toUtf8Bytes } from 'ethers/lib/utils' @@ -197,7 +206,7 @@ export class Client extends BaseXChainClient implements EVMClient { * @returns {Promise} An array containing the balance of the address. * @throws {"Invalid asset"} Thrown when the provided asset is invalid. */ - async getBalance(address: Address, assets?: Asset[]): Promise { + async getBalance(address: Address, assets?: TokenAsset[]): Promise { return await this.roundRobinGetBalance(address, assets) } @@ -481,7 +490,7 @@ export class Client extends BaseXChainClient implements EVMClient { * @returns {Promise} The balance information for the address. * @throws Error Thrown if no provider is able to retrieve the balance. */ - protected async roundRobinGetBalance(address: Address, assets?: Asset[]) { + protected async roundRobinGetBalance(address: Address, assets?: TokenAsset[]) { for (const provider of this.config.dataProviders) { try { const prov = provider[this.network]