four-flap-meme-sdk 4.3.15 → 4.3.16
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/bundle/four-meme/core/create-openfour.js +2 -2
- package/dist/bundle/four-meme/utils-disperse.js +2 -2
- package/dist/bundle/four-meme/utils-pairwise.js +2 -2
- package/dist/bundle/four-meme/utils-sweep/erc20-no-hop.js +2 -2
- package/dist/bundle/four-meme/utils-sweep/with-hops.js +3 -3
- package/dist/bundle/internal.d.ts +1 -1
- package/dist/bundle/internal.js +8 -11
- package/dist/core/constants/gas-erc20-floor.test.d.ts +1 -0
- package/dist/core/constants/gas-erc20-floor.test.js +24 -0
- package/dist/core/constants/gas.d.ts +2 -0
- package/dist/core/constants/gas.js +5 -0
- package/dist/core/constants/index.d.ts +1 -1
- package/dist/core/constants/index.js +1 -1
- package/dist/domains/openfour/create-arg.d.ts +4 -2
- package/dist/domains/openfour/create-arg.js +6 -2
- package/dist/domains/openfour/create-arg.test.js +11 -1
- package/dist/domains/openfour/index.d.ts +1 -1
- package/dist/domains/openfour/index.js +1 -1
- package/package.json +1 -1
|
@@ -11,7 +11,7 @@ import { getTxType, getGasPriceConfig, getBribeAmount, calculateProfit, getProfi
|
|
|
11
11
|
import { signBribeTransaction } from '../../../core/sign-context-helpers.js';
|
|
12
12
|
import { createChainContext, loginFourClient, resolveTokenImage } from '../core-helpers.js';
|
|
13
13
|
import { OPENFOUR_CORE_ABI } from '../../../abis/openfour.js';
|
|
14
|
-
import { OPENFOUR_CREATE_EXPIRED_MESSAGE, computeOpenFourCreateValueWei, decodeOpenFourCreateArg, isOpenFourPresaleNative, loadOpenFourAddresses, shouldRefreshOpenFourCreateArg, } from '../../../domains/openfour/index.js';
|
|
14
|
+
import { OPENFOUR_CREATE_EXPIRED_MESSAGE, computeOpenFourCreateValueWei, decodeOpenFourCreateArg, isOpenFourCreateArgExpired, isOpenFourPresaleNative, loadOpenFourAddresses, shouldRefreshOpenFourCreateArg, } from '../../../domains/openfour/index.js';
|
|
15
15
|
import { signQuoteApproveIfNeeded } from './create-token-quote.js';
|
|
16
16
|
const BSC_SUBMIT_FEE_DUST_WEI = 10n ** 12n;
|
|
17
17
|
export function openFourSubmitProfitWei(nativeFlowWei) {
|
|
@@ -44,7 +44,7 @@ async function fetchFreshOpenFourCreateArg(fourClient, accessToken, body, provid
|
|
|
44
44
|
createResp = await pull();
|
|
45
45
|
decoded = decodeOpenFourCreateArg(createResp.createArg);
|
|
46
46
|
}
|
|
47
|
-
if (
|
|
47
|
+
if (isOpenFourCreateArgExpired(decoded.validTimestamp, await readChainTimestamp(provider))) {
|
|
48
48
|
throw new Error(OPENFOUR_CREATE_EXPIRED_MESSAGE);
|
|
49
49
|
}
|
|
50
50
|
return createResp;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ethers, Wallet } from 'ethers';
|
|
2
2
|
import { getOptimizedGasPrice, NonceManager, buildProfitHopTransactions, PROFIT_HOP_COUNT, } from '../../utils/bundle-helpers.js';
|
|
3
|
-
import { calculateTransferFee, GAS_LIMITS, isBscChain } from '../../core/constants/index.js';
|
|
3
|
+
import { calculateTransferFee, floorErc20TransferGasLimit, GAS_LIMITS, isBscChain } from '../../core/constants/index.js';
|
|
4
4
|
import { getGasPriceConfig, shouldExtractProfit, getProfitRecipient, getBribeAmount } from '../config-helpers.js';
|
|
5
5
|
import { getErc20Decimals as _getErc20Decimals, generateHopWallets as _generateHopWallets, normalizeAmounts as _normalizeAmounts, calculateGasLimit as _calculateGasLimit, isNativeTokenAddress as _isNativeTokenAddress, } from '../internal.js';
|
|
6
6
|
import { normalizeItemsOrRecipientsAmounts, resolveHopCountInput, resolveProvidedHops, resolveSignContext, signBribeTransaction, } from '../../core/sign-context-helpers.js';
|
|
@@ -138,7 +138,7 @@ export async function disperseWithBundleMerkle(params) {
|
|
|
138
138
|
// - 原生代币转账:贿赂档
|
|
139
139
|
// - ERC20 转账:走 GAS_LIMITS(含股票币代理)
|
|
140
140
|
const nativeTransferGasLimit = GAS_LIMITS.BRIBE;
|
|
141
|
-
const erc20TransferGasLimit =
|
|
141
|
+
const erc20TransferGasLimit = floorErc20TransferGasLimit(finalGasLimit);
|
|
142
142
|
// ✅ 原生代币多跳的 gas 费(每跳只需要 21000)
|
|
143
143
|
const nativeHopGasFee = nativeTransferGasLimit * gasPrice;
|
|
144
144
|
// ✅ ERC20 多跳时,中转钱包需要执行 2 笔交易(转 gas + 转 ERC20)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ethers, Wallet } from 'ethers';
|
|
2
2
|
import { getOptimizedGasPrice, NonceManager, buildProfitHopTransactions, PROFIT_HOP_COUNT, buildGasFields, } from '../../utils/bundle-helpers.js';
|
|
3
|
-
import { BLOCKRAZOR_BUILDER_EOA, calculateTransferFee, CHAINS,
|
|
3
|
+
import { BLOCKRAZOR_BUILDER_EOA, calculateTransferFee, CHAINS, floorErc20TransferGasLimit, isBscChain, } from '../../core/constants/index.js';
|
|
4
4
|
import { getTxType, getGasPriceConfig, shouldExtractProfit, getProfitRecipient, getBribeAmount, } from '../config-helpers.js';
|
|
5
5
|
import { getErc20Decimals as _getErc20Decimals, generateHopWallets as _generateHopWallets, calculateGasLimit as _calculateGasLimit, isNativeTokenAddress as _isNativeTokenAddress, } from '../internal.js';
|
|
6
6
|
import { createSignProvider, resolveProvidedHops } from '../../core/sign-context-helpers.js';
|
|
@@ -48,7 +48,7 @@ export async function pairwiseTransferWithBundleMerkle(params) {
|
|
|
48
48
|
const finalGasLimit = _calculateGasLimit(config, isNative, hasHops, maxHopCount);
|
|
49
49
|
const nativeGasLimit = (config.prefer21000ForNative ?? false) ? 21000n : finalGasLimit;
|
|
50
50
|
const nativeTransferGasLimit = 21000n;
|
|
51
|
-
const erc20TransferGasLimit =
|
|
51
|
+
const erc20TransferGasLimit = floorErc20TransferGasLimit(config.gasLimit);
|
|
52
52
|
const [gasPrice, decimals] = await Promise.all([
|
|
53
53
|
getOptimizedGasPrice(provider, getGasPriceConfig(config)),
|
|
54
54
|
isNative
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { ethers, Wallet } from 'ethers';
|
|
5
5
|
import { NonceManager, getOptimizedGasPrice, buildProfitHopTransactions, PROFIT_HOP_COUNT, } from '../../../utils/bundle-helpers.js';
|
|
6
6
|
import { getGasPriceConfig } from '../../config-helpers.js';
|
|
7
|
-
import { calculateTransferFee } from '../../../core/constants/index.js';
|
|
7
|
+
import { calculateTransferFee, floorErc20TransferGasLimit } from '../../../core/constants/index.js';
|
|
8
8
|
import { batchGetBalances as _batchGetBalances, getErc20Decimals as _getErc20Decimals } from '../../internal.js';
|
|
9
9
|
import { clampRatio } from './context.js';
|
|
10
10
|
export async function sweepErc20NoHop(ctx) {
|
|
@@ -134,7 +134,7 @@ export async function sweepErc20NoHop(ctx) {
|
|
|
134
134
|
value: 0n,
|
|
135
135
|
nonce,
|
|
136
136
|
gasPrice,
|
|
137
|
-
gasLimit: finalGasLimit,
|
|
137
|
+
gasLimit: floorErc20TransferGasLimit(finalGasLimit),
|
|
138
138
|
chainId: BigInt(chainIdNum),
|
|
139
139
|
type: txType,
|
|
140
140
|
});
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { ethers, Wallet } from 'ethers';
|
|
5
5
|
import { NonceManager, getOptimizedGasPrice, buildProfitHopTransactions, PROFIT_HOP_COUNT, } from '../../../utils/bundle-helpers.js';
|
|
6
6
|
import { getGasPriceConfig } from '../../config-helpers.js';
|
|
7
|
-
import { calculateTransferFee, GAS_LIMITS } from '../../../core/constants/index.js';
|
|
7
|
+
import { calculateTransferFee, floorErc20TransferGasLimit, GAS_LIMITS } from '../../../core/constants/index.js';
|
|
8
8
|
import { batchGetBalances as _batchGetBalances, getErc20Decimals as _getErc20Decimals } from '../../internal.js';
|
|
9
9
|
import { clampRatio } from './context.js';
|
|
10
10
|
export async function sweepWithHops(ctx, preparedHops) {
|
|
@@ -38,7 +38,7 @@ export async function sweepWithHops(ctx, preparedHops) {
|
|
|
38
38
|
const iface = isNative ? null : new ethers.Interface(['function transfer(address,uint256) returns (bool)']);
|
|
39
39
|
// ✅ Gas limit 设置(与分散函数保持一致)
|
|
40
40
|
const nativeTransferGasLimit = GAS_LIMITS.BRIBE;
|
|
41
|
-
const erc20TransferGasLimit =
|
|
41
|
+
const erc20TransferGasLimit = floorErc20TransferGasLimit(finalGasLimit);
|
|
42
42
|
// ✅ 原生代币多跳的 gas 费(每跳只需要 21000)
|
|
43
43
|
const nativeHopGasFee = nativeTransferGasLimit * gasPrice;
|
|
44
44
|
// ✅ ERC20 多跳时,中转钱包需要执行 2 笔交易(转 gas + 转 ERC20)
|
|
@@ -124,7 +124,7 @@ export async function sweepWithHops(ctx, preparedHops) {
|
|
|
124
124
|
value: 0n,
|
|
125
125
|
nonce,
|
|
126
126
|
gasPrice,
|
|
127
|
-
gasLimit:
|
|
127
|
+
gasLimit: erc20TransferGasLimit,
|
|
128
128
|
chainId: BigInt(chainIdNum),
|
|
129
129
|
type: txType,
|
|
130
130
|
});
|
|
@@ -11,6 +11,6 @@ export declare function normalizeAmounts(recipients: string[], amount?: AmountLi
|
|
|
11
11
|
export declare function batchGetBalances(provider: JsonRpcProvider, addresses: string[], tokenAddress?: string, chainId?: number): Promise<bigint[]>;
|
|
12
12
|
export declare function estimateErc20TransferGas(provider: JsonRpcProvider, tokenAddress: string, from: string, to: string, amount: bigint, bufferPercent?: number): Promise<bigint>;
|
|
13
13
|
export declare function estimateMaxErc20TransferGas(provider: JsonRpcProvider, tokenAddress: string, from: string, recipients: string[], amounts: bigint[], bufferPercent?: number): Promise<bigint>;
|
|
14
|
-
export declare function calculateGasLimit(config: BundleGasConfig, isNative: boolean,
|
|
14
|
+
export declare function calculateGasLimit(config: BundleGasConfig, isNative: boolean, _hasHops: boolean, _hopCount?: number): bigint;
|
|
15
15
|
export declare function isNativeTokenAddress(tokenAddress?: string): boolean;
|
|
16
16
|
export type { AmountLike, BundleGasConfig } from './types/index.js';
|
package/dist/bundle/internal.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ethers, Wallet } from 'ethers';
|
|
2
2
|
import { MULTICALL3_ABI, ERC20_BALANCE_ABI } from '../abis/common.js';
|
|
3
|
-
import { CHAINS, GAS_LIMITS, getMulticall3Address } from '../core/constants/index.js';
|
|
3
|
+
import { CHAINS, GAS_LIMITS, floorErc20TransferGasLimit, getMulticall3Address } from '../core/constants/index.js';
|
|
4
4
|
export { getErc20Decimals, getErc20DecimalsMerkle } from '../core/erc20/decimals.js';
|
|
5
5
|
function mapAggregate3Results(results, decode, fallback) {
|
|
6
6
|
return results.map((result) => {
|
|
@@ -129,20 +129,17 @@ export async function estimateMaxErc20TransferGas(provider, tokenAddress, from,
|
|
|
129
129
|
return 52000n;
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
|
-
export function calculateGasLimit(config, isNative,
|
|
132
|
+
export function calculateGasLimit(config, isNative, _hasHops, _hopCount = 0) {
|
|
133
|
+
if (!isNative) {
|
|
134
|
+
return floorErc20TransferGasLimit(config.gasLimit);
|
|
135
|
+
}
|
|
133
136
|
if (config.gasLimit !== undefined) {
|
|
134
137
|
return BigInt(config.gasLimit);
|
|
135
138
|
}
|
|
136
139
|
const isXLayer = config.chainId === CHAINS.XLAYER.chainId;
|
|
137
|
-
const baseGas =
|
|
138
|
-
?
|
|
139
|
-
|
|
140
|
-
: Number(GAS_LIMITS.NATIVE_TRANSFER)
|
|
141
|
-
: 46815;
|
|
142
|
-
if (hasHops && hopCount > 0) {
|
|
143
|
-
const multiplier = config.gasLimitMultiplier ?? 1.1;
|
|
144
|
-
return BigInt(Math.ceil(baseGas * multiplier));
|
|
145
|
-
}
|
|
140
|
+
const baseGas = isXLayer
|
|
141
|
+
? Number(GAS_LIMITS.XLAYER_NATIVE_TRANSFER)
|
|
142
|
+
: Number(GAS_LIMITS.NATIVE_TRANSFER);
|
|
146
143
|
const multiplier = config.gasLimitMultiplier ?? 1.1;
|
|
147
144
|
return BigInt(Math.ceil(baseGas * multiplier));
|
|
148
145
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { calculateGasLimit } from '../../bundle/internal.js';
|
|
3
|
+
import { GAS_LIMITS, floorErc20TransferGasLimit } from './gas.js';
|
|
4
|
+
describe('floorErc20TransferGasLimit', () => {
|
|
5
|
+
it('raises USDT-era 65000 to SPCXB-safe 120000', () => {
|
|
6
|
+
expect(floorErc20TransferGasLimit(65000)).toBe(GAS_LIMITS.ERC20_TRANSFER);
|
|
7
|
+
expect(floorErc20TransferGasLimit(65000n)).toBe(120000n);
|
|
8
|
+
});
|
|
9
|
+
it('keeps higher user limits for tax tokens', () => {
|
|
10
|
+
expect(floorErc20TransferGasLimit(150000)).toBe(150000n);
|
|
11
|
+
expect(floorErc20TransferGasLimit(300000n)).toBe(300000n);
|
|
12
|
+
});
|
|
13
|
+
it('defaults to ERC20_TRANSFER', () => {
|
|
14
|
+
expect(floorErc20TransferGasLimit()).toBe(120000n);
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
describe('bundle calculateGasLimit ERC20 floor', () => {
|
|
18
|
+
it('does not honor 65000 for ERC20 collect', () => {
|
|
19
|
+
expect(calculateGasLimit({ gasLimit: 65000 }, false, false)).toBe(120000n);
|
|
20
|
+
});
|
|
21
|
+
it('keeps native collect at 21055', () => {
|
|
22
|
+
expect(calculateGasLimit({ gasLimit: 21055 }, true, false)).toBe(21055n);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -82,3 +82,5 @@ export declare function calculateGasLimit(chainId: number, isNative: boolean, ha
|
|
|
82
82
|
* @param isNative 是否原生代币
|
|
83
83
|
*/
|
|
84
84
|
export declare function getTransferGasLimit(chainId: number, isNative: boolean): bigint;
|
|
85
|
+
/** 归集/分发 ERC20:UI 常传 65000(USDT),SPCXB/税币 transfer 会 OOG。 */
|
|
86
|
+
export declare function floorErc20TransferGasLimit(requested?: number | bigint): bigint;
|
|
@@ -119,3 +119,8 @@ export function getTransferGasLimit(chainId, isNative) {
|
|
|
119
119
|
}
|
|
120
120
|
return GAS_LIMITS.ERC20_TRANSFER;
|
|
121
121
|
}
|
|
122
|
+
/** 归集/分发 ERC20:UI 常传 65000(USDT),SPCXB/税币 transfer 会 OOG。 */
|
|
123
|
+
export function floorErc20TransferGasLimit(requested) {
|
|
124
|
+
const n = requested === undefined ? GAS_LIMITS.ERC20_TRANSFER : BigInt(requested);
|
|
125
|
+
return n < GAS_LIMITS.ERC20_TRANSFER ? GAS_LIMITS.ERC20_TRANSFER : n;
|
|
126
|
+
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* const wbnb = ADDRESSES.BSC.WBNB;
|
|
10
10
|
*/
|
|
11
11
|
export { CHAINS, CHAIN_ID_MAP, getChainById, getChainName, getDefaultRpcUrl, isKnownChain, isBscChain, isXLayerChain, isMonadChain, isEniChain, isRobinhoodChain, getConfirmationTimeout, type ChainKey, type ChainConfig, } from './chains.js';
|
|
12
|
-
export { GAS_LIMITS, GAS_CONFIG, V3_FEE_TIERS, calculateGasLimit, getTransferGasLimit, type GasLimitKey, type V3FeeTier, } from './gas.js';
|
|
12
|
+
export { GAS_LIMITS, GAS_CONFIG, V3_FEE_TIERS, calculateGasLimit, getTransferGasLimit, floorErc20TransferGasLimit, type GasLimitKey, type V3FeeTier, } from './gas.js';
|
|
13
13
|
export { QUOTE_CONFIG, QUOTE_V3_FEE_TIERS, getQuoteChainKey, type QuoteConfigChain } from './quote.js';
|
|
14
14
|
export { applySlippageBps, reverseSlippageBps } from './slippage.js';
|
|
15
15
|
/** Flap 链标识(与 `FlapPortal` 一致,供子路径 `./constants` 使用) */
|
|
@@ -15,7 +15,7 @@ export { CHAINS, CHAIN_ID_MAP, getChainById, getChainName, getDefaultRpcUrl, isK
|
|
|
15
15
|
// ============================================================================
|
|
16
16
|
// Gas 常量
|
|
17
17
|
// ============================================================================
|
|
18
|
-
export { GAS_LIMITS, GAS_CONFIG, V3_FEE_TIERS, calculateGasLimit, getTransferGasLimit, } from './gas.js';
|
|
18
|
+
export { GAS_LIMITS, GAS_CONFIG, V3_FEE_TIERS, calculateGasLimit, getTransferGasLimit, floorErc20TransferGasLimit, } from './gas.js';
|
|
19
19
|
export { QUOTE_CONFIG, QUOTE_V3_FEE_TIERS, getQuoteChainKey } from './quote.js';
|
|
20
20
|
export { applySlippageBps, reverseSlippageBps } from './slippage.js';
|
|
21
21
|
// ============================================================================
|
|
@@ -4,11 +4,13 @@ export type OpenFourDecodedCreateArg = {
|
|
|
4
4
|
quoteAsset: string;
|
|
5
5
|
validTimestamp: bigint;
|
|
6
6
|
};
|
|
7
|
-
/** Four 签名在链上只活到 validTimestamp
|
|
8
|
-
export declare const OPENFOUR_CREATE_MIN_REMAIN_SEC =
|
|
7
|
+
/** Four 签名在链上只活到 validTimestamp;剩余少于此秒数就再拉一次 createArg,但未过期仍提交。 */
|
|
8
|
+
export declare const OPENFOUR_CREATE_MIN_REMAIN_SEC = 90n;
|
|
9
9
|
export declare const OPENFOUR_CREATE_EXPIRED_MESSAGE = "OpenFour \u53D1\u5E01\u7B7E\u540D\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u518D\u70B9\u4E00\u6B21\u53D1\u5C04\u3002Four \u7684 validTimestamp \u5F88\u77ED\uFF0C\u63A5\u53E3\u6162\u65F6\u7B7E\u540D\u5230\u8FBE\u94FE\u4E0A\u5C31\u5DF2\u7ECF\u5931\u6548\u3002";
|
|
10
10
|
export declare function decodeOpenFourCreateArg(rawCreateArg: string): OpenFourDecodedCreateArg;
|
|
11
11
|
export declare function shouldRefreshOpenFourCreateArg(validTimestamp: bigint, chainTimestamp: bigint, minRemainSec?: bigint): boolean;
|
|
12
|
+
/** 合约是 block.timestamp > validTimestamp 才回滚;相等这一秒仍有效。 */
|
|
13
|
+
export declare function isOpenFourCreateArgExpired(validTimestamp: bigint, chainTimestamp: bigint): boolean;
|
|
12
14
|
export declare function isOpenFourPresaleNative(params: {
|
|
13
15
|
presaleQuote: bigint;
|
|
14
16
|
quoteAsset: string;
|
|
@@ -40,8 +40,8 @@ const ABI_13 = [
|
|
|
40
40
|
}),
|
|
41
41
|
];
|
|
42
42
|
const coder = AbiCoder.defaultAbiCoder();
|
|
43
|
-
/** Four 签名在链上只活到 validTimestamp
|
|
44
|
-
export const OPENFOUR_CREATE_MIN_REMAIN_SEC =
|
|
43
|
+
/** Four 签名在链上只活到 validTimestamp;剩余少于此秒数就再拉一次 createArg,但未过期仍提交。 */
|
|
44
|
+
export const OPENFOUR_CREATE_MIN_REMAIN_SEC = 90n;
|
|
45
45
|
export const OPENFOUR_CREATE_EXPIRED_MESSAGE = 'OpenFour 发币签名已过期,请再点一次发射。Four 的 validTimestamp 很短,接口慢时签名到达链上就已经失效。';
|
|
46
46
|
function toBigInt(value) {
|
|
47
47
|
if (value == null)
|
|
@@ -69,6 +69,10 @@ export function decodeOpenFourCreateArg(rawCreateArg) {
|
|
|
69
69
|
export function shouldRefreshOpenFourCreateArg(validTimestamp, chainTimestamp, minRemainSec = OPENFOUR_CREATE_MIN_REMAIN_SEC) {
|
|
70
70
|
return validTimestamp < chainTimestamp + minRemainSec;
|
|
71
71
|
}
|
|
72
|
+
/** 合约是 block.timestamp > validTimestamp 才回滚;相等这一秒仍有效。 */
|
|
73
|
+
export function isOpenFourCreateArgExpired(validTimestamp, chainTimestamp) {
|
|
74
|
+
return validTimestamp < chainTimestamp;
|
|
75
|
+
}
|
|
72
76
|
export function isOpenFourPresaleNative(params) {
|
|
73
77
|
if (params.presaleQuote <= 0n)
|
|
74
78
|
return false;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AbiCoder, ParamType, ZeroAddress, ZeroHash } from 'ethers';
|
|
2
2
|
import { describe, expect, it } from 'vitest';
|
|
3
|
-
import { OPENFOUR_CREATE_MIN_REMAIN_SEC, decodeOpenFourCreateArg, shouldRefreshOpenFourCreateArg, } from './create-arg.js';
|
|
3
|
+
import { OPENFOUR_CREATE_MIN_REMAIN_SEC, decodeOpenFourCreateArg, isOpenFourCreateArgExpired, shouldRefreshOpenFourCreateArg, } from './create-arg.js';
|
|
4
4
|
const INIT = [
|
|
5
5
|
{ name: 'name', type: 'string' },
|
|
6
6
|
{ name: 'symbol', type: 'string' },
|
|
@@ -79,3 +79,13 @@ describe('shouldRefreshOpenFourCreateArg', () => {
|
|
|
79
79
|
expect(shouldRefreshOpenFourCreateArg(100n + OPENFOUR_CREATE_MIN_REMAIN_SEC, 100n)).toBe(false);
|
|
80
80
|
});
|
|
81
81
|
});
|
|
82
|
+
describe('isOpenFourCreateArgExpired', () => {
|
|
83
|
+
it('treats equal timestamps as still valid', () => {
|
|
84
|
+
expect(isOpenFourCreateArgExpired(100n, 100n)).toBe(false);
|
|
85
|
+
});
|
|
86
|
+
it('treats the dumped Royalty+SPCXB deadline as expired at 17:30 CST', () => {
|
|
87
|
+
const validTimestamp = 1789982212n;
|
|
88
|
+
const reportedAt = BigInt(Math.floor(Date.parse('2026-09-21T09:30:00.000Z') / 1000));
|
|
89
|
+
expect(isOpenFourCreateArgExpired(validTimestamp, reportedAt)).toBe(true);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export type { OpenFourAddresses, OpenFourCreateReq, OpenFourInitParams, OpenFourModuleSchema, OpenFourParamDescriptor, OpenFourPresetSchemas, OpenFourTemplate, OpenFourTemplateConfig, } from './types.js';
|
|
2
2
|
export { collectOpenFourSchemaParams, defaultOpenFourFormFromSchema, emptyOpenFourInitParams, encodeOpenFourInitParams, encodeOpenFourModuleParams, } from './schema.js';
|
|
3
|
-
export { OPENFOUR_CREATE_EXPIRED_MESSAGE, OPENFOUR_CREATE_MIN_REMAIN_SEC, computeOpenFourCreateValueWei, decodeOpenFourCreateArg, isOpenFourPresaleNative, shouldRefreshOpenFourCreateArg, type OpenFourDecodedCreateArg, } from './create-arg.js';
|
|
3
|
+
export { OPENFOUR_CREATE_EXPIRED_MESSAGE, OPENFOUR_CREATE_MIN_REMAIN_SEC, computeOpenFourCreateValueWei, decodeOpenFourCreateArg, isOpenFourCreateArgExpired, isOpenFourPresaleNative, shouldRefreshOpenFourCreateArg, type OpenFourDecodedCreateArg, } from './create-arg.js';
|
|
4
4
|
export { loadOpenFourAddresses, loadOpenFourPresetSchemas } from './registry.js';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { collectOpenFourSchemaParams, defaultOpenFourFormFromSchema, emptyOpenFourInitParams, encodeOpenFourInitParams, encodeOpenFourModuleParams, } from './schema.js';
|
|
2
|
-
export { OPENFOUR_CREATE_EXPIRED_MESSAGE, OPENFOUR_CREATE_MIN_REMAIN_SEC, computeOpenFourCreateValueWei, decodeOpenFourCreateArg, isOpenFourPresaleNative, shouldRefreshOpenFourCreateArg, } from './create-arg.js';
|
|
2
|
+
export { OPENFOUR_CREATE_EXPIRED_MESSAGE, OPENFOUR_CREATE_MIN_REMAIN_SEC, computeOpenFourCreateValueWei, decodeOpenFourCreateArg, isOpenFourCreateArgExpired, isOpenFourPresaleNative, shouldRefreshOpenFourCreateArg, } from './create-arg.js';
|
|
3
3
|
export { loadOpenFourAddresses, loadOpenFourPresetSchemas } from './registry.js';
|