@lifi/sdk 1.1.4 → 1.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/CHANGELOG.md +11 -0
- package/dist/Lifi.js +3 -0
- package/dist/cjs/Lifi.d.ts +200 -0
- package/dist/cjs/Lifi.js +379 -0
- package/dist/cjs/allowance/index.d.ts +22 -0
- package/dist/cjs/allowance/index.js +78 -0
- package/dist/cjs/allowance/utils.d.ts +14 -0
- package/dist/cjs/allowance/utils.js +82 -0
- package/dist/cjs/balances/index.d.ts +11 -0
- package/dist/cjs/balances/index.js +46 -0
- package/dist/cjs/balances/utils.d.ts +5 -0
- package/dist/cjs/balances/utils.js +150 -0
- package/dist/cjs/connectors.d.ts +6 -0
- package/dist/cjs/connectors.js +77 -0
- package/dist/cjs/execution/StatusManager.d.ts +65 -0
- package/dist/cjs/execution/StatusManager.js +167 -0
- package/dist/cjs/execution/StepExecutor.d.ts +15 -0
- package/dist/cjs/execution/StepExecutor.js +74 -0
- package/dist/cjs/execution/allowance.execute.d.ts +4 -0
- package/dist/cjs/execution/allowance.execute.js +97 -0
- package/dist/cjs/execution/balanceCheck.execute.d.ts +3 -0
- package/dist/cjs/execution/balanceCheck.execute.js +48 -0
- package/dist/cjs/execution/bridges/bridge.execute.d.ts +7 -0
- package/dist/cjs/execution/bridges/bridge.execute.js +154 -0
- package/dist/cjs/execution/exchanges/swap.execute.d.ts +7 -0
- package/dist/cjs/execution/exchanges/swap.execute.js +164 -0
- package/dist/cjs/execution/index.d.ts +1 -0
- package/dist/cjs/execution/index.js +17 -0
- package/dist/cjs/execution/stepComparison.d.ts +14 -0
- package/dist/cjs/execution/stepComparison.js +46 -0
- package/dist/cjs/execution/switchChain.d.ts +16 -0
- package/dist/cjs/execution/switchChain.js +58 -0
- package/dist/cjs/execution/utils.d.ts +6 -0
- package/dist/cjs/execution/utils.js +137 -0
- package/dist/cjs/helpers.d.ts +19 -0
- package/dist/cjs/helpers.js +88 -0
- package/dist/cjs/index.d.ts +6 -0
- package/dist/cjs/index.js +27 -0
- package/dist/cjs/services/ApiService.d.ts +15 -0
- package/dist/cjs/services/ApiService.js +272 -0
- package/dist/cjs/services/ChainsService.d.ts +11 -0
- package/dist/cjs/services/ChainsService.js +54 -0
- package/dist/cjs/services/ConfigService.d.ts +23 -0
- package/dist/cjs/services/ConfigService.js +98 -0
- package/dist/cjs/typeguards.d.ts +4 -0
- package/dist/cjs/typeguards.js +53 -0
- package/dist/cjs/types/ERC20.d.ts +22 -0
- package/dist/cjs/types/ERC20.js +53 -0
- package/dist/cjs/types/index.d.ts +4 -0
- package/dist/cjs/types/index.js +22 -0
- package/dist/cjs/types/internal.types.d.ts +87 -0
- package/dist/cjs/types/internal.types.js +2 -0
- package/dist/cjs/utils/errors.d.ts +75 -0
- package/dist/cjs/utils/errors.js +115 -0
- package/dist/cjs/utils/getProvider.d.ts +3 -0
- package/dist/cjs/utils/getProvider.js +11 -0
- package/dist/cjs/utils/multicall.d.ts +10 -0
- package/dist/cjs/utils/multicall.js +77 -0
- package/dist/cjs/utils/multicallAbi.json +313 -0
- package/dist/cjs/utils/parseError.d.ts +38 -0
- package/dist/cjs/utils/parseError.js +141 -0
- package/dist/cjs/utils/preRestart.d.ts +2 -0
- package/dist/cjs/utils/preRestart.js +31 -0
- package/dist/cjs/utils/utils.d.ts +26 -0
- package/dist/cjs/utils/utils.js +120 -0
- package/dist/cjs/version.d.ts +2 -0
- package/dist/cjs/version.js +5 -0
- package/dist/helpers.d.ts +1 -0
- package/dist/helpers.js +33 -0
- package/dist/types/internal.types.d.ts +2 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.js +2 -0
- package/package.json +40 -12
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.SwapExecutionManager = void 0;
|
|
16
|
+
const ethers_1 = require("ethers");
|
|
17
|
+
const ApiService_1 = __importDefault(require("../../services/ApiService"));
|
|
18
|
+
const ChainsService_1 = __importDefault(require("../../services/ChainsService"));
|
|
19
|
+
const errors_1 = require("../../utils/errors");
|
|
20
|
+
const getProvider_1 = require("../../utils/getProvider");
|
|
21
|
+
const parseError_1 = require("../../utils/parseError");
|
|
22
|
+
const utils_1 = require("../../utils/utils");
|
|
23
|
+
const allowance_execute_1 = require("../allowance.execute");
|
|
24
|
+
const balanceCheck_execute_1 = require("../balanceCheck.execute");
|
|
25
|
+
const stepComparison_1 = require("../stepComparison");
|
|
26
|
+
const switchChain_1 = require("../switchChain");
|
|
27
|
+
const utils_2 = require("../utils");
|
|
28
|
+
class SwapExecutionManager {
|
|
29
|
+
constructor() {
|
|
30
|
+
this.shouldContinue = true;
|
|
31
|
+
this.setShouldContinue = (val) => {
|
|
32
|
+
this.shouldContinue = val;
|
|
33
|
+
};
|
|
34
|
+
this.execute = ({ signer, step, statusManager, settings, }) => __awaiter(this, void 0, void 0, function* () {
|
|
35
|
+
// setup
|
|
36
|
+
var _a, _b, _c, _d;
|
|
37
|
+
const { action, estimate } = step;
|
|
38
|
+
step.execution = statusManager.initExecutionObject(step);
|
|
39
|
+
const chainsService = ChainsService_1.default.getInstance();
|
|
40
|
+
const fromChain = yield chainsService.getChainById(action.fromChainId);
|
|
41
|
+
// Approval
|
|
42
|
+
if (action.fromToken.address !== ethers_1.constants.AddressZero) {
|
|
43
|
+
yield (0, allowance_execute_1.checkAllowance)(signer, step, fromChain, action.fromToken, action.fromAmount, estimate.approvalAddress, statusManager, settings.infiniteApproval, this.shouldContinue);
|
|
44
|
+
}
|
|
45
|
+
// Start Swap
|
|
46
|
+
// -> set step.execution
|
|
47
|
+
let swapProcess = statusManager.findOrCreateProcess('SWAP', step);
|
|
48
|
+
// -> swapping
|
|
49
|
+
let tx;
|
|
50
|
+
try {
|
|
51
|
+
if (swapProcess.txHash) {
|
|
52
|
+
// -> restore existing tx
|
|
53
|
+
tx = yield (0, getProvider_1.getProvider)(signer).getTransaction(swapProcess.txHash);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
// -> check balance
|
|
57
|
+
yield (0, balanceCheck_execute_1.balanceCheck)(signer, step);
|
|
58
|
+
// -> get tx from backend
|
|
59
|
+
const personalizedStep = yield (0, utils_1.personalizeStep)(signer, step);
|
|
60
|
+
const updatedStep = yield ApiService_1.default.getStepTransaction(personalizedStep);
|
|
61
|
+
step = Object.assign(Object.assign({}, (yield (0, stepComparison_1.stepComparison)(statusManager, personalizedStep, updatedStep, settings.acceptSlippageUpdateHook, this.shouldContinue))), { execution: step.execution });
|
|
62
|
+
const { transactionRequest } = step;
|
|
63
|
+
if (!transactionRequest) {
|
|
64
|
+
throw new errors_1.TransactionError(errors_1.LifiErrorCode.TransactionUnprepared, 'Unable to prepare transaction.');
|
|
65
|
+
}
|
|
66
|
+
// make sure that chain is still correct
|
|
67
|
+
const updatedSigner = yield (0, switchChain_1.switchChain)(signer, statusManager, step, settings.switchChainHook, this.shouldContinue);
|
|
68
|
+
if (!updatedSigner) {
|
|
69
|
+
// chain switch was not successful, stop execution here
|
|
70
|
+
return step.execution;
|
|
71
|
+
}
|
|
72
|
+
signer = updatedSigner;
|
|
73
|
+
// -> set step.execution
|
|
74
|
+
swapProcess = swapProcess = statusManager.updateProcess(step, swapProcess.type, 'ACTION_REQUIRED');
|
|
75
|
+
if (!this.shouldContinue) {
|
|
76
|
+
return step.execution; // stop before user interaction is needed
|
|
77
|
+
}
|
|
78
|
+
// -> submit tx
|
|
79
|
+
tx = yield signer.sendTransaction(transactionRequest);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
catch (e) {
|
|
83
|
+
const error = yield (0, parseError_1.parseError)(e, step, swapProcess);
|
|
84
|
+
swapProcess = statusManager.updateProcess(step, swapProcess.type, 'FAILED', {
|
|
85
|
+
error: {
|
|
86
|
+
message: error.message,
|
|
87
|
+
htmlMessage: error.htmlMessage,
|
|
88
|
+
code: error.code,
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
statusManager.updateExecution(step, 'FAILED');
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
// Wait for Transaction
|
|
95
|
+
swapProcess = statusManager.updateProcess(step, swapProcess.type, 'PENDING', {
|
|
96
|
+
txLink: fromChain.metamask.blockExplorerUrls[0] + 'tx/' + tx.hash,
|
|
97
|
+
txHash: tx.hash,
|
|
98
|
+
});
|
|
99
|
+
// -> waiting
|
|
100
|
+
let receipt;
|
|
101
|
+
try {
|
|
102
|
+
receipt = yield tx.wait();
|
|
103
|
+
}
|
|
104
|
+
catch (e) {
|
|
105
|
+
// -> set status
|
|
106
|
+
if (e.code === 'TRANSACTION_REPLACED' && e.replacement) {
|
|
107
|
+
receipt = e.replacement;
|
|
108
|
+
swapProcess = statusManager.updateProcess(step, swapProcess.type, 'PENDING', {
|
|
109
|
+
txHash: e.replacement.hash,
|
|
110
|
+
txLink: fromChain.metamask.blockExplorerUrls[0] +
|
|
111
|
+
'tx/' +
|
|
112
|
+
e.replacement.hash,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
const error = yield (0, parseError_1.parseError)(e);
|
|
117
|
+
swapProcess = statusManager.updateProcess(step, swapProcess.type, 'FAILED', {
|
|
118
|
+
error: {
|
|
119
|
+
message: error.message,
|
|
120
|
+
htmlMessage: error.htmlMessage,
|
|
121
|
+
code: error.code,
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
statusManager.updateExecution(step, 'FAILED');
|
|
125
|
+
throw error;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
let statusResponse;
|
|
129
|
+
try {
|
|
130
|
+
if (!swapProcess.txHash) {
|
|
131
|
+
throw new Error('Transaction hash is undefined.');
|
|
132
|
+
}
|
|
133
|
+
statusResponse = yield (0, utils_2.waitForReceivingTransaction)(swapProcess.txHash, statusManager, swapProcess.type, step);
|
|
134
|
+
}
|
|
135
|
+
catch (e) {
|
|
136
|
+
swapProcess = statusManager.updateProcess(step, swapProcess.type, 'FAILED', {
|
|
137
|
+
error: {
|
|
138
|
+
code: errors_1.LifiErrorCode.TransactionFailed,
|
|
139
|
+
message: 'Failed while waiting for receiving chain.',
|
|
140
|
+
htmlMessage: (0, parseError_1.getTransactionFailedMessage)(step, swapProcess.txLink),
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
statusManager.updateExecution(step, 'FAILED');
|
|
144
|
+
throw e;
|
|
145
|
+
}
|
|
146
|
+
swapProcess = statusManager.updateProcess(step, swapProcess.type, 'DONE', {
|
|
147
|
+
txHash: (_a = statusResponse.receiving) === null || _a === void 0 ? void 0 : _a.txHash,
|
|
148
|
+
txLink: fromChain.metamask.blockExplorerUrls[0] +
|
|
149
|
+
'tx/' +
|
|
150
|
+
((_b = statusResponse.receiving) === null || _b === void 0 ? void 0 : _b.txHash),
|
|
151
|
+
});
|
|
152
|
+
statusManager.updateExecution(step, 'DONE', {
|
|
153
|
+
fromAmount: statusResponse.sending.amount,
|
|
154
|
+
toAmount: (_c = statusResponse.receiving) === null || _c === void 0 ? void 0 : _c.amount,
|
|
155
|
+
toToken: (_d = statusResponse.receiving) === null || _d === void 0 ? void 0 : _d.token,
|
|
156
|
+
gasUsed: statusResponse.sending.gasUsed,
|
|
157
|
+
gasPrice: statusResponse.sending.gasPrice,
|
|
158
|
+
});
|
|
159
|
+
// DONE
|
|
160
|
+
return step.execution;
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
exports.SwapExecutionManager = SwapExecutionManager;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './StatusManager';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./StatusManager"), exports);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { StatusManager } from '.';
|
|
2
|
+
import { AcceptSlippageUpdateHook, Step } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* This method checks whether the new and updated Step meets the required slippage conditions.
|
|
5
|
+
* If yes it returns the updated Step.
|
|
6
|
+
* If no and if user interaction is allowed it triggers the acceptSlippageUpdateHook. If no user interaction is allowed it aborts.
|
|
7
|
+
*
|
|
8
|
+
* @param statusManager
|
|
9
|
+
* @param oldStep
|
|
10
|
+
* @param newStep
|
|
11
|
+
* @param acceptSlippageUpdateHook
|
|
12
|
+
* @param allowUserInteraction
|
|
13
|
+
*/
|
|
14
|
+
export declare const stepComparison: (statusManager: StatusManager, oldStep: Step, newStep: Step, acceptSlippageUpdateHook: AcceptSlippageUpdateHook, allowUserInteraction: boolean) => Promise<Step>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.stepComparison = void 0;
|
|
13
|
+
const errors_1 = require("../utils/errors");
|
|
14
|
+
const parseError_1 = require("../utils/parseError");
|
|
15
|
+
const utils_1 = require("./utils");
|
|
16
|
+
/**
|
|
17
|
+
* This method checks whether the new and updated Step meets the required slippage conditions.
|
|
18
|
+
* If yes it returns the updated Step.
|
|
19
|
+
* If no and if user interaction is allowed it triggers the acceptSlippageUpdateHook. If no user interaction is allowed it aborts.
|
|
20
|
+
*
|
|
21
|
+
* @param statusManager
|
|
22
|
+
* @param oldStep
|
|
23
|
+
* @param newStep
|
|
24
|
+
* @param acceptSlippageUpdateHook
|
|
25
|
+
* @param allowUserInteraction
|
|
26
|
+
*/
|
|
27
|
+
const stepComparison = (statusManager, oldStep, newStep, acceptSlippageUpdateHook, allowUserInteraction) => __awaiter(void 0, void 0, void 0, function* () {
|
|
28
|
+
if ((0, utils_1.updatedStepMeetsSlippageConditions)(oldStep, newStep)) {
|
|
29
|
+
return statusManager.updateStepInRoute(newStep);
|
|
30
|
+
}
|
|
31
|
+
let allowStepUpdate;
|
|
32
|
+
if (allowUserInteraction) {
|
|
33
|
+
allowStepUpdate = yield acceptSlippageUpdateHook({
|
|
34
|
+
oldToAmount: oldStep.estimate.toAmount,
|
|
35
|
+
newToAmount: newStep.estimate.toAmount,
|
|
36
|
+
toToken: newStep.action.toToken,
|
|
37
|
+
oldSlippage: oldStep.action.slippage,
|
|
38
|
+
newSlippage: newStep.action.slippage,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
if (!allowStepUpdate) {
|
|
42
|
+
throw new errors_1.TransactionError(errors_1.LifiErrorCode.SlippageNotMet, 'Slippage conditions not met!', (0, parseError_1.getSlippageNotMetMessage)(oldStep));
|
|
43
|
+
}
|
|
44
|
+
return statusManager.updateStepInRoute(newStep);
|
|
45
|
+
});
|
|
46
|
+
exports.stepComparison = stepComparison;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Step } from '@lifi/types';
|
|
2
|
+
import { Signer } from 'ethers';
|
|
3
|
+
import { SwitchChainHook } from '../types';
|
|
4
|
+
import { StatusManager } from './StatusManager';
|
|
5
|
+
/**
|
|
6
|
+
* This method checks whether the signer is configured for the correct chain.
|
|
7
|
+
* If yes it returns the signer.
|
|
8
|
+
* If no and if user interaction is allowed it triggers the switchChainHook. If no user interaction is allowed it aborts.
|
|
9
|
+
*
|
|
10
|
+
* @param signer
|
|
11
|
+
* @param statusManager
|
|
12
|
+
* @param step
|
|
13
|
+
* @param switchChainHook
|
|
14
|
+
* @param allowUserInteraction
|
|
15
|
+
*/
|
|
16
|
+
export declare const switchChain: (signer: Signer, statusManager: StatusManager, step: Step, switchChainHook: SwitchChainHook, allowUserInteraction: boolean) => Promise<Signer | undefined>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.switchChain = void 0;
|
|
13
|
+
const errors_1 = require("../utils/errors");
|
|
14
|
+
/**
|
|
15
|
+
* This method checks whether the signer is configured for the correct chain.
|
|
16
|
+
* If yes it returns the signer.
|
|
17
|
+
* If no and if user interaction is allowed it triggers the switchChainHook. If no user interaction is allowed it aborts.
|
|
18
|
+
*
|
|
19
|
+
* @param signer
|
|
20
|
+
* @param statusManager
|
|
21
|
+
* @param step
|
|
22
|
+
* @param switchChainHook
|
|
23
|
+
* @param allowUserInteraction
|
|
24
|
+
*/
|
|
25
|
+
const switchChain = (signer, statusManager, step, switchChainHook, allowUserInteraction) => __awaiter(void 0, void 0, void 0, function* () {
|
|
26
|
+
// if we are already on the correct chain we can proceed directly
|
|
27
|
+
if ((yield signer.getChainId()) === step.action.fromChainId) {
|
|
28
|
+
return signer;
|
|
29
|
+
}
|
|
30
|
+
// -> set status message
|
|
31
|
+
step.execution = statusManager.initExecutionObject(step);
|
|
32
|
+
statusManager.updateExecution(step, 'CHAIN_SWITCH_REQUIRED');
|
|
33
|
+
let switchProcess = statusManager.findOrCreateProcess('SWITCH_CHAIN', step, 'PENDING');
|
|
34
|
+
if (!allowUserInteraction) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
const updatedSigner = yield switchChainHook(step.action.fromChainId);
|
|
39
|
+
const updatedChainId = yield (updatedSigner === null || updatedSigner === void 0 ? void 0 : updatedSigner.getChainId());
|
|
40
|
+
if (updatedChainId !== step.action.fromChainId) {
|
|
41
|
+
throw new errors_1.ProviderError(errors_1.LifiErrorCode.ChainSwitchError, 'Chain switch required.');
|
|
42
|
+
}
|
|
43
|
+
switchProcess = statusManager.updateProcess(step, switchProcess.type, 'DONE');
|
|
44
|
+
statusManager.updateExecution(step, 'PENDING');
|
|
45
|
+
return updatedSigner;
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
switchProcess = statusManager.updateProcess(step, switchProcess.type, 'FAILED', {
|
|
49
|
+
error: {
|
|
50
|
+
message: error.message,
|
|
51
|
+
code: error.code,
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
statusManager.updateExecution(step, 'FAILED');
|
|
55
|
+
throw error;
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
exports.switchChain = switchChain;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ProcessType, Status, StatusMessage, StatusResponse, Step, Substatus } from '@lifi/types';
|
|
2
|
+
import { StatusManager } from '..';
|
|
3
|
+
export declare function waitForReceivingTransaction(txHash: string, statusManager: StatusManager, processType: ProcessType, step: Step): Promise<StatusResponse>;
|
|
4
|
+
export declare function getProcessMessage(type: ProcessType, status: Status): string | undefined;
|
|
5
|
+
export declare function getSubstatusMessage(status: StatusMessage, substatus?: Substatus): string | undefined;
|
|
6
|
+
export declare function updatedStepMeetsSlippageConditions(oldStep: Step, newStep: Step): boolean;
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.updatedStepMeetsSlippageConditions = exports.getSubstatusMessage = exports.getProcessMessage = exports.waitForReceivingTransaction = void 0;
|
|
16
|
+
const bignumber_js_1 = __importDefault(require("bignumber.js"));
|
|
17
|
+
const ApiService_1 = __importDefault(require("../services/ApiService"));
|
|
18
|
+
const errors_1 = require("../utils/errors");
|
|
19
|
+
const utils_1 = require("../utils/utils");
|
|
20
|
+
const TRANSACTION_HASH_OBSERVERS = {};
|
|
21
|
+
function waitForReceivingTransaction(txHash, statusManager, processType, step) {
|
|
22
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
23
|
+
const getStatus = () => new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
|
24
|
+
let statusResponse;
|
|
25
|
+
try {
|
|
26
|
+
statusResponse = yield ApiService_1.default.getStatus({
|
|
27
|
+
bridge: step.tool,
|
|
28
|
+
fromChain: step.action.fromChainId,
|
|
29
|
+
toChain: step.action.toChainId,
|
|
30
|
+
txHash,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
catch (e) {
|
|
34
|
+
console.debug('Fetching status from backend failed.', e);
|
|
35
|
+
return resolve(undefined);
|
|
36
|
+
}
|
|
37
|
+
switch (statusResponse.status) {
|
|
38
|
+
case 'DONE':
|
|
39
|
+
return resolve(statusResponse);
|
|
40
|
+
case 'PENDING':
|
|
41
|
+
statusManager === null || statusManager === void 0 ? void 0 : statusManager.updateProcess(step, processType, 'PENDING', {
|
|
42
|
+
substatus: statusResponse.substatus,
|
|
43
|
+
substatusMessage: statusResponse.substatusMessage ||
|
|
44
|
+
getSubstatusMessage(statusResponse.status, statusResponse.substatus),
|
|
45
|
+
});
|
|
46
|
+
return resolve(undefined);
|
|
47
|
+
case 'NOT_FOUND':
|
|
48
|
+
return resolve(undefined);
|
|
49
|
+
case 'FAILED':
|
|
50
|
+
default:
|
|
51
|
+
return reject();
|
|
52
|
+
}
|
|
53
|
+
}));
|
|
54
|
+
let status;
|
|
55
|
+
if (txHash in TRANSACTION_HASH_OBSERVERS) {
|
|
56
|
+
status = yield TRANSACTION_HASH_OBSERVERS[txHash];
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
TRANSACTION_HASH_OBSERVERS[txHash] = (0, utils_1.repeatUntilDone)(getStatus, 5000);
|
|
60
|
+
status = yield TRANSACTION_HASH_OBSERVERS[txHash];
|
|
61
|
+
}
|
|
62
|
+
if (!status.receiving) {
|
|
63
|
+
throw new errors_1.ServerError("Status doesn't contain receiving information.");
|
|
64
|
+
}
|
|
65
|
+
return status;
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
exports.waitForReceivingTransaction = waitForReceivingTransaction;
|
|
69
|
+
const processMessages = {
|
|
70
|
+
TOKEN_ALLOWANCE: {
|
|
71
|
+
STARTED: 'Setting token allowance.',
|
|
72
|
+
PENDING: 'Waiting for token allowance.',
|
|
73
|
+
DONE: 'Token allowance set.',
|
|
74
|
+
},
|
|
75
|
+
SWITCH_CHAIN: {
|
|
76
|
+
PENDING: 'Chain switch required.',
|
|
77
|
+
DONE: 'Chain switched successfully.',
|
|
78
|
+
},
|
|
79
|
+
SWAP: {
|
|
80
|
+
STARTED: 'Preparing swap.',
|
|
81
|
+
ACTION_REQUIRED: 'Please sign the transaction.',
|
|
82
|
+
PENDING: 'Swapping.',
|
|
83
|
+
DONE: 'Swap completed.',
|
|
84
|
+
},
|
|
85
|
+
CROSS_CHAIN: {
|
|
86
|
+
STARTED: 'Preparing transaction.',
|
|
87
|
+
ACTION_REQUIRED: 'Please sign the transaction.',
|
|
88
|
+
PENDING: 'Waiting for transaction.',
|
|
89
|
+
DONE: 'Transaction approved.',
|
|
90
|
+
},
|
|
91
|
+
RECEIVING_CHAIN: {
|
|
92
|
+
PENDING: 'Waiting for receiving chain.',
|
|
93
|
+
DONE: 'Funds received.',
|
|
94
|
+
},
|
|
95
|
+
TRANSACTION: {},
|
|
96
|
+
};
|
|
97
|
+
const substatusMessages = {
|
|
98
|
+
PENDING: {
|
|
99
|
+
BRIDGE_NOT_AVAILABLE: 'Bridge communication is temporarily unavailable.',
|
|
100
|
+
CHAIN_NOT_AVAILABLE: 'RPC communication is temporarily unavailable.',
|
|
101
|
+
NOT_PROCESSABLE_REFUND_NEEDED: 'The transfer cannot be completed successfully. A refund operation is required.',
|
|
102
|
+
UNKNOWN_ERROR: 'An unexpected error occurred. Please seek assistance in the LI.FI discord server.',
|
|
103
|
+
WAIT_SOURCE_CONFIRMATIONS: 'The bridge deposit has been received. The bridge is waiting for more confirmations to start the off-chain logic.',
|
|
104
|
+
WAIT_DESTINATION_TRANSACTION: 'The bridge off-chain logic is being executed. Wait for the transaction to appear on the destination chain.',
|
|
105
|
+
},
|
|
106
|
+
DONE: {
|
|
107
|
+
PARTIAL: 'Some of the received tokens are not the requested destination tokens.',
|
|
108
|
+
REFUNDED: 'The tokens were refunded to the sender address.',
|
|
109
|
+
COMPLETED: 'The transfer is complete.',
|
|
110
|
+
},
|
|
111
|
+
FAILED: {},
|
|
112
|
+
INVALID: {},
|
|
113
|
+
NOT_FOUND: {},
|
|
114
|
+
};
|
|
115
|
+
function getProcessMessage(type, status) {
|
|
116
|
+
const processMessage = processMessages[type][status];
|
|
117
|
+
return processMessage;
|
|
118
|
+
}
|
|
119
|
+
exports.getProcessMessage = getProcessMessage;
|
|
120
|
+
function getSubstatusMessage(status, substatus) {
|
|
121
|
+
if (!substatus) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
const message = substatusMessages[status][substatus];
|
|
125
|
+
return message;
|
|
126
|
+
}
|
|
127
|
+
exports.getSubstatusMessage = getSubstatusMessage;
|
|
128
|
+
function updatedStepMeetsSlippageConditions(oldStep, newStep) {
|
|
129
|
+
const setSlippage = new bignumber_js_1.default(oldStep.action.slippage);
|
|
130
|
+
const oldEstimatedToAmount = new bignumber_js_1.default(oldStep.estimate.toAmountMin);
|
|
131
|
+
const newEstimatedToAmount = new bignumber_js_1.default(newStep.estimate.toAmountMin);
|
|
132
|
+
const amountDifference = oldEstimatedToAmount.minus(newEstimatedToAmount);
|
|
133
|
+
const actualSlippage = amountDifference.dividedBy(oldEstimatedToAmount);
|
|
134
|
+
return (newEstimatedToAmount.gte(oldEstimatedToAmount) &&
|
|
135
|
+
actualSlippage.lte(setSlippage));
|
|
136
|
+
}
|
|
137
|
+
exports.updatedStepMeetsSlippageConditions = updatedStepMeetsSlippageConditions;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Token } from '@lifi/types';
|
|
2
|
+
/**
|
|
3
|
+
* Predefined hook that decrypts calldata using EIP-1193 compliant wallet functions.
|
|
4
|
+
* @param {string} walletAddress - The wallet address of the user that should decrypt the calldata.
|
|
5
|
+
* @return {(encryptedData: string) => Promise<any>} A function that decrypts data using EIP-1193 compliant wallet functions.
|
|
6
|
+
*/
|
|
7
|
+
export declare const getEthereumDecryptionHook: (walletAddress: string) => (encryptedData: string) => Promise<string>;
|
|
8
|
+
/**
|
|
9
|
+
* Predefined hook that get the public encryption key of a user using EIP-1193 compliant wallet functions.
|
|
10
|
+
* @param {string} walletAddress - The wallet address of the user.
|
|
11
|
+
* @return {(walletAddress: string) => () => Promise<any>} A function that return the public encryption key using EIP-1193 compliant wallet functions.
|
|
12
|
+
*/
|
|
13
|
+
export declare const getEthereumPublicKeyHook: (walletAddress: string) => () => Promise<string>;
|
|
14
|
+
/**
|
|
15
|
+
* Returns a random number between min (inclusive) and max (inclusive)
|
|
16
|
+
*/
|
|
17
|
+
export declare const getRandomNumber: (min: number, max: number) => number;
|
|
18
|
+
export declare const isSameToken: (tokenA: Token, tokenB: Token) => boolean;
|
|
19
|
+
export declare const checkPackageUpdates: (packageName?: string, packageVersion?: string, disableCheck?: boolean) => Promise<void>;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.checkPackageUpdates = exports.isSameToken = exports.getRandomNumber = exports.getEthereumPublicKeyHook = exports.getEthereumDecryptionHook = void 0;
|
|
13
|
+
const version_1 = require("./version");
|
|
14
|
+
const ethereumRequest = (method, params) => __awaiter(void 0, void 0, void 0, function* () {
|
|
15
|
+
// If ethereum.request() exists, the provider is probably EIP-1193 compliant.
|
|
16
|
+
if (!ethereum || !ethereum.request) {
|
|
17
|
+
throw new Error('Provider not available.');
|
|
18
|
+
}
|
|
19
|
+
return ethereum.request({
|
|
20
|
+
method,
|
|
21
|
+
params,
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
/**
|
|
25
|
+
* Predefined hook that decrypts calldata using EIP-1193 compliant wallet functions.
|
|
26
|
+
* @param {string} walletAddress - The wallet address of the user that should decrypt the calldata.
|
|
27
|
+
* @return {(encryptedData: string) => Promise<any>} A function that decrypts data using EIP-1193 compliant wallet functions.
|
|
28
|
+
*/
|
|
29
|
+
const getEthereumDecryptionHook = (walletAddress) => {
|
|
30
|
+
return (encryptedData) => {
|
|
31
|
+
return ethereumRequest('eth_decrypt', [encryptedData, walletAddress]);
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
exports.getEthereumDecryptionHook = getEthereumDecryptionHook;
|
|
35
|
+
/**
|
|
36
|
+
* Predefined hook that get the public encryption key of a user using EIP-1193 compliant wallet functions.
|
|
37
|
+
* @param {string} walletAddress - The wallet address of the user.
|
|
38
|
+
* @return {(walletAddress: string) => () => Promise<any>} A function that return the public encryption key using EIP-1193 compliant wallet functions.
|
|
39
|
+
*/
|
|
40
|
+
const getEthereumPublicKeyHook = (walletAddress) => {
|
|
41
|
+
return () => {
|
|
42
|
+
return ethereumRequest('eth_getEncryptionPublicKey', [walletAddress]);
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
exports.getEthereumPublicKeyHook = getEthereumPublicKeyHook;
|
|
46
|
+
/**
|
|
47
|
+
* Returns a random number between min (inclusive) and max (inclusive)
|
|
48
|
+
*/
|
|
49
|
+
const getRandomNumber = (min, max) => {
|
|
50
|
+
return Math.floor(Math.random() * (max - min + 1) + min);
|
|
51
|
+
};
|
|
52
|
+
exports.getRandomNumber = getRandomNumber;
|
|
53
|
+
const isSameToken = (tokenA, tokenB) => tokenA.chainId === tokenB.chainId &&
|
|
54
|
+
tokenA.address.toLowerCase() === tokenB.address.toLowerCase();
|
|
55
|
+
exports.isSameToken = isSameToken;
|
|
56
|
+
function semverCompare(a, b) {
|
|
57
|
+
if (a.startsWith(b + '-')) {
|
|
58
|
+
return -1;
|
|
59
|
+
}
|
|
60
|
+
if (b.startsWith(a + '-')) {
|
|
61
|
+
return 1;
|
|
62
|
+
}
|
|
63
|
+
return a.localeCompare(b, undefined, {
|
|
64
|
+
numeric: true,
|
|
65
|
+
sensitivity: 'case',
|
|
66
|
+
caseFirst: 'upper',
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
const checkPackageUpdates = (packageName, packageVersion, disableCheck) => __awaiter(void 0, void 0, void 0, function* () {
|
|
70
|
+
if (disableCheck || process.env.NODE_ENV !== 'development') {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
try {
|
|
74
|
+
const pkgName = packageName !== null && packageName !== void 0 ? packageName : version_1.name;
|
|
75
|
+
const response = yield (yield fetch(`https://unpkg.com/${pkgName}/package.json`)).json();
|
|
76
|
+
const latestVersion = response.version;
|
|
77
|
+
const currentVersion = packageVersion !== null && packageVersion !== void 0 ? packageVersion : version_1.version;
|
|
78
|
+
if (semverCompare(latestVersion, currentVersion)) {
|
|
79
|
+
console.warn(
|
|
80
|
+
// eslint-disable-next-line max-len
|
|
81
|
+
`${pkgName}: new package version is available. Please update as soon as possible to enjoy the newest features. Current version: ${currentVersion}. Latest version: ${latestVersion}.`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
// Cannot verify version, might be network error etc. We don't bother showing anything in that case
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
exports.checkPackageUpdates = checkPackageUpdates;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
17
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
// expose types and helpers
|
|
21
|
+
const Lifi_1 = __importDefault(require("./Lifi"));
|
|
22
|
+
__exportStar(require("./execution"), exports);
|
|
23
|
+
__exportStar(require("./helpers"), exports);
|
|
24
|
+
__exportStar(require("./types"), exports);
|
|
25
|
+
__exportStar(require("./utils/errors"), exports);
|
|
26
|
+
// expose sdk
|
|
27
|
+
exports.default = Lifi_1.default;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ContractCallQuoteRequest, GetStatusRequest, QuoteRequest, RequestOptions, TokensRequest, TokensResponse } from '@lifi/types';
|
|
2
|
+
import { ChainId, ChainKey, PossibilitiesRequest, PossibilitiesResponse, RoutesRequest, RoutesResponse, StatusResponse, Step, Token, ToolsRequest, ToolsResponse } from '../types';
|
|
3
|
+
declare const _default: {
|
|
4
|
+
getPossibilities: (request?: PossibilitiesRequest | undefined, options?: RequestOptions | undefined) => Promise<PossibilitiesResponse>;
|
|
5
|
+
getToken: (chain: ChainKey | ChainId, token: string, options?: RequestOptions | undefined) => Promise<Token>;
|
|
6
|
+
getQuote: (request: QuoteRequest, options?: RequestOptions | undefined) => Promise<Step>;
|
|
7
|
+
getContractCallQuote: (request: ContractCallQuoteRequest, options?: RequestOptions | undefined) => Promise<Step>;
|
|
8
|
+
getStatus: ({ bridge, fromChain, toChain, txHash }: GetStatusRequest, options?: RequestOptions | undefined) => Promise<StatusResponse>;
|
|
9
|
+
getChains: (options?: RequestOptions | undefined) => Promise<import("@lifi/types").EVMChain[]>;
|
|
10
|
+
getRoutes: (request: RoutesRequest, options?: RequestOptions | undefined) => Promise<RoutesResponse>;
|
|
11
|
+
getStepTransaction: (step: Step, options?: RequestOptions | undefined) => Promise<Step>;
|
|
12
|
+
getTools: (request?: ToolsRequest | undefined, options?: RequestOptions | undefined) => Promise<ToolsResponse>;
|
|
13
|
+
getTokens: (request?: TokensRequest | undefined, options?: RequestOptions | undefined) => Promise<TokensResponse>;
|
|
14
|
+
};
|
|
15
|
+
export default _default;
|