four-flap-meme-sdk 4.3.13 → 4.3.14
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.
|
@@ -10,6 +10,9 @@ export type { DisperseHopPath } from './types/hop-chains.js';
|
|
|
10
10
|
export declare const NATIVE_TRANSFER_GAS_LIMIT: 21055n;
|
|
11
11
|
export declare const ERC20_TRANSFER_GAS_LIMIT_HOP: 120000n;
|
|
12
12
|
export declare const BRIBE_GAS_LIMIT: 21000n;
|
|
13
|
+
/** 末跳且买地址自备 gas 时,hop 不再转发原生币,ERC20 必须从 nonce 0 起。 */
|
|
14
|
+
export declare function hopForwardsNativeGas(index: number, hopCount: number, finalGasAmount: bigint): boolean;
|
|
15
|
+
export declare function hopErc20Nonce(index: number, hopCount: number, finalGasAmount: bigint): number;
|
|
13
16
|
/**
|
|
14
17
|
* 给交易对象附加 gasPrice/maxFeePerGas(根据 txType)
|
|
15
18
|
*/
|
|
@@ -25,7 +28,7 @@ export declare function buildNativeHopChain(payer: Wallet, path: DisperseHopPath
|
|
|
25
28
|
/**
|
|
26
29
|
* 构建 ERC20 多跳转账链(需要配合 BNB 多跳使用)
|
|
27
30
|
*/
|
|
28
|
-
export declare function buildERC20HopChain(payer: Wallet, path: DisperseHopPath, erc20Address: string, erc20Amount: bigint, gasPrice: bigint, chainId: number, txType: 0 | 2, payerNonce: number): Promise<string[]>;
|
|
31
|
+
export declare function buildERC20HopChain(payer: Wallet, path: DisperseHopPath, erc20Address: string, erc20Amount: bigint, gasPrice: bigint, chainId: number, txType: 0 | 2, payerNonce: number, finalNativeForwardAmount?: bigint): Promise<string[]>;
|
|
29
32
|
/**
|
|
30
33
|
* 构建 BNB 多跳转账链(为 ERC20 中间钱包预留 gas)
|
|
31
34
|
*/
|
package/dist/utils/hop-chains.js
CHANGED
|
@@ -11,6 +11,15 @@ import { generateWallets } from './wallet.js';
|
|
|
11
11
|
export const NATIVE_TRANSFER_GAS_LIMIT = GAS_LIMITS.NATIVE_TRANSFER;
|
|
12
12
|
export const ERC20_TRANSFER_GAS_LIMIT_HOP = GAS_LIMITS.ERC20_TRANSFER;
|
|
13
13
|
export const BRIBE_GAS_LIMIT = GAS_LIMITS.BRIBE;
|
|
14
|
+
/** 末跳且买地址自备 gas 时,hop 不再转发原生币,ERC20 必须从 nonce 0 起。 */
|
|
15
|
+
export function hopForwardsNativeGas(index, hopCount, finalGasAmount) {
|
|
16
|
+
if (hopCount <= 0 || index < 0 || index >= hopCount)
|
|
17
|
+
return false;
|
|
18
|
+
return !(index === hopCount - 1 && finalGasAmount === 0n);
|
|
19
|
+
}
|
|
20
|
+
export function hopErc20Nonce(index, hopCount, finalGasAmount) {
|
|
21
|
+
return hopForwardsNativeGas(index, hopCount, finalGasAmount) ? 1 : 0;
|
|
22
|
+
}
|
|
14
23
|
/**
|
|
15
24
|
* 给交易对象附加 gasPrice/maxFeePerGas(根据 txType)
|
|
16
25
|
*/
|
|
@@ -107,7 +116,7 @@ export async function buildNativeHopChain(payer, path, finalAmount, gasPrice, ch
|
|
|
107
116
|
/**
|
|
108
117
|
* 构建 ERC20 多跳转账链(需要配合 BNB 多跳使用)
|
|
109
118
|
*/
|
|
110
|
-
export async function buildERC20HopChain(payer, path, erc20Address, erc20Amount, gasPrice, chainId, txType, payerNonce) {
|
|
119
|
+
export async function buildERC20HopChain(payer, path, erc20Address, erc20Amount, gasPrice, chainId, txType, payerNonce, finalNativeForwardAmount = 0n) {
|
|
111
120
|
const signedTxs = [];
|
|
112
121
|
const hopCount = path.hopWallets.length;
|
|
113
122
|
const erc20Interface = new ethers.Interface(ERC20_ABI);
|
|
@@ -139,7 +148,7 @@ export async function buildERC20HopChain(payer, path, erc20Address, erc20Amount,
|
|
|
139
148
|
};
|
|
140
149
|
applyTxTypeGas(firstTx, gasPrice, txType);
|
|
141
150
|
signedTxs.push(await payer.signTransaction(firstTx));
|
|
142
|
-
// hop1 → hop2 → ... → target
|
|
151
|
+
// hop1 → hop2 → ... → target。末跳若不再转发 BNB,ERC20 用 nonce=0。
|
|
143
152
|
for (let i = 0; i < hopCount; i++) {
|
|
144
153
|
const fromWallet = path.hopWallets[i];
|
|
145
154
|
const toAddress = i === hopCount - 1 ? path.targetAddress : path.hopWallets[i + 1].address;
|
|
@@ -148,7 +157,7 @@ export async function buildERC20HopChain(payer, path, erc20Address, erc20Amount,
|
|
|
148
157
|
to: erc20Address,
|
|
149
158
|
data,
|
|
150
159
|
value: 0n,
|
|
151
|
-
nonce:
|
|
160
|
+
nonce: hopErc20Nonce(i, hopCount, finalNativeForwardAmount),
|
|
152
161
|
gasLimit: ERC20_TRANSFER_GAS_LIMIT_HOP,
|
|
153
162
|
chainId,
|
|
154
163
|
type: txType,
|
|
@@ -197,7 +206,7 @@ export async function buildBNBHopChainForERC20(payer, path, finalGasAmount, gasP
|
|
|
197
206
|
const fromWallet = path.hopWallets[i];
|
|
198
207
|
const toAddress = i === hopCount - 1 ? path.targetAddress : path.hopWallets[i + 1].address;
|
|
199
208
|
const amount = i === hopCount - 1 ? finalGasAmount : amountsPerHop[i + 1];
|
|
200
|
-
if (i
|
|
209
|
+
if (!hopForwardsNativeGas(i, hopCount, finalGasAmount))
|
|
201
210
|
continue;
|
|
202
211
|
const tx = {
|
|
203
212
|
to: toAddress,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { hopErc20Nonce, hopForwardsNativeGas } from './hop-chains.js';
|
|
3
|
+
describe('hopErc20Nonce', () => {
|
|
4
|
+
it('uses nonce 0 on a single hop when the buyer keeps its own gas', () => {
|
|
5
|
+
expect(hopForwardsNativeGas(0, 1, 0n)).toBe(false);
|
|
6
|
+
expect(hopErc20Nonce(0, 1, 0n)).toBe(0);
|
|
7
|
+
});
|
|
8
|
+
it('keeps nonce 1 on intermediate hops and 0 on the last hop', () => {
|
|
9
|
+
expect(hopErc20Nonce(0, 2, 0n)).toBe(1);
|
|
10
|
+
expect(hopErc20Nonce(1, 2, 0n)).toBe(0);
|
|
11
|
+
});
|
|
12
|
+
it('uses nonce 1 on the last hop when it also forwards native gas', () => {
|
|
13
|
+
expect(hopForwardsNativeGas(0, 1, 1n)).toBe(true);
|
|
14
|
+
expect(hopErc20Nonce(0, 1, 1n)).toBe(1);
|
|
15
|
+
});
|
|
16
|
+
});
|