@depay/web3-payments-evm
Version:
JavaScript library to scan crypto wallets for liquefiable assets and perform cost-effective, auto-converted payments on-chain.
782 lines (660 loc) • 1.87 MB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@depay/web3-exchanges-evm'), require('@depay/web3-tokens-evm'), require('@depay/web3-blockchains'), require('ethers'), require('@depay/web3-client')) :
typeof define === 'function' && define.amd ? define(['exports', '@depay/web3-exchanges-evm', '@depay/web3-tokens-evm', '@depay/web3-blockchains', 'ethers', '@depay/web3-client'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Web3Payments = {}, global.Web3Exchanges, global.Web3Tokens, global.Web3Blockchains, global.ethers, global.Web3Client));
})(this, (function (exports, Exchanges, Token$1, Blockchains, ethers, web3Client) { 'use strict';
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var Exchanges__default = /*#__PURE__*/_interopDefaultLegacy(Exchanges);
var Token__default = /*#__PURE__*/_interopDefaultLegacy(Token$1);
var Blockchains__default = /*#__PURE__*/_interopDefaultLegacy(Blockchains);
const config = {
endpoints: {
routesBest: 'https://public.depay.com/routes/best'
}
};
const API = [{"inputs":[{"internalType":"address","name":"_PERMIT2","type":"address"},{"internalType":"address","name":"_FORWARDER","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ExchangeCallFailed","type":"error"},{"inputs":[],"name":"ExchangeCallMissing","type":"error"},{"inputs":[],"name":"ExchangeNotApproved","type":"error"},{"inputs":[],"name":"ForwardingPaymentFailed","type":"error"},{"inputs":[],"name":"InsufficientBalanceInAfterPayment","type":"error"},{"inputs":[],"name":"InsufficientBalanceOutAfterPayment","type":"error"},{"inputs":[],"name":"InsufficientProtocolAmount","type":"error"},{"inputs":[],"name":"NativeFeePaymentFailed","type":"error"},{"inputs":[],"name":"NativePaymentFailed","type":"error"},{"inputs":[],"name":"PaymentDeadlineReached","type":"error"},{"inputs":[],"name":"PaymentToZeroAddressNotAllowed","type":"error"},{"inputs":[],"name":"WrongAmountPaidIn","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"exchange","type":"address"}],"name":"Disabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"exchange","type":"address"}],"name":"Enabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"deadline","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"paymentAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feeAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feeAmount2","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"protocolAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"slippageInAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"slippageOutAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"tokenInAddress","type":"address"},{"indexed":false,"internalType":"address","name":"tokenOutAddress","type":"address"},{"indexed":false,"internalType":"address","name":"feeReceiverAddress","type":"address"},{"indexed":false,"internalType":"address","name":"feeReceiverAddress2","type":"address"}],"name":"Payment","type":"event"},{"inputs":[],"name":"FORWARDER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT2","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"exchange","type":"address"},{"internalType":"bool","name":"enabled","type":"bool"}],"name":"enable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"exchanges","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"paymentAmount","type":"uint256"},{"internalType":"uint256","name":"feeAmount","type":"uint256"},{"internalType":"uint256","name":"feeAmount2","type":"uint256"},{"internalType":"uint256","name":"protocolAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"address","name":"tokenInAddress","type":"address"},{"internalType":"address","name":"exchangeAddress","type":"address"},{"internalType":"address","name":"tokenOutAddress","type":"address"},{"internalType":"address","name":"paymentReceiverAddress","type":"address"},{"internalType":"address","name":"feeReceiverAddress","type":"address"},{"internalType":"address","name":"feeReceiverAddress2","type":"address"},{"internalType":"uint8","name":"exchangeType","type":"uint8"},{"internalType":"uint8","name":"receiverType","type":"uint8"},{"internalType":"bool","name":"permit2","type":"bool"},{"internalType":"bytes","name":"exchangeCallData","type":"bytes"},{"internalType":"bytes","name":"receiverCallData","type":"bytes"}],"internalType":"struct IDePayRouterV3.Payment","name":"payment","type":"tuple"},{"components":[{"components":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct IPermit2.TokenPermissions","name":"permitted","type":"tuple"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"internalType":"struct IPermit2.PermitTransferFrom","name":"permitTransferFrom","type":"tuple"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct IDePayRouterV3.PermitTransferFromAndSignature","name":"permitTransferFromAndSignature","type":"tuple"}],"name":"pay","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"paymentAmount","type":"uint256"},{"internalType":"uint256","name":"feeAmount","type":"uint256"},{"internalType":"uint256","name":"feeAmount2","type":"uint256"},{"internalType":"uint256","name":"protocolAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"address","name":"tokenInAddress","type":"address"},{"internalType":"address","name":"exchangeAddress","type":"address"},{"internalType":"address","name":"tokenOutAddress","type":"address"},{"internalType":"address","name":"paymentReceiverAddress","type":"address"},{"internalType":"address","name":"feeReceiverAddress","type":"address"},{"internalType":"address","name":"feeReceiverAddress2","type":"address"},{"internalType":"uint8","name":"exchangeType","type":"uint8"},{"internalType":"uint8","name":"receiverType","type":"uint8"},{"internalType":"bool","name":"permit2","type":"bool"},{"internalType":"bytes","name":"exchangeCallData","type":"bytes"},{"internalType":"bytes","name":"receiverCallData","type":"bytes"}],"internalType":"struct IDePayRouterV3.Payment","name":"payment","type":"tuple"}],"name":"pay","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"paymentAmount","type":"uint256"},{"internalType":"uint256","name":"feeAmount","type":"uint256"},{"internalType":"uint256","name":"feeAmount2","type":"uint256"},{"internalType":"uint256","name":"protocolAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"address","name":"tokenInAddress","type":"address"},{"internalType":"address","name":"exchangeAddress","type":"address"},{"internalType":"address","name":"tokenOutAddress","type":"address"},{"internalType":"address","name":"paymentReceiverAddress","type":"address"},{"internalType":"address","name":"feeReceiverAddress","type":"address"},{"internalType":"address","name":"feeReceiverAddress2","type":"address"},{"internalType":"uint8","name":"exchangeType","type":"uint8"},{"internalType":"uint8","name":"receiverType","type":"uint8"},{"internalType":"bool","name":"permit2","type":"bool"},{"internalType":"bytes","name":"exchangeCallData","type":"bytes"},{"internalType":"bytes","name":"receiverCallData","type":"bytes"}],"internalType":"struct IDePayRouterV3.Payment","name":"payment","type":"tuple"},{"components":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint160","name":"amount","type":"uint160"},{"internalType":"uint48","name":"expiration","type":"uint48"},{"internalType":"uint48","name":"nonce","type":"uint48"}],"internalType":"struct IPermit2.PermitDetails","name":"details","type":"tuple"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"sigDeadline","type":"uint256"}],"internalType":"struct IPermit2.PermitSingle","name":"permitSingle","type":"tuple"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"pay","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}];
var routers$2 = {
ethereum: {
address: '0x365f7B56D2fB16C8Af89D7d33b420E4e013461e8',
api: API
},
bsc: {
address: '0x5F565EDfB9C446976a9F9910631cfeDb6A87220c',
api: API
},
polygon: {
address: '0xe04b08Dfc6CaA0F4Ec523a3Ae283Ece7efE00019',
api: API
},
avalanche: {
address: '0x39E7C98BF4ac3E4C394dD600397f5f7Ee3779BE8',
api: API
},
gnosis: {
address: '0x328FE8bbd30487BB7b5A8eEb909f892E9E229271',
api: API
},
arbitrum: {
address: '0x328FE8bbd30487BB7b5A8eEb909f892E9E229271',
api: API
},
optimism: {
address: '0x558302715e3011Be6695605c11A65526D2ba2245',
api: API
},
base: {
address: '0x48825133EF08327535D0b24d73779E82BE6Ea4d9',
api: API
},
worldchain: {
address: '0x886eb82a7e5E7310F66A0E83748662A17E391eb0',
api: API
},
};
let svmRouters = {};
var routers$1 = {... routers$2, ...svmRouters};
let _window;
let getWindow = () => {
if(_window) { return _window }
if (typeof global == 'object') {
_window = global;
} else {
_window = window;
}
return _window
};
const getConfiguration = () =>{
if(getWindow()._Web3ClientConfiguration === undefined) {
getWindow()._Web3ClientConfiguration = {};
}
return getWindow()._Web3ClientConfiguration
};
function _optionalChain$3$1(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
const BATCH_INTERVAL = 10;
const CHUNK_SIZE$1 = 50;
const MAX_RETRY = 5;
class StaticJsonRpcBatchProvider extends ethers.ethers.providers.JsonRpcProvider {
constructor(url, network, endpoints) {
super(url);
this._network = network;
this._endpoint = url;
this._endpoints = endpoints;
this._pendingBatch = [];
}
handleError(error, endpoint, attempt, chunk) {
if(attempt < MAX_RETRY && error) {
const index = this._endpoints.indexOf(endpoint) + 1;
const retryWithNextUrl = index >= this._endpoints.length ? this._endpoints[0] : this._endpoints[index];
this.requestChunk(chunk, retryWithNextUrl, attempt+1);
} else {
chunk.forEach((inflightRequest) => {
inflightRequest.reject(error);
});
}
}
detectNetwork() {
return Promise.resolve(Blockchains__default["default"].findByName(this._network).id)
}
batchRequest(batch, endpoint, attempt) {
return new Promise((resolve, reject) => {
if (batch.length === 0) resolve([]); // Do nothing if requests is empty
fetch(
endpoint,
{
method: 'POST',
body: JSON.stringify(batch),
headers: { 'Content-Type': 'application/json' },
signal: _optionalChain$3$1([AbortSignal, 'optionalAccess', _ => _.timeout]) ? AbortSignal.timeout(10000) : undefined // 10-second timeout
}
).then((response)=>{
if(response.ok) {
response.json().then((parsedJson)=>{
if(!(parsedJson instanceof Array)) {
parsedJson = [parsedJson];
}
if(parsedJson.find((entry)=>{
return _optionalChain$3$1([entry, 'optionalAccess', _2 => _2.error]) && [-32062,-32016].includes(_optionalChain$3$1([entry, 'optionalAccess', _3 => _3.error, 'optionalAccess', _4 => _4.code]))
})) {
if(attempt < MAX_RETRY) {
reject('Error in batch found!');
} else {
resolve(parsedJson);
}
} else {
resolve(parsedJson);
}
}).catch(reject);
} else {
reject(`${response.status} ${response.text}`);
}
}).catch(reject);
})
}
requestChunk(chunk, endpoint, attempt) {
const batch = chunk.map((inflight) => inflight.request);
try {
return this.batchRequest(batch, endpoint, attempt)
.then((result) => {
// For each result, feed it to the correct Promise, depending
// on whether it was a success or error
chunk.forEach((inflightRequest, index) => {
const payload = result[index];
if (_optionalChain$3$1([payload, 'optionalAccess', _5 => _5.error])) {
const error = new Error(payload.error.message);
error.code = payload.error.code;
error.data = payload.error.data;
inflightRequest.reject(error);
} else if(_optionalChain$3$1([payload, 'optionalAccess', _6 => _6.result])) {
inflightRequest.resolve(payload.result);
} else {
inflightRequest.reject();
}
});
}).catch((error) => this.handleError(error, endpoint, attempt, chunk))
} catch (error){ this.handleError(error, endpoint, attempt, chunk); }
}
send(method, params) {
const request = {
method: method,
params: params,
id: (this._nextId++),
jsonrpc: "2.0"
};
if (this._pendingBatch == null) {
this._pendingBatch = [];
}
const inflightRequest = { request, resolve: null, reject: null };
const promise = new Promise((resolve, reject) => {
inflightRequest.resolve = resolve;
inflightRequest.reject = reject;
});
this._pendingBatch.push(inflightRequest);
if (!this._pendingBatchAggregator) {
// Schedule batch for next event loop + short duration
this._pendingBatchAggregator = setTimeout(() => {
// Get the current batch and clear it, so new requests
// go into the next batch
const batch = this._pendingBatch;
this._pendingBatch = [];
this._pendingBatchAggregator = null;
// Prepare Chunks of CHUNK_SIZE
const chunks = [];
for (let i = 0; i < Math.ceil(batch.length / CHUNK_SIZE$1); i++) {
chunks[i] = batch.slice(i*CHUNK_SIZE$1, (i+1)*CHUNK_SIZE$1);
}
chunks.forEach((chunk)=>{
// Get the request as an array of requests
chunk.map((inflight) => inflight.request);
return this.requestChunk(chunk, this._endpoint, 1)
});
}, getConfiguration().batchInterval || BATCH_INTERVAL);
}
return promise
}
}
function _optionalChain$2$1(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
const getAllProviders = ()=> {
if(getWindow()._Web3ClientProviders == undefined) {
getWindow()._Web3ClientProviders = {};
}
return getWindow()._Web3ClientProviders
};
const setProvider$1 = (blockchain, provider)=> {
if(provider == undefined) { return }
if(getAllProviders()[blockchain] === undefined) { getAllProviders()[blockchain] = []; }
const index = getAllProviders()[blockchain].indexOf(provider);
if(index > -1) {
getAllProviders()[blockchain].splice(index, 1);
}
getAllProviders()[blockchain].unshift(provider);
};
const setProviderEndpoints$1 = async (blockchain, endpoints, detectFastest = true)=> {
getAllProviders()[blockchain] = endpoints.map((endpoint, index)=>
new StaticJsonRpcBatchProvider(endpoint, blockchain, endpoints)
);
let provider;
let window = getWindow();
if(
window.fetch == undefined ||
(typeof process != 'undefined' && process['env'] && process['env']['NODE_ENV'] == 'test') ||
(typeof window.cy != 'undefined') ||
detectFastest === false
) {
provider = getAllProviders()[blockchain][0];
} else {
let responseTimes = await Promise.all(endpoints.map((endpoint)=>{
return new Promise(async (resolve)=>{
let timeout = 900;
let before = new Date().getTime();
setTimeout(()=>resolve(timeout), timeout);
let response;
try {
response = await fetch(endpoint, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
referrer: "",
referrerPolicy: "no-referrer",
body: JSON.stringify({ method: 'net_version', id: 1, jsonrpc: '2.0' }),
signal: _optionalChain$2$1([AbortSignal, 'optionalAccess', _ => _.timeout]) ? AbortSignal.timeout(10000) : undefined // 10-second timeout
});
} catch (e) {}
if(!_optionalChain$2$1([response, 'optionalAccess', _2 => _2.ok])) { return resolve(999) }
let after = new Date().getTime();
resolve(after-before);
})
}));
const fastestResponse = Math.min(...responseTimes);
const fastestIndex = responseTimes.indexOf(fastestResponse);
provider = getAllProviders()[blockchain][fastestIndex];
}
setProvider$1(blockchain, provider);
};
const getProvider$1 = async (blockchain)=> {
let providers = getAllProviders();
if(providers && providers[blockchain]){ return providers[blockchain][0] }
let window = getWindow();
if(window._Web3ClientGetProviderPromise && window._Web3ClientGetProviderPromise[blockchain]) { return await window._Web3ClientGetProviderPromise[blockchain] }
if(!window._Web3ClientGetProviderPromise){ window._Web3ClientGetProviderPromise = {}; }
window._Web3ClientGetProviderPromise[blockchain] = new Promise(async(resolve)=> {
await setProviderEndpoints$1(blockchain, Blockchains__default["default"][blockchain].endpoints);
resolve(getWindow()._Web3ClientProviders[blockchain][0]);
});
return await window._Web3ClientGetProviderPromise[blockchain]
};
const getProviders$1 = async(blockchain)=>{
let providers = getAllProviders();
if(providers && providers[blockchain]){ return providers[blockchain] }
let window = getWindow();
if(window._Web3ClientGetProvidersPromise && window._Web3ClientGetProvidersPromise[blockchain]) { return await window._Web3ClientGetProvidersPromise[blockchain] }
if(!window._Web3ClientGetProvidersPromise){ window._Web3ClientGetProvidersPromise = {}; }
window._Web3ClientGetProvidersPromise[blockchain] = new Promise(async(resolve)=> {
await setProviderEndpoints$1(blockchain, Blockchains__default["default"][blockchain].endpoints);
resolve(getWindow()._Web3ClientProviders[blockchain]);
});
return await window._Web3ClientGetProvidersPromise[blockchain]
};
var EVM = {
getProvider: getProvider$1,
getProviders: getProviders$1,
setProviderEndpoints: setProviderEndpoints$1,
setProvider: setProvider$1,
};
let supported$2 = ['ethereum', 'bsc', 'polygon', 'fantom', 'arbitrum', 'avalanche', 'gnosis', 'optimism', 'base', 'worldchain'];
supported$2.evm = ['ethereum', 'bsc', 'polygon', 'fantom', 'arbitrum', 'avalanche', 'gnosis', 'optimism', 'base', 'worldchain'];
supported$2.svm = [];
function _optionalChain$1$1(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
let getCacheStore = () => {
if (getWindow()._Web3ClientCacheStore == undefined) {
getWindow()._Web3ClientCacheStore = {};
}
return getWindow()._Web3ClientCacheStore
};
let getPromiseStore = () => {
if (getWindow()._Web3ClientPromiseStore == undefined) {
getWindow()._Web3ClientPromiseStore = {};
}
return getWindow()._Web3ClientPromiseStore
};
let set = function ({ key, value, expires }) {
getCacheStore()[key] = {
expiresAt: Date.now() + expires,
value,
};
};
let get = function ({ key, expires }) {
let cachedEntry = getCacheStore()[key];
if (_optionalChain$1$1([cachedEntry, 'optionalAccess', _ => _.expiresAt]) > Date.now()) {
return cachedEntry.value
}
};
let getPromise = function({ key }) {
return getPromiseStore()[key]
};
let setPromise = function({ key, promise }) {
getPromiseStore()[key] = promise;
return promise
};
let deletePromise = function({ key }) {
getPromiseStore()[key] = undefined;
};
let cache = function ({ call, key, expires = 0 }) {
return new Promise((resolve, reject)=>{
let value;
key = JSON.stringify(key);
// get existing promise (of a previous pending request asking for the exact same thing)
let existingPromise = getPromise({ key });
if(existingPromise) {
return existingPromise
.then(resolve)
.catch(reject)
}
setPromise({ key, promise: new Promise((resolveQueue, rejectQueue)=>{
if (expires === 0) {
return call()
.then((value)=>{
resolve(value);
resolveQueue(value);
})
.catch((error)=>{
reject(error);
rejectQueue(error);
})
}
// get cached value
value = get({ key, expires });
if (value) {
resolve(value);
resolveQueue(value);
return value
}
// set new cache value
call()
.then((value)=>{
if (value) {
set({ key, value, expires });
}
resolve(value);
resolveQueue(value);
})
.catch((error)=>{
reject(error);
rejectQueue(error);
});
})
}).then(()=>{
deletePromise({ key });
}).catch(()=>{
deletePromise({ key });
});
})
};
// Periodically clean up expired cache entries (every 5 minutes), to prevent memory leaks
if (typeof process == 'undefined' || process.env && "production" === 'test') {
setInterval(() => {
const store = getCacheStore();
const now = Date.now();
for (const key in store) {
if (store[key].expiresAt < now) {
delete store[key];
}
}
}, 10 * 60 * 1000); // 10 minutes in milliseconds
}
let paramsToContractArgs = ({ contract, method, params }) => {
let fragment = contract.interface.fragments.find((fragment) => {
return fragment.name == method
});
return fragment.inputs.map((input, index) => {
if (Array.isArray(params)) {
return params[index]
} else {
return params[input.name]
}
})
};
const contractCall = ({ address, api, method, params, provider, block }) => {
const contract = new ethers.ethers.Contract(address, api, provider);
const args = paramsToContractArgs({ contract, method, params });
const fragment = contract.interface.fragments.find((fragment)=>fragment.name === method);
if(contract[method] === undefined) {
method = `${method}(${fragment.inputs.map((input)=>input.type).join(',')})`;
}
if(fragment && fragment.stateMutability === 'nonpayable') {
return contract.callStatic[method](...args, { blockTag: block })
} else {
return contract[method](...args, { blockTag: block })
}
};
const balance = ({ address, provider, block }) => {
return provider.getBalance(address, block)
};
const transactionCount = ({ address, provider }) => {
return provider.getTransactionCount(address)
};
const singleRequest$1 = ({ blockchain, address, api, method, params, block, provider }) =>{
if (api) {
return contractCall({ address, api, method, params, provider, block })
} else if (method === 'latestBlockNumber') {
return provider.getBlockNumber()
} else if (method === 'balance') {
return balance({ address, provider, block })
} else if (method === 'transactionCount') {
return transactionCount({ address, provider })
}
};
var requestEVM = async ({ blockchain, address, api, method, params, block, timeout, strategy }) => {
strategy = strategy ? strategy : (getConfiguration().strategy || 'failover');
timeout = timeout ? timeout : (getConfiguration().timeout || undefined);
if(strategy === 'fastest') {
const providers = await EVM.getProviders(blockchain);
let allRequestsFailed = [];
const allRequestsInParallel = providers.map((provider)=>{
return new Promise((resolve)=>{
allRequestsFailed.push(
singleRequest$1({ blockchain, address, api, method, params, block, provider }).then(resolve)
);
})
});
const timeoutPromise = new Promise((_, reject)=>setTimeout(()=>{ reject(new Error("Web3ClientTimeout")); }, timeout || 10000));
allRequestsFailed = Promise.all(allRequestsFailed.map((request)=>{
return new Promise((resolve)=>{ request.catch(resolve); })
})).then(()=>{ return });
return Promise.race([...allRequestsInParallel, timeoutPromise, allRequestsFailed])
} else { // failover
const provider = await EVM.getProvider(blockchain);
const request = singleRequest$1({ blockchain, address, api, method, params, block, provider });
if(timeout) {
timeout = new Promise((_, reject)=>setTimeout(()=>{ reject(new Error("Web3ClientTimeout")); }, timeout));
return Promise.race([request, timeout])
} else {
return request
}
}
};
var parseUrl = (url) => {
if (typeof url == 'object') {
return url
}
let deconstructed = url.match(/(?<blockchain>\w+):\/\/(?<part1>[\w\d]+)(\/(?<part2>[\w\d]+)*)?/);
if(deconstructed.groups.part2 == undefined) {
if(deconstructed.groups.part1.match(/\d/)) {
return {
blockchain: deconstructed.groups.blockchain,
address: deconstructed.groups.part1
}
} else {
return {
blockchain: deconstructed.groups.blockchain,
method: deconstructed.groups.part1
}
}
} else {
return {
blockchain: deconstructed.groups.blockchain,
address: deconstructed.groups.part1,
method: deconstructed.groups.part2
}
}
};
const request = async function (url, options) {
const { blockchain, address, method } = parseUrl(url);
const { api, params, cache: cache$1, block, timeout, strategy, cacheKey } = (typeof(url) == 'object' ? url : options) || {};
return await cache({
expires: cache$1 || 0,
key: cacheKey || [blockchain, address, method, params, block],
call: async()=>{
if(supported$2.evm.includes(blockchain)) {
return await requestEVM({ blockchain, address, api, method, params, block, strategy, timeout })
} else if(supported$2.svm.includes(blockchain)) ; else {
throw 'Unknown blockchain: ' + blockchain
}
}
})
};
function _optionalChain$7(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
const EXCHANGE_PROXIES = {
'arbitrum': {
[Blockchains__default["default"].arbitrum.wrapped.address]: '0x7E655088214d0657251A51aDccE9109CFd23B5B5'
},
'avalanche': {
[Blockchains__default["default"].avalanche.wrapped.address]: '0x2d0a6275eaDa0d03226919ce6D93661E589B2d59'
},
'base': {
[Blockchains__default["default"].base.wrapped.address]: '0xD1711710843B125a6a01FfDF9b95fDc3064BeF7A'
},
'bsc': {
[Blockchains__default["default"].bsc.wrapped.address]: '0xeEb80d14abfB058AA78DE38813fe705c3e3b243E'
},
'ethereum': {
[Blockchains__default["default"].ethereum.wrapped.address]: '0x298f4980525594b3b982779cf74ba76819708D43'
},
'fantom': {
[Blockchains__default["default"].fantom.wrapped.address]: '0x2d0a6275eaDa0d03226919ce6D93661E589B2d59'
},
'gnosis': {
[Blockchains__default["default"].gnosis.wrapped.address]: '0x2d0a6275eaDa0d03226919ce6D93661E589B2d59'
},
'optimism': {
[Blockchains__default["default"].optimism.wrapped.address]: '0x69594057e2C0224deb1180c7a5Df9ec9d5B611B5'
},
'polygon': {
[Blockchains__default["default"].polygon.wrapped.address]: '0xaE59C9d3E055BdFAa583E169aA5Ebe395689476a'
},
'worldchain': {
[Blockchains__default["default"].worldchain.wrapped.address]: '0x2CA727BC33915823e3D05fe043d310B8c5b2dC5b'
},
'solana': {}
};
const getTransaction$3 = async({ paymentRoute, options })=> {
let deadline = _optionalChain$7([options, 'optionalAccess', _ => _.deadline]) || Math.ceil(new Date())+(1800*1000); // 30 minutes in ms (default)
const transaction = {
blockchain: paymentRoute.blockchain,
to: transactionAddress({ paymentRoute, options }),
api: transactionApi({ paymentRoute, options }),
method: transactionMethod({ paymentRoute, options }),
params: await transactionParams({ paymentRoute, options, deadline }),
value: transactionValue({ paymentRoute })
};
transaction.deadline = deadline;
return transaction
};
const transactionAddress = ({ paymentRoute, options })=> {
if(paymentRoute.directTransfer && !paymentRoute.fee && !paymentRoute.fee2 && _optionalChain$7([options, 'optionalAccess', _2 => _2.wallet, 'optionalAccess', _3 => _3.name]) !== 'World App') {
if(paymentRoute.toToken.address == Blockchains__default["default"][paymentRoute.blockchain].currency.address) {
return paymentRoute.toAddress
} else {
return paymentRoute.toToken.address
}
} else {
return routers$2[paymentRoute.blockchain].address
}
};
const transactionApi = ({ paymentRoute, options })=> {
if(paymentRoute.directTransfer && !paymentRoute.fee && !paymentRoute.fee2 && _optionalChain$7([options, 'optionalAccess', _4 => _4.wallet, 'optionalAccess', _5 => _5.name]) !== 'World App') {
if(paymentRoute.toToken.address == Blockchains__default["default"][paymentRoute.blockchain].currency.address) {
return undefined
} else {
return Token__default["default"][paymentRoute.blockchain].DEFAULT
}
} else {
return routers$2[paymentRoute.blockchain].api
}
};
const transactionMethod = ({ paymentRoute, options })=> {
if(paymentRoute.directTransfer && !paymentRoute.fee && !paymentRoute.fee2 && _optionalChain$7([options, 'optionalAccess', _6 => _6.wallet, 'optionalAccess', _7 => _7.name]) !== 'World App') {
if(paymentRoute.toToken.address == Blockchains__default["default"][paymentRoute.blockchain].currency.address) {
return undefined
} else { // standard token transfer
return 'transfer'
}
} else {
return 'pay'
}
};
const getExchangeType = ({ exchangeRoute, blockchain })=> {
if( typeof exchangeRoute === 'undefined' ) { return 0 }
if(exchangeRoute.exchange[blockchain].router.address === Blockchains__default["default"][blockchain].wrapped.address) {
return 2 // push
} else {
return 1 // pull
}
};
const getExchangeCallData = ({ exchangeTransaction })=>{
const contract = new ethers.ethers.Contract(exchangeTransaction.to, exchangeTransaction.api);
const method = exchangeTransaction.method;
const params = exchangeTransaction.params;
let contractMethod;
let fragment;
fragment = contract.interface.fragments.find((fragment) => {
return(
fragment.name == method &&
(fragment.inputs && params && typeof(params) === 'object' ? fragment.inputs.length == Object.keys(params).length : true)
)
});
let paramsToEncode;
if(fragment.inputs.length === 1 && fragment.inputs[0].type === 'tuple') {
contractMethod = method;
paramsToEncode = [params[fragment.inputs[0].name]];
} else {
contractMethod = `${method}(${fragment.inputs.map((input)=>input.type).join(',')})`;
paramsToEncode = fragment.inputs.map((input) => {
if(input.type === 'tuple') {
let tuple = {};
input.components.forEach((component, index)=>{
tuple[component.name] = params[input.name][index];
});
contractMethod = method;
return tuple
} else {
return params[input.name]
}
});
}
return contract.interface.encodeFunctionData(contractMethod, paramsToEncode)
};
const getPermit2SignatureTransferNonce = async({ address, blockchain })=>{
const getBitmap = (address, word)=>request({
blockchain: blockchain,
address: Blockchains__default["default"][blockchain].permit2,
api: [{"inputs":[{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"AllowanceExpired","type":"error"},{"inputs":[],"name":"ExcessiveInvalidation","type":"error"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"uint256","name":"maxAmount","type":"uint256"}],"name":"InvalidAmount","type":"error"},{"inputs":[],"name":"InvalidContractSignature","type":"error"},{"inputs":[],"name":"InvalidNonce","type":"error"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[],"name":"InvalidSignatureLength","type":"error"},{"inputs":[],"name":"InvalidSigner","type":"error"},{"inputs":[],"name":"LengthMismatch","type":"error"},{"inputs":[{"internalType":"uint256","name":"signatureDeadline","type":"uint256"}],"name":"SignatureExpired","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint160","name":"amount","type":"uint160"},{"indexed":false,"internalType":"uint48","name":"expiration","type":"uint48"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"address","name":"spender","type":"address"}],"name":"Lockdown","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint48","name":"newNonce","type":"uint48"},{"indexed":false,"internalType":"uint48","name":"oldNonce","type":"uint48"}],"name":"NonceInvalidation","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint160","name":"amount","type":"uint160"},{"indexed":false,"internalType":"uint48","name":"expiration","type":"uint48"},{"indexed":false,"internalType":"uint48","name":"nonce","type":"uint48"}],"name":"Permit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"word","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"mask","type":"uint256"}],"name":"UnorderedNonceInvalidation","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint160","name":"amount","type":"uint160"},{"internalType":"uint48","name":"expiration","type":"uint48"},{"internalType":"uint48","name":"nonce","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint160","name":"amount","type":"uint160"},{"internalType":"uint48","name":"expiration","type":"uint48"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint48","name":"newNonce","type":"uint48"}],"name":"invalidateNonces","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"wordPos","type":"uint256"},{"internalType":"uint256","name":"mask","type":"uint256"}],"name":"invalidateUnorderedNonces","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"internalType":"struct IAllowanceTransfer.TokenSpenderPair[]","name":"approvals","type":"tuple[]"}],"name":"lockdown","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"nonceBitmap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"components":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint160","name":"amount","type":"uint160"},{"internalType":"uint48","name":"expiration","type":"uint48"},{"internalType":"uint48","name":"nonce","type":"uint48"}],"internalType":"struct IAllowanceTransfer.PermitDetails[]","name":"details","type":"tuple[]"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"sigDeadline","type":"uint256"}],"internalType":"struct IAllowanceTransfer.PermitBatch","name":"permitBatch","type":"tuple"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"components":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint160","name":"amount","type":"uint160"},{"internalType":"uint48","name":"expiration","type":"uint48"},{"internalType":"uint48","name":"nonce","type":"uint48"}],"internalType":"struct IAllowanceTransfer.PermitDetails","name":"details","type":"tuple"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"sigDeadline","type":"uint256"}],"internalType":"struct IAllowanceTransfer.PermitSingle","name":"permitSingle","type":"tuple"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct ISignatureTransfer.TokenPermissions","name":"permitted","type":"tuple"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"internalType":"struct ISignatureTransfer.PermitTransferFrom","name":"permit","type":"tuple"},{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"requestedAmount","type":"uint256"}],"internalType":"struct ISignatureTransfer.SignatureTransferDetails","name":"transferDetails","type":"tuple"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"permitTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct ISignatureTransfer.TokenPermissions[]","name":"permitted","type":"tuple[]"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"internalType":"struct ISignatureTransfer.PermitBatchTransferFrom","name":"permit","type":"tuple"},{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"requestedAmount","type":"uint256"}],"internalType":"struct ISignatureTransfer.SignatureTransferDetails[]","name":"transferDetails","type":"tuple[]"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"permitTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct ISignatureTransfer.TokenPermissions","name":"permitted","type":"tuple"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"internalType":"struct ISignatureTransfer.PermitTransferFrom","name":"permit","type":"tuple"},{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"requestedAmount","type":"uint256"}],"internalType":"struct ISignatureTransfer.SignatureTransferDetails","name":"transferDetails","type":"tuple"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"bytes32","name":"witness","type":"bytes32"},{"internalType":"string","name":"witnessTypeString","type":"string"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"permitWitnessTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct ISignatureTransfer.TokenPermissions[]","name":"permitted","type":"tuple[]"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"internalType":"struct ISignatureTransfer.PermitBatchTransferFrom","name":"permit","type":"tuple"},{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"requestedAmount","type":"uint256"}],"internalType":"struct ISignatureTransfer.SignatureTransferDetails[]","name":"transferDetails","type":"tuple[]"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"bytes32","name":"witness","type":"bytes32"},{"internalType":"string","name":"witnessTypeString","type":"string"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"permitWitnessTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint160","name":"amount","type":"uint160"},{"internalType":"address","name":"token","type":"address"}],"internalType":"struct IAllowanceTransfer.AllowanceTransferDetails[]","name":"transferDetails","type":"tuple[]"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint160","name":"amount","type":"uint160"},{"internalType":"address","name":"token","type":"address"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"}],
method: 'nonceBitmap',
params: [address, word]
});
const getFirstUnsetBit = (bitmap)=>{
for (let i = 0; i < 256; i++) {
if (bitmap.shr(i).and(1).eq(0)) {
return i
}
}
return -1
};
function buildNonce(word, bitPos) {
return ethers.ethers.BigNumber.from(word).mul(256).add(bitPos)
}
let word = 0;
while(word < 1) {
const bitmap = await getBitmap(address, word);
if(bitmap.toString() != Blockchains__default["default"][blockchain].maxInt) {
const bitPos = getFirstUnsetBit(bitmap);
if (bitPos >= 0) {
// Build and return the nonce
const nonce = buildNonce(word, bitPos);
return nonce
}
}
word = word+1;
}
};
const transactionParams = async ({ paymentRoute, options, deadline })=> {
if(paymentRoute.directTransfer && !paymentRoute.fee && !paymentRoute.fee2 && _optionalChain$7([options, 'optionalAccess', _8 => _8.wallet, 'optionalAccess', _9 => _9.name]) !== 'World App') {
if(paymentRoute.toToken.address == Blockchains__default["default"][paymentRoute.blockchain].currency.address) {
return undefined
} else { // standard token transfer
return [paymentRoute.toAddress, paymentRoute.toAmount]
}
} else {
const exchangeRoute = paymentRoute.exchangeRoutes[0];
const exchangeTyp