refactor: move brother_node development artifact to dev/test-nodes subdirectory
Development Artifact Cleanup: ✅ BROTHER_NODE REORGANIZATION: Moved development test node to appropriate location - dev/test-nodes/brother_node/: Moved from root directory for better organization - Contains development configuration, test logs, and test chain data - No impact on production systems - purely development/testing artifact ✅ DEVELOPMENT ARTIFACTS IDENTIFIED: - Chain ID: aitbc-brother-chain (test/development chain) - Ports: 8010 (P2P) and 8011 (RPC) - different from production - Environment: .env file with test configuration - Logs: rpc.log and node.log from development testing session (March 15, 2026) ✅ ROOT DIRECTORY CLEANUP: Removed development clutter from production directory - brother_node/ moved to dev/test-nodes/brother_node/ - Root directory now contains only production-ready components - Development artifacts properly organized in dev/ subdirectory DIRECTORY STRUCTURE IMPROVEMENT: 📁 dev/test-nodes/: Development and testing node configurations 🏗️ Root Directory: Clean production structure with only essential components 🧪 Development Isolation: Test environments separated from production BENEFITS: ✅ Clean Production Directory: No development artifacts in root ✅ Better Organization: Development nodes grouped in dev/ subdirectory ✅ Clear Separation: Production vs development environments clearly distinguished ✅ Maintainability: Easier to identify and manage development components RESULT: Successfully moved brother_node development artifact to dev/test-nodes/ subdirectory, cleaning up the root directory while preserving development testing environment for future use.
This commit is contained in:
246
dev/env/node_modules/micro-eth-signer/net/archive.d.ts
generated
vendored
Executable file
246
dev/env/node_modules/micro-eth-signer/net/archive.d.ts
generated
vendored
Executable file
@@ -0,0 +1,246 @@
|
||||
import { TxVersions, type AccessList } from '../tx.ts';
|
||||
import { type IWeb3Provider, type Web3CallArgs } from '../utils.ts';
|
||||
declare const CONTRACT_CAPABILITIES: Record<string, string>;
|
||||
export type BlockInfo = {
|
||||
baseFeePerGas: bigint;
|
||||
difficulty: bigint;
|
||||
extraData: string;
|
||||
gasLimit: bigint;
|
||||
gasUsed: bigint;
|
||||
hash: string;
|
||||
logsBloom: string;
|
||||
miner: string;
|
||||
mixHash: string;
|
||||
nonce: string;
|
||||
number: number;
|
||||
parentHash: string;
|
||||
receiptsRoot: string;
|
||||
sha3Uncles: string;
|
||||
size: number;
|
||||
stateRoot: string;
|
||||
timestamp: number;
|
||||
totalDifficulty?: bigint;
|
||||
transactions: string[];
|
||||
transactionsRoot: string;
|
||||
uncles: string[];
|
||||
};
|
||||
export type Action = {
|
||||
action: {
|
||||
from: string;
|
||||
callType: string;
|
||||
gas: bigint;
|
||||
input: string;
|
||||
to: string;
|
||||
value: bigint;
|
||||
};
|
||||
blockHash: string;
|
||||
blockNumber: number;
|
||||
result: {
|
||||
gasUsed: bigint;
|
||||
output: string;
|
||||
};
|
||||
subtraces: number;
|
||||
traceAddress: string[];
|
||||
transactionHash: string;
|
||||
transactionPosition: number;
|
||||
type: string;
|
||||
};
|
||||
export type Log = {
|
||||
address: string;
|
||||
topics: string[];
|
||||
data: string;
|
||||
blockNumber: number;
|
||||
transactionHash: string;
|
||||
transactionIndex: number;
|
||||
blockHash: string;
|
||||
logIndex: number;
|
||||
removed: boolean;
|
||||
};
|
||||
export type TxInfo = {
|
||||
blockHash: string;
|
||||
blockNumber: number;
|
||||
hash: string;
|
||||
accessList?: AccessList;
|
||||
transactionIndex: number;
|
||||
type: number;
|
||||
nonce: bigint;
|
||||
input: string;
|
||||
r: bigint;
|
||||
s: bigint;
|
||||
chainId: bigint;
|
||||
v: bigint;
|
||||
yParity?: string;
|
||||
gas: bigint;
|
||||
maxPriorityFeePerGas?: bigint;
|
||||
from: string;
|
||||
to: string;
|
||||
maxFeePerGas?: bigint;
|
||||
value: bigint;
|
||||
gasPrice: bigint;
|
||||
maxFeePerBlobGas?: bigint;
|
||||
blobVersionedHashes?: string[];
|
||||
};
|
||||
export type TxReceipt = {
|
||||
transactionHash: string;
|
||||
blockHash: string;
|
||||
blockNumber: number;
|
||||
logsBloom: string;
|
||||
gasUsed: bigint;
|
||||
contractAddress: string | null;
|
||||
cumulativeGasUsed: bigint;
|
||||
transactionIndex: number;
|
||||
from: string;
|
||||
to: string;
|
||||
type: number;
|
||||
effectiveGasPrice: bigint;
|
||||
logs: Log[];
|
||||
status: number;
|
||||
blobGasPrice?: bigint;
|
||||
blobGasUsed?: bigint;
|
||||
};
|
||||
export type Unspent = {
|
||||
symbol: 'ETH';
|
||||
decimals: number;
|
||||
balance: bigint;
|
||||
nonce: number;
|
||||
active: boolean;
|
||||
};
|
||||
type ERC20Token = {
|
||||
abi: 'ERC20';
|
||||
name?: string;
|
||||
symbol?: string;
|
||||
decimals?: number;
|
||||
totalSupply: bigint;
|
||||
};
|
||||
type ERC721Token = {
|
||||
abi: 'ERC721';
|
||||
name?: string;
|
||||
symbol?: string;
|
||||
totalSupply?: bigint;
|
||||
enumerable?: boolean;
|
||||
metadata?: boolean;
|
||||
};
|
||||
type ERC1155Token = {
|
||||
abi: 'ERC1155';
|
||||
};
|
||||
export type TokenInfo = {
|
||||
contract: string;
|
||||
} & (ERC20Token | ERC721Token | ERC1155Token);
|
||||
type TokenError = {
|
||||
contract: string;
|
||||
error: string;
|
||||
};
|
||||
type TokenBalanceSingle = Map<bigint, bigint>;
|
||||
export type TokenBalances = Record<string, TokenBalanceSingle | TokenError>;
|
||||
export type Topics = (string | null | (string | null)[])[];
|
||||
export type Transfer = {
|
||||
from: string;
|
||||
to?: string;
|
||||
value: bigint;
|
||||
};
|
||||
export type TokenTransfer = TokenInfo & {
|
||||
from: string;
|
||||
to: string;
|
||||
tokens: Map<bigint, bigint>;
|
||||
};
|
||||
export type TxTransfers = {
|
||||
hash: string;
|
||||
timestamp?: number;
|
||||
block?: number;
|
||||
transfers: Transfer[];
|
||||
tokenTransfers: TokenTransfer[];
|
||||
reverted: boolean;
|
||||
info: {
|
||||
type: keyof typeof TxVersions;
|
||||
info: TxInfo;
|
||||
receipt: TxReceipt;
|
||||
raw?: string;
|
||||
block: BlockInfo;
|
||||
actions: Action[];
|
||||
};
|
||||
};
|
||||
/**
|
||||
* Callbacks are needed, because we want to call getTx / getBlock / getTokenInfo
|
||||
* requests as fast as possible, to reduce amount of sequential execution.
|
||||
* If we retrieve 10 pages of transactions, we can call per tx
|
||||
* callbacks for transaction from first page before all other pages fetched.
|
||||
*
|
||||
* Ensure caching: they can be called multiple times for same tx / block.
|
||||
*/
|
||||
export type Callbacks = {
|
||||
txCallback?: (txHash: string) => void;
|
||||
blockCallback?: (blockNum: number) => void;
|
||||
contractCallback?: (contrct: string) => void;
|
||||
};
|
||||
export type Pagination = {
|
||||
fromBlock?: number;
|
||||
toBlock?: number;
|
||||
};
|
||||
export type TraceOpts = Callbacks & Pagination & {
|
||||
perRequest?: number;
|
||||
limitTrace?: number;
|
||||
};
|
||||
export type LogOpts = Callbacks & (Pagination | {
|
||||
fromBlock: number;
|
||||
toBlock: number;
|
||||
limitLogs: number;
|
||||
});
|
||||
export type Balances = {
|
||||
balances: Record<string, bigint>;
|
||||
tokenBalances: Record<string, Record<string, bigint>>;
|
||||
};
|
||||
export type TxInfoOpts = Callbacks & {
|
||||
ignoreTxRebuildErrors?: boolean;
|
||||
};
|
||||
export type TxAllowances = Record<string, Record<string, bigint>>;
|
||||
export type JsonrpcInterface = {
|
||||
call: (method: string, ...args: any[]) => Promise<any>;
|
||||
};
|
||||
/**
|
||||
* Transaction-related code around Web3Provider.
|
||||
* High-level methods are `height`, `unspent`, `transfers`, `allowances` and `tokenBalances`.
|
||||
*
|
||||
* Low-level methods are `blockInfo`, `internalTransactions`, `ethLogs`, `tokenTransfers`, `wethTransfers`,
|
||||
* `tokenInfo` and `txInfo`.
|
||||
*/
|
||||
export declare class Web3Provider implements IWeb3Provider {
|
||||
private rpc;
|
||||
constructor(rpc: JsonrpcInterface);
|
||||
call(method: string, ...args: any[]): Promise<any>;
|
||||
ethCall(args: Web3CallArgs, tag?: string): Promise<any>;
|
||||
estimateGas(args: Web3CallArgs, tag?: string): Promise<bigint>;
|
||||
blockInfo(block: number): Promise<BlockInfo>;
|
||||
unspent(address: string): Promise<Unspent>;
|
||||
height(): Promise<number>;
|
||||
traceFilterSingle(address: string, opts?: TraceOpts): Promise<any>;
|
||||
internalTransactions(address: string, opts?: TraceOpts): Promise<any[]>;
|
||||
contractCapabilities(address: string, capabilities?: typeof CONTRACT_CAPABILITIES): Promise<{
|
||||
[k: string]: boolean;
|
||||
}>;
|
||||
ethLogsSingle(topics: Topics, opts: LogOpts): Promise<Log[]>;
|
||||
ethLogs(topics: Topics, opts?: LogOpts): Promise<Log[]>;
|
||||
tokenTransfers(address: string, opts?: LogOpts): Promise<[Log[], Log[]]>;
|
||||
wethTransfers(address: string, opts?: LogOpts): Promise<[Log[]]>;
|
||||
erc1155Transfers(address: string, opts?: LogOpts): Promise<[Log[], Log[], Log[], Log[]]>;
|
||||
txInfo(txHash: string, opts?: TxInfoOpts): Promise<{
|
||||
type: 'legacy' | 'eip2930' | 'eip1559' | 'eip4844' | 'eip7702';
|
||||
info: any;
|
||||
receipt: any;
|
||||
raw: string | undefined;
|
||||
}>;
|
||||
tokenInfo(contract: string): Promise<TokenInfo | TokenError>;
|
||||
private tokenBalanceSingle;
|
||||
tokenURI(token: TokenInfo | TokenError | string, tokenId: bigint): Promise<string | TokenError>;
|
||||
tokenBalances(address: string, tokens: string[], tokenIds?: Record<string, Set<bigint>>): Promise<TokenBalances>;
|
||||
private decodeTokenTransfer;
|
||||
transfers(address: string, opts?: TraceOpts & LogOpts): Promise<TxTransfers[]>;
|
||||
allowances(address: string, opts?: LogOpts): Promise<TxAllowances>;
|
||||
}
|
||||
/**
|
||||
* Calculates balances at specific point in time after tx.
|
||||
* Also, useful as a sanity check in case we've missed something.
|
||||
* Info from multiple addresses can be merged (sort everything first).
|
||||
*/
|
||||
export declare function calcTransfersDiff(transfers: TxTransfers[]): (TxTransfers & Balances)[];
|
||||
export {};
|
||||
//# sourceMappingURL=archive.d.ts.map
|
||||
1
dev/env/node_modules/micro-eth-signer/net/archive.d.ts.map
generated
vendored
Executable file
1
dev/env/node_modules/micro-eth-signer/net/archive.d.ts.map
generated
vendored
Executable file
File diff suppressed because one or more lines are too long
772
dev/env/node_modules/micro-eth-signer/net/archive.js
generated
vendored
Executable file
772
dev/env/node_modules/micro-eth-signer/net/archive.js
generated
vendored
Executable file
@@ -0,0 +1,772 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Web3Provider = void 0;
|
||||
exports.calcTransfersDiff = calcTransfersDiff;
|
||||
const index_ts_1 = require("../abi/index.js");
|
||||
const index_ts_2 = require("../index.js");
|
||||
const tx_ts_1 = require("../tx.js");
|
||||
const utils_ts_1 = require("../utils.js");
|
||||
/*
|
||||
Methods to fetch list of transactions from any ETH node RPC.
|
||||
It should be easy. However, this is sparta^W ethereum, so, prepare to suffer.
|
||||
|
||||
The network is not directly called: `ArchiveNodeProvider#rpc` calls `Web3Provider`.
|
||||
|
||||
- There is no simple & fast API inside nodes, all external API create their own namespace for this
|
||||
- API is different between nodes: erigon uses streaming, other nodes use pagination
|
||||
- Recently, Erigon have been also adding pagination
|
||||
- For token transactions: download block headers, look at bloom filter, download affected blocks
|
||||
- There is a good `getLogs` API for contracts, but nothing for ETH transfers
|
||||
- `trace_filter` is slow: it not only finds the transaction, but also executes them
|
||||
- It's good that it allows to get internal transactions
|
||||
- The whole thing could be 10x simpler if there was an event in logs for ETH transfer
|
||||
- For most cases, we only need to see last transactions and know blocks of last txs, which is 20x faster
|
||||
- This creates a lot of requests to node (2 per tx, 1 per block, and some more depends on block range limits)
|
||||
|
||||
Recommended software:
|
||||
|
||||
- eth-nodes-for-rent are bad, because of their limits and timeouts
|
||||
- erigon nodes are fast, taking ~15 seconds per batch
|
||||
- reth has 100-block limit for trace_filter, requiring 190k requests just get transactions
|
||||
*/
|
||||
// Utils
|
||||
const ethNum = (n) => `0x${!n ? '0' : n.toString(16).replace(/^0+/, '')}`;
|
||||
const ERC_TRANSFER = (0, index_ts_1.events)(index_ts_1.ERC20).Transfer;
|
||||
const WETH_DEPOSIT = (0, index_ts_1.events)(index_ts_1.WETH).Deposit;
|
||||
const WETH_WITHDRAW = (0, index_ts_1.events)(index_ts_1.WETH).Withdrawal;
|
||||
const ERC721_TRANSFER = (0, index_ts_1.events)(index_ts_1.ERC721).Transfer;
|
||||
const ERC1155_SINGLE = (0, index_ts_1.events)(index_ts_1.ERC1155).TransferSingle;
|
||||
const ERC1155_BATCH = (0, index_ts_1.events)(index_ts_1.ERC1155).TransferBatch;
|
||||
const ERC165 = [
|
||||
// function supportsInterface(bytes4 interfaceID) external view returns (bool);
|
||||
{
|
||||
type: 'function',
|
||||
name: 'supportsInterface',
|
||||
inputs: [{ name: 'interfaceID', type: 'bytes4' }],
|
||||
outputs: [{ type: 'bool' }],
|
||||
},
|
||||
];
|
||||
const CONTRACT_CAPABILITIES = {
|
||||
erc165: '0x01ffc9a7',
|
||||
erc165_check: '0xffffffff',
|
||||
erc20: '0x36372b07',
|
||||
erc721: '0x80ac58cd',
|
||||
erc721_metadata: '0x5b5e139f',
|
||||
erc721_enumerable: '0x780e9d63',
|
||||
erc1155: '0xd9b67a26',
|
||||
erc1155_tokenreceiver: '0x4e2312e0',
|
||||
erc1155_metadata: '0x0e89341c',
|
||||
};
|
||||
function group(items, s) {
|
||||
let res = {};
|
||||
for (let i of items) {
|
||||
const key = typeof s === 'function' ? s(i) : i[s];
|
||||
if (!res[key])
|
||||
res[key] = [];
|
||||
res[key].push(i);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
function fixBlock(block) {
|
||||
block.timestamp = Number(block.timestamp) * 1000;
|
||||
block.size = Number(block.size);
|
||||
if (block.number && block.number !== null)
|
||||
block.number = Number(block.number);
|
||||
for (const i of [
|
||||
'baseFeePerGas',
|
||||
'difficulty',
|
||||
'gasLimit',
|
||||
'gasUsed',
|
||||
'totalDifficulty',
|
||||
]) {
|
||||
if (block[i] && block[i] !== null)
|
||||
block[i] = BigInt(block[i]);
|
||||
}
|
||||
}
|
||||
function fixAction(action, opts = {}) {
|
||||
action.action.value = BigInt(action.action.value);
|
||||
action.action.gas = BigInt(action.action.gas);
|
||||
action.result.gasUsed = BigInt(action.result.gasUsed);
|
||||
if (opts.txCallback)
|
||||
opts.txCallback(action.transactionHash);
|
||||
if (opts.blockCallback)
|
||||
opts.blockCallback(action.blockNumber);
|
||||
}
|
||||
// Fixes type of network response inplace
|
||||
function fixLog(log, opts = {}) {
|
||||
log.blockNumber = Number(log.blockNumber);
|
||||
log.transactionIndex = Number(log.transactionIndex);
|
||||
log.logIndex = Number(log.logIndex);
|
||||
if (opts.txCallback)
|
||||
opts.txCallback(log.transactionHash);
|
||||
if (opts.blockCallback)
|
||||
opts.blockCallback(log.blockNumber);
|
||||
if (opts.contractCallback)
|
||||
opts.contractCallback(log.address);
|
||||
return log;
|
||||
}
|
||||
function fixTxInfo(info) {
|
||||
for (const i of ['blockNumber', 'type', 'transactionIndex'])
|
||||
info[i] = Number(info[i]);
|
||||
for (const i of [
|
||||
'nonce',
|
||||
'r',
|
||||
's',
|
||||
'chainId',
|
||||
'v',
|
||||
'gas',
|
||||
'maxPriorityFeePerGas',
|
||||
'maxFeePerGas',
|
||||
'value',
|
||||
'gasPrice',
|
||||
'maxFeePerBlobGas',
|
||||
]) {
|
||||
if (info[i] !== undefined && info[i] !== null)
|
||||
info[i] = BigInt(info[i]);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
function fixTxReceipt(receipt) {
|
||||
for (const i of ['blockNumber', 'type', 'transactionIndex', 'status'])
|
||||
receipt[i] = Number(receipt[i]);
|
||||
for (const i of [
|
||||
'gasUsed',
|
||||
'cumulativeGasUsed',
|
||||
'effectiveGasPrice',
|
||||
'blobGasPrice',
|
||||
'blobGasUsed',
|
||||
]) {
|
||||
if (receipt[i] !== undefined)
|
||||
receipt[i] = BigInt(receipt[i]);
|
||||
}
|
||||
for (const log of receipt.logs)
|
||||
fixLog(log);
|
||||
return receipt;
|
||||
}
|
||||
function validateCallbacks(opts) {
|
||||
for (const i of ['txCallback', 'blockCallback', 'contractCallback']) {
|
||||
if (opts[i] !== undefined && typeof opts[i] !== 'function')
|
||||
throw new Error(`validateCallbacks: ${i} should be function`);
|
||||
}
|
||||
}
|
||||
function validatePagination(opts) {
|
||||
for (const i of ['fromBlock', 'toBlock']) {
|
||||
if (opts[i] === undefined || Number.isSafeInteger(opts[i]))
|
||||
continue;
|
||||
throw new Error(`validatePagination: wrong field ${i}=${opts[i]}. Should be integer or undefined`);
|
||||
}
|
||||
}
|
||||
function validateTraceOpts(opts) {
|
||||
validatePagination(opts);
|
||||
for (const i of ['perRequest', 'limitTrace']) {
|
||||
if (opts[i] === undefined || Number.isSafeInteger(opts[i]))
|
||||
continue;
|
||||
throw new Error(`validateTraceOpts: wrong field ${i}=${opts[i]}. Should be integer or undefined`);
|
||||
}
|
||||
if (opts.limitTrace !== undefined) {
|
||||
if (opts.fromBlock === undefined || opts.toBlock === undefined)
|
||||
throw new Error('validateTraceOpts: fromBlock/toBlock required if limitTrace is present');
|
||||
}
|
||||
validateCallbacks(opts);
|
||||
}
|
||||
function validateLogOpts(opts) {
|
||||
validatePagination(opts);
|
||||
for (const i of ['limitLogs']) {
|
||||
if (opts[i] === undefined || Number.isSafeInteger(opts[i]))
|
||||
continue;
|
||||
throw new Error(`validateLogOpts: wrong field ${i}=${opts[i]}. Should be integer or undefined`);
|
||||
}
|
||||
if (opts.limitLogs !== undefined) {
|
||||
if (opts.fromBlock === undefined || opts.toBlock === undefined)
|
||||
throw new Error('validateLogOpts: fromBlock/toBlock required if limitLogs is present');
|
||||
}
|
||||
validateCallbacks(opts);
|
||||
}
|
||||
// Promise.all for objects, undefined if error
|
||||
async function wait(obj) {
|
||||
const keys = Object.keys(obj);
|
||||
const p = await Promise.allSettled(Object.values(obj));
|
||||
const res = p.map((r, i) => [keys[i], r.status === 'fulfilled' ? r.value : undefined]);
|
||||
return Object.fromEntries(res);
|
||||
}
|
||||
const isReverted = (e) => e instanceof Error && e.message.toLowerCase().includes('revert');
|
||||
/**
|
||||
* Transaction-related code around Web3Provider.
|
||||
* High-level methods are `height`, `unspent`, `transfers`, `allowances` and `tokenBalances`.
|
||||
*
|
||||
* Low-level methods are `blockInfo`, `internalTransactions`, `ethLogs`, `tokenTransfers`, `wethTransfers`,
|
||||
* `tokenInfo` and `txInfo`.
|
||||
*/
|
||||
class Web3Provider {
|
||||
constructor(rpc) {
|
||||
this.rpc = rpc;
|
||||
}
|
||||
call(method, ...args) {
|
||||
return this.rpc.call(method, ...args);
|
||||
}
|
||||
ethCall(args, tag = 'latest') {
|
||||
return this.rpc.call('eth_call', args, tag);
|
||||
}
|
||||
async estimateGas(args, tag = 'latest') {
|
||||
return (0, utils_ts_1.hexToNumber)(await this.rpc.call('eth_estimateGas', args, tag));
|
||||
}
|
||||
// Timestamp is available only inside blocks
|
||||
async blockInfo(block) {
|
||||
const res = await this.call('eth_getBlockByNumber', ethNum(block), false);
|
||||
fixBlock(res);
|
||||
return res;
|
||||
}
|
||||
async unspent(address) {
|
||||
let [balance, nonce] = await Promise.all([
|
||||
this.call('eth_getBalance', address, 'latest'),
|
||||
this.call('eth_getTransactionCount', address, 'latest'),
|
||||
]);
|
||||
balance = BigInt(balance);
|
||||
nonce = BigInt(nonce);
|
||||
return {
|
||||
symbol: 'ETH',
|
||||
decimals: utils_ts_1.amounts.ETH_PRECISION,
|
||||
balance,
|
||||
nonce,
|
||||
// Note: account can be active even if nonce!==0!
|
||||
active: balance > 0 || nonce !== 0,
|
||||
};
|
||||
}
|
||||
async height() {
|
||||
return Number.parseInt(await this.call('eth_blockNumber'));
|
||||
}
|
||||
async traceFilterSingle(address, opts = {}) {
|
||||
const res = await this.call('trace_filter', {
|
||||
fromBlock: ethNum(opts.fromBlock),
|
||||
toBlock: ethNum(opts.toBlock),
|
||||
toAddress: [address],
|
||||
fromAddress: [address],
|
||||
});
|
||||
for (const action of res)
|
||||
fixAction(action, opts);
|
||||
return res;
|
||||
}
|
||||
async internalTransactions(address, opts = {}) {
|
||||
if (typeof address !== 'string')
|
||||
throw new Error('internalTransactions: wrong address');
|
||||
validateTraceOpts(opts);
|
||||
// For reth
|
||||
if (opts.limitTrace) {
|
||||
const promises = [];
|
||||
for (let i = opts.fromBlock; i <= opts.toBlock; i += opts.limitTrace)
|
||||
promises.push(this.traceFilterSingle(address, { fromBlock: i, toBlock: i + opts.limitTrace }));
|
||||
const out = [];
|
||||
for (const i of await Promise.all(promises))
|
||||
out.push(...i);
|
||||
return out;
|
||||
}
|
||||
let lastBlock = opts.fromBlock || 0;
|
||||
const perBlock = {};
|
||||
const out = [];
|
||||
for (;;) {
|
||||
const params = {
|
||||
fromBlock: ethNum(lastBlock),
|
||||
toAddress: [address],
|
||||
fromAddress: [address],
|
||||
after: perBlock[lastBlock] || 0, // we cannot just store after, since fromBlock changes to last block
|
||||
};
|
||||
if (opts.toBlock !== undefined)
|
||||
params.toBlock = ethNum(opts.toBlock);
|
||||
if (opts.perRequest !== undefined)
|
||||
params.count = opts.perRequest;
|
||||
const res = await this.call('trace_filter', params);
|
||||
if (!res.length)
|
||||
break;
|
||||
for (const action of res) {
|
||||
fixAction(action, opts);
|
||||
if (perBlock[action.blockNumber] === undefined)
|
||||
perBlock[action.blockNumber] = 0;
|
||||
perBlock[action.blockNumber]++;
|
||||
out.push(action);
|
||||
lastBlock = Math.max(lastBlock, action.blockNumber);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
async contractCapabilities(address, capabilities = {}) {
|
||||
const all = { ...CONTRACT_CAPABILITIES, ...capabilities };
|
||||
let c = (0, index_ts_1.createContract)(ERC165, this, address);
|
||||
const keys = Object.keys(all);
|
||||
// TODO: what about revert?
|
||||
// if reverted -> all capabilities disabled
|
||||
try {
|
||||
const promises = await Promise.all(Object.values(all).map((i) => c.supportsInterface.call(utils_ts_1.ethHex.decode(i))));
|
||||
const res = Object.fromEntries(keys.map((k, i) => [k, promises[i]]));
|
||||
// if somehow there is same method, but it doesn't support erc165, then it is different method!
|
||||
// erc165_check if sailsafe when there is method that always returns true
|
||||
if (!res.erc165 || res.erc165_check)
|
||||
for (const k in res)
|
||||
res[k] = false;
|
||||
return res;
|
||||
}
|
||||
catch (e) {
|
||||
// If execution reverted: contract doesn't support ERC165
|
||||
if (isReverted(e))
|
||||
return Object.fromEntries(keys.map((k) => [k, false]));
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
async ethLogsSingle(topics, opts) {
|
||||
const req = { topics, fromBlock: ethNum(opts.fromBlock || 0) };
|
||||
if (opts.toBlock !== undefined)
|
||||
req.toBlock = ethNum(opts.toBlock);
|
||||
const res = await this.call('eth_getLogs', req);
|
||||
return res.map((i) => fixLog(i, opts));
|
||||
}
|
||||
async ethLogs(topics, opts = {}) {
|
||||
validateLogOpts(opts);
|
||||
const fromBlock = opts.fromBlock || 0;
|
||||
if (!('limitLogs' in opts))
|
||||
return this.ethLogsSingle(topics, opts);
|
||||
const promises = [];
|
||||
for (let i = fromBlock; i <= opts.toBlock; i += opts.limitLogs)
|
||||
promises.push(this.ethLogsSingle(topics, { fromBlock: i, toBlock: i + opts.limitLogs }));
|
||||
const out = [];
|
||||
for (const i of await Promise.all(promises))
|
||||
out.push(...i);
|
||||
return out;
|
||||
}
|
||||
// NOTE: this is very low-level methods that return parts used for .transfers method,
|
||||
// you will need to decode data yourself.
|
||||
async tokenTransfers(address, opts = {}) {
|
||||
if (typeof address !== 'string')
|
||||
throw new Error('tokenTransfers: wrong address');
|
||||
validateLogOpts(opts);
|
||||
// If we want incoming and outgoing token transfers we need to call both
|
||||
return await Promise.all([
|
||||
this.ethLogs(ERC_TRANSFER.topics({ from: address, to: null, value: null }), opts), // From
|
||||
this.ethLogs(ERC_TRANSFER.topics({ from: null, to: address, value: null }), opts), // To
|
||||
]);
|
||||
}
|
||||
async wethTransfers(address, opts = {}) {
|
||||
if (typeof address !== 'string')
|
||||
throw new Error('tokenTransfers: wrong address');
|
||||
validateLogOpts(opts);
|
||||
const depositTopic = WETH_DEPOSIT.topics({ dst: address, wad: null });
|
||||
const withdrawTopic = WETH_WITHDRAW.topics({ src: address, wad: null });
|
||||
// OR query
|
||||
return await Promise.all([
|
||||
this.ethLogs([[depositTopic[0], withdrawTopic[0]], depositTopic[1]], opts),
|
||||
]);
|
||||
}
|
||||
async erc1155Transfers(address, opts = {}) {
|
||||
if (typeof address !== 'string')
|
||||
throw new Error('tokenTransfers: wrong address');
|
||||
validateLogOpts(opts);
|
||||
return await Promise.all([
|
||||
// Single
|
||||
this.ethLogs(ERC1155_SINGLE.topics({ operator: null, from: address, to: null, id: null, value: null }), opts),
|
||||
this.ethLogs(ERC1155_SINGLE.topics({ operator: null, from: null, to: address, id: null, value: null }), opts),
|
||||
// Batch
|
||||
this.ethLogs(ERC1155_BATCH.topics({ operator: null, from: address, to: null, ids: null, values: null }), opts),
|
||||
this.ethLogs(ERC1155_BATCH.topics({ operator: null, from: null, to: address, ids: null, values: null }), opts),
|
||||
]);
|
||||
}
|
||||
async txInfo(txHash, opts = {}) {
|
||||
let [info, receipt] = await Promise.all([
|
||||
this.call('eth_getTransactionByHash', txHash),
|
||||
this.call('eth_getTransactionReceipt', txHash),
|
||||
]);
|
||||
info = fixTxInfo(info);
|
||||
receipt = fixTxReceipt(receipt);
|
||||
const type = Object.keys(tx_ts_1.TxVersions)[info.type];
|
||||
// This is not strictly neccessary, but allows to store tx info in very compact format and remove unneccessary fields
|
||||
// Also, there is additional validation that node returned actual with correct hash/sender and not corrupted stuff.
|
||||
let raw = undefined;
|
||||
try {
|
||||
const rawData = {
|
||||
nonce: info.nonce,
|
||||
gasLimit: info.gas,
|
||||
to: info.to === null ? '0x' : info.to,
|
||||
value: info.value,
|
||||
data: info.input,
|
||||
r: info.r,
|
||||
s: info.s,
|
||||
yParity: Number(info.v),
|
||||
chainId: info.chainId,
|
||||
};
|
||||
if (info.accessList)
|
||||
rawData.accessList = info.accessList;
|
||||
if (info.maxFeePerBlobGas)
|
||||
rawData.maxFeePerBlobGas = info.maxFeePerBlobGas;
|
||||
if (info.blobVersionedHashes)
|
||||
rawData.blobVersionedHashes = info.blobVersionedHashes;
|
||||
if (info.maxFeePerGas) {
|
||||
rawData.maxFeePerGas = info.maxFeePerGas;
|
||||
rawData.maxPriorityFeePerGas = info.maxPriorityFeePerGas;
|
||||
}
|
||||
else if (info.gasPrice)
|
||||
rawData.gasPrice = info.gasPrice;
|
||||
if (type === 'legacy')
|
||||
Object.assign(rawData, tx_ts_1.legacySig.encode({ v: info.v, r: info.r, s: info.s }));
|
||||
const tx = new index_ts_2.Transaction(type, rawData, false, true);
|
||||
if (tx.recoverSender().address.toLowerCase() !== info.from.toLowerCase())
|
||||
throw new Error('txInfo: wrong sender');
|
||||
if (receipt.transactionHash !== `0x${tx.hash}`)
|
||||
throw new Error('txInfo: wrong hash');
|
||||
raw = tx.toHex();
|
||||
}
|
||||
catch (err) {
|
||||
// This can crash if something wrong with our parser or limits, so
|
||||
// we have option to make network code to work even if rebuilding is crashed
|
||||
if (!opts.ignoreTxRebuildErrors)
|
||||
throw err;
|
||||
}
|
||||
if (opts.blockCallback && info.blockNumber !== null)
|
||||
opts.blockCallback(info.blockNumber);
|
||||
return { type, info, receipt, raw };
|
||||
}
|
||||
async tokenInfo(contract) {
|
||||
const c = (0, index_ts_1.createContract)(index_ts_1.ERC20, this, contract);
|
||||
const t = await wait({
|
||||
code: this.call('eth_getCode', contract, 'latest'),
|
||||
capabilities: this.contractCapabilities(contract),
|
||||
// We call all stuff at same time to reduce latency (should be done in single req if batched)
|
||||
name: c.name.call(), // ERC-20 (optional), ERC-721 (metada)
|
||||
symbol: c.symbol.call(), // ERC-20 (optional), ERC-721 (metadata)
|
||||
decimals: c.decimals.call(), // ERC-20 (optional), ERC-721 (enumarable)
|
||||
totalSupply: c.totalSupply.call(), // ERC-20 (required), ERC-721
|
||||
});
|
||||
// No code, probably self-destructed
|
||||
if (t.code === '0x')
|
||||
return { contract, error: 'not contract or destructed' };
|
||||
if (t.capabilities && t.capabilities.erc1155) {
|
||||
// All metadata is inside URI per tokenId to outside network stuff (maybe ipfs), so nothing to do here.
|
||||
return { contract, abi: 'ERC1155' };
|
||||
}
|
||||
if (t.capabilities && t.capabilities.erc721) {
|
||||
const res = { contract, abi: 'ERC721' };
|
||||
if (t.capabilities.erc721_metadata) {
|
||||
if (t.name === undefined)
|
||||
return { contract, error: 'ERC721+Metadata without name' };
|
||||
if (t.symbol === undefined)
|
||||
return { contract, error: 'ERC721+Metadata without symbol' };
|
||||
Object.assign(res, { name: t.name, symbol: t.symbol, metadata: true });
|
||||
}
|
||||
if (t.capabilities.erc721_enumerable) {
|
||||
if (t.totalSupply === undefined)
|
||||
return { contract, error: 'ERC721+Enumerable without totalSupply' };
|
||||
Object.assign(res, { totalSupply: t.totalSupply, enumerable: true });
|
||||
}
|
||||
return res;
|
||||
}
|
||||
if (t.totalSupply === undefined)
|
||||
return { contract, error: 'not ERC20 token' }; // If there is no totalSupply, it is not ERC20!
|
||||
return {
|
||||
contract,
|
||||
abi: 'ERC20',
|
||||
name: t.name,
|
||||
symbol: t.symbol,
|
||||
totalSupply: t.totalSupply,
|
||||
decimals: t.decimals ? Number(t.decimals) : undefined,
|
||||
};
|
||||
}
|
||||
async tokenBalanceSingle(address, token, tokenIds) {
|
||||
if ('error' in token)
|
||||
return token;
|
||||
if (token.abi === 'ERC20') {
|
||||
const balance = await (0, index_ts_1.createContract)(index_ts_1.ERC20, this, token.contract).balanceOf.call(address);
|
||||
if (tokenIds && (tokenIds.size > 1 || Array.from(tokenIds)[0] !== 1n)) {
|
||||
return { contract: token.contract, error: 'unexpected tokenIds for ERC20' };
|
||||
}
|
||||
return new Map([[1n, balance]]);
|
||||
}
|
||||
else if (token.abi === 'ERC721') {
|
||||
const c = (0, index_ts_1.createContract)(index_ts_1.ERC721, this, token.contract);
|
||||
const balance = await c.balanceOf.call(address);
|
||||
if (!token.enumerable) {
|
||||
if (!tokenIds) {
|
||||
if (!balance)
|
||||
return new Map(); // no tokens owned by user
|
||||
return {
|
||||
contract: token.contract,
|
||||
error: 'erc721 contract not enumerable, but owner has ' + balance + ' tokens',
|
||||
};
|
||||
}
|
||||
// if we cannot enumerate, but has tokenIds, we can check if tokenIds still owned by account
|
||||
const ids = Array.from(tokenIds);
|
||||
const owners = await Promise.all(ids.map((i) => c.ownerOf.call(i)));
|
||||
return new Map(ids.map((i, j) => [i, owners[j].toLowerCase() === address.toLowerCase() ? 1n : 0n]));
|
||||
}
|
||||
// if we can fetch tokenIds: always do this
|
||||
const p = [];
|
||||
for (let i = 0; i < balance; i++)
|
||||
p.push(c.tokenOfOwnerByIndex.call({ owner: address, index: BigInt(i) }));
|
||||
tokenIds = new Set(await Promise.all(p));
|
||||
const ids = Array.from(tokenIds);
|
||||
return new Map(ids.map((i) => [i, 1n]));
|
||||
}
|
||||
else if (token.abi === 'ERC1155') {
|
||||
// This is pretty bad standard, because it doesn't allow enumeration of tokenIds for owner
|
||||
if (!tokenIds)
|
||||
return { contract: token.contract, error: 'cannot fetch erc1155 without tokenIds' };
|
||||
const c = (0, index_ts_1.createContract)(index_ts_1.ERC1155, this, token.contract);
|
||||
const ids = Array.from(tokenIds);
|
||||
const balances = await c.balanceOfBatch.call({ accounts: ids.map((_) => address), ids });
|
||||
const res = new Map(ids.map((i, j) => [i, balances[j]]));
|
||||
return res;
|
||||
}
|
||||
throw new Error('unknown token type');
|
||||
}
|
||||
async tokenURI(token, tokenId) {
|
||||
if (typeof token === 'string')
|
||||
token = await this.tokenInfo(token);
|
||||
if ('error' in token)
|
||||
return token;
|
||||
if (token.abi === 'ERC721') {
|
||||
const c = (0, index_ts_1.createContract)(index_ts_1.ERC721, this, token.contract);
|
||||
if (!token.metadata)
|
||||
return { contract: token.contract, error: 'erc721 without metadata' };
|
||||
return c.tokenURI.call(tokenId);
|
||||
}
|
||||
else if (token.abi === 'ERC1155') {
|
||||
const c = (0, index_ts_1.createContract)(index_ts_1.ERC1155, this, token.contract);
|
||||
return c.uri.call(tokenId);
|
||||
}
|
||||
return { contract: token.contract, error: 'not supported token type' };
|
||||
}
|
||||
async tokenBalances(address, tokens, tokenIds) {
|
||||
// New API requires data from tokenInfo (which is slow and should be cached).
|
||||
// But for compat with old API, we do tokenInfo call if contract address (as string) presented
|
||||
const _tokens = await Promise.all(tokens.map((i) => (typeof i === 'string' ? this.tokenInfo(i) : i)));
|
||||
const balances = await Promise.all(_tokens.map((i) => this.tokenBalanceSingle(address, i, tokenIds && tokenIds[i.contract])));
|
||||
return Object.fromEntries(_tokens.map((i, j) => [i.contract, balances[j]]));
|
||||
}
|
||||
decodeTokenTransfer(token, log) {
|
||||
if ('error' in token)
|
||||
return;
|
||||
if (token.abi === 'ERC20') {
|
||||
try {
|
||||
const decoded = ERC_TRANSFER.decode(log.topics, log.data);
|
||||
return {
|
||||
...token,
|
||||
contract: log.address,
|
||||
to: decoded.to,
|
||||
from: decoded.from,
|
||||
tokens: new Map([[1n, decoded.value]]),
|
||||
};
|
||||
}
|
||||
catch (e) { }
|
||||
// Weth doesn't issue Transfer event on Deposit/Withdrawal
|
||||
// NOTE: we don't filter for WETH_CONTRACT here in case of other contracts with similar API or different networks
|
||||
try {
|
||||
const decoded = WETH_DEPOSIT.decode(log.topics, log.data);
|
||||
return {
|
||||
...token,
|
||||
contract: log.address,
|
||||
from: log.address,
|
||||
to: decoded.dst,
|
||||
tokens: new Map([[1n, decoded.wad]]),
|
||||
};
|
||||
}
|
||||
catch (e) { }
|
||||
try {
|
||||
const decoded = WETH_WITHDRAW.decode(log.topics, log.data);
|
||||
return {
|
||||
...token,
|
||||
contract: log.address,
|
||||
from: decoded.src,
|
||||
to: log.address,
|
||||
tokens: new Map([[1n, decoded.wad]]),
|
||||
};
|
||||
}
|
||||
catch (e) { }
|
||||
}
|
||||
else if (token.abi === 'ERC721') {
|
||||
try {
|
||||
const decoded = ERC721_TRANSFER.decode(log.topics, log.data);
|
||||
return {
|
||||
...token,
|
||||
from: decoded.from,
|
||||
to: decoded.to,
|
||||
tokens: new Map([[decoded.tokenId, 1n]]),
|
||||
};
|
||||
}
|
||||
catch (e) { }
|
||||
}
|
||||
else if (token.abi === 'ERC1155') {
|
||||
try {
|
||||
const decoded = ERC1155_SINGLE.decode(log.topics, log.data);
|
||||
return {
|
||||
...token,
|
||||
from: decoded.from,
|
||||
to: decoded.to,
|
||||
tokens: new Map([[decoded.id, decoded.value]]),
|
||||
};
|
||||
}
|
||||
catch (e) { }
|
||||
try {
|
||||
const decoded = ERC1155_BATCH.decode(log.topics, log.data);
|
||||
return {
|
||||
...token,
|
||||
from: decoded.from,
|
||||
to: decoded.to,
|
||||
tokens: new Map(decoded.ids.map((i, j) => [i, decoded.values[j]])),
|
||||
};
|
||||
}
|
||||
catch (e) { }
|
||||
}
|
||||
return; // unknown token type
|
||||
}
|
||||
// We want to get all transactions related to address, that means:
|
||||
// - from or to equals address in tx
|
||||
// - any internal tx from or to equals address in tx
|
||||
// - any erc20 token transfer which hash address in src or dst
|
||||
// - erc721 is exactly same function signature as erc20 (need to detect after getting transactions)
|
||||
// - erc1155: from/to + single/batch
|
||||
// trace_filter (web3) returns information only for first two cases, most of explorers returns only first case.
|
||||
async transfers(address, opts = {}) {
|
||||
const txCache = {};
|
||||
const blockCache = {};
|
||||
const tokenCache = {};
|
||||
const _opts = {
|
||||
...opts,
|
||||
txCallback: (txHash) => {
|
||||
if (txCache[txHash])
|
||||
return;
|
||||
txCache[txHash] = this.txInfo(txHash, opts);
|
||||
},
|
||||
blockCallback: (blockNumber) => {
|
||||
if (blockCache[blockNumber])
|
||||
return;
|
||||
blockCache[blockNumber] = this.blockInfo(blockNumber);
|
||||
},
|
||||
contractCallback: (address) => {
|
||||
if (tokenCache[address])
|
||||
return;
|
||||
tokenCache[address] = this.tokenInfo(address);
|
||||
},
|
||||
};
|
||||
if (!_opts.fromBlock)
|
||||
_opts.fromBlock = 0;
|
||||
// This runs in parallel and executes callbacks
|
||||
// Note, we ignore logs and weth, but they will call callbacks and fetch related
|
||||
const [actions, _logs, _weth] = await Promise.all([
|
||||
this.internalTransactions(address, _opts),
|
||||
this.tokenTransfers(address, _opts),
|
||||
this.wethTransfers(address, _opts),
|
||||
this.erc1155Transfers(address, _opts),
|
||||
]);
|
||||
const mapCache = async (cache) => {
|
||||
const keys = Object.keys(cache);
|
||||
const values = await Promise.all(Object.values(cache));
|
||||
return Object.fromEntries(values.map((v, i) => [keys[i], v]));
|
||||
};
|
||||
// it is ok to do this sequentially, since promises already started and probably resolved at this point
|
||||
const blocks = await mapCache(blockCache);
|
||||
const tx = await mapCache(txCache);
|
||||
const tokens = await mapCache(tokenCache);
|
||||
const actionPerTx = group(actions, 'transactionHash');
|
||||
// Sort transactions by [blockNumber, transactionIndex]
|
||||
const _txHashes = Object.entries(tx).map(([k, v]) => [k, v.info.blockNumber, v.info.transactionIndex]);
|
||||
_txHashes.sort((a, b) => (a[1] !== b[1] ? a[1] - b[1] : a[2] - b[2]));
|
||||
const txHashes = _txHashes.map((i) => i[0]);
|
||||
return txHashes.map((txHash) => {
|
||||
const { info, receipt } = tx[txHash];
|
||||
const actions = actionPerTx[txHash];
|
||||
const block = info.blockNumber !== null ? blocks[info.blockNumber] : undefined;
|
||||
const transfers = [];
|
||||
if (actions) {
|
||||
for (const a of actions)
|
||||
transfers.push({ from: a.action.from, to: a.action.to, value: a.action.value });
|
||||
}
|
||||
else {
|
||||
// If we have action, it was call to contract and transfer from tx is already added
|
||||
transfers.push({ from: info.from, to: info.to, value: info.value });
|
||||
}
|
||||
// cumulativeGasUsed includes all transactions before that in block, so useless. gasUsed is correct even for internal transactions
|
||||
transfers.push({ from: info.from, value: receipt.gasUsed * receipt.effectiveGasPrice });
|
||||
// Tokens
|
||||
const tokenTransfers = [];
|
||||
for (const log of receipt.logs) {
|
||||
const tokenInfo = tokens[log.address];
|
||||
if (!tokenInfo)
|
||||
continue;
|
||||
const tt = this.decodeTokenTransfer(tokenInfo, log);
|
||||
if (tt)
|
||||
tokenTransfers.push(tt);
|
||||
}
|
||||
return {
|
||||
hash: txHash,
|
||||
timestamp: block.timestamp,
|
||||
block: info.blockNumber !== null ? info.blockNumber : undefined,
|
||||
reverted: !receipt.status,
|
||||
transfers,
|
||||
tokenTransfers,
|
||||
info: { ...tx[txHash], block, actions },
|
||||
};
|
||||
});
|
||||
}
|
||||
async allowances(address, opts = {}) {
|
||||
const approval = (0, index_ts_1.events)(index_ts_1.ERC20).Approval;
|
||||
// ERC-721/ERC-1155: +ApprovalForAll
|
||||
// ERC-1761 Scoped Approval for partial with 1155/721?
|
||||
const topics = approval.topics({ owner: address, spender: null, value: null });
|
||||
const logs = await this.ethLogs(topics, opts);
|
||||
// res[tokenContract][spender] = value
|
||||
const res = {};
|
||||
for (const l of logs) {
|
||||
const decoded = approval.decode(l.topics, l.data);
|
||||
if (decoded.owner.toLowerCase() !== address.toLowerCase())
|
||||
continue;
|
||||
if (!res[l.address])
|
||||
res[l.address] = {};
|
||||
res[l.address][decoded.spender] = decoded.value;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
exports.Web3Provider = Web3Provider;
|
||||
/**
|
||||
* Calculates balances at specific point in time after tx.
|
||||
* Also, useful as a sanity check in case we've missed something.
|
||||
* Info from multiple addresses can be merged (sort everything first).
|
||||
*/
|
||||
function calcTransfersDiff(transfers) {
|
||||
// address -> balance
|
||||
const balances = {};
|
||||
// contract -> address -> tokenId -> balance
|
||||
const tokenBalances = {};
|
||||
let _0 = BigInt(0);
|
||||
for (const t of transfers) {
|
||||
for (const it of t.transfers) {
|
||||
if (it.from) {
|
||||
if (balances[it.from] === undefined)
|
||||
balances[it.from] = _0;
|
||||
balances[it.from] -= it.value;
|
||||
}
|
||||
if (it.to) {
|
||||
if (balances[it.to] === undefined)
|
||||
balances[it.to] = _0;
|
||||
balances[it.to] += it.value;
|
||||
}
|
||||
}
|
||||
for (const tt of t.tokenTransfers) {
|
||||
if (!tokenBalances[tt.contract])
|
||||
tokenBalances[tt.contract] = {};
|
||||
const token = tokenBalances[tt.contract];
|
||||
for (const [tokenId, value] of tt.tokens) {
|
||||
if (token[tt.from] === undefined)
|
||||
token[tt.from] = new Map();
|
||||
if (token[tt.to] === undefined)
|
||||
token[tt.to] = new Map();
|
||||
const fromTokens = token[tt.from];
|
||||
const toTokens = token[tt.to];
|
||||
fromTokens.set(tokenId, (fromTokens.get(tokenId) || _0) - value);
|
||||
toTokens.set(tokenId, (toTokens.get(tokenId) || _0) + value);
|
||||
}
|
||||
}
|
||||
Object.assign(t, {
|
||||
balances: { ...balances },
|
||||
// deep copy
|
||||
tokenBalances: Object.fromEntries(Object.entries(tokenBalances).map(([k, v]) => [k, { ...v }])),
|
||||
});
|
||||
}
|
||||
return transfers;
|
||||
}
|
||||
//# sourceMappingURL=archive.js.map
|
||||
1
dev/env/node_modules/micro-eth-signer/net/archive.js.map
generated
vendored
Executable file
1
dev/env/node_modules/micro-eth-signer/net/archive.js.map
generated
vendored
Executable file
File diff suppressed because one or more lines are too long
14
dev/env/node_modules/micro-eth-signer/net/chainlink.d.ts
generated
vendored
Executable file
14
dev/env/node_modules/micro-eth-signer/net/chainlink.d.ts
generated
vendored
Executable file
@@ -0,0 +1,14 @@
|
||||
import { type IWeb3Provider } from '../utils.ts';
|
||||
export declare const TOKENS: Record<string, {
|
||||
decimals: number;
|
||||
contract: string;
|
||||
tokenContract: string;
|
||||
}>;
|
||||
export default class Chainlink {
|
||||
readonly net: IWeb3Provider;
|
||||
constructor(net: IWeb3Provider);
|
||||
price(contract: string, decimals: number): Promise<number>;
|
||||
coinPrice(symbol: string): Promise<number>;
|
||||
tokenPrice(symbol: string): Promise<number>;
|
||||
}
|
||||
//# sourceMappingURL=chainlink.d.ts.map
|
||||
1
dev/env/node_modules/micro-eth-signer/net/chainlink.d.ts.map
generated
vendored
Executable file
1
dev/env/node_modules/micro-eth-signer/net/chainlink.d.ts.map
generated
vendored
Executable file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"chainlink.d.ts","sourceRoot":"","sources":["../src/net/chainlink.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,aAAa,EAAiB,MAAM,aAAa,CAAC;AAgBhE,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAuQ9F,CAAC;AAEJ,MAAM,CAAC,OAAO,OAAO,SAAS;IAC5B,QAAQ,CAAC,GAAG,EAAE,aAAa,CAAC;gBAChB,GAAG,EAAE,aAAa;IAGxB,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQ1D,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAe1C,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAKlD"}
|
||||
317
dev/env/node_modules/micro-eth-signer/net/chainlink.js
generated
vendored
Executable file
317
dev/env/node_modules/micro-eth-signer/net/chainlink.js
generated
vendored
Executable file
@@ -0,0 +1,317 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.TOKENS = void 0;
|
||||
const index_ts_1 = require("../abi/index.js");
|
||||
const utils_ts_1 = require("../utils.js");
|
||||
const ABI = [
|
||||
{
|
||||
type: 'function',
|
||||
name: 'latestRoundData',
|
||||
outputs: [
|
||||
{ name: 'roundId', type: 'uint80' },
|
||||
{ name: 'answer', type: 'int256' },
|
||||
{ name: 'startedAt', type: 'uint256' },
|
||||
{ name: 'updatedAt', type: 'uint256' },
|
||||
{ name: 'answeredInRound', type: 'uint80' },
|
||||
],
|
||||
},
|
||||
];
|
||||
exports.TOKENS = {
|
||||
'1INCH': {
|
||||
decimals: 8,
|
||||
contract: '0xc929ad75b72593967de83e7f7cda0493458261d9',
|
||||
tokenContract: '0x111111111117dc0aa78b770fa6a738034120c302',
|
||||
},
|
||||
AAPL: {
|
||||
decimals: 8,
|
||||
contract: '0x139c8512cde1778e9b9a8e721ce1aebd4dd43587',
|
||||
tokenContract: '0x7edc9e8a1196259b7c6aba632037a9443d4e14f7',
|
||||
},
|
||||
AAVE: {
|
||||
decimals: 8,
|
||||
contract: '0x547a514d5e3769680ce22b2361c10ea13619e8a9',
|
||||
tokenContract: '0x7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9',
|
||||
},
|
||||
ADX: {
|
||||
decimals: 8,
|
||||
contract: '0x231e764b44b2c1b7ca171fa8021a24ed520cde10',
|
||||
tokenContract: '0x4470bb87d77b963a013db939be332f927f2b992e',
|
||||
},
|
||||
AKRO: {
|
||||
decimals: 8,
|
||||
contract: '0xb23d105df4958b4b81757e12f2151b5b5183520b',
|
||||
tokenContract: '0x8ab7404063ec4dbcfd4598215992dc3f8ec853d7',
|
||||
},
|
||||
AMP: {
|
||||
decimals: 8,
|
||||
contract: '0x8797abc4641de76342b8ace9c63e3301dc35e3d8',
|
||||
tokenContract: '0xff20817765cb7f73d4bde2e66e067e58d11095c2',
|
||||
},
|
||||
AMPL: {
|
||||
decimals: 18,
|
||||
contract: '0xe20ca8d7546932360e37e9d72c1a47334af57706',
|
||||
tokenContract: '0xd46ba6d942050d489dbd938a2c909a5d5039a161',
|
||||
},
|
||||
AMZN: {
|
||||
decimals: 8,
|
||||
contract: '0x8994115d287207144236c13be5e2bdbf6357d9fd',
|
||||
tokenContract: '0xd6a073d973f95b7ce2ecf2b19224fa12103cf460',
|
||||
},
|
||||
ANKR: {
|
||||
decimals: 8,
|
||||
contract: '0x7eed379bf00005cfed29fed4009669de9bcc21ce',
|
||||
tokenContract: '0x8290333cef9e6d528dd5618fb97a76f268f3edd4',
|
||||
},
|
||||
BADGER: {
|
||||
decimals: 8,
|
||||
contract: '0x66a47b7206130e6ff64854ef0e1edfa237e65339',
|
||||
tokenContract: '0x3472a5a71965499acd81997a54bba8d852c6e53d',
|
||||
},
|
||||
BAND: {
|
||||
decimals: 8,
|
||||
contract: '0x919c77acc7373d000b329c1276c76586ed2dd19f',
|
||||
tokenContract: '0xba11d00c5f74255f56a5e366f4f77f5a186d7f55',
|
||||
},
|
||||
BAT: {
|
||||
decimals: 8,
|
||||
contract: '0x9441d7556e7820b5ca42082cfa99487d56aca958',
|
||||
tokenContract: '0x0d8775f648430679a709e98d2b0cb6250d2887ef',
|
||||
},
|
||||
BNB: {
|
||||
decimals: 8,
|
||||
contract: '0x14e613ac84a31f709eadbdf89c6cc390fdc9540a',
|
||||
tokenContract: '0xb8c77482e45f1f44de1745f52c74426c631bdd52',
|
||||
},
|
||||
BNT: {
|
||||
decimals: 8,
|
||||
contract: '0x1e6cf0d433de4fe882a437abc654f58e1e78548c',
|
||||
tokenContract: '0x1f573d6fb3f13d689ff844b4ce37794d79a7ff1c',
|
||||
},
|
||||
BTM: {
|
||||
decimals: 8,
|
||||
contract: '0x9fccf42d21ab278e205e7bb310d8979f8f4b5751',
|
||||
tokenContract: '0xcb97e65f07da24d46bcdd078ebebd7c6e6e3d750',
|
||||
},
|
||||
BUSD: {
|
||||
decimals: 8,
|
||||
contract: '0x833d8eb16d306ed1fbb5d7a2e019e106b960965a',
|
||||
tokenContract: '0x4fabb145d64652a948d72533023f6e7a623c7c53',
|
||||
},
|
||||
COMP: {
|
||||
decimals: 8,
|
||||
contract: '0xdbd020caef83efd542f4de03e3cf0c28a4428bd5',
|
||||
tokenContract: '0xc00e94cb662c3520282e6f5717214004a7f26888',
|
||||
},
|
||||
COVER: {
|
||||
decimals: 8,
|
||||
contract: '0x0ad50393f11ffac4dd0fe5f1056448ecb75226cf',
|
||||
tokenContract: '0x4688a8b1f292fdab17e9a90c8bc379dc1dbd8713',
|
||||
},
|
||||
CRO: {
|
||||
decimals: 8,
|
||||
contract: '0x00cb80cf097d9aa9a3779ad8ee7cf98437eae050',
|
||||
tokenContract: '0xa0b73e1ff0b80914ab6fe0444e65848c4c34450b',
|
||||
},
|
||||
CRV: {
|
||||
decimals: 8,
|
||||
contract: '0xcd627aa160a6fa45eb793d19ef54f5062f20f33f',
|
||||
tokenContract: '0xd533a949740bb3306d119cc777fa900ba034cd52',
|
||||
},
|
||||
DAI: {
|
||||
decimals: 8,
|
||||
contract: '0xaed0c38402a5d19df6e4c03f4e2dced6e29c1ee9',
|
||||
tokenContract: '0x60d9564303c70d3f040ea9393d98d94f767d020c',
|
||||
},
|
||||
DPI: {
|
||||
decimals: 8,
|
||||
contract: '0xd2a593bf7594ace1fad597adb697b5645d5eddb2',
|
||||
tokenContract: '0x1494ca1f11d487c2bbe4543e90080aeba4ba3c2b',
|
||||
},
|
||||
EOS: {
|
||||
decimals: 8,
|
||||
contract: '0x10a43289895eaff840e8d45995bba89f9115ecee',
|
||||
tokenContract: '0x86fa049857e0209aa7d9e616f7eb3b3b78ecfdb0',
|
||||
},
|
||||
FXS: {
|
||||
decimals: 8,
|
||||
contract: '0x6ebc52c8c1089be9eb3945c4350b68b8e4c2233f',
|
||||
tokenContract: '0x3432b6a60d23ca0dfca7761b7ab56459d9c964d0',
|
||||
},
|
||||
HT: {
|
||||
decimals: 8,
|
||||
contract: '0xe1329b3f6513912caf589659777b66011aee5880',
|
||||
tokenContract: '0x6f259637dcd74c767781e37bc6133cd6a68aa161',
|
||||
},
|
||||
IOST: {
|
||||
decimals: 8,
|
||||
contract: '0xd0935838935349401c73a06fcde9d63f719e84e5',
|
||||
tokenContract: '0xfa1a856cfa3409cfa145fa4e20eb270df3eb21ab',
|
||||
},
|
||||
KNC: {
|
||||
decimals: 8,
|
||||
contract: '0xf8ff43e991a81e6ec886a3d281a2c6cc19ae70fc',
|
||||
tokenContract: '0xdd974d5c2e2928dea5f71b9825b8b646686bd200',
|
||||
},
|
||||
LINK: {
|
||||
decimals: 8,
|
||||
contract: '0x2c1d072e956affc0d435cb7ac38ef18d24d9127c',
|
||||
tokenContract: '0x514910771af9ca656af840dff83e8264ecf986ca',
|
||||
},
|
||||
LRC: {
|
||||
decimals: 8,
|
||||
contract: '0xfd33ec6abaa1bdc3d9c6c85f1d6299e5a1a5511f',
|
||||
tokenContract: '0xef68e7c694f40c8202821edf525de3782458639f',
|
||||
},
|
||||
MATIC: {
|
||||
decimals: 8,
|
||||
contract: '0x7bac85a8a13a4bcd8abb3eb7d6b4d632c5a57676',
|
||||
tokenContract: '0x7d1afa7b718fb893db30a3abc0cfc608aacfebb0',
|
||||
},
|
||||
MKR: {
|
||||
decimals: 8,
|
||||
contract: '0xec1d1b3b0443256cc3860e24a46f108e699484aa',
|
||||
tokenContract: '0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2',
|
||||
},
|
||||
MTA: {
|
||||
decimals: 8,
|
||||
contract: '0xc751e86208f0f8af2d5cd0e29716ca7ad98b5ef5',
|
||||
tokenContract: '0xa3bed4e1c75d00fa6f4e5e6922db7261b5e9acd2',
|
||||
},
|
||||
NFLX: {
|
||||
decimals: 8,
|
||||
contract: '0x67c2e69c5272b94af3c90683a9947c39dc605dde',
|
||||
tokenContract: '0x0a3dc37762f0102175fd43d3871d7fa855626146',
|
||||
},
|
||||
NMR: {
|
||||
decimals: 8,
|
||||
contract: '0xcc445b35b3636bc7cc7051f4769d8982ed0d449a',
|
||||
tokenContract: '0x1776e1f26f98b1a5df9cd347953a26dd3cb46671',
|
||||
},
|
||||
OCEAN: {
|
||||
decimals: 8,
|
||||
contract: '0x7ece4e4e206ed913d991a074a19c192142726797',
|
||||
tokenContract: '0x967da4048cd07ab37855c090aaf366e4ce1b9f48',
|
||||
},
|
||||
OKB: {
|
||||
decimals: 8,
|
||||
contract: '0x22134617ae0f6ca8d89451e5ae091c94f7d743dc',
|
||||
tokenContract: '0x75231f58b43240c9718dd58b4967c5114342a86c',
|
||||
},
|
||||
OMG: {
|
||||
decimals: 8,
|
||||
contract: '0x7d476f061f8212a8c9317d5784e72b4212436e93',
|
||||
tokenContract: '0xd26114cd6ee289accf82350c8d8487fedb8a0c07',
|
||||
},
|
||||
OXT: {
|
||||
decimals: 8,
|
||||
contract: '0xd75aaae4af0c398ca13e2667be57af2cca8b5de6',
|
||||
tokenContract: '0x4575f41308ec1483f3d399aa9a2826d74da13deb',
|
||||
},
|
||||
REN: {
|
||||
decimals: 8,
|
||||
contract: '0x0f59666ede214281e956cb3b2d0d69415aff4a01',
|
||||
tokenContract: '0x408e41876cccdc0f92210600ef50372656052a38',
|
||||
},
|
||||
SAND: {
|
||||
decimals: 8,
|
||||
contract: '0x35e3f7e558c04ce7eee1629258ecbba03b36ec56',
|
||||
tokenContract: '0x3845badade8e6dff049820680d1f14bd3903a5d0',
|
||||
},
|
||||
SNX: {
|
||||
decimals: 8,
|
||||
contract: '0xdc3ea94cd0ac27d9a86c180091e7f78c683d3699',
|
||||
tokenContract: '0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f',
|
||||
},
|
||||
SUSHI: {
|
||||
decimals: 8,
|
||||
contract: '0xcc70f09a6cc17553b2e31954cd36e4a2d89501f7',
|
||||
tokenContract: '0x6b3595068778dd592e39a122f4f5a5cf09c90fe2',
|
||||
},
|
||||
SXP: {
|
||||
decimals: 8,
|
||||
contract: '0xfb0cfd6c19e25db4a08d8a204a387cea48cc138f',
|
||||
tokenContract: '0x8ce9137d39326ad0cd6491fb5cc0cba0e089b6a9',
|
||||
},
|
||||
UNI: {
|
||||
decimals: 8,
|
||||
contract: '0x553303d460ee0afb37edff9be42922d8ff63220e',
|
||||
tokenContract: '0x1f9840a85d5af5bf1d1762f925bdaddc4201f984',
|
||||
},
|
||||
USDC: {
|
||||
decimals: 8,
|
||||
contract: '0x8fffffd4afb6115b954bd326cbe7b4ba576818f6',
|
||||
tokenContract: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
|
||||
},
|
||||
USDK: {
|
||||
decimals: 8,
|
||||
contract: '0xfac81ea9dd29d8e9b212acd6edbeb6de38cb43af',
|
||||
tokenContract: '0x1c48f86ae57291f7686349f12601910bd8d470bb',
|
||||
},
|
||||
USDT: {
|
||||
decimals: 8,
|
||||
contract: '0x3e7d1eab13ad0104d2750b8863b489d65364e32d',
|
||||
tokenContract: '0xdac17f958d2ee523a2206206994597c13d831ec7',
|
||||
},
|
||||
YFI: {
|
||||
decimals: 8,
|
||||
contract: '0xa027702dbb89fbd58938e4324ac03b58d812b0e1',
|
||||
tokenContract: '0x0bc529c00c6401aef6d220be8c6ea1667f6ad93e',
|
||||
},
|
||||
ZRX: {
|
||||
decimals: 8,
|
||||
contract: '0x2885d15b8af22648b98b122b22fdf4d2a56c6023',
|
||||
tokenContract: '0xe41d2489571d322189246dafa5ebde1f4699f498',
|
||||
},
|
||||
SUSD: {
|
||||
decimals: 8,
|
||||
contract: '0xad35bd71b9afe6e4bdc266b345c198eadef9ad94',
|
||||
tokenContract: '0x57ab1e02fee23774580c119740129eac7081e9d3',
|
||||
},
|
||||
// Wrapped tokens uses price of original coin
|
||||
WBTC: {
|
||||
decimals: 8,
|
||||
contract: '0xf4030086522a5beea4988f8ca5b36dbc97bee88c',
|
||||
tokenContract: (0, index_ts_1.tokenFromSymbol)('WBTC').contract,
|
||||
},
|
||||
WETH: {
|
||||
decimals: 8,
|
||||
contract: '0x5f4ec3df9cbd43714fe2740f5e3616155c5b8419',
|
||||
tokenContract: (0, index_ts_1.tokenFromSymbol)('WETH').contract,
|
||||
},
|
||||
};
|
||||
class Chainlink {
|
||||
constructor(net) {
|
||||
this.net = net;
|
||||
}
|
||||
async price(contract, decimals) {
|
||||
const prices = (0, index_ts_1.createContract)(ABI, this.net, contract);
|
||||
let res = await prices.latestRoundData.call();
|
||||
const num = Number.parseFloat((0, utils_ts_1.createDecimal)(decimals).encode(res.answer));
|
||||
if (Number.isNaN(num))
|
||||
throw new Error('invalid data received');
|
||||
return num;
|
||||
}
|
||||
async coinPrice(symbol) {
|
||||
// Only common coins
|
||||
const COINS = {
|
||||
BCH: { decimals: 8, contract: '0x9f0f69428f923d6c95b781f89e165c9b2df9789d' },
|
||||
BTC: { decimals: 8, contract: '0xf4030086522a5beea4988f8ca5b36dbc97bee88c' },
|
||||
DOGE: { decimals: 8, contract: '0x2465cefd3b488be410b941b1d4b2767088e2a028' },
|
||||
ETH: { decimals: 8, contract: '0x5f4ec3df9cbd43714fe2740f5e3616155c5b8419' },
|
||||
XMR: { decimals: 8, contract: '0xfa66458cce7dd15d8650015c4fce4d278271618f' },
|
||||
ZEC: { decimals: 8, contract: '0xd54b033d48d0475f19c5fccf7484e8a981848501' },
|
||||
};
|
||||
const coin = COINS[symbol.toUpperCase()];
|
||||
if (!coin)
|
||||
throw new Error(`micro-web3/chainlink: unknown coin: ${symbol}`);
|
||||
return await this.price(coin.contract, coin.decimals);
|
||||
}
|
||||
async tokenPrice(symbol) {
|
||||
const token = exports.TOKENS[symbol.toUpperCase()];
|
||||
if (!token)
|
||||
throw new Error(`micro-web3/chainlink: unknown token: ${symbol}`);
|
||||
return await this.price(token.contract, token.decimals);
|
||||
}
|
||||
}
|
||||
exports.default = Chainlink;
|
||||
//# sourceMappingURL=chainlink.js.map
|
||||
1
dev/env/node_modules/micro-eth-signer/net/chainlink.js.map
generated
vendored
Executable file
1
dev/env/node_modules/micro-eth-signer/net/chainlink.js.map
generated
vendored
Executable file
File diff suppressed because one or more lines are too long
44
dev/env/node_modules/micro-eth-signer/net/ens.d.ts
generated
vendored
Executable file
44
dev/env/node_modules/micro-eth-signer/net/ens.d.ts
generated
vendored
Executable file
@@ -0,0 +1,44 @@
|
||||
import { type IWeb3Provider } from '../utils.ts';
|
||||
export declare function namehash(address: string): Uint8Array;
|
||||
export default class ENS {
|
||||
static ADDRESS_ZERO: string;
|
||||
static REGISTRY: string;
|
||||
static REGISTRY_CONTRACT: readonly [{
|
||||
readonly name: "resolver";
|
||||
readonly type: "function";
|
||||
readonly inputs: readonly [{
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}];
|
||||
readonly outputs: readonly [{
|
||||
readonly type: "address";
|
||||
}];
|
||||
}];
|
||||
static RESOLVER_CONTRACT: readonly [{
|
||||
readonly name: "addr";
|
||||
readonly type: "function";
|
||||
readonly inputs: readonly [{
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}];
|
||||
readonly outputs: readonly [{
|
||||
readonly type: "address";
|
||||
}];
|
||||
}, {
|
||||
readonly name: "name";
|
||||
readonly type: "function";
|
||||
readonly inputs: readonly [{
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}];
|
||||
readonly outputs: readonly [{
|
||||
readonly type: "string";
|
||||
}];
|
||||
}];
|
||||
readonly net: IWeb3Provider;
|
||||
constructor(net: IWeb3Provider);
|
||||
getResolver(name: string): Promise<string | undefined>;
|
||||
nameToAddress(name: string): Promise<string | undefined>;
|
||||
addressToName(address: string): Promise<string | undefined>;
|
||||
}
|
||||
//# sourceMappingURL=ens.d.ts.map
|
||||
1
dev/env/node_modules/micro-eth-signer/net/ens.d.ts.map
generated
vendored
Executable file
1
dev/env/node_modules/micro-eth-signer/net/ens.d.ts.map
generated
vendored
Executable file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"ens.d.ts","sourceRoot":"","sources":["../src/net/ens.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,aAAa,EAAW,MAAM,aAAa,CAAC;AAG1D,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CAMpD;AAED,MAAM,CAAC,OAAO,OAAO,GAAG;IACtB,MAAM,CAAC,YAAY,SAAgD;IACnE,MAAM,CAAC,QAAQ,SAAgD;IAC/D,MAAM,CAAC,iBAAiB;;;;;;;;;;OAOb;IACX,MAAM,CAAC,iBAAiB;;;;;;;;;;;;;;;;;;;;OAab;IAEX,QAAQ,CAAC,GAAG,EAAE,aAAa,CAAC;gBAChB,GAAG,EAAE,aAAa;IAGxB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAOtD,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IASxD,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;CAelE"}
|
||||
82
dev/env/node_modules/micro-eth-signer/net/ens.js
generated
vendored
Executable file
82
dev/env/node_modules/micro-eth-signer/net/ens.js
generated
vendored
Executable file
@@ -0,0 +1,82 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.namehash = namehash;
|
||||
const sha3_1 = require("@noble/hashes/sha3");
|
||||
const utils_1 = require("@noble/hashes/utils");
|
||||
const decoder_ts_1 = require("../abi/decoder.js");
|
||||
const utils_ts_1 = require("../utils.js");
|
||||
// No support for IDN names
|
||||
function namehash(address) {
|
||||
let res = new Uint8Array(32);
|
||||
if (!address)
|
||||
return res;
|
||||
for (let label of address.split('.').reverse())
|
||||
res = (0, sha3_1.keccak_256)((0, utils_1.concatBytes)(res, (0, sha3_1.keccak_256)(label)));
|
||||
return res;
|
||||
}
|
||||
class ENS {
|
||||
constructor(net) {
|
||||
this.net = net;
|
||||
}
|
||||
async getResolver(name) {
|
||||
const contract = (0, decoder_ts_1.createContract)(ENS.REGISTRY_CONTRACT, this.net, ENS.REGISTRY);
|
||||
const res = await contract.resolver.call(namehash(name));
|
||||
if (res === ENS.ADDRESS_ZERO)
|
||||
return;
|
||||
return res;
|
||||
}
|
||||
async nameToAddress(name) {
|
||||
const resolver = await this.getResolver(name);
|
||||
if (!resolver)
|
||||
return;
|
||||
const contract = (0, decoder_ts_1.createContract)(ENS.RESOLVER_CONTRACT, this.net, resolver);
|
||||
const addr = await contract.addr.call(namehash(name));
|
||||
if (addr === ENS.ADDRESS_ZERO)
|
||||
return;
|
||||
return addr;
|
||||
}
|
||||
async addressToName(address) {
|
||||
const addrDomain = `${(0, utils_ts_1.strip0x)(address).toLowerCase()}.addr.reverse`;
|
||||
const resolver = await this.getResolver(addrDomain);
|
||||
if (!resolver)
|
||||
return;
|
||||
const contract = (0, decoder_ts_1.createContract)(ENS.RESOLVER_CONTRACT, this.net, resolver);
|
||||
const name = await contract.name.call(namehash(addrDomain));
|
||||
if (!name)
|
||||
return;
|
||||
// From spec: ENS does not enforce accuracy of reverse records -
|
||||
// anyone may claim that the name for their address is 'alice.eth'.
|
||||
// To be certain the claim is accurate, you must always perform a forward
|
||||
// resolution for the returned name and check whether it matches the original address.
|
||||
const realAddr = await this.nameToAddress(name);
|
||||
if (realAddr !== address)
|
||||
return;
|
||||
return name;
|
||||
}
|
||||
}
|
||||
ENS.ADDRESS_ZERO = '0x0000000000000000000000000000000000000000';
|
||||
ENS.REGISTRY = '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e';
|
||||
ENS.REGISTRY_CONTRACT = [
|
||||
{
|
||||
name: 'resolver',
|
||||
type: 'function',
|
||||
inputs: [{ name: 'node', type: 'bytes32' }],
|
||||
outputs: [{ type: 'address' }],
|
||||
},
|
||||
];
|
||||
ENS.RESOLVER_CONTRACT = [
|
||||
{
|
||||
name: 'addr',
|
||||
type: 'function',
|
||||
inputs: [{ name: 'node', type: 'bytes32' }],
|
||||
outputs: [{ type: 'address' }],
|
||||
},
|
||||
{
|
||||
name: 'name',
|
||||
type: 'function',
|
||||
inputs: [{ name: 'node', type: 'bytes32' }],
|
||||
outputs: [{ type: 'string' }],
|
||||
},
|
||||
];
|
||||
exports.default = ENS;
|
||||
//# sourceMappingURL=ens.js.map
|
||||
1
dev/env/node_modules/micro-eth-signer/net/ens.js.map
generated
vendored
Executable file
1
dev/env/node_modules/micro-eth-signer/net/ens.js.map
generated
vendored
Executable file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"ens.js","sourceRoot":"","sources":["../src/net/ens.ts"],"names":[],"mappings":";;AAMA,4BAMC;AAZD,6CAAgD;AAChD,+CAAkD;AAClD,kDAAmD;AACnD,0CAA0D;AAE1D,2BAA2B;AAC3B,SAAgB,QAAQ,CAAC,OAAe;IACtC,IAAI,GAAG,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;IAC7B,IAAI,CAAC,OAAO;QAAE,OAAO,GAAG,CAAC;IACzB,KAAK,IAAI,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE;QAC5C,GAAG,GAAG,IAAA,iBAAU,EAAC,IAAA,mBAAW,EAAC,GAAG,EAAE,IAAA,iBAAU,EAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACxD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAqB,GAAG;IA2BtB,YAAY,GAAkB;QAC5B,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACjB,CAAC;IACD,KAAK,CAAC,WAAW,CAAC,IAAY;QAC5B,MAAM,QAAQ,GAAG,IAAA,2BAAc,EAAC,GAAG,CAAC,iBAAiB,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC/E,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QACzD,IAAI,GAAG,KAAK,GAAG,CAAC,YAAY;YAAE,OAAO;QACrC,OAAO,GAAG,CAAC;IACb,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,IAAY;QAC9B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAI,CAAC,QAAQ;YAAE,OAAO;QACtB,MAAM,QAAQ,GAAG,IAAA,2BAAc,EAAC,GAAG,CAAC,iBAAiB,EAAE,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAC3E,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QACtD,IAAI,IAAI,KAAK,GAAG,CAAC,YAAY;YAAE,OAAO;QACtC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,OAAe;QACjC,MAAM,UAAU,GAAG,GAAG,IAAA,kBAAO,EAAC,OAAO,CAAC,CAAC,WAAW,EAAE,eAAe,CAAC;QACpE,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;QACpD,IAAI,CAAC,QAAQ;YAAE,OAAO;QACtB,MAAM,QAAQ,GAAG,IAAA,2BAAc,EAAC,GAAG,CAAC,iBAAiB,EAAE,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAC3E,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;QAC5D,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,gEAAgE;QAChE,mEAAmE;QACnE,yEAAyE;QACzE,sFAAsF;QACtF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAChD,IAAI,QAAQ,KAAK,OAAO;YAAE,OAAO;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;;AA3DM,gBAAY,GAAG,4CAA4C,CAAC;AAC5D,YAAQ,GAAG,4CAA4C,CAAC;AACxD,qBAAiB,GAAG;IACzB;QACE,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,UAAU;QAChB,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAC3C,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;KAC/B;CACO,CAAC;AACJ,qBAAiB,GAAG;IACzB;QACE,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,UAAU;QAChB,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAC3C,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;KAC/B;IACD;QACE,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,UAAU;QAChB,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAC3C,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;KAC9B;CACO,CAAC;kBAxBQ,GAAG"}
|
||||
7
dev/env/node_modules/micro-eth-signer/net/index.d.ts
generated
vendored
Executable file
7
dev/env/node_modules/micro-eth-signer/net/index.d.ts
generated
vendored
Executable file
@@ -0,0 +1,7 @@
|
||||
import { Web3Provider, calcTransfersDiff } from './archive.ts';
|
||||
import Chainlink from './chainlink.ts';
|
||||
import ENS from './ens.ts';
|
||||
import UniswapV2 from './uniswap-v2.ts';
|
||||
import UniswapV3 from './uniswap-v3.ts';
|
||||
export { Chainlink, ENS, UniswapV2, UniswapV3, Web3Provider, calcTransfersDiff };
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
1
dev/env/node_modules/micro-eth-signer/net/index.d.ts.map
generated
vendored
Executable file
1
dev/env/node_modules/micro-eth-signer/net/index.d.ts.map
generated
vendored
Executable file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/net/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,SAAS,MAAM,gBAAgB,CAAC;AACvC,OAAO,GAAG,MAAM,UAAU,CAAC;AAC3B,OAAO,SAAS,MAAM,iBAAiB,CAAC;AACxC,OAAO,SAAS,MAAM,iBAAiB,CAAC;AAGxC,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,iBAAiB,EAAE,CAAC"}
|
||||
15
dev/env/node_modules/micro-eth-signer/net/index.js
generated
vendored
Executable file
15
dev/env/node_modules/micro-eth-signer/net/index.js
generated
vendored
Executable file
@@ -0,0 +1,15 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.calcTransfersDiff = exports.Web3Provider = exports.UniswapV3 = exports.UniswapV2 = exports.ENS = exports.Chainlink = void 0;
|
||||
const archive_ts_1 = require("./archive.js");
|
||||
Object.defineProperty(exports, "Web3Provider", { enumerable: true, get: function () { return archive_ts_1.Web3Provider; } });
|
||||
Object.defineProperty(exports, "calcTransfersDiff", { enumerable: true, get: function () { return archive_ts_1.calcTransfersDiff; } });
|
||||
const chainlink_ts_1 = require("./chainlink.js");
|
||||
exports.Chainlink = chainlink_ts_1.default;
|
||||
const ens_ts_1 = require("./ens.js");
|
||||
exports.ENS = ens_ts_1.default;
|
||||
const uniswap_v2_ts_1 = require("./uniswap-v2.js");
|
||||
exports.UniswapV2 = uniswap_v2_ts_1.default;
|
||||
const uniswap_v3_ts_1 = require("./uniswap-v3.js");
|
||||
exports.UniswapV3 = uniswap_v3_ts_1.default;
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
dev/env/node_modules/micro-eth-signer/net/index.js.map
generated
vendored
Executable file
1
dev/env/node_modules/micro-eth-signer/net/index.js.map
generated
vendored
Executable file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/net/index.ts"],"names":[],"mappings":";;;AAAA,6CAA+D;AAOhB,6FAPtC,yBAAY,OAOsC;AAAE,kGAPtC,8BAAiB,OAOsC;AAN9E,iDAAuC;AAM9B,oBANF,sBAAS,CAME;AALlB,qCAA2B;AAKP,cALb,gBAAG,CAKa;AAJvB,mDAAwC;AAIf,oBAJlB,uBAAS,CAIkB;AAHlC,mDAAwC;AAGJ,oBAH7B,uBAAS,CAG6B"}
|
||||
72
dev/env/node_modules/micro-eth-signer/net/uniswap-common.d.ts
generated
vendored
Executable file
72
dev/env/node_modules/micro-eth-signer/net/uniswap-common.d.ts
generated
vendored
Executable file
@@ -0,0 +1,72 @@
|
||||
import { type IWeb3Provider } from '../utils.ts';
|
||||
export type SwapOpt = {
|
||||
slippagePercent: number;
|
||||
ttl: number;
|
||||
};
|
||||
export declare const DEFAULT_SWAP_OPT: SwapOpt;
|
||||
export type ExchangeTx = {
|
||||
address: string;
|
||||
amount: string;
|
||||
currency: string;
|
||||
expectedAmount: string;
|
||||
data?: string;
|
||||
allowance?: {
|
||||
token: string;
|
||||
contract: string;
|
||||
amount: string;
|
||||
};
|
||||
txId?: string;
|
||||
};
|
||||
export type SwapElm = {
|
||||
name: string;
|
||||
expectedAmount: string;
|
||||
tx: (fromAddress: string, toAddress: string) => Promise<ExchangeTx>;
|
||||
};
|
||||
export declare function addPercent(n: bigint, _perc: number): bigint;
|
||||
export declare function isPromise(o: unknown): boolean;
|
||||
export type UnPromise<T> = T extends Promise<infer U> ? U : T;
|
||||
type NestedUnPromise<T> = {
|
||||
[K in keyof T]: NestedUnPromise<UnPromise<T[K]>>;
|
||||
};
|
||||
type UnPromiseIgnore<T> = T extends Promise<infer U> ? U | undefined : T;
|
||||
type NestedUnPromiseIgnore<T> = {
|
||||
[K in keyof T]: NestedUnPromiseIgnore<UnPromiseIgnore<T[K]>>;
|
||||
};
|
||||
export declare function awaitDeep<T, E extends boolean | undefined>(o: T, ignore_errors: E): Promise<E extends true ? NestedUnPromiseIgnore<T> : NestedUnPromise<T>>;
|
||||
export type CommonBase = {
|
||||
contract: string;
|
||||
} & import('../abi/decoder.js').ContractInfo;
|
||||
export declare const COMMON_BASES: CommonBase[];
|
||||
export declare const WETH: string;
|
||||
export declare function wrapContract(contract: string): string;
|
||||
export declare function sortTokens(a: string, b: string): [string, string];
|
||||
export declare function isValidEthAddr(address: string): boolean;
|
||||
export declare function isValidUniAddr(address: string): boolean;
|
||||
export type Token = {
|
||||
decimals: number;
|
||||
contract: string;
|
||||
symbol: string;
|
||||
};
|
||||
export declare abstract class UniswapAbstract {
|
||||
abstract name: string;
|
||||
abstract contract: string;
|
||||
abstract bestPath(fromCoin: string, toCoin: string, inputAmount: bigint): any;
|
||||
abstract txData(toAddress: string, fromCoin: string, toCoin: string, path: any, inputAmount?: bigint, outputAmount?: bigint, opt?: {
|
||||
slippagePercent: number;
|
||||
}): any;
|
||||
readonly net: IWeb3Provider;
|
||||
constructor(net: IWeb3Provider);
|
||||
swap(fromCoin: 'eth' | Token, toCoin: 'eth' | Token, amount: string, opt?: SwapOpt): Promise<{
|
||||
name: string;
|
||||
expectedAmount: string;
|
||||
tx: (_fromAddress: string, toAddress: string) => Promise<{
|
||||
amount: string;
|
||||
address: any;
|
||||
expectedAmount: string;
|
||||
data: string;
|
||||
allowance: any;
|
||||
}>;
|
||||
} | undefined>;
|
||||
}
|
||||
export {};
|
||||
//# sourceMappingURL=uniswap-common.d.ts.map
|
||||
1
dev/env/node_modules/micro-eth-signer/net/uniswap-common.d.ts.map
generated
vendored
Executable file
1
dev/env/node_modules/micro-eth-signer/net/uniswap-common.d.ts.map
generated
vendored
Executable file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"uniswap-common.d.ts","sourceRoot":"","sources":["../src/net/uniswap-common.ts"],"names":[],"mappings":"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"}
|
||||
154
dev/env/node_modules/micro-eth-signer/net/uniswap-common.js
generated
vendored
Executable file
154
dev/env/node_modules/micro-eth-signer/net/uniswap-common.js
generated
vendored
Executable file
@@ -0,0 +1,154 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.UniswapAbstract = exports.WETH = exports.COMMON_BASES = exports.DEFAULT_SWAP_OPT = void 0;
|
||||
exports.addPercent = addPercent;
|
||||
exports.isPromise = isPromise;
|
||||
exports.awaitDeep = awaitDeep;
|
||||
exports.wrapContract = wrapContract;
|
||||
exports.sortTokens = sortTokens;
|
||||
exports.isValidEthAddr = isValidEthAddr;
|
||||
exports.isValidUniAddr = isValidUniAddr;
|
||||
const index_ts_1 = require("../abi/index.js");
|
||||
const index_ts_2 = require("../index.js");
|
||||
const utils_ts_1 = require("../utils.js");
|
||||
exports.DEFAULT_SWAP_OPT = { slippagePercent: 0.5, ttl: 30 * 60 };
|
||||
function addPercent(n, _perc) {
|
||||
const perc = BigInt((_perc * 10000) | 0);
|
||||
const p100 = BigInt(100) * BigInt(10000);
|
||||
return ((p100 + perc) * n) / p100;
|
||||
}
|
||||
function isPromise(o) {
|
||||
if (!o || !['object', 'function'].includes(typeof o))
|
||||
return false;
|
||||
return typeof o.then === 'function';
|
||||
}
|
||||
async function awaitDeep(o, ignore_errors) {
|
||||
let promises = [];
|
||||
const traverse = (o) => {
|
||||
if (Array.isArray(o))
|
||||
return o.map((i) => traverse(i));
|
||||
if ((0, utils_ts_1.isBytes)(o))
|
||||
return o;
|
||||
if (isPromise(o))
|
||||
return { awaitDeep: promises.push(o) };
|
||||
if (typeof o === 'object') {
|
||||
let ret = {};
|
||||
for (let k in o)
|
||||
ret[k] = traverse(o[k]);
|
||||
return ret;
|
||||
}
|
||||
return o;
|
||||
};
|
||||
let out = traverse(o);
|
||||
let values;
|
||||
if (!ignore_errors)
|
||||
values = await Promise.all(promises);
|
||||
else {
|
||||
values = (await Promise.allSettled(promises)).map((i) => i.status === 'fulfilled' ? i.value : undefined);
|
||||
}
|
||||
const trBack = (o) => {
|
||||
if (Array.isArray(o))
|
||||
return o.map((i) => trBack(i));
|
||||
if ((0, utils_ts_1.isBytes)(o))
|
||||
return o;
|
||||
if (typeof o === 'object') {
|
||||
if (typeof o === 'object' && o.awaitDeep)
|
||||
return values[o.awaitDeep - 1];
|
||||
let ret = {};
|
||||
for (let k in o)
|
||||
ret[k] = trBack(o[k]);
|
||||
return ret;
|
||||
}
|
||||
return o;
|
||||
};
|
||||
return trBack(out);
|
||||
}
|
||||
exports.COMMON_BASES = [
|
||||
'WETH',
|
||||
'DAI',
|
||||
'USDC',
|
||||
'USDT',
|
||||
'COMP',
|
||||
'MKR',
|
||||
'WBTC',
|
||||
'AMPL',
|
||||
]
|
||||
.map((i) => (0, index_ts_1.tokenFromSymbol)(i))
|
||||
.filter((i) => !!i);
|
||||
exports.WETH = (0, index_ts_1.tokenFromSymbol)('WETH').contract;
|
||||
if (!exports.WETH)
|
||||
throw new Error('WETH is undefined!');
|
||||
function wrapContract(contract) {
|
||||
contract = contract.toLowerCase();
|
||||
return contract === 'eth' ? exports.WETH : contract;
|
||||
}
|
||||
function sortTokens(a, b) {
|
||||
a = wrapContract(a);
|
||||
b = wrapContract(b);
|
||||
if (a === b)
|
||||
throw new Error('uniswap.sortTokens: same token!');
|
||||
return a < b ? [a, b] : [b, a];
|
||||
}
|
||||
function isValidEthAddr(address) {
|
||||
return index_ts_2.addr.isValid(address);
|
||||
}
|
||||
function isValidUniAddr(address) {
|
||||
return address === 'eth' || isValidEthAddr(address);
|
||||
}
|
||||
function getToken(token) {
|
||||
if (typeof token === 'string' && token.toLowerCase() === 'eth')
|
||||
return { symbol: 'ETH', decimals: 18, contract: 'eth' };
|
||||
return token;
|
||||
}
|
||||
class UniswapAbstract {
|
||||
constructor(net) {
|
||||
this.net = net;
|
||||
}
|
||||
// private async coinInfo(netName: string) {
|
||||
// if (!validateAddr(netName)) return;
|
||||
// if (netName === 'eth') return { symbol: 'ETH', decimals: 18 };
|
||||
// //return await this.mgr.tokenInfo('eth', netName);
|
||||
// }
|
||||
async swap(fromCoin, toCoin, amount, opt = exports.DEFAULT_SWAP_OPT) {
|
||||
const fromInfo = getToken(fromCoin);
|
||||
const toInfo = getToken(toCoin);
|
||||
if (!fromInfo || !toInfo)
|
||||
return;
|
||||
const fromContract = fromInfo.contract.toLowerCase();
|
||||
const toContract = toInfo.contract.toLowerCase();
|
||||
if (!fromContract || !toContract)
|
||||
return;
|
||||
const fromDecimal = (0, utils_ts_1.createDecimal)(fromInfo.decimals);
|
||||
const toDecimal = (0, utils_ts_1.createDecimal)(toInfo.decimals);
|
||||
const inputAmount = fromDecimal.decode(amount);
|
||||
try {
|
||||
const path = await this.bestPath(fromContract, toContract, inputAmount);
|
||||
const expectedAmount = toDecimal.encode(path.amountOut);
|
||||
return {
|
||||
name: this.name,
|
||||
expectedAmount,
|
||||
tx: async (_fromAddress, toAddress) => {
|
||||
const txUni = this.txData(toAddress, fromContract, toContract, path, inputAmount, undefined, opt);
|
||||
return {
|
||||
amount: utils_ts_1.weieth.encode(txUni.value),
|
||||
address: txUni.to,
|
||||
expectedAmount,
|
||||
data: utils_ts_1.ethHex.encode(txUni.data),
|
||||
allowance: txUni.allowance && {
|
||||
token: txUni.allowance.token,
|
||||
contract: this.contract,
|
||||
amount: fromDecimal.encode(txUni.allowance.amount),
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
catch (e) {
|
||||
// @ts-ignore
|
||||
console.log('E', e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.UniswapAbstract = UniswapAbstract;
|
||||
//# sourceMappingURL=uniswap-common.js.map
|
||||
1
dev/env/node_modules/micro-eth-signer/net/uniswap-common.js.map
generated
vendored
Executable file
1
dev/env/node_modules/micro-eth-signer/net/uniswap-common.js.map
generated
vendored
Executable file
File diff suppressed because one or more lines are too long
30
dev/env/node_modules/micro-eth-signer/net/uniswap-v2.d.ts
generated
vendored
Executable file
30
dev/env/node_modules/micro-eth-signer/net/uniswap-v2.d.ts
generated
vendored
Executable file
@@ -0,0 +1,30 @@
|
||||
import * as uni from './uniswap-common.ts';
|
||||
export declare function create2(from: Uint8Array, salt: Uint8Array, initCodeHash: Uint8Array): string;
|
||||
export declare function pairAddress(a: string, b: string, factory?: string): string;
|
||||
export declare function amount(reserveIn: bigint, reserveOut: bigint, amountIn?: bigint, amountOut?: bigint): bigint;
|
||||
export type Path = {
|
||||
path: string[];
|
||||
amountIn: bigint;
|
||||
amountOut: bigint;
|
||||
};
|
||||
export declare function txData(to: string, input: string, output: string, path: Path, amountIn?: bigint, amountOut?: bigint, opt?: {
|
||||
ttl: number;
|
||||
deadline?: number;
|
||||
slippagePercent: number;
|
||||
feeOnTransfer: boolean;
|
||||
}): {
|
||||
to: string;
|
||||
value: bigint;
|
||||
data: any;
|
||||
allowance: {
|
||||
token: string;
|
||||
amount: bigint;
|
||||
} | undefined;
|
||||
};
|
||||
export default class UniswapV2 extends uni.UniswapAbstract {
|
||||
name: string;
|
||||
contract: string;
|
||||
bestPath(fromCoin: string, toCoin: string, inputAmount: bigint): Promise<Path>;
|
||||
txData(toAddress: string, fromCoin: string, toCoin: string, path: any, inputAmount?: bigint, outputAmount?: bigint, opt?: uni.SwapOpt): any;
|
||||
}
|
||||
//# sourceMappingURL=uniswap-v2.d.ts.map
|
||||
1
dev/env/node_modules/micro-eth-signer/net/uniswap-v2.d.ts.map
generated
vendored
Executable file
1
dev/env/node_modules/micro-eth-signer/net/uniswap-v2.d.ts.map
generated
vendored
Executable file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"uniswap-v2.d.ts","sourceRoot":"","sources":["../src/net/uniswap-v2.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,GAAG,MAAM,qBAAqB,CAAC;AAkB3C,wBAAgB,OAAO,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,GAAG,MAAM,CAG5F;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,MAAwB,GAAG,MAAM,CAI3F;AAaD,wBAAgB,MAAM,CACpB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,CAeR;AAED,MAAM,MAAM,IAAI,GAAG;IAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AA8D3E,wBAAgB,MAAM,CACpB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,IAAI,EACV,QAAQ,CAAC,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,EAClB,GAAG,GAAE;IACH,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,OAAO,CAAC;CACP,GACjB;IACD,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,GAAG,CAAC;IACV,SAAS,EACL;QACE,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KAChB,GACD,SAAS,CAAC;CACf,CAqCA;AAGD,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,GAAG,CAAC,eAAe;IACxD,IAAI,SAAgB;IACpB,QAAQ,EAAE,MAAM,CAA8B;IAC9C,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAG9E,MAAM,CACJ,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,GAAG,EACT,WAAW,CAAC,EAAE,MAAM,EACpB,YAAY,CAAC,EAAE,MAAM,EACrB,GAAG,GAAE,GAAG,CAAC,OAA8B,GACtC,GAAG;CAMP"}
|
||||
169
dev/env/node_modules/micro-eth-signer/net/uniswap-v2.js
generated
vendored
Executable file
169
dev/env/node_modules/micro-eth-signer/net/uniswap-v2.js
generated
vendored
Executable file
@@ -0,0 +1,169 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.create2 = create2;
|
||||
exports.pairAddress = pairAddress;
|
||||
exports.amount = amount;
|
||||
exports.txData = txData;
|
||||
const sha3_1 = require("@noble/hashes/sha3");
|
||||
const utils_1 = require("@noble/hashes/utils");
|
||||
const decoder_ts_1 = require("../abi/decoder.js");
|
||||
const uniswap_v2_ts_1 = require("../abi/uniswap-v2.js");
|
||||
const utils_ts_1 = require("../utils.js");
|
||||
const uni = require("./uniswap-common.js");
|
||||
const FACTORY_ADDRESS = '0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f';
|
||||
const INIT_CODE_HASH = (0, utils_1.hexToBytes)('96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f');
|
||||
const PAIR_CONTRACT = [
|
||||
{
|
||||
type: 'function',
|
||||
name: 'getReserves',
|
||||
outputs: [
|
||||
{ name: 'reserve0', type: 'uint112' },
|
||||
{ name: 'reserve1', type: 'uint112' },
|
||||
{ name: 'blockTimestampLast', type: 'uint32' },
|
||||
],
|
||||
},
|
||||
];
|
||||
function create2(from, salt, initCodeHash) {
|
||||
const cat = (0, utils_1.concatBytes)(new Uint8Array([255]), from, salt, initCodeHash);
|
||||
return utils_ts_1.ethHex.encode((0, sha3_1.keccak_256)(cat).slice(12));
|
||||
}
|
||||
function pairAddress(a, b, factory = FACTORY_ADDRESS) {
|
||||
// This is completely broken: '0x11' '0x11' will return '0x1111'. But this is how it works in sdk.
|
||||
const data = (0, utils_1.concatBytes)(...uni.sortTokens(a, b).map((i) => utils_ts_1.ethHex.decode(i)));
|
||||
return create2(utils_ts_1.ethHex.decode(factory), (0, sha3_1.keccak_256)(data), INIT_CODE_HASH);
|
||||
}
|
||||
async function reserves(net, a, b) {
|
||||
a = uni.wrapContract(a);
|
||||
b = uni.wrapContract(b);
|
||||
const contract = (0, decoder_ts_1.createContract)(PAIR_CONTRACT, net, pairAddress(a, b));
|
||||
const res = await contract.getReserves.call();
|
||||
return a < b ? [res.reserve0, res.reserve1] : [res.reserve1, res.reserve0];
|
||||
}
|
||||
// amountIn set: returns amountOut, how many tokenB user gets for amountIn of tokenA
|
||||
// amountOut set: returns amountIn, how many tokenA user should send to get exact
|
||||
// amountOut of tokenB
|
||||
function amount(reserveIn, reserveOut, amountIn, amountOut) {
|
||||
if (amountIn && amountOut)
|
||||
throw new Error('uniswap.amount: provide only one amount');
|
||||
if (!reserveIn || !reserveOut || (amountOut && amountOut >= reserveOut))
|
||||
throw new Error('Uniswap: Insufficient reserves');
|
||||
if (amountIn) {
|
||||
const amountInWithFee = amountIn * BigInt(997);
|
||||
const amountOut = (amountInWithFee * reserveOut) / (reserveIn * BigInt(1000) + amountInWithFee);
|
||||
if (amountOut === BigInt(0) || amountOut >= reserveOut)
|
||||
throw new Error('Uniswap: Insufficient reserves');
|
||||
return amountOut;
|
||||
}
|
||||
else if (amountOut)
|
||||
return ((reserveIn * amountOut * BigInt(1000)) / ((reserveOut - amountOut) * BigInt(997)) + BigInt(1));
|
||||
else
|
||||
throw new Error('uniswap.amount: provide only one amount');
|
||||
}
|
||||
async function bestPath(net, tokenA, tokenB, amountIn, amountOut) {
|
||||
if ((amountIn && amountOut) || (!amountIn && !amountOut))
|
||||
throw new Error('uniswap.bestPath: provide only one amount');
|
||||
const wA = uni.wrapContract(tokenA);
|
||||
const wB = uni.wrapContract(tokenB);
|
||||
let resP = [];
|
||||
// Direct pair
|
||||
resP.push((async () => {
|
||||
const pairAmount = amount(...(await reserves(net, tokenA, tokenB)), amountIn, amountOut);
|
||||
return {
|
||||
path: [wA, wB],
|
||||
amountIn: amountIn ? amountIn : pairAmount,
|
||||
amountOut: amountOut ? amountOut : pairAmount,
|
||||
};
|
||||
})());
|
||||
const BASES = uni.COMMON_BASES.filter((c) => c && c.contract && c.contract !== wA && c.contract !== wB);
|
||||
for (let c of BASES) {
|
||||
resP.push((async () => {
|
||||
const [rAC, rCB] = await Promise.all([
|
||||
reserves(net, wA, c.contract),
|
||||
reserves(net, c.contract, wB),
|
||||
]);
|
||||
const path = [wA, c.contract, wB];
|
||||
if (amountIn)
|
||||
return { path, amountIn, amountOut: amount(...rCB, amount(...rAC, amountIn)) };
|
||||
else if (amountOut) {
|
||||
return {
|
||||
path,
|
||||
amountOut,
|
||||
amountIn: amount(...rAC, undefined, amount(...rCB, undefined, amountOut)),
|
||||
};
|
||||
}
|
||||
else
|
||||
throw new Error('Impossible invariant');
|
||||
})());
|
||||
}
|
||||
let res = (await uni.awaitDeep(resP, true)).filter((i) => !!i);
|
||||
// biggest output or smallest input
|
||||
res.sort((a, b) => Number(amountIn ? b.amountOut - a.amountOut : a.amountIn - b.amountIn));
|
||||
if (!res.length)
|
||||
throw new Error('uniswap: cannot find path');
|
||||
return res[0];
|
||||
}
|
||||
const ROUTER_CONTRACT = (0, decoder_ts_1.createContract)(uniswap_v2_ts_1.default, undefined, uniswap_v2_ts_1.UNISWAP_V2_ROUTER_CONTRACT);
|
||||
const TX_DEFAULT_OPT = {
|
||||
...uni.DEFAULT_SWAP_OPT,
|
||||
feeOnTransfer: false, // have no idea what it is
|
||||
};
|
||||
function txData(to, input, output, path, amountIn, amountOut, opt = TX_DEFAULT_OPT) {
|
||||
opt = { ...TX_DEFAULT_OPT, ...opt };
|
||||
if (!uni.isValidUniAddr(input) || !uni.isValidUniAddr(output) || !uni.isValidEthAddr(to))
|
||||
throw new Error('Invalid address');
|
||||
if (input === 'eth' && output === 'eth')
|
||||
throw new Error('Both input and output is ETH!');
|
||||
if (input === 'eth' && path.path[0] !== uni.WETH)
|
||||
throw new Error('Input is ETH but path starts with different contract');
|
||||
if (output === 'eth' && path.path[path.path.length - 1] !== uni.WETH)
|
||||
throw new Error('Output is ETH but path ends with different contract');
|
||||
if ((amountIn && amountOut) || (!amountIn && !amountOut))
|
||||
throw new Error('uniswap.txData: provide only one amount');
|
||||
if (amountOut && opt.feeOnTransfer)
|
||||
throw new Error('Exact output + feeOnTransfer is impossible');
|
||||
const method = ('swap' +
|
||||
(amountIn ? 'Exact' : '') +
|
||||
(input === 'eth' ? 'ETH' : 'Tokens') +
|
||||
'For' +
|
||||
(amountOut ? 'Exact' : '') +
|
||||
(output === 'eth' ? 'ETH' : 'Tokens') +
|
||||
(opt.feeOnTransfer ? 'SupportingFeeOnTransferTokens' : ''));
|
||||
if (!(method in ROUTER_CONTRACT))
|
||||
throw new Error('Invalid method');
|
||||
const deadline = opt.deadline ? opt.deadline : Math.floor(Date.now() / 1000) + opt.ttl;
|
||||
const amountInMax = uni.addPercent(path.amountIn, opt.slippagePercent);
|
||||
const amountOutMin = uni.addPercent(path.amountOut, -opt.slippagePercent);
|
||||
// TODO: remove any
|
||||
const data = ROUTER_CONTRACT[method].encodeInput({
|
||||
amountInMax,
|
||||
amountOutMin,
|
||||
amountIn,
|
||||
amountOut,
|
||||
to,
|
||||
deadline,
|
||||
path: path.path,
|
||||
});
|
||||
const amount = amountIn ? amountIn : amountInMax;
|
||||
const value = input === 'eth' ? amount : BigInt(0);
|
||||
const allowance = input === 'eth' ? undefined : { token: input, amount };
|
||||
return { to: uniswap_v2_ts_1.UNISWAP_V2_ROUTER_CONTRACT, value, data, allowance };
|
||||
}
|
||||
// Here goes Exchange API. Everything above is SDK. Supports almost everything from official sdk except liquidity stuff.
|
||||
class UniswapV2 extends uni.UniswapAbstract {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.name = 'Uniswap V2';
|
||||
this.contract = uniswap_v2_ts_1.UNISWAP_V2_ROUTER_CONTRACT;
|
||||
}
|
||||
bestPath(fromCoin, toCoin, inputAmount) {
|
||||
return bestPath(this.net, fromCoin, toCoin, inputAmount);
|
||||
}
|
||||
txData(toAddress, fromCoin, toCoin, path, inputAmount, outputAmount, opt = uni.DEFAULT_SWAP_OPT) {
|
||||
return txData(toAddress, fromCoin, toCoin, path, inputAmount, outputAmount, {
|
||||
...TX_DEFAULT_OPT,
|
||||
...opt,
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.default = UniswapV2;
|
||||
//# sourceMappingURL=uniswap-v2.js.map
|
||||
1
dev/env/node_modules/micro-eth-signer/net/uniswap-v2.js.map
generated
vendored
Executable file
1
dev/env/node_modules/micro-eth-signer/net/uniswap-v2.js.map
generated
vendored
Executable file
File diff suppressed because one or more lines are too long
36
dev/env/node_modules/micro-eth-signer/net/uniswap-v3.d.ts
generated
vendored
Executable file
36
dev/env/node_modules/micro-eth-signer/net/uniswap-v3.d.ts
generated
vendored
Executable file
@@ -0,0 +1,36 @@
|
||||
import * as uni from './uniswap-common.ts';
|
||||
export declare const Fee: Record<string, number>;
|
||||
type Route = {
|
||||
path?: Uint8Array;
|
||||
fee?: number;
|
||||
amountIn?: bigint;
|
||||
amountOut?: bigint;
|
||||
p?: any;
|
||||
};
|
||||
export type TxOpt = {
|
||||
slippagePercent: number;
|
||||
ttl: number;
|
||||
sqrtPriceLimitX96?: bigint;
|
||||
deadline?: number;
|
||||
fee?: {
|
||||
fee: number;
|
||||
to: string;
|
||||
};
|
||||
};
|
||||
export declare function txData(to: string, input: string, output: string, route: Route, amountIn?: bigint, amountOut?: bigint, opt?: TxOpt): {
|
||||
to: string;
|
||||
value: bigint;
|
||||
data: Uint8Array;
|
||||
allowance: {
|
||||
token: string;
|
||||
amount: bigint;
|
||||
} | undefined;
|
||||
};
|
||||
export default class UniswapV3 extends uni.UniswapAbstract {
|
||||
name: string;
|
||||
contract: string;
|
||||
bestPath(fromCoin: string, toCoin: string, inputAmount: bigint): Promise<Route>;
|
||||
txData(toAddress: string, fromCoin: string, toCoin: string, path: any, inputAmount?: bigint, outputAmount?: bigint, opt?: uni.SwapOpt): any;
|
||||
}
|
||||
export {};
|
||||
//# sourceMappingURL=uniswap-v3.d.ts.map
|
||||
1
dev/env/node_modules/micro-eth-signer/net/uniswap-v3.d.ts.map
generated
vendored
Executable file
1
dev/env/node_modules/micro-eth-signer/net/uniswap-v3.d.ts.map
generated
vendored
Executable file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"uniswap-v3.d.ts","sourceRoot":"","sources":["../src/net/uniswap-v3.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,GAAG,MAAM,qBAAqB,CAAC;AAiD3C,eAAO,MAAM,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAItC,CAAC;AAEF,KAAK,KAAK,GAAG;IAAE,IAAI,CAAC,EAAE,UAAU,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,CAAC,EAAE,GAAG,CAAA;CAAE,CAAC;AAoDjG,MAAM,MAAM,KAAK,GAAG;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;CACnC,CAAC;AAEF,wBAAgB,MAAM,CACpB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,KAAK,EACZ,QAAQ,CAAC,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,EAClB,GAAG,GAAE,KAA4B,GAChC;IACD,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,EACL;QACE,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KAChB,GACD,SAAS,CAAC;CACf,CAoEA;AAGD,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,GAAG,CAAC,eAAe;IACxD,IAAI,SAAgB;IACpB,QAAQ,EAAE,MAAM,CAA8B;IAC9C,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IAG/E,MAAM,CACJ,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,GAAG,EACT,WAAW,CAAC,EAAE,MAAM,EACpB,YAAY,CAAC,EAAE,MAAM,EACrB,GAAG,GAAE,GAAG,CAAC,OAA8B,GACtC,GAAG;CAMP"}
|
||||
181
dev/env/node_modules/micro-eth-signer/net/uniswap-v3.js
generated
vendored
Executable file
181
dev/env/node_modules/micro-eth-signer/net/uniswap-v3.js
generated
vendored
Executable file
@@ -0,0 +1,181 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Fee = void 0;
|
||||
exports.txData = txData;
|
||||
const utils_1 = require("@noble/hashes/utils");
|
||||
const decoder_ts_1 = require("../abi/decoder.js");
|
||||
const uniswap_v3_ts_1 = require("../abi/uniswap-v3.js");
|
||||
const utils_ts_1 = require("../utils.js");
|
||||
const uni = require("./uniswap-common.js");
|
||||
const ADDRESS_ZERO = '0x0000000000000000000000000000000000000000';
|
||||
const QUOTER_ADDRESS = '0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6';
|
||||
const QUOTER_ABI = [
|
||||
{
|
||||
type: 'function',
|
||||
name: 'quoteExactInput',
|
||||
inputs: [
|
||||
{ name: 'path', type: 'bytes' },
|
||||
{ name: 'amountIn', type: 'uint256' },
|
||||
],
|
||||
outputs: [{ name: 'amountOut', type: 'uint256' }],
|
||||
},
|
||||
{
|
||||
type: 'function',
|
||||
name: 'quoteExactInputSingle',
|
||||
inputs: [
|
||||
{ name: 'tokenIn', type: 'address' },
|
||||
{ name: 'tokenOut', type: 'address' },
|
||||
{ name: 'fee', type: 'uint24' },
|
||||
{ name: 'amountIn', type: 'uint256' },
|
||||
{ name: 'sqrtPriceLimitX96', type: 'uint160' },
|
||||
],
|
||||
outputs: [{ name: 'amountOut', type: 'uint256' }],
|
||||
},
|
||||
{
|
||||
type: 'function',
|
||||
name: 'quoteExactOutput',
|
||||
inputs: [
|
||||
{ name: 'path', type: 'bytes' },
|
||||
{ name: 'amountOut', type: 'uint256' },
|
||||
],
|
||||
outputs: [{ name: 'amountIn', type: 'uint256' }],
|
||||
},
|
||||
{
|
||||
type: 'function',
|
||||
name: 'quoteExactOutputSingle',
|
||||
inputs: [
|
||||
{ name: 'tokenIn', type: 'address' },
|
||||
{ name: 'tokenOut', type: 'address' },
|
||||
{ name: 'fee', type: 'uint24' },
|
||||
{ name: 'amountOut', type: 'uint256' },
|
||||
{ name: 'sqrtPriceLimitX96', type: 'uint160' },
|
||||
],
|
||||
outputs: [{ name: 'amountIn', type: 'uint256' }],
|
||||
},
|
||||
];
|
||||
exports.Fee = {
|
||||
LOW: 500,
|
||||
MEDIUM: 3000,
|
||||
HIGH: 10000,
|
||||
};
|
||||
function basePaths(a, b, exactOutput = false) {
|
||||
let res = [];
|
||||
for (let fee in exports.Fee)
|
||||
res.push({ fee: exports.Fee[fee], p: [a, b] });
|
||||
const wA = uni.wrapContract(a);
|
||||
const wB = uni.wrapContract(b);
|
||||
const BASES = uni.COMMON_BASES.filter((c) => c && c.contract && c.contract !== wA && c.contract !== wB);
|
||||
const packFee = (n) => exports.Fee[n].toString(16).padStart(6, '0');
|
||||
for (let c of BASES) {
|
||||
for (let fee1 in exports.Fee) {
|
||||
for (let fee2 in exports.Fee) {
|
||||
let path = [wA, packFee(fee1), c.contract, packFee(fee2), wB].map((i) => utils_ts_1.ethHex.decode(i));
|
||||
if (exactOutput)
|
||||
path = path.reverse();
|
||||
res.push({ path: (0, utils_1.concatBytes)(...path) });
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
async function bestPath(net, a, b, amountIn, amountOut) {
|
||||
if ((amountIn && amountOut) || (!amountIn && !amountOut))
|
||||
throw new Error('uniswapV3.bestPath: provide only one amount');
|
||||
const quoter = (0, decoder_ts_1.createContract)(QUOTER_ABI, net, QUOTER_ADDRESS);
|
||||
let paths = basePaths(a, b, !!amountOut);
|
||||
for (let i of paths) {
|
||||
if (!i.path && !i.fee)
|
||||
continue;
|
||||
const opt = { ...i, tokenIn: a, tokenOut: b, amountIn, amountOut, sqrtPriceLimitX96: 0 };
|
||||
const method = 'quoteExact' + (amountIn ? 'Input' : 'Output') + (i.path ? '' : 'Single');
|
||||
// TODO: remove any
|
||||
i[amountIn ? 'amountOut' : 'amountIn'] = quoter[method].call(opt);
|
||||
}
|
||||
paths = (await uni.awaitDeep(paths, true));
|
||||
paths = paths.filter((i) => i.amountIn || i.amountOut);
|
||||
paths.sort((a, b) => Number(amountIn ? b.amountOut - a.amountOut : a.amountIn - b.amountIn));
|
||||
if (!paths.length)
|
||||
throw new Error('uniswap: cannot find path');
|
||||
return paths[0];
|
||||
}
|
||||
const ROUTER_CONTRACT = (0, decoder_ts_1.createContract)(uniswap_v3_ts_1.default, undefined, uniswap_v3_ts_1.UNISWAP_V3_ROUTER_CONTRACT);
|
||||
function txData(to, input, output, route, amountIn, amountOut, opt = uni.DEFAULT_SWAP_OPT) {
|
||||
opt = { ...uni.DEFAULT_SWAP_OPT, ...opt };
|
||||
const err = 'Uniswap v3: ';
|
||||
if (!uni.isValidUniAddr(input))
|
||||
throw new Error(err + 'invalid input address');
|
||||
if (!uni.isValidUniAddr(output))
|
||||
throw new Error(err + 'invalid output address');
|
||||
if (!uni.isValidEthAddr(to))
|
||||
throw new Error(err + 'invalid to address');
|
||||
if (opt.fee && !uni.isValidUniAddr(opt.fee.to))
|
||||
throw new Error(err + 'invalid fee recepient addresss');
|
||||
if (input === 'eth' && output === 'eth')
|
||||
throw new Error(err + 'both input and output cannot be eth');
|
||||
if ((amountIn && amountOut) || (!amountIn && !amountOut))
|
||||
throw new Error(err + 'specify either amountIn or amountOut, but not both');
|
||||
if ((amountIn && !route.amountOut) ||
|
||||
(amountOut && !route.amountIn) ||
|
||||
(!route.fee && !route.path))
|
||||
throw new Error(err + 'invalid route');
|
||||
if (route.path && opt.sqrtPriceLimitX96)
|
||||
throw new Error(err + 'sqrtPriceLimitX96 on multi-hop trade');
|
||||
const deadline = opt.deadline || Math.floor(Date.now() / 1000);
|
||||
// flags for whether funds should be send first to the router
|
||||
const routerMustCustody = output === 'eth' || !!opt.fee;
|
||||
// TODO: remove "as bigint"
|
||||
let args = {
|
||||
...route,
|
||||
tokenIn: uni.wrapContract(input),
|
||||
tokenOut: uni.wrapContract(output),
|
||||
recipient: routerMustCustody ? ADDRESS_ZERO : to,
|
||||
deadline,
|
||||
amountIn: (amountIn || route.amountIn),
|
||||
amountOut: (amountOut || route.amountOut),
|
||||
sqrtPriceLimitX96: opt.sqrtPriceLimitX96 || BigInt(0),
|
||||
amountInMaximum: undefined,
|
||||
amountOutMinimum: undefined,
|
||||
};
|
||||
args.amountInMaximum = uni.addPercent(args.amountIn, opt.slippagePercent);
|
||||
args.amountOutMinimum = uni.addPercent(args.amountOut, -opt.slippagePercent);
|
||||
const method = ('exact' + (amountIn ? 'Input' : 'Output') + (!args.path ? 'Single' : ''));
|
||||
// TODO: remove unknown
|
||||
const calldatas = [ROUTER_CONTRACT[method].encodeInput(args)];
|
||||
if (input === 'eth' && amountOut)
|
||||
calldatas.push(ROUTER_CONTRACT['refundETH'].encodeInput());
|
||||
// unwrap
|
||||
if (routerMustCustody) {
|
||||
calldatas.push(ROUTER_CONTRACT[(output === 'eth' ? 'unwrapWETH9' : 'sweepToken') + (opt.fee ? 'WithFee' : '')].encodeInput({
|
||||
token: uni.wrapContract(output),
|
||||
amountMinimum: args.amountOutMinimum,
|
||||
recipient: to,
|
||||
feeBips: opt.fee && opt.fee.fee * 10000,
|
||||
feeRecipient: opt.fee && opt.fee.to,
|
||||
}));
|
||||
}
|
||||
const data = calldatas.length === 1 ? calldatas[0] : ROUTER_CONTRACT['multicall'].encodeInput(calldatas);
|
||||
const value = input === 'eth' ? (amountIn ? amountIn : args.amountInMaximum) : BigInt(0);
|
||||
const allowance = input !== 'eth'
|
||||
? { token: input, amount: amountIn ? amountIn : args.amountInMaximum }
|
||||
: undefined;
|
||||
return { to: uniswap_v3_ts_1.UNISWAP_V3_ROUTER_CONTRACT, value, data, allowance };
|
||||
}
|
||||
// Here goes Exchange API. Everything above is SDK.
|
||||
class UniswapV3 extends uni.UniswapAbstract {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.name = 'Uniswap V3';
|
||||
this.contract = uniswap_v3_ts_1.UNISWAP_V3_ROUTER_CONTRACT;
|
||||
}
|
||||
bestPath(fromCoin, toCoin, inputAmount) {
|
||||
return bestPath(this.net, fromCoin, toCoin, inputAmount);
|
||||
}
|
||||
txData(toAddress, fromCoin, toCoin, path, inputAmount, outputAmount, opt = uni.DEFAULT_SWAP_OPT) {
|
||||
return txData(toAddress, fromCoin, toCoin, path, inputAmount, outputAmount, {
|
||||
...uni.DEFAULT_SWAP_OPT,
|
||||
...opt,
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.default = UniswapV3;
|
||||
//# sourceMappingURL=uniswap-v3.js.map
|
||||
1
dev/env/node_modules/micro-eth-signer/net/uniswap-v3.js.map
generated
vendored
Executable file
1
dev/env/node_modules/micro-eth-signer/net/uniswap-v3.js.map
generated
vendored
Executable file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user