From da9e4f89852cd92a3d8161e212808ceb4a357dbb Mon Sep 17 00:00:00 2001 From: Xaber Date: Sun, 19 Dec 2021 12:25:10 +0800 Subject: [PATCH 1/5] feat: update amount as withdraw final receive amount --- src/index.ts | 17 ++++++++++++----- src/utils/errors.ts | 4 +++- src/utils/util.ts | 5 +++++ 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/index.ts b/src/index.ts index b08c67d..0af5c83 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ import { getEverpayTxMessage, signMessageAsync, transferAsync } from './lib/sign' import { getSwapInfo, getEverpayBalance, getEverpayBalances, getEverpayInfo, getEverpayTransaction, getEverpayTransactions, getExpressInfo, getMintdEverpayTransactionByChainTxHash, postTx, getSwapPrice, placeSwapOrder, getFees, getFee } from './api' import { everpayTxVersion, getExpressHost, getEverpayHost, getSwapHost } from './config' -import { getTimestamp, getTokenBySymbol, toBN, getAccountChainType, fromDecimalToUnit, genTokenTag, matchTokenTag, genExpressData, fromUnitToDecimalBN, genBundleData, getTokenBurnFeeByChainType, getChainDecimalByChainType } from './utils/util' +import { getTimestamp, getTokenBySymbol, toBN, getAccountChainType, fromDecimalToUnit, genTokenTag, matchTokenTag, genExpressData, fromUnitToDecimalBN, genBundleData, getTokenBurnFeeByChainType, getChainDecimalByChainType, isArweaveChainPSTMode } from './utils/util' import { GetEverpayBalanceParams, GetEverpayBalancesParams, GetEverpayTransactionsParams } from './types/api' import { checkParams } from './utils/check' import { ERRORS } from './utils/errors' @@ -174,6 +174,10 @@ class Everpay extends EverpayBase { const from = this._config.account checkParams({ account: from, symbol, token, amount }) + if (isArweaveChainPSTMode(token) && parseInt(amount) !== +amount) { + throw new Error(ERRORS.DEPOSIT_ARWEAVE_PST_MUST_BE_INTEGER) + } + return await transferAsync(this._config, this._cachedInfo.everpay?.value as EverpayInfo, { symbol, token, @@ -182,6 +186,7 @@ class Everpay extends EverpayBase { }) } + // amount 为实际收款数量 async getEverpayTxWithoutSig ( type: 'transfer' | 'withdraw' | 'bundle', params: TransferParams | WithdrawParams | BundleParams @@ -211,6 +216,8 @@ class Everpay extends EverpayBase { checkParams({ amount }) const chainType = (params as WithdrawParams).chainType const tokenChainType = token?.chainType as string + const balance = await this.balance({ symbol }) + const decimalBalanceBN = fromUnitToDecimalBN(balance, token?.decimals ?? 0) // 快速提现 if (quickMode === true) { @@ -232,7 +239,7 @@ class Everpay extends EverpayBase { // 快速提现的 amount 为全部数量 decimalOperateAmountBN = fromUnitToDecimalBN(amount, token?.decimals ?? 0) - if (decimalOperateAmountBN.lte(quickWithdrawFeeBN)) { + if (decimalOperateAmountBN.plus(quickWithdrawFeeBN).gt(decimalBalanceBN)) { throw new Error(ERRORS.WITHDRAW_AMOUNT_LESS_THAN_FEE) } @@ -264,9 +271,9 @@ class Everpay extends EverpayBase { const targetChainType = chainType data = data !== undefined ? { ...data, targetChainType } : { targetChainType } } - decimalOperateAmountBN = fromUnitToDecimalBN(amount, token?.decimals ?? 0).minus(decimalFeeBN) - // 普通提现的 amount 为实际到账数量 - if (decimalOperateAmountBN.lte(0)) { + decimalOperateAmountBN = fromUnitToDecimalBN(amount, token?.decimals ?? 0) + + if (decimalOperateAmountBN.plus(decimalFeeBN).gt(decimalBalanceBN)) { throw new Error(ERRORS.WITHDRAW_AMOUNT_LESS_THAN_FEE) } } diff --git a/src/utils/errors.ts b/src/utils/errors.ts index 15dd093..d8ef682 100644 --- a/src/utils/errors.ts +++ b/src/utils/errors.ts @@ -15,5 +15,7 @@ export enum ERRORS { UNSUPPORTED_TOKEN_SWAP = 'UNSUPPORTED_TOKEN_SWAP', WITHDRAW_AMOUNT_LESS_THAN_FEE = 'WITHDRAW_AMOUNT_LESS_THAN_FEE', INSUFFICIENT_QUICK_WITHDRAWAL_AMOUNT = 'INSUFFICIENT_QUICK_WITHDRAWAL_AMOUNT', - WITHDRAW_TOKEN_NOT_SUPPORT_QUICK_MODE = 'WITHDRAW_TOKEN_NOT_SUPPORT_QUICK_MODE' + WITHDRAW_TOKEN_NOT_SUPPORT_QUICK_MODE = 'WITHDRAW_TOKEN_NOT_SUPPORT_QUICK_MODE', + DEPOSIT_ARWEAVE_PST_MUST_BE_INTEGER = 'DEPOSIT_ARWEAVE_PST_MUST_BE_INTEGER', + PST_WITHDARW_TO_ARWEAVE_MUST_BE_INTEGER = 'PST_WITHDARW_TO_ARWEAVE_MUST_BE_INTEGER' } diff --git a/src/utils/util.ts b/src/utils/util.ts index 60ab01a..91f8b66 100644 --- a/src/utils/util.ts +++ b/src/utils/util.ts @@ -54,6 +54,11 @@ const isArweaveAddress = (address: string): boolean => { return isString(address) && address.length === 43 && address.search(/[a-z0-9A-Z_-]{43}/g) === 0 } +export const isArweaveChainPSTMode = (token?: Token): boolean => { + if (token == null) return false + return token.chainType.includes(ChainType.arweave) && token.symbol.toUpperCase() !== 'AR' +} + export const getAccountChainType = (from: string): ChainType => { if (isEthereumAddress(from)) { return ChainType.ethereum From 14eccea1b89505eaa01515c2c3f8d80b11e60b53 Mon Sep 17 00:00:00 2001 From: Xaber Date: Mon, 20 Dec 2021 10:48:30 +0800 Subject: [PATCH 2/5] feat: process deposit pst check --- src/index.ts | 10 +++++----- test/deposit.pst.test.ts | 30 ++++++++++++++++++++++++++++++ test/withdraw.ethereum.test.ts | 34 +++++++++++++++++----------------- 3 files changed, 52 insertions(+), 22 deletions(-) create mode 100644 test/deposit.pst.test.ts diff --git a/src/index.ts b/src/index.ts index 0af5c83..b3f758d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -167,17 +167,17 @@ class Everpay extends EverpayBase { async deposit (params: DepositParams): Promise { await this.info() const { amount, symbol } = params - const token = getTokenBySymbol(symbol, this._cachedInfo?.everpay?.value.tokenList) as Token - const accountChainType = getAccountChainType(this._config.account as string) - const chainDecimal = getChainDecimalByChainType(token, accountChainType) - const value = utils.parseUnits(toBN(amount).toString(), chainDecimal) const from = this._config.account + const token = getTokenBySymbol(symbol, this._cachedInfo?.everpay?.value.tokenList) as Token checkParams({ account: from, symbol, token, amount }) - if (isArweaveChainPSTMode(token) && parseInt(amount) !== +amount) { throw new Error(ERRORS.DEPOSIT_ARWEAVE_PST_MUST_BE_INTEGER) } + const accountChainType = getAccountChainType(this._config.account as string) + const chainDecimal = getChainDecimalByChainType(token, accountChainType) + const value = utils.parseUnits(toBN(amount).toString(), chainDecimal) + return await transferAsync(this._config, this._cachedInfo.everpay?.value as EverpayInfo, { symbol, token, diff --git a/test/deposit.pst.test.ts b/test/deposit.pst.test.ts new file mode 100644 index 0000000..fe93b92 --- /dev/null +++ b/test/deposit.pst.test.ts @@ -0,0 +1,30 @@ +import Everpay from '../src/index' +import { arWallet2 } from './constants/wallet' +import { ArweaveTransaction } from '../src/types' + +const everpay = new Everpay({ + account: arWallet2.address, + arJWK: arWallet2.jwk, + debug: true +}) + +test(`check ${arWallet2.address} deposit VRT`, async () => { + return await everpay.deposit({ + symbol: 'vrt', + amount: '1' + }).then((arTx) => { + console.log('arTx', arTx as ArweaveTransaction) + expect((arTx as ArweaveTransaction).id).toBeTruthy() + }) +}) + +test(`check ${arWallet2.address} deposit VRT failed`, async () => { + await expect( + everpay.deposit({ + symbol: 'vrt', + amount: '0.1' + }) + ) + .rejects + .toThrow('DEPOSIT_ARWEAVE_PST_MUST_BE_INTEGER') +}) diff --git a/test/withdraw.ethereum.test.ts b/test/withdraw.ethereum.test.ts index 603b184..ea394de 100644 --- a/test/withdraw.ethereum.test.ts +++ b/test/withdraw.ethereum.test.ts @@ -5,24 +5,24 @@ import { ChainType } from '../src/types' const provider = new ethers.providers.InfuraProvider('kovan') -test(`${ethWalletHasUSDT.address} withdraw USDT to ${ethWalletHasUSDT2.address}`, async () => { - const signer = new ethers.Wallet(ethWalletHasUSDT.privateKey, provider) - const everpay = new Everpay({ - account: ethWalletHasUSDT.address, - ethConnectedSigner: signer, - debug: true - }) +// test(`${ethWalletHasUSDT.address} withdraw USDT to ${ethWalletHasUSDT2.address}`, async () => { +// const signer = new ethers.Wallet(ethWalletHasUSDT.privateKey, provider) +// const everpay = new Everpay({ +// account: ethWalletHasUSDT.address, +// ethConnectedSigner: signer, +// debug: true +// }) - return await everpay.withdraw({ - chainType: ChainType.ethereum, - symbol: 'usdt', - amount: '100', - to: ethWalletHasUSDT2.address - }).then(withdrawResult => { - console.log('withdrawResult', withdrawResult) - expect(withdrawResult.status).toBe('ok') - }) -}) +// return await everpay.withdraw({ +// chainType: ChainType.ethereum, +// symbol: 'usdt', +// amount: '100', +// to: ethWalletHasUSDT2.address +// }).then(withdrawResult => { +// console.log('withdrawResult', withdrawResult) +// expect(withdrawResult.status).toBe('ok') +// }) +// }) test(`use another ${ethWalletHasUSDT.address} singer to sign ${ethWalletHasUSDT2.address}'s tx`, async () => { const signer = new ethers.Wallet(ethWalletHasUSDT.privateKey, provider) From 5d07361ffc82816ac330840911743fe00fcd5272 Mon Sep 17 00:00:00 2001 From: Xaber Date: Mon, 20 Dec 2021 11:16:29 +0800 Subject: [PATCH 3/5] feat: add pst withdraw to arweave validation --- src/index.ts | 14 +++++++--- test/withdraw.pst.test.ts | 56 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 test/withdraw.pst.test.ts diff --git a/src/index.ts b/src/index.ts index b3f758d..81511d6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,7 +9,7 @@ import { utils } from 'ethers' import { Config, EverpayInfo, EverpayBase, BalanceParams, BalancesParams, DepositParams, SwapInfo, SendEverpayTxResult, TransferParams, WithdrawParams, EverpayTxWithoutSig, EverpayAction, BundleData, - SwapOrder, SwapPriceParams, SwapPriceResult, FeeItem, + SwapOrder, SwapPriceParams, SwapPriceResult, FeeItem, ChainType, BalanceItem, TxsParams, TxsByAccountParams, TxsResult, EverpayTransaction, Token, EthereumTransaction, ArweaveTransaction, ExpressInfo, CachedInfo, InternalTransferItem, BundleDataWithSigs, BundleParams } from './types' import { swapParamsClientToServer, swapParamsServerToClient } from './utils/swap' @@ -170,11 +170,13 @@ class Everpay extends EverpayBase { const from = this._config.account const token = getTokenBySymbol(symbol, this._cachedInfo?.everpay?.value.tokenList) as Token checkParams({ account: from, symbol, token, amount }) - if (isArweaveChainPSTMode(token) && parseInt(amount) !== +amount) { + const accountChainType = getAccountChainType(this._config.account as string) + + // arweave 上的 PST 充值必须是整数 + if (isArweaveChainPSTMode(token) && accountChainType === ChainType.arweave && parseInt(amount) !== +amount) { throw new Error(ERRORS.DEPOSIT_ARWEAVE_PST_MUST_BE_INTEGER) } - const accountChainType = getAccountChainType(this._config.account as string) const chainDecimal = getChainDecimalByChainType(token, accountChainType) const value = utils.parseUnits(toBN(amount).toString(), chainDecimal) @@ -215,6 +217,12 @@ class Everpay extends EverpayBase { } else if (type === 'withdraw') { checkParams({ amount }) const chainType = (params as WithdrawParams).chainType + + // PST 提现到 arweave 网络必须是整数 + if (isArweaveChainPSTMode(token) && chainType === ChainType.arweave && parseInt(amount) !== +amount) { + throw new Error(ERRORS.PST_WITHDARW_TO_ARWEAVE_MUST_BE_INTEGER) + } + const tokenChainType = token?.chainType as string const balance = await this.balance({ symbol }) const decimalBalanceBN = fromUnitToDecimalBN(balance, token?.decimals ?? 0) diff --git a/test/withdraw.pst.test.ts b/test/withdraw.pst.test.ts new file mode 100644 index 0000000..d06b735 --- /dev/null +++ b/test/withdraw.pst.test.ts @@ -0,0 +1,56 @@ +import Everpay from '../src/index' +import { arWallet2, ethWalletHasUSDT } from './constants/wallet' +import { ChainType } from '../src/types' + +test(`${arWallet2.address} withdraw vrt to ${arWallet2.address}`, async () => { + const everpay = new Everpay({ + account: arWallet2.address, + arJWK: arWallet2.jwk, + debug: true + }) + + return await everpay.withdraw({ + chainType: ChainType.arweave, + symbol: 'vrt', + amount: '1', + to: arWallet2.address + }).then(withdrawResult => { + console.log('withdrawResult', withdrawResult) + expect(withdrawResult.status).toBe('ok') + }) +}) + +test(`check ${arWallet2.address} deposit VRT failed`, async () => { + const everpay = new Everpay({ + account: arWallet2.address, + arJWK: arWallet2.jwk, + debug: true + }) + await expect( + everpay.withdraw({ + chainType: ChainType.arweave, + symbol: 'vrt', + amount: '0.1' + }) + ) + .rejects + .toThrow('PST_WITHDARW_TO_ARWEAVE_MUST_BE_INTEGER') +}) + +test(`${arWallet2.address} withdraw ar to ethereum address ${ethWalletHasUSDT.address}`, async () => { + const everpay = new Everpay({ + account: arWallet2.address, + arJWK: arWallet2.jwk, + debug: true + }) + + return await everpay.withdraw({ + chainType: ChainType.ethereum, + symbol: 'vrt', + amount: '0.000010001', + to: ethWalletHasUSDT.address + }).then(withdrawResult => { + console.log('withdrawResult', withdrawResult) + expect(withdrawResult.status).toBe('ok') + }) +}) From 7992ce07872481a76fb38bff4da5176ddc4c84d6 Mon Sep 17 00:00:00 2001 From: Xaber Date: Mon, 20 Dec 2021 11:32:56 +0800 Subject: [PATCH 4/5] feat: add PST test cases --- test/deposit.pst.test.ts | 28 ++++++++++++++++++++++++---- test/transfer.pst.test.ts | 19 +++++++++++++++++++ test/withdraw.ethereum.test.ts | 34 +++++++++++++++++----------------- 3 files changed, 60 insertions(+), 21 deletions(-) create mode 100644 test/transfer.pst.test.ts diff --git a/test/deposit.pst.test.ts b/test/deposit.pst.test.ts index fe93b92..cc4b3a9 100644 --- a/test/deposit.pst.test.ts +++ b/test/deposit.pst.test.ts @@ -1,15 +1,35 @@ import Everpay from '../src/index' -import { arWallet2 } from './constants/wallet' +import { ethWalletHasUSDT, arWallet2 } from './constants/wallet' import { ArweaveTransaction } from '../src/types' +import { ethers } from 'ethers' -const everpay = new Everpay({ +const provider = new ethers.providers.InfuraProvider('kovan') +const signer = new ethers.Wallet(ethWalletHasUSDT.privateKey, provider) + +const everpayEthereumMode = new Everpay({ + account: ethWalletHasUSDT.address, + ethConnectedSigner: signer, + debug: true +}) + +test(`check ${ethWalletHasUSDT.address} deposit vrt`, async () => { + return await everpayEthereumMode.deposit({ + symbol: 'vrt', + amount: '0.000000001' + }).then(ethTx => { + console.log('ethTx', ethTx) + expect(ethTx).toBeTruthy() + }) +}) + +const everpayARMode = new Everpay({ account: arWallet2.address, arJWK: arWallet2.jwk, debug: true }) test(`check ${arWallet2.address} deposit VRT`, async () => { - return await everpay.deposit({ + return await everpayARMode.deposit({ symbol: 'vrt', amount: '1' }).then((arTx) => { @@ -20,7 +40,7 @@ test(`check ${arWallet2.address} deposit VRT`, async () => { test(`check ${arWallet2.address} deposit VRT failed`, async () => { await expect( - everpay.deposit({ + everpayARMode.deposit({ symbol: 'vrt', amount: '0.1' }) diff --git a/test/transfer.pst.test.ts b/test/transfer.pst.test.ts new file mode 100644 index 0000000..da70c06 --- /dev/null +++ b/test/transfer.pst.test.ts @@ -0,0 +1,19 @@ +import Everpay from '../src/index' +import { arWallet2, ethWalletHasUSDT } from './constants/wallet' + +test(`${arWallet2.address} withdraw ar to ${arWallet2.address}`, async () => { + const everpay = new Everpay({ + account: arWallet2.address, + arJWK: arWallet2.jwk, + debug: true + }) + + return await everpay.transfer({ + symbol: 'VRT', + amount: '0.000010001', + to: ethWalletHasUSDT.address + }).then(withdrawResult => { + console.log('withdrawResult', withdrawResult) + expect(withdrawResult.status).toBe('ok') + }) +}) diff --git a/test/withdraw.ethereum.test.ts b/test/withdraw.ethereum.test.ts index ea394de..603b184 100644 --- a/test/withdraw.ethereum.test.ts +++ b/test/withdraw.ethereum.test.ts @@ -5,24 +5,24 @@ import { ChainType } from '../src/types' const provider = new ethers.providers.InfuraProvider('kovan') -// test(`${ethWalletHasUSDT.address} withdraw USDT to ${ethWalletHasUSDT2.address}`, async () => { -// const signer = new ethers.Wallet(ethWalletHasUSDT.privateKey, provider) -// const everpay = new Everpay({ -// account: ethWalletHasUSDT.address, -// ethConnectedSigner: signer, -// debug: true -// }) +test(`${ethWalletHasUSDT.address} withdraw USDT to ${ethWalletHasUSDT2.address}`, async () => { + const signer = new ethers.Wallet(ethWalletHasUSDT.privateKey, provider) + const everpay = new Everpay({ + account: ethWalletHasUSDT.address, + ethConnectedSigner: signer, + debug: true + }) -// return await everpay.withdraw({ -// chainType: ChainType.ethereum, -// symbol: 'usdt', -// amount: '100', -// to: ethWalletHasUSDT2.address -// }).then(withdrawResult => { -// console.log('withdrawResult', withdrawResult) -// expect(withdrawResult.status).toBe('ok') -// }) -// }) + return await everpay.withdraw({ + chainType: ChainType.ethereum, + symbol: 'usdt', + amount: '100', + to: ethWalletHasUSDT2.address + }).then(withdrawResult => { + console.log('withdrawResult', withdrawResult) + expect(withdrawResult.status).toBe('ok') + }) +}) test(`use another ${ethWalletHasUSDT.address} singer to sign ${ethWalletHasUSDT2.address}'s tx`, async () => { const signer = new ethers.Wallet(ethWalletHasUSDT.privateKey, provider) From 1eddb59d48ffbf0c720f6a1ee370e3bb6f4b88e9 Mon Sep 17 00:00:00 2001 From: Xaber Date: Mon, 20 Dec 2021 16:03:14 +0800 Subject: [PATCH 5/5] Update package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4c55938..118e652 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "everpay", - "version": "0.2.1", + "version": "0.3.0", "main": "./cjs/index.js", "module": "./esm/index.js", "files": [