New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@lifi/sdk

Package Overview
Dependencies
Maintainers
1
Versions
172
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@lifi/sdk - npm Package Compare versions

Comparing version 1.4.1 to 1.5.0

7

CHANGELOG.md

@@ -5,2 +5,9 @@ # Changelog

## [1.5.0](https://github.com/lifinance/sdk/compare/v1.4.1...v1.5.0) (2022-09-06)
### Features
* add an option to start or resume execution in background ([#103](https://github.com/lifinance/sdk/issues/103)) ([c452559](https://github.com/lifinance/sdk/commit/c45255991ebcf494715c094db77f6c7599080c5d)), closes [#106](https://github.com/lifinance/sdk/issues/106) [#104](https://github.com/lifinance/sdk/issues/104)
### [1.4.1](https://github.com/lifinance/sdk/compare/v1.4.0...v1.4.1) (2022-09-06)

@@ -7,0 +14,0 @@

4

dist/cjs/execution/allowance.execute.d.ts
import { Signer } from 'ethers';
import { Chain, Step, Token } from '../types';
import { Chain, InternalExecutionSettings, Step } from '../types';
import { StatusManager } from './StatusManager';
export declare const checkAllowance: (signer: Signer, step: Step, chain: Chain, token: Token, amount: string, spenderAddress: string, statusManager: StatusManager, infiniteApproval?: boolean, allowUserInteraction?: boolean) => Promise<void>;
export declare const checkAllowance: (signer: Signer, step: Step, statusManager: StatusManager, settings: InternalExecutionSettings, chain: Chain, allowUserInteraction?: boolean) => Promise<void>;

@@ -21,30 +21,24 @@ "use strict";

const parseError_1 = require("../utils/parseError");
const checkAllowance = (signer, step, chain, token, amount, spenderAddress, statusManager, infiniteApproval = false, allowUserInteraction = false
// eslint-disable-next-line max-params
) => __awaiter(void 0, void 0, void 0, function* () {
// Ask user to set allowance
// -> set currentExecution
let allowanceProcess = statusManager.findOrCreateProcess('TOKEN_ALLOWANCE', step);
// -> check allowance
const checkAllowance = (signer, step, statusManager, settings, chain, allowUserInteraction = false) => __awaiter(void 0, void 0, void 0, function* () {
// Ask the user to set an allowance
let allowanceProcess = statusManager.findOrCreateProcess(step, 'TOKEN_ALLOWANCE');
// Check allowance
try {
if (allowanceProcess.txHash) {
allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'PENDING');
if (allowanceProcess.txHash && allowanceProcess.status !== 'DONE') {
if (allowanceProcess.status !== 'PENDING') {
allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'PENDING');
}
yield (0, getProvider_1.getProvider)(signer).waitForTransaction(allowanceProcess.txHash);
allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'DONE');
// TODO: Do we need this check?
}
else if (allowanceProcess.status === 'DONE') {
allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'DONE');
}
else {
const approved = yield (0, utils_1.getApproved)(signer, token.address, spenderAddress);
if (new bignumber_js_1.default(amount).gt(approved)) {
const approved = yield (0, utils_1.getApproved)(signer, step.action.fromToken.address, step.estimate.approvalAddress);
if (new bignumber_js_1.default(step.action.fromAmount).gt(approved)) {
if (!allowUserInteraction) {
return;
}
const approvalAmount = infiniteApproval
const approvalAmount = settings.infiniteApproval
? ethers_1.constants.MaxUint256.toString()
: amount;
const approveTx = yield (0, utils_1.setApproval)(signer, token.address, spenderAddress, approvalAmount);
// update currentExecution
: step.action.fromAmount;
const approveTx = yield (0, utils_1.setApproval)(signer, step.action.fromToken.address, step.estimate.approvalAddress, approvalAmount);
allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'PENDING', {

@@ -54,3 +48,3 @@ txHash: approveTx.hash,

});
// wait for transcation
// Wait for the transcation
yield approveTx.wait();

@@ -65,3 +59,2 @@ allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'DONE');

catch (e) {
// -> set status
if (e.code === 'TRANSACTION_REPLACED' && e.replacement) {

@@ -68,0 +61,0 @@ yield transactionReplaced(e.replacement, allowanceProcess, step, chain, statusManager);

import { Execution } from '@lifi/types';
import { ExecuteCrossParams } from '../../types';
export declare class BridgeExecutionManager {
shouldContinue: boolean;
setShouldContinue: (val: boolean) => void;
allowUserInteraction: boolean;
allowInteraction: (value: boolean) => void;
execute: ({ signer, step, statusManager, settings, }: ExecuteCrossParams) => Promise<Execution>;
}

@@ -16,3 +16,2 @@ "use strict";

exports.BridgeExecutionManager = void 0;
const ethers_1 = require("ethers");
const ApiService_1 = __importDefault(require("../../services/ApiService"));

@@ -31,88 +30,99 @@ const ChainsService_1 = __importDefault(require("../../services/ChainsService"));

constructor() {
this.shouldContinue = true;
this.setShouldContinue = (val) => {
this.shouldContinue = val;
this.allowUserInteraction = true;
this.allowInteraction = (value) => {
this.allowUserInteraction = value;
};
this.execute = ({ signer, step, statusManager, settings, }) => __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c, _d;
const { action, estimate } = step;
step.execution = statusManager.initExecutionObject(step);
const chainsService = ChainsService_1.default.getInstance();
const fromChain = yield chainsService.getChainById(action.fromChainId);
const toChain = yield chainsService.getChainById(action.toChainId);
// STEP 1: Check Allowance ////////////////////////////////////////////////
// approval still needed?
const fromChain = yield chainsService.getChainById(step.action.fromChainId);
const toChain = yield chainsService.getChainById(step.action.toChainId);
// STEP 1: Check allowance
const oldCrossProcess = step.execution.process.find((p) => p.type === 'CROSS_CHAIN');
if (!(oldCrossProcess === null || oldCrossProcess === void 0 ? void 0 : oldCrossProcess.txHash)) {
if (action.fromToken.address !== ethers_1.constants.AddressZero) {
// Check Token Approval only if fromToken is not the native token => no approval needed in that case
yield (0, allowance_execute_1.checkAllowance)(signer, step, fromChain, action.fromToken, action.fromAmount, estimate.approvalAddress, statusManager, settings.infiniteApproval, this.shouldContinue);
}
// Check token approval only if fromToken is not the native token => no approval needed in that case
if (!(oldCrossProcess === null || oldCrossProcess === void 0 ? void 0 : oldCrossProcess.txHash) &&
!(0, utils_1.isZeroAddress)(step.action.fromToken.address)) {
yield (0, allowance_execute_1.checkAllowance)(signer, step, statusManager, settings, fromChain, this.allowUserInteraction);
}
// STEP 2: Get Transaction ////////////////////////////////////////////////
let crossChainProcess = statusManager.findOrCreateProcess('CROSS_CHAIN', step);
try {
let tx;
if (crossChainProcess.txHash) {
// load exiting transaction
tx = yield (0, getProvider_1.getProvider)(signer).getTransaction(crossChainProcess.txHash);
}
else {
// check balance
yield (0, balanceCheck_execute_1.balanceCheck)(signer, step);
if (!step.transactionRequest) {
const personalizedStep = yield (0, utils_1.personalizeStep)(signer, step);
const updatedStep = yield ApiService_1.default.getStepTransaction(personalizedStep);
step = Object.assign(Object.assign({}, (yield (0, stepComparison_1.stepComparison)(statusManager, personalizedStep, updatedStep, settings.acceptSlippageUpdateHook, this.shouldContinue))), { execution: step.execution });
// STEP 2: Get transaction
let crossChainProcess = statusManager.findOrCreateProcess(step, 'CROSS_CHAIN');
if (crossChainProcess.status !== 'DONE') {
try {
let transaction;
if (crossChainProcess.txHash) {
// Make sure that the chain is still correct
const updatedSigner = yield (0, switchChain_1.switchChain)(signer, statusManager, step, settings.switchChainHook, this.allowUserInteraction);
if (!updatedSigner) {
// Chain switch was not successful, stop execution here
return step.execution;
}
signer = updatedSigner;
// Load exiting transaction
transaction = yield (0, getProvider_1.getProvider)(signer).getTransaction(crossChainProcess.txHash);
}
const { transactionRequest } = step;
if (!transactionRequest) {
throw new errors_1.TransactionError(errors_1.LifiErrorCode.TransactionUnprepared, 'Unable to prepare transaction.');
else {
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'STARTED');
// Check balance
yield (0, balanceCheck_execute_1.balanceCheck)(signer, step);
// Create new transaction
if (!step.transactionRequest) {
const personalizedStep = yield (0, utils_1.personalizeStep)(signer, step);
const updatedStep = yield ApiService_1.default.getStepTransaction(personalizedStep);
step = Object.assign(Object.assign({}, (yield (0, stepComparison_1.stepComparison)(statusManager, personalizedStep, updatedStep, settings.acceptSlippageUpdateHook, this.allowUserInteraction))), { execution: step.execution });
}
const { transactionRequest } = step;
if (!transactionRequest) {
throw new errors_1.TransactionError(errors_1.LifiErrorCode.TransactionUnprepared, 'Unable to prepare transaction.');
}
// STEP 3: Send the transaction
// Make sure that the chain is still correct
const updatedSigner = yield (0, switchChain_1.switchChain)(signer, statusManager, step, settings.switchChainHook, this.allowUserInteraction);
if (!updatedSigner) {
// Chain switch was not successful, stop execution here
return step.execution;
}
signer = updatedSigner;
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'ACTION_REQUIRED');
if (!this.allowUserInteraction) {
return step.execution;
}
// Submit the transaction
transaction = yield signer.sendTransaction(transactionRequest);
// STEP 4: Wait for the transaction
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'PENDING', {
txHash: transaction.hash,
txLink: fromChain.metamask.blockExplorerUrls[0] +
'tx/' +
transaction.hash,
});
}
// STEP 3: Send Transaction ///////////////////////////////////////////////
// make sure that chain is still correct
const updatedSigner = yield (0, switchChain_1.switchChain)(signer, statusManager, step, settings.switchChainHook, this.shouldContinue);
if (!updatedSigner) {
// chain switch was not successful, stop execution here
return step.execution;
yield transaction.wait();
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'DONE');
}
catch (e) {
if (e.code === 'TRANSACTION_REPLACED' && e.replacement) {
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'DONE', {
txHash: e.replacement.hash,
txLink: fromChain.metamask.blockExplorerUrls[0] +
'tx/' +
e.replacement.hash,
});
}
signer = updatedSigner;
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'ACTION_REQUIRED');
if (!this.shouldContinue) {
return step.execution;
else {
const error = yield (0, parseError_1.parseError)(e, step, crossChainProcess);
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'FAILED', {
error: {
message: error.message,
htmlMessage: error.htmlMessage,
code: error.code,
},
});
statusManager.updateExecution(step, 'FAILED');
throw error;
}
tx = yield signer.sendTransaction(transactionRequest);
// STEP 4: Wait for Transaction ///////////////////////////////////////////
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'PENDING', {
txHash: tx.hash,
txLink: fromChain.metamask.blockExplorerUrls[0] + 'tx/' + tx.hash,
});
}
yield tx.wait();
}
catch (e) {
if (e.code === 'TRANSACTION_REPLACED' && e.replacement) {
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'PENDING', {
txHash: e.replacement.hash,
txLink: fromChain.metamask.blockExplorerUrls[0] +
'tx/' +
e.replacement.hash,
});
}
else {
const error = yield (0, parseError_1.parseError)(e, step, crossChainProcess);
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'FAILED', {
error: {
message: error.message,
htmlMessage: error.htmlMessage,
code: error.code,
},
});
statusManager.updateExecution(step, 'FAILED');
throw error;
}
}
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'DONE');
// STEP 5: Wait for Receiver //////////////////////////////////////
let receivingChainProcess = statusManager.findOrCreateProcess('RECEIVING_CHAIN', step, 'PENDING');
// STEP 5: Wait for the receiving chain
let receivingChainProcess = statusManager.findOrCreateProcess(step, 'RECEIVING_CHAIN', 'PENDING');
let statusResponse;

@@ -124,2 +134,18 @@ try {

statusResponse = yield (0, utils_2.waitForReceivingTransaction)(crossChainProcess.txHash, statusManager, receivingChainProcess.type, step);
receivingChainProcess = statusManager.updateProcess(step, receivingChainProcess.type, 'DONE', {
substatus: statusResponse.substatus,
substatusMessage: statusResponse.substatusMessage ||
(0, utils_2.getSubstatusMessage)(statusResponse.status, statusResponse.substatus),
txHash: (_a = statusResponse.receiving) === null || _a === void 0 ? void 0 : _a.txHash,
txLink: toChain.metamask.blockExplorerUrls[0] +
'tx/' +
((_b = statusResponse.receiving) === null || _b === void 0 ? void 0 : _b.txHash),
});
statusManager.updateExecution(step, 'DONE', {
fromAmount: statusResponse.sending.amount,
toAmount: (_c = statusResponse.receiving) === null || _c === void 0 ? void 0 : _c.amount,
toToken: (_d = statusResponse.receiving) === null || _d === void 0 ? void 0 : _d.token,
gasUsed: statusResponse.sending.gasUsed,
gasPrice: statusResponse.sending.gasPrice,
});
}

@@ -135,20 +161,5 @@ catch (e) {

statusManager.updateExecution(step, 'FAILED');
console.warn(e);
throw e;
}
receivingChainProcess = statusManager.updateProcess(step, receivingChainProcess.type, 'DONE', {
substatus: statusResponse.substatus,
substatusMessage: statusResponse.substatusMessage ||
(0, utils_2.getSubstatusMessage)(statusResponse.status, statusResponse.substatus),
txHash: (_a = statusResponse.receiving) === null || _a === void 0 ? void 0 : _a.txHash,
txLink: toChain.metamask.blockExplorerUrls[0] +
'tx/' +
((_b = statusResponse.receiving) === null || _b === void 0 ? void 0 : _b.txHash),
});
statusManager.updateExecution(step, 'DONE', {
fromAmount: statusResponse.sending.amount,
toAmount: (_c = statusResponse.receiving) === null || _c === void 0 ? void 0 : _c.amount,
toToken: (_d = statusResponse.receiving) === null || _d === void 0 ? void 0 : _d.token,
gasUsed: statusResponse.sending.gasUsed,
gasPrice: statusResponse.sending.gasPrice,
});
// DONE

@@ -155,0 +166,0 @@ return step.execution;

import { Execution } from '@lifi/types';
import { ExecuteSwapParams } from '../../types';
export declare class SwapExecutionManager {
shouldContinue: boolean;
setShouldContinue: (val: boolean) => void;
allowUserInteraction: boolean;
allowInteraction: (value: boolean) => void;
execute: ({ signer, step, statusManager, settings, }: ExecuteSwapParams) => Promise<Execution>;
}

@@ -16,3 +16,2 @@ "use strict";

exports.SwapExecutionManager = void 0;
const ethers_1 = require("ethers");
const ApiService_1 = __importDefault(require("../../services/ApiService"));

@@ -31,35 +30,39 @@ const ChainsService_1 = __importDefault(require("../../services/ChainsService"));

constructor() {
this.shouldContinue = true;
this.setShouldContinue = (val) => {
this.shouldContinue = val;
this.allowUserInteraction = true;
this.allowInteraction = (value) => {
this.allowUserInteraction = value;
};
this.execute = ({ signer, step, statusManager, settings, }) => __awaiter(this, void 0, void 0, function* () {
// setup
var _a, _b, _c, _d;
const { action, estimate } = step;
step.execution = statusManager.initExecutionObject(step);
const chainsService = ChainsService_1.default.getInstance();
const fromChain = yield chainsService.getChainById(action.fromChainId);
// Approval
if (action.fromToken.address !== ethers_1.constants.AddressZero) {
yield (0, allowance_execute_1.checkAllowance)(signer, step, fromChain, action.fromToken, action.fromAmount, estimate.approvalAddress, statusManager, settings.infiniteApproval, this.shouldContinue);
const fromChain = yield chainsService.getChainById(step.action.fromChainId);
// STEP 1: Check allowance
if (!(0, utils_1.isZeroAddress)(step.action.fromToken.address)) {
yield (0, allowance_execute_1.checkAllowance)(signer, step, statusManager, settings, fromChain, this.allowUserInteraction);
}
// Start Swap
// -> set step.execution
let swapProcess = statusManager.findOrCreateProcess('SWAP', step);
// -> swapping
let tx;
// STEP 2: Get transaction
let swapProcess = statusManager.findOrCreateProcess(step, 'SWAP');
let transaction;
try {
if (swapProcess.txHash) {
// -> restore existing tx
tx = yield (0, getProvider_1.getProvider)(signer).getTransaction(swapProcess.txHash);
// Make sure that the chain is still correct
const updatedSigner = yield (0, switchChain_1.switchChain)(signer, statusManager, step, settings.switchChainHook, this.allowUserInteraction);
if (!updatedSigner) {
// Chain switch was not successful, stop execution here
return step.execution;
}
signer = updatedSigner;
// Load exiting transaction
transaction = yield (0, getProvider_1.getProvider)(signer).getTransaction(swapProcess.txHash);
}
else {
// -> check balance
swapProcess = statusManager.updateProcess(step, swapProcess.type, 'STARTED');
// Check balance
yield (0, balanceCheck_execute_1.balanceCheck)(signer, step);
// -> get tx from backend
// Create new transaction
if (!step.transactionRequest) {
const personalizedStep = yield (0, utils_1.personalizeStep)(signer, step);
const updatedStep = yield ApiService_1.default.getStepTransaction(personalizedStep);
step = Object.assign(Object.assign({}, (yield (0, stepComparison_1.stepComparison)(statusManager, personalizedStep, updatedStep, settings.acceptSlippageUpdateHook, this.shouldContinue))), { execution: step.execution });
step = Object.assign(Object.assign({}, (yield (0, stepComparison_1.stepComparison)(statusManager, personalizedStep, updatedStep, settings.acceptSlippageUpdateHook, this.allowUserInteraction))), { execution: step.execution });
}

@@ -70,44 +73,26 @@ const { transactionRequest } = step;

}
// make sure that chain is still correct
const updatedSigner = yield (0, switchChain_1.switchChain)(signer, statusManager, step, settings.switchChainHook, this.shouldContinue);
// STEP 3: Send the transaction
// Make sure that the chain is still correct
const updatedSigner = yield (0, switchChain_1.switchChain)(signer, statusManager, step, settings.switchChainHook, this.allowUserInteraction);
if (!updatedSigner) {
// chain switch was not successful, stop execution here
// Chain switch was not successful, stop execution here
return step.execution;
}
signer = updatedSigner;
// -> set step.execution
swapProcess = swapProcess = statusManager.updateProcess(step, swapProcess.type, 'ACTION_REQUIRED');
if (!this.shouldContinue) {
return step.execution; // stop before user interaction is needed
swapProcess = statusManager.updateProcess(step, swapProcess.type, 'ACTION_REQUIRED');
if (!this.allowUserInteraction) {
return step.execution;
}
// -> submit tx
tx = yield signer.sendTransaction(transactionRequest);
// Submit the transaction
transaction = yield signer.sendTransaction(transactionRequest);
}
}
catch (e) {
const error = yield (0, parseError_1.parseError)(e, step, swapProcess);
swapProcess = statusManager.updateProcess(step, swapProcess.type, 'FAILED', {
error: {
message: error.message,
htmlMessage: error.htmlMessage,
code: error.code,
},
// STEP 4: Wait for the transaction
swapProcess = statusManager.updateProcess(step, swapProcess.type, 'PENDING', {
txLink: fromChain.metamask.blockExplorerUrls[0] + 'tx/' + transaction.hash,
txHash: transaction.hash,
});
statusManager.updateExecution(step, 'FAILED');
throw error;
yield transaction.wait();
}
// Wait for Transaction
swapProcess = statusManager.updateProcess(step, swapProcess.type, 'PENDING', {
txLink: fromChain.metamask.blockExplorerUrls[0] + 'tx/' + tx.hash,
txHash: tx.hash,
});
// -> waiting
let receipt;
try {
receipt = yield tx.wait();
}
catch (e) {
// -> set status
if (e.code === 'TRANSACTION_REPLACED' && e.replacement) {
receipt = e.replacement;
swapProcess = statusManager.updateProcess(step, swapProcess.type, 'PENDING', {

@@ -133,2 +118,3 @@ txHash: e.replacement.hash,

}
// STEP 5: Wait for the receiving chain
let statusResponse;

@@ -135,0 +121,0 @@ try {

@@ -45,3 +45,3 @@ import { Execution, InternalExecutionSettings, Process, ProcessType, Route, Status, Step, Token } from '../types';

*/
findOrCreateProcess: (type: ProcessType, step: Step, status?: Status) => Process;
findOrCreateProcess: (step: Step, type: ProcessType, status?: Status) => Process;
/**

@@ -64,4 +64,4 @@ * Update a process object.

updateStepInRoute: (step: Step) => Step;
setShouldUpdate(value: boolean): void;
allowUpdates(value: boolean): void;
}
export {};

@@ -43,4 +43,5 @@ "use strict";

*/
this.findOrCreateProcess = (type, step, status) => {
if (!step.execution || !step.execution.process) {
this.findOrCreateProcess = (step, type, status) => {
var _a;
if (!((_a = step.execution) === null || _a === void 0 ? void 0 : _a.process)) {
throw new Error("Execution hasn't been initialized.");

@@ -50,2 +51,6 @@ }

if (process) {
if (status && process.status !== status) {
process.status = status;
this.updateStepInRoute(step);
}
return process;

@@ -72,3 +77,3 @@ }

this.updateProcess = (step, type, status, params) => {
var _a;
var _a, _b, _c;
if (!step.execution) {

@@ -98,5 +103,2 @@ throw new Error("Can't update an empty step execution.");

break;
case 'CHAIN_SWITCH_REQUIRED':
step.execution.status = 'CHAIN_SWITCH_REQUIRED';
break;
default:

@@ -113,2 +115,7 @@ break;

}
// Sort processes, the ones with DONE status go first
step.execution.process = [
...(_b = step === null || step === void 0 ? void 0 : step.execution) === null || _b === void 0 ? void 0 : _b.process.filter((process) => process.status === 'DONE'),
...(_c = step === null || step === void 0 ? void 0 : step.execution) === null || _c === void 0 ? void 0 : _c.process.filter((process) => process.status !== 'DONE'),
];
this.updateStepInRoute(step); // updates the step in the route

@@ -168,3 +175,3 @@ return currentProcess;

}
setShouldUpdate(value) {
allowUpdates(value) {
this.shouldUpdate = value;

@@ -171,0 +178,0 @@ }

import { Signer } from 'ethers';
import { HaltingSettings, InternalExecutionSettings, Step } from '../types';
import { InteractionSettings, InternalExecutionSettings, Step } from '../types';
import { StatusManager } from './StatusManager';

@@ -9,5 +9,7 @@ export declare class StepExecutor {

private bridgeExecutionManager;
allowUserInteraction: boolean;
executionStopped: boolean;
constructor(statusManager: StatusManager, settings: InternalExecutionSettings);
stopStepExecution: (settings?: HaltingSettings) => void;
setInteraction: (settings?: InteractionSettings) => void;
checkChain: () => never;
executeStep: (signer: Signer, step: Step) => Promise<Step>;

@@ -14,0 +16,0 @@ private executeSwap;

@@ -16,4 +16,7 @@ "use strict";

const switchChain_1 = require("./switchChain");
const defaultExecutionHaltSettings = {
// Please be careful when changing the defaults as it may break the behavior (e.g., background execution)
const defaultInteractionSettings = {
allowInteraction: true,
allowUpdates: true,
stopExecution: false,
};

@@ -24,15 +27,23 @@ class StepExecutor {

this.bridgeExecutionManager = new bridge_execute_1.BridgeExecutionManager();
this.allowUserInteraction = true;
this.executionStopped = false;
this.stopStepExecution = (settings) => {
const haltingSettings = Object.assign(Object.assign({}, defaultExecutionHaltSettings), settings);
this.swapExecutionManager.setShouldContinue(false);
this.bridgeExecutionManager.setShouldContinue(false);
this.statusManager.setShouldUpdate(haltingSettings.allowUpdates);
this.executionStopped = true;
this.setInteraction = (settings) => {
const interactionSettings = Object.assign(Object.assign({}, defaultInteractionSettings), settings);
this.allowUserInteraction = interactionSettings.allowInteraction;
this.swapExecutionManager.allowInteraction(interactionSettings.allowInteraction);
this.bridgeExecutionManager.allowInteraction(interactionSettings.allowInteraction);
this.statusManager.allowUpdates(interactionSettings.allowUpdates);
this.executionStopped = interactionSettings.stopExecution;
};
// TODO: add checkChain method and update signer inside executors
// This can come in handy when we execute multiple routes simultaneously and
// should be sure that we are on the right chain when waiting for transactions.
this.checkChain = () => {
throw new Error('checkChain is not implemented.');
};
this.executeStep = (signer, step) => __awaiter(this, void 0, void 0, function* () {
// check if signer is for correct chain
const updatedSigner = yield (0, switchChain_1.switchChain)(signer, this.statusManager, step, this.settings.switchChainHook, !this.executionStopped);
// Make sure that the chain is still correct
const updatedSigner = yield (0, switchChain_1.switchChain)(signer, this.statusManager, step, this.settings.switchChainHook, this.allowUserInteraction);
if (!updatedSigner) {
// chain switch was not successful, stop execution here
// Chain switch was not successful, stop execution here
return step;

@@ -54,3 +65,3 @@ }

});
this.executeSwap = (signer, step) => __awaiter(this, void 0, void 0, function* () {
this.executeSwap = (signer, step) => {
const swapParams = {

@@ -62,5 +73,5 @@ signer,

};
return yield this.swapExecutionManager.execute(swapParams);
});
this.executeCross = (signer, step) => __awaiter(this, void 0, void 0, function* () {
return this.swapExecutionManager.execute(swapParams);
};
this.executeCross = (signer, step) => {
const crossParams = {

@@ -72,4 +83,4 @@ signer,

};
return yield this.bridgeExecutionManager.execute(crossParams);
});
return this.bridgeExecutionManager.execute(crossParams);
};
this.statusManager = statusManager;

@@ -76,0 +87,0 @@ this.settings = settings;

@@ -32,4 +32,4 @@ "use strict";

step.execution = statusManager.initExecutionObject(step);
statusManager.updateExecution(step, 'CHAIN_SWITCH_REQUIRED');
let switchProcess = statusManager.findOrCreateProcess('SWITCH_CHAIN', step, 'PENDING');
statusManager.updateExecution(step, 'ACTION_REQUIRED');
let switchProcess = statusManager.findOrCreateProcess(step, 'SWITCH_CHAIN', 'ACTION_REQUIRED');
if (!allowUserInteraction) {

@@ -52,3 +52,3 @@ return;

message: error.message,
code: error.code,
code: errors_1.LifiErrorCode.ChainSwitchError,
},

@@ -55,0 +55,0 @@ });

@@ -16,3 +16,3 @@ "use strict";

// If ethereum.request() exists, the provider is probably EIP-1193 compliant.
if (!ethereum || !ethereum.request) {
if (!(ethereum === null || ethereum === void 0 ? void 0 : ethereum.request)) {
throw new Error('Provider not available.');

@@ -19,0 +19,0 @@ }

@@ -107,5 +107,12 @@ import { FallbackProvider } from '@ethersproject/providers';

* @param {Route} route - A route that is currently in execution.
* @deprecated use updateRouteExecution instead.
*/
moveExecutionToBackground: (route: Route) => void;
/**
* Updates route execution to background or foreground state.
* @param {Route} route - A route that is currently in execution.
* @param {boolean} settings - An object with execution settings.
*/
updateRouteExecution: (route: Route, settings: Pick<ExecutionSettings, 'executeInBackground'>) => void;
/**
* Execute a route.

@@ -112,0 +119,0 @@ * @param {Signer} signer - The signer required to send the transactions.

@@ -157,3 +157,7 @@ "use strict";

for (const executor of this.activeRouteDictionary[route.id].executors) {
executor.stopStepExecution({ allowUpdates: false });
executor.setInteraction({
allowInteraction: false,
allowUpdates: false,
stopExecution: true,
});
}

@@ -166,12 +170,34 @@ delete this.activeRouteDictionary[route.id];

* @param {Route} route - A route that is currently in execution.
* @deprecated use updateRouteExecution instead.
*/
this.moveExecutionToBackground = (route) => {
if (!this.activeRouteDictionary[route.id]) {
const activeRoute = this.activeRouteDictionary[route.id];
if (!activeRoute) {
return;
}
for (const executor of this.activeRouteDictionary[route.id].executors) {
executor.stopStepExecution({ allowUpdates: true });
for (const executor of activeRoute.executors) {
executor.setInteraction({ allowInteraction: false, allowUpdates: true });
}
activeRoute.settings = Object.assign(Object.assign({}, activeRoute.settings), { executeInBackground: true });
};
/**
* Updates route execution to background or foreground state.
* @param {Route} route - A route that is currently in execution.
* @param {boolean} settings - An object with execution settings.
*/
this.updateRouteExecution = (route, settings) => {
const activeRoute = this.activeRouteDictionary[route.id];
if (!activeRoute) {
return;
}
for (const executor of activeRoute.executors) {
executor.setInteraction({
allowInteraction: !settings.executeInBackground,
allowUpdates: true,
});
}
// Update active route settings so we know what the current state of execution is
activeRoute.settings = Object.assign(Object.assign({}, activeRoute.settings), settings);
};
/**
* Execute a route.

@@ -185,4 +211,5 @@ * @param {Signer} signer - The signer required to send the transactions.

this.executeRoute = (signer, route, settings) => __awaiter(this, void 0, void 0, function* () {
const clonedRoute = (0, utils_1.deepClone)(route); // deep clone to prevent side effects
// check if route is already running
// Deep clone to prevent side effects
const clonedRoute = (0, utils_1.deepClone)(route);
// Check if route is already running
if (this.activeRouteDictionary[clonedRoute.id]) {

@@ -203,3 +230,4 @@ // TODO: maybe inform user why nothing happens?

this.resumeRoute = (signer, route, settings) => __awaiter(this, void 0, void 0, function* () {
const clonedRoute = (0, utils_1.deepClone)(route); // deep clone to prevent side effects
// Deep clone to prevent side effects
const clonedRoute = (0, utils_1.deepClone)(route);
const activeRoute = this.activeRouteDictionary[clonedRoute.id];

@@ -209,2 +237,6 @@ if (activeRoute) {

if (!executionHalted) {
// Check if we want to resume route execution in the background
this.updateRouteExecution(route, {
executeInBackground: settings === null || settings === void 0 ? void 0 : settings.executeInBackground,
});
return clonedRoute;

@@ -217,4 +249,5 @@ }

this.executeSteps = (signer, route, settings) => __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c;
const config = this.configService.getConfig();
const execData = {
const executionData = {
route,

@@ -224,27 +257,39 @@ executors: [],

};
this.activeRouteDictionary[route.id] = execData;
const statusManager = new StatusManager_1.StatusManager(route, this.activeRouteDictionary[route.id].settings, (route) => (this.activeRouteDictionary[route.id].route = route));
// loop over steps and execute them
this.activeRouteDictionary[route.id] = executionData;
const statusManager = new StatusManager_1.StatusManager(route, this.activeRouteDictionary[route.id].settings, (route) => {
if (this.activeRouteDictionary[route.id]) {
this.activeRouteDictionary[route.id].route = route;
}
});
// Loop over steps and execute them
for (let index = 0; index < route.steps.length; index++) {
//check if execution has stopped in meantime
if (!this.activeRouteDictionary[route.id]) {
const activeRoute = this.activeRouteDictionary[route.id];
// Check if execution has stopped in the meantime
if (!activeRoute) {
break;
}
const step = route.steps[index];
const previousStep = index !== 0 ? route.steps[index - 1] : undefined;
// check if step already done
if (step.execution && step.execution.status === 'DONE') {
const previousStep = route.steps[index - 1];
// Check if the step is already done
if (((_a = step.execution) === null || _a === void 0 ? void 0 : _a.status) === 'DONE') {
continue;
}
// update amount using output of previous execution. In the future this should be handled by calling `updateRoute`
if (previousStep &&
previousStep.execution &&
previousStep.execution.toAmount) {
// Update amount using output of previous execution. In the future this should be handled by calling `updateRoute`
if ((_b = previousStep === null || previousStep === void 0 ? void 0 : previousStep.execution) === null || _b === void 0 ? void 0 : _b.toAmount) {
step.action.fromAmount = previousStep.execution.toAmount;
}
let stepExecutor;
try {
stepExecutor = new StepExecutor_1.StepExecutor(statusManager, this.activeRouteDictionary[route.id].settings);
this.activeRouteDictionary[route.id].executors.push(stepExecutor);
yield stepExecutor.executeStep(signer, step);
const stepExecutor = new StepExecutor_1.StepExecutor(statusManager, activeRoute.settings);
activeRoute.executors.push(stepExecutor);
// Check if we want to execute this step in the background
this.updateRouteExecution(route, activeRoute.settings);
const executedStep = yield stepExecutor.executeStep(signer, step);
// We may reach this point if user interaction isn't allowed. We want to stop execution until we resume it
if (((_c = executedStep.execution) === null || _c === void 0 ? void 0 : _c.status) !== 'DONE') {
this.stopExecution(route);
}
// Execution stopped during the current step, we don't want to continue to the next step so we return already
if (stepExecutor.executionStopped) {
return route;
}
}

@@ -255,8 +300,4 @@ catch (e) {

}
// execution stopped during the current step, we don't want to continue to the next step so we return already
if (stepExecutor.executionStopped) {
return route;
}
}
//clean up after execution
// Clean up after the execution
delete this.activeRouteDictionary[route.id];

@@ -378,3 +419,4 @@ return route;

if (configUpdate) {
this.configService.updateConfig(configUpdate); // update API urls before we request chains
// Update API urls before we request chains
this.configService.updateConfig(configUpdate);
}

@@ -381,0 +423,0 @@ this.chainsService = ChainsService_1.default.getInstance();

@@ -19,2 +19,3 @@ "use strict";

infiniteApproval: false,
executeInBackground: false,
};

@@ -21,0 +22,0 @@ class ConfigService {

@@ -67,2 +67,3 @@ import { Route, RouteOptions, Step, Token } from '@lifi/types';

infiniteApproval?: boolean;
executeInBackground?: boolean;
}

@@ -74,2 +75,3 @@ export interface InternalExecutionSettings extends ExecutionSettings {

infiniteApproval: boolean;
executeInBackground: boolean;
}

@@ -86,5 +88,7 @@ export declare type EnforcedObjectProperties<T> = T & {

};
export interface HaltingSettings {
export interface InteractionSettings {
allowInteraction?: boolean;
allowUpdates?: boolean;
stopExecution?: boolean;
}
export {};

@@ -80,3 +80,3 @@ "use strict";

const parseError = (e, step, process) => __awaiter(void 0, void 0, void 0, function* () {
var _a, _b;
var _a, _b, _c;
if (e instanceof errors_1.LifiError) {

@@ -92,8 +92,7 @@ return e;

if (e.code === eth_rpc_errors_1.errorCodes.rpc.internal &&
e.message &&
e.message.includes('underpriced')) {
((_a = e.message) === null || _a === void 0 ? void 0 : _a.includes('underpriced'))) {
return new errors_1.RPCError(errors_1.LifiErrorCode.TransactionUnderpriced, 'Transaction is underpriced.', yield (0, exports.getTransactionNotSentMessage)(step, process), e.stack);
}
if (((_a = e.message) === null || _a === void 0 ? void 0 : _a.includes('intrinsic gas too low')) ||
((_b = e.message) === null || _b === void 0 ? void 0 : _b.includes('out of gas'))) {
if (((_b = e.message) === null || _b === void 0 ? void 0 : _b.includes('intrinsic gas too low')) ||
((_c = e.message) === null || _c === void 0 ? void 0 : _c.includes('out of gas'))) {
return new errors_1.TransactionError(errors_1.LifiErrorCode.GasLimitError, 'Gas limit is too low.', yield (0, exports.getTransactionNotSentMessage)(step, process), e.stack);

@@ -100,0 +99,0 @@ }

@@ -30,3 +30,3 @@ "use strict";

if (route.steps[index].execution) {
route.steps[index].execution.process = route.steps[index].execution.process.filter((process) => process.status !== 'FAILED');
route.steps[index].execution.process = route.steps[index].execution.process.filter((process) => process.status === 'DONE');
}

@@ -33,0 +33,0 @@ };

export declare const name = "@lifi/sdk";
export declare const version = "1.4.1";
export declare const version = "1.5.0";

@@ -5,2 +5,2 @@ "use strict";

exports.name = '@lifi/sdk';
exports.version = '1.4.1';
exports.version = '1.5.0';
import { Signer } from 'ethers';
import { Chain, Step, Token } from '../types';
import { Chain, InternalExecutionSettings, Step } from '../types';
import { StatusManager } from './StatusManager';
export declare const checkAllowance: (signer: Signer, step: Step, chain: Chain, token: Token, amount: string, spenderAddress: string, statusManager: StatusManager, infiniteApproval?: boolean, allowUserInteraction?: boolean) => Promise<void>;
export declare const checkAllowance: (signer: Signer, step: Step, statusManager: StatusManager, settings: InternalExecutionSettings, chain: Chain, allowUserInteraction?: boolean) => Promise<void>;

@@ -15,30 +15,24 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

import { parseError } from '../utils/parseError';
export const checkAllowance = (signer, step, chain, token, amount, spenderAddress, statusManager, infiniteApproval = false, allowUserInteraction = false
// eslint-disable-next-line max-params
) => __awaiter(void 0, void 0, void 0, function* () {
// Ask user to set allowance
// -> set currentExecution
let allowanceProcess = statusManager.findOrCreateProcess('TOKEN_ALLOWANCE', step);
// -> check allowance
export const checkAllowance = (signer, step, statusManager, settings, chain, allowUserInteraction = false) => __awaiter(void 0, void 0, void 0, function* () {
// Ask the user to set an allowance
let allowanceProcess = statusManager.findOrCreateProcess(step, 'TOKEN_ALLOWANCE');
// Check allowance
try {
if (allowanceProcess.txHash) {
allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'PENDING');
if (allowanceProcess.txHash && allowanceProcess.status !== 'DONE') {
if (allowanceProcess.status !== 'PENDING') {
allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'PENDING');
}
yield getProvider(signer).waitForTransaction(allowanceProcess.txHash);
allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'DONE');
// TODO: Do we need this check?
}
else if (allowanceProcess.status === 'DONE') {
allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'DONE');
}
else {
const approved = yield getApproved(signer, token.address, spenderAddress);
if (new BigNumber(amount).gt(approved)) {
const approved = yield getApproved(signer, step.action.fromToken.address, step.estimate.approvalAddress);
if (new BigNumber(step.action.fromAmount).gt(approved)) {
if (!allowUserInteraction) {
return;
}
const approvalAmount = infiniteApproval
const approvalAmount = settings.infiniteApproval
? constants.MaxUint256.toString()
: amount;
const approveTx = yield setApproval(signer, token.address, spenderAddress, approvalAmount);
// update currentExecution
: step.action.fromAmount;
const approveTx = yield setApproval(signer, step.action.fromToken.address, step.estimate.approvalAddress, approvalAmount);
allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'PENDING', {

@@ -48,3 +42,3 @@ txHash: approveTx.hash,

});
// wait for transcation
// Wait for the transcation
yield approveTx.wait();

@@ -59,3 +53,2 @@ allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'DONE');

catch (e) {
// -> set status
if (e.code === 'TRANSACTION_REPLACED' && e.replacement) {

@@ -62,0 +55,0 @@ yield transactionReplaced(e.replacement, allowanceProcess, step, chain, statusManager);

import { Execution } from '@lifi/types';
import { ExecuteCrossParams } from '../../types';
export declare class BridgeExecutionManager {
shouldContinue: boolean;
setShouldContinue: (val: boolean) => void;
allowUserInteraction: boolean;
allowInteraction: (value: boolean) => void;
execute: ({ signer, step, statusManager, settings, }: ExecuteCrossParams) => Promise<Execution>;
}

@@ -10,3 +10,2 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

};
import { constants } from 'ethers';
import ApiService from '../../services/ApiService';

@@ -17,3 +16,3 @@ import ChainsService from '../../services/ChainsService';

import { getTransactionFailedMessage, parseError } from '../../utils/parseError';
import { personalizeStep } from '../../utils/utils';
import { isZeroAddress, personalizeStep } from '../../utils/utils';
import { checkAllowance } from '../allowance.execute';

@@ -26,88 +25,99 @@ import { balanceCheck } from '../balanceCheck.execute';

constructor() {
this.shouldContinue = true;
this.setShouldContinue = (val) => {
this.shouldContinue = val;
this.allowUserInteraction = true;
this.allowInteraction = (value) => {
this.allowUserInteraction = value;
};
this.execute = ({ signer, step, statusManager, settings, }) => __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c, _d;
const { action, estimate } = step;
step.execution = statusManager.initExecutionObject(step);
const chainsService = ChainsService.getInstance();
const fromChain = yield chainsService.getChainById(action.fromChainId);
const toChain = yield chainsService.getChainById(action.toChainId);
// STEP 1: Check Allowance ////////////////////////////////////////////////
// approval still needed?
const fromChain = yield chainsService.getChainById(step.action.fromChainId);
const toChain = yield chainsService.getChainById(step.action.toChainId);
// STEP 1: Check allowance
const oldCrossProcess = step.execution.process.find((p) => p.type === 'CROSS_CHAIN');
if (!(oldCrossProcess === null || oldCrossProcess === void 0 ? void 0 : oldCrossProcess.txHash)) {
if (action.fromToken.address !== constants.AddressZero) {
// Check Token Approval only if fromToken is not the native token => no approval needed in that case
yield checkAllowance(signer, step, fromChain, action.fromToken, action.fromAmount, estimate.approvalAddress, statusManager, settings.infiniteApproval, this.shouldContinue);
}
// Check token approval only if fromToken is not the native token => no approval needed in that case
if (!(oldCrossProcess === null || oldCrossProcess === void 0 ? void 0 : oldCrossProcess.txHash) &&
!isZeroAddress(step.action.fromToken.address)) {
yield checkAllowance(signer, step, statusManager, settings, fromChain, this.allowUserInteraction);
}
// STEP 2: Get Transaction ////////////////////////////////////////////////
let crossChainProcess = statusManager.findOrCreateProcess('CROSS_CHAIN', step);
try {
let tx;
if (crossChainProcess.txHash) {
// load exiting transaction
tx = yield getProvider(signer).getTransaction(crossChainProcess.txHash);
}
else {
// check balance
yield balanceCheck(signer, step);
if (!step.transactionRequest) {
const personalizedStep = yield personalizeStep(signer, step);
const updatedStep = yield ApiService.getStepTransaction(personalizedStep);
step = Object.assign(Object.assign({}, (yield stepComparison(statusManager, personalizedStep, updatedStep, settings.acceptSlippageUpdateHook, this.shouldContinue))), { execution: step.execution });
// STEP 2: Get transaction
let crossChainProcess = statusManager.findOrCreateProcess(step, 'CROSS_CHAIN');
if (crossChainProcess.status !== 'DONE') {
try {
let transaction;
if (crossChainProcess.txHash) {
// Make sure that the chain is still correct
const updatedSigner = yield switchChain(signer, statusManager, step, settings.switchChainHook, this.allowUserInteraction);
if (!updatedSigner) {
// Chain switch was not successful, stop execution here
return step.execution;
}
signer = updatedSigner;
// Load exiting transaction
transaction = yield getProvider(signer).getTransaction(crossChainProcess.txHash);
}
const { transactionRequest } = step;
if (!transactionRequest) {
throw new TransactionError(LifiErrorCode.TransactionUnprepared, 'Unable to prepare transaction.');
else {
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'STARTED');
// Check balance
yield balanceCheck(signer, step);
// Create new transaction
if (!step.transactionRequest) {
const personalizedStep = yield personalizeStep(signer, step);
const updatedStep = yield ApiService.getStepTransaction(personalizedStep);
step = Object.assign(Object.assign({}, (yield stepComparison(statusManager, personalizedStep, updatedStep, settings.acceptSlippageUpdateHook, this.allowUserInteraction))), { execution: step.execution });
}
const { transactionRequest } = step;
if (!transactionRequest) {
throw new TransactionError(LifiErrorCode.TransactionUnprepared, 'Unable to prepare transaction.');
}
// STEP 3: Send the transaction
// Make sure that the chain is still correct
const updatedSigner = yield switchChain(signer, statusManager, step, settings.switchChainHook, this.allowUserInteraction);
if (!updatedSigner) {
// Chain switch was not successful, stop execution here
return step.execution;
}
signer = updatedSigner;
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'ACTION_REQUIRED');
if (!this.allowUserInteraction) {
return step.execution;
}
// Submit the transaction
transaction = yield signer.sendTransaction(transactionRequest);
// STEP 4: Wait for the transaction
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'PENDING', {
txHash: transaction.hash,
txLink: fromChain.metamask.blockExplorerUrls[0] +
'tx/' +
transaction.hash,
});
}
// STEP 3: Send Transaction ///////////////////////////////////////////////
// make sure that chain is still correct
const updatedSigner = yield switchChain(signer, statusManager, step, settings.switchChainHook, this.shouldContinue);
if (!updatedSigner) {
// chain switch was not successful, stop execution here
return step.execution;
yield transaction.wait();
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'DONE');
}
catch (e) {
if (e.code === 'TRANSACTION_REPLACED' && e.replacement) {
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'DONE', {
txHash: e.replacement.hash,
txLink: fromChain.metamask.blockExplorerUrls[0] +
'tx/' +
e.replacement.hash,
});
}
signer = updatedSigner;
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'ACTION_REQUIRED');
if (!this.shouldContinue) {
return step.execution;
else {
const error = yield parseError(e, step, crossChainProcess);
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'FAILED', {
error: {
message: error.message,
htmlMessage: error.htmlMessage,
code: error.code,
},
});
statusManager.updateExecution(step, 'FAILED');
throw error;
}
tx = yield signer.sendTransaction(transactionRequest);
// STEP 4: Wait for Transaction ///////////////////////////////////////////
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'PENDING', {
txHash: tx.hash,
txLink: fromChain.metamask.blockExplorerUrls[0] + 'tx/' + tx.hash,
});
}
yield tx.wait();
}
catch (e) {
if (e.code === 'TRANSACTION_REPLACED' && e.replacement) {
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'PENDING', {
txHash: e.replacement.hash,
txLink: fromChain.metamask.blockExplorerUrls[0] +
'tx/' +
e.replacement.hash,
});
}
else {
const error = yield parseError(e, step, crossChainProcess);
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'FAILED', {
error: {
message: error.message,
htmlMessage: error.htmlMessage,
code: error.code,
},
});
statusManager.updateExecution(step, 'FAILED');
throw error;
}
}
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'DONE');
// STEP 5: Wait for Receiver //////////////////////////////////////
let receivingChainProcess = statusManager.findOrCreateProcess('RECEIVING_CHAIN', step, 'PENDING');
// STEP 5: Wait for the receiving chain
let receivingChainProcess = statusManager.findOrCreateProcess(step, 'RECEIVING_CHAIN', 'PENDING');
let statusResponse;

@@ -119,2 +129,18 @@ try {

statusResponse = yield waitForReceivingTransaction(crossChainProcess.txHash, statusManager, receivingChainProcess.type, step);
receivingChainProcess = statusManager.updateProcess(step, receivingChainProcess.type, 'DONE', {
substatus: statusResponse.substatus,
substatusMessage: statusResponse.substatusMessage ||
getSubstatusMessage(statusResponse.status, statusResponse.substatus),
txHash: (_a = statusResponse.receiving) === null || _a === void 0 ? void 0 : _a.txHash,
txLink: toChain.metamask.blockExplorerUrls[0] +
'tx/' +
((_b = statusResponse.receiving) === null || _b === void 0 ? void 0 : _b.txHash),
});
statusManager.updateExecution(step, 'DONE', {
fromAmount: statusResponse.sending.amount,
toAmount: (_c = statusResponse.receiving) === null || _c === void 0 ? void 0 : _c.amount,
toToken: (_d = statusResponse.receiving) === null || _d === void 0 ? void 0 : _d.token,
gasUsed: statusResponse.sending.gasUsed,
gasPrice: statusResponse.sending.gasPrice,
});
}

@@ -130,20 +156,5 @@ catch (e) {

statusManager.updateExecution(step, 'FAILED');
console.warn(e);
throw e;
}
receivingChainProcess = statusManager.updateProcess(step, receivingChainProcess.type, 'DONE', {
substatus: statusResponse.substatus,
substatusMessage: statusResponse.substatusMessage ||
getSubstatusMessage(statusResponse.status, statusResponse.substatus),
txHash: (_a = statusResponse.receiving) === null || _a === void 0 ? void 0 : _a.txHash,
txLink: toChain.metamask.blockExplorerUrls[0] +
'tx/' +
((_b = statusResponse.receiving) === null || _b === void 0 ? void 0 : _b.txHash),
});
statusManager.updateExecution(step, 'DONE', {
fromAmount: statusResponse.sending.amount,
toAmount: (_c = statusResponse.receiving) === null || _c === void 0 ? void 0 : _c.amount,
toToken: (_d = statusResponse.receiving) === null || _d === void 0 ? void 0 : _d.token,
gasUsed: statusResponse.sending.gasUsed,
gasPrice: statusResponse.sending.gasPrice,
});
// DONE

@@ -150,0 +161,0 @@ return step.execution;

import { Execution } from '@lifi/types';
import { ExecuteSwapParams } from '../../types';
export declare class SwapExecutionManager {
shouldContinue: boolean;
setShouldContinue: (val: boolean) => void;
allowUserInteraction: boolean;
allowInteraction: (value: boolean) => void;
execute: ({ signer, step, statusManager, settings, }: ExecuteSwapParams) => Promise<Execution>;
}

@@ -10,3 +10,2 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

};
import { constants } from 'ethers';
import ApiService from '../../services/ApiService';

@@ -17,3 +16,3 @@ import ChainsService from '../../services/ChainsService';

import { getTransactionFailedMessage, parseError } from '../../utils/parseError';
import { personalizeStep } from '../../utils/utils';
import { isZeroAddress, personalizeStep } from '../../utils/utils';
import { checkAllowance } from '../allowance.execute';

@@ -26,35 +25,39 @@ import { balanceCheck } from '../balanceCheck.execute';

constructor() {
this.shouldContinue = true;
this.setShouldContinue = (val) => {
this.shouldContinue = val;
this.allowUserInteraction = true;
this.allowInteraction = (value) => {
this.allowUserInteraction = value;
};
this.execute = ({ signer, step, statusManager, settings, }) => __awaiter(this, void 0, void 0, function* () {
// setup
var _a, _b, _c, _d;
const { action, estimate } = step;
step.execution = statusManager.initExecutionObject(step);
const chainsService = ChainsService.getInstance();
const fromChain = yield chainsService.getChainById(action.fromChainId);
// Approval
if (action.fromToken.address !== constants.AddressZero) {
yield checkAllowance(signer, step, fromChain, action.fromToken, action.fromAmount, estimate.approvalAddress, statusManager, settings.infiniteApproval, this.shouldContinue);
const fromChain = yield chainsService.getChainById(step.action.fromChainId);
// STEP 1: Check allowance
if (!isZeroAddress(step.action.fromToken.address)) {
yield checkAllowance(signer, step, statusManager, settings, fromChain, this.allowUserInteraction);
}
// Start Swap
// -> set step.execution
let swapProcess = statusManager.findOrCreateProcess('SWAP', step);
// -> swapping
let tx;
// STEP 2: Get transaction
let swapProcess = statusManager.findOrCreateProcess(step, 'SWAP');
let transaction;
try {
if (swapProcess.txHash) {
// -> restore existing tx
tx = yield getProvider(signer).getTransaction(swapProcess.txHash);
// Make sure that the chain is still correct
const updatedSigner = yield switchChain(signer, statusManager, step, settings.switchChainHook, this.allowUserInteraction);
if (!updatedSigner) {
// Chain switch was not successful, stop execution here
return step.execution;
}
signer = updatedSigner;
// Load exiting transaction
transaction = yield getProvider(signer).getTransaction(swapProcess.txHash);
}
else {
// -> check balance
swapProcess = statusManager.updateProcess(step, swapProcess.type, 'STARTED');
// Check balance
yield balanceCheck(signer, step);
// -> get tx from backend
// Create new transaction
if (!step.transactionRequest) {
const personalizedStep = yield personalizeStep(signer, step);
const updatedStep = yield ApiService.getStepTransaction(personalizedStep);
step = Object.assign(Object.assign({}, (yield stepComparison(statusManager, personalizedStep, updatedStep, settings.acceptSlippageUpdateHook, this.shouldContinue))), { execution: step.execution });
step = Object.assign(Object.assign({}, (yield stepComparison(statusManager, personalizedStep, updatedStep, settings.acceptSlippageUpdateHook, this.allowUserInteraction))), { execution: step.execution });
}

@@ -65,44 +68,26 @@ const { transactionRequest } = step;

}
// make sure that chain is still correct
const updatedSigner = yield switchChain(signer, statusManager, step, settings.switchChainHook, this.shouldContinue);
// STEP 3: Send the transaction
// Make sure that the chain is still correct
const updatedSigner = yield switchChain(signer, statusManager, step, settings.switchChainHook, this.allowUserInteraction);
if (!updatedSigner) {
// chain switch was not successful, stop execution here
// Chain switch was not successful, stop execution here
return step.execution;
}
signer = updatedSigner;
// -> set step.execution
swapProcess = swapProcess = statusManager.updateProcess(step, swapProcess.type, 'ACTION_REQUIRED');
if (!this.shouldContinue) {
return step.execution; // stop before user interaction is needed
swapProcess = statusManager.updateProcess(step, swapProcess.type, 'ACTION_REQUIRED');
if (!this.allowUserInteraction) {
return step.execution;
}
// -> submit tx
tx = yield signer.sendTransaction(transactionRequest);
// Submit the transaction
transaction = yield signer.sendTransaction(transactionRequest);
}
}
catch (e) {
const error = yield parseError(e, step, swapProcess);
swapProcess = statusManager.updateProcess(step, swapProcess.type, 'FAILED', {
error: {
message: error.message,
htmlMessage: error.htmlMessage,
code: error.code,
},
// STEP 4: Wait for the transaction
swapProcess = statusManager.updateProcess(step, swapProcess.type, 'PENDING', {
txLink: fromChain.metamask.blockExplorerUrls[0] + 'tx/' + transaction.hash,
txHash: transaction.hash,
});
statusManager.updateExecution(step, 'FAILED');
throw error;
yield transaction.wait();
}
// Wait for Transaction
swapProcess = statusManager.updateProcess(step, swapProcess.type, 'PENDING', {
txLink: fromChain.metamask.blockExplorerUrls[0] + 'tx/' + tx.hash,
txHash: tx.hash,
});
// -> waiting
let receipt;
try {
receipt = yield tx.wait();
}
catch (e) {
// -> set status
if (e.code === 'TRANSACTION_REPLACED' && e.replacement) {
receipt = e.replacement;
swapProcess = statusManager.updateProcess(step, swapProcess.type, 'PENDING', {

@@ -128,2 +113,3 @@ txHash: e.replacement.hash,

}
// STEP 5: Wait for the receiving chain
let statusResponse;

@@ -130,0 +116,0 @@ try {

@@ -45,3 +45,3 @@ import { Execution, InternalExecutionSettings, Process, ProcessType, Route, Status, Step, Token } from '../types';

*/
findOrCreateProcess: (type: ProcessType, step: Step, status?: Status) => Process;
findOrCreateProcess: (step: Step, type: ProcessType, status?: Status) => Process;
/**

@@ -64,4 +64,4 @@ * Update a process object.

updateStepInRoute: (step: Step) => Step;
setShouldUpdate(value: boolean): void;
allowUpdates(value: boolean): void;
}
export {};

@@ -40,4 +40,5 @@ import { emptyExecution, } from '../types';

*/
this.findOrCreateProcess = (type, step, status) => {
if (!step.execution || !step.execution.process) {
this.findOrCreateProcess = (step, type, status) => {
var _a;
if (!((_a = step.execution) === null || _a === void 0 ? void 0 : _a.process)) {
throw new Error("Execution hasn't been initialized.");

@@ -47,2 +48,6 @@ }

if (process) {
if (status && process.status !== status) {
process.status = status;
this.updateStepInRoute(step);
}
return process;

@@ -69,3 +74,3 @@ }

this.updateProcess = (step, type, status, params) => {
var _a;
var _a, _b, _c;
if (!step.execution) {

@@ -95,5 +100,2 @@ throw new Error("Can't update an empty step execution.");

break;
case 'CHAIN_SWITCH_REQUIRED':
step.execution.status = 'CHAIN_SWITCH_REQUIRED';
break;
default:

@@ -110,2 +112,7 @@ break;

}
// Sort processes, the ones with DONE status go first
step.execution.process = [
...(_b = step === null || step === void 0 ? void 0 : step.execution) === null || _b === void 0 ? void 0 : _b.process.filter((process) => process.status === 'DONE'),
...(_c = step === null || step === void 0 ? void 0 : step.execution) === null || _c === void 0 ? void 0 : _c.process.filter((process) => process.status !== 'DONE'),
];
this.updateStepInRoute(step); // updates the step in the route

@@ -165,5 +172,5 @@ return currentProcess;

}
setShouldUpdate(value) {
allowUpdates(value) {
this.shouldUpdate = value;
}
}
import { Signer } from 'ethers';
import { HaltingSettings, InternalExecutionSettings, Step } from '../types';
import { InteractionSettings, InternalExecutionSettings, Step } from '../types';
import { StatusManager } from './StatusManager';

@@ -9,5 +9,7 @@ export declare class StepExecutor {

private bridgeExecutionManager;
allowUserInteraction: boolean;
executionStopped: boolean;
constructor(statusManager: StatusManager, settings: InternalExecutionSettings);
stopStepExecution: (settings?: HaltingSettings) => void;
setInteraction: (settings?: InteractionSettings) => void;
checkChain: () => never;
executeStep: (signer: Signer, step: Step) => Promise<Step>;

@@ -14,0 +16,0 @@ private executeSwap;

@@ -13,4 +13,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

import { switchChain } from './switchChain';
const defaultExecutionHaltSettings = {
// Please be careful when changing the defaults as it may break the behavior (e.g., background execution)
const defaultInteractionSettings = {
allowInteraction: true,
allowUpdates: true,
stopExecution: false,
};

@@ -21,15 +24,23 @@ export class StepExecutor {

this.bridgeExecutionManager = new BridgeExecutionManager();
this.allowUserInteraction = true;
this.executionStopped = false;
this.stopStepExecution = (settings) => {
const haltingSettings = Object.assign(Object.assign({}, defaultExecutionHaltSettings), settings);
this.swapExecutionManager.setShouldContinue(false);
this.bridgeExecutionManager.setShouldContinue(false);
this.statusManager.setShouldUpdate(haltingSettings.allowUpdates);
this.executionStopped = true;
this.setInteraction = (settings) => {
const interactionSettings = Object.assign(Object.assign({}, defaultInteractionSettings), settings);
this.allowUserInteraction = interactionSettings.allowInteraction;
this.swapExecutionManager.allowInteraction(interactionSettings.allowInteraction);
this.bridgeExecutionManager.allowInteraction(interactionSettings.allowInteraction);
this.statusManager.allowUpdates(interactionSettings.allowUpdates);
this.executionStopped = interactionSettings.stopExecution;
};
// TODO: add checkChain method and update signer inside executors
// This can come in handy when we execute multiple routes simultaneously and
// should be sure that we are on the right chain when waiting for transactions.
this.checkChain = () => {
throw new Error('checkChain is not implemented.');
};
this.executeStep = (signer, step) => __awaiter(this, void 0, void 0, function* () {
// check if signer is for correct chain
const updatedSigner = yield switchChain(signer, this.statusManager, step, this.settings.switchChainHook, !this.executionStopped);
// Make sure that the chain is still correct
const updatedSigner = yield switchChain(signer, this.statusManager, step, this.settings.switchChainHook, this.allowUserInteraction);
if (!updatedSigner) {
// chain switch was not successful, stop execution here
// Chain switch was not successful, stop execution here
return step;

@@ -51,3 +62,3 @@ }

});
this.executeSwap = (signer, step) => __awaiter(this, void 0, void 0, function* () {
this.executeSwap = (signer, step) => {
const swapParams = {

@@ -59,5 +70,5 @@ signer,

};
return yield this.swapExecutionManager.execute(swapParams);
});
this.executeCross = (signer, step) => __awaiter(this, void 0, void 0, function* () {
return this.swapExecutionManager.execute(swapParams);
};
this.executeCross = (signer, step) => {
const crossParams = {

@@ -69,4 +80,4 @@ signer,

};
return yield this.bridgeExecutionManager.execute(crossParams);
});
return this.bridgeExecutionManager.execute(crossParams);
};
this.statusManager = statusManager;

@@ -73,0 +84,0 @@ this.settings = settings;

@@ -29,4 +29,4 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

step.execution = statusManager.initExecutionObject(step);
statusManager.updateExecution(step, 'CHAIN_SWITCH_REQUIRED');
let switchProcess = statusManager.findOrCreateProcess('SWITCH_CHAIN', step, 'PENDING');
statusManager.updateExecution(step, 'ACTION_REQUIRED');
let switchProcess = statusManager.findOrCreateProcess(step, 'SWITCH_CHAIN', 'ACTION_REQUIRED');
if (!allowUserInteraction) {

@@ -49,3 +49,3 @@ return;

message: error.message,
code: error.code,
code: LifiErrorCode.ChainSwitchError,
},

@@ -52,0 +52,0 @@ });

@@ -13,3 +13,3 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

// If ethereum.request() exists, the provider is probably EIP-1193 compliant.
if (!ethereum || !ethereum.request) {
if (!(ethereum === null || ethereum === void 0 ? void 0 : ethereum.request)) {
throw new Error('Provider not available.');

@@ -16,0 +16,0 @@ }

@@ -107,5 +107,12 @@ import { FallbackProvider } from '@ethersproject/providers';

* @param {Route} route - A route that is currently in execution.
* @deprecated use updateRouteExecution instead.
*/
moveExecutionToBackground: (route: Route) => void;
/**
* Updates route execution to background or foreground state.
* @param {Route} route - A route that is currently in execution.
* @param {boolean} settings - An object with execution settings.
*/
updateRouteExecution: (route: Route, settings: Pick<ExecutionSettings, 'executeInBackground'>) => void;
/**
* Execute a route.

@@ -112,0 +119,0 @@ * @param {Signer} signer - The signer required to send the transactions.

@@ -152,3 +152,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

for (const executor of this.activeRouteDictionary[route.id].executors) {
executor.stopStepExecution({ allowUpdates: false });
executor.setInteraction({
allowInteraction: false,
allowUpdates: false,
stopExecution: true,
});
}

@@ -161,12 +165,34 @@ delete this.activeRouteDictionary[route.id];

* @param {Route} route - A route that is currently in execution.
* @deprecated use updateRouteExecution instead.
*/
this.moveExecutionToBackground = (route) => {
if (!this.activeRouteDictionary[route.id]) {
const activeRoute = this.activeRouteDictionary[route.id];
if (!activeRoute) {
return;
}
for (const executor of this.activeRouteDictionary[route.id].executors) {
executor.stopStepExecution({ allowUpdates: true });
for (const executor of activeRoute.executors) {
executor.setInteraction({ allowInteraction: false, allowUpdates: true });
}
activeRoute.settings = Object.assign(Object.assign({}, activeRoute.settings), { executeInBackground: true });
};
/**
* Updates route execution to background or foreground state.
* @param {Route} route - A route that is currently in execution.
* @param {boolean} settings - An object with execution settings.
*/
this.updateRouteExecution = (route, settings) => {
const activeRoute = this.activeRouteDictionary[route.id];
if (!activeRoute) {
return;
}
for (const executor of activeRoute.executors) {
executor.setInteraction({
allowInteraction: !settings.executeInBackground,
allowUpdates: true,
});
}
// Update active route settings so we know what the current state of execution is
activeRoute.settings = Object.assign(Object.assign({}, activeRoute.settings), settings);
};
/**
* Execute a route.

@@ -180,4 +206,5 @@ * @param {Signer} signer - The signer required to send the transactions.

this.executeRoute = (signer, route, settings) => __awaiter(this, void 0, void 0, function* () {
const clonedRoute = deepClone(route); // deep clone to prevent side effects
// check if route is already running
// Deep clone to prevent side effects
const clonedRoute = deepClone(route);
// Check if route is already running
if (this.activeRouteDictionary[clonedRoute.id]) {

@@ -198,3 +225,4 @@ // TODO: maybe inform user why nothing happens?

this.resumeRoute = (signer, route, settings) => __awaiter(this, void 0, void 0, function* () {
const clonedRoute = deepClone(route); // deep clone to prevent side effects
// Deep clone to prevent side effects
const clonedRoute = deepClone(route);
const activeRoute = this.activeRouteDictionary[clonedRoute.id];

@@ -204,2 +232,6 @@ if (activeRoute) {

if (!executionHalted) {
// Check if we want to resume route execution in the background
this.updateRouteExecution(route, {
executeInBackground: settings === null || settings === void 0 ? void 0 : settings.executeInBackground,
});
return clonedRoute;

@@ -212,4 +244,5 @@ }

this.executeSteps = (signer, route, settings) => __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c;
const config = this.configService.getConfig();
const execData = {
const executionData = {
route,

@@ -219,27 +252,39 @@ executors: [],

};
this.activeRouteDictionary[route.id] = execData;
const statusManager = new StatusManager(route, this.activeRouteDictionary[route.id].settings, (route) => (this.activeRouteDictionary[route.id].route = route));
// loop over steps and execute them
this.activeRouteDictionary[route.id] = executionData;
const statusManager = new StatusManager(route, this.activeRouteDictionary[route.id].settings, (route) => {
if (this.activeRouteDictionary[route.id]) {
this.activeRouteDictionary[route.id].route = route;
}
});
// Loop over steps and execute them
for (let index = 0; index < route.steps.length; index++) {
//check if execution has stopped in meantime
if (!this.activeRouteDictionary[route.id]) {
const activeRoute = this.activeRouteDictionary[route.id];
// Check if execution has stopped in the meantime
if (!activeRoute) {
break;
}
const step = route.steps[index];
const previousStep = index !== 0 ? route.steps[index - 1] : undefined;
// check if step already done
if (step.execution && step.execution.status === 'DONE') {
const previousStep = route.steps[index - 1];
// Check if the step is already done
if (((_a = step.execution) === null || _a === void 0 ? void 0 : _a.status) === 'DONE') {
continue;
}
// update amount using output of previous execution. In the future this should be handled by calling `updateRoute`
if (previousStep &&
previousStep.execution &&
previousStep.execution.toAmount) {
// Update amount using output of previous execution. In the future this should be handled by calling `updateRoute`
if ((_b = previousStep === null || previousStep === void 0 ? void 0 : previousStep.execution) === null || _b === void 0 ? void 0 : _b.toAmount) {
step.action.fromAmount = previousStep.execution.toAmount;
}
let stepExecutor;
try {
stepExecutor = new StepExecutor(statusManager, this.activeRouteDictionary[route.id].settings);
this.activeRouteDictionary[route.id].executors.push(stepExecutor);
yield stepExecutor.executeStep(signer, step);
const stepExecutor = new StepExecutor(statusManager, activeRoute.settings);
activeRoute.executors.push(stepExecutor);
// Check if we want to execute this step in the background
this.updateRouteExecution(route, activeRoute.settings);
const executedStep = yield stepExecutor.executeStep(signer, step);
// We may reach this point if user interaction isn't allowed. We want to stop execution until we resume it
if (((_c = executedStep.execution) === null || _c === void 0 ? void 0 : _c.status) !== 'DONE') {
this.stopExecution(route);
}
// Execution stopped during the current step, we don't want to continue to the next step so we return already
if (stepExecutor.executionStopped) {
return route;
}
}

@@ -250,8 +295,4 @@ catch (e) {

}
// execution stopped during the current step, we don't want to continue to the next step so we return already
if (stepExecutor.executionStopped) {
return route;
}
}
//clean up after execution
// Clean up after the execution
delete this.activeRouteDictionary[route.id];

@@ -373,3 +414,4 @@ return route;

if (configUpdate) {
this.configService.updateConfig(configUpdate); // update API urls before we request chains
// Update API urls before we request chains
this.configService.updateConfig(configUpdate);
}

@@ -376,0 +418,0 @@ this.chainsService = ChainsService.getInstance();

@@ -17,2 +17,3 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

infiniteApproval: false,
executeInBackground: false,
};

@@ -19,0 +20,0 @@ export default class ConfigService {

@@ -67,2 +67,3 @@ import { Route, RouteOptions, Step, Token } from '@lifi/types';

infiniteApproval?: boolean;
executeInBackground?: boolean;
}

@@ -74,2 +75,3 @@ export interface InternalExecutionSettings extends ExecutionSettings {

infiniteApproval: boolean;
executeInBackground: boolean;
}

@@ -86,5 +88,7 @@ export declare type EnforcedObjectProperties<T> = T & {

};
export interface HaltingSettings {
export interface InteractionSettings {
allowInteraction?: boolean;
allowUpdates?: boolean;
stopExecution?: boolean;
}
export {};

@@ -72,3 +72,3 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

export const parseError = (e, step, process) => __awaiter(void 0, void 0, void 0, function* () {
var _a, _b;
var _a, _b, _c;
if (e instanceof LifiError) {

@@ -84,8 +84,7 @@ return e;

if (e.code === MetaMaskErrorCodes.rpc.internal &&
e.message &&
e.message.includes('underpriced')) {
((_a = e.message) === null || _a === void 0 ? void 0 : _a.includes('underpriced'))) {
return new RPCError(LifiErrorCode.TransactionUnderpriced, 'Transaction is underpriced.', yield getTransactionNotSentMessage(step, process), e.stack);
}
if (((_a = e.message) === null || _a === void 0 ? void 0 : _a.includes('intrinsic gas too low')) ||
((_b = e.message) === null || _b === void 0 ? void 0 : _b.includes('out of gas'))) {
if (((_b = e.message) === null || _b === void 0 ? void 0 : _b.includes('intrinsic gas too low')) ||
((_c = e.message) === null || _c === void 0 ? void 0 : _c.includes('out of gas'))) {
return new TransactionError(LifiErrorCode.GasLimitError, 'Gas limit is too low.', yield getTransactionNotSentMessage(step, process), e.stack);

@@ -92,0 +91,0 @@ }

@@ -26,3 +26,3 @@ import { LifiErrorCode } from './errors';

if (route.steps[index].execution) {
route.steps[index].execution.process = route.steps[index].execution.process.filter((process) => process.status !== 'FAILED');
route.steps[index].execution.process = route.steps[index].execution.process.filter((process) => process.status === 'DONE');
}

@@ -29,0 +29,0 @@ };

export declare const name = "@lifi/sdk";
export declare const version = "1.4.1";
export declare const version = "1.5.0";
export const name = '@lifi/sdk';
export const version = '1.4.1';
export const version = '1.5.0';
{
"name": "@lifi/sdk",
"version": "1.4.1",
"version": "1.5.0",
"description": "LI.FI Any-to-Any Cross-Chain-Swap SDK",

@@ -86,16 +86,16 @@ "main": "./dist/cjs/index.js",

"devDependencies": {
"@commitlint/cli": "^17.0.3",
"@commitlint/config-conventional": "^17.0.3",
"@commitlint/cli": "^17.1.2",
"@commitlint/config-conventional": "^17.1.0",
"@types/bip39": "^3.0.0",
"@types/chai": "^4.3.3",
"@types/hdkey": "^2.0.0",
"@types/jest": "^28.1.8",
"@types/jest": "^29.0.0",
"@types/websocket": "^1.0.4",
"@typescript-eslint/eslint-plugin": "^5.34.0",
"@typescript-eslint/parser": "^5.34.0",
"eslint": "^8.22.0",
"@typescript-eslint/eslint-plugin": "^5.36.1",
"@typescript-eslint/parser": "^5.36.1",
"eslint": "^8.23.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.2.1",
"husky": "^8.0.1",
"jest": "^28.1.2",
"jest": "^29.0.2",
"lint-staged": "^13.0.3",

@@ -108,3 +108,3 @@ "npm-run-all": "^4.1.5",

"ts-loader": "^9.3.1",
"typescript": "^4.7.4",
"typescript": "^4.8.2",
"webpack": "^5.73.0",

@@ -111,0 +111,0 @@ "webpack-cli": "^4.10.0"

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc