@deserialize/multi-vm-wallet 1.2.11 → 1.2.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/IChainWallet.d.ts +5 -1
- package/dist/IChainWallet.js.map +1 -1
- package/dist/constant.d.ts +16 -0
- package/dist/constant.js +37 -6
- package/dist/constant.js.map +1 -1
- package/dist/evm/evm.d.ts +6 -1
- package/dist/evm/evm.js +36 -45
- package/dist/evm/evm.js.map +1 -1
- package/dist/evm/transaction.utils.d.ts +362 -0
- package/dist/evm/transaction.utils.js +669 -0
- package/dist/evm/transaction.utils.js.map +1 -0
- package/dist/evm/transactionParsing.d.ts +55 -0
- package/dist/evm/transactionParsing.js +414 -0
- package/dist/evm/transactionParsing.js.map +1 -0
- package/dist/evm/utils.d.ts +10 -9
- package/dist/evm/utils.js +37 -16
- package/dist/evm/utils.js.map +1 -1
- package/dist/helpers/index.d.ts +4 -0
- package/dist/helpers/index.js +13 -0
- package/dist/helpers/index.js.map +1 -0
- package/dist/svm/constant.d.ts +15 -0
- package/dist/svm/constant.js +25 -0
- package/dist/svm/constant.js.map +1 -0
- package/dist/svm/svm.d.ts +5 -2
- package/dist/svm/svm.js +10 -0
- package/dist/svm/svm.js.map +1 -1
- package/dist/svm/transactionParsing.d.ts +28 -0
- package/dist/svm/transactionParsing.js +207 -0
- package/dist/svm/transactionParsing.js.map +1 -0
- package/dist/svm/utils.d.ts +3 -2
- package/dist/svm/utils.js +45 -4
- package/dist/svm/utils.js.map +1 -1
- package/dist/test.d.ts +1 -1
- package/dist/test.js +47 -9
- package/dist/test.js.map +1 -1
- package/dist/types.d.ts +5 -1
- package/dist/types.js.map +1 -1
- package/package.json +4 -2
- package/utils/IChainWallet.ts +6 -2
- package/utils/constant.ts +40 -7
- package/utils/evm/evm.ts +53 -48
- package/utils/evm/transaction.utils.ts +824 -0
- package/utils/evm/transactionParsing.ts +613 -0
- package/utils/evm/utils.ts +44 -25
- package/utils/helpers/index.ts +11 -0
- package/utils/svm/constant.ts +29 -0
- package/utils/svm/svm.ts +14 -2
- package/utils/svm/transactionParsing.ts +294 -0
- package/utils/svm/utils.ts +60 -13
- package/utils/test.ts +56 -6
- package/utils/types.ts +6 -1
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { type PublicClient, type Address } from 'viem';
|
|
2
|
+
import { TransactionType } from '../constant';
|
|
3
|
+
export interface EVMTransactionHistoryItem {
|
|
4
|
+
hash: string;
|
|
5
|
+
timestamp: number | null;
|
|
6
|
+
status: 'success' | 'failed' | 'pending';
|
|
7
|
+
fee: string;
|
|
8
|
+
type: TransactionType;
|
|
9
|
+
from: string;
|
|
10
|
+
to: string | null;
|
|
11
|
+
blockNumber: bigint;
|
|
12
|
+
gasUsed: bigint;
|
|
13
|
+
gasPrice: string;
|
|
14
|
+
value: string;
|
|
15
|
+
method?: string;
|
|
16
|
+
tokenTransfers?: TokenTransfer[];
|
|
17
|
+
nftTransfers?: NFTTransfer[];
|
|
18
|
+
}
|
|
19
|
+
export interface TokenTransfer {
|
|
20
|
+
type: 'ERC20';
|
|
21
|
+
from: string;
|
|
22
|
+
to: string;
|
|
23
|
+
amount: string;
|
|
24
|
+
tokenAddress: string;
|
|
25
|
+
tokenSymbol?: string;
|
|
26
|
+
tokenDecimals?: number;
|
|
27
|
+
}
|
|
28
|
+
export interface NFTTransfer {
|
|
29
|
+
type: 'ERC721' | 'ERC1155';
|
|
30
|
+
from: string;
|
|
31
|
+
to: string;
|
|
32
|
+
tokenId: string;
|
|
33
|
+
amount?: string;
|
|
34
|
+
tokenAddress: string;
|
|
35
|
+
collectionName?: string;
|
|
36
|
+
}
|
|
37
|
+
export interface TransactionHistoryOptions {
|
|
38
|
+
startBlock?: bigint;
|
|
39
|
+
endBlock?: bigint;
|
|
40
|
+
includeTokenTransfers?: boolean;
|
|
41
|
+
includeNFTTransfers?: boolean;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Fetches and parses transaction history for an EVM wallet address
|
|
45
|
+
* @param client - Viem public client
|
|
46
|
+
* @param walletAddress - Ethereum address
|
|
47
|
+
* @param options - Optional parameters for filtering and features
|
|
48
|
+
* @returns Array of parsed transaction history items
|
|
49
|
+
*/
|
|
50
|
+
export declare function getEVMTransactionHistory(client: PublicClient, walletAddress: Address, options?: TransactionHistoryOptions): Promise<EVMTransactionHistoryItem[]>;
|
|
51
|
+
/**
|
|
52
|
+
* Alternative function that uses Etherscan-like API
|
|
53
|
+
* This is the recommended approach for production use
|
|
54
|
+
*/
|
|
55
|
+
export declare function getEVMTransactionHistoryWithAPI(client: PublicClient, walletAddress: Address, apiEndpoint: string, apiKey: string, options?: TransactionHistoryOptions): Promise<EVMTransactionHistoryItem[]>;
|
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getEVMTransactionHistory = getEVMTransactionHistory;
|
|
4
|
+
exports.getEVMTransactionHistoryWithAPI = getEVMTransactionHistoryWithAPI;
|
|
5
|
+
const viem_1 = require("viem");
|
|
6
|
+
const constant_1 = require("../constant");
|
|
7
|
+
// ERC20 Transfer event signature
|
|
8
|
+
const ERC20_TRANSFER_EVENT = (0, viem_1.parseAbi)([
|
|
9
|
+
'event Transfer(address indexed from, address indexed to, uint256 value)'
|
|
10
|
+
]);
|
|
11
|
+
// ERC721 Transfer event signature
|
|
12
|
+
const ERC721_TRANSFER_EVENT = (0, viem_1.parseAbi)([
|
|
13
|
+
'event Transfer(address indexed from, address indexed to, uint256 indexed tokenId)'
|
|
14
|
+
]);
|
|
15
|
+
// ERC1155 TransferSingle event signature
|
|
16
|
+
const ERC1155_TRANSFER_SINGLE_EVENT = (0, viem_1.parseAbi)([
|
|
17
|
+
'event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value)'
|
|
18
|
+
]);
|
|
19
|
+
// ERC1155 TransferBatch event signature
|
|
20
|
+
const ERC1155_TRANSFER_BATCH_EVENT = (0, viem_1.parseAbi)([
|
|
21
|
+
'event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values)'
|
|
22
|
+
]);
|
|
23
|
+
/**
|
|
24
|
+
* Fetches and parses transaction history for an EVM wallet address
|
|
25
|
+
* @param client - Viem public client
|
|
26
|
+
* @param walletAddress - Ethereum address
|
|
27
|
+
* @param options - Optional parameters for filtering and features
|
|
28
|
+
* @returns Array of parsed transaction history items
|
|
29
|
+
*/
|
|
30
|
+
async function getEVMTransactionHistory(client, walletAddress, options = {}) {
|
|
31
|
+
const { startBlock = 0n, endBlock, includeTokenTransfers = true, includeNFTTransfers = true, } = options;
|
|
32
|
+
try {
|
|
33
|
+
const currentBlock = await client.getBlockNumber();
|
|
34
|
+
const toBlock = endBlock || currentBlock;
|
|
35
|
+
// For wallet UI, we typically want recent transactions
|
|
36
|
+
// Start scanning from current block backwards
|
|
37
|
+
const scanStartBlock = startBlock > 0n ? startBlock : (currentBlock > 5000n ? currentBlock - 5000n : 0n);
|
|
38
|
+
console.log(`Fetching recent transactions from block ${scanStartBlock} to ${toBlock}`);
|
|
39
|
+
// Get transaction hashes for the address (max 15 transactions)
|
|
40
|
+
const txHashes = await getRecentTransactionHashes(client, walletAddress, scanStartBlock, toBlock, 15 // max transactions to fetch
|
|
41
|
+
);
|
|
42
|
+
console.log(`Found ${txHashes.length} unique transactions`);
|
|
43
|
+
// Fetch full transaction details in batches
|
|
44
|
+
const transactions = await fetchTransactionsInBatches(client, txHashes, 10);
|
|
45
|
+
// Parse each transaction
|
|
46
|
+
const history = [];
|
|
47
|
+
for (const { tx, receipt, block } of transactions) {
|
|
48
|
+
if (!tx || !receipt)
|
|
49
|
+
continue;
|
|
50
|
+
const parsed = await parseEVMTransaction(client, tx, receipt, block?.timestamp || null, walletAddress, includeTokenTransfers, includeNFTTransfers);
|
|
51
|
+
history.push(parsed);
|
|
52
|
+
}
|
|
53
|
+
// Sort by block number (newest first)
|
|
54
|
+
history.sort((a, b) => Number(b.blockNumber - a.blockNumber));
|
|
55
|
+
return history;
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
console.error('Error fetching EVM transaction history:', error);
|
|
59
|
+
throw error;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Gets recent transaction hashes by scanning blocks backwards
|
|
64
|
+
* Uses batched parallel requests for better performance
|
|
65
|
+
*/
|
|
66
|
+
async function getRecentTransactionHashes(client, address, startBlock, endBlock, maxTransactions = 15, batchSize = 9) {
|
|
67
|
+
const txHashes = [];
|
|
68
|
+
const seenHashes = new Map();
|
|
69
|
+
const addressLower = address.toLowerCase();
|
|
70
|
+
let currentBlock = endBlock;
|
|
71
|
+
let blocksScanned = 0n;
|
|
72
|
+
console.log(`Scanning blocks backwards from ${endBlock}...`);
|
|
73
|
+
// Iterate backwards in batches
|
|
74
|
+
while (currentBlock >= startBlock && txHashes.length < maxTransactions) {
|
|
75
|
+
// Create batch of block numbers to fetch
|
|
76
|
+
const blockNumbers = [];
|
|
77
|
+
for (let i = 0; i < batchSize && currentBlock >= startBlock; i++) {
|
|
78
|
+
blockNumbers.push(currentBlock);
|
|
79
|
+
currentBlock--;
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
// Fetch all blocks in parallel
|
|
83
|
+
const blocks = await Promise.all(blockNumbers.map(blockNumber => client.getBlock({
|
|
84
|
+
blockNumber,
|
|
85
|
+
includeTransactions: true,
|
|
86
|
+
}).catch(error => {
|
|
87
|
+
console.error(`Error fetching block ${blockNumber}:`, error);
|
|
88
|
+
return null;
|
|
89
|
+
})));
|
|
90
|
+
blocks.length;
|
|
91
|
+
console.log('blocks.length: ', blocks.length);
|
|
92
|
+
// Process blocks in order (newest to oldest)
|
|
93
|
+
for (const block of blocks) {
|
|
94
|
+
if (!block || !block.transactions)
|
|
95
|
+
continue;
|
|
96
|
+
for (let i = 0; i < block.transactions.length && txHashes.length < maxTransactions; i++) {
|
|
97
|
+
const tx = block.transactions[i];
|
|
98
|
+
if (typeof tx === 'object') {
|
|
99
|
+
// Check if wallet is sender or receiver
|
|
100
|
+
const isSender = tx.from.toLowerCase() === addressLower;
|
|
101
|
+
const isReceiver = tx.to?.toLowerCase() === addressLower;
|
|
102
|
+
if ((isSender || isReceiver) && !seenHashes.has(tx.hash)) {
|
|
103
|
+
seenHashes.set(tx.hash, true);
|
|
104
|
+
txHashes.push(tx.hash);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
console.log("Transaction is not an object: ", tx);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// Early exit if we found enough transactions
|
|
112
|
+
if (txHashes.length >= maxTransactions)
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
blocksScanned += BigInt(blockNumbers.length);
|
|
116
|
+
// Log progress
|
|
117
|
+
if (blocksScanned % 50n === 0n || blocksScanned < 50n) {
|
|
118
|
+
console.log(`Scanned ${blocksScanned} blocks, found ${txHashes.length} transactions`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
console.error(`Error fetching block batch:`, error);
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
console.log(`Found ${txHashes.length} transactions after scanning ${blocksScanned} blocks`);
|
|
127
|
+
return txHashes;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Alternative function that uses Etherscan-like API
|
|
131
|
+
* This is the recommended approach for production use
|
|
132
|
+
*/
|
|
133
|
+
async function getEVMTransactionHistoryWithAPI(client, walletAddress, apiEndpoint, apiKey, options = {}) {
|
|
134
|
+
const { includeTokenTransfers = true, includeNFTTransfers = true } = options;
|
|
135
|
+
try {
|
|
136
|
+
// Fetch normal transactions
|
|
137
|
+
const normalTxResponse = await fetch(`${apiEndpoint}?module=account&action=txlist&address=${walletAddress}&startblock=0&endblock=99999999&sort=desc&apikey=${apiKey}`);
|
|
138
|
+
const normalTxData = await normalTxResponse.json();
|
|
139
|
+
const history = [];
|
|
140
|
+
if (normalTxData.status === '1' && normalTxData.result) {
|
|
141
|
+
for (const tx of normalTxData.result.slice(0, 50)) { // Limit to 50 most recent
|
|
142
|
+
const receipt = await client.getTransactionReceipt({ hash: tx.hash });
|
|
143
|
+
const parsed = await parseEVMTransaction(client, {
|
|
144
|
+
hash: tx.hash,
|
|
145
|
+
from: tx.from,
|
|
146
|
+
to: tx.to,
|
|
147
|
+
value: BigInt(tx.value),
|
|
148
|
+
blockNumber: BigInt(tx.blockNumber),
|
|
149
|
+
input: tx.input,
|
|
150
|
+
nonce: parseInt(tx.nonce),
|
|
151
|
+
gas: BigInt(tx.gas),
|
|
152
|
+
gasPrice: tx.gasPrice ? BigInt(tx.gasPrice) : undefined,
|
|
153
|
+
}, receipt, BigInt(tx.timeStamp), walletAddress, includeTokenTransfers, includeNFTTransfers);
|
|
154
|
+
history.push(parsed);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return history;
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
console.error('Error fetching EVM transaction history with API:', error);
|
|
161
|
+
throw error;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Fetches transaction hashes for an address by iterating through blocks
|
|
166
|
+
* Efficient for recent transactions (last 10-15 txs)
|
|
167
|
+
*/
|
|
168
|
+
async function getTransactionHashesByAddress(client, address, startBlock, endBlock, direction, maxTransactions = 15) {
|
|
169
|
+
const txHashes = [];
|
|
170
|
+
const addressLower = address.toLowerCase();
|
|
171
|
+
let currentBlock = endBlock;
|
|
172
|
+
console.log(`Scanning blocks backwards from ${endBlock} to ${startBlock}...`);
|
|
173
|
+
// Iterate backwards from most recent block
|
|
174
|
+
while (currentBlock >= startBlock && txHashes.length < maxTransactions) {
|
|
175
|
+
try {
|
|
176
|
+
const block = await client.getBlock({
|
|
177
|
+
blockNumber: currentBlock,
|
|
178
|
+
includeTransactions: true,
|
|
179
|
+
});
|
|
180
|
+
if (block.transactions) {
|
|
181
|
+
for (const tx of block.transactions) {
|
|
182
|
+
// Check if transaction matches the direction filter
|
|
183
|
+
if (typeof tx === 'object') {
|
|
184
|
+
const matchesDirection = (direction === 'from' && tx.from.toLowerCase() === addressLower) ||
|
|
185
|
+
(direction === 'to' && tx.to?.toLowerCase() === addressLower) ||
|
|
186
|
+
(direction === 'from' && tx.from.toLowerCase() === addressLower) ||
|
|
187
|
+
(direction === 'to' && tx.to?.toLowerCase() === addressLower);
|
|
188
|
+
if (matchesDirection) {
|
|
189
|
+
txHashes.push(tx.hash);
|
|
190
|
+
// Stop if we've found enough transactions
|
|
191
|
+
if (txHashes.length >= maxTransactions) {
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
currentBlock--;
|
|
199
|
+
// Log progress every 100 blocks
|
|
200
|
+
if ((endBlock - currentBlock) % 100n === 0n) {
|
|
201
|
+
console.log(`Scanned ${endBlock - currentBlock} blocks, found ${txHashes.length} transactions`);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
catch (error) {
|
|
205
|
+
console.error(`Error fetching block ${currentBlock}:`, error);
|
|
206
|
+
currentBlock--;
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
console.log(`Found ${txHashes.length} transactions after scanning ${endBlock - currentBlock} blocks`);
|
|
211
|
+
return txHashes;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Fetches full transaction details in batches
|
|
215
|
+
*/
|
|
216
|
+
async function fetchTransactionsInBatches(client, hashes, batchSize) {
|
|
217
|
+
const results = [];
|
|
218
|
+
for (let i = 0; i < hashes.length; i += batchSize) {
|
|
219
|
+
const batch = hashes.slice(i, i + batchSize);
|
|
220
|
+
const batchResults = await Promise.all(batch.map(async (hash) => {
|
|
221
|
+
try {
|
|
222
|
+
const [tx, receipt] = await Promise.all([
|
|
223
|
+
client.getTransaction({ hash }),
|
|
224
|
+
client.getTransactionReceipt({ hash }),
|
|
225
|
+
]);
|
|
226
|
+
let block = null;
|
|
227
|
+
if (tx?.blockNumber) {
|
|
228
|
+
block = await client.getBlock({ blockNumber: tx.blockNumber });
|
|
229
|
+
}
|
|
230
|
+
return { tx, receipt, block };
|
|
231
|
+
}
|
|
232
|
+
catch (error) {
|
|
233
|
+
console.error(`Error fetching transaction ${hash}:`, error);
|
|
234
|
+
return { tx: null, receipt: null, block: null };
|
|
235
|
+
}
|
|
236
|
+
}));
|
|
237
|
+
results.push(...batchResults);
|
|
238
|
+
// Small delay to avoid rate limiting
|
|
239
|
+
if (i + batchSize < hashes.length) {
|
|
240
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return results;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Parses a single EVM transaction
|
|
247
|
+
*/
|
|
248
|
+
async function parseEVMTransaction(client, tx, receipt, timestamp, walletAddress, includeTokenTransfers, includeNFTTransfers) {
|
|
249
|
+
const gasUsed = receipt.gasUsed;
|
|
250
|
+
const effectiveGasPrice = receipt.effectiveGasPrice || tx.gasPrice || 0n;
|
|
251
|
+
const fee = (0, viem_1.formatEther)(gasUsed * effectiveGasPrice);
|
|
252
|
+
const gasPrice = (0, viem_1.formatUnits)(effectiveGasPrice, 9); // gwei
|
|
253
|
+
// Determine transaction type
|
|
254
|
+
const type = determineTransactionType(tx, receipt);
|
|
255
|
+
// Extract method signature
|
|
256
|
+
const method = tx.input && tx.input.length >= 10
|
|
257
|
+
? tx.input.slice(0, 10)
|
|
258
|
+
: undefined;
|
|
259
|
+
// Parse token transfers from logs
|
|
260
|
+
let tokenTransfers = [];
|
|
261
|
+
let nftTransfers = [];
|
|
262
|
+
if (includeTokenTransfers || includeNFTTransfers) {
|
|
263
|
+
const transfers = await parseTransferLogs(client, receipt.logs, walletAddress, includeTokenTransfers, includeNFTTransfers);
|
|
264
|
+
tokenTransfers = transfers.tokens;
|
|
265
|
+
nftTransfers = transfers.nfts;
|
|
266
|
+
}
|
|
267
|
+
return {
|
|
268
|
+
hash: tx.hash,
|
|
269
|
+
timestamp: timestamp ? Number(timestamp) : null,
|
|
270
|
+
blockNumber: tx.blockNumber || 0n,
|
|
271
|
+
status: receipt.status === 'success' ? 'success' : 'failed',
|
|
272
|
+
fee,
|
|
273
|
+
gasUsed,
|
|
274
|
+
gasPrice,
|
|
275
|
+
type,
|
|
276
|
+
from: tx.from,
|
|
277
|
+
to: tx.to || null,
|
|
278
|
+
value: (0, viem_1.formatEther)(tx.value || 0n),
|
|
279
|
+
method,
|
|
280
|
+
tokenTransfers: tokenTransfers.length > 0 ? tokenTransfers : undefined,
|
|
281
|
+
nftTransfers: nftTransfers.length > 0 ? nftTransfers : undefined,
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Determines the transaction type
|
|
286
|
+
*/
|
|
287
|
+
function determineTransactionType(tx, receipt) {
|
|
288
|
+
// Contract creation
|
|
289
|
+
if (!tx.to)
|
|
290
|
+
return constant_1.TRANSACTION_TYPE.CONTRACT_CREATION;
|
|
291
|
+
// Check if it's a token/NFT transfer based on method signature
|
|
292
|
+
const methodSig = tx.input?.slice(0, 10);
|
|
293
|
+
if (methodSig === '0xa9059cbb')
|
|
294
|
+
return constant_1.TRANSACTION_TYPE.TOKEN_TRANSFER; // ERC20 transfer
|
|
295
|
+
if (methodSig === '0x23b872dd')
|
|
296
|
+
return constant_1.TRANSACTION_TYPE.TOKEN_TRANSFER; // ERC20 transferFrom
|
|
297
|
+
if (methodSig === '0x42842e0e')
|
|
298
|
+
return constant_1.TRANSACTION_TYPE.NFT_TRANSFER; // ERC721 safeTransferFrom
|
|
299
|
+
if (methodSig === '0xf242432a')
|
|
300
|
+
return constant_1.TRANSACTION_TYPE.NFT_TRANSFER; // ERC1155 safeTransferFrom
|
|
301
|
+
// Check value
|
|
302
|
+
if (tx.value && tx.value > 0n)
|
|
303
|
+
return constant_1.TRANSACTION_TYPE.NATIVE_TRANSFER;
|
|
304
|
+
// Check logs for common patterns
|
|
305
|
+
if (receipt.logs.some(log => log.topics[0]?.includes('Swap')))
|
|
306
|
+
return constant_1.TRANSACTION_TYPE.SWAP;
|
|
307
|
+
if (receipt.logs.some(log => log.topics[0]?.includes('Deposit')))
|
|
308
|
+
return constant_1.TRANSACTION_TYPE.DEPOSIT;
|
|
309
|
+
if (receipt.logs.some(log => log.topics[0]?.includes('Withdraw')))
|
|
310
|
+
return constant_1.TRANSACTION_TYPE.WITHDRAWAL;
|
|
311
|
+
return constant_1.TRANSACTION_TYPE.CONTRACT_INTERACTION;
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Parses transfer events from transaction logs
|
|
315
|
+
*/
|
|
316
|
+
async function parseTransferLogs(client, logs, walletAddress, includeTokenTransfers, includeNFTTransfers) {
|
|
317
|
+
const tokens = [];
|
|
318
|
+
const nfts = [];
|
|
319
|
+
for (const log of logs) {
|
|
320
|
+
try {
|
|
321
|
+
// Try ERC20 Transfer
|
|
322
|
+
if (includeTokenTransfers && log.topics.length === 3) {
|
|
323
|
+
try {
|
|
324
|
+
const decoded = (0, viem_1.decodeEventLog)({
|
|
325
|
+
abi: ERC20_TRANSFER_EVENT,
|
|
326
|
+
data: log.data,
|
|
327
|
+
topics: log.topics,
|
|
328
|
+
});
|
|
329
|
+
if (decoded.eventName === 'Transfer') {
|
|
330
|
+
const { from, to, value } = decoded.args;
|
|
331
|
+
// Only include if wallet is involved
|
|
332
|
+
if (from.toLowerCase() === walletAddress.toLowerCase() ||
|
|
333
|
+
to.toLowerCase() === walletAddress.toLowerCase()) {
|
|
334
|
+
// Try to get token info (this might fail for non-standard tokens)
|
|
335
|
+
let decimals = 18;
|
|
336
|
+
try {
|
|
337
|
+
decimals = await client.readContract({
|
|
338
|
+
address: log.address,
|
|
339
|
+
abi: (0, viem_1.parseAbi)(['function decimals() view returns (uint8)']),
|
|
340
|
+
functionName: 'decimals',
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
catch { }
|
|
344
|
+
tokens.push({
|
|
345
|
+
type: 'ERC20',
|
|
346
|
+
from,
|
|
347
|
+
to,
|
|
348
|
+
amount: (0, viem_1.formatUnits)(value, decimals),
|
|
349
|
+
tokenAddress: log.address,
|
|
350
|
+
tokenDecimals: decimals,
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
catch { }
|
|
356
|
+
}
|
|
357
|
+
// Try ERC721 Transfer (has indexed tokenId)
|
|
358
|
+
if (includeNFTTransfers && log.topics.length === 4) {
|
|
359
|
+
try {
|
|
360
|
+
const decoded = (0, viem_1.decodeEventLog)({
|
|
361
|
+
abi: ERC721_TRANSFER_EVENT,
|
|
362
|
+
data: log.data,
|
|
363
|
+
topics: log.topics,
|
|
364
|
+
});
|
|
365
|
+
if (decoded.eventName === 'Transfer') {
|
|
366
|
+
const { from, to, tokenId } = decoded.args;
|
|
367
|
+
if (from.toLowerCase() === walletAddress.toLowerCase() ||
|
|
368
|
+
to.toLowerCase() === walletAddress.toLowerCase()) {
|
|
369
|
+
nfts.push({
|
|
370
|
+
type: 'ERC721',
|
|
371
|
+
from,
|
|
372
|
+
to,
|
|
373
|
+
tokenId: tokenId.toString(),
|
|
374
|
+
tokenAddress: log.address,
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
catch { }
|
|
380
|
+
}
|
|
381
|
+
// Try ERC1155 TransferSingle
|
|
382
|
+
if (includeNFTTransfers) {
|
|
383
|
+
try {
|
|
384
|
+
const decoded = (0, viem_1.decodeEventLog)({
|
|
385
|
+
abi: ERC1155_TRANSFER_SINGLE_EVENT,
|
|
386
|
+
data: log.data,
|
|
387
|
+
topics: log.topics,
|
|
388
|
+
});
|
|
389
|
+
if (decoded.eventName === 'TransferSingle') {
|
|
390
|
+
const { from, to, id, value } = decoded.args;
|
|
391
|
+
if (from.toLowerCase() === walletAddress.toLowerCase() ||
|
|
392
|
+
to.toLowerCase() === walletAddress.toLowerCase()) {
|
|
393
|
+
nfts.push({
|
|
394
|
+
type: 'ERC1155',
|
|
395
|
+
from,
|
|
396
|
+
to,
|
|
397
|
+
tokenId: id.toString(),
|
|
398
|
+
amount: value.toString(),
|
|
399
|
+
tokenAddress: log.address,
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
catch { }
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
catch (error) {
|
|
408
|
+
// Skip logs that don't match our patterns
|
|
409
|
+
continue;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
return { tokens, nfts };
|
|
413
|
+
}
|
|
414
|
+
//# sourceMappingURL=transactionParsing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transactionParsing.js","sourceRoot":"","sources":["../../utils/evm/transactionParsing.ts"],"names":[],"mappings":"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"}
|
package/dist/evm/utils.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Balance, TokenInfo } from '../types';
|
|
1
|
+
import { Balance, ChainWalletConfig, UserTokenBalance, TokenInfo } from '../types';
|
|
2
2
|
import { JsonRpcProvider, Wallet, TransactionReceipt } from 'ethers';
|
|
3
3
|
export interface TransactionParams {
|
|
4
4
|
to: string;
|
|
@@ -186,6 +186,15 @@ export declare const safeApprove: (wallet: Wallet, tokenAddress: string, spender
|
|
|
186
186
|
resetResult: TransactionResult;
|
|
187
187
|
approveResult: TransactionResult;
|
|
188
188
|
}>;
|
|
189
|
+
export declare const discoverTokens: (wallet: string, chain: ChainWalletConfig) => Promise<UserTokenBalance<string>[]>;
|
|
190
|
+
export declare function calcGasTotal(gasLimit?: string, gasPrice?: string): string;
|
|
191
|
+
export declare function toPrecisionWithoutTrailingZeros(n: number, precision: number): string;
|
|
192
|
+
/**
|
|
193
|
+
* @param {number|string|BigNumber} value
|
|
194
|
+
* @param {number=} decimals
|
|
195
|
+
* @returns {BigNumber}
|
|
196
|
+
*/
|
|
197
|
+
export declare function calcTokenAmount(value: number | string | BigNumber, decimals?: number): BigNumber;
|
|
189
198
|
export declare function getKyberSwapRoute(params: KyberSwapParams): Promise<KyberSwapResponse>;
|
|
190
199
|
export declare function buildKyberSwapTransaction(chainId: string, routeSummary: KyberRoute, sender: string, recipient: string, slippageTolerance?: number, deadline?: number, clientId?: string): Promise<KyberBuildResponse>;
|
|
191
200
|
export declare function performSwap(params: {
|
|
@@ -216,13 +225,5 @@ export declare function prepareSwapParams(tokenIn: string, tokenOut: string, amo
|
|
|
216
225
|
tokenOutAddress: string;
|
|
217
226
|
formattedAmountIn: string;
|
|
218
227
|
};
|
|
219
|
-
/**
|
|
220
|
-
* Normalize token address for Debonk
|
|
221
|
-
* Converts 'native' or variations to the standard 0xEeeee... address
|
|
222
|
-
*/
|
|
223
|
-
/**
|
|
224
|
-
* Convert slippage from basis points to percentage for Debonk
|
|
225
|
-
* Input: 50 (0.5% in bps) -> Output: 0.5 (percentage)
|
|
226
|
-
*/
|
|
227
228
|
export declare function convertSlippageForDebonk(slippageBps: number): number;
|
|
228
229
|
export {};
|
package/dist/evm/utils.js
CHANGED
|
@@ -3,7 +3,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.safeApprove = exports.resetAllowance = exports.checkAndApprove = exports.approveTokenUnlimited = exports.approveToken = exports.isAllowanceSufficient = exports.checkAllowance = exports.estimateGas = exports.getGasPrices = exports.executeContractMethod = exports.sendERC20Token = exports.sendNativeToken = exports.signSendAndConfirm = exports.getTokenBalance = exports.getTokenInfo = exports.getNativeBalance = exports.DESERIALIZED_SUPPORTED_CHAINS = void 0;
|
|
6
|
+
exports.discoverTokens = exports.safeApprove = exports.resetAllowance = exports.checkAndApprove = exports.approveTokenUnlimited = exports.approveToken = exports.isAllowanceSufficient = exports.checkAllowance = exports.estimateGas = exports.getGasPrices = exports.executeContractMethod = exports.sendERC20Token = exports.sendNativeToken = exports.signSendAndConfirm = exports.getTokenBalance = exports.getTokenInfo = exports.getNativeBalance = exports.DESERIALIZED_SUPPORTED_CHAINS = void 0;
|
|
7
|
+
exports.calcGasTotal = calcGasTotal;
|
|
8
|
+
exports.toPrecisionWithoutTrailingZeros = toPrecisionWithoutTrailingZeros;
|
|
9
|
+
exports.calcTokenAmount = calcTokenAmount;
|
|
7
10
|
exports.getKyberSwapRoute = getKyberSwapRoute;
|
|
8
11
|
exports.buildKyberSwapTransaction = buildKyberSwapTransaction;
|
|
9
12
|
exports.performSwap = performSwap;
|
|
@@ -17,6 +20,7 @@ exports.prepareSwapParams = prepareSwapParams;
|
|
|
17
20
|
exports.convertSlippageForDebonk = convertSlippageForDebonk;
|
|
18
21
|
const ethers_1 = require("ethers");
|
|
19
22
|
const bn_js_1 = __importDefault(require("bn.js"));
|
|
23
|
+
const helpers_1 = require("../helpers");
|
|
20
24
|
const KYBER_BASE_URL = 'https://aggregator-api.kyberswap.com';
|
|
21
25
|
const KYBER_SUPPORTED_CHAINS = {
|
|
22
26
|
'1': 'ethereum',
|
|
@@ -393,6 +397,38 @@ const safeApprove = async (wallet, tokenAddress, spender, amount, gasLimit, conf
|
|
|
393
397
|
}
|
|
394
398
|
};
|
|
395
399
|
exports.safeApprove = safeApprove;
|
|
400
|
+
const discoverTokens = async (wallet, chain) => {
|
|
401
|
+
const balances = await helpers_1.HelperAPI.getUserToken(wallet, chain.vmType ?? "EVM", chain.chainId);
|
|
402
|
+
const formatBalances = balances.data.map((token) => {
|
|
403
|
+
return {
|
|
404
|
+
address: token.contractAddress,
|
|
405
|
+
name: token.name,
|
|
406
|
+
symbol: token.symbol,
|
|
407
|
+
decimals: token.decimals,
|
|
408
|
+
balance: token.balance,
|
|
409
|
+
owner: wallet
|
|
410
|
+
};
|
|
411
|
+
});
|
|
412
|
+
return formatBalances;
|
|
413
|
+
};
|
|
414
|
+
exports.discoverTokens = discoverTokens;
|
|
415
|
+
function calcGasTotal(gasLimit = '0', gasPrice = '0') {
|
|
416
|
+
return new bn_js_1.default(gasLimit, 16).mul(new bn_js_1.default(gasPrice, 16)).toString();
|
|
417
|
+
}
|
|
418
|
+
function toPrecisionWithoutTrailingZeros(n, precision) {
|
|
419
|
+
return new BigNumber(n)
|
|
420
|
+
.toPrecision(precision)
|
|
421
|
+
.replace(/(\.[0-9]*[1-9])0*|(\.0*)/u, '$1');
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* @param {number|string|BigNumber} value
|
|
425
|
+
* @param {number=} decimals
|
|
426
|
+
* @returns {BigNumber}
|
|
427
|
+
*/
|
|
428
|
+
function calcTokenAmount(value, decimals) {
|
|
429
|
+
const divisor = new BigNumber(10).pow(decimals ?? 0);
|
|
430
|
+
return new BigNumber(String(value)).div(divisor);
|
|
431
|
+
}
|
|
396
432
|
//swaps
|
|
397
433
|
//kyber swap here
|
|
398
434
|
//docs -. https://docs.kyberswap.com/kyberswap-solutions/kyberswap-aggregator/developer-guides/execute-a-swap-with-the-aggregator-api
|
|
@@ -586,21 +622,6 @@ function prepareSwapParams(tokenIn, tokenOut, amountIn, tokenInDecimals, isNativ
|
|
|
586
622
|
formattedAmountIn
|
|
587
623
|
};
|
|
588
624
|
}
|
|
589
|
-
/**
|
|
590
|
-
* Normalize token address for Debonk
|
|
591
|
-
* Converts 'native' or variations to the standard 0xEeeee... address
|
|
592
|
-
*/
|
|
593
|
-
// export function normalizeTokenAddressForDebonk(tokenAddress: string): string {
|
|
594
|
-
// if (tokenAddress === 'native' ||
|
|
595
|
-
// tokenAddress.toLowerCase() === '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee') {
|
|
596
|
-
// return getNativeTokenAddress();
|
|
597
|
-
// }
|
|
598
|
-
// return tokenAddress;
|
|
599
|
-
// }
|
|
600
|
-
/**
|
|
601
|
-
* Convert slippage from basis points to percentage for Debonk
|
|
602
|
-
* Input: 50 (0.5% in bps) -> Output: 0.5 (percentage)
|
|
603
|
-
*/
|
|
604
625
|
function convertSlippageForDebonk(slippageBps) {
|
|
605
626
|
return slippageBps / 100;
|
|
606
627
|
}
|