four-flap-meme-sdk 2.0.0 → 2.1.0
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/__tests__/subpath-exports.test.js +34 -0
- package/dist/chains/index.d.ts +13 -0
- package/dist/chains/index.js +13 -0
- package/dist/chains/xlayer/eip7702/index.d.ts +2 -0
- package/dist/flap/index.d.ts +10 -0
- package/dist/flap/index.js +8 -0
- package/dist/shared/constants/index.d.ts +2 -0
- package/dist/shared/index.d.ts +2 -0
- package/package.json +66 -1
- package/dist/chains/bsc/four/disperse.d.ts +0 -12
- package/dist/chains/bsc/four/disperse.js +0 -470
- package/dist/chains/bsc/four/pairwise.d.ts +0 -7
- package/dist/chains/bsc/four/pairwise.js +0 -308
- package/dist/chains/bsc/four/submit/blockrazor.d.ts +0 -18
- package/dist/chains/bsc/four/submit/blockrazor.js +0 -86
- package/dist/chains/bsc/four/submit/direct.d.ts +0 -66
- package/dist/chains/bsc/four/submit/direct.js +0 -452
- package/dist/chains/bsc/four/submit/helpers.d.ts +0 -18
- package/dist/chains/bsc/four/submit/helpers.js +0 -57
- package/dist/chains/bsc/four/submit/index.d.ts +0 -12
- package/dist/chains/bsc/four/submit/index.js +0 -11
- package/dist/chains/bsc/four/submit/merkle.d.ts +0 -18
- package/dist/chains/bsc/four/submit/merkle.js +0 -74
- package/dist/chains/bsc/four/submit/types.d.ts +0 -143
- package/dist/chains/bsc/four/swap/index.d.ts +0 -32
- package/dist/chains/bsc/four/swap/index.js +0 -829
- package/dist/chains/bsc/four/swap/types.d.ts +0 -70
- package/dist/chains/bsc/four/swap/types.js +0 -1
- package/dist/chains/bsc/four/sweep.d.ts +0 -13
- package/dist/chains/bsc/four/sweep.js +0 -788
- package/dist/chains/bsc/four/utils/index.d.ts +0 -20
- package/dist/chains/bsc/four/utils/index.js +0 -1558
- package/dist/chains/bsc/four/utils/types.d.ts +0 -1
- package/dist/chains/bsc/four/utils/types.js +0 -1
- package/dist/chains/bsc/pancake/bundle-buy-first/index.d.ts +0 -8
- package/dist/chains/bsc/pancake/bundle-buy-first/index.js +0 -907
- package/dist/chains/bsc/pancake/bundle-buy-first/types.d.ts +0 -73
- package/dist/chains/bsc/pancake/bundle-buy-first/types.js +0 -1
- package/dist/chains/bsc/pancake/bundle-swap/helpers.d.ts +0 -102
- package/dist/chains/bsc/pancake/bundle-swap/helpers.js +0 -572
- package/dist/chains/bsc/pancake/bundle-swap/index.d.ts +0 -50
- package/dist/chains/bsc/pancake/bundle-swap/index.js +0 -1066
- package/dist/chains/bsc/pancake/bundle-swap/types.d.ts +0 -202
- package/dist/chains/bsc/pancake/bundle-swap/types.js +0 -3
- package/dist/chains/xlayer/eip7702/bundle-swap/index.d.ts +0 -72
- package/dist/chains/xlayer/eip7702/bundle-swap/index.js +0 -921
- package/dist/chains/xlayer/eip7702/bundle-swap/types.d.ts +0 -65
- package/dist/chains/xlayer/eip7702/bundle-swap/types.js +0 -1
- package/dist/chains/xlayer/eip7702/multi-hop-transfer/index.d.ts +0 -128
- package/dist/chains/xlayer/eip7702/multi-hop-transfer/index.js +0 -857
- package/dist/chains/xlayer/eip7702/multi-hop-transfer/types.d.ts +0 -85
- package/dist/chains/xlayer/eip7702/multi-hop-transfer/types.js +0 -1
- package/dist/chains/xlayer/eip7702/volume/index.d.ts +0 -96
- package/dist/chains/xlayer/eip7702/volume/index.js +0 -793
- package/dist/chains/xlayer/eip7702/volume/types.d.ts +0 -124
- package/dist/chains/xlayer/eip7702/volume/types.js +0 -1
- package/dist/chains/xlayer/eoa/types-core.d.ts +0 -363
- package/dist/chains/xlayer/eoa/types-core.js +0 -53
- package/dist/chains/xlayer/eoa/types-create.d.ts +0 -413
- package/dist/chains/xlayer/eoa/types-create.js +0 -9
- package/dist/chains/xlayer/eoa/types-volume.d.ts +0 -209
- package/dist/chains/xlayer/eoa/types-volume.js +0 -13
- package/dist/dex/direct-router/index.d.ts +0 -70
- package/dist/dex/direct-router/index.js +0 -1410
- package/dist/dex/direct-router/types.d.ts +0 -81
- package/dist/dex/direct-router/types.js +0 -1
- package/dist/shared/abis/TaxToken.json +0 -969
- package/dist/shared/abis/TokenManager.json +0 -836
- package/dist/shared/abis/TokenManager2.json +0 -136
- package/dist/shared/abis/TokenManagerHelper3.json +0 -993
- package/dist/shared/abis 2/TaxToken.json +0 -105
- package/dist/shared/abis 2/TokenManager.json +0 -836
- package/dist/shared/abis 2/TokenManager2.json +0 -60
- package/dist/shared/abis 2/TokenManagerHelper3.json +0 -993
- package/dist/shared/abis 2/common.d.ts +0 -85
- package/dist/shared/abis 2/common.js +0 -254
- package/dist/shared/abis 2/index.d.ts +0 -8
- package/dist/shared/abis 2/index.js +0 -8
- package/dist/shared/clients 2/blockrazor.d.ts +0 -314
- package/dist/shared/clients 2/blockrazor.js +0 -596
- package/dist/shared/clients 2/club48.d.ts +0 -154
- package/dist/shared/clients 2/club48.js +0 -331
- package/dist/shared/clients 2/emitservice.d.ts +0 -47
- package/dist/shared/clients 2/emitservice.js +0 -44
- package/dist/shared/clients 2/four.d.ts +0 -132
- package/dist/shared/clients 2/four.js +0 -281
- package/dist/shared/clients 2/merkle.d.ts +0 -210
- package/dist/shared/clients 2/merkle.js +0 -400
- package/dist/shared/flap/__tests__/curve.test.d.ts +0 -1
- package/dist/shared/flap/__tests__/curve.test.js +0 -85
- package/dist/shared/flap/portal/index.d.ts +0 -12
- package/dist/shared/flap/portal/index.js +0 -11
- package/dist/shared/flap/portal/portal.d.ts +0 -47
- package/dist/shared/flap/portal/portal.js +0 -218
- package/dist/shared/flap/portal/types.d.ts +0 -227
- package/dist/shared/flap/portal/types.js +0 -80
- package/dist/shared/flap/portal/writer.d.ts +0 -121
- package/dist/shared/flap/portal/writer.js +0 -265
- package/dist/shared/flap/portal-bundle-merkle/core/index.d.ts +0 -18
- package/dist/shared/flap/portal-bundle-merkle/core/index.js +0 -938
- package/dist/shared/flap/portal-bundle-merkle/core/types.d.ts +0 -1
- package/dist/shared/flap/portal-bundle-merkle/core/types.js +0 -1
- package/dist/shared/flap/portal-bundle-merkle/swap/index.d.ts +0 -42
- package/dist/shared/flap/portal-bundle-merkle/swap/index.js +0 -1448
- package/dist/shared/flap/portal-bundle-merkle/swap/types.d.ts +0 -84
- package/dist/shared/flap/portal-bundle-merkle/swap/types.js +0 -1
- package/dist/shared/flap/portal-bundle-merkle/utils/index.d.ts +0 -17
- package/dist/shared/flap/portal-bundle-merkle/utils/index.js +0 -1024
- package/dist/shared/flap/portal-bundle-merkle/utils/types.d.ts +0 -16
- package/dist/shared/flap/portal-bundle-merkle/utils/types.js +0 -1
- package/dist/shared/flap/portal-bundle-merkle/utils-helpers.d.ts +0 -100
- package/dist/shared/flap/portal-bundle-merkle/utils-helpers.js +0 -133
- package/dist/shared/flap 2/__tests__/curve.test.d.ts +0 -1
- package/dist/shared/flap 2/__tests__/curve.test.js +0 -85
- package/dist/shared/flap 2/abi.d.ts +0 -4
- package/dist/shared/flap 2/abi.js +0 -4
- package/dist/shared/flap 2/constants.d.ts +0 -128
- package/dist/shared/flap 2/constants.js +0 -143
- package/dist/shared/flap 2/curve.d.ts +0 -33
- package/dist/shared/flap 2/curve.js +0 -84
- package/dist/shared/flap 2/errors.d.ts +0 -37
- package/dist/shared/flap 2/errors.js +0 -114
- package/dist/shared/flap 2/index.d.ts +0 -22
- package/dist/shared/flap 2/index.js +0 -33
- package/dist/shared/flap 2/ipfs.d.ts +0 -21
- package/dist/shared/flap 2/ipfs.js +0 -38
- package/dist/shared/flap 2/meta.d.ts +0 -30
- package/dist/shared/flap 2/meta.js +0 -195
- package/dist/shared/flap 2/permit.d.ts +0 -16
- package/dist/shared/flap 2/permit.js +0 -67
- package/dist/shared/flap 2/pinata.d.ts +0 -40
- package/dist/shared/flap 2/pinata.js +0 -106
- package/dist/shared/flap 2/portal-bundle-merkle/config.d.ts +0 -79
- package/dist/shared/flap 2/portal-bundle-merkle/config.js +0 -133
- package/dist/shared/flap 2/portal-bundle-merkle/core.d.ts +0 -18
- package/dist/shared/flap 2/portal-bundle-merkle/core.js +0 -938
- package/dist/shared/flap 2/portal-bundle-merkle/create-to-dex.d.ts +0 -125
- package/dist/shared/flap 2/portal-bundle-merkle/create-to-dex.js +0 -665
- package/dist/shared/flap 2/portal-bundle-merkle/curve-to-dex.d.ts +0 -88
- package/dist/shared/flap 2/portal-bundle-merkle/curve-to-dex.js +0 -446
- package/dist/shared/flap 2/portal-bundle-merkle/index.d.ts +0 -14
- package/dist/shared/flap 2/portal-bundle-merkle/index.js +0 -26
- package/dist/shared/flap 2/portal-bundle-merkle/pancake-proxy.d.ts +0 -28
- package/dist/shared/flap 2/portal-bundle-merkle/pancake-proxy.js +0 -701
- package/dist/shared/flap 2/portal-bundle-merkle/private.d.ts +0 -17
- package/dist/shared/flap 2/portal-bundle-merkle/private.js +0 -549
- package/dist/shared/flap 2/portal-bundle-merkle/swap-buy-first.d.ts +0 -65
- package/dist/shared/flap 2/portal-bundle-merkle/swap-buy-first.js +0 -831
- package/dist/shared/flap 2/portal-bundle-merkle/swap.d.ts +0 -201
- package/dist/shared/flap 2/portal-bundle-merkle/swap.js +0 -1359
- package/dist/shared/flap 2/portal-bundle-merkle/types.d.ts +0 -358
- package/dist/shared/flap 2/portal-bundle-merkle/types.js +0 -1
- package/dist/shared/flap 2/portal-bundle-merkle/utils.d.ts +0 -89
- package/dist/shared/flap 2/portal-bundle-merkle/utils.js +0 -963
- package/dist/shared/flap 2/portal-bundle.d.ts +0 -119
- package/dist/shared/flap 2/portal-bundle.js +0 -584
- package/dist/shared/flap 2/portal.d.ts +0 -392
- package/dist/shared/flap 2/portal.js +0 -559
- package/dist/shared/flap 2/vanity.d.ts +0 -48
- package/dist/shared/flap 2/vanity.js +0 -110
- package/dist/shared/flap 2/vault.d.ts +0 -240
- package/dist/shared/flap 2/vault.js +0 -366
- package/dist/shared/four 2/index.d.ts +0 -7
- package/dist/shared/four 2/index.js +0 -22
- package/dist/shared/four 2/tax-token.d.ts +0 -176
- package/dist/shared/four 2/tax-token.js +0 -302
- package/dist/shared/index 2.js +0 -10
- package/dist/shared/index.d 2.ts +0 -10
- package/dist/types/distribute.d.ts +0 -72
- package/dist/types/distribute.js +0 -1
- package/dist/types 2/errors.d.ts +0 -27
- package/dist/types 2/errors.js +0 -34
- package/dist/utils/__tests__/errors.test.d.ts +0 -1
- package/dist/utils/__tests__/errors.test.js +0 -76
- package/dist/utils/airdrop-sweep-types.d.ts +0 -1
- package/dist/utils/airdrop-sweep-types.js +0 -1
- package/dist/utils/erc20/index.d.ts +0 -242
- package/dist/utils/erc20/index.js +0 -645
- package/dist/utils/erc20/types.d.ts +0 -77
- package/dist/utils/erc20/types.js +0 -1
- package/dist/utils/erc20-types.d.ts +0 -1
- package/dist/utils/erc20-types.js +0 -1
- package/dist/utils/holders-maker/helpers.d.ts +0 -43
- package/dist/utils/holders-maker/helpers.js +0 -371
- package/dist/utils/holders-maker/index.d.ts +0 -26
- package/dist/utils/holders-maker/index.js +0 -218
- package/dist/utils/holders-maker/types.d.ts +0 -72
- package/dist/utils/holders-maker/types.js +0 -4
- package/dist/utils/holders-maker-types.d.ts +0 -1
- package/dist/utils/holders-maker-types.js +0 -1
- package/dist/utils/lp-inspect/index.d.ts +0 -44
- package/dist/utils/lp-inspect/index.js +0 -937
- package/dist/utils/lp-inspect/types.d.ts +0 -100
- package/dist/utils/lp-inspect/types.js +0 -1
- package/dist/utils/lp-inspect-types.d.ts +0 -1
- package/dist/utils/lp-inspect-types.js +0 -1
- package/dist/utils/private-sale-types.d.ts +0 -1
- package/dist/utils/private-sale-types.js +0 -1
- package/dist/utils/quote-helpers/index.d.ts +0 -107
- package/dist/utils/quote-helpers/index.js +0 -346
- package/dist/utils/quote-helpers/types.d.ts +0 -16
- package/dist/utils/quote-helpers/types.js +0 -1
- package/dist/utils/quote-helpers-types.d.ts +0 -1
- package/dist/utils/quote-helpers-types.js +0 -1
- /package/dist/{chains/bsc/four/submit/types.js → __tests__/subpath-exports.test.d.ts} +0 -0
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 48.club Bundle 交易服务客户端
|
|
3
|
-
* 官方文档: https://docs.48.club/
|
|
4
|
-
*/
|
|
5
|
-
export type BundleParams = {
|
|
6
|
-
txs: string[];
|
|
7
|
-
maxTimestamp?: number;
|
|
8
|
-
maxBlockNumber?: number;
|
|
9
|
-
acceptReverting?: string[];
|
|
10
|
-
revertingTxHashes?: string[];
|
|
11
|
-
soulPointSignature?: string;
|
|
12
|
-
backrunTarget?: string;
|
|
13
|
-
noMerge?: boolean;
|
|
14
|
-
};
|
|
15
|
-
export type SoulPointSignatureMode = 'none' | 'timestampPersonalSign' | 'concatTxHash' | 'rawTimestamp';
|
|
16
|
-
export type VNormalizationMode = '27_28' | '0_1';
|
|
17
|
-
export type BundleStatus = {
|
|
18
|
-
status: 'INCLUDED' | 'PENDING' | 'FAILED';
|
|
19
|
-
includedBlock?: number;
|
|
20
|
-
hash: string;
|
|
21
|
-
maxTimestamp: number;
|
|
22
|
-
transaction: {
|
|
23
|
-
from: string;
|
|
24
|
-
gasPrice: string;
|
|
25
|
-
nonce: number;
|
|
26
|
-
};
|
|
27
|
-
};
|
|
28
|
-
export type Club48Config = {
|
|
29
|
-
endpoint?: string;
|
|
30
|
-
explorerEndpoint?: string;
|
|
31
|
-
};
|
|
32
|
-
/**
|
|
33
|
-
* 48.club Bundle 客户端
|
|
34
|
-
*/
|
|
35
|
-
export declare class Club48Client {
|
|
36
|
-
private endpoint;
|
|
37
|
-
private explorerEndpoint;
|
|
38
|
-
constructor(config?: Club48Config);
|
|
39
|
-
/**
|
|
40
|
-
* 生成 48 Soul Point 签名
|
|
41
|
-
* 用于提升会员等级(Signed Guest 及以上)
|
|
42
|
-
*
|
|
43
|
-
* @param privateKey 私钥
|
|
44
|
-
* @param txs 已签名的交易数组
|
|
45
|
-
* @returns 签名字符串
|
|
46
|
-
*/
|
|
47
|
-
static sign48SoulPoint(privateKey: string, txs: string[]): string;
|
|
48
|
-
/**
|
|
49
|
-
* 生成 48SP 签名(timestamp personal_sign 模式)
|
|
50
|
-
* 常见规则:对当前 Unix 秒级时间戳的字符串做 personal_sign
|
|
51
|
-
*/
|
|
52
|
-
static sign48SoulPointTimestamp(privateKey: string, timestamp?: number): Promise<string>;
|
|
53
|
-
/**
|
|
54
|
-
* 生成 48SP 签名(rawTimestamp 裸签 keccak(timestampString))
|
|
55
|
-
*/
|
|
56
|
-
static sign48SoulPointRawTimestamp(privateKey: string, timestamp?: number): string;
|
|
57
|
-
/**
|
|
58
|
-
* 规范化签名 v 值
|
|
59
|
-
* mode = '27_28':将 0/1 规范为 27/28
|
|
60
|
-
* mode = '0_1':将 27/28 规范为 0/1
|
|
61
|
-
*/
|
|
62
|
-
static normalizeSignatureV(signature: string, mode?: VNormalizationMode): string;
|
|
63
|
-
/**
|
|
64
|
-
* 发送 Bundle(Puissant)
|
|
65
|
-
*
|
|
66
|
-
* @param params Bundle 参数
|
|
67
|
-
* @returns Bundle UUID
|
|
68
|
-
*/
|
|
69
|
-
sendBundle(params: BundleParams, opts?: {
|
|
70
|
-
spMode?: SoulPointSignatureMode;
|
|
71
|
-
spPrivateKey?: string;
|
|
72
|
-
spVMode?: VNormalizationMode;
|
|
73
|
-
timestamp?: number;
|
|
74
|
-
}): Promise<string>;
|
|
75
|
-
/**
|
|
76
|
-
* 发送私有交易(单笔)
|
|
77
|
-
*
|
|
78
|
-
* @param signedTx 已签名的原始交易
|
|
79
|
-
* @returns 交易哈希
|
|
80
|
-
*/
|
|
81
|
-
sendPrivateTransaction(signedTx: string): Promise<string>;
|
|
82
|
-
/**
|
|
83
|
-
* 发送单笔私有交易(含 48SP)
|
|
84
|
-
* 文档参考:eth_sendPrivateTransactionWith48SP
|
|
85
|
-
* 规则:使用私钥对当前 Unix 时间戳字符串 personal_sign,作为 48SoulPointMemberSignature
|
|
86
|
-
*
|
|
87
|
-
* @param signedTx 已签名原始交易
|
|
88
|
-
* @param spPrivateKey 具有 SoulPoint 会员资格的钱包私钥
|
|
89
|
-
* @returns 交易哈希
|
|
90
|
-
*/
|
|
91
|
-
sendPrivateTransactionWith48SP(signedTx: string, spPrivateKey: string, opts?: {
|
|
92
|
-
spMode?: SoulPointSignatureMode;
|
|
93
|
-
spVMode?: VNormalizationMode;
|
|
94
|
-
timestamp?: number;
|
|
95
|
-
}): Promise<string>;
|
|
96
|
-
/**
|
|
97
|
-
* 获取最低 gas price
|
|
98
|
-
*
|
|
99
|
-
* @returns 最低 gas price (wei)
|
|
100
|
-
*/
|
|
101
|
-
getMinGasPrice(): Promise<bigint>;
|
|
102
|
-
/**
|
|
103
|
-
* 查询 Bundle 状态
|
|
104
|
-
* 文档参考:https://docs.48.club/puissant-builder/bundle-submission-and-on-chain-status-query
|
|
105
|
-
*
|
|
106
|
-
* @param bundleHash Bundle Hash (从 eth_sendBundle 返回的结果)
|
|
107
|
-
* @returns Bundle 状态
|
|
108
|
-
*/
|
|
109
|
-
getBundleStatus(bundleHash: string): Promise<BundleStatus>;
|
|
110
|
-
/**
|
|
111
|
-
* 等待 Bundle 完成
|
|
112
|
-
*
|
|
113
|
-
* @param bundleHash Bundle Hash (从 eth_sendBundle 返回的结果)
|
|
114
|
-
* @param timeout 超时时间(毫秒),默认 60 秒
|
|
115
|
-
* @returns Bundle 状态
|
|
116
|
-
*/
|
|
117
|
-
waitForBundle(bundleHash: string, timeout?: number): Promise<BundleStatus>;
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Builder Control EOA(用于提升排序权重的“小费”收款地址)
|
|
121
|
-
* 文档: https://docs.48.club/puissant-builder/send-bundle
|
|
122
|
-
*/
|
|
123
|
-
export declare const BUILDER_CONTROL_EOA = "0x4848489f0b2BEdd788c696e2D79b6b69D7484848";
|
|
124
|
-
/**
|
|
125
|
-
* Auction Feed 订阅(雏形占位)
|
|
126
|
-
* 说明:48 官方为 WebSocket-RPC 订阅;此处仅预留接口签名,实际网络订阅由上层应用实现
|
|
127
|
-
*/
|
|
128
|
-
export type AuctionFeedCallbacks = {
|
|
129
|
-
onOpen?: () => void;
|
|
130
|
-
onMessage?: (data: any) => void;
|
|
131
|
-
onError?: (err: any) => void;
|
|
132
|
-
onClose?: () => void;
|
|
133
|
-
};
|
|
134
|
-
export declare function createAuctionFeedClient(wsUrl: string, callbacks: AuctionFeedCallbacks): {
|
|
135
|
-
connect: () => void;
|
|
136
|
-
close: () => void;
|
|
137
|
-
};
|
|
138
|
-
/**
|
|
139
|
-
* 批量私有交易辅助函数
|
|
140
|
-
*/
|
|
141
|
-
export declare function sendBatchPrivateTransactions(signedTxs: string[], spPrivateKey: string, endpoint?: string, opts?: {
|
|
142
|
-
spMode?: SoulPointSignatureMode;
|
|
143
|
-
spVMode?: VNormalizationMode;
|
|
144
|
-
timestamp?: number;
|
|
145
|
-
}): Promise<boolean>;
|
|
146
|
-
/**
|
|
147
|
-
* 发送 backrun bundle(便捷方法)
|
|
148
|
-
* - 自动填充 backrunTarget 参数
|
|
149
|
-
* - 其他参数透传
|
|
150
|
-
* 文档参考: Auction Transaction Feed / SendBundle with backrunTarget
|
|
151
|
-
*/
|
|
152
|
-
export declare function sendBackrunBundle(client: Club48Client, params: Omit<BundleParams, 'backrunTarget'> & {
|
|
153
|
-
backrunTarget: string;
|
|
154
|
-
}): Promise<string>;
|
|
@@ -1,331 +0,0 @@
|
|
|
1
|
-
import axios from 'axios';
|
|
2
|
-
import { ethers } from 'ethers';
|
|
3
|
-
/**
|
|
4
|
-
* 48.club Bundle 客户端
|
|
5
|
-
*/
|
|
6
|
-
export class Club48Client {
|
|
7
|
-
constructor(config) {
|
|
8
|
-
this.endpoint = config?.endpoint || 'https://puissant-bsc.48.club';
|
|
9
|
-
this.explorerEndpoint = config?.explorerEndpoint || 'https://explore.48.club';
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* 生成 48 Soul Point 签名
|
|
13
|
-
* 用于提升会员等级(Signed Guest 及以上)
|
|
14
|
-
*
|
|
15
|
-
* @param privateKey 私钥
|
|
16
|
-
* @param txs 已签名的交易数组
|
|
17
|
-
* @returns 签名字符串
|
|
18
|
-
*/
|
|
19
|
-
static sign48SoulPoint(privateKey, txs) {
|
|
20
|
-
// 1. 计算每笔交易的哈希
|
|
21
|
-
const txHashes = txs.map(tx => ethers.keccak256(tx));
|
|
22
|
-
// 2. 连接所有哈希
|
|
23
|
-
const concatenated = ethers.concat(txHashes);
|
|
24
|
-
// 3. 对连接后的数据进行哈希
|
|
25
|
-
const messageHash = ethers.keccak256(concatenated);
|
|
26
|
-
// 4. 使用私钥签名
|
|
27
|
-
const wallet = new ethers.Wallet(privateKey);
|
|
28
|
-
const signature = wallet.signingKey.sign(messageHash).serialized;
|
|
29
|
-
return signature;
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* 生成 48SP 签名(timestamp personal_sign 模式)
|
|
33
|
-
* 常见规则:对当前 Unix 秒级时间戳的字符串做 personal_sign
|
|
34
|
-
*/
|
|
35
|
-
static async sign48SoulPointTimestamp(privateKey, timestamp) {
|
|
36
|
-
const wallet = new ethers.Wallet(privateKey);
|
|
37
|
-
const ts = String(timestamp ?? Math.floor(Date.now() / 1000));
|
|
38
|
-
// ethers v6: signMessage 做 EIP-191 personal_sign
|
|
39
|
-
return await wallet.signMessage(ts);
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* 生成 48SP 签名(rawTimestamp 裸签 keccak(timestampString))
|
|
43
|
-
*/
|
|
44
|
-
static sign48SoulPointRawTimestamp(privateKey, timestamp) {
|
|
45
|
-
const ts = String(timestamp ?? Math.floor(Date.now() / 1000));
|
|
46
|
-
const msgHash = ethers.keccak256(ethers.toUtf8Bytes(ts));
|
|
47
|
-
const wallet = new ethers.Wallet(privateKey);
|
|
48
|
-
return wallet.signingKey.sign(msgHash).serialized;
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* 规范化签名 v 值
|
|
52
|
-
* mode = '27_28':将 0/1 规范为 27/28
|
|
53
|
-
* mode = '0_1':将 27/28 规范为 0/1
|
|
54
|
-
*/
|
|
55
|
-
static normalizeSignatureV(signature, mode = '27_28') {
|
|
56
|
-
const bytes = ethers.getBytes(signature);
|
|
57
|
-
if (bytes.length !== 65)
|
|
58
|
-
return signature;
|
|
59
|
-
const v = bytes[64];
|
|
60
|
-
let v2 = v;
|
|
61
|
-
if (mode === '27_28') {
|
|
62
|
-
if (v === 0 || v === 1)
|
|
63
|
-
v2 = (v + 27);
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
if (v === 27 || v === 28)
|
|
67
|
-
v2 = (v - 27);
|
|
68
|
-
}
|
|
69
|
-
if (v2 === v)
|
|
70
|
-
return signature;
|
|
71
|
-
const out = new Uint8Array(65);
|
|
72
|
-
out.set(bytes.subarray(0, 64), 0);
|
|
73
|
-
out[64] = v2;
|
|
74
|
-
return ethers.hexlify(out);
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* 发送 Bundle(Puissant)
|
|
78
|
-
*
|
|
79
|
-
* @param params Bundle 参数
|
|
80
|
-
* @returns Bundle UUID
|
|
81
|
-
*/
|
|
82
|
-
async sendBundle(params, opts) {
|
|
83
|
-
const maxTimestamp = params.maxTimestamp || Math.floor(Date.now() / 1000) + 300; // 默认 5 分钟
|
|
84
|
-
const bundleParams = { txs: params.txs };
|
|
85
|
-
if (typeof params.maxBlockNumber === 'number') {
|
|
86
|
-
bundleParams.maxBlockNumber = params.maxBlockNumber;
|
|
87
|
-
}
|
|
88
|
-
else {
|
|
89
|
-
bundleParams.maxTimestamp = maxTimestamp;
|
|
90
|
-
}
|
|
91
|
-
// 兼容两种字段名
|
|
92
|
-
if (params.revertingTxHashes && params.revertingTxHashes.length > 0) {
|
|
93
|
-
bundleParams.revertingTxHashes = params.revertingTxHashes;
|
|
94
|
-
}
|
|
95
|
-
else if (params.acceptReverting && params.acceptReverting.length > 0) {
|
|
96
|
-
bundleParams.revertingTxHashes = params.acceptReverting;
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
bundleParams.revertingTxHashes = [];
|
|
100
|
-
}
|
|
101
|
-
if (typeof params.noMerge === 'boolean') {
|
|
102
|
-
bundleParams.noMerge = params.noMerge;
|
|
103
|
-
}
|
|
104
|
-
// 添加 Soul Point 签名(优先:调用方直接提供;否则按 opts 生成)
|
|
105
|
-
if (params.soulPointSignature) {
|
|
106
|
-
bundleParams["48spSign"] = params.soulPointSignature;
|
|
107
|
-
}
|
|
108
|
-
else if (opts && opts.spMode && opts.spMode !== 'none') {
|
|
109
|
-
if (!opts.spPrivateKey) {
|
|
110
|
-
throw new Error('48SP mode enabled but spPrivateKey is missing');
|
|
111
|
-
}
|
|
112
|
-
let sig = '';
|
|
113
|
-
if (opts.spMode === 'timestampPersonalSign') {
|
|
114
|
-
sig = await Club48Client.sign48SoulPointTimestamp(opts.spPrivateKey, opts.timestamp);
|
|
115
|
-
}
|
|
116
|
-
else if (opts.spMode === 'concatTxHash') {
|
|
117
|
-
sig = Club48Client.sign48SoulPoint(opts.spPrivateKey, params.txs);
|
|
118
|
-
}
|
|
119
|
-
else if (opts.spMode === 'rawTimestamp') {
|
|
120
|
-
sig = Club48Client.sign48SoulPointRawTimestamp(opts.spPrivateKey, opts.timestamp);
|
|
121
|
-
}
|
|
122
|
-
if (opts.spVMode)
|
|
123
|
-
sig = Club48Client.normalizeSignatureV(sig, opts.spVMode);
|
|
124
|
-
bundleParams["48spSign"] = sig;
|
|
125
|
-
}
|
|
126
|
-
// 添加 backrun 目标(如果提供)
|
|
127
|
-
if (params.backrunTarget) {
|
|
128
|
-
bundleParams.backrunTarget = params.backrunTarget;
|
|
129
|
-
}
|
|
130
|
-
const response = await axios.post(this.endpoint, {
|
|
131
|
-
jsonrpc: "2.0",
|
|
132
|
-
id: 1,
|
|
133
|
-
method: "eth_sendBundle",
|
|
134
|
-
params: [bundleParams]
|
|
135
|
-
});
|
|
136
|
-
if (response.data.error) {
|
|
137
|
-
throw new Error(`48.club bundle failed: ${response.data.error.message}`);
|
|
138
|
-
}
|
|
139
|
-
return response.data.result;
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* 发送私有交易(单笔)
|
|
143
|
-
*
|
|
144
|
-
* @param signedTx 已签名的原始交易
|
|
145
|
-
* @returns 交易哈希
|
|
146
|
-
*/
|
|
147
|
-
async sendPrivateTransaction(signedTx) {
|
|
148
|
-
const response = await axios.post(this.endpoint, {
|
|
149
|
-
jsonrpc: "2.0",
|
|
150
|
-
id: 1,
|
|
151
|
-
method: "eth_sendPrivateRawTransaction",
|
|
152
|
-
params: [signedTx]
|
|
153
|
-
});
|
|
154
|
-
if (response.data.error) {
|
|
155
|
-
throw new Error(`48.club tx failed: ${response.data.error.message}`);
|
|
156
|
-
}
|
|
157
|
-
return response.data.result;
|
|
158
|
-
}
|
|
159
|
-
/**
|
|
160
|
-
* 发送单笔私有交易(含 48SP)
|
|
161
|
-
* 文档参考:eth_sendPrivateTransactionWith48SP
|
|
162
|
-
* 规则:使用私钥对当前 Unix 时间戳字符串 personal_sign,作为 48SoulPointMemberSignature
|
|
163
|
-
*
|
|
164
|
-
* @param signedTx 已签名原始交易
|
|
165
|
-
* @param spPrivateKey 具有 SoulPoint 会员资格的钱包私钥
|
|
166
|
-
* @returns 交易哈希
|
|
167
|
-
*/
|
|
168
|
-
async sendPrivateTransactionWith48SP(signedTx, spPrivateKey, opts) {
|
|
169
|
-
// 1) 生成 48SP 签名(默认使用 timestamp personal_sign)
|
|
170
|
-
const mode = opts?.spMode ?? 'timestampPersonalSign';
|
|
171
|
-
let signature = '';
|
|
172
|
-
if (mode === 'timestampPersonalSign') {
|
|
173
|
-
signature = await Club48Client.sign48SoulPointTimestamp(spPrivateKey, opts?.timestamp);
|
|
174
|
-
}
|
|
175
|
-
else {
|
|
176
|
-
signature = Club48Client.sign48SoulPoint(spPrivateKey, [signedTx]);
|
|
177
|
-
}
|
|
178
|
-
if (opts?.spVMode)
|
|
179
|
-
signature = Club48Client.normalizeSignatureV(signature, opts.spVMode);
|
|
180
|
-
// 2) 调用 48.club RPC
|
|
181
|
-
const response = await axios.post(this.endpoint, {
|
|
182
|
-
jsonrpc: "2.0",
|
|
183
|
-
id: 1,
|
|
184
|
-
method: "eth_sendPrivateTransactionWith48SP",
|
|
185
|
-
params: [signedTx, signature]
|
|
186
|
-
});
|
|
187
|
-
if (response.data.error) {
|
|
188
|
-
throw new Error(`48.club tx failed: ${response.data.error.message}`);
|
|
189
|
-
}
|
|
190
|
-
return response.data.result;
|
|
191
|
-
}
|
|
192
|
-
/**
|
|
193
|
-
* 获取最低 gas price
|
|
194
|
-
*
|
|
195
|
-
* @returns 最低 gas price (wei)
|
|
196
|
-
*/
|
|
197
|
-
async getMinGasPrice() {
|
|
198
|
-
const response = await axios.post(this.endpoint, {
|
|
199
|
-
jsonrpc: "2.0",
|
|
200
|
-
id: 1,
|
|
201
|
-
method: "eth_gasPrice"
|
|
202
|
-
});
|
|
203
|
-
if (response.data.error) {
|
|
204
|
-
throw new Error(`Get gas price failed: ${response.data.error.message}`);
|
|
205
|
-
}
|
|
206
|
-
return BigInt(response.data.result);
|
|
207
|
-
}
|
|
208
|
-
/**
|
|
209
|
-
* 查询 Bundle 状态
|
|
210
|
-
* 文档参考:https://docs.48.club/puissant-builder/bundle-submission-and-on-chain-status-query
|
|
211
|
-
*
|
|
212
|
-
* @param bundleHash Bundle Hash (从 eth_sendBundle 返回的结果)
|
|
213
|
-
* @returns Bundle 状态
|
|
214
|
-
*/
|
|
215
|
-
async getBundleStatus(bundleHash) {
|
|
216
|
-
const response = await axios.get(`${this.explorerEndpoint}/v2/bundle?hash=${bundleHash}`);
|
|
217
|
-
return response.data;
|
|
218
|
-
}
|
|
219
|
-
/**
|
|
220
|
-
* 等待 Bundle 完成
|
|
221
|
-
*
|
|
222
|
-
* @param bundleHash Bundle Hash (从 eth_sendBundle 返回的结果)
|
|
223
|
-
* @param timeout 超时时间(毫秒),默认 60 秒
|
|
224
|
-
* @returns Bundle 状态
|
|
225
|
-
*/
|
|
226
|
-
async waitForBundle(bundleHash, timeout = 60000) {
|
|
227
|
-
const startTime = Date.now();
|
|
228
|
-
let lastStatus = null;
|
|
229
|
-
while (Date.now() - startTime < timeout) {
|
|
230
|
-
try {
|
|
231
|
-
const status = await this.getBundleStatus(bundleHash);
|
|
232
|
-
lastStatus = status;
|
|
233
|
-
if (status.status === 'INCLUDED') {
|
|
234
|
-
return status;
|
|
235
|
-
}
|
|
236
|
-
if (status.status === 'FAILED') {
|
|
237
|
-
throw new Error(`Bundle failed to execute: ${JSON.stringify(status)}`);
|
|
238
|
-
}
|
|
239
|
-
// 等待 3 秒后重试
|
|
240
|
-
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
241
|
-
}
|
|
242
|
-
catch (error) {
|
|
243
|
-
// 如果是 404 或网络错误,继续等待(可能是 explorer 还没索引到)
|
|
244
|
-
if (error.response?.status === 404 || error.code === 'ECONNREFUSED' || error.code === 'ENOTFOUND') {
|
|
245
|
-
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
246
|
-
continue;
|
|
247
|
-
}
|
|
248
|
-
// 其他错误,如果有最后状态且为 INCLUDED,返回成功
|
|
249
|
-
if (lastStatus?.status === 'INCLUDED') {
|
|
250
|
-
return lastStatus;
|
|
251
|
-
}
|
|
252
|
-
throw error;
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
// 超时:如果最后状态是 INCLUDED,返回成功;否则返回超时但带有最后状态信息
|
|
256
|
-
if (lastStatus?.status === 'INCLUDED') {
|
|
257
|
-
return lastStatus;
|
|
258
|
-
}
|
|
259
|
-
// 如果有最后状态,返回它;否则创建一个 PENDING 状态
|
|
260
|
-
if (lastStatus) {
|
|
261
|
-
return lastStatus;
|
|
262
|
-
}
|
|
263
|
-
// 创建一个基本的 PENDING 状态
|
|
264
|
-
return {
|
|
265
|
-
status: 'PENDING',
|
|
266
|
-
hash: bundleHash,
|
|
267
|
-
maxTimestamp: Math.floor(Date.now() / 1000) + 300,
|
|
268
|
-
transaction: {
|
|
269
|
-
from: '0x0000000000000000000000000000000000000000',
|
|
270
|
-
gasPrice: '0',
|
|
271
|
-
nonce: 0
|
|
272
|
-
}
|
|
273
|
-
};
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
/**
|
|
277
|
-
* Builder Control EOA(用于提升排序权重的“小费”收款地址)
|
|
278
|
-
* 文档: https://docs.48.club/puissant-builder/send-bundle
|
|
279
|
-
*/
|
|
280
|
-
export const BUILDER_CONTROL_EOA = '0x4848489f0b2BEdd788c696e2D79b6b69D7484848';
|
|
281
|
-
export function createAuctionFeedClient(wsUrl, callbacks) {
|
|
282
|
-
// 仅导出接口占位,避免引入 ws 依赖;用户可在应用层实现
|
|
283
|
-
return {
|
|
284
|
-
connect: () => {
|
|
285
|
-
callbacks.onOpen && callbacks.onOpen();
|
|
286
|
-
},
|
|
287
|
-
close: () => {
|
|
288
|
-
callbacks.onClose && callbacks.onClose();
|
|
289
|
-
}
|
|
290
|
-
};
|
|
291
|
-
}
|
|
292
|
-
/**
|
|
293
|
-
* 批量私有交易辅助函数
|
|
294
|
-
*/
|
|
295
|
-
export async function sendBatchPrivateTransactions(signedTxs, spPrivateKey, endpoint = 'https://puissant-bsc.48.club', opts) {
|
|
296
|
-
// 1. 生成 48SP 签名
|
|
297
|
-
const mode = opts?.spMode ?? 'timestampPersonalSign';
|
|
298
|
-
let signature = '';
|
|
299
|
-
if (mode === 'timestampPersonalSign') {
|
|
300
|
-
signature = await Club48Client.sign48SoulPointTimestamp(spPrivateKey, opts?.timestamp);
|
|
301
|
-
}
|
|
302
|
-
else {
|
|
303
|
-
signature = Club48Client.sign48SoulPoint(spPrivateKey, signedTxs);
|
|
304
|
-
}
|
|
305
|
-
if (opts?.spVMode)
|
|
306
|
-
signature = Club48Client.normalizeSignatureV(signature, opts.spVMode);
|
|
307
|
-
// 2. 批量提交
|
|
308
|
-
const response = await axios.post(endpoint, {
|
|
309
|
-
jsonrpc: "2.0",
|
|
310
|
-
id: 1,
|
|
311
|
-
method: "eth_sendBatchPrivateTransactionsWith48SP",
|
|
312
|
-
params: [
|
|
313
|
-
signedTxs, // 已签名的交易数组
|
|
314
|
-
signature // 48SP 签名
|
|
315
|
-
]
|
|
316
|
-
});
|
|
317
|
-
// 注意:批量方法不返回交易哈希,只确认接收
|
|
318
|
-
if (response.data.error) {
|
|
319
|
-
throw new Error(response.data.error.message);
|
|
320
|
-
}
|
|
321
|
-
return true;
|
|
322
|
-
}
|
|
323
|
-
/**
|
|
324
|
-
* 发送 backrun bundle(便捷方法)
|
|
325
|
-
* - 自动填充 backrunTarget 参数
|
|
326
|
-
* - 其他参数透传
|
|
327
|
-
* 文档参考: Auction Transaction Feed / SendBundle with backrunTarget
|
|
328
|
-
*/
|
|
329
|
-
export async function sendBackrunBundle(client, params) {
|
|
330
|
-
return await client.sendBundle({ ...params, backrunTarget: params.backrunTarget });
|
|
331
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
export interface EmitServiceClientConfig {
|
|
2
|
-
baseUrl: string;
|
|
3
|
-
headers?: HeadersInit | (() => HeadersInit | Promise<HeadersInit>);
|
|
4
|
-
}
|
|
5
|
-
export interface EmitServiceSubmitRequest {
|
|
6
|
-
signature: string[];
|
|
7
|
-
chain_name: string;
|
|
8
|
-
sequential?: boolean;
|
|
9
|
-
waitConfirmation?: boolean;
|
|
10
|
-
type?: string;
|
|
11
|
-
xlayer_aa?: boolean;
|
|
12
|
-
xlayer_bundle?: boolean;
|
|
13
|
-
isBSC_EOA?: boolean;
|
|
14
|
-
slippageBps?: number;
|
|
15
|
-
}
|
|
16
|
-
export interface EmitServiceSubmitResponseData {
|
|
17
|
-
bundle_hash?: string;
|
|
18
|
-
bundleHash?: string;
|
|
19
|
-
tx_hashes?: string[];
|
|
20
|
-
txHashes?: string[];
|
|
21
|
-
targetBlock?: number;
|
|
22
|
-
txCount?: number;
|
|
23
|
-
successCount?: number;
|
|
24
|
-
results?: unknown[];
|
|
25
|
-
[key: string]: unknown;
|
|
26
|
-
}
|
|
27
|
-
export interface EmitServiceSubmitResponse {
|
|
28
|
-
code: number;
|
|
29
|
-
data?: EmitServiceSubmitResponseData;
|
|
30
|
-
msg?: string;
|
|
31
|
-
}
|
|
32
|
-
export interface EmitServiceRouteConfigResponse {
|
|
33
|
-
code: number;
|
|
34
|
-
data?: {
|
|
35
|
-
chain_name: string;
|
|
36
|
-
route_address: string;
|
|
37
|
-
};
|
|
38
|
-
msg?: string;
|
|
39
|
-
}
|
|
40
|
-
export declare class EmitServiceClient {
|
|
41
|
-
private baseUrl;
|
|
42
|
-
private headers?;
|
|
43
|
-
constructor(config: EmitServiceClientConfig);
|
|
44
|
-
submitToBlockRazor(request: EmitServiceSubmitRequest): Promise<EmitServiceSubmitResponse>;
|
|
45
|
-
getTransactionConfig(chainName: string): Promise<EmitServiceRouteConfigResponse>;
|
|
46
|
-
}
|
|
47
|
-
export declare function submitToEmitServiceBlockRazor(config: EmitServiceClientConfig, request: EmitServiceSubmitRequest): Promise<EmitServiceSubmitResponse>;
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
function trimTrailingSlash(url) {
|
|
2
|
-
return url.endsWith('/') ? url.slice(0, -1) : url;
|
|
3
|
-
}
|
|
4
|
-
async function resolveHeaders(input) {
|
|
5
|
-
if (!input)
|
|
6
|
-
return {};
|
|
7
|
-
return typeof input === 'function' ? await input() : input;
|
|
8
|
-
}
|
|
9
|
-
async function parseJsonSafe(resp) {
|
|
10
|
-
const text = await resp.text();
|
|
11
|
-
if (!text)
|
|
12
|
-
return {};
|
|
13
|
-
return JSON.parse(text);
|
|
14
|
-
}
|
|
15
|
-
export class EmitServiceClient {
|
|
16
|
-
constructor(config) {
|
|
17
|
-
this.baseUrl = trimTrailingSlash(config.baseUrl);
|
|
18
|
-
this.headers = config.headers;
|
|
19
|
-
}
|
|
20
|
-
async submitToBlockRazor(request) {
|
|
21
|
-
const headers = await resolveHeaders(this.headers);
|
|
22
|
-
const response = await fetch(`${this.baseUrl}/submit_transaction/submit_blockrazor`, {
|
|
23
|
-
method: 'POST',
|
|
24
|
-
headers: {
|
|
25
|
-
'content-type': 'application/json',
|
|
26
|
-
...headers,
|
|
27
|
-
},
|
|
28
|
-
body: JSON.stringify(request),
|
|
29
|
-
});
|
|
30
|
-
return parseJsonSafe(response);
|
|
31
|
-
}
|
|
32
|
-
async getTransactionConfig(chainName) {
|
|
33
|
-
const headers = await resolveHeaders(this.headers);
|
|
34
|
-
const response = await fetch(`${this.baseUrl}/submit_transaction/get_transaction_config?chain_name=${encodeURIComponent(chainName)}`, {
|
|
35
|
-
method: 'GET',
|
|
36
|
-
headers,
|
|
37
|
-
});
|
|
38
|
-
return parseJsonSafe(response);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
export async function submitToEmitServiceBlockRazor(config, request) {
|
|
42
|
-
const client = new EmitServiceClient(config);
|
|
43
|
-
return client.submitToBlockRazor(request);
|
|
44
|
-
}
|