diff --git a/jest.config.js b/jest.config.js index aa8cdfd14..d0e188f02 100644 --- a/jest.config.js +++ b/jest.config.js @@ -2,7 +2,7 @@ module.exports = { preset: 'ts-jest', globals: { 'ts-jest': { - tsConfig: '/tsconfig.json' + tsconfig: '/tsconfig.json' } }, testEnvironment: 'node', diff --git a/lib/connextclient/ConnextClient.ts b/lib/connextclient/ConnextClient.ts index 0cb803194..308abb82e 100644 --- a/lib/connextclient/ConnextClient.ts +++ b/lib/connextclient/ConnextClient.ts @@ -21,8 +21,8 @@ import { XudError } from '../types'; import { UnitConverter } from '../utils/UnitConverter'; import { parseResponseBody } from '../utils/utils'; import errors, { errorCodes } from './errors'; +import { EthProvider, getEthprovider } from './ethprovider'; import { - ConnextBalanceResponse, ConnextBlockNumberResponse, ConnextChannelBalanceResponse, ConnextChannelDetails, @@ -39,7 +39,6 @@ import { EthproviderGasPriceResponse, ExpectedIncomingTransfer, GetBlockByNumberResponse, - OnchainTransferResponse, ProvidePreimageEvent, TransferReceivedEvent, } from './types'; @@ -146,6 +145,7 @@ class ConnextClient extends SwapClient { public publicIdentifier: string | undefined; /** On-chain deposit address */ public signerAddress: string | undefined; + private ethProvider: EthProvider | undefined; /** The set of hashes for outgoing transfers. */ private outgoingTransferHashes = new Set(); private port: number; @@ -162,7 +162,7 @@ class ConnextClient extends SwapClient { private requestCollateralPromises = new Map>(); private outboundAmounts = new Map(); private inboundAmounts = new Map(); - private _reconcileDepositSubscriber: Subscription | undefined; + private _reconcileDepositSubscriptions: Subscription[] = []; /** Channel multisig address */ private channelAddress: string | undefined; @@ -212,6 +212,7 @@ class ConnextClient extends SwapClient { // Related issue: https://github.com/ExchangeUnion/xud/issues/1494 public setSeed = (seed: string) => { this.seed = seed; + this.ethProvider = getEthprovider(this.host, this.port, this.network, CHAIN_IDENTIFIERS[this.network], this.seed); }; public initConnextClient = async (seedMnemonic: string) => { @@ -387,41 +388,48 @@ class ConnextClient extends SwapClient { }; private reconcileDeposit = () => { - if (this._reconcileDepositSubscriber) { - this._reconcileDepositSubscriber.unsubscribe(); - } - const ethBalance$ = interval(30000).pipe( - mergeMap(() => from(this.getBalanceForAddress(this.channelAddress!))), - // only emit new ETH balance events when the balance changes - distinctUntilChanged(), - ); - this._reconcileDepositSubscriber = ethBalance$ - // when ETH balance changes - .pipe( - mergeMap(() => { - if (this.status === ClientStatus.ConnectionVerified) { - return defer(() => { - // create new commitment transaction - return from( - this.sendRequest('/deposit', 'POST', { - channelAddress: this.channelAddress, - publicIdentifier: this.publicIdentifier, - assetId: '0x0000000000000000000000000000000000000000', // TODO: multi currency support - }), - ); - }); - } - return throwError('stopping deposit calls because client is no longer connected'); - }), - ) - .subscribe({ + this._reconcileDepositSubscriptions.forEach((subscription) => subscription.unsubscribe()); + const getBalance$ = (assetId: string, pollInterval: number) => { + return interval(pollInterval).pipe( + mergeMap(() => from(this.getBalanceForAddress(assetId, this.channelAddress))), + // only emit new balance events when the balance changes + distinctUntilChanged(), + ); + }; + const reconcileForAsset = (assetId: string, balance$: ReturnType) => { + return ( + balance$ + // when balance changes + .pipe( + mergeMap(() => { + if (this.status === ClientStatus.ConnectionVerified) { + // create new commitment transaction + return from( + this.sendRequest('/deposit', 'POST', { + channelAddress: this.channelAddress, + publicIdentifier: this.publicIdentifier, + assetId, + }), + ); + } + return throwError('stopping deposit calls because client is no longer connected'); + }), + ) + ); + }; + this.tokenAddresses.forEach((assetId) => { + const subscription = reconcileForAsset(assetId, getBalance$(assetId, 30000)).subscribe({ next: () => { - this.logger.trace('deposit successfully reconciled'); + this.logger.trace(`deposit successfully reconciled for ${this.getCurrencyByTokenaddress(assetId)}`); }, error: (e) => { - this.logger.trace(`stopped deposit calls because: ${JSON.stringify(e)}`); + this.logger.trace( + `stopped ${this.getCurrencyByTokenaddress(assetId)} deposit calls because: ${JSON.stringify(e)}`, + ); }, }); + this._reconcileDepositSubscriptions.push(subscription); + }); }; public sendSmallestAmount = async () => { @@ -774,13 +782,22 @@ class ConnextClient extends SwapClient { return gweiGasPrice; }; - private getBalanceForAddress = async (assetId: string) => { - const res = await this.sendRequest(`/ethprovider/${CHAIN_IDENTIFIERS[this.network]}`, 'POST', { - method: 'eth_getBalance', - params: [assetId, 'latest'], - }); - const getBalanceResponse = await parseResponseBody(res); - return parseInt(getBalanceResponse.result, 16); + /** + * Returns the on-chain balance for a given assetId and address. + * Address defaults to signer address. + */ + private getBalanceForAddress = async (assetId: string, address?: string) => { + assert(this.ethProvider, 'Cannot get balance without ethProvider'); + if (assetId === this.tokenAddresses.get('ETH')) { + const ethBalance$ = address ? this.ethProvider.getEthBalanceByAddress(address) : this.ethProvider.getEthBalance(); + return BigInt(await ethBalance$.toPromise()); + } else { + const contract = this.ethProvider.getContract(assetId); + const erc20balance$ = address + ? this.ethProvider.getERC20BalanceByAddress(address, contract) + : this.ethProvider.getERC20Balance(contract); + return BigInt(await erc20balance$.toPromise()); + } }; public getInfo = async (): Promise => { @@ -912,7 +929,7 @@ class ConnextClient extends SwapClient { const tokenAddress = this.getTokenAddress(currency); getBalancePromise = Promise.all([ this.sendRequest(`/${this.publicIdentifier}/channels/${this.channelAddress}`, 'GET'), - this.getBalanceForAddress(this.signerAddress!), + this.getBalanceForAddress(tokenAddress), ]) .then(async ([channelDetailsRes, onChainBalance]) => { const channelDetails = await parseResponseBody(channelDetailsRes); @@ -1015,6 +1032,8 @@ class ConnextClient extends SwapClient { // Withdraw on-chain funds public withdraw = async ({ all, currency, amount, destination, fee }: WithdrawArguments): Promise => { + assert(this.ethProvider, 'cannot send transaction without ethProvider'); + if (fee) { // TODO: allow overwriting gas price throw Error('setting fee for Ethereum withdrawals is not supported yet'); @@ -1043,20 +1062,15 @@ class ConnextClient extends SwapClient { throw new Error('either all must be true or amount must be non-zero'); } - const res = await this.sendRequest('/onchain-transfer', 'POST', { - assetId: this.getTokenAddress(currency), - amount: unitsStr, - recipient: destination, - }); - const { txhash } = await parseResponseBody(res); - return txhash; + const sendTransaction$ = this.ethProvider.onChainTransfer(this.getTokenAddress(currency), destination, unitsStr); + const transaction = await sendTransaction$.toPromise(); + this.logger.info(`on-chain transfer sent, transaction hash: ${transaction.hash}`); + return transaction.hash; }; /** Connext client specific cleanup. */ protected disconnect = async () => { - if (this._reconcileDepositSubscriber) { - this._reconcileDepositSubscriber.unsubscribe(); - } + this._reconcileDepositSubscriptions.forEach((subscription) => subscription.unsubscribe()); this.setStatus(ClientStatus.Disconnected); for (const req of this.pendingRequests) { diff --git a/lib/connextclient/ethprovider.ts b/lib/connextclient/ethprovider.ts new file mode 100644 index 000000000..9b0f6d52b --- /dev/null +++ b/lib/connextclient/ethprovider.ts @@ -0,0 +1,119 @@ +import { ethers } from 'ethers'; +import { curry } from 'ramda'; +import { from, Observable } from 'rxjs'; +import { mergeMap } from 'rxjs/operators'; +// This file will be a separate module with the above dependencies. + +// gets the Ethereum provider object to read data from the chain +const getProvider = (host: string, port: number, name: string, chainId: number): ethers.providers.JsonRpcProvider => { + return new ethers.providers.JsonRpcProvider( + { url: `http://${host}:${port}/ethprovider/${chainId}` }, + { + name, + chainId, + }, + ); +}; + +// gets the signer object necessary for write access (think unlock wallet) +const getSigner = (provider: ethers.providers.JsonRpcProvider, seed: string): ethers.Wallet => { + return ethers.Wallet.fromMnemonic(seed).connect(provider); +}; + +// We curry getContract so that we can provide its arguments one at a time. +// This allows us to provide some of the necessary arguments (that we already have) before we export the function. +// Read more: https://ramdajs.com/docs/#curry +const getContract = curry( + (signer: ethers.Wallet, contractAddress: string): ethers.Contract => { + // we use the minimum viable contract ABI for ERC20 tokens + // for full contract ABI we should compile it from the solidity source + const erc20abi = ['function balanceOf(address) view returns (uint)', 'function transfer(address to, uint amount)']; + return new ethers.Contract(contractAddress, erc20abi, signer); + }, +); + +// Sends on-chain ERC20 transfer +// We also curry this function, just like the previous one. +// All the functions that we export out of the package will be curried +const onChainSendERC20 = curry( + ( + signer: ethers.Wallet, + contract: ethers.Contract, + destinationAddress: string, + units: string, + ): Observable => { + // get the gas price + return from(signer.provider.getGasPrice()).pipe( + mergeMap( + (gasPrice) => + // then send the transaction + from(contract.transfer(destinationAddress, units, { gasPrice })) as Observable, + ), + ); + }, +); + +// Sends on-chain ETH transfer +const onChainSendETH = curry( + (signer: ethers.Wallet, destinationAddress: string, units: string): Observable => { + return from(signer.provider.getGasPrice()).pipe( + mergeMap((gasPrice) => { + const ether = ethers.utils.formatEther(units); + const value = ethers.utils.parseEther(ether); + return signer.sendTransaction({ + to: destinationAddress, + value, + gasPrice, + }); + }), + ); + }, +); + +// returns ETH on-chain balance for the address in wei +const getEthBalanceByAddress = curry((provider: ethers.providers.JsonRpcProvider, address: string) => + from(provider.getBalance(address)), +); + +// returns ERC20 on-chain balance for the contract address in the smallest unit +const getERC20Balance = curry( + (address: string, contract: ethers.Contract): Observable => { + return from(contract.balanceOf(address)) as Observable; + }, +); + +// This is the main function that has to be called before this package exposes more functions. +// Think of it as a constructor where we create the interal state of the module before +// we export more functionality to the consumer. +const getEthprovider = (host: string, port: number, name: string, chainId: number, seed: string) => { + // create the internal state + const provider = getProvider(host, port, name, chainId); + const signer = getSigner(provider, seed); + // because the functions below are curried we can only provide some of the arguments + const getERC20BalanceWithSigner = getERC20Balance(signer.address); + const getContractWithSigner = getContract(signer); + const onChainSendERC20WithSigner = onChainSendERC20(signer); + const onChainSendETHWithSigner = onChainSendETH(signer); + const getEthBalanceByAddressWithProvider = getEthBalanceByAddress(provider); + const onChainTransfer = (contractAddress: string, destinationAddress: string, units: string) => { + if (contractAddress === ethers.constants.AddressZero) { + return onChainSendETHWithSigner(destinationAddress, units); + } else { + const contract = getContractWithSigner(contractAddress); + return onChainSendERC20WithSigner(contract, destinationAddress, units); + } + }; + // expose functionality to the consumer + return { + getEthBalance: () => from(signer.getBalance()), + getEthBalanceByAddress: getEthBalanceByAddressWithProvider, + getContract: getContractWithSigner, + getERC20Balance: getERC20BalanceWithSigner, + getERC20BalanceByAddress: getERC20Balance, + onChainTransfer, + }; +}; + +type EthProvider = ReturnType; + +export { getEthprovider, EthProvider }; diff --git a/lib/connextclient/types.ts b/lib/connextclient/types.ts index f1e0981db..9cd0b3503 100644 --- a/lib/connextclient/types.ts +++ b/lib/connextclient/types.ts @@ -121,15 +121,6 @@ export type ConnextChannelBalanceResponse = { freeBalanceOnChain: string; }; -/** - * The response for ethprovider eth_getBalance call. - */ -export type ConnextBalanceResponse = { - id: number; - jsonrpc: string; - result: string; -}; - export type GetBlockByNumberResponse = { result: { difficulty: string; @@ -319,7 +310,3 @@ export type TransferReceivedEvent = { units: bigint; routingId: string; }; - -export type OnchainTransferResponse = { - txhash: string; -}; diff --git a/lib/db/seeds/simnet.ts b/lib/db/seeds/simnet.ts index 0d68d1cd9..e11c3b736 100644 --- a/lib/db/seeds/simnet.ts +++ b/lib/db/seeds/simnet.ts @@ -33,20 +33,18 @@ const currencies = [ decimalPlaces: 18, tokenAddress: '0x0000000000000000000000000000000000000000', }, - /* { id: 'USDT', swapClient: SwapClientType.Connext, decimalPlaces: 6, - tokenAddress: '0x6149AA6798a75450EFb0151204513ce197f626Ce', + tokenAddress: '0x5C533069289be37789086DB7A615ca5e963Fe5Bc', }, { id: 'DAI', swapClient: SwapClientType.Connext, decimalPlaces: 18, - tokenAddress: '0x69C3d485623bA3f382Fc0FB6756c4574d43C1618', + tokenAddress: '0x514a44ABFB7F02256eF658d31425385787498Fcd', }, - */ /* { id: 'XUC', @@ -58,15 +56,15 @@ const currencies = [ ] as db.CurrencyAttributes[]; const pairs = [ - // { baseCurrency: 'BTC', quoteCurrency: 'DAI' }, - // { baseCurrency: 'BTC', quoteCurrency: 'USDT' }, { baseCurrency: 'ETH', quoteCurrency: 'BTC' }, + { baseCurrency: 'LTC', quoteCurrency: 'BTC' }, + { baseCurrency: 'BTC', quoteCurrency: 'USDT' }, + { baseCurrency: 'USDT', quoteCurrency: 'DAI' }, + // { baseCurrency: 'BTC', quoteCurrency: 'DAI' }, // { baseCurrency: 'ETH', quoteCurrency: 'DAI' }, // { baseCurrency: 'ETH', quoteCurrency: 'USDT' }, - { baseCurrency: 'LTC', quoteCurrency: 'BTC' }, // { baseCurrency: 'LTC', quoteCurrency: 'DAI' }, // { baseCurrency: 'LTC', quoteCurrency: 'USDT' }, - // { baseCurrency: 'USDT', quoteCurrency: 'DAI' }, // { baseCurrency: 'XUC', quoteCurrency: 'BTC' }, // { baseCurrency: 'XUC', quoteCurrency: 'ETH' }, // { baseCurrency: 'XUC', quoteCurrency: 'DAI' }, diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 86e20ea09..28897f72f 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -546,6 +546,183 @@ } } }, + "@ethersproject/abi": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.9.tgz", + "integrity": "sha512-ily2OufA2DTrxkiHQw5GqbkMSnNKuwZBqKsajtT0ERhZy1r9w2CpW1bmtRMIGzaqQxCdn/GEoFogexk72cBBZQ==", + "requires": { + "@ethersproject/address": "^5.0.4", + "@ethersproject/bignumber": "^5.0.7", + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/constants": "^5.0.4", + "@ethersproject/hash": "^5.0.4", + "@ethersproject/keccak256": "^5.0.3", + "@ethersproject/logger": "^5.0.5", + "@ethersproject/properties": "^5.0.3", + "@ethersproject/strings": "^5.0.4" + }, + "dependencies": { + "@ethersproject/bignumber": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.0.12.tgz", + "integrity": "sha512-mbFZjwthx6vFlHG9owXP/C5QkNvsA+xHpDCkPPPdG2n1dS9AmZAL5DI0InNLid60rQWL3MXpEl19tFmtL7Q9jw==", + "requires": { + "@ethersproject/bytes": "^5.0.8", + "@ethersproject/logger": "^5.0.5", + "bn.js": "^4.4.0" + }, + "dependencies": { + "@ethersproject/bytes": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.0.8.tgz", + "integrity": "sha512-O+sJNVGzzuy51g+EMK8BegomqNIg+C2RO6vOt0XP6ac4o4saiq69FnjlsrNslaiMFVO7qcEHBsWJ9hx1tj1lMw==", + "requires": { + "@ethersproject/logger": "^5.0.5" + } + } + } + }, + "@ethersproject/constants": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.0.7.tgz", + "integrity": "sha512-cbQK1UpE4hamB52Eg6DLhJoXeQ1plSzekh5Ujir1xdREdwdsZPPXKczkrWqBBR0KyywJZHN/o/hj0w8j7scSGg==", + "requires": { + "@ethersproject/bignumber": "^5.0.7" + } + }, + "@ethersproject/strings": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.0.7.tgz", + "integrity": "sha512-a+6T80LvmXGMOOWQTZHtGGQEg1z4v8rm8oX70KNs55YtPXI/5J3LBbVf5pyqCKSlmiBw5IaepPvs5XGalRUSZQ==", + "requires": { + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/constants": "^5.0.4", + "@ethersproject/logger": "^5.0.5" + } + } + } + }, + "@ethersproject/abstract-provider": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.0.7.tgz", + "integrity": "sha512-NF16JGn6M0zZP5ZS8KtDL2Rh7yHxZbUjBIHLNHMm/0X0BephhjUWy8jqs/Zks6kDJRzNthgmPVy41Ec0RYWPYA==", + "requires": { + "@ethersproject/bignumber": "^5.0.7", + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/logger": "^5.0.5", + "@ethersproject/networks": "^5.0.3", + "@ethersproject/properties": "^5.0.3", + "@ethersproject/transactions": "^5.0.5", + "@ethersproject/web": "^5.0.6" + }, + "dependencies": { + "@ethersproject/bignumber": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.0.12.tgz", + "integrity": "sha512-mbFZjwthx6vFlHG9owXP/C5QkNvsA+xHpDCkPPPdG2n1dS9AmZAL5DI0InNLid60rQWL3MXpEl19tFmtL7Q9jw==", + "requires": { + "@ethersproject/bytes": "^5.0.8", + "@ethersproject/logger": "^5.0.5", + "bn.js": "^4.4.0" + }, + "dependencies": { + "@ethersproject/bytes": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.0.8.tgz", + "integrity": "sha512-O+sJNVGzzuy51g+EMK8BegomqNIg+C2RO6vOt0XP6ac4o4saiq69FnjlsrNslaiMFVO7qcEHBsWJ9hx1tj1lMw==", + "requires": { + "@ethersproject/logger": "^5.0.5" + } + } + } + } + } + }, + "@ethersproject/abstract-signer": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.0.9.tgz", + "integrity": "sha512-CM5UNmXQaA03MyYARFDDRjHWBxujO41tVle7glf5kHcQsDDULgqSVpkliLJMtPzZjOKFeCVZBHybTZDEZg5zzg==", + "requires": { + "@ethersproject/abstract-provider": "^5.0.4", + "@ethersproject/bignumber": "^5.0.7", + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/logger": "^5.0.5", + "@ethersproject/properties": "^5.0.3" + }, + "dependencies": { + "@ethersproject/bignumber": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.0.12.tgz", + "integrity": "sha512-mbFZjwthx6vFlHG9owXP/C5QkNvsA+xHpDCkPPPdG2n1dS9AmZAL5DI0InNLid60rQWL3MXpEl19tFmtL7Q9jw==", + "requires": { + "@ethersproject/bytes": "^5.0.8", + "@ethersproject/logger": "^5.0.5", + "bn.js": "^4.4.0" + }, + "dependencies": { + "@ethersproject/bytes": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.0.8.tgz", + "integrity": "sha512-O+sJNVGzzuy51g+EMK8BegomqNIg+C2RO6vOt0XP6ac4o4saiq69FnjlsrNslaiMFVO7qcEHBsWJ9hx1tj1lMw==", + "requires": { + "@ethersproject/logger": "^5.0.5" + } + } + } + } + } + }, + "@ethersproject/address": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.0.8.tgz", + "integrity": "sha512-V87DHiZMZR6hmFYmoGaHex0D53UEbZpW75uj8AqPbjYUmi65RB4N2LPRcJXuWuN2R0Y2CxkvW6ArijWychr5FA==", + "requires": { + "@ethersproject/bignumber": "^5.0.10", + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/keccak256": "^5.0.3", + "@ethersproject/logger": "^5.0.5", + "@ethersproject/rlp": "^5.0.3" + }, + "dependencies": { + "@ethersproject/bignumber": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.0.12.tgz", + "integrity": "sha512-mbFZjwthx6vFlHG9owXP/C5QkNvsA+xHpDCkPPPdG2n1dS9AmZAL5DI0InNLid60rQWL3MXpEl19tFmtL7Q9jw==", + "requires": { + "@ethersproject/bytes": "^5.0.8", + "@ethersproject/logger": "^5.0.5", + "bn.js": "^4.4.0" + }, + "dependencies": { + "@ethersproject/bytes": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.0.8.tgz", + "integrity": "sha512-O+sJNVGzzuy51g+EMK8BegomqNIg+C2RO6vOt0XP6ac4o4saiq69FnjlsrNslaiMFVO7qcEHBsWJ9hx1tj1lMw==", + "requires": { + "@ethersproject/logger": "^5.0.5" + } + } + } + } + } + }, + "@ethersproject/base64": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.0.6.tgz", + "integrity": "sha512-HwrGn8YMiUf7bcdVvB4NJ+eWT0BtEFpDtrYxVXEbR7p/XBSJjwiR7DEggIiRvxbualMKg+EZijQWJ3az2li0uw==", + "requires": { + "@ethersproject/bytes": "^5.0.4" + } + }, + "@ethersproject/basex": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.0.6.tgz", + "integrity": "sha512-Y/8dowRxBF3bsKkqEp7XN4kcFFQ0o5xxP1YyopfqkXejaOEGiD7ToQdQ0pIZpAJ5GreW56oFOTDDSO6ZcUCNYg==", + "requires": { + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/properties": "^5.0.3" + } + }, "@ethersproject/bignumber": { "version": "5.0.6", "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.0.6.tgz", @@ -572,6 +749,226 @@ "@ethersproject/bignumber": "^5.0.6" } }, + "@ethersproject/contracts": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.0.8.tgz", + "integrity": "sha512-PecBL4vnsrpuks2lzzkRsOts8csJy338HNDKDIivbFmx92BVzh3ohOOv3XsoYPSXIHQvobF959W+aSk3RCZL/g==", + "requires": { + "@ethersproject/abi": "^5.0.5", + "@ethersproject/abstract-provider": "^5.0.4", + "@ethersproject/abstract-signer": "^5.0.4", + "@ethersproject/address": "^5.0.4", + "@ethersproject/bignumber": "^5.0.7", + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/constants": "^5.0.4", + "@ethersproject/logger": "^5.0.5", + "@ethersproject/properties": "^5.0.3" + }, + "dependencies": { + "@ethersproject/bignumber": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.0.12.tgz", + "integrity": "sha512-mbFZjwthx6vFlHG9owXP/C5QkNvsA+xHpDCkPPPdG2n1dS9AmZAL5DI0InNLid60rQWL3MXpEl19tFmtL7Q9jw==", + "requires": { + "@ethersproject/bytes": "^5.0.8", + "@ethersproject/logger": "^5.0.5", + "bn.js": "^4.4.0" + }, + "dependencies": { + "@ethersproject/bytes": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.0.8.tgz", + "integrity": "sha512-O+sJNVGzzuy51g+EMK8BegomqNIg+C2RO6vOt0XP6ac4o4saiq69FnjlsrNslaiMFVO7qcEHBsWJ9hx1tj1lMw==", + "requires": { + "@ethersproject/logger": "^5.0.5" + } + } + } + }, + "@ethersproject/constants": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.0.7.tgz", + "integrity": "sha512-cbQK1UpE4hamB52Eg6DLhJoXeQ1plSzekh5Ujir1xdREdwdsZPPXKczkrWqBBR0KyywJZHN/o/hj0w8j7scSGg==", + "requires": { + "@ethersproject/bignumber": "^5.0.7" + } + } + } + }, + "@ethersproject/hash": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.0.9.tgz", + "integrity": "sha512-e8/i2ZDeGSgCxXT0vocL54+pMbw5oX5fNjb2E3bAIvdkh5kH29M7zz1jHu1QDZnptIuvCZepIbhUH8lxKE2/SQ==", + "requires": { + "@ethersproject/abstract-signer": "^5.0.6", + "@ethersproject/address": "^5.0.5", + "@ethersproject/bignumber": "^5.0.8", + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/keccak256": "^5.0.3", + "@ethersproject/logger": "^5.0.5", + "@ethersproject/properties": "^5.0.4", + "@ethersproject/strings": "^5.0.4" + }, + "dependencies": { + "@ethersproject/bignumber": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.0.12.tgz", + "integrity": "sha512-mbFZjwthx6vFlHG9owXP/C5QkNvsA+xHpDCkPPPdG2n1dS9AmZAL5DI0InNLid60rQWL3MXpEl19tFmtL7Q9jw==", + "requires": { + "@ethersproject/bytes": "^5.0.8", + "@ethersproject/logger": "^5.0.5", + "bn.js": "^4.4.0" + }, + "dependencies": { + "@ethersproject/bytes": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.0.8.tgz", + "integrity": "sha512-O+sJNVGzzuy51g+EMK8BegomqNIg+C2RO6vOt0XP6ac4o4saiq69FnjlsrNslaiMFVO7qcEHBsWJ9hx1tj1lMw==", + "requires": { + "@ethersproject/logger": "^5.0.5" + } + } + } + }, + "@ethersproject/constants": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.0.7.tgz", + "integrity": "sha512-cbQK1UpE4hamB52Eg6DLhJoXeQ1plSzekh5Ujir1xdREdwdsZPPXKczkrWqBBR0KyywJZHN/o/hj0w8j7scSGg==", + "requires": { + "@ethersproject/bignumber": "^5.0.7" + } + }, + "@ethersproject/strings": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.0.7.tgz", + "integrity": "sha512-a+6T80LvmXGMOOWQTZHtGGQEg1z4v8rm8oX70KNs55YtPXI/5J3LBbVf5pyqCKSlmiBw5IaepPvs5XGalRUSZQ==", + "requires": { + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/constants": "^5.0.4", + "@ethersproject/logger": "^5.0.5" + } + } + } + }, + "@ethersproject/hdnode": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.0.7.tgz", + "integrity": "sha512-89tphqlji4y/LNE1cSaMQ3hrBtJ4lO1qWGi2hn54LiHym85DTw+zAKbA8QgmdSdJDLGR/kc9VHaIPQ+vZQ2LkQ==", + "requires": { + "@ethersproject/abstract-signer": "^5.0.4", + "@ethersproject/basex": "^5.0.3", + "@ethersproject/bignumber": "^5.0.7", + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/logger": "^5.0.5", + "@ethersproject/pbkdf2": "^5.0.3", + "@ethersproject/properties": "^5.0.3", + "@ethersproject/sha2": "^5.0.3", + "@ethersproject/signing-key": "^5.0.4", + "@ethersproject/strings": "^5.0.4", + "@ethersproject/transactions": "^5.0.5", + "@ethersproject/wordlists": "^5.0.4" + }, + "dependencies": { + "@ethersproject/bignumber": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.0.12.tgz", + "integrity": "sha512-mbFZjwthx6vFlHG9owXP/C5QkNvsA+xHpDCkPPPdG2n1dS9AmZAL5DI0InNLid60rQWL3MXpEl19tFmtL7Q9jw==", + "requires": { + "@ethersproject/bytes": "^5.0.8", + "@ethersproject/logger": "^5.0.5", + "bn.js": "^4.4.0" + }, + "dependencies": { + "@ethersproject/bytes": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.0.8.tgz", + "integrity": "sha512-O+sJNVGzzuy51g+EMK8BegomqNIg+C2RO6vOt0XP6ac4o4saiq69FnjlsrNslaiMFVO7qcEHBsWJ9hx1tj1lMw==", + "requires": { + "@ethersproject/logger": "^5.0.5" + } + } + } + }, + "@ethersproject/constants": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.0.7.tgz", + "integrity": "sha512-cbQK1UpE4hamB52Eg6DLhJoXeQ1plSzekh5Ujir1xdREdwdsZPPXKczkrWqBBR0KyywJZHN/o/hj0w8j7scSGg==", + "requires": { + "@ethersproject/bignumber": "^5.0.7" + } + }, + "@ethersproject/strings": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.0.7.tgz", + "integrity": "sha512-a+6T80LvmXGMOOWQTZHtGGQEg1z4v8rm8oX70KNs55YtPXI/5J3LBbVf5pyqCKSlmiBw5IaepPvs5XGalRUSZQ==", + "requires": { + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/constants": "^5.0.4", + "@ethersproject/logger": "^5.0.5" + } + } + } + }, + "@ethersproject/json-wallets": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.0.9.tgz", + "integrity": "sha512-EWuFvJd8nu90dkmJwmJddxOYCvFvMkKBsZi8rxTme2XEZsHKOFnybVkoL23u7ZtApuEfTKmVcR2PTwgZwqDsKw==", + "requires": { + "@ethersproject/abstract-signer": "^5.0.4", + "@ethersproject/address": "^5.0.4", + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/hdnode": "^5.0.4", + "@ethersproject/keccak256": "^5.0.3", + "@ethersproject/logger": "^5.0.5", + "@ethersproject/pbkdf2": "^5.0.3", + "@ethersproject/properties": "^5.0.3", + "@ethersproject/random": "^5.0.3", + "@ethersproject/strings": "^5.0.4", + "@ethersproject/transactions": "^5.0.5", + "aes-js": "3.0.0", + "scrypt-js": "3.0.1" + }, + "dependencies": { + "@ethersproject/bignumber": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.0.12.tgz", + "integrity": "sha512-mbFZjwthx6vFlHG9owXP/C5QkNvsA+xHpDCkPPPdG2n1dS9AmZAL5DI0InNLid60rQWL3MXpEl19tFmtL7Q9jw==", + "requires": { + "@ethersproject/bytes": "^5.0.8", + "@ethersproject/logger": "^5.0.5", + "bn.js": "^4.4.0" + }, + "dependencies": { + "@ethersproject/bytes": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.0.8.tgz", + "integrity": "sha512-O+sJNVGzzuy51g+EMK8BegomqNIg+C2RO6vOt0XP6ac4o4saiq69FnjlsrNslaiMFVO7qcEHBsWJ9hx1tj1lMw==", + "requires": { + "@ethersproject/logger": "^5.0.5" + } + } + } + }, + "@ethersproject/constants": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.0.7.tgz", + "integrity": "sha512-cbQK1UpE4hamB52Eg6DLhJoXeQ1plSzekh5Ujir1xdREdwdsZPPXKczkrWqBBR0KyywJZHN/o/hj0w8j7scSGg==", + "requires": { + "@ethersproject/bignumber": "^5.0.7" + } + }, + "@ethersproject/strings": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.0.7.tgz", + "integrity": "sha512-a+6T80LvmXGMOOWQTZHtGGQEg1z4v8rm8oX70KNs55YtPXI/5J3LBbVf5pyqCKSlmiBw5IaepPvs5XGalRUSZQ==", + "requires": { + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/constants": "^5.0.4", + "@ethersproject/logger": "^5.0.5" + } + } + } + }, "@ethersproject/keccak256": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.0.3.tgz", @@ -586,6 +983,120 @@ "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.0.5.tgz", "integrity": "sha512-gJj72WGzQhUtCk6kfvI8elTaPOQyMvrMghp/nbz0ivTo39fZ7IjypFh/ySDeUSdBNplAwhzWKKejQhdpyefg/w==" }, + "@ethersproject/networks": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.0.6.tgz", + "integrity": "sha512-2Cg1N5109zzFOBfkyuPj+FfF7ioqAsRffmybJ2lrsiB5skphIAE72XNSCs4fqktlf+rwSh/5o/UXRjXxvSktZw==", + "requires": { + "@ethersproject/logger": "^5.0.5" + } + }, + "@ethersproject/pbkdf2": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.0.6.tgz", + "integrity": "sha512-CUYciSxR/AaCoKMJk3WUW+BDhR41G3C+O9lOeZ4bR1wDhLKL2Z8p0ciF5XDEiVbmI4CToW6boVKybeVMdngRrg==", + "requires": { + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/sha2": "^5.0.3" + } + }, + "@ethersproject/properties": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.0.6.tgz", + "integrity": "sha512-a9DUMizYhJ0TbtuDkO9iYlb2CDlpSKqGPDr+amvlZhRspQ6jbl5Eq8jfu4SCcGlcfaTbguJmqGnyOGn1EFt6xA==", + "requires": { + "@ethersproject/logger": "^5.0.5" + } + }, + "@ethersproject/providers": { + "version": "5.0.17", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.0.17.tgz", + "integrity": "sha512-bJnvs5X7ttU5x2ekGJYG7R3Z+spZawLFfR0IDsbaMDLiCwZOyrgk+VTBU7amSFLT0WUhWFv8WwSUB+AryCQG1Q==", + "requires": { + "@ethersproject/abstract-provider": "^5.0.4", + "@ethersproject/abstract-signer": "^5.0.4", + "@ethersproject/address": "^5.0.4", + "@ethersproject/basex": "^5.0.3", + "@ethersproject/bignumber": "^5.0.7", + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/constants": "^5.0.4", + "@ethersproject/hash": "^5.0.4", + "@ethersproject/logger": "^5.0.5", + "@ethersproject/networks": "^5.0.3", + "@ethersproject/properties": "^5.0.3", + "@ethersproject/random": "^5.0.3", + "@ethersproject/rlp": "^5.0.3", + "@ethersproject/sha2": "^5.0.3", + "@ethersproject/strings": "^5.0.4", + "@ethersproject/transactions": "^5.0.5", + "@ethersproject/web": "^5.0.6", + "bech32": "1.1.4", + "ws": "7.2.3" + }, + "dependencies": { + "@ethersproject/bignumber": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.0.12.tgz", + "integrity": "sha512-mbFZjwthx6vFlHG9owXP/C5QkNvsA+xHpDCkPPPdG2n1dS9AmZAL5DI0InNLid60rQWL3MXpEl19tFmtL7Q9jw==", + "requires": { + "@ethersproject/bytes": "^5.0.8", + "@ethersproject/logger": "^5.0.5", + "bn.js": "^4.4.0" + }, + "dependencies": { + "@ethersproject/bytes": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.0.8.tgz", + "integrity": "sha512-O+sJNVGzzuy51g+EMK8BegomqNIg+C2RO6vOt0XP6ac4o4saiq69FnjlsrNslaiMFVO7qcEHBsWJ9hx1tj1lMw==", + "requires": { + "@ethersproject/logger": "^5.0.5" + } + } + } + }, + "@ethersproject/constants": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.0.7.tgz", + "integrity": "sha512-cbQK1UpE4hamB52Eg6DLhJoXeQ1plSzekh5Ujir1xdREdwdsZPPXKczkrWqBBR0KyywJZHN/o/hj0w8j7scSGg==", + "requires": { + "@ethersproject/bignumber": "^5.0.7" + } + }, + "@ethersproject/strings": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.0.7.tgz", + "integrity": "sha512-a+6T80LvmXGMOOWQTZHtGGQEg1z4v8rm8oX70KNs55YtPXI/5J3LBbVf5pyqCKSlmiBw5IaepPvs5XGalRUSZQ==", + "requires": { + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/constants": "^5.0.4", + "@ethersproject/logger": "^5.0.5" + } + }, + "ws": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.3.tgz", + "integrity": "sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ==" + } + } + }, + "@ethersproject/random": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.0.6.tgz", + "integrity": "sha512-8nsVNaZvZ9OD5NXfzE4mmz8IH/1DYJbAR95xpRxZkIuNmfn6QlMp49ccJYZWGhs6m0Zj2+FXjx3pzXfYlo9/dA==", + "requires": { + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/logger": "^5.0.5" + } + }, + "@ethersproject/rlp": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.0.6.tgz", + "integrity": "sha512-M223MTaydfmQSsvqAl0FJZDYFlSqt6cgbhnssLDwqCKYegAHE16vrFyo+eiOapYlt32XAIJm0BXlqSunULzZuQ==", + "requires": { + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/logger": "^5.0.5" + } + }, "@ethersproject/sha2": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.0.3.tgz", @@ -607,6 +1118,17 @@ } } }, + "@ethersproject/signing-key": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.0.7.tgz", + "integrity": "sha512-JYndnhFPKH0daPcIjyhi+GMcw3srIHkQ40hGRe6DA0CdGrpMfgyfSYDQ2D8HL2lgR+Xm4SHfEB0qba6+sCyrvg==", + "requires": { + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/logger": "^5.0.5", + "@ethersproject/properties": "^5.0.3", + "elliptic": "6.5.3" + } + }, "@ethersproject/solidity": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.0.3.tgz", @@ -629,6 +1151,238 @@ "@ethersproject/logger": "^5.0.5" } }, + "@ethersproject/transactions": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.0.8.tgz", + "integrity": "sha512-i7NtOXVzUe+YSU6QufzlRrI2WzHaTmULAKHJv4duIZMLqzehCBXGA9lTpFgFdqGYcQJ7vOtNFC2BB2mSjmuXqg==", + "requires": { + "@ethersproject/address": "^5.0.4", + "@ethersproject/bignumber": "^5.0.7", + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/constants": "^5.0.4", + "@ethersproject/keccak256": "^5.0.3", + "@ethersproject/logger": "^5.0.5", + "@ethersproject/properties": "^5.0.3", + "@ethersproject/rlp": "^5.0.3", + "@ethersproject/signing-key": "^5.0.4" + }, + "dependencies": { + "@ethersproject/bignumber": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.0.12.tgz", + "integrity": "sha512-mbFZjwthx6vFlHG9owXP/C5QkNvsA+xHpDCkPPPdG2n1dS9AmZAL5DI0InNLid60rQWL3MXpEl19tFmtL7Q9jw==", + "requires": { + "@ethersproject/bytes": "^5.0.8", + "@ethersproject/logger": "^5.0.5", + "bn.js": "^4.4.0" + }, + "dependencies": { + "@ethersproject/bytes": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.0.8.tgz", + "integrity": "sha512-O+sJNVGzzuy51g+EMK8BegomqNIg+C2RO6vOt0XP6ac4o4saiq69FnjlsrNslaiMFVO7qcEHBsWJ9hx1tj1lMw==", + "requires": { + "@ethersproject/logger": "^5.0.5" + } + } + } + }, + "@ethersproject/constants": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.0.7.tgz", + "integrity": "sha512-cbQK1UpE4hamB52Eg6DLhJoXeQ1plSzekh5Ujir1xdREdwdsZPPXKczkrWqBBR0KyywJZHN/o/hj0w8j7scSGg==", + "requires": { + "@ethersproject/bignumber": "^5.0.7" + } + } + } + }, + "@ethersproject/units": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.0.8.tgz", + "integrity": "sha512-3O4MaNHFs05vC5v2ZGqVFVWtO1WyqFejO78M7Qh16njo282aoMlENtVI6cn2B36zOLFXRvYt2pYx6xCG53qKzg==", + "requires": { + "@ethersproject/bignumber": "^5.0.7", + "@ethersproject/constants": "^5.0.4", + "@ethersproject/logger": "^5.0.5" + }, + "dependencies": { + "@ethersproject/bignumber": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.0.12.tgz", + "integrity": "sha512-mbFZjwthx6vFlHG9owXP/C5QkNvsA+xHpDCkPPPdG2n1dS9AmZAL5DI0InNLid60rQWL3MXpEl19tFmtL7Q9jw==", + "requires": { + "@ethersproject/bytes": "^5.0.8", + "@ethersproject/logger": "^5.0.5", + "bn.js": "^4.4.0" + } + }, + "@ethersproject/bytes": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.0.8.tgz", + "integrity": "sha512-O+sJNVGzzuy51g+EMK8BegomqNIg+C2RO6vOt0XP6ac4o4saiq69FnjlsrNslaiMFVO7qcEHBsWJ9hx1tj1lMw==", + "requires": { + "@ethersproject/logger": "^5.0.5" + } + }, + "@ethersproject/constants": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.0.7.tgz", + "integrity": "sha512-cbQK1UpE4hamB52Eg6DLhJoXeQ1plSzekh5Ujir1xdREdwdsZPPXKczkrWqBBR0KyywJZHN/o/hj0w8j7scSGg==", + "requires": { + "@ethersproject/bignumber": "^5.0.7" + } + } + } + }, + "@ethersproject/wallet": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.0.9.tgz", + "integrity": "sha512-GfpQF56PO/945SJq7Wdg5F5U6wkxaDgkAzcgGbCW6Joz8oW8MzKItkvYCzMh+j/8gJMzFncsuqX4zg2gq3J6nQ==", + "requires": { + "@ethersproject/abstract-provider": "^5.0.4", + "@ethersproject/abstract-signer": "^5.0.4", + "@ethersproject/address": "^5.0.4", + "@ethersproject/bignumber": "^5.0.7", + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/hash": "^5.0.4", + "@ethersproject/hdnode": "^5.0.4", + "@ethersproject/json-wallets": "^5.0.6", + "@ethersproject/keccak256": "^5.0.3", + "@ethersproject/logger": "^5.0.5", + "@ethersproject/properties": "^5.0.3", + "@ethersproject/random": "^5.0.3", + "@ethersproject/signing-key": "^5.0.4", + "@ethersproject/transactions": "^5.0.5", + "@ethersproject/wordlists": "^5.0.4" + }, + "dependencies": { + "@ethersproject/bignumber": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.0.12.tgz", + "integrity": "sha512-mbFZjwthx6vFlHG9owXP/C5QkNvsA+xHpDCkPPPdG2n1dS9AmZAL5DI0InNLid60rQWL3MXpEl19tFmtL7Q9jw==", + "requires": { + "@ethersproject/bytes": "^5.0.8", + "@ethersproject/logger": "^5.0.5", + "bn.js": "^4.4.0" + }, + "dependencies": { + "@ethersproject/bytes": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.0.8.tgz", + "integrity": "sha512-O+sJNVGzzuy51g+EMK8BegomqNIg+C2RO6vOt0XP6ac4o4saiq69FnjlsrNslaiMFVO7qcEHBsWJ9hx1tj1lMw==", + "requires": { + "@ethersproject/logger": "^5.0.5" + } + } + } + } + } + }, + "@ethersproject/web": { + "version": "5.0.11", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.0.11.tgz", + "integrity": "sha512-x03ihbPoN1S8Gsh9WSwxkYxUIumLi02ZEKJku1C43sxBfe+mdprWyvujzYlpuoRNfWRgNhdRDKMP8JbG6MwNGA==", + "requires": { + "@ethersproject/base64": "^5.0.3", + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/logger": "^5.0.5", + "@ethersproject/properties": "^5.0.3", + "@ethersproject/strings": "^5.0.4" + }, + "dependencies": { + "@ethersproject/bignumber": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.0.12.tgz", + "integrity": "sha512-mbFZjwthx6vFlHG9owXP/C5QkNvsA+xHpDCkPPPdG2n1dS9AmZAL5DI0InNLid60rQWL3MXpEl19tFmtL7Q9jw==", + "requires": { + "@ethersproject/bytes": "^5.0.8", + "@ethersproject/logger": "^5.0.5", + "bn.js": "^4.4.0" + }, + "dependencies": { + "@ethersproject/bytes": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.0.8.tgz", + "integrity": "sha512-O+sJNVGzzuy51g+EMK8BegomqNIg+C2RO6vOt0XP6ac4o4saiq69FnjlsrNslaiMFVO7qcEHBsWJ9hx1tj1lMw==", + "requires": { + "@ethersproject/logger": "^5.0.5" + } + } + } + }, + "@ethersproject/constants": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.0.7.tgz", + "integrity": "sha512-cbQK1UpE4hamB52Eg6DLhJoXeQ1plSzekh5Ujir1xdREdwdsZPPXKczkrWqBBR0KyywJZHN/o/hj0w8j7scSGg==", + "requires": { + "@ethersproject/bignumber": "^5.0.7" + } + }, + "@ethersproject/strings": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.0.7.tgz", + "integrity": "sha512-a+6T80LvmXGMOOWQTZHtGGQEg1z4v8rm8oX70KNs55YtPXI/5J3LBbVf5pyqCKSlmiBw5IaepPvs5XGalRUSZQ==", + "requires": { + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/constants": "^5.0.4", + "@ethersproject/logger": "^5.0.5" + } + } + } + }, + "@ethersproject/wordlists": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.0.7.tgz", + "integrity": "sha512-ZjQtYxm41FmHfYgpkdQG++EDcBPQWv9O6FfP6NndYRVaXaQZh6eq3sy7HQP8zCZ8dznKgy6ZyKECS8qdvnGHwA==", + "requires": { + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/hash": "^5.0.4", + "@ethersproject/logger": "^5.0.5", + "@ethersproject/properties": "^5.0.3", + "@ethersproject/strings": "^5.0.4" + }, + "dependencies": { + "@ethersproject/bignumber": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.0.12.tgz", + "integrity": "sha512-mbFZjwthx6vFlHG9owXP/C5QkNvsA+xHpDCkPPPdG2n1dS9AmZAL5DI0InNLid60rQWL3MXpEl19tFmtL7Q9jw==", + "requires": { + "@ethersproject/bytes": "^5.0.8", + "@ethersproject/logger": "^5.0.5", + "bn.js": "^4.4.0" + }, + "dependencies": { + "@ethersproject/bytes": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.0.8.tgz", + "integrity": "sha512-O+sJNVGzzuy51g+EMK8BegomqNIg+C2RO6vOt0XP6ac4o4saiq69FnjlsrNslaiMFVO7qcEHBsWJ9hx1tj1lMw==", + "requires": { + "@ethersproject/logger": "^5.0.5" + } + } + } + }, + "@ethersproject/constants": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.0.7.tgz", + "integrity": "sha512-cbQK1UpE4hamB52Eg6DLhJoXeQ1plSzekh5Ujir1xdREdwdsZPPXKczkrWqBBR0KyywJZHN/o/hj0w8j7scSGg==", + "requires": { + "@ethersproject/bignumber": "^5.0.7" + } + }, + "@ethersproject/strings": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.0.7.tgz", + "integrity": "sha512-a+6T80LvmXGMOOWQTZHtGGQEg1z4v8rm8oX70KNs55YtPXI/5J3LBbVf5pyqCKSlmiBw5IaepPvs5XGalRUSZQ==", + "requires": { + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/constants": "^5.0.4", + "@ethersproject/logger": "^5.0.5" + } + } + } + }, "@exchangeunion/grpc-dynamic-gateway": { "version": "0.3.10", "resolved": "https://registry.npmjs.org/@exchangeunion/grpc-dynamic-gateway/-/grpc-dynamic-gateway-0.3.10.tgz", @@ -1743,6 +2497,7 @@ "requires": { "anymatch": "~3.1.1", "braces": "~3.0.2", + "fsevents": "~2.1.2", "glob-parent": "~5.1.0", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", @@ -1759,6 +2514,13 @@ "to-regex-range": "^5.0.1" } }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, "glob-parent": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", @@ -1924,6 +2686,15 @@ "integrity": "sha512-UEyp8LwZ4Dg30kVU2Q3amHHyTn1jEdhCIE59ANed76GaT1Vp76DD3ZWSAxgCrw6wJ0TqeoBpqmfUHiUDPs//HQ==", "dev": true }, + "@types/ramda": { + "version": "0.27.33", + "resolved": "https://registry.npmjs.org/@types/ramda/-/ramda-0.27.33.tgz", + "integrity": "sha512-uStXyYPPe9VxOe++ymWugHoMGh8SlCFGVJxuZPZG+S0WHEqE3T9hKuFAkTNo5j1Cb3lWnfxMesT2SPyx333cGQ==", + "dev": true, + "requires": { + "ts-toolbelt": "^6.15.1" + } + }, "@types/secp256k1": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-3.5.0.tgz", @@ -2372,6 +3143,11 @@ "integrity": "sha1-anmQQ3ynNtXhKI25K9MmbV9csqo=", "dev": true }, + "aes-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", + "integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0=" + }, "ajv": { "version": "6.10.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", @@ -3224,6 +4000,11 @@ "tweetnacl": "^0.14.3" } }, + "bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" + }, "binary-extensions": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", @@ -6474,6 +7255,126 @@ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" }, + "ethers": { + "version": "5.0.24", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.0.24.tgz", + "integrity": "sha512-77CEtVC88fJGEhxGXRvQqAEH6e2A+ZFiv2FBT6ikXndlty5sw6vMatAhg1v+w3CaaGZOf1CP81jl4Mc8Zrj08A==", + "requires": { + "@ethersproject/abi": "5.0.9", + "@ethersproject/abstract-provider": "5.0.7", + "@ethersproject/abstract-signer": "5.0.9", + "@ethersproject/address": "5.0.8", + "@ethersproject/base64": "5.0.6", + "@ethersproject/basex": "5.0.6", + "@ethersproject/bignumber": "5.0.12", + "@ethersproject/bytes": "5.0.8", + "@ethersproject/constants": "5.0.7", + "@ethersproject/contracts": "5.0.8", + "@ethersproject/hash": "5.0.9", + "@ethersproject/hdnode": "5.0.7", + "@ethersproject/json-wallets": "5.0.9", + "@ethersproject/keccak256": "5.0.6", + "@ethersproject/logger": "5.0.8", + "@ethersproject/networks": "5.0.6", + "@ethersproject/pbkdf2": "5.0.6", + "@ethersproject/properties": "5.0.6", + "@ethersproject/providers": "5.0.17", + "@ethersproject/random": "5.0.6", + "@ethersproject/rlp": "5.0.6", + "@ethersproject/sha2": "5.0.6", + "@ethersproject/signing-key": "5.0.7", + "@ethersproject/solidity": "5.0.7", + "@ethersproject/strings": "5.0.7", + "@ethersproject/transactions": "5.0.8", + "@ethersproject/units": "5.0.8", + "@ethersproject/wallet": "5.0.9", + "@ethersproject/web": "5.0.11", + "@ethersproject/wordlists": "5.0.7" + }, + "dependencies": { + "@ethersproject/bignumber": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.0.12.tgz", + "integrity": "sha512-mbFZjwthx6vFlHG9owXP/C5QkNvsA+xHpDCkPPPdG2n1dS9AmZAL5DI0InNLid60rQWL3MXpEl19tFmtL7Q9jw==", + "requires": { + "@ethersproject/bytes": "^5.0.8", + "@ethersproject/logger": "^5.0.5", + "bn.js": "^4.4.0" + } + }, + "@ethersproject/bytes": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.0.8.tgz", + "integrity": "sha512-O+sJNVGzzuy51g+EMK8BegomqNIg+C2RO6vOt0XP6ac4o4saiq69FnjlsrNslaiMFVO7qcEHBsWJ9hx1tj1lMw==", + "requires": { + "@ethersproject/logger": "^5.0.5" + } + }, + "@ethersproject/constants": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.0.7.tgz", + "integrity": "sha512-cbQK1UpE4hamB52Eg6DLhJoXeQ1plSzekh5Ujir1xdREdwdsZPPXKczkrWqBBR0KyywJZHN/o/hj0w8j7scSGg==", + "requires": { + "@ethersproject/bignumber": "^5.0.7" + } + }, + "@ethersproject/keccak256": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.0.6.tgz", + "integrity": "sha512-eJ4Id/i2rwrf5JXEA7a12bG1phuxjj47mPZgDUbttuNBodhSuZF2nEO5QdpaRjmlphQ8Kt9PNqY/z7lhtJptZg==", + "requires": { + "@ethersproject/bytes": "^5.0.4", + "js-sha3": "0.5.7" + } + }, + "@ethersproject/logger": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.0.8.tgz", + "integrity": "sha512-SkJCTaVTnaZ3/ieLF5pVftxGEFX56pTH+f2Slrpv7cU0TNpUZNib84QQdukd++sWUp/S7j5t5NW+WegbXd4U/A==" + }, + "@ethersproject/sha2": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.0.6.tgz", + "integrity": "sha512-30gypDLkfkP5gE3llqi0jEuRV8m4/nvzeqmqMxiihZ7veFQHqDaGpyFeHzFim+qGeH9fq0lgYjavLvwW69+Fkw==", + "requires": { + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/logger": "^5.0.5", + "hash.js": "1.1.3" + } + }, + "@ethersproject/solidity": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.0.7.tgz", + "integrity": "sha512-dUevKUZ06p/VMLP/+cz4QUV+lA17NixucDJfm0ioWF0B3R0Lf+6wqwPchcqiAXlxkNFGIax7WNLgGMh4CkQ8iw==", + "requires": { + "@ethersproject/bignumber": "^5.0.7", + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/keccak256": "^5.0.3", + "@ethersproject/sha2": "^5.0.3", + "@ethersproject/strings": "^5.0.4" + } + }, + "@ethersproject/strings": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.0.7.tgz", + "integrity": "sha512-a+6T80LvmXGMOOWQTZHtGGQEg1z4v8rm8oX70KNs55YtPXI/5J3LBbVf5pyqCKSlmiBw5IaepPvs5XGalRUSZQ==", + "requires": { + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/constants": "^5.0.4", + "@ethersproject/logger": "^5.0.5" + } + }, + "hash.js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", + "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.0" + } + } + } + }, "evp_bytestokey": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", @@ -10062,6 +10963,7 @@ "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", "graceful-fs": "^4.2.4", "jest-regex-util": "^26.0.0", "jest-serializer": "^26.6.2", @@ -10116,6 +11018,13 @@ "to-regex-range": "^5.0.1" } }, + "fsevents": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.2.1.tgz", + "integrity": "sha512-bTLYHSeC0UH/EFXS9KqWnXuOl/wHK5Z/d+ghd5AsFMYN7wIGkUCOJyzy88+wJKkZPGON8u4Z9f6U4FdgURE9qA==", + "dev": true, + "optional": true + }, "graceful-fs": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", @@ -14159,6 +15068,11 @@ "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", "dev": true }, + "ramda": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.1.tgz", + "integrity": "sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw==" + }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -14662,6 +15576,11 @@ "xmlchars": "^2.2.0" } }, + "scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" + }, "secp256k1": { "version": "3.7.1", "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.7.1.tgz", @@ -16094,6 +17013,12 @@ "yn": "3.1.1" } }, + "ts-toolbelt": { + "version": "6.15.5", + "resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-6.15.5.tgz", + "integrity": "sha512-FZIXf1ksVyLcfr7M317jbB67XFJhOO1YqdTcuGaq9q5jLUoTikukZ+98TPjKiP2jC5CgmYdWWYs0s2nLSU0/1A==", + "dev": true + }, "tsconfig-paths": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", diff --git a/package.json b/package.json index ab7809913..a1bc3de2e 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "test:sim:logs": "cd test/simulation && ./logs.sh", "test:jest": "jest --testMatch='/test/jest/**/*.spec.[jt]s?(x)' --unhandled-rejections=strict --forceExit", "test:seedutil": "jest --testMatch='/seedutil/*.spec.[jt]s?(x)'", - "test:jest:watch": "jest --watch", + "test:jest:watch": "jest --watch --testMatch='/test/jest/**/*.spec.[jt]s?(x)'", "typedoc": "typedoc --out typedoc --module commonjs --target es6 lib --readme none", "preversion": "npm run lintNoFix && npm test && npm run test:sim:build && npm run test:sim", "postversion": "npm run compile", @@ -165,6 +165,7 @@ "cross-os": "^1.3.0", "distributions-poisson-quantile": "0.0.0", "dotenv": "^8.2.0", + "ethers": "^5.0.24", "express": "^4.17.1", "fastpriorityqueue": "^0.6.3", "google-protobuf": "^3.14.0", @@ -174,6 +175,7 @@ "keccak": "^2.1.0", "moment": "^2.29.1", "node-forge": "^0.10.0", + "ramda": "0.27.1", "rxjs": "^6.6.3", "secp256k1": "^3.7.1", "semver": "^6.3.0", @@ -198,6 +200,7 @@ "@types/mocha": "^8.2.0", "@types/node": "^14.14.12", "@types/node-forge": "^0.8.7", + "@types/ramda": "0.27.33", "@types/secp256k1": "^3.5.0", "@types/semver": "^6.2.2", "@types/sinon": "^9.0.9", diff --git a/test/jest/Connext.spec.ts b/test/jest/Connext.spec.ts index 52dadfe75..f0db2da08 100644 --- a/test/jest/Connext.spec.ts +++ b/test/jest/Connext.spec.ts @@ -5,6 +5,8 @@ import { CurrencyInstance } from '../../lib/db/types'; import Logger from '../../lib/Logger'; import { PaymentState } from '../../lib/swaps/SwapClient'; import { getUnitConverter } from '../utils'; +import { EthProvider } from '../../lib/connextclient/ethprovider'; +import { of } from 'rxjs'; const MOCK_TX_HASH = '0x5544332211'; jest.mock('../../lib/utils/utils', () => { @@ -93,6 +95,7 @@ describe('ConnextClient', () => { const MOCK_ETH_FREE_BALANCE_ON_CHAIN = 10n ** 18n; // 1 ETH const MOCK_USDT_FREE_BALANCE_ON_CHAIN = 10000n * 10n ** 6n; // 10000 USDT const DESTINATION_ADDRESS = '0x12345'; + const onChainTransfer = jest.fn(() => of(Promise.resolve({ hash: MOCK_TX_HASH }))); beforeEach(() => { connext['getBalance'] = jest.fn().mockImplementation((currency: string) => { @@ -105,25 +108,28 @@ describe('ConnextClient', () => { return { freeBalanceOnChain: 0 }; } }); - connext['sendRequest'] = jest.fn(); + connext['ethProvider'] = ({ + onChainTransfer, + } as unknown) as EthProvider; }); afterEach(() => { jest.clearAllMocks(); - }), - it('fails with custom fee', async () => { - expect.assertions(1); - try { - await connext.withdraw({ - currency: 'ETH', - destination: DESTINATION_ADDRESS, - amount: 123, - fee: 1, - }); - } catch (e) { - expect(e).toMatchSnapshot(); - } - }); + }); + + it('fails with custom fee', async () => { + expect.assertions(1); + try { + await connext.withdraw({ + currency: 'ETH', + destination: DESTINATION_ADDRESS, + amount: 123, + fee: 1, + }); + } catch (e) { + expect(e).toMatchSnapshot(); + } + }); it('fails to withdraw all ETH', async () => { expect.assertions(1); @@ -158,16 +164,8 @@ describe('ConnextClient', () => { destination: DESTINATION_ADDRESS, all: true, }); - expect(connext['sendRequest']).toHaveBeenCalledTimes(1); - expect(connext['sendRequest']).toHaveBeenCalledWith( - '/onchain-transfer', - 'POST', - expect.objectContaining({ - assetId: USDT_ASSET_ID, - amount: MOCK_USDT_FREE_BALANCE_ON_CHAIN, - recipient: DESTINATION_ADDRESS, - }), - ); + expect(onChainTransfer).toHaveBeenCalledTimes(1); + expect(onChainTransfer).toHaveBeenCalledWith(USDT_ASSET_ID, DESTINATION_ADDRESS, MOCK_USDT_FREE_BALANCE_ON_CHAIN); expect(txhash).toEqual(MOCK_TX_HASH); }); @@ -178,16 +176,8 @@ describe('ConnextClient', () => { destination: DESTINATION_ADDRESS, amount: 5000 * 10 ** 8, }); - expect(connext['sendRequest']).toHaveBeenCalledTimes(1); - expect(connext['sendRequest']).toHaveBeenCalledWith( - '/onchain-transfer', - 'POST', - expect.objectContaining({ - assetId: USDT_ASSET_ID, - amount: '5000000000', - recipient: DESTINATION_ADDRESS, - }), - ); + expect(onChainTransfer).toHaveBeenCalledTimes(1); + expect(onChainTransfer).toHaveBeenCalledWith(USDT_ASSET_ID, DESTINATION_ADDRESS, '5000000000'); expect(txhash).toEqual(MOCK_TX_HASH); }); @@ -198,16 +188,8 @@ describe('ConnextClient', () => { destination: DESTINATION_ADDRESS, amount: 1 * 10 ** 2, }); - expect(connext['sendRequest']).toHaveBeenCalledTimes(1); - expect(connext['sendRequest']).toHaveBeenCalledWith( - '/onchain-transfer', - 'POST', - expect.objectContaining({ - assetId: ETH_ASSET_ID, - amount: '1000000000000', - recipient: DESTINATION_ADDRESS, - }), - ); + expect(onChainTransfer).toHaveBeenCalledTimes(1); + expect(onChainTransfer).toHaveBeenCalledWith(ETH_ASSET_ID, DESTINATION_ADDRESS, '1000000000000'); expect(txhash).toEqual(MOCK_TX_HASH); }); });