@depay/web3-mock
Version:
JavaScript library to mock web3 responses either by emulating web3 wallets or web3 RPC requests.
1,251 lines (1,075 loc) • 62.2 kB
JavaScript
import { ethers } from 'ethers';
import Blockchains from '@depay/web3-blockchains';
function _optionalChain$j(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 normalize = function (input) {
if (input instanceof Array) {
return input.map((element) => normalize(element))
} else if (typeof input === 'undefined') {
return input
} else if (typeof input === 'object' && input._isBigNumber) {
return input.toString()
} else {
if (_optionalChain$j([input, 'optionalAccess', _ => _.toString])) {
return input.toString().toLowerCase()
} else if (typeof input === 'object') {
return JSON.stringify(input)
} else if (typeof input === 'string' && input.match('0x')) {
return input.toLowerCase()
} else {
return input
}
}
};
let anything = '__ANYTHING__';
let fillMockParamsWithAnything = ({ contractArguments, mockParams }) => {
if (typeof mockParams === 'object' && !Array.isArray(mockParams) && !mockParams._isBigNumber) {
let filledMockParams = {};
Object.keys(mockParams).forEach((key) => {
filledMockParams[key] = fillMockParamsWithAnything({
contractArguments: contractArguments[key],
mockParams: mockParams[key],
});
});
return filledMockParams
} else if (Array.isArray(mockParams)) {
return mockParams.map((element, index) => {
return fillMockParamsWithAnything({
contractArguments: contractArguments[index],
mockParams: element,
})
})
} else {
if (mockParams === anything) {
return normalize(contractArguments)
} else {
return mockParams
}
}
};
let anythingDeepMatch = ({ contractArguments, mockParams }) => {
let filledMockParams = fillMockParamsWithAnything({ contractArguments, mockParams });
return Object.keys(filledMockParams).every((key) => {
return (
JSON.stringify(normalize(filledMockParams[key])) ==
JSON.stringify(normalize(contractArguments[key]))
)
})
};
let anythingMatch = ({ contractArguments, mockParams }) => {
if (
mockParams === anything &&
typeof contractArguments !== 'undefined' &&
contractArguments.length > 0
) {
return true
} else if (!JSON.stringify(mockParams).match(anything)) {
return false
} else if (Array.isArray(mockParams) && anythingDeepMatch({ contractArguments, mockParams })) {
return true
}
return false
};
var raise = (msg)=>{
console.log(msg);
throw(msg)
};
function _optionalChain$i(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 getContract = ({ address, api, provider }) => {
return new ethers.Contract(address, api, provider)
};
let getContractFunction = ({ data, address, api, provider }) => {
let contract = getContract({ address, api, provider });
let methodSelector = data.substring(0, 10);
try {
return contract.interface.getFunction(methodSelector)
} catch (error) {
if (error.reason == 'no matching function') {
raise('Web3Mock: method not found in mocked api!');
} else {
raise(error);
}
}
};
let getContractArguments = ({ params, api, provider }) => {
let data = params.data;
let address = params.to;
let contract = getContract({ address, api, provider });
let contractFunction = getContractFunction({ data, address, api, provider });
return contract.interface.decodeFunctionData(contractFunction, data)
};
let encode = ({ result, params, api, provider }) => {
let address = params.to;
let data = params.data;
let contract = getContract({ address, api, provider });
let contractFunction = getContractFunction({ data, address, api, provider });
let encodedResult;
if(_optionalChain$i([contractFunction, 'optionalAccess', _ => _.outputs]) && contractFunction.outputs.length == 1) {
encodedResult = [result];
} else {
encodedResult = result;
}
let method = contractFunction.name;
if(contract[method] === undefined) {
method = `${contractFunction.name}(${contractFunction.inputs.map((input)=>input.type).join(',')})`;
}
return contract.interface.encodeFunctionResult(method, encodedResult)
};
function _optionalChain$h(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 getWindow = (configuration) => {
if (_optionalChain$h([configuration, 'optionalAccess', _ => _.window])) return configuration.window
if (typeof global == 'object') return global
if (typeof cy == 'object') return cy.window().specWindow.window
if (typeof window == 'object') return window
};
let currentBlock;
let blockData = {};
let getCurrentBlock = () => {
return currentBlock
};
let resetCurrentBlock = ()=>{
currentBlock = 1;
};
resetCurrentBlock();
let increaseBlock = (amount = 1) => {
currentBlock += amount;
};
let getBlockData = (number) => {
return(blockData[number] || null)
};
let setBlockData = (number, data) => {
blockData[number] = data;
};
let resetBlockData = ()=> {
blockData = {};
};
let required = [];
let requireMock = (type) => {
required.push(type);
};
let resetRequire = () => {
required = [];
};
let count = {};
let increaseTransactionCount = (address) => {
address = address.toLowerCase();
if(count[address] == undefined) { count[address] = 0; }
count[address] += 1;
};
let getTransactionCount = (address) => {
address = address.toLowerCase();
if(count[address] == undefined) { count[address] = 0; }
return ethers.BigNumber.from(count[address].toString())._hex
};
let resetTransactionCount = ()=> {
count = {};
};
let WalletConnectClass, WalletLinkClass;
let mocks = [];
const setWalletConnectClass = (givenWalletConnectClass)=> {
WalletConnectClass = givenWalletConnectClass;
};
const setWalletLinkClass = (givenWalletLinkClass)=> {
WalletLinkClass = givenWalletLinkClass;
};
const resetMocks = ()=> {
let window = getWindow();
if (window.ethereum) {
window.ethereum = undefined;
}
mocks = [];
resetRequire();
resetCurrentBlock();
resetBlockData();
resetTransactionCount();
if(WalletConnectClass) { WalletConnectClass.instance = undefined; }
if(WalletLinkClass) { WalletLinkClass.instance = undefined; }
};
resetMocks();
function _optionalChain$g(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 mockIsNotAnObject = (mock) => {
return typeof mock !== 'object'
};
let mockHasWrongType = (mock, type) => {
return mock[type] == undefined
};
let mockHasWrongBlockchain = (mock, blockchain) => {
if(blockchain == undefined) { return false }
return mock.blockchain != blockchain
};
let mockHasWrongProvider = (mock, provider) => {
if(mock.provider == undefined) { return false }
return mock.provider != provider
};
let mockHasWrongTransactionData = (mock, type, params) => {
return (
(mock[type].to && normalize(params.to) !== normalize(mock[type].to)) ||
(mock[type].from && normalize(params.from) !== normalize(mock[type].from)) ||
(mock[type].value &&
ethers.BigNumber.from(params.value).toString() !== normalize(mock[type].value))
)
};
let mockHasWrongBalanceData = (mock, type, params) => {
return mock[type].for && normalize(params.address) !== normalize(mock[type].for)
};
let mockHasWrongToAddress = (mock, type, params) => {
return normalize(mock[type].to) !== normalize(_optionalChain$g([params, 'optionalAccess', _ => _.to]))
};
let mockHasWrongForAddress = (mock, type, params) =>{
if(mock[type].for == null) { return false }
return normalize(mock[type].for) !== normalize(_optionalChain$g([params, 'optionalAccess', _2 => _2.address]))
};
let mockDataDoesNotMatchSingleArgument = (mock, type, contractArguments) => {
return (
Array.isArray(mock[type].params) == false &&
contractArguments.length == 1 &&
_optionalChain$g([contractArguments, 'access', _3 => _3[0], 'optionalAccess', _4 => _4.length]) === undefined &&
(
normalize(mock[type].params) != normalize(contractArguments[0]) &&
normalize(Object.values(mock[type].params)[0]) != normalize(contractArguments[0])
) &&
!anythingMatch({ contractArguments, mockParams: mock[type].params })
)
};
let mockDataDoesNotMatchArrayArgument = (mock, type, contractArguments) => {
return (
Array.isArray(mock[type].params) &&
JSON.stringify(contractArguments.map((argument) => normalize(argument))) !==
JSON.stringify(mock[type].params.map((argument) => normalize(argument))) &&
!anythingMatch({ contractArguments, mockParams: mock[type].params })
)
};
let mockedArgumentsDoMatch = (mock, type, contractArguments, parentKey) => {
if (mock[type].params == undefined) {
return true
}
if (mock[type].params == anything) {
return true
}
let isDeepAnythingMatch = anythingDeepMatch({ contractArguments, mockParams: parentKey ? mock[type].params[parentKey] : mock[type].params });
return Object.keys(mock[type].params).every((key) => {
if (mock[type].params && mock[type].params[key]) {
let allParamsMatch;
if(!parentKey && typeof mock[type].params[key] === 'object') {
allParamsMatch = mockedArgumentsDoMatch(mock, type, contractArguments[key], key);
}
if(allParamsMatch){
return true
} else {
return (
JSON.stringify(normalize(mock[type].params[key])) ==
JSON.stringify(normalize(contractArguments[key])) || isDeepAnythingMatch
)
}
} else {
return true
}
})
};
let mockDataDoesNotMatchObjectArugment = (mock, type, contractArguments) => {
return (
Array.isArray(mock[type].params) == false &&
normalize(mock[type].params) != normalize(contractArguments[0]) &&
!mockedArgumentsDoMatch(mock, type, contractArguments) &&
!anythingMatch({ contractArguments, mockParams: mock[type].params })
)
};
let mockHasWrongBlock = (mock, block) => {
if((typeof block == 'undefined' || block == 'latest') && typeof mock.block == 'undefined'){ return false }
if(typeof mock.block == 'undefined') { return true }
return ethers.utils.hexValue(mock.block) != block
};
let mockHasWrongData = (mock, type, params, provider) => {
if (_optionalChain$g([mock, 'access', _5 => _5[type], 'optionalAccess', _6 => _6.api]) == undefined) {
return
}
let api = mock[type].api;
let contractFunction = getContractFunction({
data: params.data,
address: params.to,
api,
provider,
});
if (mock[type].method !== contractFunction.name) {
return true
}
let contractArguments = getContractArguments({ params, api, provider });
if (mockDataDoesNotMatchSingleArgument(mock, type, contractArguments)) {
return true
}
if (mockDataDoesNotMatchArrayArgument(mock, type, contractArguments)) {
return true
}
if (mockDataDoesNotMatchObjectArugment(mock, type, contractArguments)) {
return true
}
};
let mockHasWrongNetworkAction = (mock, type, params) => {
if(type != 'network') { return false }
return Object.keys(mock.network)[0] != Object.keys(params)[0]
};
let findMock = ({ type, blockchain, params, block, provider }) => {
return mocks.find((mock) => {
if (mockIsNotAnObject(mock)) {
return
}
if (mockHasWrongBlockchain(mock, blockchain)) {
return
}
if (mockHasWrongProvider(mock, provider)) {
return
}
if (mockHasWrongType(mock, type)) {
return
}
if (mockHasWrongTransactionData(mock, type, params)) {
return
}
if (mockHasWrongBalanceData(mock, type, params)) {
return
}
if (mockHasWrongToAddress(mock, type, params)) {
return
}
if (mockHasWrongForAddress(mock, type, params)) {
return
}
if (mockHasWrongData(mock, type, params, provider)) {
return
}
if (mockHasWrongBlock(mock, block)) {
return
}
if (mockHasWrongNetworkAction(mock, type, params)) {
return
}
return mock
})
};
let findAnyMockForThisAddress = ({ type, params }) => {
return mocks.find((mock) => {
if (mock[type] === undefined) {
return
}
if (normalize(_optionalChain$g([mock, 'access', _7 => _7[type], 'optionalAccess', _8 => _8.to])) !== normalize(params.to)) {
return
}
return mock
})
};
let findMockByTransactionHash = (hash) => {
return mocks.find((mock) => {
return _optionalChain$g([mock, 'optionalAccess', _9 => _9.transaction, 'optionalAccess', _10 => _10._id]) == hash && (
_optionalChain$g([mock, 'optionalAccess', _11 => _11.transaction, 'optionalAccess', _12 => _12._confirmed]) || _optionalChain$g([mock, 'optionalAccess', _13 => _13.transaction, 'optionalAccess', _14 => _14._failed])
)
})
};
let confirm$1 = (transaction) => {
let mock = findMockByTransactionHash(transaction._id);
transaction._confirmedAtBlock = getCurrentBlock();
if(mock && mock._from) { increaseTransactionCount(mock._from); }
return transaction
};
let supported = ['ethereum', 'bsc', 'polygon', 'fantom', 'arbitrum', 'avalanche', 'gnosis', 'optimism', 'base', 'worldchain'];
supported.evm = ['ethereum', 'bsc', 'polygon', 'fantom', 'arbitrum', 'avalanche', 'gnosis', 'optimism', 'base', 'worldchain'];
supported.svm = [];
function _optionalChain$f(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; }
var confirm = (mock) => {
if (_optionalChain$f([mock, 'optionalAccess', _ => _.transaction, 'optionalAccess', _2 => _2._id])) {
mock.transaction._confirmed = true;
if(supported.evm.includes(mock.blockchain)) {
confirm$1(mock.transaction);
} else if(supported.svm.includes(mock.blockchain)) ; else {
raise('Web3Mock: Unknown blockchain!');
}
increaseBlock();
} else {
raise('Web3Mock: Given mock is not a sent transaction: ' + JSON.stringify(mock));
}
};
var to_b58 = function(
B, //Uint8Array raw byte input
A //Base58 characters (i.e. "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz")
) {
var d = [], //the array for storing the stream of base58 digits
s = "", //the result string variable that will be returned
i, //the iterator variable for the byte input
j, //the iterator variable for the base58 digit array (d)
c, //the carry amount variable that is used to overflow from the current base58 digit to the next base58 digit
n; //a temporary placeholder variable for the current base58 digit
for(i in B) { //loop through each byte in the input stream
j = 0, //reset the base58 digit iterator
c = B[i]; //set the initial carry amount equal to the current byte amount
s += c || s.length ^ i ? "" : 1; //prepend the result string with a "1" (0 in base58) if the byte stream is zero and non-zero bytes haven't been seen yet (to ensure correct decode length)
while(j in d || c) { //start looping through the digits until there are no more digits and no carry amount
n = d[j]; //set the placeholder for the current base58 digit
n = n ? n * 256 + c : c; //shift the current base58 one byte and add the carry amount (or just add the carry amount if this is a new digit)
c = n / 58 | 0; //find the new carry amount (floored integer of current digit divided by 58)
d[j] = n % 58; //reset the current base58 digit to the remainder (the carry amount will pass on the overflow)
j++; //iterate to the next base58 digit
}
}
while(j--) //since the base58 digits are backwards, loop through them in reverse order
s += A[d[j]]; //lookup the character associated with each base58 digit
return s //return the final base58 string
};
const getRandomTransactionHash = (blockchain) => {
if(supported.evm.includes(blockchain)) {
return ethers.BigNumber.from(
'1' +
Array(76)
.fill()
.map(() => Math.random().toString()[4])
.join(''),
)._hex
} else if (supported.svm.includes(blockchain)) {
return to_b58(
Array(32)
.fill()
.map(() => parseInt(Math.random().toString()[4]), 10),
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
)
}
};
var replace = (transactionMock, replacingTransactionMock, confirmed = true) => {
if(transactionMock == undefined || replacingTransactionMock == undefined) { raise('replace requires (transactionMock, replacingTransactionMock)'); }
if(transactionMock.transaction.from == undefined) { raise('transactionMock to be replaced requires at least a "from"'); }
replacingTransactionMock.transaction._id = getRandomTransactionHash(replacingTransactionMock.blockchain);
if(confirmed){
replacingTransactionMock.transaction._confirmed = true;
} else {
replacingTransactionMock.transaction._failed = true;
}
setBlockData(getCurrentBlock(), {
"number": "0xd6fa38",
"baseFeePerGas": "0x2d79336308",
"difficulty": "0x2ca5a8551de6c9",
"extraData": "0x6575726f70652d63656e7472616c322d33",
"gasLimit": "0x1ca35d2",
"gasUsed": "0x4f1487",
"hash": "0x8110e001148adad4d749559998e82061aa7d11bfdab65b840608327f98550fbc",
"logsBloom": "0x04200102130400839382604c8300800e003008904824c0060100214904200e03012450500400101050704850004005208a028000092171092200140020202001c24221a08488114c08a4000c844008340024058014408121408021d1c04401011320800023240000031050205300088921155204008186203102141410180102d840890204a0d202001801070004003010060011030081090000044800100e0462580e48280221000a2020d0801186a80001800922060000506288a092c81814c1482202402041882514000204008800c00c3300044900102860814e088221219411248a86440000020017c104088b10404180012100004000011892002004b8",
"miner": "0xea674fdde714fd979de3edf0f56aa9716b898ec8",
"mixHash": "0x3c18abd91830b37cab8451afbbfb480de19bfc43e6cb9dea4b2eac1c41c81c2b",
"nonce": "0x41fdf9e14a45d935",
"parentHash": "0x885327d9913d7effef8532b5ee0815b1711a279b3414da90b93f175135701803",
"receiptsRoot": "0x605fecc910c7e00a244da10635b170f7eabded9449321e79b73e42eb82619747",
"sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"size": "0x6e63",
"stateRoot": "0xc5549451a31830f2cbba18453066f9ef7539243f58ee1340341d1376a87ffd56",
"timestamp": "0x61f2c7ec",
"totalDifficulty": "0x87820e2f3a1f8913fee",
"transactionsRoot": "0x5582fa18ef2f1eb6a4f3ca7d225b9fb1050074293cd30127ef3919a35fd50d2b",
"uncles": [],
transactions: [
{
"hash": replacingTransactionMock.transaction._id,
"accessList": [],
"blockHash": "0x8110e001148adad4d749559998e82061aa7d11bfdab65b840608327f98550fbc",
"blockNumber": "0xd6fa38",
"from": replacingTransactionMock.transaction.from,
"gas": "0x55730",
"gasPrice": "0x2d79336308",
"input": "0x8803dbee0000000000000000000000000000000000000000001782b76fd64557b6b780000000000000000000000000000000000000000000000000032a27fd31187d551000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000008817d887960737a604cf712d3e5da8673dddb7f00000000000000000000000000000000000000000000000000000000061f2ca440000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000090185f2135308bad17527004364ebcc2d37e5f6",
"maxFeePerGas": "0x2e87159fb3",
"maxPriorityFeePerGas": "0x0",
"nonce": getTransactionCount(replacingTransactionMock.transaction.from),
"r": "0x81d4fe714af2e1725ad1746fc240a6ac3b0f795d207ac207f36abaf8db6c72b2",
"s": "0x3c4f61eef2ecb98a50bf3940bc90e7dcacbc7f233a57d5eb44c0ae07fdec4ced",
"to": replacingTransactionMock.transaction.to,
"transactionIndex": "0x0",
"type": "0x2",
"v": "0x0",
"value": "0x0"
}
]
});
increaseBlock();
increaseTransactionCount(transactionMock.transaction.from);
};
let fail$1 = (transaction, reason) => {
let mock = findMockByTransactionHash(transaction._id);
transaction._confirmedAtBlock = getCurrentBlock();
transaction._failed = true;
transaction._failedReason = reason;
if(mock && mock._from) { increaseTransactionCount(mock._from); }
return transaction
};
function _optionalChain$e(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; }
var fail = (mock, reason) => {
if (_optionalChain$e([mock, 'optionalAccess', _ => _.transaction, 'optionalAccess', _2 => _2._id])) {
mock.transaction._failed = true;
mock.transaction._confirmed = false;
if(supported.evm.includes(mock.blockchain)) {
fail$1(mock.transaction, reason);
} else if(supported.svm.includes(mock.blockchain)) ; else {
raise('Web3Mock: Unknown blockchain!');
}
increaseBlock();
} else {
raise('Web3Mock: Given mock is not a sent transaction: ' + JSON.stringify(mock));
}
};
let events$2 = {};
let triggerEvent$2 = (eventName, value) => {
if(events$2[eventName] == undefined) { return }
events$2[eventName].forEach(function (callback) {
callback(value);
});
};
let on$2 = (eventName, callback) => {
if (events$2[eventName] === undefined) {
events$2[eventName] = [];
}
events$2[eventName].push(callback);
};
let removeListener$1 = (eventName, callback) => {
if (events$2[eventName]) {
let index = events$2[eventName].indexOf(callback);
if (index >= 0) {
events$2[eventName].splice(index, 1);
}
}
};
function _optionalChain$d(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; }
var getTransactionByHash = (hash) => {
let mock = findMockByTransactionHash(hash);
let lastTransactionMock = mocks.find((mock)=>mock.transaction);
let from = (lastTransactionMock && lastTransactionMock.transaction.from) ? lastTransactionMock.transaction.from : '0xb7576e9d314df41ec5506494293afb1bd5d3f65d';
let to = (lastTransactionMock && lastTransactionMock.transaction.to) ? lastTransactionMock.transaction.to : '0xae60aC8e69414C2Dc362D0e6a03af643d1D85b92';
let transaction = {
from,
gas: '0x29857',
gasPrice: '0xba43b7400',
hash: hash,
input:
'0x606060405261022e806100136000396000f300606060405260e060020a6000350463201745d5811461003c578063432ced04146100d257806379ce9fac14610141578063d5fa2b00146101a8575b005b61003a6004356024356000828152602081905260409020600101548290600160a060020a039081163391909116141561020857604060009081206001810180548254600160a060020a0319908116909355919091169055600160a060020a038316906803bd913e6c1df40000606082818181858883f1505060405184935060008051602061020e833981519152929150a2505050565b61003a600435600081815260208190526040812060010154600160a060020a031614801561010957506803bd913e6c1df400003410155b1561013e57604060009081206001018054600160a060020a03191633179055819060008051602061020e833981519152906060a25b50565b61003a6004356024356000828152602081905260409020600101548290600160a060020a039081163391909116141561020857604060009081206001018054600160a060020a03191684179055819060008051602061020e833981519152906060a2505050565b61003a6004356024356000828152602081905260409020600101548290600160a060020a039081163391909116141561020857604060009081208054600160a060020a03191684179055819060008051602061020e833981519152906060a25b5050505600a6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc',
nonce: ethers.utils.hexlify(getTransactionCount(from)),
r: '0xcfb56087c168a48bc69bd2634172fd9defd77bd172387e2137643906ff3606f6',
s: '0x3474eb47999927f2bed4d4ec27d7e8bb4ad17c61d76761e40fdbd859d84c3bd5',
to,
transactionIndex: '0x1',
type: '0x0',
v: '0x1c',
value: ethers.BigNumber.from(_optionalChain$d([mock, 'optionalAccess', _ => _.transaction, 'optionalAccess', _2 => _2.value]) || 0)._hex,
};
if (mock) {
Object.assign(transaction, {
blockHash: getRandomTransactionHash(mock.blockchain),
blockNumber: ethers.BigNumber.from(mock.transaction._confirmedAtBlock || getCurrentBlock())
._hex,
});
}
return Promise.resolve(transaction)
};
function _optionalChain$c(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; }
var getTransactionReceipt = (hash) => {
let mock = findMockByTransactionHash(hash);
if (mock) {
return Promise.resolve({
from: _optionalChain$c([mock, 'optionalAccess', _ => _.transaction, 'optionalAccess', _2 => _2.from]),
to: _optionalChain$c([mock, 'optionalAccess', _3 => _3.transaction, 'optionalAccess', _4 => _4.to]),
transactionHash: hash,
transactionIndex: '0x1',
blockNumber: ethers.BigNumber.from(mock.transaction._confirmedAtBlock || getCurrentBlock())
._hex,
blockHash: getRandomTransactionHash(mock.blockchain),
cumulativeGasUsed: '0x33bc',
gasUsed: '0x4dc',
logs: _optionalChain$c([mock, 'optionalAccess', _5 => _5.transaction, 'optionalAccess', _6 => _6.logs]) || [],
logsBloom: '0x0000000000000000000000000000000000000000',
status: _optionalChain$c([mock, 'access', _7 => _7.transaction, 'optionalAccess', _8 => _8._failed]) ? '0x0' : '0x1',
})
} else {
return Promise.resolve(null)
}
};
function _optionalChain$b(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 balance = function ({ blockchain, params, provider }) {
params = (typeof params == 'object') ? params : { address: params };
let mock = findMock({ blockchain, type: 'balance', params, provider });
if (mock && _optionalChain$b([mock, 'access', _ => _.balance, 'optionalAccess', _2 => _2.return])) {
mock.calls.add(params);
if (_optionalChain$b([mock, 'optionalAccess', _3 => _3.balance, 'optionalAccess', _4 => _4.return]) instanceof Error) {
return Promise.reject(mock.balance.return)
} else {
return Promise.resolve(ethers.BigNumber.from(mock.balance.return))
}
} else {
raise(
'Web3Mock: Please mock the balance request: ' +
JSON.stringify({
blockchain: blockchain,
balance: {
for: params.address,
return: 'PUT BALANCE AMOUNT HERE',
},
})
);
}
};
function _optionalChain$a(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 callMock$1 = ({ mock, params, provider })=> {
mock.calls.add(params);
if (mock.request.return instanceof Error) {
return Promise.reject({
error: {
message: mock.request.return.message
}
})
} else {
return Promise.resolve(
encode({ result: mock.request.return, api: mock.request.api, params, provider })
)
}
};
let call = function ({ blockchain, params, block, provider }) {
let mock = findMock({ type: 'request', params, block, provider });
if (mock) {
if(mock.request.delay) {
return new Promise((resolve)=>{
setTimeout(()=>resolve(callMock$1({ mock, params, provider })), mock.request.delay);
})
} else {
return callMock$1({ mock, params, provider })
}
} else {
mock = findAnyMockForThisAddress({ type: 'request', params });
if (mock && _optionalChain$a([mock, 'access', _ => _.request, 'optionalAccess', _2 => _2.api])) {
raise(
'Web3Mock: Please mock the request: ' +
JSON.stringify({
blockchain,
request: getCallToBeMock$1({ mock, params, provider, block }),
})
);
} else {
raise('Web3Mock: Please mock the request to: ' + params.to);
}
}
};
let getCallToBeMock$1 = ({ mock, params, provider, block }) => {
let address = params.to;
let api = mock.request.api;
let contractFunction = getContractFunction({ data: params.data, address, api, provider });
let contractArguments = getContractArguments({ params, api, provider });
let toBeMocked = {
to: address,
api: ['PLACE API HERE'],
method: contractFunction.name,
return: 'Your Value',
};
if(block && block != 'latest') { toBeMocked['block'] = parseInt(block, 16); }
if (contractArguments && contractArguments.length) {
if (Array.isArray(contractArguments) && contractArguments.length === 1) {
toBeMocked['params'] = normalize(contractArguments[0]);
} else {
toBeMocked['params'] = contractArguments.map((argument) => normalize(argument));
}
}
return toBeMocked
};
let callMock = ({ mock, params, provider })=> {
mock.calls.add(params);
if (mock.code.return instanceof Error) {
return Promise.reject({
error: {
message: mock.code.return.message
}
})
} else {
return Promise.resolve(mock.code.return)
}
};
let code = function ({ blockchain, params, provider }) {
let mock = findMock({ type: 'code', params, provider });
if (mock) {
if(mock.code.delay) {
return new Promise((resolve)=>{
setTimeout(()=>resolve(callMock({ mock, params, provider })), mock.code.delay);
})
} else {
return callMock({ mock, params, provider })
}
} else {
raise(
'Web3Mock: Please mock the request: ' +
JSON.stringify({
blockchain,
code: getCallToBeMock({ mock, params, provider }),
})
);
}
};
let getCallToBeMock = ({ mock, params, provider }) => {
let toBeMocked = {
for: params.address,
return: 'Your Value',
};
return toBeMocked
};
function _optionalChain$9(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 throwSuggestedMock = ({ blockchain, mock, params, provider }) => {
raise(
'Web3Mock: Please mock the estimate: ' +
JSON.stringify({
blockchain,
estimate: getEstimateToBeMocked({ mock, params, provider }),
})
);
};
let estimate = ({ blockchain, params, provider }) => {
let defaultEstimate = Promise.resolve('0x2c4a0');
let mock;
if(_optionalChain$9([params, 'optionalAccess', _ => _.transaction])) { params = params.transaction; }
mock = findMock({ type: 'estimate', params, provider });
if (mock) {
mock.calls.add(params);
if (_optionalChain$9([mock, 'optionalAccess', _2 => _2.estimate, 'optionalAccess', _3 => _3.return]) instanceof Error) {
return Promise.reject(mock.estimate.return)
} else if (_optionalChain$9([mock, 'access', _4 => _4.estimate, 'optionalAccess', _5 => _5.return])) {
return Promise.resolve(ethers.BigNumber.from(mock.estimate.return))
} else {
return defaultEstimate
}
} else if (required.includes('estimate')) {
return throwSuggestedMock({ blockchain, params, provider })
}
mock = findMock({ type: 'transaction', params, provider });
if (mock) {
return defaultEstimate
}
mock = findAnyMockForThisAddress({ type: 'estimate', params });
if (mock) {
return throwSuggestedMock({ blockchain, mock, params, provider })
} else {
return defaultEstimate
}
};
let getEstimateToBeMocked = ({ mock, params, provider }) => {
let address = params.to;
let toBeMocked = {
to: address,
api: ['PLACE API HERE'],
return: 'ESTIMATED GAS',
};
if (mock === undefined) {
return toBeMocked
}
let api = _optionalChain$9([mock, 'access', _6 => _6.estimate, 'optionalAccess', _7 => _7.api]);
if (api) {
let contractFunction = getContractFunction({ data: params.data, address, api, provider });
let contractArguments = getContractArguments({ params, api, provider });
toBeMocked['method'] = contractFunction.name;
if (contractArguments && contractArguments.length) {
let paramsToBeMocked = {};
Object.keys(contractArguments).forEach((key) => {
if (key.match(/\D/)) {
paramsToBeMocked[key] = normalize(contractArguments[key]);
}
});
toBeMocked['params'] = paramsToBeMocked;
}
}
return toBeMocked
};
let requestAccounts = ({ mock, params })=> {
mock.calls.add(params || {});
if (mock.accounts.return instanceof Error) {
return Promise.reject(mock.accounts.return)
} else {
return Promise.resolve(
mock.accounts.return
)
}
};
let getAccounts = function ({ blockchain, params, provider }) {
let mock = findMock({ type: 'accounts', blockchain, params, provider });
if (mock) {
if(mock.accounts.delay) {
return new Promise((resolve)=>{
setTimeout(()=>resolve(requestAccounts({ mock, params })), mock.accounts.delay);
})
} else {
return requestAccounts({ mock, params })
}
} else {
raise(
'Web3Mock: Please mock accounts: ' +
JSON.stringify({
blockchain,
accounts: {
return: ['YOUR ACCOUNT HERE']
}
})
);
}
};
let currentNetwork;
let getCurrentNetwork = ()=>{
return currentNetwork
};
let setCurrentNetwork = (network)=>{
currentNetwork = network;
};
function _optionalChain$8(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 getLogs = ({ blockchain, params, provider })=> {
let mock = findMock({ type: 'logs', blockchain, params, provider });
if(mock && _optionalChain$8([mock, 'optionalAccess', _ => _.logs, 'optionalAccess', _2 => _2.return])) {
return Promise.resolve(mock.logs.return)
} else {
raise(
'Web3Mock: Please mock the logs request: ' +
JSON.stringify({
blockchain,
logs: getLogsToBeMocked({ params, provider }),
})
);
}
};
const getLogsToBeMocked = ({ params, provider }) => {
return {
address: params.address,
topics: params.topics,
fromBlock: params.fromBlock,
toBlock: params.toBlock,
return: ['THE_RETURNED_LOGS']
}
};
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; }
let sign = function ({ blockchain, params, provider }) {
let mock = findMock({ blockchain, type: 'signature', params, provider });
if (mock && _optionalChain$7([mock, 'access', _ => _.signature, 'optionalAccess', _2 => _2.return])) {
mock.calls.add(params);
if(mock.signature.delay) {
return new Promise((resolve, reject)=>{
setTimeout(()=>{
if (mock.signature.return instanceof Error) {
reject(mock.signature.return);
} else {
resolve(mock.signature.return);
}
}, mock.signature.delay);
})
} else {
if (mock.signature.return instanceof Error) {
return Promise.reject(mock.signature.return)
} else {
return Promise.resolve(mock.signature.return)
}
}
} else {
raise(
'Web3Mock: Please mock the sign request: ' +
JSON.stringify({
blockchain: blockchain,
signature: {
params: params,
return: 'PUT SIGNATURE HERE',
},
})
);
}
};
function _optionalChain$6(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 switchNetwork = function ({ blockchain, id, provider }) {
let toBlockchain = Blockchains.findById(id);
if(toBlockchain == undefined) { throw `No blockchain found for id ${id}` }
let params = { switchTo: toBlockchain.name };
let mock = findMock({ type: 'network', params, provider });
if (mock && _optionalChain$6([mock, 'access', _ => _.network, 'optionalAccess', _2 => _2.switchTo])) {
mock.calls.add(params);
if(mock.network.error) {
if(typeof mock.network.error == 'function') {
return Promise.reject(mock.network.error())
} else {
return Promise.reject(mock.network.error)
}
} else {
setCurrentNetwork(toBlockchain.name);
return Promise.resolve()
}
} else {
raise(
'Web3Mock: Please mock the network switch: ' +
JSON.stringify({
blockchain,
network: {
switchTo: toBlockchain.name
},
})
);
}
};
let addNetwork = function ({ blockchain, params, provider }) {
let mock = findMock({ type: 'network', params: { add: params }, provider });
if (mock && _optionalChain$6([mock, 'access', _3 => _3.network, 'optionalAccess', _4 => _4.add])) {
mock.calls.add(params);
return Promise.resolve()
} else {
raise(
'Web3Mock: Please mock the network addition: ' +
JSON.stringify({
blockchain,
network: {
add: params
},
})
);
}
};
function _optionalChain$5(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 traceTransaction = ({ blockchain, params, provider })=> {
let mock = findMock({ type: 'trace', blockchain, params, provider });
if(mock && _optionalChain$5([mock, 'optionalAccess', _ => _.trace, 'optionalAccess', _2 => _2.return])) {
return Promise.resolve(mock.trace.return)
} else {
raise(
'Web3Mock: Please mock the trace request: ' +
JSON.stringify({
blockchain,
trace: getTraceToBeMocked({ params, provider }),
})
);
}
};
const getTraceToBeMocked = ({ params, provider }) => {
return {
params: params,
return: 'YOUR_TRACE_OBJECT'
}
};
function _optionalChain$4(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 transaction = ({ blockchain, params, provider }) => {
let mock = findMock({ type: 'transaction', params, provider });
if (mock) {
mock.calls.add(params);
if(params && params.from) { mock._from = params.from; }
if(mock.transaction.delay) {
return new Promise((resolve, reject)=>{
setTimeout(()=>{
if (mock.transaction.return instanceof Error) {
reject(mock.transaction.return);
} else {
resolve(mock.transaction._id);
}
}, mock.transaction.delay);
})
} else {
if (mock.transaction.return instanceof Error) {
return Promise.reject(mock.transaction.return)
} else {
return Promise.resolve(mock.transaction._id)
}
}
} else {
mock = findAnyMockForThisAddress({ type: 'transaction', params });
if (mock && _optionalChain$4([mock, 'access', _ => _.transaction, 'optionalAccess', _2 => _2.api])) {
raise(
'Web3Mock: Please mock the transaction: ' +
JSON.stringify({
blockchain,
transaction: getTransactionToBeMocked({ mock, params, provider }),
})
);
} else {
raise('Web3Mock: Please mock the transaction to: ' + params.to);
}
}
};
let getTransactionToBeMocked = ({ mock, params, provider }) => {
let address = params.to;
let api = mock.transaction.api;
let contractFunction = getContractFunction({ data: params.data, address, api, provider });
let contractArguments = getContractArguments({ params, api, provider });
let toBeMocked = {
to: address,
api: ['PLACE API HERE'],
method: contractFunction.name,
};
if (contractArguments && contractArguments.length) {
let paramsToBeMocked = {};
Object.keys(contractArguments).forEach((key) => {
if (key.match(/\D/)) {
paramsToBeMocked[key] = normalize(contractArguments[key]);
}
});
toBeMocked['params'] = paramsToBeMocked;
}
return toBeMocked
};
function _optionalChain$3(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 request = ({ blockchain, request, provider }) => {
let params;
// Web3js request fix (nested request)
if(Object.keys(request.method).includes('method')) {
request = request.method;
}
if(blockchain == undefined && _optionalChain$3([provider, 'optionalAccess', _ => _._blockchain])) {
blockchain = provider._blockchain;
} else if(blockchain == undefined) {
blockchain = getCurrentNetwork();
}
switch (request.method) {
case 'eth_chainId':
return Promise.resolve(Blockchains.findByName(blockchain).id)
case 'eth_getBalance':
return balance({ blockchain, params: (request.params instanceof Array) ? request.params[0] : request.params, provider })
case 'net_version':
return Promise.resolve(Blockchains.findByName(blockchain).networkId)
case 'eth_requestAccounts':
case 'eth_accounts':
return getAccounts({ blockchain, provider })
case 'eth_estimateGas':
params = request.params ? ((request.params instanceof Array) ? request.params[0] : request.params) : undefined;
return estimate({ blockchain, params, provider })
case 'eth_blockNumber':
case 'eth_getBlockNumber':
return Promise.resolve(ethers.BigNumber.from(getCurrentBlock())._hex)
case 'eth_getBlockByNumber':
let blockNumber;
if(request.params[0] == 'latest'){
blockNumber = getCurrentBlock();
} else {
blockNumber = ethers.BigNumber.from(request.params[0].toString());
}
return Promise.resolve(getBlockData(parseInt(blockNumber.toString())))
case 'eth_gasPrice':
return Promise.resolve('0x12fee89674')
case 'eth_call':
if(request.params instanceof Array) {
return call({ blockchain, params: request.params[0], block: request.params[1], provider })
} else if(typeof request.params == 'object') {
return call({ blockchain, params: request.params.transaction, block: request.params.blockTag, provider })
}
break
case 'eth_sendTransaction':
return transaction({ blockchain, params: request.params[0], provider })
case 'eth_getTransactionByHash':
case 'eth_getTransaction':
return getTransactionByHash((request.params instanceof Array) ? request.params[0] : request.params.transactionHash)
case 'eth_getTransactionReceipt':
return getTransactionReceipt((request.params instanceof Array) ? request.params[0] : request.params.transactionHash)
case 'eth_getTransactionCount':
params = request.params ? ((request.params instanceof Array) ? request.params[0] : request.params.address) : undefined;
return Promise.resolve(getTransactionCount(params))
case 'eth_subscribe':
return Promise.resolve()
case 'wallet_switchEthereumChain':
return switchNetwork({ blockchain, id: request.params[0].chainId, provider })
case 'wallet_addEthereumChain':
return addNetwork({ blockchain, params: request.params[0], provider })
case 'eth_sign':
case 'personal_sign':
case 'eth_signTypedData':
case 'eth_signTypedData_v1':
case 'eth_signTypedData_v2':
case 'eth_signTypedData_v3':
case 'eth_signTypedData_v4':
return sign({ blockchain, params: request.params, provider })
case 'eth_getCode':
return code({ blockchain, params: request.params, provider })
case 'eth_getGasPrice':
return Promise.resolve(ethers.utils.hexlify(13370000000))
case 'eth_getLogs':
params = request.params ? ((request.params instanceof Array) ? request.params[0] : request.params) : undefined;
return getLogs({ blockchain, params, provider })
case 'debug_traceTransaction':
return traceTransaction({ blockchain, params: requ