four-flap-meme-sdk 1.8.7 → 1.8.8

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/index.d.ts CHANGED
@@ -50,6 +50,7 @@ export { flapBundleBuyFirstMerkle, type FlapBuyFirstSignConfig, type FlapBuyFirs
50
50
  export { pancakeBundleBuyFirstMerkle, type PancakeBuyFirstSignConfig, type PancakeBuyFirstConfig, type PancakeBundleBuyFirstSignParams, type PancakeBundleBuyFirstParams, type PancakeBuyFirstResult } from './chains/bsc/pancake/bundle-buy-first.js';
51
51
  export { flapBundleCurveToDex, type CurveToDexChain, type DexPoolType, type CurveToDexSignConfig, type CurveBuyerConfig, type DexBuyerConfig, type FlapCurveToDexParams, type FlapCurveToDexResult } from './shared/flap/portal-bundle-merkle/curve-to-dex.js';
52
52
  export { flapBundleCreateToDex, type CreateToDexChain, type CreateToDexSignConfig, type CreateTokenInfo, type FlapCreateToDexParams, type FlapCreateToDexResult } from './shared/flap/portal-bundle-merkle/create-to-dex.js';
53
+ export { VAULT_EXTENSION_IDS, VAULT_TYPE_LABELS, TAX_VAULT_ABI, VAULT_FACTORY_ABI, type VaultType, type TaxVaultConfig, type VaultInfo, type VaultRewards, getVaultExtensionId, encodeVaultExtensionData, buildVaultExtensionParams, getVaultTypeFromExtensionId, getVaultInfo, getVaultRewards, claimVaultRewards, isValidVaultContract, } from './shared/flap/vault.js';
53
54
  export { PROFIT_CONFIG } from './shared/constants/index.js';
54
55
  export { quoteV2, quoteV3, quote, getTokenToNativeQuote, getNativeToTokenQuote, getWrappedNativeAddress, // ✅ 来自 quote-helpers,与 shared/constants 同名但实现可能不同
55
56
  getStableCoins, V3_FEE_TIERS, // ✅ 来自 quote-helpers
package/dist/index.js CHANGED
@@ -95,6 +95,8 @@ export { pancakeBundleBuyFirstMerkle } from './chains/bsc/pancake/bundle-buy-fir
95
95
  export { flapBundleCurveToDex } from './shared/flap/portal-bundle-merkle/curve-to-dex.js';
96
96
  // ✅ 发币 + 一键买到外盘(Create → Curve → DEX)- 新代币
97
97
  export { flapBundleCreateToDex } from './shared/flap/portal-bundle-merkle/create-to-dex.js';
98
+ // ✅ Tax Vault 金库模块
99
+ export { VAULT_EXTENSION_IDS, VAULT_TYPE_LABELS, TAX_VAULT_ABI, VAULT_FACTORY_ABI, getVaultExtensionId, encodeVaultExtensionData, buildVaultExtensionParams, getVaultTypeFromExtensionId, getVaultInfo, getVaultRewards, claimVaultRewards, isValidVaultContract, } from './shared/flap/vault.js';
98
100
  // ✅ 硬编码利润配置(统一管理)- 从 shared/constants 导出
99
101
  export { PROFIT_CONFIG } from './shared/constants/index.js';
100
102
  // ✅ V2/V3 报价工具(统一管理)
@@ -19,3 +19,4 @@ export { FLAP_DEFAULT_FEE_RATES, FLAP_IPFS_API_URL, FLAP_VANITY_SUFFIX, FLAP_DEX
19
19
  export * from './abi.js';
20
20
  export { createTokenWithBundleBuy, batchBuyWithBundle, batchSellWithBundle, type FlapBundleConfig, type FlapChainForBundle, type FlapCreateWithBundleBuyParams, type FlapCreateWithBundleBuyResult, type FlapBatchBuyParams, type FlapBatchBuyResult, type FlapBatchSellParams, type FlapBatchSellResult, flapPrivateBuy, flapPrivateSell, flapBatchPrivateBuy, flapBatchPrivateSell, type FlapPrivateBuyParams, type FlapPrivateSellParams, type FlapBatchPrivateBuyParams, type FlapBatchPrivateSellParams, type FlapBatchPrivateSellResult, } from './portal-bundle.js';
21
21
  export * from './portal-bundle-merkle/index.js';
22
+ export { VAULT_EXTENSION_IDS, VAULT_TYPE_LABELS, TAX_VAULT_ABI, VAULT_FACTORY_ABI, type VaultType, type TaxVaultConfig, type VaultInfo, type VaultRewards, getVaultExtensionId, encodeVaultExtensionData, buildVaultExtensionParams, getVaultTypeFromExtensionId, getVaultInfo, getVaultRewards, claimVaultRewards, isValidVaultContract, } from './vault.js';
@@ -21,3 +21,11 @@ export * from './abi.js';
21
21
  export { createTokenWithBundleBuy, batchBuyWithBundle, batchSellWithBundle, flapPrivateBuy, flapPrivateSell, flapBatchPrivateBuy, flapBatchPrivateSell, } from './portal-bundle.js';
22
22
  // portal-bundle-merkle 子模块
23
23
  export * from './portal-bundle-merkle/index.js';
24
+ // ✅ Tax Vault 金库模块
25
+ export {
26
+ // 常量
27
+ VAULT_EXTENSION_IDS, VAULT_TYPE_LABELS, TAX_VAULT_ABI, VAULT_FACTORY_ABI,
28
+ // 编码/解码工具
29
+ getVaultExtensionId, encodeVaultExtensionData, buildVaultExtensionParams, getVaultTypeFromExtensionId,
30
+ // 链上查询
31
+ getVaultInfo, getVaultRewards, claimVaultRewards, isValidVaultContract, } from './vault.js';
@@ -4,6 +4,7 @@ import { ADDRESSES, ZERO_ADDRESS } from '../../../utils/constants.js';
4
4
  import { GAS_LIMITS, CHAINS } from '../../constants/index.js';
5
5
  import { MULTICALL3_ABI, V2_ROUTER_QUOTE_ABI } from '../../abis/common.js';
6
6
  import { FLAP_PORTAL_ADDRESSES, FLAP_ORIGINAL_PORTAL_ADDRESSES } from '../constants.js';
7
+ import { buildVaultExtensionParams } from '../vault.js';
7
8
  import { CHAIN_ID_MAP, PORTAL_ABI, getErrorMessage, getTxType, getGasPriceConfig, shouldExtractProfit, calculateProfit, getProfitRecipient, getBribeAmount, BLOCKRAZOR_BUILDER_EOA } from './config.js';
8
9
  // ✅ 常量
9
10
  const MULTICALL3_ADDRESS = ADDRESSES.BSC.Multicall3;
@@ -119,6 +120,10 @@ export async function createTokenWithBundleBuyMerkle(params) {
119
120
  if (total !== 10000) {
120
121
  throw new Error(`Tax distribution must sum to 10000 (100%), got ${total}`);
121
122
  }
123
+ // ✅ 如果配置了 Tax Vault,使用金库的 extensionID/extensionData
124
+ const vaultParams = buildVaultExtensionParams(tv2.vaultConfig);
125
+ const finalExtensionID = params.extensionID || vaultParams.extensionID;
126
+ const finalExtensionData = params.extensionData || vaultParams.extensionData;
122
127
  createTxPromise = portal.newTokenV5.populateTransaction({
123
128
  name: tokenInfo.name,
124
129
  symbol: tokenInfo.symbol,
@@ -131,8 +136,8 @@ export async function createTokenWithBundleBuyMerkle(params) {
131
136
  quoteAmt: 0n,
132
137
  beneficiary: devWallet.address,
133
138
  permitData: '0x',
134
- extensionID: params.extensionID ?? '0x' + '00'.repeat(32),
135
- extensionData: params.extensionData ?? '0x',
139
+ extensionID: finalExtensionID,
140
+ extensionData: finalExtensionData,
136
141
  dexId: (params.dexId ?? 0) & 0xff,
137
142
  lpFeeProfile: (params.lpFeeProfile ?? 0) & 0xff,
138
143
  taxDuration: BigInt(tv2.taxDuration),
@@ -84,6 +84,8 @@ export interface FlapCreateToDexParams {
84
84
  dividendBps: number;
85
85
  lpBps: number;
86
86
  minimumShareBalance?: number;
87
+ /** ✅ Tax Vault 金库配置(可选) */
88
+ vaultConfig?: import('../vault.js').TaxVaultConfig;
87
89
  };
88
90
  /** V3 扩展 ID */
89
91
  extensionID?: string;
@@ -10,6 +10,7 @@
10
10
  import { ethers, Contract, Wallet } from 'ethers';
11
11
  import { NonceManager, getOptimizedGasPrice, buildProfitHopTransactions, PROFIT_HOP_COUNT } from '../../../utils/bundle-helpers.js';
12
12
  import { FLAP_PORTAL_ADDRESSES, FLAP_ORIGINAL_PORTAL_ADDRESSES } from '../constants.js';
13
+ import { buildVaultExtensionParams } from '../vault.js';
13
14
  import { PROFIT_CONFIG, ZERO_ADDRESS } from '../../../utils/constants.js';
14
15
  import { GAS_LIMITS } from '../../constants/index.js';
15
16
  import { getGasPriceConfig, getTxType, getProfitRecipient, getBribeAmount, BLOCKRAZOR_BUILDER_EOA, PORTAL_ABI } from './config.js';
@@ -333,6 +334,10 @@ export async function flapBundleCreateToDex(params) {
333
334
  if (total !== 10000) {
334
335
  throw new Error(`Tax distribution must sum to 10000 (100%), got ${total}`);
335
336
  }
337
+ // ✅ 如果配置了 Tax Vault,使用金库的 extensionID/extensionData
338
+ const vaultParams = buildVaultExtensionParams(tv2.vaultConfig);
339
+ const finalExtensionID = params.extensionID || vaultParams.extensionID;
340
+ const finalExtensionData = params.extensionData || vaultParams.extensionData;
336
341
  createUnsigned = await originalPortal.newTokenV5.populateTransaction({
337
342
  name: tokenInfo.name,
338
343
  symbol: tokenInfo.symbol,
@@ -345,8 +350,8 @@ export async function flapBundleCreateToDex(params) {
345
350
  quoteAmt: 0n,
346
351
  beneficiary: devWallet.address,
347
352
  permitData: '0x',
348
- extensionID: params.extensionID ?? '0x' + '00'.repeat(32),
349
- extensionData: params.extensionData ?? '0x',
353
+ extensionID: finalExtensionID,
354
+ extensionData: finalExtensionData,
350
355
  dexId: (params.dexId ?? 0) & 0xff,
351
356
  lpFeeProfile: (params.lpFeeProfile ?? 0) & 0xff,
352
357
  // Tax Token V2 专属字段
@@ -21,3 +21,6 @@ export { flapBundleCurveToDex } from './curve-to-dex.js';
21
21
  export { flapBundleCreateToDex } from './create-to-dex.js';
22
22
  // ✅ 内盘换手方法(一卖一买、一卖多买、快捷资金利用率、交叉换手)
23
23
  export { flapBundleSwapMerkle, flapBatchSwapMerkle, flapQuickBatchSwapMerkle, flapCrossSwapMerkle } from './swap.js';
24
+ // ✅ Tax Vault 金库类型(types.ts 中 TaxV2Config.vaultConfig 使用的类型)
25
+ // 注意:TaxVaultConfig 完整导出在 flap/index.ts → vault.js 中
26
+ // 这里仅从 types.ts 导出 TaxV2Config 中嵌套使用时的类型引用
@@ -1,4 +1,5 @@
1
1
  import type { GeneratedWallet } from '../../../utils/wallet.js';
2
+ import type { TaxVaultConfig } from '../vault.js';
2
3
  /**
3
4
  * ✅ 利润模式:
4
5
  * - 'single': 单一模式(默认),从金额最大的钱包统一扣除所有利润,只有一组多跳交易
@@ -32,6 +33,8 @@ export type TaxV2Config = {
32
33
  antiFarmerDuration: number;
33
34
  /** 税收分配配置 */
34
35
  distribution: TaxDistributionConfig;
36
+ /** ✅ Tax Vault 金库配置(可选) */
37
+ vaultConfig?: TaxVaultConfig;
35
38
  };
36
39
  export type FlapSignConfig = {
37
40
  rpcUrl: string;
@@ -0,0 +1,204 @@
1
+ /**
2
+ * Flap Tax Vaults(税收金库)
3
+ *
4
+ * Tax Vaults 是 Flap Protocol 的扩展功能,允许开发者创建自定义智能合约
5
+ * 来管理税收代币的税费收入。通过 newTokenV5 的 extensionID/extensionData 参数集成。
6
+ *
7
+ * 工作原理:
8
+ * 1. extensionID = 金库类型标识符(bytes32)
9
+ * 2. extensionData = ABI 编码的金库初始化参数
10
+ * 3. 代币创建后,税费自动流入金库合约
11
+ * 4. 金库合约根据预设规则分配税费收入
12
+ *
13
+ * @module vault
14
+ */
15
+ import { type JsonRpcProvider, type Wallet } from 'ethers';
16
+ /**
17
+ * Flap 预定义金库扩展 ID
18
+ *
19
+ * 这些 ID 用于标识金库类型,作为 newTokenV5 的 extensionID 参数
20
+ * 计算方式:keccak256(vaultTypeName)
21
+ *
22
+ * ⚠️ 注意:当 Flap 官方发布正式的 Vault Extension ID 时,需要更新这些值
23
+ */
24
+ export declare const VAULT_EXTENSION_IDS: {
25
+ /** 无金库(默认) */
26
+ readonly NONE: string;
27
+ /** 标准税收金库 - 累积税费并允许受益人提取 */
28
+ readonly STANDARD: string;
29
+ /** 自动回购金库 - 税费用于自动回购代币并销毁 */
30
+ readonly AUTO_BUYBACK: string;
31
+ /** 分红金库 - 税费按持仓比例分配给持有者 */
32
+ readonly DIVIDEND: string;
33
+ /** 流动性金库 - 税费自动添加到流动性池 */
34
+ readonly LIQUIDITY: string;
35
+ /** 自定义金库 - 用户部署的自定义合约 */
36
+ readonly CUSTOM: string;
37
+ };
38
+ /**
39
+ * 金库类型标签(用于 UI 显示)
40
+ */
41
+ export declare const VAULT_TYPE_LABELS: Record<string, string>;
42
+ /** 金库类型枚举 */
43
+ export type VaultType = 'none' | 'standard' | 'auto_buyback' | 'dividend' | 'liquidity' | 'custom';
44
+ /**
45
+ * Tax Vault 配置
46
+ * 用于在创建代币时指定金库设置
47
+ */
48
+ export interface TaxVaultConfig {
49
+ /** 金库类型 */
50
+ vaultType: VaultType;
51
+ /**
52
+ * 自定义金库合约地址
53
+ * 仅当 vaultType === 'custom' 时必填
54
+ * 合约必须实现 ITaxVault 接口
55
+ */
56
+ vaultAddress?: string;
57
+ /**
58
+ * 自定义扩展 ID(bytes32)
59
+ * 高级用法:直接指定 extensionID,覆盖 vaultType 对应的默认值
60
+ */
61
+ customExtensionId?: string;
62
+ /**
63
+ * 自定义扩展数据(hex)
64
+ * 高级用法:直接指定 extensionData
65
+ * 不提供时,SDK 将根据 vaultType 自动编码
66
+ */
67
+ customExtensionData?: string;
68
+ /**
69
+ * 自动回购参数(vaultType === 'auto_buyback' 时使用)
70
+ */
71
+ buybackConfig?: {
72
+ /** 回购间隔(秒) */
73
+ interval: number;
74
+ /** 每次回购的最大金额(原生代币,wei) */
75
+ maxAmount: bigint;
76
+ /** 回购的代币是否销毁(true=销毁,false=发送到 beneficiary) */
77
+ burnAfterBuy: boolean;
78
+ };
79
+ /**
80
+ * 分红参数(vaultType === 'dividend' 时使用)
81
+ */
82
+ dividendConfig?: {
83
+ /** 最低持仓门槛(代币数量,ether 单位) */
84
+ minimumBalance: number;
85
+ /** 分红周期(秒) */
86
+ distributionInterval: number;
87
+ };
88
+ /**
89
+ * 流动性参数(vaultType === 'liquidity' 时使用)
90
+ */
91
+ liquidityConfig?: {
92
+ /** 自动添加流动性的触发阈值(原生代币,ether 单位) */
93
+ threshold: number;
94
+ /** 添加到的 DEX 池类型 */
95
+ poolType: 'v2' | 'v3';
96
+ };
97
+ }
98
+ /**
99
+ * 金库信息(链上查询结果)
100
+ */
101
+ export interface VaultInfo {
102
+ /** 金库合约地址 */
103
+ address: string;
104
+ /** 金库中的代币余额 */
105
+ tokenBalance: bigint;
106
+ /** 金库中的原生代币余额 */
107
+ nativeBalance: bigint;
108
+ /** 金库所有者 */
109
+ owner: string;
110
+ /** 关联的代币地址 */
111
+ tokenAddress: string;
112
+ /** 是否已激活 */
113
+ isActive: boolean;
114
+ }
115
+ /**
116
+ * 金库奖励信息
117
+ */
118
+ export interface VaultRewards {
119
+ /** 待领取的代币奖励 */
120
+ pendingTokenRewards: bigint;
121
+ /** 待领取的原生代币奖励 */
122
+ pendingNativeRewards: bigint;
123
+ /** 已领取的总代币奖励 */
124
+ claimedTokenRewards: bigint;
125
+ /** 已领取的总原生代币奖励 */
126
+ claimedNativeRewards: bigint;
127
+ }
128
+ /**
129
+ * ITaxVault 接口 ABI
130
+ * 所有 Flap Tax Vault 合约必须实现此接口
131
+ *
132
+ * ⚠️ 注意:这是基于 Flap 文档推断的标准接口
133
+ * 当官方发布正式接口规范时,需要更新此 ABI
134
+ */
135
+ export declare const TAX_VAULT_ABI: string[];
136
+ /**
137
+ * Vault Factory ABI
138
+ * 用于部署新的金库合约
139
+ */
140
+ export declare const VAULT_FACTORY_ABI: string[];
141
+ /**
142
+ * 根据 VaultType 获取对应的 extensionID
143
+ */
144
+ export declare function getVaultExtensionId(vaultType: VaultType): string;
145
+ /**
146
+ * 编码金库配置为 extensionData
147
+ *
148
+ * @param config - 金库配置
149
+ * @returns ABI 编码的 extensionData(hex string)
150
+ */
151
+ export declare function encodeVaultExtensionData(config: TaxVaultConfig): string;
152
+ /**
153
+ * 将 TaxVaultConfig 转换为 newTokenV5 需要的 extensionID 和 extensionData
154
+ *
155
+ * @param config - 金库配置
156
+ * @returns { extensionID, extensionData }
157
+ */
158
+ export declare function buildVaultExtensionParams(config?: TaxVaultConfig): {
159
+ extensionID: string;
160
+ extensionData: string;
161
+ };
162
+ /**
163
+ * 查询金库信息
164
+ *
165
+ * @param provider - RPC Provider
166
+ * @param vaultAddress - 金库合约地址
167
+ * @returns 金库信息
168
+ */
169
+ export declare function getVaultInfo(provider: JsonRpcProvider, vaultAddress: string): Promise<VaultInfo | null>;
170
+ /**
171
+ * 查询用户在金库中的奖励
172
+ *
173
+ * @param provider - RPC Provider
174
+ * @param vaultAddress - 金库合约地址
175
+ * @param userAddress - 用户地址
176
+ * @returns 奖励信息
177
+ */
178
+ export declare function getVaultRewards(provider: JsonRpcProvider, vaultAddress: string, userAddress: string): Promise<VaultRewards>;
179
+ /**
180
+ * 从金库领取奖励
181
+ *
182
+ * @param wallet - 签名钱包
183
+ * @param vaultAddress - 金库合约地址
184
+ * @returns 交易收据
185
+ */
186
+ export declare function claimVaultRewards(wallet: Wallet, vaultAddress: string): Promise<{
187
+ txHash: string;
188
+ amount: bigint;
189
+ }>;
190
+ /**
191
+ * 验证金库合约是否有效(是否部署了代码)
192
+ *
193
+ * @param provider - RPC Provider
194
+ * @param vaultAddress - 金库合约地址
195
+ * @returns 是否为有效合约
196
+ */
197
+ export declare function isValidVaultContract(provider: JsonRpcProvider, vaultAddress: string): Promise<boolean>;
198
+ /**
199
+ * 获取代币关联的金库地址(通过 extensionID 推断)
200
+ *
201
+ * @param extensionID - 代币的 extensionID(从 getTokenV5 获取)
202
+ * @returns 金库类型
203
+ */
204
+ export declare function getVaultTypeFromExtensionId(extensionID: string): VaultType;
@@ -0,0 +1,288 @@
1
+ /**
2
+ * Flap Tax Vaults(税收金库)
3
+ *
4
+ * Tax Vaults 是 Flap Protocol 的扩展功能,允许开发者创建自定义智能合约
5
+ * 来管理税收代币的税费收入。通过 newTokenV5 的 extensionID/extensionData 参数集成。
6
+ *
7
+ * 工作原理:
8
+ * 1. extensionID = 金库类型标识符(bytes32)
9
+ * 2. extensionData = ABI 编码的金库初始化参数
10
+ * 3. 代币创建后,税费自动流入金库合约
11
+ * 4. 金库合约根据预设规则分配税费收入
12
+ *
13
+ * @module vault
14
+ */
15
+ import { Contract, AbiCoder, keccak256, toUtf8Bytes, ZeroAddress } from 'ethers';
16
+ // ============================================================================
17
+ // 常量
18
+ // ============================================================================
19
+ /**
20
+ * Flap 预定义金库扩展 ID
21
+ *
22
+ * 这些 ID 用于标识金库类型,作为 newTokenV5 的 extensionID 参数
23
+ * 计算方式:keccak256(vaultTypeName)
24
+ *
25
+ * ⚠️ 注意:当 Flap 官方发布正式的 Vault Extension ID 时,需要更新这些值
26
+ */
27
+ export const VAULT_EXTENSION_IDS = {
28
+ /** 无金库(默认) */
29
+ NONE: '0x' + '00'.repeat(32),
30
+ /** 标准税收金库 - 累积税费并允许受益人提取 */
31
+ STANDARD: keccak256(toUtf8Bytes('FlapTaxVault.Standard')),
32
+ /** 自动回购金库 - 税费用于自动回购代币并销毁 */
33
+ AUTO_BUYBACK: keccak256(toUtf8Bytes('FlapTaxVault.AutoBuyback')),
34
+ /** 分红金库 - 税费按持仓比例分配给持有者 */
35
+ DIVIDEND: keccak256(toUtf8Bytes('FlapTaxVault.Dividend')),
36
+ /** 流动性金库 - 税费自动添加到流动性池 */
37
+ LIQUIDITY: keccak256(toUtf8Bytes('FlapTaxVault.Liquidity')),
38
+ /** 自定义金库 - 用户部署的自定义合约 */
39
+ CUSTOM: keccak256(toUtf8Bytes('FlapTaxVault.Custom')),
40
+ };
41
+ /**
42
+ * 金库类型标签(用于 UI 显示)
43
+ */
44
+ export const VAULT_TYPE_LABELS = {
45
+ none: '无金库(标准税收)',
46
+ standard: '标准税收金库',
47
+ auto_buyback: '自动回购金库',
48
+ dividend: '分红金库',
49
+ liquidity: '流动性金库',
50
+ custom: '自定义金库',
51
+ };
52
+ // ============================================================================
53
+ // ABI 定义
54
+ // ============================================================================
55
+ /**
56
+ * ITaxVault 接口 ABI
57
+ * 所有 Flap Tax Vault 合约必须实现此接口
58
+ *
59
+ * ⚠️ 注意:这是基于 Flap 文档推断的标准接口
60
+ * 当官方发布正式接口规范时,需要更新此 ABI
61
+ */
62
+ export const TAX_VAULT_ABI = [
63
+ // 查询方法
64
+ 'function token() external view returns (address)',
65
+ 'function owner() external view returns (address)',
66
+ 'function isActive() external view returns (bool)',
67
+ 'function totalTaxCollected() external view returns (uint256)',
68
+ 'function pendingRewards(address user) external view returns (uint256)',
69
+ 'function claimedRewards(address user) external view returns (uint256)',
70
+ // 写入方法
71
+ 'function claimRewards() external returns (uint256)',
72
+ 'function withdraw(uint256 amount) external',
73
+ 'function withdrawNative(uint256 amount) external',
74
+ 'function activate() external',
75
+ 'function deactivate() external',
76
+ // 事件
77
+ 'event TaxReceived(address indexed token, uint256 amount)',
78
+ 'event RewardsClaimed(address indexed user, uint256 amount)',
79
+ 'event VaultActivated()',
80
+ 'event VaultDeactivated()',
81
+ ];
82
+ /**
83
+ * Vault Factory ABI
84
+ * 用于部署新的金库合约
85
+ */
86
+ export const VAULT_FACTORY_ABI = [
87
+ 'function createVault(address token, address owner, bytes32 vaultType, bytes initData) external returns (address)',
88
+ 'function getVault(address token) external view returns (address)',
89
+ 'function getVaultsByOwner(address owner) external view returns (address[])',
90
+ 'event VaultCreated(address indexed token, address indexed vault, address indexed owner, bytes32 vaultType)',
91
+ ];
92
+ // ============================================================================
93
+ // 编码/解码工具
94
+ // ============================================================================
95
+ const abiCoder = AbiCoder.defaultAbiCoder();
96
+ /**
97
+ * 根据 VaultType 获取对应的 extensionID
98
+ */
99
+ export function getVaultExtensionId(vaultType) {
100
+ switch (vaultType) {
101
+ case 'none':
102
+ return VAULT_EXTENSION_IDS.NONE;
103
+ case 'standard':
104
+ return VAULT_EXTENSION_IDS.STANDARD;
105
+ case 'auto_buyback':
106
+ return VAULT_EXTENSION_IDS.AUTO_BUYBACK;
107
+ case 'dividend':
108
+ return VAULT_EXTENSION_IDS.DIVIDEND;
109
+ case 'liquidity':
110
+ return VAULT_EXTENSION_IDS.LIQUIDITY;
111
+ case 'custom':
112
+ return VAULT_EXTENSION_IDS.CUSTOM;
113
+ default:
114
+ return VAULT_EXTENSION_IDS.NONE;
115
+ }
116
+ }
117
+ /**
118
+ * 编码金库配置为 extensionData
119
+ *
120
+ * @param config - 金库配置
121
+ * @returns ABI 编码的 extensionData(hex string)
122
+ */
123
+ export function encodeVaultExtensionData(config) {
124
+ if (config.customExtensionData) {
125
+ return config.customExtensionData;
126
+ }
127
+ switch (config.vaultType) {
128
+ case 'none':
129
+ return '0x';
130
+ case 'standard':
131
+ // 标准金库无额外参数
132
+ return '0x';
133
+ case 'auto_buyback': {
134
+ if (!config.buybackConfig)
135
+ return '0x';
136
+ return abiCoder.encode(['uint256', 'uint256', 'bool'], [config.buybackConfig.interval, config.buybackConfig.maxAmount, config.buybackConfig.burnAfterBuy]);
137
+ }
138
+ case 'dividend': {
139
+ if (!config.dividendConfig)
140
+ return '0x';
141
+ return abiCoder.encode(['uint256', 'uint256'], [config.dividendConfig.minimumBalance, config.dividendConfig.distributionInterval]);
142
+ }
143
+ case 'liquidity': {
144
+ if (!config.liquidityConfig)
145
+ return '0x';
146
+ const poolTypeInt = config.liquidityConfig.poolType === 'v3' ? 1 : 0;
147
+ return abiCoder.encode(['uint256', 'uint8'], [config.liquidityConfig.threshold, poolTypeInt]);
148
+ }
149
+ case 'custom': {
150
+ if (!config.vaultAddress) {
151
+ throw new Error('自定义金库必须提供 vaultAddress');
152
+ }
153
+ // 自定义金库:编码金库合约地址
154
+ return abiCoder.encode(['address'], [config.vaultAddress]);
155
+ }
156
+ default:
157
+ return '0x';
158
+ }
159
+ }
160
+ /**
161
+ * 将 TaxVaultConfig 转换为 newTokenV5 需要的 extensionID 和 extensionData
162
+ *
163
+ * @param config - 金库配置
164
+ * @returns { extensionID, extensionData }
165
+ */
166
+ export function buildVaultExtensionParams(config) {
167
+ if (!config || config.vaultType === 'none') {
168
+ return {
169
+ extensionID: VAULT_EXTENSION_IDS.NONE,
170
+ extensionData: '0x',
171
+ };
172
+ }
173
+ return {
174
+ extensionID: config.customExtensionId || getVaultExtensionId(config.vaultType),
175
+ extensionData: encodeVaultExtensionData(config),
176
+ };
177
+ }
178
+ // ============================================================================
179
+ // 链上查询
180
+ // ============================================================================
181
+ /**
182
+ * 查询金库信息
183
+ *
184
+ * @param provider - RPC Provider
185
+ * @param vaultAddress - 金库合约地址
186
+ * @returns 金库信息
187
+ */
188
+ export async function getVaultInfo(provider, vaultAddress) {
189
+ try {
190
+ const vault = new Contract(vaultAddress, TAX_VAULT_ABI, provider);
191
+ const [tokenAddress, owner, isActive, nativeBalance] = await Promise.all([
192
+ vault.token().catch(() => ZeroAddress),
193
+ vault.owner().catch(() => ZeroAddress),
194
+ vault.isActive().catch(() => false),
195
+ provider.getBalance(vaultAddress),
196
+ ]);
197
+ // 如果金库关联了代币,查询代币余额
198
+ let tokenBalance = 0n;
199
+ if (tokenAddress !== ZeroAddress) {
200
+ const erc20 = new Contract(tokenAddress, [
201
+ 'function balanceOf(address) view returns (uint256)',
202
+ ], provider);
203
+ tokenBalance = await erc20.balanceOf(vaultAddress).catch(() => 0n);
204
+ }
205
+ return {
206
+ address: vaultAddress,
207
+ tokenBalance,
208
+ nativeBalance,
209
+ owner: owner,
210
+ tokenAddress: tokenAddress,
211
+ isActive: isActive,
212
+ };
213
+ }
214
+ catch {
215
+ return null;
216
+ }
217
+ }
218
+ /**
219
+ * 查询用户在金库中的奖励
220
+ *
221
+ * @param provider - RPC Provider
222
+ * @param vaultAddress - 金库合约地址
223
+ * @param userAddress - 用户地址
224
+ * @returns 奖励信息
225
+ */
226
+ export async function getVaultRewards(provider, vaultAddress, userAddress) {
227
+ const vault = new Contract(vaultAddress, TAX_VAULT_ABI, provider);
228
+ const [pendingTokenRewards, claimedTokenRewards] = await Promise.all([
229
+ vault.pendingRewards(userAddress).catch(() => 0n),
230
+ vault.claimedRewards(userAddress).catch(() => 0n),
231
+ ]);
232
+ return {
233
+ pendingTokenRewards: pendingTokenRewards,
234
+ pendingNativeRewards: 0n, // 需要根据实际合约接口调整
235
+ claimedTokenRewards: claimedTokenRewards,
236
+ claimedNativeRewards: 0n,
237
+ };
238
+ }
239
+ /**
240
+ * 从金库领取奖励
241
+ *
242
+ * @param wallet - 签名钱包
243
+ * @param vaultAddress - 金库合约地址
244
+ * @returns 交易收据
245
+ */
246
+ export async function claimVaultRewards(wallet, vaultAddress) {
247
+ const vault = new Contract(vaultAddress, TAX_VAULT_ABI, wallet);
248
+ const tx = await vault.claimRewards();
249
+ const receipt = await tx.wait();
250
+ return {
251
+ txHash: receipt.hash,
252
+ amount: 0n, // 从事件中解析实际金额
253
+ };
254
+ }
255
+ /**
256
+ * 验证金库合约是否有效(是否部署了代码)
257
+ *
258
+ * @param provider - RPC Provider
259
+ * @param vaultAddress - 金库合约地址
260
+ * @returns 是否为有效合约
261
+ */
262
+ export async function isValidVaultContract(provider, vaultAddress) {
263
+ try {
264
+ const code = await provider.getCode(vaultAddress);
265
+ return code !== '0x' && code !== '0x0';
266
+ }
267
+ catch {
268
+ return false;
269
+ }
270
+ }
271
+ /**
272
+ * 获取代币关联的金库地址(通过 extensionID 推断)
273
+ *
274
+ * @param extensionID - 代币的 extensionID(从 getTokenV5 获取)
275
+ * @returns 金库类型
276
+ */
277
+ export function getVaultTypeFromExtensionId(extensionID) {
278
+ if (!extensionID || extensionID === VAULT_EXTENSION_IDS.NONE) {
279
+ return 'none';
280
+ }
281
+ for (const [key, value] of Object.entries(VAULT_EXTENSION_IDS)) {
282
+ if (value.toLowerCase() === extensionID.toLowerCase()) {
283
+ return key.toLowerCase();
284
+ }
285
+ }
286
+ // 未知的 extensionID,视为自定义金库
287
+ return 'custom';
288
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "four-flap-meme-sdk",
3
- "version": "1.8.7",
3
+ "version": "1.8.8",
4
4
  "description": "SDK for Flap bonding curve and four.meme TokenManager",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",