anchor-sdk 0.1.41-internal.4 → 0.1.41-internal.6
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/AnchorPayClient.d.ts +94 -0
- package/dist/AnchorPayClient.js +633 -0
- package/dist/abi/AnchorPay.json +126 -0
- package/dist/constants.d.ts +111 -0
- package/dist/constants.js +147 -1
- package/package.json +1 -1
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { Account, Address, Chain, Hex, PublicClient, TransactionReceipt, WalletClient } from "viem";
|
|
2
2
|
import { PaymentOptions } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* 批量转账参数
|
|
5
|
+
*/
|
|
6
|
+
export interface BatchTransferItem {
|
|
7
|
+
recipient: Address;
|
|
8
|
+
amount: bigint;
|
|
9
|
+
data?: Hex;
|
|
10
|
+
}
|
|
3
11
|
/**
|
|
4
12
|
* AnchorPay 客户端
|
|
5
13
|
* 用于与 AnchorPay 合约交互
|
|
@@ -76,4 +84,90 @@ export declare class AnchorPayClient {
|
|
|
76
84
|
data: string;
|
|
77
85
|
value: bigint;
|
|
78
86
|
};
|
|
87
|
+
/**
|
|
88
|
+
* 查询账户在 AnchorPay 合约中的代币余额
|
|
89
|
+
* @param account 账户地址
|
|
90
|
+
* @param token 代币地址(使用 NATIVE_TOKEN_ADDRESS 表示原生代币)
|
|
91
|
+
* @returns 余额
|
|
92
|
+
*/
|
|
93
|
+
balanceOf(account: Address, token: Address): Promise<bigint>;
|
|
94
|
+
/**
|
|
95
|
+
* 为指定地址存入 ETH 到 AnchorPay 合约
|
|
96
|
+
* @param recipient 接收者地址
|
|
97
|
+
* @param amount 金额(单位:wei)
|
|
98
|
+
* @param options 交易选项
|
|
99
|
+
* @returns 交易收据或交易数据
|
|
100
|
+
*/
|
|
101
|
+
depositETH(recipient: Address, amount: bigint, options?: PaymentOptions): Promise<TransactionReceipt | {
|
|
102
|
+
to: string;
|
|
103
|
+
data: string;
|
|
104
|
+
value: bigint;
|
|
105
|
+
}>;
|
|
106
|
+
/**
|
|
107
|
+
* 为指定地址存入 ERC20 代币到 AnchorPay 合约
|
|
108
|
+
* @param recipient 接收者地址
|
|
109
|
+
* @param tokenAddress ERC20 代币地址
|
|
110
|
+
* @param amount 金额
|
|
111
|
+
* @param options 交易选项
|
|
112
|
+
* @returns 交易收据或交易数据
|
|
113
|
+
*/
|
|
114
|
+
depositERC20(recipient: Address, tokenAddress: Address, amount: bigint, options?: PaymentOptions): Promise<TransactionReceipt | {
|
|
115
|
+
to: string;
|
|
116
|
+
data: string;
|
|
117
|
+
value: bigint;
|
|
118
|
+
}>;
|
|
119
|
+
/**
|
|
120
|
+
* 从 AnchorPay 合约提取代币
|
|
121
|
+
* @param tokenAddress 代币地址(使用 NATIVE_TOKEN_ADDRESS 表示原生代币)
|
|
122
|
+
* @param amount 金额
|
|
123
|
+
* @param options 交易选项
|
|
124
|
+
* @returns 交易收据
|
|
125
|
+
*/
|
|
126
|
+
withdraw(tokenAddress: Address, amount: bigint, options?: PaymentOptions): Promise<TransactionReceipt>;
|
|
127
|
+
/**
|
|
128
|
+
* 批量存入 ETH(使用 Multicall3)
|
|
129
|
+
* @param deposits 批量存款参数数组,每项包含接收者地址和金额
|
|
130
|
+
* @param options 交易选项
|
|
131
|
+
* @returns 交易收据或交易数据
|
|
132
|
+
*/
|
|
133
|
+
batchDepositETH(deposits: BatchTransferItem[], options?: PaymentOptions): Promise<TransactionReceipt | {
|
|
134
|
+
to: string;
|
|
135
|
+
data: string;
|
|
136
|
+
value: bigint;
|
|
137
|
+
}>;
|
|
138
|
+
/**
|
|
139
|
+
* 批量存入 ERC20 代币(使用 Multicall3)
|
|
140
|
+
* @param tokenAddress ERC20 代币地址
|
|
141
|
+
* @param deposits 批量存款参数数组
|
|
142
|
+
* @param options 交易选项
|
|
143
|
+
* @returns 交易收据或交易数据
|
|
144
|
+
*/
|
|
145
|
+
batchDepositERC20(tokenAddress: Address, deposits: BatchTransferItem[], options?: PaymentOptions): Promise<TransactionReceipt | {
|
|
146
|
+
to: string;
|
|
147
|
+
data: string;
|
|
148
|
+
value: bigint;
|
|
149
|
+
}>;
|
|
150
|
+
/**
|
|
151
|
+
* 批量发送 ETH(使用 Multicall3)
|
|
152
|
+
* @param transfers 批量转账参数数组
|
|
153
|
+
* @param options 交易选项
|
|
154
|
+
* @returns 交易收据或交易数据
|
|
155
|
+
*/
|
|
156
|
+
batchSendETH(transfers: BatchTransferItem[], options?: PaymentOptions): Promise<TransactionReceipt | {
|
|
157
|
+
to: string;
|
|
158
|
+
data: string;
|
|
159
|
+
value: bigint;
|
|
160
|
+
}>;
|
|
161
|
+
/**
|
|
162
|
+
* 批量发送 ERC20 代币(使用 Multicall3)
|
|
163
|
+
* @param tokenAddress ERC20 代币地址
|
|
164
|
+
* @param transfers 批量转账参数数组
|
|
165
|
+
* @param options 交易选项
|
|
166
|
+
* @returns 交易收据或交易数据
|
|
167
|
+
*/
|
|
168
|
+
batchSendERC20(tokenAddress: Address, transfers: BatchTransferItem[], options?: PaymentOptions): Promise<TransactionReceipt | {
|
|
169
|
+
to: string;
|
|
170
|
+
data: string;
|
|
171
|
+
value: bigint;
|
|
172
|
+
}>;
|
|
79
173
|
}
|
package/dist/AnchorPayClient.js
CHANGED
|
@@ -271,5 +271,638 @@ class AnchorPayClient {
|
|
|
271
271
|
value: 0n, // ERC20 批准不需要发送 ETH
|
|
272
272
|
};
|
|
273
273
|
}
|
|
274
|
+
/**
|
|
275
|
+
* 查询账户在 AnchorPay 合约中的代币余额
|
|
276
|
+
* @param account 账户地址
|
|
277
|
+
* @param token 代币地址(使用 NATIVE_TOKEN_ADDRESS 表示原生代币)
|
|
278
|
+
* @returns 余额
|
|
279
|
+
*/
|
|
280
|
+
async balanceOf(account, token) {
|
|
281
|
+
return (await this.publicClient.readContract({
|
|
282
|
+
address: this.contracts?.anchorPay || "",
|
|
283
|
+
abi: AnchorPay_json_1.default,
|
|
284
|
+
functionName: "balanceOf",
|
|
285
|
+
args: [account, token],
|
|
286
|
+
}));
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* 为指定地址存入 ETH 到 AnchorPay 合约
|
|
290
|
+
* @param recipient 接收者地址
|
|
291
|
+
* @param amount 金额(单位:wei)
|
|
292
|
+
* @param options 交易选项
|
|
293
|
+
* @returns 交易收据或交易数据
|
|
294
|
+
*/
|
|
295
|
+
async depositETH(recipient, amount, options) {
|
|
296
|
+
// 如果需要发送交易,但没有钱包客户端或账户
|
|
297
|
+
if (options?.sendTransaction !== false &&
|
|
298
|
+
(!this.walletClient || !this.account)) {
|
|
299
|
+
throw new Error("Wallet client and account are required to send transactions");
|
|
300
|
+
}
|
|
301
|
+
// 准备交易数据
|
|
302
|
+
const calldata = (0, viem_1.encodeFunctionData)({
|
|
303
|
+
abi: AnchorPay_json_1.default,
|
|
304
|
+
functionName: "depositFor",
|
|
305
|
+
args: [recipient, constants_1.NATIVE_TOKEN_ADDRESS, amount],
|
|
306
|
+
});
|
|
307
|
+
// 如果不需要发送交易,只返回交易数据(AA 模式)
|
|
308
|
+
if (options?.sendTransaction === false) {
|
|
309
|
+
return {
|
|
310
|
+
to: this.contracts?.anchorPay || "",
|
|
311
|
+
data: calldata,
|
|
312
|
+
value: amount,
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
// 估算 gas 和费用
|
|
316
|
+
const { maxFeePerGas, maxPriorityFeePerGas } = await this.publicClient.estimateFeesPerGas();
|
|
317
|
+
const gas = await this.publicClient.estimateGas({
|
|
318
|
+
to: this.contracts?.anchorPay || "",
|
|
319
|
+
data: calldata,
|
|
320
|
+
value: amount,
|
|
321
|
+
account: this.account,
|
|
322
|
+
});
|
|
323
|
+
// 发送交易(EOA 模式)
|
|
324
|
+
if (!this.walletClient || !this.account) {
|
|
325
|
+
throw new Error("Wallet client and account are required to send transactions");
|
|
326
|
+
}
|
|
327
|
+
const txHash = await this.walletClient.sendTransaction({
|
|
328
|
+
account: this.account,
|
|
329
|
+
to: this.contracts?.anchorPay || "",
|
|
330
|
+
data: calldata,
|
|
331
|
+
value: amount,
|
|
332
|
+
maxFeePerGas: options?.maxFeePerGas || maxFeePerGas,
|
|
333
|
+
maxPriorityFeePerGas: options?.maxPriorityFeePerGas || maxPriorityFeePerGas,
|
|
334
|
+
gas: options?.gas || gas,
|
|
335
|
+
chain: this.publicClient.chain,
|
|
336
|
+
});
|
|
337
|
+
// 等待交易确认并返回收据
|
|
338
|
+
const receipt = await this.publicClient.waitForTransactionReceipt({
|
|
339
|
+
hash: txHash,
|
|
340
|
+
});
|
|
341
|
+
return receipt;
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* 为指定地址存入 ERC20 代币到 AnchorPay 合约
|
|
345
|
+
* @param recipient 接收者地址
|
|
346
|
+
* @param tokenAddress ERC20 代币地址
|
|
347
|
+
* @param amount 金额
|
|
348
|
+
* @param options 交易选项
|
|
349
|
+
* @returns 交易收据或交易数据
|
|
350
|
+
*/
|
|
351
|
+
async depositERC20(recipient, tokenAddress, amount, options) {
|
|
352
|
+
// 如果需要发送交易,但没有钱包客户端或账户
|
|
353
|
+
if (options?.sendTransaction !== false &&
|
|
354
|
+
(!this.walletClient || !this.account)) {
|
|
355
|
+
throw new Error("Wallet client and account are required to send transactions");
|
|
356
|
+
}
|
|
357
|
+
// 如果需要自动批准,则先批准代币(默认开启自动批准)
|
|
358
|
+
if (options?.autoApprove !== false && this.walletClient && this.account) {
|
|
359
|
+
try {
|
|
360
|
+
console.log(`Checking ERC20 token approval status: ${tokenAddress}`);
|
|
361
|
+
// 检查授权
|
|
362
|
+
const allowance = (await this.publicClient.readContract({
|
|
363
|
+
address: tokenAddress,
|
|
364
|
+
abi: constants_1.ERC20_ABI,
|
|
365
|
+
functionName: "allowance",
|
|
366
|
+
args: [this.account.address, this.contracts?.anchorPay],
|
|
367
|
+
}));
|
|
368
|
+
console.log(`Current allowance: ${allowance}, Required amount: ${amount}, AnchorPay contract address: ${this.contracts?.anchorPay}`);
|
|
369
|
+
if (allowance < amount) {
|
|
370
|
+
console.log(`Approving ${amount} tokens to AnchorPay contract...`);
|
|
371
|
+
// 批准代币 - 使用最大可能值进行授权,避免多次授权
|
|
372
|
+
const maxApproveAmount = 2n ** 256n - 1n;
|
|
373
|
+
// 估算 gas 和费用
|
|
374
|
+
const { maxFeePerGas: approveMaxFeePerGas, maxPriorityFeePerGas: approveMaxPriorityFeePerGas, } = await this.publicClient.estimateFeesPerGas();
|
|
375
|
+
const approveCalldata = (0, viem_1.encodeFunctionData)({
|
|
376
|
+
abi: constants_1.ERC20_ABI,
|
|
377
|
+
functionName: "approve",
|
|
378
|
+
args: [this.contracts?.anchorPay, maxApproveAmount],
|
|
379
|
+
});
|
|
380
|
+
const approveGas = await this.publicClient.estimateGas({
|
|
381
|
+
to: tokenAddress,
|
|
382
|
+
data: approveCalldata,
|
|
383
|
+
value: 0n,
|
|
384
|
+
account: this.account,
|
|
385
|
+
});
|
|
386
|
+
const approveTxHash = await this.walletClient.writeContract({
|
|
387
|
+
account: this.account,
|
|
388
|
+
address: tokenAddress,
|
|
389
|
+
abi: constants_1.ERC20_ABI,
|
|
390
|
+
functionName: "approve",
|
|
391
|
+
args: [this.contracts?.anchorPay, maxApproveAmount],
|
|
392
|
+
chain: this.publicClient.chain,
|
|
393
|
+
maxFeePerGas: approveMaxFeePerGas,
|
|
394
|
+
maxPriorityFeePerGas: approveMaxPriorityFeePerGas,
|
|
395
|
+
gas: approveGas,
|
|
396
|
+
});
|
|
397
|
+
console.log(`Approval transaction sent, hash: ${approveTxHash}`);
|
|
398
|
+
// 等待交易确认
|
|
399
|
+
await this.publicClient.waitForTransactionReceipt({
|
|
400
|
+
hash: approveTxHash,
|
|
401
|
+
});
|
|
402
|
+
console.log(`Approval transaction confirmed`);
|
|
403
|
+
}
|
|
404
|
+
else {
|
|
405
|
+
console.log(`Sufficient allowance already exists, no need for additional approval`);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
catch (error) {
|
|
409
|
+
console.error(`Approval failed:`, error);
|
|
410
|
+
throw new Error(`ERC20 approval failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
// 准备交易数据
|
|
414
|
+
const calldata = (0, viem_1.encodeFunctionData)({
|
|
415
|
+
abi: AnchorPay_json_1.default,
|
|
416
|
+
functionName: "depositFor",
|
|
417
|
+
args: [recipient, tokenAddress, amount],
|
|
418
|
+
});
|
|
419
|
+
// 如果不需要发送交易,只返回交易数据(AA 模式)
|
|
420
|
+
if (options?.sendTransaction === false) {
|
|
421
|
+
return {
|
|
422
|
+
to: this.contracts?.anchorPay || "",
|
|
423
|
+
data: calldata,
|
|
424
|
+
value: 0n,
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
// 估算 gas 和费用
|
|
428
|
+
const { maxFeePerGas, maxPriorityFeePerGas } = await this.publicClient.estimateFeesPerGas();
|
|
429
|
+
const gas = await this.publicClient.estimateGas({
|
|
430
|
+
to: this.contracts?.anchorPay || "",
|
|
431
|
+
data: calldata,
|
|
432
|
+
value: 0n,
|
|
433
|
+
account: this.account,
|
|
434
|
+
});
|
|
435
|
+
// 发送交易(EOA 模式)
|
|
436
|
+
if (!this.walletClient || !this.account) {
|
|
437
|
+
throw new Error("Wallet client and account are required to send transactions");
|
|
438
|
+
}
|
|
439
|
+
const txHash = await this.walletClient.sendTransaction({
|
|
440
|
+
account: this.account,
|
|
441
|
+
to: this.contracts?.anchorPay || "",
|
|
442
|
+
data: calldata,
|
|
443
|
+
maxFeePerGas: options?.maxFeePerGas || maxFeePerGas,
|
|
444
|
+
maxPriorityFeePerGas: options?.maxPriorityFeePerGas || maxPriorityFeePerGas,
|
|
445
|
+
gas: options?.gas || gas,
|
|
446
|
+
chain: this.publicClient.chain,
|
|
447
|
+
});
|
|
448
|
+
// 等待交易确认并返回收据
|
|
449
|
+
const receipt = await this.publicClient.waitForTransactionReceipt({
|
|
450
|
+
hash: txHash,
|
|
451
|
+
});
|
|
452
|
+
return receipt;
|
|
453
|
+
}
|
|
454
|
+
/**
|
|
455
|
+
* 从 AnchorPay 合约提取代币
|
|
456
|
+
* @param tokenAddress 代币地址(使用 NATIVE_TOKEN_ADDRESS 表示原生代币)
|
|
457
|
+
* @param amount 金额
|
|
458
|
+
* @param options 交易选项
|
|
459
|
+
* @returns 交易收据
|
|
460
|
+
*/
|
|
461
|
+
async withdraw(tokenAddress, amount, options) {
|
|
462
|
+
if (!this.walletClient || !this.account) {
|
|
463
|
+
throw new Error("Wallet client and account are required to send transactions");
|
|
464
|
+
}
|
|
465
|
+
// 估算 gas 和费用
|
|
466
|
+
const { maxFeePerGas, maxPriorityFeePerGas } = await this.publicClient.estimateFeesPerGas();
|
|
467
|
+
const calldata = (0, viem_1.encodeFunctionData)({
|
|
468
|
+
abi: AnchorPay_json_1.default,
|
|
469
|
+
functionName: "withdraw",
|
|
470
|
+
args: [tokenAddress, amount],
|
|
471
|
+
});
|
|
472
|
+
const gas = await this.publicClient.estimateGas({
|
|
473
|
+
to: this.contracts?.anchorPay || "",
|
|
474
|
+
data: calldata,
|
|
475
|
+
value: 0n,
|
|
476
|
+
account: this.account,
|
|
477
|
+
});
|
|
478
|
+
const txHash = await this.walletClient.sendTransaction({
|
|
479
|
+
account: this.account,
|
|
480
|
+
to: this.contracts?.anchorPay || "",
|
|
481
|
+
data: calldata,
|
|
482
|
+
maxFeePerGas: options?.maxFeePerGas || maxFeePerGas,
|
|
483
|
+
maxPriorityFeePerGas: options?.maxPriorityFeePerGas || maxPriorityFeePerGas,
|
|
484
|
+
gas: options?.gas || gas,
|
|
485
|
+
chain: this.publicClient.chain,
|
|
486
|
+
});
|
|
487
|
+
// 等待交易确认并返回收据
|
|
488
|
+
const receipt = await this.publicClient.waitForTransactionReceipt({
|
|
489
|
+
hash: txHash,
|
|
490
|
+
});
|
|
491
|
+
return receipt;
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* 批量存入 ETH(使用 Multicall3)
|
|
495
|
+
* @param deposits 批量存款参数数组,每项包含接收者地址和金额
|
|
496
|
+
* @param options 交易选项
|
|
497
|
+
* @returns 交易收据或交易数据
|
|
498
|
+
*/
|
|
499
|
+
async batchDepositETH(deposits, options) {
|
|
500
|
+
if (deposits.length === 0) {
|
|
501
|
+
throw new Error("No deposits provided");
|
|
502
|
+
}
|
|
503
|
+
// 如果需要发送交易,但没有钱包客户端或账户
|
|
504
|
+
if (options?.sendTransaction !== false &&
|
|
505
|
+
(!this.walletClient || !this.account)) {
|
|
506
|
+
throw new Error("Wallet client and account are required to send transactions");
|
|
507
|
+
}
|
|
508
|
+
// 准备批量调用数据
|
|
509
|
+
const calls = deposits.map((deposit) => {
|
|
510
|
+
const calldata = (0, viem_1.encodeFunctionData)({
|
|
511
|
+
abi: AnchorPay_json_1.default,
|
|
512
|
+
functionName: "depositFor",
|
|
513
|
+
args: [deposit.recipient, constants_1.NATIVE_TOKEN_ADDRESS, deposit.amount],
|
|
514
|
+
});
|
|
515
|
+
return {
|
|
516
|
+
target: this.contracts?.anchorPay || "",
|
|
517
|
+
allowFailure: false,
|
|
518
|
+
value: deposit.amount,
|
|
519
|
+
callData: calldata,
|
|
520
|
+
};
|
|
521
|
+
});
|
|
522
|
+
// 计算总金额
|
|
523
|
+
const totalValue = deposits.reduce((sum, deposit) => sum + deposit.amount, 0n);
|
|
524
|
+
// 编码 Multicall3 调用
|
|
525
|
+
const multicallData = (0, viem_1.encodeFunctionData)({
|
|
526
|
+
abi: constants_1.MULTICALL3_ABI,
|
|
527
|
+
functionName: "aggregate3Value",
|
|
528
|
+
args: [calls],
|
|
529
|
+
});
|
|
530
|
+
// 如果不需要发送交易,只返回交易数据(AA 模式)
|
|
531
|
+
if (options?.sendTransaction === false) {
|
|
532
|
+
return {
|
|
533
|
+
to: constants_1.MULTICALL3_ADDRESS,
|
|
534
|
+
data: multicallData,
|
|
535
|
+
value: totalValue,
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
// 估算 gas 和费用
|
|
539
|
+
const { maxFeePerGas, maxPriorityFeePerGas } = await this.publicClient.estimateFeesPerGas();
|
|
540
|
+
const gas = await this.publicClient.estimateGas({
|
|
541
|
+
to: constants_1.MULTICALL3_ADDRESS,
|
|
542
|
+
data: multicallData,
|
|
543
|
+
value: totalValue,
|
|
544
|
+
account: this.account,
|
|
545
|
+
});
|
|
546
|
+
// 发送交易(EOA 模式)
|
|
547
|
+
if (!this.walletClient || !this.account) {
|
|
548
|
+
throw new Error("Wallet client and account are required to send transactions");
|
|
549
|
+
}
|
|
550
|
+
const txHash = await this.walletClient.sendTransaction({
|
|
551
|
+
account: this.account,
|
|
552
|
+
to: constants_1.MULTICALL3_ADDRESS,
|
|
553
|
+
data: multicallData,
|
|
554
|
+
value: totalValue,
|
|
555
|
+
maxFeePerGas: options?.maxFeePerGas || maxFeePerGas,
|
|
556
|
+
maxPriorityFeePerGas: options?.maxPriorityFeePerGas || maxPriorityFeePerGas,
|
|
557
|
+
gas: options?.gas || gas,
|
|
558
|
+
chain: this.publicClient.chain,
|
|
559
|
+
});
|
|
560
|
+
// 等待交易确认并返回收据
|
|
561
|
+
const receipt = await this.publicClient.waitForTransactionReceipt({
|
|
562
|
+
hash: txHash,
|
|
563
|
+
});
|
|
564
|
+
return receipt;
|
|
565
|
+
}
|
|
566
|
+
/**
|
|
567
|
+
* 批量存入 ERC20 代币(使用 Multicall3)
|
|
568
|
+
* @param tokenAddress ERC20 代币地址
|
|
569
|
+
* @param deposits 批量存款参数数组
|
|
570
|
+
* @param options 交易选项
|
|
571
|
+
* @returns 交易收据或交易数据
|
|
572
|
+
*/
|
|
573
|
+
async batchDepositERC20(tokenAddress, deposits, options) {
|
|
574
|
+
if (deposits.length === 0) {
|
|
575
|
+
throw new Error("No deposits provided");
|
|
576
|
+
}
|
|
577
|
+
// 如果需要发送交易,但没有钱包客户端或账户
|
|
578
|
+
if (options?.sendTransaction !== false &&
|
|
579
|
+
(!this.walletClient || !this.account)) {
|
|
580
|
+
throw new Error("Wallet client and account are required to send transactions");
|
|
581
|
+
}
|
|
582
|
+
// 计算总金额(用于批准检查)
|
|
583
|
+
const totalAmount = deposits.reduce((sum, deposit) => sum + deposit.amount, 0n);
|
|
584
|
+
// 如果需要自动批准,则先批准代币(默认开启自动批准)
|
|
585
|
+
if (options?.autoApprove !== false && this.walletClient && this.account) {
|
|
586
|
+
try {
|
|
587
|
+
console.log(`Checking ERC20 token approval status: ${tokenAddress}`);
|
|
588
|
+
// 检查授权
|
|
589
|
+
const allowance = (await this.publicClient.readContract({
|
|
590
|
+
address: tokenAddress,
|
|
591
|
+
abi: constants_1.ERC20_ABI,
|
|
592
|
+
functionName: "allowance",
|
|
593
|
+
args: [this.account.address, this.contracts?.anchorPay],
|
|
594
|
+
}));
|
|
595
|
+
console.log(`Current allowance: ${allowance}, Required amount: ${totalAmount}, AnchorPay contract address: ${this.contracts?.anchorPay}`);
|
|
596
|
+
if (allowance < totalAmount) {
|
|
597
|
+
console.log(`Approving ${totalAmount} tokens to AnchorPay contract...`);
|
|
598
|
+
// 批准代币 - 使用最大可能值进行授权,避免多次授权
|
|
599
|
+
const maxApproveAmount = 2n ** 256n - 1n;
|
|
600
|
+
// 估算 gas 和费用
|
|
601
|
+
const { maxFeePerGas: approveMaxFeePerGas, maxPriorityFeePerGas: approveMaxPriorityFeePerGas, } = await this.publicClient.estimateFeesPerGas();
|
|
602
|
+
const approveCalldata = (0, viem_1.encodeFunctionData)({
|
|
603
|
+
abi: constants_1.ERC20_ABI,
|
|
604
|
+
functionName: "approve",
|
|
605
|
+
args: [this.contracts?.anchorPay, maxApproveAmount],
|
|
606
|
+
});
|
|
607
|
+
const approveGas = await this.publicClient.estimateGas({
|
|
608
|
+
to: tokenAddress,
|
|
609
|
+
data: approveCalldata,
|
|
610
|
+
value: 0n,
|
|
611
|
+
account: this.account,
|
|
612
|
+
});
|
|
613
|
+
const approveTxHash = await this.walletClient.writeContract({
|
|
614
|
+
account: this.account,
|
|
615
|
+
address: tokenAddress,
|
|
616
|
+
abi: constants_1.ERC20_ABI,
|
|
617
|
+
functionName: "approve",
|
|
618
|
+
args: [this.contracts?.anchorPay, maxApproveAmount],
|
|
619
|
+
chain: this.publicClient.chain,
|
|
620
|
+
maxFeePerGas: approveMaxFeePerGas,
|
|
621
|
+
maxPriorityFeePerGas: approveMaxPriorityFeePerGas,
|
|
622
|
+
gas: approveGas,
|
|
623
|
+
});
|
|
624
|
+
console.log(`Approval transaction sent, hash: ${approveTxHash}`);
|
|
625
|
+
// 等待交易确认
|
|
626
|
+
await this.publicClient.waitForTransactionReceipt({
|
|
627
|
+
hash: approveTxHash,
|
|
628
|
+
});
|
|
629
|
+
console.log(`Approval transaction confirmed`);
|
|
630
|
+
}
|
|
631
|
+
else {
|
|
632
|
+
console.log(`Sufficient allowance already exists, no need for additional approval`);
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
catch (error) {
|
|
636
|
+
console.error(`Approval failed:`, error);
|
|
637
|
+
throw new Error(`ERC20 approval failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
// 准备批量调用数据
|
|
641
|
+
const calls = deposits.map((deposit) => {
|
|
642
|
+
const calldata = (0, viem_1.encodeFunctionData)({
|
|
643
|
+
abi: AnchorPay_json_1.default,
|
|
644
|
+
functionName: "depositFor",
|
|
645
|
+
args: [deposit.recipient, tokenAddress, deposit.amount],
|
|
646
|
+
});
|
|
647
|
+
return {
|
|
648
|
+
target: this.contracts?.anchorPay || "",
|
|
649
|
+
allowFailure: false,
|
|
650
|
+
value: 0n,
|
|
651
|
+
callData: calldata,
|
|
652
|
+
};
|
|
653
|
+
});
|
|
654
|
+
// 编码 Multicall3 调用
|
|
655
|
+
const multicallData = (0, viem_1.encodeFunctionData)({
|
|
656
|
+
abi: constants_1.MULTICALL3_ABI,
|
|
657
|
+
functionName: "aggregate3Value",
|
|
658
|
+
args: [calls],
|
|
659
|
+
});
|
|
660
|
+
// 如果不需要发送交易,只返回交易数据(AA 模式)
|
|
661
|
+
if (options?.sendTransaction === false) {
|
|
662
|
+
return {
|
|
663
|
+
to: constants_1.MULTICALL3_ADDRESS,
|
|
664
|
+
data: multicallData,
|
|
665
|
+
value: 0n,
|
|
666
|
+
};
|
|
667
|
+
}
|
|
668
|
+
// 估算 gas 和费用
|
|
669
|
+
const { maxFeePerGas, maxPriorityFeePerGas } = await this.publicClient.estimateFeesPerGas();
|
|
670
|
+
const gas = await this.publicClient.estimateGas({
|
|
671
|
+
to: constants_1.MULTICALL3_ADDRESS,
|
|
672
|
+
data: multicallData,
|
|
673
|
+
value: 0n,
|
|
674
|
+
account: this.account,
|
|
675
|
+
});
|
|
676
|
+
// 发送交易(EOA 模式)
|
|
677
|
+
if (!this.walletClient || !this.account) {
|
|
678
|
+
throw new Error("Wallet client and account are required to send transactions");
|
|
679
|
+
}
|
|
680
|
+
const txHash = await this.walletClient.sendTransaction({
|
|
681
|
+
account: this.account,
|
|
682
|
+
to: constants_1.MULTICALL3_ADDRESS,
|
|
683
|
+
data: multicallData,
|
|
684
|
+
maxFeePerGas: options?.maxFeePerGas || maxFeePerGas,
|
|
685
|
+
maxPriorityFeePerGas: options?.maxPriorityFeePerGas || maxPriorityFeePerGas,
|
|
686
|
+
gas: options?.gas || gas,
|
|
687
|
+
chain: this.publicClient.chain,
|
|
688
|
+
});
|
|
689
|
+
// 等待交易确认并返回收据
|
|
690
|
+
const receipt = await this.publicClient.waitForTransactionReceipt({
|
|
691
|
+
hash: txHash,
|
|
692
|
+
});
|
|
693
|
+
return receipt;
|
|
694
|
+
}
|
|
695
|
+
/**
|
|
696
|
+
* 批量发送 ETH(使用 Multicall3)
|
|
697
|
+
* @param transfers 批量转账参数数组
|
|
698
|
+
* @param options 交易选项
|
|
699
|
+
* @returns 交易收据或交易数据
|
|
700
|
+
*/
|
|
701
|
+
async batchSendETH(transfers, options) {
|
|
702
|
+
if (transfers.length === 0) {
|
|
703
|
+
throw new Error("No transfers provided");
|
|
704
|
+
}
|
|
705
|
+
// 如果需要发送交易,但没有钱包客户端或账户
|
|
706
|
+
if (options?.sendTransaction !== false &&
|
|
707
|
+
(!this.walletClient || !this.account)) {
|
|
708
|
+
throw new Error("Wallet client and account are required to send transactions");
|
|
709
|
+
}
|
|
710
|
+
// 准备批量调用数据
|
|
711
|
+
const calls = transfers.map((transfer) => {
|
|
712
|
+
const calldata = (0, viem_1.encodeFunctionData)({
|
|
713
|
+
abi: AnchorPay_json_1.default,
|
|
714
|
+
functionName: "send",
|
|
715
|
+
args: [
|
|
716
|
+
transfer.recipient,
|
|
717
|
+
constants_1.NATIVE_TOKEN_ADDRESS,
|
|
718
|
+
transfer.amount,
|
|
719
|
+
transfer.data || "0x",
|
|
720
|
+
],
|
|
721
|
+
});
|
|
722
|
+
return {
|
|
723
|
+
target: this.contracts?.anchorPay || "",
|
|
724
|
+
allowFailure: false,
|
|
725
|
+
value: transfer.amount,
|
|
726
|
+
callData: calldata,
|
|
727
|
+
};
|
|
728
|
+
});
|
|
729
|
+
// 计算总金额
|
|
730
|
+
const totalValue = transfers.reduce((sum, transfer) => sum + transfer.amount, 0n);
|
|
731
|
+
// 编码 Multicall3 调用
|
|
732
|
+
const multicallData = (0, viem_1.encodeFunctionData)({
|
|
733
|
+
abi: constants_1.MULTICALL3_ABI,
|
|
734
|
+
functionName: "aggregate3Value",
|
|
735
|
+
args: [calls],
|
|
736
|
+
});
|
|
737
|
+
// 如果不需要发送交易,只返回交易数据(AA 模式)
|
|
738
|
+
if (options?.sendTransaction === false) {
|
|
739
|
+
return {
|
|
740
|
+
to: constants_1.MULTICALL3_ADDRESS,
|
|
741
|
+
data: multicallData,
|
|
742
|
+
value: totalValue,
|
|
743
|
+
};
|
|
744
|
+
}
|
|
745
|
+
// 估算 gas 和费用
|
|
746
|
+
const { maxFeePerGas, maxPriorityFeePerGas } = await this.publicClient.estimateFeesPerGas();
|
|
747
|
+
const gas = await this.publicClient.estimateGas({
|
|
748
|
+
to: constants_1.MULTICALL3_ADDRESS,
|
|
749
|
+
data: multicallData,
|
|
750
|
+
value: totalValue,
|
|
751
|
+
account: this.account,
|
|
752
|
+
});
|
|
753
|
+
// 发送交易(EOA 模式)
|
|
754
|
+
if (!this.walletClient || !this.account) {
|
|
755
|
+
throw new Error("Wallet client and account are required to send transactions");
|
|
756
|
+
}
|
|
757
|
+
const txHash = await this.walletClient.sendTransaction({
|
|
758
|
+
account: this.account,
|
|
759
|
+
to: constants_1.MULTICALL3_ADDRESS,
|
|
760
|
+
data: multicallData,
|
|
761
|
+
value: totalValue,
|
|
762
|
+
maxFeePerGas: options?.maxFeePerGas || maxFeePerGas,
|
|
763
|
+
maxPriorityFeePerGas: options?.maxPriorityFeePerGas || maxPriorityFeePerGas,
|
|
764
|
+
gas: options?.gas || gas,
|
|
765
|
+
chain: this.publicClient.chain,
|
|
766
|
+
});
|
|
767
|
+
// 等待交易确认并返回收据
|
|
768
|
+
const receipt = await this.publicClient.waitForTransactionReceipt({
|
|
769
|
+
hash: txHash,
|
|
770
|
+
});
|
|
771
|
+
return receipt;
|
|
772
|
+
}
|
|
773
|
+
/**
|
|
774
|
+
* 批量发送 ERC20 代币(使用 Multicall3)
|
|
775
|
+
* @param tokenAddress ERC20 代币地址
|
|
776
|
+
* @param transfers 批量转账参数数组
|
|
777
|
+
* @param options 交易选项
|
|
778
|
+
* @returns 交易收据或交易数据
|
|
779
|
+
*/
|
|
780
|
+
async batchSendERC20(tokenAddress, transfers, options) {
|
|
781
|
+
if (transfers.length === 0) {
|
|
782
|
+
throw new Error("No transfers provided");
|
|
783
|
+
}
|
|
784
|
+
// 如果需要发送交易,但没有钱包客户端或账户
|
|
785
|
+
if (options?.sendTransaction !== false &&
|
|
786
|
+
(!this.walletClient || !this.account)) {
|
|
787
|
+
throw new Error("Wallet client and account are required to send transactions");
|
|
788
|
+
}
|
|
789
|
+
// 计算总金额(用于批准检查)
|
|
790
|
+
const totalAmount = transfers.reduce((sum, transfer) => sum + transfer.amount, 0n);
|
|
791
|
+
// 如果需要自动批准,则先批准代币(默认开启自动批准)
|
|
792
|
+
if (options?.autoApprove !== false && this.walletClient && this.account) {
|
|
793
|
+
try {
|
|
794
|
+
console.log(`Checking ERC20 token approval status: ${tokenAddress}`);
|
|
795
|
+
// 检查授权
|
|
796
|
+
const allowance = (await this.publicClient.readContract({
|
|
797
|
+
address: tokenAddress,
|
|
798
|
+
abi: constants_1.ERC20_ABI,
|
|
799
|
+
functionName: "allowance",
|
|
800
|
+
args: [this.account.address, this.contracts?.anchorPay],
|
|
801
|
+
}));
|
|
802
|
+
console.log(`Current allowance: ${allowance}, Required amount: ${totalAmount}, AnchorPay contract address: ${this.contracts?.anchorPay}`);
|
|
803
|
+
if (allowance < totalAmount) {
|
|
804
|
+
console.log(`Approving ${totalAmount} tokens to AnchorPay contract...`);
|
|
805
|
+
// 批准代币 - 使用最大可能值进行授权,避免多次授权
|
|
806
|
+
const maxApproveAmount = 2n ** 256n - 1n;
|
|
807
|
+
// 估算 gas 和费用
|
|
808
|
+
const { maxFeePerGas: approveMaxFeePerGas, maxPriorityFeePerGas: approveMaxPriorityFeePerGas, } = await this.publicClient.estimateFeesPerGas();
|
|
809
|
+
const approveCalldata = (0, viem_1.encodeFunctionData)({
|
|
810
|
+
abi: constants_1.ERC20_ABI,
|
|
811
|
+
functionName: "approve",
|
|
812
|
+
args: [this.contracts?.anchorPay, maxApproveAmount],
|
|
813
|
+
});
|
|
814
|
+
const approveGas = await this.publicClient.estimateGas({
|
|
815
|
+
to: tokenAddress,
|
|
816
|
+
data: approveCalldata,
|
|
817
|
+
value: 0n,
|
|
818
|
+
account: this.account,
|
|
819
|
+
});
|
|
820
|
+
const approveTxHash = await this.walletClient.writeContract({
|
|
821
|
+
account: this.account,
|
|
822
|
+
address: tokenAddress,
|
|
823
|
+
abi: constants_1.ERC20_ABI,
|
|
824
|
+
functionName: "approve",
|
|
825
|
+
args: [this.contracts?.anchorPay, maxApproveAmount],
|
|
826
|
+
chain: this.publicClient.chain,
|
|
827
|
+
maxFeePerGas: approveMaxFeePerGas,
|
|
828
|
+
maxPriorityFeePerGas: approveMaxPriorityFeePerGas,
|
|
829
|
+
gas: approveGas,
|
|
830
|
+
});
|
|
831
|
+
console.log(`Approval transaction sent, hash: ${approveTxHash}`);
|
|
832
|
+
// 等待交易确认
|
|
833
|
+
await this.publicClient.waitForTransactionReceipt({
|
|
834
|
+
hash: approveTxHash,
|
|
835
|
+
});
|
|
836
|
+
console.log(`Approval transaction confirmed`);
|
|
837
|
+
}
|
|
838
|
+
else {
|
|
839
|
+
console.log(`Sufficient allowance already exists, no need for additional approval`);
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
catch (error) {
|
|
843
|
+
console.error(`Approval failed:`, error);
|
|
844
|
+
throw new Error(`ERC20 approval failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
// 准备批量调用数据
|
|
848
|
+
const calls = transfers.map((transfer) => {
|
|
849
|
+
const calldata = (0, viem_1.encodeFunctionData)({
|
|
850
|
+
abi: AnchorPay_json_1.default,
|
|
851
|
+
functionName: "send",
|
|
852
|
+
args: [
|
|
853
|
+
transfer.recipient,
|
|
854
|
+
tokenAddress,
|
|
855
|
+
transfer.amount,
|
|
856
|
+
transfer.data || "0x",
|
|
857
|
+
],
|
|
858
|
+
});
|
|
859
|
+
return {
|
|
860
|
+
target: this.contracts?.anchorPay || "",
|
|
861
|
+
allowFailure: false,
|
|
862
|
+
value: 0n,
|
|
863
|
+
callData: calldata,
|
|
864
|
+
};
|
|
865
|
+
});
|
|
866
|
+
// 编码 Multicall3 调用
|
|
867
|
+
const multicallData = (0, viem_1.encodeFunctionData)({
|
|
868
|
+
abi: constants_1.MULTICALL3_ABI,
|
|
869
|
+
functionName: "aggregate3Value",
|
|
870
|
+
args: [calls],
|
|
871
|
+
});
|
|
872
|
+
// 如果不需要发送交易,只返回交易数据(AA 模式)
|
|
873
|
+
if (options?.sendTransaction === false) {
|
|
874
|
+
return {
|
|
875
|
+
to: constants_1.MULTICALL3_ADDRESS,
|
|
876
|
+
data: multicallData,
|
|
877
|
+
value: 0n,
|
|
878
|
+
};
|
|
879
|
+
}
|
|
880
|
+
// 估算 gas 和费用
|
|
881
|
+
const { maxFeePerGas, maxPriorityFeePerGas } = await this.publicClient.estimateFeesPerGas();
|
|
882
|
+
const gas = await this.publicClient.estimateGas({
|
|
883
|
+
to: constants_1.MULTICALL3_ADDRESS,
|
|
884
|
+
data: multicallData,
|
|
885
|
+
value: 0n,
|
|
886
|
+
account: this.account,
|
|
887
|
+
});
|
|
888
|
+
// 发送交易(EOA 模式)
|
|
889
|
+
if (!this.walletClient || !this.account) {
|
|
890
|
+
throw new Error("Wallet client and account are required to send transactions");
|
|
891
|
+
}
|
|
892
|
+
const txHash = await this.walletClient.sendTransaction({
|
|
893
|
+
account: this.account,
|
|
894
|
+
to: constants_1.MULTICALL3_ADDRESS,
|
|
895
|
+
data: multicallData,
|
|
896
|
+
maxFeePerGas: options?.maxFeePerGas || maxFeePerGas,
|
|
897
|
+
maxPriorityFeePerGas: options?.maxPriorityFeePerGas || maxPriorityFeePerGas,
|
|
898
|
+
gas: options?.gas || gas,
|
|
899
|
+
chain: this.publicClient.chain,
|
|
900
|
+
});
|
|
901
|
+
// 等待交易确认并返回收据
|
|
902
|
+
const receipt = await this.publicClient.waitForTransactionReceipt({
|
|
903
|
+
hash: txHash,
|
|
904
|
+
});
|
|
905
|
+
return receipt;
|
|
906
|
+
}
|
|
274
907
|
}
|
|
275
908
|
exports.AnchorPayClient = AnchorPayClient;
|
package/dist/abi/AnchorPay.json
CHANGED
|
@@ -24,6 +24,53 @@
|
|
|
24
24
|
"outputs": [],
|
|
25
25
|
"stateMutability": "nonpayable"
|
|
26
26
|
},
|
|
27
|
+
{
|
|
28
|
+
"type": "function",
|
|
29
|
+
"name": "balanceOf",
|
|
30
|
+
"inputs": [
|
|
31
|
+
{
|
|
32
|
+
"name": "account",
|
|
33
|
+
"type": "address",
|
|
34
|
+
"internalType": "address"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"name": "token",
|
|
38
|
+
"type": "address",
|
|
39
|
+
"internalType": "address"
|
|
40
|
+
}
|
|
41
|
+
],
|
|
42
|
+
"outputs": [
|
|
43
|
+
{
|
|
44
|
+
"name": "",
|
|
45
|
+
"type": "uint256",
|
|
46
|
+
"internalType": "uint256"
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
"stateMutability": "view"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"type": "function",
|
|
53
|
+
"name": "depositFor",
|
|
54
|
+
"inputs": [
|
|
55
|
+
{
|
|
56
|
+
"name": "recipient",
|
|
57
|
+
"type": "address",
|
|
58
|
+
"internalType": "address"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"name": "token",
|
|
62
|
+
"type": "address",
|
|
63
|
+
"internalType": "address"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"name": "amount",
|
|
67
|
+
"type": "uint256",
|
|
68
|
+
"internalType": "uint256"
|
|
69
|
+
}
|
|
70
|
+
],
|
|
71
|
+
"outputs": [],
|
|
72
|
+
"stateMutability": "payable"
|
|
73
|
+
},
|
|
27
74
|
{
|
|
28
75
|
"type": "function",
|
|
29
76
|
"name": "getInterfaceImplementer",
|
|
@@ -203,6 +250,55 @@
|
|
|
203
250
|
"outputs": [],
|
|
204
251
|
"stateMutability": "payable"
|
|
205
252
|
},
|
|
253
|
+
{
|
|
254
|
+
"type": "function",
|
|
255
|
+
"name": "withdraw",
|
|
256
|
+
"inputs": [
|
|
257
|
+
{
|
|
258
|
+
"name": "token",
|
|
259
|
+
"type": "address",
|
|
260
|
+
"internalType": "address"
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
"name": "amount",
|
|
264
|
+
"type": "uint256",
|
|
265
|
+
"internalType": "uint256"
|
|
266
|
+
}
|
|
267
|
+
],
|
|
268
|
+
"outputs": [],
|
|
269
|
+
"stateMutability": "nonpayable"
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
"type": "event",
|
|
273
|
+
"name": "Deposited",
|
|
274
|
+
"inputs": [
|
|
275
|
+
{
|
|
276
|
+
"name": "from",
|
|
277
|
+
"type": "address",
|
|
278
|
+
"indexed": true,
|
|
279
|
+
"internalType": "address"
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
"name": "recipient",
|
|
283
|
+
"type": "address",
|
|
284
|
+
"indexed": true,
|
|
285
|
+
"internalType": "address"
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
"name": "token",
|
|
289
|
+
"type": "address",
|
|
290
|
+
"indexed": true,
|
|
291
|
+
"internalType": "address"
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
"name": "amount",
|
|
295
|
+
"type": "uint256",
|
|
296
|
+
"indexed": false,
|
|
297
|
+
"internalType": "uint256"
|
|
298
|
+
}
|
|
299
|
+
],
|
|
300
|
+
"anonymous": false
|
|
301
|
+
},
|
|
206
302
|
{
|
|
207
303
|
"type": "event",
|
|
208
304
|
"name": "Initialized",
|
|
@@ -323,6 +419,31 @@
|
|
|
323
419
|
],
|
|
324
420
|
"anonymous": false
|
|
325
421
|
},
|
|
422
|
+
{
|
|
423
|
+
"type": "event",
|
|
424
|
+
"name": "Withdrawn",
|
|
425
|
+
"inputs": [
|
|
426
|
+
{
|
|
427
|
+
"name": "recipient",
|
|
428
|
+
"type": "address",
|
|
429
|
+
"indexed": true,
|
|
430
|
+
"internalType": "address"
|
|
431
|
+
},
|
|
432
|
+
{
|
|
433
|
+
"name": "token",
|
|
434
|
+
"type": "address",
|
|
435
|
+
"indexed": true,
|
|
436
|
+
"internalType": "address"
|
|
437
|
+
},
|
|
438
|
+
{
|
|
439
|
+
"name": "amount",
|
|
440
|
+
"type": "uint256",
|
|
441
|
+
"indexed": false,
|
|
442
|
+
"internalType": "uint256"
|
|
443
|
+
}
|
|
444
|
+
],
|
|
445
|
+
"anonymous": false
|
|
446
|
+
},
|
|
326
447
|
{
|
|
327
448
|
"type": "error",
|
|
328
449
|
"name": "AddressEmptyCode",
|
|
@@ -360,6 +481,11 @@
|
|
|
360
481
|
"name": "FailedCall",
|
|
361
482
|
"inputs": []
|
|
362
483
|
},
|
|
484
|
+
{
|
|
485
|
+
"type": "error",
|
|
486
|
+
"name": "InsufficientBalance",
|
|
487
|
+
"inputs": []
|
|
488
|
+
},
|
|
363
489
|
{
|
|
364
490
|
"type": "error",
|
|
365
491
|
"name": "InsufficientPayment",
|
package/dist/constants.d.ts
CHANGED
|
@@ -47,3 +47,114 @@ export declare const INTERFACE_HASHES: {
|
|
|
47
47
|
TOKEN_RECEIVED: string;
|
|
48
48
|
};
|
|
49
49
|
export declare const NATIVE_TOKEN_ADDRESS = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
|
|
50
|
+
/**
|
|
51
|
+
* Multicall3 合约地址(跨链通用)
|
|
52
|
+
*/
|
|
53
|
+
export declare const MULTICALL3_ADDRESS = "0xcA11bde05977b3631167028862bE2a173976CA11";
|
|
54
|
+
/**
|
|
55
|
+
* Multicall3 合约 ABI
|
|
56
|
+
*/
|
|
57
|
+
export declare const MULTICALL3_ABI: readonly [{
|
|
58
|
+
readonly inputs: readonly [{
|
|
59
|
+
readonly components: readonly [{
|
|
60
|
+
readonly internalType: "address";
|
|
61
|
+
readonly name: "target";
|
|
62
|
+
readonly type: "address";
|
|
63
|
+
}, {
|
|
64
|
+
readonly internalType: "bytes";
|
|
65
|
+
readonly name: "callData";
|
|
66
|
+
readonly type: "bytes";
|
|
67
|
+
}];
|
|
68
|
+
readonly internalType: "struct Multicall3.Call[]";
|
|
69
|
+
readonly name: "calls";
|
|
70
|
+
readonly type: "tuple[]";
|
|
71
|
+
}];
|
|
72
|
+
readonly name: "aggregate";
|
|
73
|
+
readonly outputs: readonly [{
|
|
74
|
+
readonly internalType: "uint256";
|
|
75
|
+
readonly name: "blockNumber";
|
|
76
|
+
readonly type: "uint256";
|
|
77
|
+
}, {
|
|
78
|
+
readonly internalType: "bytes[]";
|
|
79
|
+
readonly name: "returnData";
|
|
80
|
+
readonly type: "bytes[]";
|
|
81
|
+
}];
|
|
82
|
+
readonly stateMutability: "payable";
|
|
83
|
+
readonly type: "function";
|
|
84
|
+
}, {
|
|
85
|
+
readonly inputs: readonly [{
|
|
86
|
+
readonly components: readonly [{
|
|
87
|
+
readonly internalType: "address";
|
|
88
|
+
readonly name: "target";
|
|
89
|
+
readonly type: "address";
|
|
90
|
+
}, {
|
|
91
|
+
readonly internalType: "bool";
|
|
92
|
+
readonly name: "allowFailure";
|
|
93
|
+
readonly type: "bool";
|
|
94
|
+
}, {
|
|
95
|
+
readonly internalType: "bytes";
|
|
96
|
+
readonly name: "callData";
|
|
97
|
+
readonly type: "bytes";
|
|
98
|
+
}];
|
|
99
|
+
readonly internalType: "struct Multicall3.Call3[]";
|
|
100
|
+
readonly name: "calls";
|
|
101
|
+
readonly type: "tuple[]";
|
|
102
|
+
}];
|
|
103
|
+
readonly name: "aggregate3";
|
|
104
|
+
readonly outputs: readonly [{
|
|
105
|
+
readonly components: readonly [{
|
|
106
|
+
readonly internalType: "bool";
|
|
107
|
+
readonly name: "success";
|
|
108
|
+
readonly type: "bool";
|
|
109
|
+
}, {
|
|
110
|
+
readonly internalType: "bytes";
|
|
111
|
+
readonly name: "returnData";
|
|
112
|
+
readonly type: "bytes";
|
|
113
|
+
}];
|
|
114
|
+
readonly internalType: "struct Multicall3.Result[]";
|
|
115
|
+
readonly name: "returnData";
|
|
116
|
+
readonly type: "tuple[]";
|
|
117
|
+
}];
|
|
118
|
+
readonly stateMutability: "payable";
|
|
119
|
+
readonly type: "function";
|
|
120
|
+
}, {
|
|
121
|
+
readonly inputs: readonly [{
|
|
122
|
+
readonly components: readonly [{
|
|
123
|
+
readonly internalType: "address";
|
|
124
|
+
readonly name: "target";
|
|
125
|
+
readonly type: "address";
|
|
126
|
+
}, {
|
|
127
|
+
readonly internalType: "bool";
|
|
128
|
+
readonly name: "allowFailure";
|
|
129
|
+
readonly type: "bool";
|
|
130
|
+
}, {
|
|
131
|
+
readonly internalType: "uint256";
|
|
132
|
+
readonly name: "value";
|
|
133
|
+
readonly type: "uint256";
|
|
134
|
+
}, {
|
|
135
|
+
readonly internalType: "bytes";
|
|
136
|
+
readonly name: "callData";
|
|
137
|
+
readonly type: "bytes";
|
|
138
|
+
}];
|
|
139
|
+
readonly internalType: "struct Multicall3.Call3Value[]";
|
|
140
|
+
readonly name: "calls";
|
|
141
|
+
readonly type: "tuple[]";
|
|
142
|
+
}];
|
|
143
|
+
readonly name: "aggregate3Value";
|
|
144
|
+
readonly outputs: readonly [{
|
|
145
|
+
readonly components: readonly [{
|
|
146
|
+
readonly internalType: "bool";
|
|
147
|
+
readonly name: "success";
|
|
148
|
+
readonly type: "bool";
|
|
149
|
+
}, {
|
|
150
|
+
readonly internalType: "bytes";
|
|
151
|
+
readonly name: "returnData";
|
|
152
|
+
readonly type: "bytes";
|
|
153
|
+
}];
|
|
154
|
+
readonly internalType: "struct Multicall3.Result[]";
|
|
155
|
+
readonly name: "returnData";
|
|
156
|
+
readonly type: "tuple[]";
|
|
157
|
+
}];
|
|
158
|
+
readonly stateMutability: "payable";
|
|
159
|
+
readonly type: "function";
|
|
160
|
+
}];
|
package/dist/constants.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.NATIVE_TOKEN_ADDRESS = exports.INTERFACE_HASHES = exports.ENVIRONMENTS = exports.ERC20_ABI = exports.Environment = void 0;
|
|
3
|
+
exports.MULTICALL3_ABI = exports.MULTICALL3_ADDRESS = exports.NATIVE_TOKEN_ADDRESS = exports.INTERFACE_HASHES = exports.ENVIRONMENTS = exports.ERC20_ABI = exports.Environment = void 0;
|
|
4
4
|
const chains_1 = require("viem/chains");
|
|
5
5
|
/**
|
|
6
6
|
* 环境枚举
|
|
@@ -219,3 +219,149 @@ exports.INTERFACE_HASHES = {
|
|
|
219
219
|
TOKEN_RECEIVED: "0x8b2cb2c7b7e2282e2e4b29a6a8c2b2db4218c6a5f8e8fcb3d5598f3e1e6c59d9",
|
|
220
220
|
};
|
|
221
221
|
exports.NATIVE_TOKEN_ADDRESS = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
|
|
222
|
+
/**
|
|
223
|
+
* Multicall3 合约地址(跨链通用)
|
|
224
|
+
*/
|
|
225
|
+
exports.MULTICALL3_ADDRESS = "0xcA11bde05977b3631167028862bE2a173976CA11";
|
|
226
|
+
/**
|
|
227
|
+
* Multicall3 合约 ABI
|
|
228
|
+
*/
|
|
229
|
+
exports.MULTICALL3_ABI = [
|
|
230
|
+
{
|
|
231
|
+
inputs: [
|
|
232
|
+
{
|
|
233
|
+
components: [
|
|
234
|
+
{
|
|
235
|
+
internalType: "address",
|
|
236
|
+
name: "target",
|
|
237
|
+
type: "address",
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
internalType: "bytes",
|
|
241
|
+
name: "callData",
|
|
242
|
+
type: "bytes",
|
|
243
|
+
},
|
|
244
|
+
],
|
|
245
|
+
internalType: "struct Multicall3.Call[]",
|
|
246
|
+
name: "calls",
|
|
247
|
+
type: "tuple[]",
|
|
248
|
+
},
|
|
249
|
+
],
|
|
250
|
+
name: "aggregate",
|
|
251
|
+
outputs: [
|
|
252
|
+
{
|
|
253
|
+
internalType: "uint256",
|
|
254
|
+
name: "blockNumber",
|
|
255
|
+
type: "uint256",
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
internalType: "bytes[]",
|
|
259
|
+
name: "returnData",
|
|
260
|
+
type: "bytes[]",
|
|
261
|
+
},
|
|
262
|
+
],
|
|
263
|
+
stateMutability: "payable",
|
|
264
|
+
type: "function",
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
inputs: [
|
|
268
|
+
{
|
|
269
|
+
components: [
|
|
270
|
+
{
|
|
271
|
+
internalType: "address",
|
|
272
|
+
name: "target",
|
|
273
|
+
type: "address",
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
internalType: "bool",
|
|
277
|
+
name: "allowFailure",
|
|
278
|
+
type: "bool",
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
internalType: "bytes",
|
|
282
|
+
name: "callData",
|
|
283
|
+
type: "bytes",
|
|
284
|
+
},
|
|
285
|
+
],
|
|
286
|
+
internalType: "struct Multicall3.Call3[]",
|
|
287
|
+
name: "calls",
|
|
288
|
+
type: "tuple[]",
|
|
289
|
+
},
|
|
290
|
+
],
|
|
291
|
+
name: "aggregate3",
|
|
292
|
+
outputs: [
|
|
293
|
+
{
|
|
294
|
+
components: [
|
|
295
|
+
{
|
|
296
|
+
internalType: "bool",
|
|
297
|
+
name: "success",
|
|
298
|
+
type: "bool",
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
internalType: "bytes",
|
|
302
|
+
name: "returnData",
|
|
303
|
+
type: "bytes",
|
|
304
|
+
},
|
|
305
|
+
],
|
|
306
|
+
internalType: "struct Multicall3.Result[]",
|
|
307
|
+
name: "returnData",
|
|
308
|
+
type: "tuple[]",
|
|
309
|
+
},
|
|
310
|
+
],
|
|
311
|
+
stateMutability: "payable",
|
|
312
|
+
type: "function",
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
inputs: [
|
|
316
|
+
{
|
|
317
|
+
components: [
|
|
318
|
+
{
|
|
319
|
+
internalType: "address",
|
|
320
|
+
name: "target",
|
|
321
|
+
type: "address",
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
internalType: "bool",
|
|
325
|
+
name: "allowFailure",
|
|
326
|
+
type: "bool",
|
|
327
|
+
},
|
|
328
|
+
{
|
|
329
|
+
internalType: "uint256",
|
|
330
|
+
name: "value",
|
|
331
|
+
type: "uint256",
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
internalType: "bytes",
|
|
335
|
+
name: "callData",
|
|
336
|
+
type: "bytes",
|
|
337
|
+
},
|
|
338
|
+
],
|
|
339
|
+
internalType: "struct Multicall3.Call3Value[]",
|
|
340
|
+
name: "calls",
|
|
341
|
+
type: "tuple[]",
|
|
342
|
+
},
|
|
343
|
+
],
|
|
344
|
+
name: "aggregate3Value",
|
|
345
|
+
outputs: [
|
|
346
|
+
{
|
|
347
|
+
components: [
|
|
348
|
+
{
|
|
349
|
+
internalType: "bool",
|
|
350
|
+
name: "success",
|
|
351
|
+
type: "bool",
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
internalType: "bytes",
|
|
355
|
+
name: "returnData",
|
|
356
|
+
type: "bytes",
|
|
357
|
+
},
|
|
358
|
+
],
|
|
359
|
+
internalType: "struct Multicall3.Result[]",
|
|
360
|
+
name: "returnData",
|
|
361
|
+
type: "tuple[]",
|
|
362
|
+
},
|
|
363
|
+
],
|
|
364
|
+
stateMutability: "payable",
|
|
365
|
+
type: "function",
|
|
366
|
+
},
|
|
367
|
+
];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "anchor-sdk",
|
|
3
|
-
"version": "0.1.41-internal.
|
|
3
|
+
"version": "0.1.41-internal.6",
|
|
4
4
|
"description": "TypeScript SDK for interacting with Anchor ecosystem - badge minting, payment processing, and ERC1155 token management",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|