@shapeshiftoss/swapper 4.1.2 → 5.0.1
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 +38 -1
- package/dist/api.js +22 -4
- package/dist/manager/SwapperManager.d.ts +0 -3
- package/dist/manager/SwapperManager.js +17 -12
- package/dist/swappercli.js +17 -8
- package/dist/swappers/zrx/ZrxApprovalNeeded/ZrxApprovalNeeded.js +46 -24
- package/dist/swappers/zrx/ZrxApproveInfinite/ZrxApproveInfinite.js +22 -12
- package/dist/swappers/zrx/ZrxSwapper.d.ts +0 -3
- package/dist/swappers/zrx/ZrxSwapper.js +1 -8
- package/dist/swappers/zrx/getZrxMinMax/getZrxMinMax.js +17 -12
- package/dist/swappers/zrx/getZrxTradeQuote/getZrxTradeQuote.js +18 -37
- package/dist/swappers/zrx/utils/helpers/helpers.js +93 -78
- package/dist/swappers/zrx/utils/test-data/assets.js +3 -4
- package/dist/swappers/zrx/zrxBuildTrade/zrxBuildTrade.js +18 -43
- package/dist/swappers/zrx/zrxExecuteTrade/zrxExecuteTrade.js +31 -51
- package/package.json +11 -9
package/dist/api.d.ts
CHANGED
|
@@ -1,6 +1,28 @@
|
|
|
1
1
|
import { AssetId } from '@shapeshiftoss/caip';
|
|
2
2
|
import { HDWallet } from '@shapeshiftoss/hdwallet-core';
|
|
3
3
|
import { ApprovalNeededOutput, Asset, ChainSpecific, ExecQuoteOutput, GetMinMaxInput, MinMaxOutput, SupportedChainIds, SwapperType } from '@shapeshiftoss/types';
|
|
4
|
+
export declare const SwapError: {
|
|
5
|
+
new <V extends {
|
|
6
|
+
cause?: unknown;
|
|
7
|
+
details?: Record<string, unknown> | undefined;
|
|
8
|
+
code?: string | undefined;
|
|
9
|
+
}>(message?: string | undefined, options?: V | undefined): {
|
|
10
|
+
details: V extends {
|
|
11
|
+
details: infer R;
|
|
12
|
+
} ? R : undefined;
|
|
13
|
+
"__#1@#code"?: string | undefined;
|
|
14
|
+
code: string | undefined;
|
|
15
|
+
readonly cause: V extends {
|
|
16
|
+
cause: infer R_1;
|
|
17
|
+
} ? R_1 : undefined;
|
|
18
|
+
name: string;
|
|
19
|
+
message: string;
|
|
20
|
+
stack?: string | undefined;
|
|
21
|
+
};
|
|
22
|
+
captureStackTrace(targetObject: object, constructorOpt?: Function | undefined): void;
|
|
23
|
+
prepareStackTrace?: ((err: Error, stackTraces: NodeJS.CallSite[]) => any) | undefined;
|
|
24
|
+
stackTraceLimit: number;
|
|
25
|
+
};
|
|
4
26
|
export declare type SupportedAssetInput = {
|
|
5
27
|
assetIds: AssetId[];
|
|
6
28
|
};
|
|
@@ -80,7 +102,22 @@ export declare type ApprovalNeededInput<C extends SupportedChainIds> = {
|
|
|
80
102
|
quote: TradeQuote<C>;
|
|
81
103
|
wallet: HDWallet;
|
|
82
104
|
};
|
|
83
|
-
export declare
|
|
105
|
+
export declare enum SwapErrorTypes {
|
|
106
|
+
ALLOWANCE_REQUIRED_FAILED = "ALLOWANCE_REQUIRED_FAILED",
|
|
107
|
+
CHECK_APPROVAL_FAILED = "CHECK_APPROVAL_FAILED",
|
|
108
|
+
APPROVE_INFINITE_FAILED = "APPROVE_INFINITE_FAILED",
|
|
109
|
+
BUILD_TRADE_FAILED = "BUILD_TRADE_FAILED",
|
|
110
|
+
EXECUTE_TRADE_FAILED = "EXECUTE_TRADE_FAILED",
|
|
111
|
+
GRANT_ALLOWANCE_FAILED = "GRANT_ALLOWANCE_FAILED",
|
|
112
|
+
MANAGER_ERROR = "MANAGER_ERROR",
|
|
113
|
+
MIN_MAX_FAILED = "MIN_MAX_FAILED",
|
|
114
|
+
SIGN_AND_BROADCAST_FAILED = "SIGN_AND_BROADCAST_FAILED",
|
|
115
|
+
TRADE_QUOTE_FAILED = "TRADE_QUOTE_FAILED",
|
|
116
|
+
UNSUPPORTED_PAIR = "UNSUPPORTED_PAIR",
|
|
117
|
+
USD_RATE_FAILED = "USD_RATE_FAILED",
|
|
118
|
+
UNSUPPORTED_CHAIN = "UNSUPPORTED_CHAIN",
|
|
119
|
+
VALIDATION_FAILED = "VALIDATION_FAILED",
|
|
120
|
+
RESPONSE_ERROR = "RESPONSE_ERROR"
|
|
84
121
|
}
|
|
85
122
|
export interface Swapper {
|
|
86
123
|
/** Returns the swapper type */
|
package/dist/api.js
CHANGED
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SwapError = void 0;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
exports.SwapErrorTypes = exports.SwapError = void 0;
|
|
4
|
+
const errors_1 = require("@shapeshiftoss/errors");
|
|
5
|
+
exports.SwapError = (0, errors_1.createErrorClass)('SwapError');
|
|
6
|
+
// Swap Errors
|
|
7
|
+
var SwapErrorTypes;
|
|
8
|
+
(function (SwapErrorTypes) {
|
|
9
|
+
SwapErrorTypes["ALLOWANCE_REQUIRED_FAILED"] = "ALLOWANCE_REQUIRED_FAILED";
|
|
10
|
+
SwapErrorTypes["CHECK_APPROVAL_FAILED"] = "CHECK_APPROVAL_FAILED";
|
|
11
|
+
SwapErrorTypes["APPROVE_INFINITE_FAILED"] = "APPROVE_INFINITE_FAILED";
|
|
12
|
+
SwapErrorTypes["BUILD_TRADE_FAILED"] = "BUILD_TRADE_FAILED";
|
|
13
|
+
SwapErrorTypes["EXECUTE_TRADE_FAILED"] = "EXECUTE_TRADE_FAILED";
|
|
14
|
+
SwapErrorTypes["GRANT_ALLOWANCE_FAILED"] = "GRANT_ALLOWANCE_FAILED";
|
|
15
|
+
SwapErrorTypes["MANAGER_ERROR"] = "MANAGER_ERROR";
|
|
16
|
+
SwapErrorTypes["MIN_MAX_FAILED"] = "MIN_MAX_FAILED";
|
|
17
|
+
SwapErrorTypes["SIGN_AND_BROADCAST_FAILED"] = "SIGN_AND_BROADCAST_FAILED";
|
|
18
|
+
SwapErrorTypes["TRADE_QUOTE_FAILED"] = "TRADE_QUOTE_FAILED";
|
|
19
|
+
SwapErrorTypes["UNSUPPORTED_PAIR"] = "UNSUPPORTED_PAIR";
|
|
20
|
+
SwapErrorTypes["USD_RATE_FAILED"] = "USD_RATE_FAILED";
|
|
21
|
+
SwapErrorTypes["UNSUPPORTED_CHAIN"] = "UNSUPPORTED_CHAIN";
|
|
22
|
+
SwapErrorTypes["VALIDATION_FAILED"] = "VALIDATION_FAILED";
|
|
23
|
+
SwapErrorTypes["RESPONSE_ERROR"] = "RESPONSE_ERROR";
|
|
24
|
+
})(SwapErrorTypes = exports.SwapErrorTypes || (exports.SwapErrorTypes = {}));
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import { SwapperType } from '@shapeshiftoss/types';
|
|
2
2
|
import { BuyAssetBySellIdInput, ByPairInput, SupportedSellAssetsInput, Swapper } from '..';
|
|
3
|
-
export declare class SwapperError extends Error {
|
|
4
|
-
constructor(message: string);
|
|
5
|
-
}
|
|
6
3
|
export declare class SwapperManager {
|
|
7
4
|
swappers: Map<SwapperType, Swapper>;
|
|
8
5
|
constructor();
|
|
@@ -3,18 +3,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.SwapperManager =
|
|
6
|
+
exports.SwapperManager = void 0;
|
|
7
7
|
const uniq_1 = __importDefault(require("lodash/uniq"));
|
|
8
|
-
|
|
9
|
-
constructor(message) {
|
|
10
|
-
super(message);
|
|
11
|
-
this.message = `SwapperError:${message}`;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
exports.SwapperError = SwapperError;
|
|
8
|
+
const api_1 = require("../api");
|
|
15
9
|
function validateSwapper(swapper) {
|
|
16
10
|
if (!(typeof swapper === 'object' && typeof swapper.getType === 'function'))
|
|
17
|
-
throw new
|
|
11
|
+
throw new api_1.SwapError('[validateSwapper] - invalid swapper instance', {
|
|
12
|
+
code: api_1.SwapErrorTypes.MANAGER_ERROR
|
|
13
|
+
});
|
|
18
14
|
}
|
|
19
15
|
// TODO: remove me
|
|
20
16
|
class SwapperManager {
|
|
@@ -30,7 +26,10 @@ class SwapperManager {
|
|
|
30
26
|
addSwapper(swapperType, swapperInstance) {
|
|
31
27
|
const swapper = this.swappers.get(swapperType);
|
|
32
28
|
if (swapper)
|
|
33
|
-
throw new
|
|
29
|
+
throw new api_1.SwapError('[addSwapper] - swapper already exists', {
|
|
30
|
+
code: api_1.SwapErrorTypes.MANAGER_ERROR,
|
|
31
|
+
details: { swapperType }
|
|
32
|
+
});
|
|
34
33
|
validateSwapper(swapperInstance);
|
|
35
34
|
this.swappers.set(swapperType, swapperInstance);
|
|
36
35
|
return this;
|
|
@@ -43,7 +42,10 @@ class SwapperManager {
|
|
|
43
42
|
getSwapper(swapperType) {
|
|
44
43
|
const swapper = this.swappers.get(swapperType);
|
|
45
44
|
if (!swapper)
|
|
46
|
-
throw new
|
|
45
|
+
throw new api_1.SwapError('[getSwapper] - swapperType doesnt exist', {
|
|
46
|
+
code: api_1.SwapErrorTypes.MANAGER_ERROR,
|
|
47
|
+
details: { swapperType }
|
|
48
|
+
});
|
|
47
49
|
return swapper;
|
|
48
50
|
}
|
|
49
51
|
/**
|
|
@@ -54,7 +56,10 @@ class SwapperManager {
|
|
|
54
56
|
removeSwapper(swapperType) {
|
|
55
57
|
const swapper = this.swappers.get(swapperType);
|
|
56
58
|
if (!swapper)
|
|
57
|
-
throw new
|
|
59
|
+
throw new api_1.SwapError('[removeSwapper] - swapperType doesnt exist', {
|
|
60
|
+
code: api_1.SwapErrorTypes.MANAGER_ERROR,
|
|
61
|
+
details: { swapperType }
|
|
62
|
+
});
|
|
58
63
|
this.swappers.delete(swapperType);
|
|
59
64
|
return this;
|
|
60
65
|
}
|
package/dist/swappercli.js
CHANGED
|
@@ -14,7 +14,7 @@ const web3_1 = __importDefault(require("web3"));
|
|
|
14
14
|
const SwapperManager_1 = require("./manager/SwapperManager");
|
|
15
15
|
const ZrxSwapper_1 = require("./swappers/zrx/ZrxSwapper");
|
|
16
16
|
dotenv_1.default.config();
|
|
17
|
-
const { UNCHAINED_HTTP_API = 'http://localhost:31300', UNCHAINED_WS_API = 'wss://localhost:31300', ETH_NODE_URL = 'http://localhost:3000', DEVICE_ID = 'device123', MNEMONIC = '
|
|
17
|
+
const { UNCHAINED_HTTP_API = 'http://localhost:31300', UNCHAINED_WS_API = 'wss://localhost:31300', ETH_NODE_URL = 'http://localhost:3000', DEVICE_ID = 'device123', MNEMONIC = 'all all all all all all all all all all all all' } = process.env;
|
|
18
18
|
const toBaseUnit = (amount, precision) => {
|
|
19
19
|
return new bignumber_js_1.default(amount)
|
|
20
20
|
.multipliedBy(new bignumber_js_1.default(10).exponentiatedBy(new bignumber_js_1.default(precision)))
|
|
@@ -86,13 +86,22 @@ const main = async () => {
|
|
|
86
86
|
manager.addSwapper(types_1.SwapperType.Zrx, zrxSwapper);
|
|
87
87
|
const swapper = manager.getSwapper(types_1.SwapperType.Zrx);
|
|
88
88
|
const sellAmountBase = toBaseUnit(sellAmount, sellAsset.precision);
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
89
|
+
let quote;
|
|
90
|
+
try {
|
|
91
|
+
quote = await swapper.getTradeQuote({
|
|
92
|
+
sellAsset,
|
|
93
|
+
buyAsset,
|
|
94
|
+
sellAmount: sellAmountBase,
|
|
95
|
+
sellAssetAccountId: '0',
|
|
96
|
+
sendMax: false
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
catch (e) {
|
|
100
|
+
console.error(e);
|
|
101
|
+
}
|
|
102
|
+
if (!quote) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
96
105
|
console.info('quote = ', JSON.stringify(quote));
|
|
97
106
|
if (!quote.success) {
|
|
98
107
|
console.error('Obtaining the quote failed: ', quote.statusReason);
|
|
@@ -9,31 +9,53 @@ const helpers_1 = require("../utils/helpers/helpers");
|
|
|
9
9
|
async function ZrxApprovalNeeded({ adapterManager, web3 }, { quote, wallet }) {
|
|
10
10
|
var _a, _b;
|
|
11
11
|
const { sellAsset } = quote;
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
try {
|
|
13
|
+
if (sellAsset.chainId !== 'eip155:1') {
|
|
14
|
+
throw new api_1.SwapError('[ZrxApprovalNeeded] - sellAsset chainId is not supported', {
|
|
15
|
+
code: api_1.SwapErrorTypes.UNSUPPORTED_CHAIN,
|
|
16
|
+
details: { chainId: sellAsset.chainId }
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
// No approval needed for trading eth itself
|
|
20
|
+
if (sellAsset.assetId === 'eip155:1/slip44:60') {
|
|
21
|
+
return { approvalNeeded: false };
|
|
22
|
+
}
|
|
23
|
+
const accountNumber = (0, bignumber_1.bnOrZero)(quote.sellAssetAccountId).toNumber();
|
|
24
|
+
const adapter = await adapterManager.byChainId(sellAsset.chainId);
|
|
25
|
+
const bip44Params = adapter.buildBIP44Params({ accountNumber });
|
|
26
|
+
const receiveAddress = await adapter.getAddress({ wallet, bip44Params });
|
|
27
|
+
if (!quote.sellAsset.tokenId || !quote.allowanceContract) {
|
|
28
|
+
throw new api_1.SwapError('[ZrxApprovalNeeded] - tokenId and allowanceTarget are required', {
|
|
29
|
+
code: api_1.SwapErrorTypes.VALIDATION_FAILED,
|
|
30
|
+
details: { chainId: sellAsset.chainId }
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
const allowanceResult = await (0, helpers_1.getERC20Allowance)({
|
|
34
|
+
web3,
|
|
35
|
+
erc20AllowanceAbi: erc20Allowance_abi_1.erc20AllowanceAbi,
|
|
36
|
+
tokenId: quote.sellAsset.tokenId,
|
|
37
|
+
spenderAddress: quote.allowanceContract,
|
|
38
|
+
ownerAddress: receiveAddress
|
|
39
|
+
});
|
|
40
|
+
const allowanceOnChain = (0, bignumber_1.bnOrZero)(allowanceResult);
|
|
41
|
+
if (!((_a = quote.feeData.chainSpecific) === null || _a === void 0 ? void 0 : _a.gasPrice))
|
|
42
|
+
throw new api_1.SwapError('[ZrxApprovalNeeded] - no gas price with quote', {
|
|
43
|
+
code: api_1.SwapErrorTypes.RESPONSE_ERROR,
|
|
44
|
+
details: { feeData: quote.feeData }
|
|
45
|
+
});
|
|
46
|
+
return {
|
|
47
|
+
approvalNeeded: allowanceOnChain.lte((0, bignumber_1.bnOrZero)(quote.sellAmount)),
|
|
48
|
+
gas: constants_1.APPROVAL_GAS_LIMIT,
|
|
49
|
+
gasPrice: (_b = quote.feeData.chainSpecific) === null || _b === void 0 ? void 0 : _b.gasPrice
|
|
50
|
+
};
|
|
14
51
|
}
|
|
15
|
-
|
|
16
|
-
|
|
52
|
+
catch (e) {
|
|
53
|
+
if (e instanceof api_1.SwapError)
|
|
54
|
+
throw e;
|
|
55
|
+
throw new api_1.SwapError('[ZrxApprovalNeeded]', {
|
|
56
|
+
cause: e,
|
|
57
|
+
code: api_1.SwapErrorTypes.CHECK_APPROVAL_FAILED
|
|
58
|
+
});
|
|
17
59
|
}
|
|
18
|
-
const accountNumber = quote.sellAssetAccountId ? Number(quote.sellAssetAccountId) : 0;
|
|
19
|
-
const adapter = await adapterManager.byChainId(sellAsset.chainId);
|
|
20
|
-
const bip44Params = adapter.buildBIP44Params({ accountNumber });
|
|
21
|
-
const receiveAddress = await adapter.getAddress({ wallet, bip44Params });
|
|
22
|
-
if (!quote.sellAsset.tokenId || !quote.allowanceContract) {
|
|
23
|
-
throw new api_1.SwapError('ZrxApprovalNeeded - tokenId and allowanceTarget are required');
|
|
24
|
-
}
|
|
25
|
-
const allowanceResult = await (0, helpers_1.getERC20Allowance)({
|
|
26
|
-
web3,
|
|
27
|
-
erc20AllowanceAbi: erc20Allowance_abi_1.erc20AllowanceAbi,
|
|
28
|
-
tokenId: quote.sellAsset.tokenId,
|
|
29
|
-
spenderAddress: quote.allowanceContract,
|
|
30
|
-
ownerAddress: receiveAddress
|
|
31
|
-
});
|
|
32
|
-
const allowanceOnChain = (0, bignumber_1.bnOrZero)(allowanceResult);
|
|
33
|
-
return {
|
|
34
|
-
approvalNeeded: allowanceOnChain.lte((0, bignumber_1.bnOrZero)(quote.sellAmount)),
|
|
35
|
-
gas: constants_1.APPROVAL_GAS_LIMIT,
|
|
36
|
-
gasPrice: (_b = (_a = quote === null || quote === void 0 ? void 0 : quote.feeData) === null || _a === void 0 ? void 0 : _a.chainSpecific) === null || _b === void 0 ? void 0 : _b.gasPrice
|
|
37
|
-
};
|
|
38
60
|
}
|
|
39
61
|
exports.ZrxApprovalNeeded = ZrxApprovalNeeded;
|
|
@@ -1,21 +1,31 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ZrxApproveInfinite = void 0;
|
|
4
|
+
const api_1 = require("../../../api");
|
|
4
5
|
const erc20_abi_1 = require("../utils/abi/erc20-abi");
|
|
5
6
|
const constants_1 = require("../utils/constants");
|
|
6
7
|
const helpers_1 = require("../utils/helpers/helpers");
|
|
7
8
|
async function ZrxApproveInfinite({ adapterManager, web3 }, { quote, wallet }) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
9
|
+
try {
|
|
10
|
+
const allowanceGrantRequired = await (0, helpers_1.grantAllowance)({
|
|
11
|
+
quote: {
|
|
12
|
+
...quote,
|
|
13
|
+
sellAmount: constants_1.MAX_ALLOWANCE
|
|
14
|
+
},
|
|
15
|
+
wallet,
|
|
16
|
+
adapterManager,
|
|
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('[ZrxApproveInfinite]', {
|
|
26
|
+
cause: e,
|
|
27
|
+
code: api_1.SwapErrorTypes.APPROVE_INFINITE_FAILED
|
|
28
|
+
});
|
|
29
|
+
}
|
|
20
30
|
}
|
|
21
31
|
exports.ZrxApproveInfinite = ZrxApproveInfinite;
|
|
@@ -7,9 +7,6 @@ export declare type ZrxSwapperDeps = {
|
|
|
7
7
|
adapterManager: ChainAdapterManager;
|
|
8
8
|
web3: Web3;
|
|
9
9
|
};
|
|
10
|
-
export declare class ZrxError extends Error {
|
|
11
|
-
constructor(message: string);
|
|
12
|
-
}
|
|
13
10
|
export declare class ZrxSwapper implements Swapper {
|
|
14
11
|
static swapperName: string;
|
|
15
12
|
deps: ZrxSwapperDeps;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ZrxSwapper =
|
|
3
|
+
exports.ZrxSwapper = void 0;
|
|
4
4
|
const types_1 = require("@shapeshiftoss/types");
|
|
5
5
|
const getZrxMinMax_1 = require("./getZrxMinMax/getZrxMinMax");
|
|
6
6
|
const getZrxTradeQuote_1 = require("./getZrxTradeQuote/getZrxTradeQuote");
|
|
@@ -9,13 +9,6 @@ const ZrxApprovalNeeded_1 = require("./ZrxApprovalNeeded/ZrxApprovalNeeded");
|
|
|
9
9
|
const ZrxApproveInfinite_1 = require("./ZrxApproveInfinite/ZrxApproveInfinite");
|
|
10
10
|
const zrxBuildTrade_1 = require("./zrxBuildTrade/zrxBuildTrade");
|
|
11
11
|
const zrxExecuteTrade_1 = require("./zrxExecuteTrade/zrxExecuteTrade");
|
|
12
|
-
class ZrxError extends Error {
|
|
13
|
-
constructor(message) {
|
|
14
|
-
super(message);
|
|
15
|
-
this.message = `ZrxError:${message}`;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
exports.ZrxError = ZrxError;
|
|
19
12
|
class ZrxSwapper {
|
|
20
13
|
constructor(deps) {
|
|
21
14
|
this.deps = deps;
|
|
@@ -1,22 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getZrxMinMax = void 0;
|
|
4
|
+
const api_1 = require("../../../api");
|
|
4
5
|
const bignumber_1 = require("../utils/bignumber");
|
|
5
6
|
const constants_1 = require("../utils/constants");
|
|
6
7
|
const helpers_1 = require("../utils/helpers/helpers");
|
|
7
|
-
const ZrxSwapper_1 = require("../ZrxSwapper");
|
|
8
8
|
const getZrxMinMax = async (sellAsset, buyAsset) => {
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
try {
|
|
10
|
+
if (sellAsset.chainId !== 'eip155:1' || buyAsset.chainId !== 'eip155:1') {
|
|
11
|
+
throw new api_1.SwapError('[getZrxMinMax]', { code: api_1.SwapErrorTypes.UNSUPPORTED_PAIR });
|
|
12
|
+
}
|
|
13
|
+
const usdRate = await (0, helpers_1.getUsdRate)({ ...sellAsset });
|
|
14
|
+
const minimum = (0, bignumber_1.bn)(1).dividedBy((0, bignumber_1.bnOrZero)(usdRate)).toString(); // $1 worth of the sell token.
|
|
15
|
+
const maximum = constants_1.MAX_ZRX_TRADE; // Arbitrarily large value. 10e+28 here.
|
|
16
|
+
return {
|
|
17
|
+
minimum,
|
|
18
|
+
maximum
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
catch (e) {
|
|
22
|
+
if (e instanceof api_1.SwapError)
|
|
23
|
+
throw e;
|
|
24
|
+
throw new api_1.SwapError('[getZrxMinMax]', { cause: e, code: api_1.SwapErrorTypes.MIN_MAX_FAILED });
|
|
11
25
|
}
|
|
12
|
-
const usdRate = await (0, helpers_1.getUsdRate)({
|
|
13
|
-
symbol: sellAsset.symbol,
|
|
14
|
-
tokenId: sellAsset.tokenId
|
|
15
|
-
});
|
|
16
|
-
const minimum = (0, bignumber_1.bn)(1).dividedBy((0, bignumber_1.bnOrZero)(usdRate)).toString();
|
|
17
|
-
return {
|
|
18
|
-
minimum,
|
|
19
|
-
maximum: constants_1.MAX_ZRX_TRADE // Arbitrarily large value. 10e+28 here.
|
|
20
|
-
};
|
|
21
26
|
};
|
|
22
27
|
exports.getZrxMinMax = getZrxMinMax;
|
|
@@ -1,31 +1,28 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getZrxTradeQuote = void 0;
|
|
4
|
+
const api_1 = require("../../../api");
|
|
4
5
|
const getZrxMinMax_1 = require("../getZrxMinMax/getZrxMinMax");
|
|
5
6
|
const bignumber_1 = require("../utils/bignumber");
|
|
6
7
|
const constants_1 = require("../utils/constants");
|
|
7
8
|
const helpers_1 = require("../utils/helpers/helpers");
|
|
8
9
|
const zrxService_1 = require("../utils/zrxService");
|
|
9
|
-
const ZrxSwapper_1 = require("../ZrxSwapper");
|
|
10
10
|
async function getZrxTradeQuote(input) {
|
|
11
|
-
var _a
|
|
12
|
-
const { sellAsset, buyAsset, sellAmount, sellAssetAccountId } = input;
|
|
13
|
-
if (!buyAsset) {
|
|
14
|
-
throw new ZrxSwapper_1.ZrxError('getQuote - Missing buyAsset');
|
|
15
|
-
}
|
|
16
|
-
if (!sellAsset) {
|
|
17
|
-
throw new ZrxSwapper_1.ZrxError('getQuote - Missing sellAsset');
|
|
18
|
-
}
|
|
19
|
-
if (buyAsset.chainId !== 'eip155:1' || sellAsset.chainId !== 'eip155:1') {
|
|
20
|
-
throw new ZrxSwapper_1.ZrxError('getQuote - Both assets need to be on the Ethereum chain to use Zrx');
|
|
21
|
-
}
|
|
22
|
-
const useSellAmount = !!sellAmount;
|
|
23
|
-
const buyToken = buyAsset.tokenId || buyAsset.symbol;
|
|
24
|
-
const sellToken = sellAsset.tokenId || sellAsset.symbol;
|
|
25
|
-
const { minimum, maximum } = await (0, getZrxMinMax_1.getZrxMinMax)(sellAsset, buyAsset);
|
|
26
|
-
const minQuoteSellAmount = (0, bignumber_1.bnOrZero)(minimum).times((0, bignumber_1.bn)(10).exponentiatedBy(sellAsset.precision));
|
|
27
|
-
const normalizedSellAmount = (0, helpers_1.normalizeAmount)((0, bignumber_1.bnOrZero)(sellAmount).eq(0) ? minQuoteSellAmount.toString() : sellAmount);
|
|
11
|
+
var _a;
|
|
28
12
|
try {
|
|
13
|
+
const { sellAsset, buyAsset, sellAmount, sellAssetAccountId } = input;
|
|
14
|
+
if (buyAsset.chainId !== 'eip155:1' || sellAsset.chainId !== 'eip155:1') {
|
|
15
|
+
throw new api_1.SwapError('[getZrxTradeQuote] - Both assets need to be on the Ethereum chain to use Zrx', {
|
|
16
|
+
code: api_1.SwapErrorTypes.UNSUPPORTED_PAIR,
|
|
17
|
+
details: { buyAssetChainId: buyAsset.chainId, sellAssetChainId: sellAsset.chainId }
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
const useSellAmount = !!sellAmount;
|
|
21
|
+
const buyToken = buyAsset.tokenId || buyAsset.symbol;
|
|
22
|
+
const sellToken = sellAsset.tokenId || sellAsset.symbol;
|
|
23
|
+
const { minimum, maximum } = await (0, getZrxMinMax_1.getZrxMinMax)(sellAsset, buyAsset);
|
|
24
|
+
const minQuoteSellAmount = (0, bignumber_1.bnOrZero)(minimum).times((0, bignumber_1.bn)(10).exponentiatedBy(sellAsset.precision));
|
|
25
|
+
const normalizedSellAmount = (0, helpers_1.normalizeAmount)((0, bignumber_1.bnOrZero)(sellAmount).eq(0) ? minQuoteSellAmount.toString() : sellAmount);
|
|
29
26
|
/**
|
|
30
27
|
* /swap/v1/price
|
|
31
28
|
* params: {
|
|
@@ -70,25 +67,9 @@ async function getZrxTradeQuote(input) {
|
|
|
70
67
|
};
|
|
71
68
|
}
|
|
72
69
|
catch (e) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
// This hackyness will go away when we correctly handle errors
|
|
77
|
-
return {
|
|
78
|
-
success: false,
|
|
79
|
-
statusReason,
|
|
80
|
-
maximum: '0',
|
|
81
|
-
minimum: '0',
|
|
82
|
-
rate: '0',
|
|
83
|
-
feeData: { fee: '0', chainSpecific: {} },
|
|
84
|
-
buyAmount: '0',
|
|
85
|
-
sellAmount: '0',
|
|
86
|
-
sources: [],
|
|
87
|
-
allowanceContract: '0',
|
|
88
|
-
buyAsset,
|
|
89
|
-
sellAsset,
|
|
90
|
-
sellAssetAccountId
|
|
91
|
-
};
|
|
70
|
+
if (e instanceof api_1.SwapError)
|
|
71
|
+
throw e;
|
|
72
|
+
throw new api_1.SwapError('[getZrxTradeQuote]', { cause: e, code: api_1.SwapErrorTypes.TRADE_QUOTE_FAILED });
|
|
92
73
|
}
|
|
93
74
|
}
|
|
94
75
|
exports.getZrxTradeQuote = getZrxTradeQuote;
|
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.grantAllowance = exports.getUsdRate = exports.getAllowanceRequired = exports.getERC20Allowance = exports.normalizeAmount = void 0;
|
|
4
4
|
const web3_utils_1 = require("web3-utils");
|
|
5
5
|
const api_1 = require("../../../../api");
|
|
6
|
-
const ZrxSwapper_1 = require("../../ZrxSwapper");
|
|
7
6
|
const bignumber_1 = require("../bignumber");
|
|
8
7
|
const zrxService_1 = require("../zrxService");
|
|
9
8
|
/**
|
|
@@ -26,64 +25,91 @@ const getERC20Allowance = async ({ erc20AllowanceAbi, web3, tokenId, ownerAddres
|
|
|
26
25
|
};
|
|
27
26
|
exports.getERC20Allowance = getERC20Allowance;
|
|
28
27
|
const getAllowanceRequired = async ({ receiveAddress, allowanceContract, sellAsset, sellAmount, web3, erc20AllowanceAbi }) => {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
28
|
+
try {
|
|
29
|
+
if (sellAsset.assetId === 'eip155:1/slip44:60') {
|
|
30
|
+
return (0, bignumber_1.bn)(0);
|
|
31
|
+
}
|
|
32
|
+
const ownerAddress = receiveAddress;
|
|
33
|
+
const spenderAddress = allowanceContract;
|
|
34
|
+
const tokenId = sellAsset.tokenId;
|
|
35
|
+
if (!tokenId) {
|
|
36
|
+
throw new api_1.SwapError('[getAllowanceRequired] - sellAsset.tokenId is required', {
|
|
37
|
+
code: api_1.SwapErrorTypes.VALIDATION_FAILED
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
const allowanceOnChain = await (0, exports.getERC20Allowance)({
|
|
41
|
+
web3,
|
|
42
|
+
erc20AllowanceAbi,
|
|
43
|
+
ownerAddress,
|
|
44
|
+
spenderAddress,
|
|
45
|
+
tokenId
|
|
46
|
+
});
|
|
47
|
+
if (allowanceOnChain === '0')
|
|
48
|
+
return (0, bignumber_1.bnOrZero)(sellAmount);
|
|
49
|
+
if (!allowanceOnChain) {
|
|
50
|
+
throw new api_1.SwapError(`[getAllowanceRequired] - No allowance data`, {
|
|
51
|
+
details: { allowanceContract, receiveAddress },
|
|
52
|
+
code: api_1.SwapErrorTypes.RESPONSE_ERROR
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
const allowanceRequired = (0, bignumber_1.bnOrZero)(sellAmount).minus(allowanceOnChain);
|
|
56
|
+
return allowanceRequired.lt(0) ? (0, bignumber_1.bn)(0) : allowanceRequired;
|
|
47
57
|
}
|
|
48
|
-
|
|
49
|
-
|
|
58
|
+
catch (e) {
|
|
59
|
+
if (e instanceof api_1.SwapError)
|
|
60
|
+
throw e;
|
|
61
|
+
throw new api_1.SwapError('[getAllowanceRequired]', {
|
|
62
|
+
cause: e,
|
|
63
|
+
code: api_1.SwapErrorTypes.ALLOWANCE_REQUIRED_FAILED
|
|
64
|
+
});
|
|
50
65
|
}
|
|
51
|
-
const allowanceRequired = (0, bignumber_1.bnOrZero)(sellAmount).minus(allowanceOnChain);
|
|
52
|
-
return allowanceRequired.lt(0) ? (0, bignumber_1.bn)(0) : allowanceRequired;
|
|
53
66
|
};
|
|
54
67
|
exports.getAllowanceRequired = getAllowanceRequired;
|
|
55
68
|
const getUsdRate = async (input) => {
|
|
56
69
|
const { symbol, tokenId } = input;
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
+
try {
|
|
71
|
+
const USDC_CONTRACT_ADDRESS = '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48';
|
|
72
|
+
if ((tokenId === null || tokenId === void 0 ? void 0 : tokenId.toLowerCase()) === USDC_CONTRACT_ADDRESS)
|
|
73
|
+
return '1'; // Will break if comparing against usdc
|
|
74
|
+
const rateResponse = await zrxService_1.zrxService.get('/swap/v1/price', {
|
|
75
|
+
params: {
|
|
76
|
+
buyToken: USDC_CONTRACT_ADDRESS,
|
|
77
|
+
buyAmount: '1000000000',
|
|
78
|
+
sellToken: tokenId || symbol
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
const price = (0, bignumber_1.bnOrZero)(rateResponse.data.price);
|
|
82
|
+
if (!price.gt(0))
|
|
83
|
+
throw new api_1.SwapError('[getUsdRate] - Failed to get price data', {
|
|
84
|
+
code: api_1.SwapErrorTypes.RESPONSE_ERROR
|
|
85
|
+
});
|
|
86
|
+
return (0, bignumber_1.bn)(1).dividedBy(price).toString();
|
|
87
|
+
}
|
|
88
|
+
catch (e) {
|
|
89
|
+
if (e instanceof api_1.SwapError)
|
|
90
|
+
throw e;
|
|
91
|
+
throw new api_1.SwapError('[getUsdRate]', {
|
|
92
|
+
cause: e,
|
|
93
|
+
code: api_1.SwapErrorTypes.USD_RATE_FAILED
|
|
94
|
+
});
|
|
95
|
+
}
|
|
70
96
|
};
|
|
71
97
|
exports.getUsdRate = getUsdRate;
|
|
72
98
|
const grantAllowance = async ({ quote, wallet, adapterManager, erc20Abi, web3 }) => {
|
|
73
99
|
var _a, _b, _c, _d, _e;
|
|
74
|
-
if (!quote.sellAsset.tokenId) {
|
|
75
|
-
throw new Error('sellAsset.tokenId is required');
|
|
76
|
-
}
|
|
77
|
-
const adapter = await adapterManager.byChainId('eip155:1');
|
|
78
|
-
const erc20Contract = new web3.eth.Contract(erc20Abi, quote.sellAsset.tokenId);
|
|
79
|
-
const approveTx = erc20Contract.methods
|
|
80
|
-
.approve(quote.allowanceContract, quote.sellAmount)
|
|
81
|
-
.encodeABI();
|
|
82
|
-
const bip44Params = adapter.buildBIP44Params({
|
|
83
|
-
accountNumber: Number(quote.sellAssetAccountId) || 0
|
|
84
|
-
});
|
|
85
|
-
let grantAllowanceTxToSign, signedTx, broadcastedTxId;
|
|
86
100
|
try {
|
|
101
|
+
if (!quote.sellAsset.tokenId) {
|
|
102
|
+
throw new api_1.SwapError('[grantAllowance] - sellAsset.tokenId is required', {
|
|
103
|
+
code: api_1.SwapErrorTypes.VALIDATION_FAILED
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
const adapter = await adapterManager.byChainId('eip155:1');
|
|
107
|
+
const erc20Contract = new web3.eth.Contract(erc20Abi, quote.sellAsset.tokenId);
|
|
108
|
+
const approveTx = erc20Contract.methods
|
|
109
|
+
.approve(quote.allowanceContract, quote.sellAmount)
|
|
110
|
+
.encodeABI();
|
|
111
|
+
const accountNumber = (0, bignumber_1.bnOrZero)(quote.sellAssetAccountId).toNumber();
|
|
112
|
+
const bip44Params = adapter.buildBIP44Params({ accountNumber });
|
|
87
113
|
const { txToSign } = await adapter.buildSendTransaction({
|
|
88
114
|
wallet,
|
|
89
115
|
to: quote.sellAsset.tokenId,
|
|
@@ -95,46 +121,35 @@ const grantAllowance = async ({ quote, wallet, adapterManager, erc20Abi, web3 })
|
|
|
95
121
|
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)
|
|
96
122
|
}
|
|
97
123
|
});
|
|
98
|
-
grantAllowanceTxToSign = {
|
|
124
|
+
const grantAllowanceTxToSign = {
|
|
99
125
|
...txToSign,
|
|
100
126
|
data: approveTx
|
|
101
127
|
};
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
if (wallet.supportsOfflineSigning()) {
|
|
107
|
-
try {
|
|
108
|
-
signedTx = await adapter.signTransaction({ txToSign: grantAllowanceTxToSign, wallet });
|
|
128
|
+
if (wallet.supportsOfflineSigning()) {
|
|
129
|
+
const signedTx = await adapter.signTransaction({ txToSign: grantAllowanceTxToSign, wallet });
|
|
130
|
+
const broadcastedTxId = await adapter.broadcastTransaction(signedTx);
|
|
131
|
+
return broadcastedTxId;
|
|
109
132
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
}
|
|
113
|
-
if (!signedTx) {
|
|
114
|
-
throw new api_1.SwapError(`grantAllowance - Signed transaction is required: ${signedTx}`);
|
|
115
|
-
}
|
|
116
|
-
try {
|
|
117
|
-
broadcastedTxId = await adapter.broadcastTransaction(signedTx);
|
|
118
|
-
}
|
|
119
|
-
catch (error) {
|
|
120
|
-
throw new api_1.SwapError(`grantAllowance - broadcastTransaction error: ${error}`);
|
|
121
|
-
}
|
|
122
|
-
return broadcastedTxId;
|
|
123
|
-
}
|
|
124
|
-
else if (wallet.supportsBroadcast() && adapter.signAndBroadcastTransaction) {
|
|
125
|
-
try {
|
|
126
|
-
broadcastedTxId = await ((_e = adapter.signAndBroadcastTransaction) === null || _e === void 0 ? void 0 : _e.call(adapter, {
|
|
133
|
+
else if (wallet.supportsBroadcast() && adapter.signAndBroadcastTransaction) {
|
|
134
|
+
const broadcastedTxId = await ((_e = adapter.signAndBroadcastTransaction) === null || _e === void 0 ? void 0 : _e.call(adapter, {
|
|
127
135
|
txToSign: grantAllowanceTxToSign,
|
|
128
136
|
wallet
|
|
129
137
|
}));
|
|
138
|
+
return broadcastedTxId;
|
|
130
139
|
}
|
|
131
|
-
|
|
132
|
-
throw new api_1.SwapError(
|
|
140
|
+
else {
|
|
141
|
+
throw new api_1.SwapError('[grantAllowance] - invalid HDWallet config', {
|
|
142
|
+
code: api_1.SwapErrorTypes.SIGN_AND_BROADCAST_FAILED
|
|
143
|
+
});
|
|
133
144
|
}
|
|
134
|
-
return broadcastedTxId;
|
|
135
145
|
}
|
|
136
|
-
|
|
137
|
-
|
|
146
|
+
catch (e) {
|
|
147
|
+
if (e instanceof api_1.SwapError)
|
|
148
|
+
throw e;
|
|
149
|
+
throw new api_1.SwapError('[grantAllowance]', {
|
|
150
|
+
cause: e,
|
|
151
|
+
code: api_1.SwapErrorTypes.GRANT_ALLOWANCE_FAILED
|
|
152
|
+
});
|
|
138
153
|
}
|
|
139
154
|
};
|
|
140
155
|
exports.grantAllowance = grantAllowance;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.FOX = exports.WETH = exports.BTC = void 0;
|
|
4
|
-
const caip_1 = require("@shapeshiftoss/caip");
|
|
5
4
|
const types_1 = require("@shapeshiftoss/types");
|
|
6
5
|
exports.BTC = {
|
|
7
6
|
assetId: 'bip122:000000000019d6689c085ae165831e93/slip44:0',
|
|
@@ -12,7 +11,7 @@ exports.BTC = {
|
|
|
12
11
|
network: types_1.NetworkTypes.MAINNET,
|
|
13
12
|
precision: 8,
|
|
14
13
|
slip44: 44,
|
|
15
|
-
contractType:
|
|
14
|
+
contractType: 'erc20',
|
|
16
15
|
color: '#FFFFFF',
|
|
17
16
|
secondaryColor: '#FFFFFF',
|
|
18
17
|
icon: 'https://assets.coincap.io/assets/icons/btc@2x.png',
|
|
@@ -32,7 +31,7 @@ exports.WETH = {
|
|
|
32
31
|
network: types_1.NetworkTypes.MAINNET,
|
|
33
32
|
precision: 18,
|
|
34
33
|
tokenId: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
|
|
35
|
-
contractType:
|
|
34
|
+
contractType: 'erc20',
|
|
36
35
|
color: '#FFFFFF',
|
|
37
36
|
secondaryColor: '#FFFFFF',
|
|
38
37
|
icon: 'https://assets.coingecko.com/coins/images/2518/thumb/weth.png?1628852295',
|
|
@@ -53,7 +52,7 @@ exports.FOX = {
|
|
|
53
52
|
network: types_1.NetworkTypes.MAINNET,
|
|
54
53
|
precision: 18,
|
|
55
54
|
tokenId: '0xc770eefad204b5180df6a14ee197d99d808ee52d',
|
|
56
|
-
contractType:
|
|
55
|
+
contractType: 'erc20',
|
|
57
56
|
color: '#FFFFFF',
|
|
58
57
|
secondaryColor: '#FFFFFF',
|
|
59
58
|
icon: 'https://assets.coincap.io/assets/icons/fox@2x.png',
|
|
@@ -33,30 +33,21 @@ const constants_1 = require("../utils/constants");
|
|
|
33
33
|
const helpers_1 = require("../utils/helpers/helpers");
|
|
34
34
|
const zrxService_1 = require("../utils/zrxService");
|
|
35
35
|
async function zrxBuildTrade({ adapterManager, web3 }, input) {
|
|
36
|
-
var _a, _b, _c
|
|
36
|
+
var _a, _b, _c;
|
|
37
37
|
const { sellAsset, buyAsset, sellAmount, slippage, sellAssetAccountId, buyAssetAccountId, wallet } = input;
|
|
38
|
-
if (!sellAssetAccountId || !buyAssetAccountId) {
|
|
39
|
-
throw new __1.SwapError('ZrxSwapper:ZrxBuildTrade Both sellAssetAccountId and buyAssetAccountId are required');
|
|
40
|
-
}
|
|
41
|
-
const buyToken = buyAsset.tokenId || buyAsset.symbol || buyAsset.network;
|
|
42
|
-
const sellToken = sellAsset.tokenId || sellAsset.symbol || sellAsset.network;
|
|
43
|
-
if (!buyToken) {
|
|
44
|
-
throw new __1.SwapError('ZrxSwapper:ZrxBuildTrade One of buyAssetContract or buyAssetSymbol or buyAssetNetwork are required');
|
|
45
|
-
}
|
|
46
|
-
if (!sellToken) {
|
|
47
|
-
throw new __1.SwapError('ZrxSwapper:ZrxBuildTrade One of sellAssetContract or sellAssetSymbol or sellAssetNetwork are required');
|
|
48
|
-
}
|
|
49
|
-
if (buyAsset.chainId !== 'eip155:1') {
|
|
50
|
-
throw new __1.SwapError('ZrxSwapper:ZrxBuildTrade buyAsset must be on chainId eip155:1');
|
|
51
|
-
}
|
|
52
|
-
const adapter = adapterManager.byChain(buyAsset.chain);
|
|
53
|
-
const bip44Params = adapter.buildBIP44Params({ accountNumber: Number(buyAssetAccountId) });
|
|
54
|
-
const receiveAddress = await adapter.getAddress({ wallet, bip44Params });
|
|
55
|
-
if ((0, bignumber_1.bnOrZero)(slippage).gt(constants_1.MAX_SLIPPAGE)) {
|
|
56
|
-
throw new __1.SwapError(`ZrxSwapper:ZrxBuildTrade slippage value of ${slippage} is greater than max slippage value of ${constants_1.MAX_SLIPPAGE}`);
|
|
57
|
-
}
|
|
58
|
-
const slippagePercentage = slippage ? (0, bignumber_1.bnOrZero)(slippage).div(100).toString() : constants_1.DEFAULT_SLIPPAGE;
|
|
59
38
|
try {
|
|
39
|
+
const buyToken = buyAsset.tokenId || buyAsset.symbol;
|
|
40
|
+
const sellToken = sellAsset.tokenId || sellAsset.symbol;
|
|
41
|
+
if (buyAsset.chainId !== 'eip155:1') {
|
|
42
|
+
throw new __1.SwapError('[ZrxBuildTrade] - buyAsset must be on chainId eip155:1', {
|
|
43
|
+
code: __1.SwapErrorTypes.VALIDATION_FAILED,
|
|
44
|
+
details: { chainId: sellAsset.chainId }
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
const adapter = await adapterManager.byChainId(buyAsset.chainId);
|
|
48
|
+
const bip44Params = adapter.buildBIP44Params({ accountNumber: Number(buyAssetAccountId) });
|
|
49
|
+
const receiveAddress = await adapter.getAddress({ wallet, bip44Params });
|
|
50
|
+
const slippagePercentage = slippage ? (0, bignumber_1.bnOrZero)(slippage).div(100).toString() : constants_1.DEFAULT_SLIPPAGE;
|
|
60
51
|
/**
|
|
61
52
|
* /swap/v1/quote
|
|
62
53
|
* params: {
|
|
@@ -137,27 +128,11 @@ async function zrxBuildTrade({ adapterManager, web3 }, input) {
|
|
|
137
128
|
return trade;
|
|
138
129
|
}
|
|
139
130
|
catch (e) {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
return {
|
|
146
|
-
sellAsset,
|
|
147
|
-
buyAsset,
|
|
148
|
-
success: false,
|
|
149
|
-
statusReason,
|
|
150
|
-
sellAmount: '0',
|
|
151
|
-
buyAmount: '0',
|
|
152
|
-
depositAddress: '',
|
|
153
|
-
allowanceContract: '',
|
|
154
|
-
receiveAddress: '',
|
|
155
|
-
sellAssetAccountId,
|
|
156
|
-
txData: '',
|
|
157
|
-
rate: '0',
|
|
158
|
-
feeData: { fee: '0', chainSpecific: {} },
|
|
159
|
-
sources: []
|
|
160
|
-
};
|
|
131
|
+
if (e instanceof __1.SwapError)
|
|
132
|
+
throw e;
|
|
133
|
+
throw new __1.SwapError('[ZrxBuildTrade]', {
|
|
134
|
+
code: __1.SwapErrorTypes.BUILD_TRADE_FAILED
|
|
135
|
+
});
|
|
161
136
|
}
|
|
162
137
|
}
|
|
163
138
|
exports.zrxBuildTrade = zrxBuildTrade;
|
|
@@ -3,30 +3,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.zrxExecuteTrade = void 0;
|
|
4
4
|
const web3_utils_1 = require("web3-utils");
|
|
5
5
|
const api_1 = require("../../../api");
|
|
6
|
+
const bignumber_1 = require("../utils/bignumber");
|
|
6
7
|
async function zrxExecuteTrade({ adapterManager }, { trade, wallet }) {
|
|
7
8
|
var _a, _b, _c, _d, _e, _f;
|
|
8
9
|
const { sellAsset } = trade;
|
|
9
|
-
if (!sellAsset.symbol) {
|
|
10
|
-
throw new api_1.SwapError('ZrxSwapper:ZrxExecuteTrade sellAssetSymbol is required');
|
|
11
|
-
}
|
|
12
|
-
if (!trade.sellAssetAccountId) {
|
|
13
|
-
throw new api_1.SwapError('ZrxSwapper:ZrxExecuteTrade sellAssetAccountId is required');
|
|
14
|
-
}
|
|
15
|
-
if (!trade.sellAmount) {
|
|
16
|
-
throw new api_1.SwapError('ZrxSwapper:ZrxExecuteTrade sellAmount is required');
|
|
17
|
-
}
|
|
18
|
-
if (!trade.depositAddress) {
|
|
19
|
-
throw new api_1.SwapError('ZrxSwapper:ZrxExecuteTrade depositAddress is required');
|
|
20
|
-
}
|
|
21
|
-
// value is 0 for erc20s
|
|
22
|
-
const value = sellAsset.symbol === 'ETH' ? trade.sellAmount : '0';
|
|
23
|
-
const adapter = adapterManager.byChain(sellAsset.chain);
|
|
24
|
-
const bip44Params = adapter.buildBIP44Params({
|
|
25
|
-
accountNumber: Number(trade.sellAssetAccountId)
|
|
26
|
-
});
|
|
27
|
-
let buildTxResponse, signedTx, txid;
|
|
28
10
|
try {
|
|
29
|
-
|
|
11
|
+
// value is 0 for erc20s
|
|
12
|
+
const value = sellAsset.assetId === 'eip155:1/slip44:60' ? trade.sellAmount : '0';
|
|
13
|
+
const adapter = await adapterManager.byChainId(sellAsset.chainId);
|
|
14
|
+
const bip44Params = adapter.buildBIP44Params({
|
|
15
|
+
accountNumber: (0, bignumber_1.bnOrZero)(trade.sellAssetAccountId).toNumber()
|
|
16
|
+
});
|
|
17
|
+
const buildTxResponse = await adapter.buildSendTransaction({
|
|
30
18
|
value,
|
|
31
19
|
wallet,
|
|
32
20
|
to: trade.depositAddress,
|
|
@@ -36,41 +24,33 @@ async function zrxExecuteTrade({ adapterManager }, { trade, wallet }) {
|
|
|
36
24
|
},
|
|
37
25
|
bip44Params
|
|
38
26
|
});
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
if (wallet.supportsOfflineSigning()) {
|
|
46
|
-
try {
|
|
47
|
-
signedTx = await adapter.signTransaction({ txToSign: txWithQuoteData, wallet });
|
|
27
|
+
const { txToSign } = buildTxResponse;
|
|
28
|
+
const txWithQuoteData = { ...txToSign, data: (_e = trade.txData) !== null && _e !== void 0 ? _e : '' };
|
|
29
|
+
if (wallet.supportsOfflineSigning()) {
|
|
30
|
+
const signedTx = await adapter.signTransaction({ txToSign: txWithQuoteData, wallet });
|
|
31
|
+
const txid = await adapter.broadcastTransaction(signedTx);
|
|
32
|
+
return { txid };
|
|
48
33
|
}
|
|
49
|
-
|
|
50
|
-
|
|
34
|
+
else if (wallet.supportsBroadcast() && adapter.signAndBroadcastTransaction) {
|
|
35
|
+
const txid = await ((_f = adapter.signAndBroadcastTransaction) === null || _f === void 0 ? void 0 : _f.call(adapter, {
|
|
36
|
+
txToSign: txWithQuoteData,
|
|
37
|
+
wallet
|
|
38
|
+
}));
|
|
39
|
+
return { txid };
|
|
51
40
|
}
|
|
52
|
-
|
|
53
|
-
throw new api_1.SwapError(
|
|
41
|
+
else {
|
|
42
|
+
throw new api_1.SwapError('[zrxExecuteTrade]', {
|
|
43
|
+
code: api_1.SwapErrorTypes.SIGN_AND_BROADCAST_FAILED
|
|
44
|
+
});
|
|
54
45
|
}
|
|
55
|
-
try {
|
|
56
|
-
txid = await adapter.broadcastTransaction(signedTx);
|
|
57
|
-
}
|
|
58
|
-
catch (error) {
|
|
59
|
-
throw new api_1.SwapError(`ZrxExecuteTrade - broadcastTransaction error: ${error}`);
|
|
60
|
-
}
|
|
61
|
-
return { txid };
|
|
62
|
-
}
|
|
63
|
-
else if (wallet.supportsBroadcast() && adapter.signAndBroadcastTransaction) {
|
|
64
|
-
try {
|
|
65
|
-
txid = await ((_f = adapter.signAndBroadcastTransaction) === null || _f === void 0 ? void 0 : _f.call(adapter, { txToSign: txWithQuoteData, wallet }));
|
|
66
|
-
}
|
|
67
|
-
catch (error) {
|
|
68
|
-
throw new api_1.SwapError(`ZrxExecuteTrade - signAndBroadcastTransaction error: ${error}`);
|
|
69
|
-
}
|
|
70
|
-
return { txid };
|
|
71
46
|
}
|
|
72
|
-
|
|
73
|
-
|
|
47
|
+
catch (e) {
|
|
48
|
+
if (e instanceof api_1.SwapError)
|
|
49
|
+
throw e;
|
|
50
|
+
throw new api_1.SwapError('[zrxExecuteTrade]', {
|
|
51
|
+
cause: e,
|
|
52
|
+
code: api_1.SwapErrorTypes.EXECUTE_TRADE_FAILED
|
|
53
|
+
});
|
|
74
54
|
}
|
|
75
55
|
}
|
|
76
56
|
exports.zrxExecuteTrade = zrxExecuteTrade;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shapeshiftoss/swapper",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.1",
|
|
4
4
|
"description": "TODO: description",
|
|
5
5
|
"repository": "https://github.com/shapeshift/lib",
|
|
6
6
|
"license": "MIT",
|
|
@@ -30,18 +30,20 @@
|
|
|
30
30
|
"web3": "^1.6.1"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
|
-
"@shapeshiftoss/asset-service": "^
|
|
34
|
-
"@shapeshiftoss/caip": "^
|
|
35
|
-
"@shapeshiftoss/chain-adapters": "^
|
|
33
|
+
"@shapeshiftoss/asset-service": "^3.0.0",
|
|
34
|
+
"@shapeshiftoss/caip": "^4.0.0",
|
|
35
|
+
"@shapeshiftoss/chain-adapters": "^4.0.0",
|
|
36
36
|
"@shapeshiftoss/hdwallet-core": "1.20.0",
|
|
37
|
-
"@shapeshiftoss/types": "^4.0.0"
|
|
37
|
+
"@shapeshiftoss/types": "^4.0.0",
|
|
38
|
+
"@shapeshiftoss/errors": "^1.1.0"
|
|
38
39
|
},
|
|
39
40
|
"devDependencies": {
|
|
40
|
-
"@shapeshiftoss/asset-service": "^
|
|
41
|
-
"@shapeshiftoss/caip": "^
|
|
42
|
-
"@shapeshiftoss/chain-adapters": "^
|
|
41
|
+
"@shapeshiftoss/asset-service": "^3.0.0",
|
|
42
|
+
"@shapeshiftoss/caip": "^4.0.0",
|
|
43
|
+
"@shapeshiftoss/chain-adapters": "^4.0.0",
|
|
43
44
|
"@shapeshiftoss/hdwallet-core": "^1.20.0",
|
|
44
|
-
"@shapeshiftoss/types": "^4.
|
|
45
|
+
"@shapeshiftoss/types": "^4.1.0",
|
|
46
|
+
"@shapeshiftoss/errors": "^1.1.0",
|
|
45
47
|
"@types/readline-sync": "^1.4.4",
|
|
46
48
|
"readline-sync": "^1.4.10",
|
|
47
49
|
"web3-utils": "^1.5.2"
|