From de4d8083b1fad70ff0ff34a2729ac041b6245814 Mon Sep 17 00:00:00 2001 From: Sebastian Pape Date: Fri, 28 Oct 2022 18:28:48 +0200 Subject: [PATCH] v6.6.0: evm package --- .github/workflows/publish-evm.yml | 28 + dist/esm/index.evm.js | 197 ++++++ dist/umd/index.evm.js | 203 ++++++ package.evm.json | 38 ++ package.json | 23 +- rollup.globals.js | 3 +- rollup.module.evm.config.js | 45 ++ src/dripAssets.evm.js | 115 ++++ src/getAssets.evm.js | 82 +++ src/index.evm.js | 7 + tests/units/dripAssets.evm.spec.js | 965 +++++++++++++++++++++++++++++ tests/units/getAssets.evm.spec.js | 455 ++++++++++++++ yarn.lock | 36 +- 13 files changed, 2177 insertions(+), 20 deletions(-) create mode 100644 .github/workflows/publish-evm.yml create mode 100644 dist/esm/index.evm.js create mode 100644 dist/umd/index.evm.js create mode 100644 package.evm.json create mode 100644 rollup.module.evm.config.js create mode 100644 src/dripAssets.evm.js create mode 100644 src/getAssets.evm.js create mode 100644 src/index.evm.js create mode 100644 tests/units/dripAssets.evm.spec.js create mode 100644 tests/units/getAssets.evm.spec.js diff --git a/.github/workflows/publish-evm.yml b/.github/workflows/publish-evm.yml new file mode 100644 index 0000000..c25a25d --- /dev/null +++ b/.github/workflows/publish-evm.yml @@ -0,0 +1,28 @@ +name: Publish EVM + +on: + release: + types: [created] + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + # Setup .npmrc file to publish to npm + - uses: actions/setup-node@v2 + with: + node-version: '16.x' + registry-url: 'https://registry.npmjs.org' + + - run: mv package.evm.json package.json + + - run: yarn install + + - name: get-npm-version + id: package-version + uses: martinbeentjes/npm-get-version-action@master + + - run: npm publish --access public + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTOMATION_TOKEN }} diff --git a/dist/esm/index.evm.js b/dist/esm/index.evm.js new file mode 100644 index 0000000..0d480d0 --- /dev/null +++ b/dist/esm/index.evm.js @@ -0,0 +1,197 @@ +import { CONSTANTS } from '@depay/web3-constants'; +import { request } from '@depay/web3-client-evm'; +import { Blockchain } from '@depay/web3-blockchains'; +import { Token } from '@depay/web3-tokens-evm'; + +const ensureNativeTokenAsset = async ({ address, options, assets, blockchain }) => { + if(options.only && options.only[blockchain] && !options.only[blockchain].find((only)=>(only.toLowerCase() == CONSTANTS[blockchain].NATIVE.toLowerCase()))){ return assets } + if(options.exclude && options.exclude[blockchain] && !!options.exclude[blockchain].find((exclude)=>(exclude.toLowerCase() == CONSTANTS[blockchain].NATIVE.toLowerCase()))){ return assets } + + const nativeTokenMissing = !assets.find((asset)=>(asset.address.toLowerCase() == CONSTANTS[blockchain].NATIVE.toLowerCase())); + if(nativeTokenMissing) { + let balance = await request( + { + blockchain: blockchain, + address, + method: 'balance', + }, + { cache: 30000 } + ); + assets = [{ + name: CONSTANTS[blockchain].CURRENCY, + symbol: CONSTANTS[blockchain].SYMBOL, + address: CONSTANTS[blockchain].NATIVE, + type: 'NATIVE', + blockchain, + balance: balance.toString() + }, ...assets]; + } + return assets +}; + +const filterAssets = ({ assets, blockchain, options })=>{ + if(options.only) { + return assets.filter((asset)=>{ + return (options.only[blockchain] || []).find((onlyAsset)=>(onlyAsset.toLowerCase() == asset.address.toLowerCase())) + }) + } else if(options.exclude) { + return assets.filter((asset)=>{ + return (options.exclude[blockchain] || []).find((excludeAsset)=>(excludeAsset.toLowerCase() != asset.address.toLowerCase())) + }) + } else { + return assets + } +}; + +var getAssets = async (options) => { + if(options === undefined) { options = { accounts: {} }; } + + let assets = Promise.all( + (Object.keys(options.accounts)).map((blockchain) =>{ + + return new Promise((resolve, reject)=>{ + const address = options.accounts[blockchain]; + const controller = new AbortController(); + setTimeout(()=>controller.abort(), 10000); + fetch(`https://public.depay.com/accounts/${blockchain}/${address}/assets`, { signal: controller.signal }) + .catch((error) => { console.log(error); resolve([]); }) + .then((response) => { + if(response && response.ok) { + return response.json() + } else { + resolve([]); + } + }) + .then(async (assets) => { + if(assets && assets.length) { + return await ensureNativeTokenAsset({ + address, + options, + assets: filterAssets({ assets, blockchain, options }).map((asset) => Object.assign(asset, { blockchain })), + blockchain + }) + } else { + resolve([]); + } + }) + .then(resolve) + .catch((error) => { console.log(error); resolve([]); }); + }) + }), + ).then((responses) => responses.flat()); + + return assets +}; + +const reduceAssetWithBalance = (asset, balance)=>{ + return Object.assign({}, { + address: asset.address, + symbol: asset.symbol, + name: asset.name, + decimals: asset.decimals, + type: asset.type, + blockchain: asset.blockchain + }, { balance: balance.toString() }) +}; + +const exists = ({ assets, asset })=> { + return !!assets.find(element => element.blockchain == asset.blockchain && element.address.toLowerCase() == asset.address.toLowerCase()) +}; + +const isFiltered = ({ options, address, blockchain })=> { + if(options && options.only && options.only[blockchain] && !options.only[blockchain].find((only)=>only.toLowerCase()==address.toLowerCase())){ + return true + } + if(options && options.exclude && options.exclude[blockchain] && options.exclude[blockchain].find((only)=>only.toLowerCase()==address.toLowerCase())){ + return true + } + return false +}; + +var dripAssets_evm = async (options) => { + if(options === undefined) { options = { accounts: {}, priority: [] }; } + + let assets = []; + let promises = []; + + // Prioritized Assets + + promises = promises.concat((options.priority || []).map((asset)=>{ + return new Promise(async (resolve, reject)=>{ + try { + let token = new Token(asset); + let completedAsset = Object.assign({}, + asset, + { + name: await token.name(), + symbol: await token.symbol(), + decimals: await token.decimals(), + balance: (await token.balance(options.accounts[asset.blockchain])).toString() + } + ); + if(completedAsset.balance != '0') { + if(exists({ assets, asset })) { return resolve() } + assets.push(completedAsset); + if(typeof options.drip == 'function') { options.drip(completedAsset); } + resolve(completedAsset); + } else { + resolve(); + } + } catch (e) { + resolve(); + } + }) + })); + + // Major Tokens + + let majorTokens = []; + for (var blockchain in options.accounts){ + Blockchain.findByName(blockchain).tokens.forEach((token)=>{ + if(isFiltered({ options, address: token.address, blockchain })){ return } + majorTokens.push(Object.assign({}, token, { blockchain })); + }); + } + promises = promises.concat((majorTokens.map((asset)=>{ + return new Promise((resolve, reject)=>{ + new Token(asset).balance(options.accounts[asset.blockchain]) + .then((balance)=>{ + if(exists({ assets, asset })) { return resolve() } + const assetWithBalance = reduceAssetWithBalance(asset, balance); + if(assetWithBalance.balance != '0') { + assets.push(assetWithBalance); + if(typeof options.drip == 'function') { options.drip(assetWithBalance); } + resolve(assetWithBalance); + } else { + resolve(); + }}).catch((error)=>{ console.log(error); resolve(); }); + }) + }))); + + // All other assets + + if(options.only == undefined || Object.keys(options.only).every((list)=>list.length == 0)) { + let allAssets = await getAssets(options); + promises = promises.concat((allAssets.map((asset)=>{ + return new Promise((resolve, reject)=>{ + return new Token(asset).balance(options.accounts[asset.blockchain]) + .then((balance)=>{ + if(exists({ assets, asset })) { return resolve() } + const assetWithBalance = reduceAssetWithBalance(asset, balance); + if(assetWithBalance.balance != '0') { + assets.push(assetWithBalance); + if(typeof options.drip == 'function') { options.drip(assetWithBalance); } + resolve(assetWithBalance); + } else { + resolve(); + }}).catch((error)=>{ console.log(error); resolve(); }) + }) + }))); + } + + await Promise.all(promises); + + return assets +}; + +export { dripAssets_evm as dripAssets, getAssets }; diff --git a/dist/umd/index.evm.js b/dist/umd/index.evm.js new file mode 100644 index 0000000..948ec69 --- /dev/null +++ b/dist/umd/index.evm.js @@ -0,0 +1,203 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@depay/web3-constants'), require('@depay/web3-client-evm'), require('@depay/web3-blockchains'), require('@depay/web3-tokens-evm')) : + typeof define === 'function' && define.amd ? define(['exports', '@depay/web3-constants', '@depay/web3-client-evm', '@depay/web3-blockchains', '@depay/web3-tokens-evm'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Web3Assets = {}, global.Web3Constants, global.Web3Client, global.Web3Blockchains, global.Web3Tokens)); +}(this, (function (exports, web3Constants, web3ClientEvm, web3Blockchains, web3TokensEvm) { 'use strict'; + + const ensureNativeTokenAsset = async ({ address, options, assets, blockchain }) => { + if(options.only && options.only[blockchain] && !options.only[blockchain].find((only)=>(only.toLowerCase() == web3Constants.CONSTANTS[blockchain].NATIVE.toLowerCase()))){ return assets } + if(options.exclude && options.exclude[blockchain] && !!options.exclude[blockchain].find((exclude)=>(exclude.toLowerCase() == web3Constants.CONSTANTS[blockchain].NATIVE.toLowerCase()))){ return assets } + + const nativeTokenMissing = !assets.find((asset)=>(asset.address.toLowerCase() == web3Constants.CONSTANTS[blockchain].NATIVE.toLowerCase())); + if(nativeTokenMissing) { + let balance = await web3ClientEvm.request( + { + blockchain: blockchain, + address, + method: 'balance', + }, + { cache: 30000 } + ); + assets = [{ + name: web3Constants.CONSTANTS[blockchain].CURRENCY, + symbol: web3Constants.CONSTANTS[blockchain].SYMBOL, + address: web3Constants.CONSTANTS[blockchain].NATIVE, + type: 'NATIVE', + blockchain, + balance: balance.toString() + }, ...assets]; + } + return assets + }; + + const filterAssets = ({ assets, blockchain, options })=>{ + if(options.only) { + return assets.filter((asset)=>{ + return (options.only[blockchain] || []).find((onlyAsset)=>(onlyAsset.toLowerCase() == asset.address.toLowerCase())) + }) + } else if(options.exclude) { + return assets.filter((asset)=>{ + return (options.exclude[blockchain] || []).find((excludeAsset)=>(excludeAsset.toLowerCase() != asset.address.toLowerCase())) + }) + } else { + return assets + } + }; + + var getAssets = async (options) => { + if(options === undefined) { options = { accounts: {} }; } + + let assets = Promise.all( + (Object.keys(options.accounts)).map((blockchain) =>{ + + return new Promise((resolve, reject)=>{ + const address = options.accounts[blockchain]; + const controller = new AbortController(); + setTimeout(()=>controller.abort(), 10000); + fetch(`https://public.depay.com/accounts/${blockchain}/${address}/assets`, { signal: controller.signal }) + .catch((error) => { console.log(error); resolve([]); }) + .then((response) => { + if(response && response.ok) { + return response.json() + } else { + resolve([]); + } + }) + .then(async (assets) => { + if(assets && assets.length) { + return await ensureNativeTokenAsset({ + address, + options, + assets: filterAssets({ assets, blockchain, options }).map((asset) => Object.assign(asset, { blockchain })), + blockchain + }) + } else { + resolve([]); + } + }) + .then(resolve) + .catch((error) => { console.log(error); resolve([]); }); + }) + }), + ).then((responses) => responses.flat()); + + return assets + }; + + const reduceAssetWithBalance = (asset, balance)=>{ + return Object.assign({}, { + address: asset.address, + symbol: asset.symbol, + name: asset.name, + decimals: asset.decimals, + type: asset.type, + blockchain: asset.blockchain + }, { balance: balance.toString() }) + }; + + const exists = ({ assets, asset })=> { + return !!assets.find(element => element.blockchain == asset.blockchain && element.address.toLowerCase() == asset.address.toLowerCase()) + }; + + const isFiltered = ({ options, address, blockchain })=> { + if(options && options.only && options.only[blockchain] && !options.only[blockchain].find((only)=>only.toLowerCase()==address.toLowerCase())){ + return true + } + if(options && options.exclude && options.exclude[blockchain] && options.exclude[blockchain].find((only)=>only.toLowerCase()==address.toLowerCase())){ + return true + } + return false + }; + + var dripAssets_evm = async (options) => { + if(options === undefined) { options = { accounts: {}, priority: [] }; } + + let assets = []; + let promises = []; + + // Prioritized Assets + + promises = promises.concat((options.priority || []).map((asset)=>{ + return new Promise(async (resolve, reject)=>{ + try { + let token = new web3TokensEvm.Token(asset); + let completedAsset = Object.assign({}, + asset, + { + name: await token.name(), + symbol: await token.symbol(), + decimals: await token.decimals(), + balance: (await token.balance(options.accounts[asset.blockchain])).toString() + } + ); + if(completedAsset.balance != '0') { + if(exists({ assets, asset })) { return resolve() } + assets.push(completedAsset); + if(typeof options.drip == 'function') { options.drip(completedAsset); } + resolve(completedAsset); + } else { + resolve(); + } + } catch (e) { + resolve(); + } + }) + })); + + // Major Tokens + + let majorTokens = []; + for (var blockchain in options.accounts){ + web3Blockchains.Blockchain.findByName(blockchain).tokens.forEach((token)=>{ + if(isFiltered({ options, address: token.address, blockchain })){ return } + majorTokens.push(Object.assign({}, token, { blockchain })); + }); + } + promises = promises.concat((majorTokens.map((asset)=>{ + return new Promise((resolve, reject)=>{ + new web3TokensEvm.Token(asset).balance(options.accounts[asset.blockchain]) + .then((balance)=>{ + if(exists({ assets, asset })) { return resolve() } + const assetWithBalance = reduceAssetWithBalance(asset, balance); + if(assetWithBalance.balance != '0') { + assets.push(assetWithBalance); + if(typeof options.drip == 'function') { options.drip(assetWithBalance); } + resolve(assetWithBalance); + } else { + resolve(); + }}).catch((error)=>{ console.log(error); resolve(); }); + }) + }))); + + // All other assets + + if(options.only == undefined || Object.keys(options.only).every((list)=>list.length == 0)) { + let allAssets = await getAssets(options); + promises = promises.concat((allAssets.map((asset)=>{ + return new Promise((resolve, reject)=>{ + return new web3TokensEvm.Token(asset).balance(options.accounts[asset.blockchain]) + .then((balance)=>{ + if(exists({ assets, asset })) { return resolve() } + const assetWithBalance = reduceAssetWithBalance(asset, balance); + if(assetWithBalance.balance != '0') { + assets.push(assetWithBalance); + if(typeof options.drip == 'function') { options.drip(assetWithBalance); } + resolve(assetWithBalance); + } else { + resolve(); + }}).catch((error)=>{ console.log(error); resolve(); }) + }) + }))); + } + + await Promise.all(promises); + + return assets + }; + + exports.dripAssets = dripAssets_evm; + exports.getAssets = getAssets; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}))); diff --git a/package.evm.json b/package.evm.json new file mode 100644 index 0000000..80601f4 --- /dev/null +++ b/package.evm.json @@ -0,0 +1,38 @@ +{ + "name": "@depay/web3-assets-evm", + "moduleName": "Web3Assets", + "version": "6.6.0", + "description": "JavaScript library to retrieve Web3 assets of a given or connected wallet/account.", + "main": "dist/umd/index.evm.js", + "module": "dist/esm/index.evm.js", + "source": "src/index.evm.js", + "files": [ + "dist" + ], + "repository": "git@github.com:DePayFi/web3-assets.git", + "keywords": [ + "web3", + "assets", + "tokens", + "crypto", + "blockchain" + ], + "author": "depay.com", + "license": "MIT", + "bugs": { + "url": "https://github.com/DePayFi/web3-assets/issues" + }, + "homepage": "https://depay.com", + "private": false, + "dependencies": {}, + "peerDependencies": { + "@depay/solana-web3.js": "^1.19.0", + "@depay/web3-blockchains": "^6.2.3", + "@depay/web3-client-evm": "^10.1.22", + "@depay/web3-constants": "^6.3.2", + "@depay/web3-tokens-evm": "^9.12.6" + }, + "engines": { + "node": ">=16" + } +} diff --git a/package.json b/package.json index 46ddee6..a91ab2e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@depay/web3-assets", "moduleName": "Web3Assets", - "version": "6.5.4", + "version": "6.6.0", "description": "JavaScript library to retrieve Web3 assets of a given or connected wallet/account.", "main": "dist/umd/index.js", "module": "dist/esm/index.js", @@ -10,10 +10,9 @@ "dist" ], "scripts": { - "build": "rm -rf dist && rollup -c rollup.module.config.js", + "build": "rm -rf dist && rollup -c rollup.module.config.js && rollup -c rollup.module.evm.config.js", "lint": "eslint \"src/**/*.{js,jsx,ts,tsx}\"", "lint:fix": "eslint \"src/**/*.{js,jsx,ts,tsx}\" --fix", - "prepublishOnly": "yarn build", "dev": "rollup -c rollup.dev.config.js -w", "test:units": "yarn build && npx jest --no-cache", "test": "yarn test:units" @@ -36,10 +35,10 @@ "dependencies": {}, "peerDependencies": { "@depay/solana-web3.js": "^1.19.0", - "@depay/web3-blockchains": "^6.2.0", - "@depay/web3-client": "^10.1.7", - "@depay/web3-constants": "^6.3.1", - "@depay/web3-tokens": "^9.11.4" + "@depay/web3-blockchains": "^6.2.3", + "@depay/web3-client": "^10.1.22", + "@depay/web3-constants": "^6.3.2", + "@depay/web3-tokens": "^9.12.6" }, "engines": { "node": ">=16" @@ -48,11 +47,13 @@ "@babel/core": "^7.12.9", "@babel/preset-env": "^7.12.7", "@depay/solana-web3.js": "^1.19.0", - "@depay/web3-blockchains": "^6.2.0", - "@depay/web3-client": "^10.1.7", - "@depay/web3-constants": "^6.3.1", + "@depay/web3-blockchains": "^6.2.3", + "@depay/web3-client": "^10.1.22", + "@depay/web3-client-evm": "^10.1.22", + "@depay/web3-constants": "^6.3.2", "@depay/web3-mock": "^13.22.4", - "@depay/web3-tokens": "^9.11.4", + "@depay/web3-tokens": "^9.12.6", + "@depay/web3-tokens-evm": "^9.12.6", "@rollup/plugin-commonjs": "^18.0.0", "@rollup/plugin-node-resolve": "^11.2.1", "@rollup/plugin-replace": "^2.4.2", diff --git a/rollup.globals.js b/rollup.globals.js index 7353609..53f238f 100644 --- a/rollup.globals.js +++ b/rollup.globals.js @@ -2,7 +2,8 @@ export default { '@depay/walletconnect': 'WalletConnect', '@depay/web3-blockchains': 'Web3Blockchains', '@depay/web3-client': 'Web3Client', + '@depay/web3-client-evm': 'Web3Client', '@depay/web3-constants': 'Web3Constants', '@depay/web3-tokens': 'Web3Tokens', - '@depay/web3-wallets': 'Web3Wallets', + '@depay/web3-tokens-evm': 'Web3Tokens', } diff --git a/rollup.module.evm.config.js b/rollup.module.evm.config.js new file mode 100644 index 0000000..89b31ed --- /dev/null +++ b/rollup.module.evm.config.js @@ -0,0 +1,45 @@ +import commonjs from '@rollup/plugin-commonjs' +import globals from './rollup.globals.js' +import pkg from './package.evm.json' +import replace from '@rollup/plugin-replace' +import resolve from '@rollup/plugin-node-resolve' +import sucrase from '@rollup/plugin-sucrase' +import { nodeResolve } from '@rollup/plugin-node-resolve' + +export default { + input: 'src/index.evm.js', + output: [ + { + format: 'es', + globals: globals, + file: 'dist/esm/index.evm.js' + }, + { + format: 'umd', + name: pkg.moduleName, + globals: globals, + file: 'dist/umd/index.evm.js' + }, + ], + external: [ + ...Object.keys(pkg.dependencies || {}), + ...Object.keys(pkg.peerDependencies || {}), + ], + plugins: [ + sucrase({ + exclude: ['node_modules/**'], + transforms: ['jsx'] + }), + resolve({ + extensions: ['.js', '.jsx'] + }), + nodeResolve(), + commonjs({ + include: 'node_modules/**' + }), + replace({ + 'process.env.NODE_ENV': JSON.stringify( 'production' ), + preventAssignment: true + }) + ] +} diff --git a/src/dripAssets.evm.js b/src/dripAssets.evm.js new file mode 100644 index 0000000..8a6cfd1 --- /dev/null +++ b/src/dripAssets.evm.js @@ -0,0 +1,115 @@ +import getAssets from './getAssets.evm' +import { Blockchain } from '@depay/web3-blockchains' +import { Token } from '@depay/web3-tokens-evm' + +const reduceAssetWithBalance = (asset, balance)=>{ + return Object.assign({}, { + address: asset.address, + symbol: asset.symbol, + name: asset.name, + decimals: asset.decimals, + type: asset.type, + blockchain: asset.blockchain + }, { balance: balance.toString() }) +} + +const exists = ({ assets, asset })=> { + return !!assets.find(element => element.blockchain == asset.blockchain && element.address.toLowerCase() == asset.address.toLowerCase()) +} + +const isFiltered = ({ options, address, blockchain })=> { + if(options && options.only && options.only[blockchain] && !options.only[blockchain].find((only)=>only.toLowerCase()==address.toLowerCase())){ + return true + } + if(options && options.exclude && options.exclude[blockchain] && options.exclude[blockchain].find((only)=>only.toLowerCase()==address.toLowerCase())){ + return true + } + return false +} + +export default async (options) => { + if(options === undefined) { options = { accounts: {}, priority: [] } } + + let assets = [] + let promises = [] + + // Prioritized Assets + + promises = promises.concat((options.priority || []).map((asset)=>{ + return new Promise(async (resolve, reject)=>{ + try { + let token = new Token(asset) + let completedAsset = Object.assign({}, + asset, + { + name: await token.name(), + symbol: await token.symbol(), + decimals: await token.decimals(), + balance: (await token.balance(options.accounts[asset.blockchain])).toString() + } + ) + if(completedAsset.balance != '0') { + if(exists({ assets, asset })) { return resolve() } + assets.push(completedAsset) + if(typeof options.drip == 'function') { options.drip(completedAsset) } + resolve(completedAsset) + } else { + resolve() + } + } catch { + resolve() + } + }) + })) + + // Major Tokens + + let majorTokens = [] + for (var blockchain in options.accounts){ + Blockchain.findByName(blockchain).tokens.forEach((token)=>{ + if(isFiltered({ options, address: token.address, blockchain })){ return } + majorTokens.push(Object.assign({}, token, { blockchain })) + }) + } + promises = promises.concat((majorTokens.map((asset)=>{ + return new Promise((resolve, reject)=>{ + let requestOptions + new Token(asset).balance(options.accounts[asset.blockchain]) + .then((balance)=>{ + if(exists({ assets, asset })) { return resolve() } + const assetWithBalance = reduceAssetWithBalance(asset, balance) + if(assetWithBalance.balance != '0') { + assets.push(assetWithBalance) + if(typeof options.drip == 'function') { options.drip(assetWithBalance) } + resolve(assetWithBalance) + } else { + resolve() + }}).catch((error)=>{ console.log(error); resolve() }) + }) + }))) + + // All other assets + + if(options.only == undefined || Object.keys(options.only).every((list)=>list.length == 0)) { + let allAssets = await getAssets(options) + promises = promises.concat((allAssets.map((asset)=>{ + return new Promise((resolve, reject)=>{ + return new Token(asset).balance(options.accounts[asset.blockchain]) + .then((balance)=>{ + if(exists({ assets, asset })) { return resolve() } + const assetWithBalance = reduceAssetWithBalance(asset, balance) + if(assetWithBalance.balance != '0') { + assets.push(assetWithBalance) + if(typeof options.drip == 'function') { options.drip(assetWithBalance) } + resolve(assetWithBalance) + } else { + resolve() + }}).catch((error)=>{ console.log(error); resolve() }) + }) + }))) + } + + await Promise.all(promises) + + return assets +} diff --git a/src/getAssets.evm.js b/src/getAssets.evm.js new file mode 100644 index 0000000..a0dae6d --- /dev/null +++ b/src/getAssets.evm.js @@ -0,0 +1,82 @@ +import { CONSTANTS } from '@depay/web3-constants' +import { request } from '@depay/web3-client-evm' + +const ensureNativeTokenAsset = async ({ address, options, assets, blockchain }) => { + if(options.only && options.only[blockchain] && !options.only[blockchain].find((only)=>(only.toLowerCase() == CONSTANTS[blockchain].NATIVE.toLowerCase()))){ return assets } + if(options.exclude && options.exclude[blockchain] && !!options.exclude[blockchain].find((exclude)=>(exclude.toLowerCase() == CONSTANTS[blockchain].NATIVE.toLowerCase()))){ return assets } + + const nativeTokenMissing = !assets.find((asset)=>(asset.address.toLowerCase() == CONSTANTS[blockchain].NATIVE.toLowerCase())) + if(nativeTokenMissing) { + let balance = await request( + { + blockchain: blockchain, + address, + method: 'balance', + }, + { cache: 30000 } + ) + assets = [{ + name: CONSTANTS[blockchain].CURRENCY, + symbol: CONSTANTS[blockchain].SYMBOL, + address: CONSTANTS[blockchain].NATIVE, + type: 'NATIVE', + blockchain, + balance: balance.toString() + }, ...assets] + } + return assets +} + +const filterAssets = ({ assets, blockchain, options })=>{ + if(options.only) { + return assets.filter((asset)=>{ + return (options.only[blockchain] || []).find((onlyAsset)=>(onlyAsset.toLowerCase() == asset.address.toLowerCase())) + }) + } else if(options.exclude) { + return assets.filter((asset)=>{ + return (options.exclude[blockchain] || []).find((excludeAsset)=>(excludeAsset.toLowerCase() != asset.address.toLowerCase())) + }) + } else { + return assets + } +} + +export default async (options) => { + if(options === undefined) { options = { accounts: {} } } + + let assets = Promise.all( + (Object.keys(options.accounts)).map((blockchain) =>{ + + return new Promise((resolve, reject)=>{ + const address = options.accounts[blockchain] + const controller = new AbortController() + setTimeout(()=>controller.abort(), 10000) + fetch(`https://public.depay.com/accounts/${blockchain}/${address}/assets`, { signal: controller.signal }) + .catch((error) => { console.log(error); resolve([]) }) + .then((response) => { + if(response && response.ok) { + return response.json() + } else { + resolve([]) + } + }) + .then(async (assets) => { + if(assets && assets.length) { + return await ensureNativeTokenAsset({ + address, + options, + assets: filterAssets({ assets, blockchain, options }).map((asset) => Object.assign(asset, { blockchain })), + blockchain + }) + } else { + resolve([]) + } + }) + .then(resolve) + .catch((error) => { console.log(error); resolve([]) }) + }) + }), + ).then((responses) => responses.flat()) + + return assets +} diff --git a/src/index.evm.js b/src/index.evm.js new file mode 100644 index 0000000..6fb86f8 --- /dev/null +++ b/src/index.evm.js @@ -0,0 +1,7 @@ +import getAssets from './getAssets.evm' +import dripAssets from './dripAssets.evm' + +export { + getAssets, + dripAssets, +} diff --git a/tests/units/dripAssets.evm.spec.js b/tests/units/dripAssets.evm.spec.js new file mode 100644 index 0000000..042c3fe --- /dev/null +++ b/tests/units/dripAssets.evm.spec.js @@ -0,0 +1,965 @@ +import fetchMock from 'fetch-mock' +import { Blockchain } from '@depay/web3-blockchains' +import { dripAssets } from 'src/index.evm' +import { mock, resetMocks } from '@depay/web3-mock' +import { getProvider, resetCache } from '@depay/web3-client-evm' +import { Token } from '@depay/web3-tokens-evm' + +describe('dripAssets', ()=>{ + + beforeEach(()=>fetchMock.reset()) + beforeEach(resetMocks) + beforeEach(resetCache) + afterEach(resetMocks) + + const accounts = ['0xEcA533Ef096f191A35DE76aa4580FA3A722724bE'] + const blockchains = ['ethereum', 'bsc', 'polygon'] + let provider + + beforeEach(()=>{ + + blockchains.forEach(async (blockchain)=>{ + provider = await getProvider(blockchain) + mock({ accounts: { return: accounts }, provider, blockchain }) + mock({ balance: { for: accounts[0], return: '123456789' }, provider, blockchain }) + Blockchain.findByName(blockchain).tokens.forEach((token)=>{ + if(token.type == '20') { + mock({ request: { return: '123456789', to: token.address, api: Token[blockchain].DEFAULT, method: 'balanceOf', params: accounts[0] }, provider, blockchain }) + } + }) + mock({ request: { return: '56789', to: '0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb', api: Token[blockchain].DEFAULT, method: 'balanceOf', params: accounts[0] }, provider, blockchain }) + }) + + fetchMock.get({ url: `https://public.depay.com/accounts/ethereum/${accounts[0]}/assets` }, + [{ + "name": "Ether", + "symbol": "ETH", + "address": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", + "type": "NATIVE", + "balance": "1300000000000000000" + }, { + "name": "DePay", + "symbol": "DEPAY", + "address": "0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb", + "type": "20", + "balance": "1000000000000000000", + "decimals": 18 + }] + ) + + fetchMock.get({ url: `https://public.depay.com/accounts/bsc/${accounts[0]}/assets` }, + [{ + "name": "BNB Coin", + "symbol": "BNB", + "address": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", + "type": "NATIVE", + "balance": "1300000000000000000" + }, { + "name": "DePay", + "symbol": "DEPAY", + "address": "0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb", + "type": "20", + "balance": "1000000000000000000", + "decimals": 18 + }] + ) + + fetchMock.get({ url: `https://public.depay.com/accounts/polygon/${accounts[0]}/assets` }, + [{ + "name": "Matic", + "symbol": "MATIC", + "address": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", + "type": "NATIVE", + "balance": "2100000000000000000" + }, { + "name": "DePay", + "symbol": "DEPAY", + "address": "0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb", + "type": "20", + "balance": "1000000000000000000", + "decimals": 18 + }] + ) + }) + + describe('drips assets for given accounts (first all major tokens per blockchain, then all further assets)', ()=>{ + + it('drips assets one by one immediatelly after it has been found/resolved', async()=> { + let drippedAssets = [] + let dripsCount = 0 + + let allAssets = await dripAssets({ + accounts: { ethereum: accounts[0], bsc: accounts[0], polygon: accounts[0] }, + drip: (asset)=>{ + dripsCount++ + drippedAssets.push(asset) + } + }) + + expect(dripsCount).toEqual(28) + + let expectedAssets = [{ + address: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', + symbol: 'ETH', + name: 'Ether', + decimals: 18, + type: 'NATIVE', + blockchain: 'ethereum', + balance: '123456789' + }, + { + address: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', + symbol: 'BNB', + name: 'Binance Coin', + decimals: 18, + type: 'NATIVE', + blockchain: 'bsc', + balance: '123456789' + }, + { + address: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', + symbol: 'MATIC', + name: 'Polygon', + decimals: 18, + type: 'NATIVE', + blockchain: 'polygon', + balance: '123456789' + }, + { + address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', + symbol: 'WETH', + name: 'Wrapped Ether', + decimals: 18, + type: '20', + blockchain: 'ethereum', + balance: '123456789' + }, + { + address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', + symbol: 'USDC', + name: 'USD Coin', + decimals: 6, + type: '20', + blockchain: 'ethereum', + balance: '123456789' + }, + { + address: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', + symbol: 'WBTC', + name: 'Wrapped BTC', + decimals: 8, + type: '20', + blockchain: 'ethereum', + balance: '123456789' + }, + { + address: '0xdAC17F958D2ee523a2206206994597C13D831ec7', + symbol: 'USDT', + name: 'Tether USD', + decimals: 6, + type: '20', + blockchain: 'ethereum', + balance: '123456789' + }, + { + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + symbol: 'DAI', + name: 'Dai Stablecoin', + decimals: 18, + type: '20', + blockchain: 'ethereum', + balance: '123456789' + }, + { + address: '0x853d955aCEf822Db058eb8505911ED77F175b99e', + symbol: 'FRAX', + name: 'Frax', + decimals: 18, + type: '20', + blockchain: 'ethereum', + balance: '123456789' + }, + { + address: '0x8E870D67F660D95d5be530380D0eC0bd388289E1', + symbol: 'USDP', + name: 'Pax Dollar', + decimals: 18, + type: '20', + blockchain: 'ethereum', + balance: '123456789' + }, + { + address: '0x956F47F50A910163D8BF957Cf5846D573E7f87CA', + symbol: 'FEI', + name: 'Fei USD', + decimals: 18, + type: '20', + blockchain: 'ethereum', + balance: '123456789' + }, + { + address: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c', + symbol: 'WBNB', + name: 'Wrapped BNB', + decimals: 18, + type: '20', + blockchain: 'bsc', + balance: '123456789' + }, + { + address: '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56', + symbol: 'BUSD', + name: 'BUSD Token', + decimals: 18, + type: '20', + blockchain: 'bsc', + balance: '123456789' + }, + { + address: '0x55d398326f99059fF775485246999027B3197955', + symbol: 'USDT', + name: 'Tether USD', + decimals: 18, + type: '20', + blockchain: 'bsc', + balance: '123456789' + }, + { + address: '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d', + symbol: 'USDC', + name: 'USD Coin', + decimals: 18, + type: '20', + blockchain: 'bsc', + balance: '123456789' + }, + { + address: '0x2170Ed0880ac9A755fd29B2688956BD959F933F8', + symbol: 'ETH', + name: 'Ethereum Token', + decimals: 18, + type: '20', + blockchain: 'bsc', + balance: '123456789' + }, + { + address: '0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82', + symbol: 'Cake', + name: 'PancakeSwap Token', + decimals: 18, + type: '20', + blockchain: 'bsc', + balance: '123456789' + }, + { + address: '0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c', + symbol: 'BTCB', + name: 'BTCB Token', + decimals: 18, + type: '20', + blockchain: 'bsc', + balance: '123456789' + }, + { + address: '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270', + symbol: 'WMATIC', + name: 'Wrapped Matic', + decimals: 18, + type: '20', + blockchain: 'polygon', + balance: '123456789' + }, + { + address: '0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619', + symbol: 'WETH', + name: 'Wrapped Ether', + decimals: 18, + type: '20', + blockchain: 'polygon', + balance: '123456789' + }, + { + address: '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174', + symbol: 'USDC', + name: 'USD Coin', + decimals: 6, + type: '20', + blockchain: 'polygon', + balance: '123456789' + }, + { + address: '0xc2132D05D31c914a87C6611C10748AEb04B58e8F', + symbol: 'USDT', + name: 'Tether USD', + decimals: 6, + type: '20', + blockchain: 'polygon', + balance: '123456789' + }, + { + address: '0xa3Fa99A148fA48D14Ed51d610c367C61876997F1', + symbol: 'miMATIC', + name: 'miMATIC', + decimals: 18, + type: '20', + blockchain: 'polygon', + balance: '123456789' + }, + { + address: '0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063', + symbol: 'DAI', + name: 'Dai Stablecoin', + decimals: 18, + type: '20', + blockchain: 'polygon', + balance: '123456789' + }, + { + address: '0x1BFD67037B42Cf73acF2047067bd4F2C47D9BfD6', + symbol: 'WBTC', + name: 'Wrapped BTC', + decimals: 8, + type: '20', + blockchain: 'polygon', + balance: '123456789' + }, + { + address: '0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb', + balance: '56789', + blockchain: 'ethereum', + decimals: 18, + name: 'DePay', + symbol: 'DEPAY', + type: '20' + }, + { + address: '0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb', + balance: '56789', + blockchain: 'bsc', + decimals: 18, + name: 'DePay', + symbol: 'DEPAY', + type: '20' + }, + { + address: '0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb', + balance: '56789', + blockchain: 'polygon', + decimals: 18, + name: 'DePay', + symbol: 'DEPAY', + type: '20' + } + ] + + expect(drippedAssets).toEqual(expectedAssets) + expect(allAssets).toEqual(expectedAssets) + }) + }) + + describe('only', ()=>{ + + it('only returns the assets defined', async()=> { + let drippedAssets = [] + let dripsCount = 0 + + let allAssets = await dripAssets({ + accounts: { ethereum: accounts[0], bsc: accounts[0] }, + only: { ethereum: ['0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'], bsc: ['0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c'] }, + drip: (asset)=>{ + dripsCount++ + drippedAssets.push(asset) + } + }) + + expect(dripsCount).toEqual(2) + + let expectedAssets = [ + { + address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', + symbol: 'WETH', + name: 'Wrapped Ether', + decimals: 18, + type: '20', + blockchain: 'ethereum', + balance: '123456789' + }, + { + address: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c', + symbol: 'WBNB', + name: 'Wrapped BNB', + decimals: 18, + type: '20', + blockchain: 'bsc', + balance: '123456789' + } + ] + + expect(drippedAssets).toEqual(expectedAssets) + expect(allAssets).toEqual(expectedAssets) + }) + }) + + describe('exclude', ()=>{ + + it('drips assets except for the ones that have been "excluded"', async()=> { + let drippedAssets = [] + let dripsCount = 0 + + let allAssets = await dripAssets({ + accounts: { ethereum: accounts[0], bsc: accounts[0] }, + exclude: { ethereum: ['0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'], bsc: ['0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56'] }, + drip: (asset)=>{ + dripsCount++ + drippedAssets.push(asset) + } + }) + + expect(dripsCount).toEqual(16) + + let expectedAssets = [{ + address: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', + symbol: 'ETH', + name: 'Ether', + decimals: 18, + type: 'NATIVE', + blockchain: 'ethereum', + balance: '123456789' + }, + { + address: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', + symbol: 'BNB', + name: 'Binance Coin', + decimals: 18, + type: 'NATIVE', + blockchain: 'bsc', + balance: '123456789' + }, + { + address: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', + symbol: 'WBTC', + name: 'Wrapped BTC', + decimals: 8, + type: '20', + blockchain: 'ethereum', + balance: '123456789' + }, + { + address: '0xdAC17F958D2ee523a2206206994597C13D831ec7', + symbol: 'USDT', + name: 'Tether USD', + decimals: 6, + type: '20', + blockchain: 'ethereum', + balance: '123456789' + }, + { + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + symbol: 'DAI', + name: 'Dai Stablecoin', + decimals: 18, + type: '20', + blockchain: 'ethereum', + balance: '123456789' + }, + { + address: '0x853d955aCEf822Db058eb8505911ED77F175b99e', + symbol: 'FRAX', + name: 'Frax', + decimals: 18, + type: '20', + blockchain: 'ethereum', + balance: '123456789' + }, + { + address: '0x8E870D67F660D95d5be530380D0eC0bd388289E1', + symbol: 'USDP', + name: 'Pax Dollar', + decimals: 18, + type: '20', + blockchain: 'ethereum', + balance: '123456789' + }, + { + address: '0x956F47F50A910163D8BF957Cf5846D573E7f87CA', + symbol: 'FEI', + name: 'Fei USD', + decimals: 18, + type: '20', + blockchain: 'ethereum', + balance: '123456789' + }, + { + address: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c', + symbol: 'WBNB', + name: 'Wrapped BNB', + decimals: 18, + type: '20', + blockchain: 'bsc', + balance: '123456789' + }, + { + address: '0x55d398326f99059fF775485246999027B3197955', + symbol: 'USDT', + name: 'Tether USD', + decimals: 18, + type: '20', + blockchain: 'bsc', + balance: '123456789' + }, + { + address: '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d', + symbol: 'USDC', + name: 'USD Coin', + decimals: 18, + type: '20', + blockchain: 'bsc', + balance: '123456789' + }, + { + address: '0x2170Ed0880ac9A755fd29B2688956BD959F933F8', + symbol: 'ETH', + name: 'Ethereum Token', + decimals: 18, + type: '20', + blockchain: 'bsc', + balance: '123456789' + }, + { + address: '0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82', + symbol: 'Cake', + name: 'PancakeSwap Token', + decimals: 18, + type: '20', + blockchain: 'bsc', + balance: '123456789' + }, + { + address: '0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c', + symbol: 'BTCB', + name: 'BTCB Token', + decimals: 18, + type: '20', + blockchain: 'bsc', + balance: '123456789' + }, + { + address: '0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb', + balance: '56789', + blockchain: 'ethereum', + decimals: 18, + name: 'DePay', + symbol: 'DEPAY', + type: '20' + }, + { + address: '0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb', + balance: '56789', + blockchain: 'bsc', + decimals: 18, + name: 'DePay', + symbol: 'DEPAY', + type: '20' + } + ] + + expect(drippedAssets).toEqual(expectedAssets) + expect(allAssets).toEqual(expectedAssets) + }) + }) + + describe('prioritizes given list of assets when dripping assets', ()=>{ + + it('drips according to given priority list', async()=>{ + let drippedAssets = [] + let dripsCount = 0 + + blockchains.forEach(async (blockchain)=>{ + provider = await getProvider(blockchain) + mock({ request: { return: 'DePay', to: '0xa0bed124a09ac2bd941b10349d8d224fe3c955eb', api: Token[blockchain].DEFAULT, method: 'name' }, provider, blockchain }) + mock({ request: { return: 'DEPAY', to: '0xa0bed124a09ac2bd941b10349d8d224fe3c955eb', api: Token[blockchain].DEFAULT, method: 'symbol' }, provider, blockchain }) + mock({ request: { return: 18, to: '0xa0bed124a09ac2bd941b10349d8d224fe3c955eb', api: Token[blockchain].DEFAULT, method: 'decimals' }, provider, blockchain }) + }) + + provider = await getProvider('ethereum') + mock({ request: { return: 'Wrapped Ether', to: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', api: Token['ethereum'].DEFAULT, method: 'name' }, provider, blockchain: 'ethereum' }) + mock({ request: { return: 'WETH', to: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', api: Token['ethereum'].DEFAULT, method: 'symbol' }, provider, blockchain: 'ethereum' }) + mock({ request: { return: 18, to: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', api: Token['ethereum'].DEFAULT, method: 'decimals' }, provider, blockchain: 'ethereum' }) + mock({ request: { return: '0', to: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', api: Token['ethereum'].DEFAULT, method: 'balanceOf', params: accounts[0] }, provider, blockchain: 'ethereum' }) + + provider = await getProvider('bsc') + mock({ request: { return: 'Wrapped BNB', to: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c', api: Token['bsc'].DEFAULT, method: 'name' }, provider, blockchain: 'bsc' }) + mock({ request: { return: 'BNB', to: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c', api: Token['bsc'].DEFAULT, method: 'symbol' }, provider, blockchain: 'bsc' }) + mock({ request: { return: 18, to: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c', api: Token['bsc'].DEFAULT, method: 'decimals' }, provider, blockchain: 'bsc' }) + + let allAssets = await dripAssets({ + accounts: { ethereum: accounts[0], bsc: accounts[0] }, + priority: [ + { blockchain: 'ethereum', address: '0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb' }, + { blockchain: 'bsc', address: '0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb' }, + { blockchain: 'ethereum', address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' }, + { blockchain: 'bsc', address: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c' }, + ], + drip: (asset)=>{ + dripsCount++ + drippedAssets.push(asset) + } + }) + + expect(dripsCount).toEqual(18) + + let expectedAssets = [ + { + address: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', + symbol: 'ETH', + name: 'Ether', + decimals: 18, + type: 'NATIVE', + blockchain: 'ethereum', + balance: '123456789' + }, + { + address: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', + symbol: 'BNB', + name: 'Binance Coin', + decimals: 18, + type: 'NATIVE', + blockchain: 'bsc', + balance: '123456789' + }, + { + address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', + symbol: 'USDC', + name: 'USD Coin', + decimals: 6, + type: '20', + blockchain: 'ethereum', + balance: '123456789' + }, + { + address: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', + symbol: 'WBTC', + name: 'Wrapped BTC', + decimals: 8, + type: '20', + blockchain: 'ethereum', + balance: '123456789' + }, + { + address: '0xdAC17F958D2ee523a2206206994597C13D831ec7', + symbol: 'USDT', + name: 'Tether USD', + decimals: 6, + type: '20', + blockchain: 'ethereum', + balance: '123456789' + }, + { + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + symbol: 'DAI', + name: 'Dai Stablecoin', + decimals: 18, + type: '20', + blockchain: 'ethereum', + balance: '123456789' + }, + { + address: '0x853d955aCEf822Db058eb8505911ED77F175b99e', + symbol: 'FRAX', + name: 'Frax', + decimals: 18, + type: '20', + blockchain: 'ethereum', + balance: '123456789' + }, + { + address: '0x8E870D67F660D95d5be530380D0eC0bd388289E1', + symbol: 'USDP', + name: 'Pax Dollar', + decimals: 18, + type: '20', + blockchain: 'ethereum', + balance: '123456789' + }, + { + address: '0x956F47F50A910163D8BF957Cf5846D573E7f87CA', + symbol: 'FEI', + name: 'Fei USD', + decimals: 18, + type: '20', + blockchain: 'ethereum', + balance: '123456789' + }, + { + address: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c', + symbol: 'WBNB', + name: 'Wrapped BNB', + decimals: 18, + type: '20', + blockchain: 'bsc', + balance: '123456789' + }, + { + address: '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56', + symbol: 'BUSD', + name: 'BUSD Token', + decimals: 18, + type: '20', + blockchain: 'bsc', + balance: '123456789' + }, + { + address: '0x55d398326f99059fF775485246999027B3197955', + symbol: 'USDT', + name: 'Tether USD', + decimals: 18, + type: '20', + blockchain: 'bsc', + balance: '123456789' + }, + { + address: '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d', + symbol: 'USDC', + name: 'USD Coin', + decimals: 18, + type: '20', + blockchain: 'bsc', + balance: '123456789' + }, + { + address: '0x2170Ed0880ac9A755fd29B2688956BD959F933F8', + symbol: 'ETH', + name: 'Ethereum Token', + decimals: 18, + type: '20', + blockchain: 'bsc', + balance: '123456789' + }, + { + address: '0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82', + symbol: 'Cake', + name: 'PancakeSwap Token', + decimals: 18, + type: '20', + blockchain: 'bsc', + balance: '123456789' + }, + { + address: '0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c', + symbol: 'BTCB', + name: 'BTCB Token', + decimals: 18, + type: '20', + blockchain: 'bsc', + balance: '123456789' + }, + { + address: '0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb', + symbol: 'DEPAY', + name: 'DePay', + decimals: 18, + type: '20', + blockchain: 'ethereum', + balance: '56789' + }, + { + address: '0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb', + symbol: 'DEPAY', + name: 'DePay', + decimals: 18, + type: '20', + blockchain: 'bsc', + balance: '56789' + } + ] + + expect(drippedAssets).toEqual(expectedAssets) + expect(allAssets).toEqual(expectedAssets) + }) + }) + + describe('failed getAssets', ()=>{ + + it('completes drip', async ()=>{ + + fetchMock.get({ url: `https://public.depay.com/accounts/ethereum/${accounts[0]}/assets`, overwriteRoutes: true }, 502) + + let drippedAssets = [] + let dripsCount = 0 + + let allAssets = await dripAssets({ + accounts: { ethereum: accounts[0], bsc: accounts[0] }, + drip: (asset)=>{ + dripsCount++ + drippedAssets.push(asset) + } + }) + + expect(dripsCount).toEqual(18) + + let expectedAssets = [{ + address: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', + symbol: 'ETH', + name: 'Ether', + decimals: 18, + type: 'NATIVE', + blockchain: 'ethereum', + balance: '123456789' + }, + { + address: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', + symbol: 'BNB', + name: 'Binance Coin', + decimals: 18, + type: 'NATIVE', + blockchain: 'bsc', + balance: '123456789' + }, + { + address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', + symbol: 'WETH', + name: 'Wrapped Ether', + decimals: 18, + type: '20', + blockchain: 'ethereum', + balance: '123456789' + }, + { + address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', + symbol: 'USDC', + name: 'USD Coin', + decimals: 6, + type: '20', + blockchain: 'ethereum', + balance: '123456789' + }, + { + address: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', + symbol: 'WBTC', + name: 'Wrapped BTC', + decimals: 8, + type: '20', + blockchain: 'ethereum', + balance: '123456789' + }, + { + address: '0xdAC17F958D2ee523a2206206994597C13D831ec7', + symbol: 'USDT', + name: 'Tether USD', + decimals: 6, + type: '20', + blockchain: 'ethereum', + balance: '123456789' + }, + { + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + symbol: 'DAI', + name: 'Dai Stablecoin', + decimals: 18, + type: '20', + blockchain: 'ethereum', + balance: '123456789' + }, + { + address: '0x853d955aCEf822Db058eb8505911ED77F175b99e', + symbol: 'FRAX', + name: 'Frax', + decimals: 18, + type: '20', + blockchain: 'ethereum', + balance: '123456789' + }, + { + address: '0x8E870D67F660D95d5be530380D0eC0bd388289E1', + symbol: 'USDP', + name: 'Pax Dollar', + decimals: 18, + type: '20', + blockchain: 'ethereum', + balance: '123456789' + }, + { + address: '0x956F47F50A910163D8BF957Cf5846D573E7f87CA', + symbol: 'FEI', + name: 'Fei USD', + decimals: 18, + type: '20', + blockchain: 'ethereum', + balance: '123456789' + }, + { + address: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c', + symbol: 'WBNB', + name: 'Wrapped BNB', + decimals: 18, + type: '20', + blockchain: 'bsc', + balance: '123456789' + }, + { + address: '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56', + symbol: 'BUSD', + name: 'BUSD Token', + decimals: 18, + type: '20', + blockchain: 'bsc', + balance: '123456789' + }, + { + address: '0x55d398326f99059fF775485246999027B3197955', + symbol: 'USDT', + name: 'Tether USD', + decimals: 18, + type: '20', + blockchain: 'bsc', + balance: '123456789' + }, + { + address: '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d', + symbol: 'USDC', + name: 'USD Coin', + decimals: 18, + type: '20', + blockchain: 'bsc', + balance: '123456789' + }, + { + address: '0x2170Ed0880ac9A755fd29B2688956BD959F933F8', + symbol: 'ETH', + name: 'Ethereum Token', + decimals: 18, + type: '20', + blockchain: 'bsc', + balance: '123456789' + }, + { + address: '0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82', + symbol: 'Cake', + name: 'PancakeSwap Token', + decimals: 18, + type: '20', + blockchain: 'bsc', + balance: '123456789' + }, + { + address: '0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c', + symbol: 'BTCB', + name: 'BTCB Token', + decimals: 18, + type: '20', + blockchain: 'bsc', + balance: '123456789' + }, + { + address: '0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb', + balance: '56789', + blockchain: 'bsc', + decimals: 18, + name: 'DePay', + symbol: 'DEPAY', + type: '20' + } + ] + }) + }) +}) diff --git a/tests/units/getAssets.evm.spec.js b/tests/units/getAssets.evm.spec.js new file mode 100644 index 0000000..46cd9cb --- /dev/null +++ b/tests/units/getAssets.evm.spec.js @@ -0,0 +1,455 @@ +import fetchMock from 'fetch-mock' +import { getAssets } from 'src/index.evm' +import { mock, resetMocks } from '@depay/web3-mock' +import { getProvider, resetCache } from '@depay/web3-client-evm' + +describe('getAssets', ()=>{ + + let provider + + beforeEach(()=>{ + resetMocks() + resetCache() + fetchMock.reset() + }) + afterEach(resetMocks) + + describe('fetch assets for given accounts', ()=>{ + + it('fetches the assets for a given account without any connected wallet', async()=> { + let address = '0xEcA533Ef096f191A35DE76aa4580FA3A722724bE' + fetchMock.get({ + url: `https://public.depay.com/accounts/ethereum/${address}/assets`, + }, [{ + "name": "Ether", + "symbol": "ETH", + "address": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", + "type": "NATIVE", + "balance": "1300000000000000000" + }, { + "name": "DePay", + "symbol": "DEPAY", + "address": "0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb", + "type": "20", + "balance": "1000000000000000000" + }] + ) + fetchMock.get({ + url: `https://public.depay.com/accounts/bsc/${address}/assets`, + }, [{ + "name": "BNB", + "symbol": "BNB", + "address": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", + "type": "NATIVE", + "balance": "1300000000000000000" + }, { + "name": "DePay", + "symbol": "DEPAY", + "address": "0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb", + "type": "20", + "balance": "1000000000000000000" + }] + ) + fetchMock.get({ + url: `https://public.depay.com/accounts/polygon/${address}/assets`, + }, [{ + "name": "Matic", + "symbol": "Matic", + "address": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", + "type": "NATIVE", + "balance": "1100000000000000000" + }, { + "name": "DePay", + "symbol": "DEPAY", + "address": "0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb", + "type": "20", + "balance": "1100000000000000000" + }] + ) + expect(await getAssets({ accounts: { ethereum: address, bsc: address, polygon: address } })).toEqual([ + { + name: 'Ether', + symbol: 'ETH', + address: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', + type: 'NATIVE', + balance: '1300000000000000000', + blockchain: 'ethereum' + }, + { + name: 'DePay', + symbol: 'DEPAY', + address: '0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb', + type: '20', + balance: '1000000000000000000', + blockchain: 'ethereum' + }, + { + name: 'BNB', + symbol: 'BNB', + address: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', + type: 'NATIVE', + balance: '1300000000000000000', + blockchain: 'bsc' + }, + { + name: 'DePay', + symbol: 'DEPAY', + address: '0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb', + type: '20', + balance: '1000000000000000000', + blockchain: 'bsc' + }, + { + name: 'Matic', + symbol: 'Matic', + address: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', + type: 'NATIVE', + balance: '1100000000000000000', + blockchain: 'polygon' + }, + { + name: 'DePay', + symbol: 'DEPAY', + address: '0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb', + type: '20', + balance: '1100000000000000000', + blockchain: 'polygon' + } + ]) + }) + }) + + describe('only', ()=> { + + it('only fetches the requested assets (Type 20 Tokens)', async()=> { + let address = '0xEcA533Ef096f191A35DE76aa4580FA3A722724bE' + fetchMock.get({ + url: `https://public.depay.com/accounts/ethereum/${address}/assets`, + }, [{ + "name": "Ether", + "symbol": "ETH", + "address": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", + "type": "NATIVE", + "balance": "1300000000000000000" + }, { + "name": "DePay", + "symbol": "DEPAY", + "address": "0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb", + "type": "20", + "balance": "1000000000000000000" + }] + ) + fetchMock.get({ + url: `https://public.depay.com/accounts/bsc/${address}/assets`, + }, [{ + "name": "BNB", + "symbol": "BNB", + "address": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", + "type": "NATIVE", + "balance": "1300000000000000000" + }, { + "name": "DePay", + "symbol": "DEPAY", + "address": "0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb", + "type": "20", + "balance": "1000000000000000000" + }] + ) + expect(await getAssets({ only: { ethereum: ['0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb'], bsc: ['0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb'] }, accounts: { ethereum: address, bsc: address } })).toEqual([ + { + name: 'DePay', + symbol: 'DEPAY', + address: '0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb', + type: '20', + balance: '1000000000000000000', + blockchain: 'ethereum' + }, + { + name: 'DePay', + symbol: 'DEPAY', + address: '0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb', + type: '20', + balance: '1000000000000000000', + blockchain: 'bsc' + } + ]) + }) + + it('only fetches the requested assets (NATIVE Tokens)', async()=> { + let address = '0xEcA533Ef096f191A35DE76aa4580FA3A722724bE' + fetchMock.get({ + url: `https://public.depay.com/accounts/ethereum/${address}/assets`, + }, [{ + "name": "Ether", + "symbol": "ETH", + "address": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", + "type": "NATIVE", + "balance": "1300000000000000000" + }, { + "name": "DePay", + "symbol": "DEPAY", + "address": "0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb", + "type": "20", + "balance": "1000000000000000000" + }] + ) + fetchMock.get({ + url: `https://public.depay.com/accounts/bsc/${address}/assets`, + }, [{ + "name": "BNB", + "symbol": "BNB", + "address": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", + "type": "NATIVE", + "balance": "1300000000000000000" + }, { + "name": "DePay", + "symbol": "DEPAY", + "address": "0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb", + "type": "20", + "balance": "1000000000000000000" + }] + ) + expect(await getAssets({ only: { ethereum: ['0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'], bsc: ['0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'] }, accounts: { ethereum: address, bsc: address } })).toEqual([ + { + name: 'Ether', + symbol: 'ETH', + address: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', + type: 'NATIVE', + balance: '1300000000000000000', + blockchain: 'ethereum' + }, + { + name: 'BNB', + symbol: 'BNB', + address: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', + type: 'NATIVE', + balance: '1300000000000000000', + blockchain: 'bsc' + } + ]) + }) + }) + + describe('exclude', ()=> { + + it('excludes assets (Type 20 Tokens)', async()=> { + let address = '0xEcA533Ef096f191A35DE76aa4580FA3A722724bE' + fetchMock.get({ + url: `https://public.depay.com/accounts/ethereum/${address}/assets`, + }, [{ + "name": "Ether", + "symbol": "ETH", + "address": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", + "type": "NATIVE", + "balance": "1300000000000000000" + }, { + "name": "DePay", + "symbol": "DEPAY", + "address": "0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb", + "type": "20", + "balance": "1000000000000000000" + }] + ) + fetchMock.get({ + url: `https://public.depay.com/accounts/bsc/${address}/assets`, + }, [{ + "name": "BNB", + "symbol": "BNB", + "address": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", + "type": "NATIVE", + "balance": "1300000000000000000" + }, { + "name": "DePay", + "symbol": "DEPAY", + "address": "0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb", + "type": "20", + "balance": "1000000000000000000" + }] + ) + expect(await getAssets({ exclude: { ethereum: ['0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb'], bsc: ['0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb'] }, accounts: { ethereum: address, bsc: address } })).toEqual([ + { + name: 'Ether', + symbol: 'ETH', + address: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', + type: 'NATIVE', + balance: '1300000000000000000', + blockchain: 'ethereum' + }, + { + name: 'BNB', + symbol: 'BNB', + address: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', + type: 'NATIVE', + balance: '1300000000000000000', + blockchain: 'bsc' + } + ]) + }) + + it('excludes assets (NATIVE Tokens)', async()=> { + let address = '0xEcA533Ef096f191A35DE76aa4580FA3A722724bE' + fetchMock.get({ + url: `https://public.depay.com/accounts/ethereum/${address}/assets`, + }, [{ + "name": "Ether", + "symbol": "ETH", + "address": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", + "type": "NATIVE", + "balance": "1300000000000000000" + }, { + "name": "DePay", + "symbol": "DEPAY", + "address": "0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb", + "type": "20", + "balance": "1000000000000000000" + }] + ) + fetchMock.get({ + url: `https://public.depay.com/accounts/bsc/${address}/assets`, + }, [{ + "name": "BNB", + "symbol": "BNB", + "address": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", + "type": "NATIVE", + "balance": "1300000000000000000" + }, { + "name": "DePay", + "symbol": "DEPAY", + "address": "0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb", + "type": "20", + "balance": "1000000000000000000" + }] + ) + expect(await getAssets({ exclude: { ethereum: ['0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'], bsc: ['0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'] }, accounts: { ethereum: address, bsc: address } })).toEqual([ + { + name: 'DePay', + symbol: 'DEPAY', + address: '0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb', + type: '20', + balance: '1000000000000000000', + blockchain: 'ethereum' + }, + { + name: 'DePay', + symbol: 'DEPAY', + address: '0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb', + type: '20', + balance: '1000000000000000000', + blockchain: 'bsc' + } + ]) + }) + }) + + describe('NATIVE currency missing via API', ()=>{ + + beforeEach(()=>{ + mock({ blockchain: 'ethereum', wallet: 'metamask' }) + fetchMock.get({ + url: 'https://public.depay.com/accounts/ethereum/0xd8da6bf26964af9d7eed9e03e53415d37aa96045/assets', + }, [{ + "name": "Dai Stablecoin", + "symbol": "DAI", + "address": "0x6B175474E89094C44Da98b954EedeAC495271d0F", + "type": "20" + }] + ) + fetchMock.get({ + url: 'https://public.depay.com/accounts/bsc/0xd8da6bf26964af9d7eed9e03e53415d37aa96045/assets', + }, [{ + "name": "PancakeSwap", + "symbol": "CAKE", + "address": "0x0e09fabb73bd3ade0a17ecc321fd13a19e81ce82", + "type": "20" + }] + ) + }) + + it('ensures fetching asset for NATIVE currency if it was missing in the api response', async()=> { + + provider = await getProvider('ethereum') + let ethereumBalanceMock = mock({ + provider, + blockchain: 'ethereum', + balance: { + for: '0xd8da6bf26964af9d7eed9e03e53415d37aa96045', + return: '22222221' + } + }) + + provider = await getProvider('bsc') + let bscBalanceMock = mock({ + provider, + blockchain: 'bsc', + balance: { + for: '0xd8da6bf26964af9d7eed9e03e53415d37aa96045', + return: '3333333335' + } + }) + + let assets = await getAssets({ accounts: { ethereum: '0xd8da6bf26964af9d7eed9e03e53415d37aa96045', bsc: '0xd8da6bf26964af9d7eed9e03e53415d37aa96045' }}) + + expect(assets.find((a)=>a.symbol=='ETH').balance).toEqual('22222221') + expect(assets.find((a)=>a.symbol=='BNB').balance).toEqual('3333333335') + + expect(ethereumBalanceMock).toHaveBeenCalled() + expect(bscBalanceMock).toHaveBeenCalled() + }) + }) + + describe('fetching assets fails', ()=> { + + it('still resolves with nothing', async()=> { + let address = '0xEcA533Ef096f191A35DE76aa4580FA3A722724bE' + fetchMock.get({ + url: `https://public.depay.com/accounts/ethereum/${address}/assets`, + }, 502 + ) + fetchMock.get({ + url: `https://public.depay.com/accounts/bsc/${address}/assets`, + }, [{ + "name": "BNB", + "symbol": "BNB", + "address": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", + "type": "NATIVE", + "balance": "1300000000000000000" + }, { + "name": "DePay", + "symbol": "DEPAY", + "address": "0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb", + "type": "20", + "balance": "1000000000000000000" + }] + ) + + let assets = await getAssets({ accounts: { ethereum: address, bsc: address }}) + expect(assets).toEqual([ + { + "address": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", + "balance": "1300000000000000000", + "blockchain": "bsc", + "name": "BNB", + "symbol": "BNB", + "type": "NATIVE", + }, + { + "address": "0xa0bEd124a09ac2Bd941b10349d8d224fe3c955eb", + "balance": "1000000000000000000", + "blockchain": "bsc", + "name": "DePay", + "symbol": "DEPAY", + "type": "20", + } + ]) + + fetchMock.get({ + url: `https://public.depay.com/accounts/bsc/${address}/assets`, + overwriteRoutes: true + }, 502 + ) + + assets = await getAssets({ accounts: { ethereum: address, bsc: address }}) + expect(assets).toEqual([]) + }) + }) +}) diff --git a/yarn.lock b/yarn.lock index 356c6f3..25287e3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -906,16 +906,31 @@ resolved "https://registry.yarnpkg.com/@depay/web3-blockchains/-/web3-blockchains-6.2.0.tgz#5ab856ad1ed6aa153e9f25a89c6acb64017367ce" integrity sha512-giZCoTFjRBoVDZ9WA1tlTtVtw7Pc81E8krjTrErCyoc94avuFUjFRVSf8k/oUdaQ3Yvt+yLQp3cAovlWD9Gnfg== -"@depay/web3-client@^10.1.7": - version "10.1.7" - resolved "https://registry.yarnpkg.com/@depay/web3-client/-/web3-client-10.1.7.tgz#684d2273a54ac5d1da3aa70b4ed8f0db62e23fac" - integrity sha512-Q98sCWc9EirqIMrMC528XmBQbdjihwycEJifKhRbTUwSow2xnT1vG0RJGxkisoq9dTD6Xyorv4eRdeu/3sWAdg== +"@depay/web3-blockchains@^6.2.3": + version "6.2.3" + resolved "https://registry.yarnpkg.com/@depay/web3-blockchains/-/web3-blockchains-6.2.3.tgz#8dbee9ec05e2d581dde0c1b7c4d1a64755e99cbf" + integrity sha512-n917CoFqvlRBzUc7JBxm2H3y8WjEgFtgzwWgfg7OaStn0LqvVRxwc/h1vzPPW8hAANhbpDsLW2b9KKaks6LUBA== + +"@depay/web3-client-evm@^10.1.22": + version "10.1.22" + resolved "https://registry.yarnpkg.com/@depay/web3-client-evm/-/web3-client-evm-10.1.22.tgz#4e563beb83f470828f88731ecb1f872fbb7aefe5" + integrity sha512-FjxfVibjmfT5wUJl+E7i2TmHynPC/+HUsz6a4VN22mkxdS618kkOOgfSOK06a+rjcqIoKcPz3mu51yAVHNJWrg== + +"@depay/web3-client@^10.1.22": + version "10.1.22" + resolved "https://registry.yarnpkg.com/@depay/web3-client/-/web3-client-10.1.22.tgz#0dc1ac9b7413048a677be50cd9dccdbd6d6fc02f" + integrity sha512-D60jj2LgBAOyfphV/uTpEO/XExaNE9ygqZh9XINI4g0jMBwgNhfNOuE3UrKb1NYd0i7rSSaXS7jfe4j9rif8HQ== "@depay/web3-constants@^6.3.1": version "6.3.1" resolved "https://registry.yarnpkg.com/@depay/web3-constants/-/web3-constants-6.3.1.tgz#2d15434774588ece0be69290087046a113340f3d" integrity sha512-6jpYksmKFFadotlOujlF9PUAypneeIPTtiv70iPbFuV0OvZ9F/eG7FMHEBFEl4QpHOSyzbxMOSRWz4YnvYCOXg== +"@depay/web3-constants@^6.3.2": + version "6.3.2" + resolved "https://registry.yarnpkg.com/@depay/web3-constants/-/web3-constants-6.3.2.tgz#13a6066f20baee3ea94b373eebc69bd2c4c9773b" + integrity sha512-It2ygcxIrSXMB3ilHmgtq0EMfBGf42sgnaCFbF9Lz80gPjC7O2NifNv8h3gRd/8Fy3XwzCLkjDqbVIgn7kV9tQ== + "@depay/web3-mock@^13.22.4": version "13.22.4" resolved "https://registry.yarnpkg.com/@depay/web3-mock/-/web3-mock-13.22.4.tgz#d0d84ea1d217420a67af70602153b443bffbbb9d" @@ -926,10 +941,15 @@ ethers "^5.7.1" xhr2 "^0.2.1" -"@depay/web3-tokens@^9.11.4": - version "9.11.4" - resolved "https://registry.yarnpkg.com/@depay/web3-tokens/-/web3-tokens-9.11.4.tgz#4219ff11ad3eb3ac96d3894ba06ad5ae08787dbb" - integrity sha512-OHcIWVBtIyUg21+kUb/AmkZuR+79HGUV+evUFYGE/uZVA4yGgkYIUxAadFyFfsIwh593+oFYFbJUQjy4G3FHsw== +"@depay/web3-tokens-evm@^9.12.6": + version "9.12.6" + resolved "https://registry.yarnpkg.com/@depay/web3-tokens-evm/-/web3-tokens-evm-9.12.6.tgz#aff00d14215ad0df8b2d9dd010127f6c38cfc0e6" + integrity sha512-+PYVFFIaEuhCTKrKnySkBb0POW/P5IeVmO10yiOObB4iDZ/oEP4mMvBxwxc7X6eCTr68u9TZEM/5yN5yuhkIcw== + +"@depay/web3-tokens@^9.12.6": + version "9.12.6" + resolved "https://registry.yarnpkg.com/@depay/web3-tokens/-/web3-tokens-9.12.6.tgz#9dcb9e346982dcc0a817a346a72c1397d640d863" + integrity sha512-1Uxotz/VEDzOZXS/pr0HdlDGHp+bESBxTCmZf2xdKMMA2Kfl9xd0EJrizvWlsiuuJZ7d6919pSaUDaPKXS9RbQ== "@eslint/eslintrc@^0.4.3": version "0.4.3"