@shapeshiftoss/swapper 7.1.0 → 7.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.d.ts +1 -0
- package/dist/api.js +1 -0
- package/dist/swappers/cow/CowApprovalNeeded/CowApprovalNeeded.d.ts +3 -0
- package/dist/swappers/cow/CowApprovalNeeded/CowApprovalNeeded.js +42 -0
- package/dist/swappers/cow/CowApproveInfinite/CowApproveInfinite.d.ts +3 -0
- package/dist/swappers/cow/CowApproveInfinite/CowApproveInfinite.js +31 -0
- package/dist/swappers/cow/CowSwapper.d.ts +11 -7
- package/dist/swappers/cow/CowSwapper.js +4 -4
- package/dist/swappers/cow/utils/constants.d.ts +1 -0
- package/dist/swappers/index.d.ts +1 -0
- package/dist/swappers/index.js +1 -0
- package/dist/swappers/{zrx/utils → utils}/abi/erc20-abi.d.ts +0 -0
- package/dist/swappers/{zrx/utils → utils}/abi/erc20-abi.js +0 -0
- package/dist/swappers/{zrx/utils → utils}/abi/erc20Allowance-abi.d.ts +0 -0
- package/dist/swappers/{zrx/utils → utils}/abi/erc20Allowance-abi.js +0 -0
- package/dist/swappers/utils/helpers/helpers.d.ts +33 -0
- package/dist/swappers/utils/helpers/helpers.js +98 -1
- package/dist/swappers/{zrx/utils/test-data/setupZrxDeps.d.ts → utils/test-data/setupDeps.d.ts} +1 -1
- package/dist/swappers/{zrx/utils/test-data/setupZrxDeps.js → utils/test-data/setupDeps.js} +3 -3
- package/dist/swappers/utils/test-data/setupSwapQuote.d.ts +8 -0
- package/dist/swappers/utils/test-data/setupSwapQuote.js +30 -0
- package/dist/swappers/zrx/ZrxApprovalNeeded/ZrxApprovalNeeded.js +2 -2
- package/dist/swappers/zrx/ZrxApproveInfinite/ZrxApproveInfinite.js +2 -2
- package/dist/swappers/zrx/utils/helpers/helpers.d.ts +0 -32
- package/dist/swappers/zrx/utils/helpers/helpers.js +1 -96
- package/dist/swappers/zrx/utils/test-data/{setupSwapQuote.d.ts → setupZrxSwapQuote.d.ts} +0 -7
- package/dist/swappers/zrx/utils/test-data/{setupSwapQuote.js → setupZrxSwapQuote.js} +1 -27
- package/dist/swappers/zrx/zrxBuildTrade/zrxBuildTrade.js +4 -4
- package/package.json +1 -1
package/dist/api.d.ts
CHANGED
|
@@ -151,6 +151,7 @@ export declare enum SwapErrorTypes {
|
|
|
151
151
|
UNSUPPORTED_PAIR = "UNSUPPORTED_PAIR",
|
|
152
152
|
USD_RATE_FAILED = "USD_RATE_FAILED",
|
|
153
153
|
UNSUPPORTED_CHAIN = "UNSUPPORTED_CHAIN",
|
|
154
|
+
UNSUPPORTED_NAMESPACE = "UNSUPPORTED_NAMESPACE",
|
|
154
155
|
VALIDATION_FAILED = "VALIDATION_FAILED",
|
|
155
156
|
MAKE_MEMO_FAILED = "MAKE_MEMO_FAILED",
|
|
156
157
|
PRICE_RATIO_FAILED = "PRICE_RATIO_FAILED",
|
package/dist/api.js
CHANGED
|
@@ -28,6 +28,7 @@ var SwapErrorTypes;
|
|
|
28
28
|
SwapErrorTypes["UNSUPPORTED_PAIR"] = "UNSUPPORTED_PAIR";
|
|
29
29
|
SwapErrorTypes["USD_RATE_FAILED"] = "USD_RATE_FAILED";
|
|
30
30
|
SwapErrorTypes["UNSUPPORTED_CHAIN"] = "UNSUPPORTED_CHAIN";
|
|
31
|
+
SwapErrorTypes["UNSUPPORTED_NAMESPACE"] = "UNSUPPORTED_NAMESPACE";
|
|
31
32
|
SwapErrorTypes["VALIDATION_FAILED"] = "VALIDATION_FAILED";
|
|
32
33
|
SwapErrorTypes["MAKE_MEMO_FAILED"] = "MAKE_MEMO_FAILED";
|
|
33
34
|
SwapErrorTypes["PRICE_RATIO_FAILED"] = "PRICE_RATIO_FAILED";
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { ApprovalNeededInput, ApprovalNeededOutput } from '../../../api';
|
|
2
|
+
import { CowSwapperDeps } from '../CowSwapper';
|
|
3
|
+
export declare function CowApprovalNeeded({ adapter, web3 }: CowSwapperDeps, { quote, wallet }: ApprovalNeededInput<'eip155:1'>): Promise<ApprovalNeededOutput>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CowApprovalNeeded = void 0;
|
|
4
|
+
const caip_1 = require("@shapeshiftoss/caip");
|
|
5
|
+
const api_1 = require("../../../api");
|
|
6
|
+
const erc20Allowance_abi_1 = require("../../utils/abi/erc20Allowance-abi");
|
|
7
|
+
const bignumber_1 = require("../../utils/bignumber");
|
|
8
|
+
const helpers_1 = require("../../utils/helpers/helpers");
|
|
9
|
+
const COW_SWAP_VAULT_RELAYER_ADDRESS = '0xc92e8bdf79f0507f65a392b0ab4667716bfe0110';
|
|
10
|
+
async function CowApprovalNeeded({ adapter, web3 }, { quote, wallet }) {
|
|
11
|
+
const { sellAsset } = quote;
|
|
12
|
+
const { assetReference: sellAssetErc20Address, assetNamespace } = (0, caip_1.fromAssetId)(sellAsset.assetId);
|
|
13
|
+
try {
|
|
14
|
+
if (assetNamespace !== 'erc20') {
|
|
15
|
+
throw new api_1.SwapError('[CowApprovalNeeded] - unsupported asset namespace', {
|
|
16
|
+
code: api_1.SwapErrorTypes.UNSUPPORTED_NAMESPACE,
|
|
17
|
+
details: { assetNamespace }
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
const receiveAddress = await adapter.getAddress({ wallet });
|
|
21
|
+
const allowanceResult = await (0, helpers_1.getERC20Allowance)({
|
|
22
|
+
web3,
|
|
23
|
+
erc20AllowanceAbi: erc20Allowance_abi_1.erc20AllowanceAbi,
|
|
24
|
+
sellAssetErc20Address,
|
|
25
|
+
spenderAddress: COW_SWAP_VAULT_RELAYER_ADDRESS,
|
|
26
|
+
ownerAddress: receiveAddress
|
|
27
|
+
});
|
|
28
|
+
const allowanceOnChain = (0, bignumber_1.bnOrZero)(allowanceResult);
|
|
29
|
+
return {
|
|
30
|
+
approvalNeeded: allowanceOnChain.lte((0, bignumber_1.bnOrZero)(quote.sellAmount))
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
catch (e) {
|
|
34
|
+
if (e instanceof api_1.SwapError)
|
|
35
|
+
throw e;
|
|
36
|
+
throw new api_1.SwapError('[CowApprovalNeeded]', {
|
|
37
|
+
cause: e,
|
|
38
|
+
code: api_1.SwapErrorTypes.CHECK_APPROVAL_FAILED
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.CowApprovalNeeded = CowApprovalNeeded;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CowApproveInfinite = void 0;
|
|
4
|
+
const api_1 = require("../../../api");
|
|
5
|
+
const erc20_abi_1 = require("../../utils/abi/erc20-abi");
|
|
6
|
+
const helpers_1 = require("../../utils/helpers/helpers");
|
|
7
|
+
const constants_1 = require("../utils/constants");
|
|
8
|
+
async function CowApproveInfinite({ adapter, web3 }, { quote, wallet }) {
|
|
9
|
+
try {
|
|
10
|
+
const allowanceGrantRequired = await (0, helpers_1.grantAllowance)({
|
|
11
|
+
quote: {
|
|
12
|
+
...quote,
|
|
13
|
+
sellAmount: constants_1.MAX_ALLOWANCE
|
|
14
|
+
},
|
|
15
|
+
wallet,
|
|
16
|
+
adapter,
|
|
17
|
+
erc20Abi: erc20_abi_1.erc20Abi,
|
|
18
|
+
web3
|
|
19
|
+
});
|
|
20
|
+
return allowanceGrantRequired;
|
|
21
|
+
}
|
|
22
|
+
catch (e) {
|
|
23
|
+
if (e instanceof api_1.SwapError)
|
|
24
|
+
throw e;
|
|
25
|
+
throw new api_1.SwapError('[CowApproveInfinite]', {
|
|
26
|
+
cause: e,
|
|
27
|
+
code: api_1.SwapErrorTypes.APPROVE_INFINITE_FAILED
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
exports.CowApproveInfinite = CowApproveInfinite;
|
|
@@ -1,21 +1,25 @@
|
|
|
1
|
-
import { AssetId
|
|
1
|
+
import { AssetId } from '@shapeshiftoss/caip';
|
|
2
|
+
import { ethereum } from '@shapeshiftoss/chain-adapters';
|
|
2
3
|
import { Asset } from '@shapeshiftoss/types';
|
|
4
|
+
import Web3 from 'web3';
|
|
3
5
|
import { ApprovalNeededInput, ApprovalNeededOutput, ApproveInfiniteInput, BuildTradeInput, BuyAssetBySellIdInput, ExecuteTradeInput, GetTradeQuoteInput, Swapper, SwapperType, Trade, TradeQuote, TradeResult, TradeTxs } from '../../api';
|
|
4
6
|
export declare type CowSwapperDeps = {
|
|
5
7
|
apiUrl: string;
|
|
8
|
+
adapter: ethereum.ChainAdapter;
|
|
9
|
+
web3: Web3;
|
|
6
10
|
};
|
|
7
|
-
export declare class CowSwapper implements Swapper<
|
|
11
|
+
export declare class CowSwapper implements Swapper<'eip155:1'> {
|
|
8
12
|
static swapperName: string;
|
|
9
13
|
deps: CowSwapperDeps;
|
|
10
14
|
constructor(deps: CowSwapperDeps);
|
|
11
15
|
initialize(): Promise<void>;
|
|
12
16
|
getType(): SwapperType;
|
|
13
|
-
buildTrade(args: BuildTradeInput): Promise<Trade<
|
|
14
|
-
getTradeQuote(input: GetTradeQuoteInput): Promise<TradeQuote<
|
|
17
|
+
buildTrade(args: BuildTradeInput): Promise<Trade<'eip155:1'>>;
|
|
18
|
+
getTradeQuote(input: GetTradeQuoteInput): Promise<TradeQuote<'eip155:1'>>;
|
|
15
19
|
getUsdRate(input: Asset): Promise<string>;
|
|
16
|
-
executeTrade(args: ExecuteTradeInput<
|
|
17
|
-
approvalNeeded(args: ApprovalNeededInput<
|
|
18
|
-
approveInfinite(args: ApproveInfiniteInput<
|
|
20
|
+
executeTrade(args: ExecuteTradeInput<'eip155:1'>): Promise<TradeResult>;
|
|
21
|
+
approvalNeeded(args: ApprovalNeededInput<'eip155:1'>): Promise<ApprovalNeededOutput>;
|
|
22
|
+
approveInfinite(args: ApproveInfiniteInput<'eip155:1'>): Promise<string>;
|
|
19
23
|
filterBuyAssetsBySellAssetId(args: BuyAssetBySellIdInput): AssetId[];
|
|
20
24
|
filterAssetIdsBySellable(assetIds: AssetId[]): AssetId[];
|
|
21
25
|
getTradeTxs(): Promise<TradeTxs>;
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CowSwapper = void 0;
|
|
4
4
|
const api_1 = require("../../api");
|
|
5
|
+
const CowApprovalNeeded_1 = require("./CowApprovalNeeded/CowApprovalNeeded");
|
|
6
|
+
const CowApproveInfinite_1 = require("./CowApproveInfinite/CowApproveInfinite");
|
|
5
7
|
const blacklist_1 = require("./utils/blacklist");
|
|
6
8
|
const helpers_1 = require("./utils/helpers/helpers");
|
|
7
9
|
class CowSwapper {
|
|
@@ -29,12 +31,10 @@ class CowSwapper {
|
|
|
29
31
|
throw new Error('CowSwapper: executeTrade unimplemented');
|
|
30
32
|
}
|
|
31
33
|
async approvalNeeded(args) {
|
|
32
|
-
|
|
33
|
-
throw new Error('CowSwapper: approvalNeeded unimplemented');
|
|
34
|
+
return (0, CowApprovalNeeded_1.CowApprovalNeeded)(this.deps, args);
|
|
34
35
|
}
|
|
35
36
|
async approveInfinite(args) {
|
|
36
|
-
|
|
37
|
-
throw new Error('CowSwapper: approveInfinite unimplemented');
|
|
37
|
+
return (0, CowApproveInfinite_1.CowApproveInfinite)(this.deps, args);
|
|
38
38
|
}
|
|
39
39
|
filterBuyAssetsBySellAssetId(args) {
|
|
40
40
|
const { assetIds = [], sellAssetId } = args;
|
package/dist/swappers/index.d.ts
CHANGED
package/dist/swappers/index.js
CHANGED
|
@@ -17,3 +17,4 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
17
17
|
__exportStar(require("./zrx/ZrxSwapper"), exports);
|
|
18
18
|
__exportStar(require("./thorchain/ThorchainSwapper"), exports);
|
|
19
19
|
__exportStar(require("./test/TestSwapper"), exports);
|
|
20
|
+
__exportStar(require("./cow/CowSwapper"), exports);
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -1,7 +1,40 @@
|
|
|
1
|
+
import { ethereum } from '@shapeshiftoss/chain-adapters';
|
|
2
|
+
import { HDWallet } from '@shapeshiftoss/hdwallet-core';
|
|
3
|
+
import { Asset } from '@shapeshiftoss/types';
|
|
4
|
+
import BigNumber from 'bignumber.js';
|
|
5
|
+
import Web3 from 'web3';
|
|
6
|
+
import { AbiItem } from 'web3-utils';
|
|
7
|
+
import { TradeQuote } from '../../../api';
|
|
1
8
|
import { BN } from '../bignumber';
|
|
9
|
+
export declare type GetAllowanceRequiredArgs = {
|
|
10
|
+
receiveAddress: string;
|
|
11
|
+
allowanceContract: string;
|
|
12
|
+
sellAsset: Asset;
|
|
13
|
+
sellAmount: string;
|
|
14
|
+
web3: Web3;
|
|
15
|
+
erc20AllowanceAbi: AbiItem[];
|
|
16
|
+
};
|
|
17
|
+
export declare type GetERC20AllowanceArgs = {
|
|
18
|
+
erc20AllowanceAbi: AbiItem[];
|
|
19
|
+
web3: Web3;
|
|
20
|
+
sellAssetErc20Address: string;
|
|
21
|
+
ownerAddress: string;
|
|
22
|
+
spenderAddress: string;
|
|
23
|
+
};
|
|
24
|
+
declare type GrantAllowanceArgs = {
|
|
25
|
+
quote: TradeQuote<'eip155:1'>;
|
|
26
|
+
wallet: HDWallet;
|
|
27
|
+
adapter: ethereum.ChainAdapter;
|
|
28
|
+
erc20Abi: AbiItem[];
|
|
29
|
+
web3: Web3;
|
|
30
|
+
};
|
|
31
|
+
export declare const getERC20Allowance: ({ erc20AllowanceAbi, web3, sellAssetErc20Address, ownerAddress, spenderAddress }: GetERC20AllowanceArgs) => Promise<any>;
|
|
32
|
+
export declare const getAllowanceRequired: ({ receiveAddress, allowanceContract, sellAsset, sellAmount, web3, erc20AllowanceAbi }: GetAllowanceRequiredArgs) => Promise<BigNumber>;
|
|
33
|
+
export declare const grantAllowance: ({ quote, wallet, adapter, erc20Abi, web3 }: GrantAllowanceArgs) => Promise<string>;
|
|
2
34
|
/**
|
|
3
35
|
* This function keeps 17 significant digits, so even if we try to trade 1 Billion of an
|
|
4
36
|
* ETH or ERC20, we still keep 7 decimal places.
|
|
5
37
|
* @param amount
|
|
6
38
|
*/
|
|
7
39
|
export declare const normalizeAmount: (amount: string | number | BN) => string;
|
|
40
|
+
export {};
|
|
@@ -1,7 +1,104 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.normalizeAmount = void 0;
|
|
3
|
+
exports.normalizeAmount = exports.grantAllowance = exports.getAllowanceRequired = exports.getERC20Allowance = void 0;
|
|
4
|
+
const caip_1 = require("@shapeshiftoss/caip");
|
|
5
|
+
const web3_utils_1 = require("web3-utils");
|
|
6
|
+
const api_1 = require("../../../api");
|
|
4
7
|
const bignumber_1 = require("../bignumber");
|
|
8
|
+
const getERC20Allowance = async ({ erc20AllowanceAbi, web3, sellAssetErc20Address, ownerAddress, spenderAddress }) => {
|
|
9
|
+
const erc20Contract = new web3.eth.Contract(erc20AllowanceAbi, sellAssetErc20Address);
|
|
10
|
+
return erc20Contract.methods.allowance(ownerAddress, spenderAddress).call();
|
|
11
|
+
};
|
|
12
|
+
exports.getERC20Allowance = getERC20Allowance;
|
|
13
|
+
const getAllowanceRequired = async ({ receiveAddress, allowanceContract, sellAsset, sellAmount, web3, erc20AllowanceAbi }) => {
|
|
14
|
+
try {
|
|
15
|
+
if (sellAsset.assetId === 'eip155:1/slip44:60') {
|
|
16
|
+
return (0, bignumber_1.bn)(0);
|
|
17
|
+
}
|
|
18
|
+
const ownerAddress = receiveAddress;
|
|
19
|
+
const spenderAddress = allowanceContract;
|
|
20
|
+
const { assetReference: sellAssetErc20Address } = (0, caip_1.fromAssetId)(sellAsset.assetId);
|
|
21
|
+
const allowanceOnChain = await (0, exports.getERC20Allowance)({
|
|
22
|
+
web3,
|
|
23
|
+
erc20AllowanceAbi,
|
|
24
|
+
ownerAddress,
|
|
25
|
+
spenderAddress,
|
|
26
|
+
sellAssetErc20Address
|
|
27
|
+
});
|
|
28
|
+
if (allowanceOnChain === '0')
|
|
29
|
+
return (0, bignumber_1.bnOrZero)(sellAmount);
|
|
30
|
+
if (!allowanceOnChain) {
|
|
31
|
+
throw new api_1.SwapError(`[getAllowanceRequired] - No allowance data`, {
|
|
32
|
+
details: { allowanceContract, receiveAddress },
|
|
33
|
+
code: api_1.SwapErrorTypes.RESPONSE_ERROR
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
const allowanceRequired = (0, bignumber_1.bnOrZero)(sellAmount).minus(allowanceOnChain);
|
|
37
|
+
return allowanceRequired.lt(0) ? (0, bignumber_1.bn)(0) : allowanceRequired;
|
|
38
|
+
}
|
|
39
|
+
catch (e) {
|
|
40
|
+
if (e instanceof api_1.SwapError)
|
|
41
|
+
throw e;
|
|
42
|
+
throw new api_1.SwapError('[getAllowanceRequired]', {
|
|
43
|
+
cause: e,
|
|
44
|
+
code: api_1.SwapErrorTypes.ALLOWANCE_REQUIRED_FAILED
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
exports.getAllowanceRequired = getAllowanceRequired;
|
|
49
|
+
const grantAllowance = async ({ quote, wallet, adapter, erc20Abi, web3 }) => {
|
|
50
|
+
var _a, _b, _c, _d, _e;
|
|
51
|
+
try {
|
|
52
|
+
const { assetReference: sellAssetErc20Address } = (0, caip_1.fromAssetId)(quote.sellAsset.assetId);
|
|
53
|
+
const erc20Contract = new web3.eth.Contract(erc20Abi, sellAssetErc20Address);
|
|
54
|
+
const approveTx = erc20Contract.methods
|
|
55
|
+
.approve(quote.allowanceContract, quote.sellAmount)
|
|
56
|
+
.encodeABI();
|
|
57
|
+
const accountNumber = quote.sellAssetAccountNumber;
|
|
58
|
+
const bip44Params = adapter.buildBIP44Params({ accountNumber });
|
|
59
|
+
const { txToSign } = await adapter.buildSendTransaction({
|
|
60
|
+
wallet,
|
|
61
|
+
to: sellAssetErc20Address,
|
|
62
|
+
bip44Params,
|
|
63
|
+
value: '0',
|
|
64
|
+
chainSpecific: {
|
|
65
|
+
erc20ContractAddress: sellAssetErc20Address,
|
|
66
|
+
gasPrice: (0, web3_utils_1.numberToHex)(((_b = (_a = quote.feeData) === null || _a === void 0 ? void 0 : _a.chainSpecific) === null || _b === void 0 ? void 0 : _b.gasPrice) || 0),
|
|
67
|
+
gasLimit: (0, web3_utils_1.numberToHex)(((_d = (_c = quote.feeData) === null || _c === void 0 ? void 0 : _c.chainSpecific) === null || _d === void 0 ? void 0 : _d.estimatedGas) || 0)
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
const grantAllowanceTxToSign = {
|
|
71
|
+
...txToSign,
|
|
72
|
+
data: approveTx
|
|
73
|
+
};
|
|
74
|
+
if (wallet.supportsOfflineSigning()) {
|
|
75
|
+
const signedTx = await adapter.signTransaction({ txToSign: grantAllowanceTxToSign, wallet });
|
|
76
|
+
const broadcastedTxId = await adapter.broadcastTransaction(signedTx);
|
|
77
|
+
return broadcastedTxId;
|
|
78
|
+
}
|
|
79
|
+
else if (wallet.supportsBroadcast() && adapter.signAndBroadcastTransaction) {
|
|
80
|
+
const broadcastedTxId = await ((_e = adapter.signAndBroadcastTransaction) === null || _e === void 0 ? void 0 : _e.call(adapter, {
|
|
81
|
+
txToSign: grantAllowanceTxToSign,
|
|
82
|
+
wallet
|
|
83
|
+
}));
|
|
84
|
+
return broadcastedTxId;
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
throw new api_1.SwapError('[grantAllowance] - invalid HDWallet config', {
|
|
88
|
+
code: api_1.SwapErrorTypes.SIGN_AND_BROADCAST_FAILED
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
catch (e) {
|
|
93
|
+
if (e instanceof api_1.SwapError)
|
|
94
|
+
throw e;
|
|
95
|
+
throw new api_1.SwapError('[grantAllowance]', {
|
|
96
|
+
cause: e,
|
|
97
|
+
code: api_1.SwapErrorTypes.GRANT_ALLOWANCE_FAILED
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
exports.grantAllowance = grantAllowance;
|
|
5
102
|
/**
|
|
6
103
|
* This function keeps 17 significant digits, so even if we try to trade 1 Billion of an
|
|
7
104
|
* ETH or ERC20, we still keep 7 decimal places.
|
|
@@ -26,12 +26,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
26
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.
|
|
29
|
+
exports.setupDeps = void 0;
|
|
30
30
|
const chain_adapters_1 = require("@shapeshiftoss/chain-adapters");
|
|
31
31
|
const unchained = __importStar(require("@shapeshiftoss/unchained-client"));
|
|
32
32
|
const web3_1 = __importDefault(require("web3"));
|
|
33
33
|
jest.mock('@shapeshiftoss/chain-adapters');
|
|
34
|
-
const
|
|
34
|
+
const setupDeps = () => {
|
|
35
35
|
const ethChainAdapter = new chain_adapters_1.ethereum.ChainAdapter({
|
|
36
36
|
providers: {
|
|
37
37
|
ws: new unchained.ws.Client('wss://dev-api.ethereum.shapeshift.com'),
|
|
@@ -45,4 +45,4 @@ const setupZrxDeps = () => {
|
|
|
45
45
|
const web3Provider = new web3_1.default.providers.HttpProvider(ethNodeUrl);
|
|
46
46
|
return { web3: new web3_1.default(web3Provider), adapter: ethChainAdapter };
|
|
47
47
|
};
|
|
48
|
-
exports.
|
|
48
|
+
exports.setupDeps = setupDeps;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Asset } from '@shapeshiftoss/types';
|
|
2
|
+
import { TradeQuote } from '../../../api';
|
|
3
|
+
export declare const setupQuote: () => {
|
|
4
|
+
quoteInput: import("../../../api").CommonTradeInput;
|
|
5
|
+
tradeQuote: TradeQuote<"eip155:1">;
|
|
6
|
+
buyAsset: Asset;
|
|
7
|
+
sellAsset: Asset;
|
|
8
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.setupQuote = void 0;
|
|
4
|
+
const assets_1 = require("./assets");
|
|
5
|
+
const setupQuote = () => {
|
|
6
|
+
const sellAsset = { ...assets_1.FOX };
|
|
7
|
+
const buyAsset = { ...assets_1.WETH };
|
|
8
|
+
const tradeQuote = {
|
|
9
|
+
buyAmount: '',
|
|
10
|
+
sellAmount: '1000000000000000000',
|
|
11
|
+
sellAsset,
|
|
12
|
+
buyAsset,
|
|
13
|
+
allowanceContract: 'allowanceContractAddress',
|
|
14
|
+
sellAssetAccountNumber: 0,
|
|
15
|
+
minimum: '0',
|
|
16
|
+
maximum: '999999999999',
|
|
17
|
+
feeData: { fee: '0', tradeFee: '0', chainSpecific: {} },
|
|
18
|
+
rate: '1',
|
|
19
|
+
sources: []
|
|
20
|
+
};
|
|
21
|
+
const quoteInput = {
|
|
22
|
+
sellAmount: '1000000000000000000',
|
|
23
|
+
sellAsset,
|
|
24
|
+
buyAsset,
|
|
25
|
+
sellAssetAccountNumber: 0,
|
|
26
|
+
sendMax: false
|
|
27
|
+
};
|
|
28
|
+
return { quoteInput, tradeQuote, buyAsset, sellAsset };
|
|
29
|
+
};
|
|
30
|
+
exports.setupQuote = setupQuote;
|
|
@@ -3,9 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ZrxApprovalNeeded = void 0;
|
|
4
4
|
const caip_1 = require("@shapeshiftoss/caip");
|
|
5
5
|
const api_1 = require("../../../api");
|
|
6
|
+
const erc20Allowance_abi_1 = require("../../utils/abi/erc20Allowance-abi");
|
|
6
7
|
const bignumber_1 = require("../../utils/bignumber");
|
|
7
|
-
const
|
|
8
|
-
const helpers_1 = require("../utils/helpers/helpers");
|
|
8
|
+
const helpers_1 = require("../../utils/helpers/helpers");
|
|
9
9
|
async function ZrxApprovalNeeded({ adapter, web3 }, { quote, wallet }) {
|
|
10
10
|
var _a;
|
|
11
11
|
const { sellAsset } = quote;
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ZrxApproveInfinite = void 0;
|
|
4
4
|
const api_1 = require("../../../api");
|
|
5
|
-
const erc20_abi_1 = require("
|
|
5
|
+
const erc20_abi_1 = require("../../utils/abi/erc20-abi");
|
|
6
|
+
const helpers_1 = require("../../utils/helpers/helpers");
|
|
6
7
|
const constants_1 = require("../utils/constants");
|
|
7
|
-
const helpers_1 = require("../utils/helpers/helpers");
|
|
8
8
|
async function ZrxApproveInfinite({ adapter, web3 }, { quote, wallet }) {
|
|
9
9
|
try {
|
|
10
10
|
const allowanceGrantRequired = await (0, helpers_1.grantAllowance)({
|
|
@@ -1,34 +1,2 @@
|
|
|
1
|
-
import { ethereum } from '@shapeshiftoss/chain-adapters';
|
|
2
|
-
import { HDWallet } from '@shapeshiftoss/hdwallet-core';
|
|
3
1
|
import { Asset } from '@shapeshiftoss/types';
|
|
4
|
-
import Web3 from 'web3';
|
|
5
|
-
import { AbiItem } from 'web3-utils';
|
|
6
|
-
import { TradeQuote } from '../../../../api';
|
|
7
|
-
import { BN } from '../../../utils/bignumber';
|
|
8
|
-
export declare type GetAllowanceRequiredArgs = {
|
|
9
|
-
receiveAddress: string;
|
|
10
|
-
allowanceContract: string;
|
|
11
|
-
sellAsset: Asset;
|
|
12
|
-
sellAmount: string;
|
|
13
|
-
web3: Web3;
|
|
14
|
-
erc20AllowanceAbi: AbiItem[];
|
|
15
|
-
};
|
|
16
|
-
export declare type GetERC20AllowanceArgs = {
|
|
17
|
-
erc20AllowanceAbi: AbiItem[];
|
|
18
|
-
web3: Web3;
|
|
19
|
-
sellAssetErc20Address: string;
|
|
20
|
-
ownerAddress: string;
|
|
21
|
-
spenderAddress: string;
|
|
22
|
-
};
|
|
23
|
-
declare type GrantAllowanceArgs = {
|
|
24
|
-
quote: TradeQuote<'eip155:1'>;
|
|
25
|
-
wallet: HDWallet;
|
|
26
|
-
adapter: ethereum.ChainAdapter;
|
|
27
|
-
erc20Abi: AbiItem[];
|
|
28
|
-
web3: Web3;
|
|
29
|
-
};
|
|
30
|
-
export declare const getERC20Allowance: ({ erc20AllowanceAbi, web3, sellAssetErc20Address, ownerAddress, spenderAddress }: GetERC20AllowanceArgs) => Promise<any>;
|
|
31
|
-
export declare const getAllowanceRequired: ({ receiveAddress, allowanceContract, sellAsset, sellAmount, web3, erc20AllowanceAbi }: GetAllowanceRequiredArgs) => Promise<BN>;
|
|
32
2
|
export declare const getUsdRate: (asset: Asset) => Promise<string>;
|
|
33
|
-
export declare const grantAllowance: ({ quote, wallet, adapter, erc20Abi, web3 }: GrantAllowanceArgs) => Promise<string>;
|
|
34
|
-
export {};
|
|
@@ -1,52 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.getUsdRate = void 0;
|
|
4
4
|
const caip_1 = require("@shapeshiftoss/caip");
|
|
5
|
-
const web3_utils_1 = require("web3-utils");
|
|
6
5
|
const api_1 = require("../../../../api");
|
|
7
6
|
const bignumber_1 = require("../../../utils/bignumber");
|
|
8
7
|
const zrxService_1 = require("../zrxService");
|
|
9
|
-
const getERC20Allowance = async ({ erc20AllowanceAbi, web3, sellAssetErc20Address, ownerAddress, spenderAddress }) => {
|
|
10
|
-
const erc20Contract = new web3.eth.Contract(erc20AllowanceAbi, sellAssetErc20Address);
|
|
11
|
-
return erc20Contract.methods.allowance(ownerAddress, spenderAddress).call();
|
|
12
|
-
};
|
|
13
|
-
exports.getERC20Allowance = getERC20Allowance;
|
|
14
|
-
const getAllowanceRequired = async ({ receiveAddress, allowanceContract, sellAsset, sellAmount, web3, erc20AllowanceAbi }) => {
|
|
15
|
-
try {
|
|
16
|
-
if (sellAsset.assetId === 'eip155:1/slip44:60') {
|
|
17
|
-
return (0, bignumber_1.bn)(0);
|
|
18
|
-
}
|
|
19
|
-
const ownerAddress = receiveAddress;
|
|
20
|
-
const spenderAddress = allowanceContract;
|
|
21
|
-
const { assetReference: sellAssetErc20Address } = (0, caip_1.fromAssetId)(sellAsset.assetId);
|
|
22
|
-
const allowanceOnChain = await (0, exports.getERC20Allowance)({
|
|
23
|
-
web3,
|
|
24
|
-
erc20AllowanceAbi,
|
|
25
|
-
ownerAddress,
|
|
26
|
-
spenderAddress,
|
|
27
|
-
sellAssetErc20Address
|
|
28
|
-
});
|
|
29
|
-
if (allowanceOnChain === '0')
|
|
30
|
-
return (0, bignumber_1.bnOrZero)(sellAmount);
|
|
31
|
-
if (!allowanceOnChain) {
|
|
32
|
-
throw new api_1.SwapError(`[getAllowanceRequired] - No allowance data`, {
|
|
33
|
-
details: { allowanceContract, receiveAddress },
|
|
34
|
-
code: api_1.SwapErrorTypes.RESPONSE_ERROR
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
const allowanceRequired = (0, bignumber_1.bnOrZero)(sellAmount).minus(allowanceOnChain);
|
|
38
|
-
return allowanceRequired.lt(0) ? (0, bignumber_1.bn)(0) : allowanceRequired;
|
|
39
|
-
}
|
|
40
|
-
catch (e) {
|
|
41
|
-
if (e instanceof api_1.SwapError)
|
|
42
|
-
throw e;
|
|
43
|
-
throw new api_1.SwapError('[getAllowanceRequired]', {
|
|
44
|
-
cause: e,
|
|
45
|
-
code: api_1.SwapErrorTypes.ALLOWANCE_REQUIRED_FAILED
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
exports.getAllowanceRequired = getAllowanceRequired;
|
|
50
8
|
const getUsdRate = async (asset) => {
|
|
51
9
|
const { assetReference: erc20Address, assetNamespace } = (0, caip_1.fromAssetId)(asset.assetId);
|
|
52
10
|
const { symbol } = asset;
|
|
@@ -78,56 +36,3 @@ const getUsdRate = async (asset) => {
|
|
|
78
36
|
}
|
|
79
37
|
};
|
|
80
38
|
exports.getUsdRate = getUsdRate;
|
|
81
|
-
const grantAllowance = async ({ quote, wallet, adapter, erc20Abi, web3 }) => {
|
|
82
|
-
var _a, _b, _c, _d, _e;
|
|
83
|
-
try {
|
|
84
|
-
const { assetReference: sellAssetErc20Address } = (0, caip_1.fromAssetId)(quote.sellAsset.assetId);
|
|
85
|
-
const erc20Contract = new web3.eth.Contract(erc20Abi, sellAssetErc20Address);
|
|
86
|
-
const approveTx = erc20Contract.methods
|
|
87
|
-
.approve(quote.allowanceContract, quote.sellAmount)
|
|
88
|
-
.encodeABI();
|
|
89
|
-
const accountNumber = quote.sellAssetAccountNumber;
|
|
90
|
-
const bip44Params = adapter.buildBIP44Params({ accountNumber });
|
|
91
|
-
const { txToSign } = await adapter.buildSendTransaction({
|
|
92
|
-
wallet,
|
|
93
|
-
to: sellAssetErc20Address,
|
|
94
|
-
bip44Params,
|
|
95
|
-
value: '0',
|
|
96
|
-
chainSpecific: {
|
|
97
|
-
erc20ContractAddress: sellAssetErc20Address,
|
|
98
|
-
gasPrice: (0, web3_utils_1.numberToHex)(((_b = (_a = quote.feeData) === null || _a === void 0 ? void 0 : _a.chainSpecific) === null || _b === void 0 ? void 0 : _b.gasPrice) || 0),
|
|
99
|
-
gasLimit: (0, web3_utils_1.numberToHex)(((_d = (_c = quote.feeData) === null || _c === void 0 ? void 0 : _c.chainSpecific) === null || _d === void 0 ? void 0 : _d.estimatedGas) || 0)
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
const grantAllowanceTxToSign = {
|
|
103
|
-
...txToSign,
|
|
104
|
-
data: approveTx
|
|
105
|
-
};
|
|
106
|
-
if (wallet.supportsOfflineSigning()) {
|
|
107
|
-
const signedTx = await adapter.signTransaction({ txToSign: grantAllowanceTxToSign, wallet });
|
|
108
|
-
const broadcastedTxId = await adapter.broadcastTransaction(signedTx);
|
|
109
|
-
return broadcastedTxId;
|
|
110
|
-
}
|
|
111
|
-
else if (wallet.supportsBroadcast() && adapter.signAndBroadcastTransaction) {
|
|
112
|
-
const broadcastedTxId = await ((_e = adapter.signAndBroadcastTransaction) === null || _e === void 0 ? void 0 : _e.call(adapter, {
|
|
113
|
-
txToSign: grantAllowanceTxToSign,
|
|
114
|
-
wallet
|
|
115
|
-
}));
|
|
116
|
-
return broadcastedTxId;
|
|
117
|
-
}
|
|
118
|
-
else {
|
|
119
|
-
throw new api_1.SwapError('[grantAllowance] - invalid HDWallet config', {
|
|
120
|
-
code: api_1.SwapErrorTypes.SIGN_AND_BROADCAST_FAILED
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
catch (e) {
|
|
125
|
-
if (e instanceof api_1.SwapError)
|
|
126
|
-
throw e;
|
|
127
|
-
throw new api_1.SwapError('[grantAllowance]', {
|
|
128
|
-
cause: e,
|
|
129
|
-
code: api_1.SwapErrorTypes.GRANT_ALLOWANCE_FAILED
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
};
|
|
133
|
-
exports.grantAllowance = grantAllowance;
|
|
@@ -1,12 +1,5 @@
|
|
|
1
1
|
import { Asset } from '@shapeshiftoss/types';
|
|
2
|
-
import { TradeQuote } from '../../../../api';
|
|
3
2
|
import { ZrxQuoteResponse } from '../../types';
|
|
4
|
-
export declare const setupQuote: () => {
|
|
5
|
-
quoteInput: import("../../../../api").CommonTradeInput;
|
|
6
|
-
tradeQuote: TradeQuote<"eip155:1">;
|
|
7
|
-
buyAsset: Asset;
|
|
8
|
-
sellAsset: Asset;
|
|
9
|
-
};
|
|
10
3
|
export declare const setupZrxTradeQuoteResponse: () => {
|
|
11
4
|
quoteResponse: ZrxQuoteResponse;
|
|
12
5
|
buyAsset: Asset;
|
|
@@ -1,33 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.setupExecuteTrade = exports.setupBuildTrade = exports.setupZrxTradeQuoteResponse =
|
|
3
|
+
exports.setupExecuteTrade = exports.setupBuildTrade = exports.setupZrxTradeQuoteResponse = void 0;
|
|
4
4
|
const assets_1 = require("../../../utils/test-data/assets");
|
|
5
|
-
const setupQuote = () => {
|
|
6
|
-
const sellAsset = { ...assets_1.FOX };
|
|
7
|
-
const buyAsset = { ...assets_1.WETH };
|
|
8
|
-
const tradeQuote = {
|
|
9
|
-
buyAmount: '',
|
|
10
|
-
sellAmount: '1000000000000000000',
|
|
11
|
-
sellAsset,
|
|
12
|
-
buyAsset,
|
|
13
|
-
allowanceContract: 'allowanceContractAddress',
|
|
14
|
-
sellAssetAccountNumber: 0,
|
|
15
|
-
minimum: '0',
|
|
16
|
-
maximum: '999999999999',
|
|
17
|
-
feeData: { fee: '0', tradeFee: '0', chainSpecific: {} },
|
|
18
|
-
rate: '1',
|
|
19
|
-
sources: []
|
|
20
|
-
};
|
|
21
|
-
const quoteInput = {
|
|
22
|
-
sellAmount: '1000000000000000000',
|
|
23
|
-
sellAsset,
|
|
24
|
-
buyAsset,
|
|
25
|
-
sellAssetAccountNumber: 0,
|
|
26
|
-
sendMax: false
|
|
27
|
-
};
|
|
28
|
-
return { quoteInput, tradeQuote, buyAsset, sellAsset };
|
|
29
|
-
};
|
|
30
|
-
exports.setupQuote = setupQuote;
|
|
31
5
|
const setupZrxTradeQuoteResponse = () => {
|
|
32
6
|
const sellAsset = { ...assets_1.FOX };
|
|
33
7
|
const buyAsset = { ...assets_1.WETH };
|
|
@@ -27,13 +27,13 @@ exports.zrxBuildTrade = void 0;
|
|
|
27
27
|
const caip_1 = require("@shapeshiftoss/caip");
|
|
28
28
|
const rax = __importStar(require("retry-axios"));
|
|
29
29
|
const __1 = require("../../..");
|
|
30
|
+
const erc20Allowance_abi_1 = require("../../utils/abi/erc20Allowance-abi");
|
|
30
31
|
const bignumber_1 = require("../../utils/bignumber");
|
|
31
32
|
const constants_1 = require("../../utils/constants");
|
|
32
33
|
const helpers_1 = require("../../utils/helpers/helpers");
|
|
33
|
-
const
|
|
34
|
+
const helpers_2 = require("../../utils/helpers/helpers");
|
|
34
35
|
const applyAxiosRetry_1 = require("../utils/applyAxiosRetry");
|
|
35
36
|
const constants_2 = require("../utils/constants");
|
|
36
|
-
const helpers_2 = require("../utils/helpers/helpers");
|
|
37
37
|
const zrxService_1 = require("../utils/zrxService");
|
|
38
38
|
async function zrxBuildTrade({ adapter, web3 }, input) {
|
|
39
39
|
var _a, _b, _c;
|
|
@@ -81,7 +81,7 @@ async function zrxBuildTrade({ adapter, web3 }, input) {
|
|
|
81
81
|
params: {
|
|
82
82
|
buyToken,
|
|
83
83
|
sellToken,
|
|
84
|
-
sellAmount: (0,
|
|
84
|
+
sellAmount: (0, helpers_2.normalizeAmount)(sellAmount),
|
|
85
85
|
takerAddress: receiveAddress,
|
|
86
86
|
slippagePercentage,
|
|
87
87
|
skipValidation: false,
|
|
@@ -110,7 +110,7 @@ async function zrxBuildTrade({ adapter, web3 }, input) {
|
|
|
110
110
|
buyAmount: data.buyAmount,
|
|
111
111
|
sources: ((_a = data.sources) === null || _a === void 0 ? void 0 : _a.filter((s) => parseFloat(s.proportion) > 0)) || constants_2.DEFAULT_SOURCE
|
|
112
112
|
};
|
|
113
|
-
const allowanceRequired = await (0,
|
|
113
|
+
const allowanceRequired = await (0, helpers_1.getAllowanceRequired)({
|
|
114
114
|
sellAsset,
|
|
115
115
|
allowanceContract: data.allowanceTarget,
|
|
116
116
|
receiveAddress,
|
package/package.json
CHANGED