fourmm 0.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/README.md +147 -0
- package/dist/bin.d.ts +9 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +14 -0
- package/dist/bin.js.map +1 -0
- package/dist/cli.d.ts +319 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +25 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/config.d.ts +35 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +145 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/query.d.ts +51 -0
- package/dist/commands/query.d.ts.map +1 -0
- package/dist/commands/query.js +364 -0
- package/dist/commands/query.js.map +1 -0
- package/dist/commands/token.d.ts +55 -0
- package/dist/commands/token.d.ts.map +1 -0
- package/dist/commands/token.js +650 -0
- package/dist/commands/token.js.map +1 -0
- package/dist/commands/tools.d.ts +54 -0
- package/dist/commands/tools.d.ts.map +1 -0
- package/dist/commands/tools.js +499 -0
- package/dist/commands/tools.js.map +1 -0
- package/dist/commands/trade.d.ts +63 -0
- package/dist/commands/trade.d.ts.map +1 -0
- package/dist/commands/trade.js +933 -0
- package/dist/commands/trade.js.map +1 -0
- package/dist/commands/transfer.d.ts +51 -0
- package/dist/commands/transfer.d.ts.map +1 -0
- package/dist/commands/transfer.js +728 -0
- package/dist/commands/transfer.js.map +1 -0
- package/dist/commands/wallet.d.ts +111 -0
- package/dist/commands/wallet.d.ts.map +1 -0
- package/dist/commands/wallet.js +716 -0
- package/dist/commands/wallet.js.map +1 -0
- package/dist/contracts/erc20.d.ts +72 -0
- package/dist/contracts/erc20.d.ts.map +1 -0
- package/dist/contracts/erc20.js +55 -0
- package/dist/contracts/erc20.js.map +1 -0
- package/dist/contracts/fourmemeMmRouter.d.ts +68 -0
- package/dist/contracts/fourmemeMmRouter.d.ts.map +1 -0
- package/dist/contracts/fourmemeMmRouter.js +48 -0
- package/dist/contracts/fourmemeMmRouter.js.map +1 -0
- package/dist/contracts/pancakeRouter.d.ts +73 -0
- package/dist/contracts/pancakeRouter.d.ts.map +1 -0
- package/dist/contracts/pancakeRouter.js +50 -0
- package/dist/contracts/pancakeRouter.js.map +1 -0
- package/dist/contracts/tokenManager2.d.ts +193 -0
- package/dist/contracts/tokenManager2.d.ts.map +1 -0
- package/dist/contracts/tokenManager2.js +108 -0
- package/dist/contracts/tokenManager2.js.map +1 -0
- package/dist/contracts/tokenManagerHelper3.d.ts +118 -0
- package/dist/contracts/tokenManagerHelper3.d.ts.map +1 -0
- package/dist/contracts/tokenManagerHelper3.js +66 -0
- package/dist/contracts/tokenManagerHelper3.js.map +1 -0
- package/dist/datastore/cache.d.ts +20 -0
- package/dist/datastore/cache.d.ts.map +1 -0
- package/dist/datastore/cache.js +45 -0
- package/dist/datastore/cache.js.map +1 -0
- package/dist/datastore/index.d.ts +85 -0
- package/dist/datastore/index.d.ts.map +1 -0
- package/dist/datastore/index.js +341 -0
- package/dist/datastore/index.js.map +1 -0
- package/dist/datastore/paths.d.ts +17 -0
- package/dist/datastore/paths.d.ts.map +1 -0
- package/dist/datastore/paths.js +39 -0
- package/dist/datastore/paths.js.map +1 -0
- package/dist/datastore/types.d.ts +105 -0
- package/dist/datastore/types.d.ts.map +1 -0
- package/dist/datastore/types.js +8 -0
- package/dist/datastore/types.js.map +1 -0
- package/dist/fourmeme/auth.d.ts +22 -0
- package/dist/fourmeme/auth.d.ts.map +1 -0
- package/dist/fourmeme/auth.js +78 -0
- package/dist/fourmeme/auth.js.map +1 -0
- package/dist/fourmeme/create.d.ts +31 -0
- package/dist/fourmeme/create.d.ts.map +1 -0
- package/dist/fourmeme/create.js +111 -0
- package/dist/fourmeme/create.js.map +1 -0
- package/dist/fourmeme/upload.d.ts +16 -0
- package/dist/fourmeme/upload.d.ts.map +1 -0
- package/dist/fourmeme/upload.js +52 -0
- package/dist/fourmeme/upload.js.map +1 -0
- package/dist/lib/bundle.d.ts +51 -0
- package/dist/lib/bundle.d.ts.map +1 -0
- package/dist/lib/bundle.js +95 -0
- package/dist/lib/bundle.js.map +1 -0
- package/dist/lib/config.d.ts +58 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +183 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/const.d.ts +165 -0
- package/dist/lib/const.d.ts.map +1 -0
- package/dist/lib/const.js +98 -0
- package/dist/lib/const.js.map +1 -0
- package/dist/lib/env.d.ts +14 -0
- package/dist/lib/env.d.ts.map +1 -0
- package/dist/lib/env.js +18 -0
- package/dist/lib/env.js.map +1 -0
- package/dist/lib/guards.d.ts +44 -0
- package/dist/lib/guards.d.ts.map +1 -0
- package/dist/lib/guards.js +65 -0
- package/dist/lib/guards.js.map +1 -0
- package/dist/lib/identify.d.ts +85 -0
- package/dist/lib/identify.d.ts.map +1 -0
- package/dist/lib/identify.js +88 -0
- package/dist/lib/identify.js.map +1 -0
- package/dist/lib/pricing.d.ts +62 -0
- package/dist/lib/pricing.d.ts.map +1 -0
- package/dist/lib/pricing.js +302 -0
- package/dist/lib/pricing.js.map +1 -0
- package/dist/lib/routing.d.ts +57 -0
- package/dist/lib/routing.d.ts.map +1 -0
- package/dist/lib/routing.js +67 -0
- package/dist/lib/routing.js.map +1 -0
- package/dist/lib/slippage.d.ts +29 -0
- package/dist/lib/slippage.d.ts.map +1 -0
- package/dist/lib/slippage.js +110 -0
- package/dist/lib/slippage.js.map +1 -0
- package/dist/lib/tracker.d.ts +68 -0
- package/dist/lib/tracker.d.ts.map +1 -0
- package/dist/lib/tracker.js +155 -0
- package/dist/lib/tracker.js.map +1 -0
- package/dist/lib/viem.d.ts +12 -0
- package/dist/lib/viem.d.ts.map +1 -0
- package/dist/lib/viem.js +44 -0
- package/dist/lib/viem.js.map +1 -0
- package/dist/lib/wallet-rows.d.ts +30 -0
- package/dist/lib/wallet-rows.d.ts.map +1 -0
- package/dist/lib/wallet-rows.js +9 -0
- package/dist/lib/wallet-rows.js.map +1 -0
- package/dist/lib/walletClient.d.ts +16 -0
- package/dist/lib/walletClient.d.ts.map +1 -0
- package/dist/lib/walletClient.js +26 -0
- package/dist/lib/walletClient.js.map +1 -0
- package/dist/wallets/groups/encrypt.d.ts +26 -0
- package/dist/wallets/groups/encrypt.d.ts.map +1 -0
- package/dist/wallets/groups/encrypt.js +52 -0
- package/dist/wallets/groups/encrypt.js.map +1 -0
- package/dist/wallets/groups/generate.d.ts +19 -0
- package/dist/wallets/groups/generate.d.ts.map +1 -0
- package/dist/wallets/groups/generate.js +36 -0
- package/dist/wallets/groups/generate.js.map +1 -0
- package/dist/wallets/groups/store.d.ts +107 -0
- package/dist/wallets/groups/store.d.ts.map +1 -0
- package/dist/wallets/groups/store.js +254 -0
- package/dist/wallets/groups/store.js.map +1 -0
- package/package.json +50 -0
- package/skills/SKILL.md +187 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* On-chain constants for fourMM.
|
|
3
|
+
*
|
|
4
|
+
* These addresses are immutable and come from the Four.meme protocol
|
|
5
|
+
* documentation (docs/API-Documents.03-03-2026.md) and public BSC infrastructure.
|
|
6
|
+
*
|
|
7
|
+
* DO NOT read them from config — hardcoding catches misconfiguration at
|
|
8
|
+
* import time instead of at runtime.
|
|
9
|
+
*/
|
|
10
|
+
import type { Address } from 'viem';
|
|
11
|
+
/** Legacy TokenManager (V1) — only for tokens created before 2024-09-05 */
|
|
12
|
+
export declare const TOKEN_MANAGER_V1: Address;
|
|
13
|
+
/** Current TokenManager (V2) — the default path for all new tokens */
|
|
14
|
+
export declare const TOKEN_MANAGER_V2: Address;
|
|
15
|
+
/**
|
|
16
|
+
* TokenManagerHelper3 — wrapper around V1/V2 that normalizes queries.
|
|
17
|
+
* Always prefer this for reads. Do not hardcode V1/V2 directly in commands.
|
|
18
|
+
*/
|
|
19
|
+
export declare const TOKEN_MANAGER_HELPER3: Address;
|
|
20
|
+
/**
|
|
21
|
+
* AgentIdentifier — checks whether an address holds an Agent NFT.
|
|
22
|
+
* Tokens created by Agent wallets get aiCreator=true automatically.
|
|
23
|
+
*/
|
|
24
|
+
export declare const AGENT_IDENTIFIER: Address;
|
|
25
|
+
/** PancakeSwap V2 Router on BSC mainnet */
|
|
26
|
+
export declare const PANCAKE_V2_ROUTER: Address;
|
|
27
|
+
/** PancakeSwap V2 Factory */
|
|
28
|
+
export declare const PANCAKE_V2_FACTORY: Address;
|
|
29
|
+
/**
|
|
30
|
+
* FourmemeMmRouter v2 — atomic router with reentrancy guard + approval hygiene.
|
|
31
|
+
*
|
|
32
|
+
* v2 changes: nonReentrant modifier, approval reset to 0 after sell,
|
|
33
|
+
* fee-on-transfer compat in volumePancake. BSCScan verified.
|
|
34
|
+
*
|
|
35
|
+
* v1 (0x5A3A9981...) is deprecated but still on-chain.
|
|
36
|
+
*/
|
|
37
|
+
export declare const FOURMEME_MM_ROUTER: Address;
|
|
38
|
+
/**
|
|
39
|
+
* Get the router address.
|
|
40
|
+
*
|
|
41
|
+
* Now that the router is deployed, this is a simple passthrough.
|
|
42
|
+
* Kept as a function (not direct import) so commands have a single
|
|
43
|
+
* call site to update if we ever redeploy.
|
|
44
|
+
*/
|
|
45
|
+
export declare function requireRouter(): Address;
|
|
46
|
+
export declare const CHAINS: {
|
|
47
|
+
readonly bsc: {
|
|
48
|
+
blockExplorers: {
|
|
49
|
+
readonly default: {
|
|
50
|
+
readonly name: "BscScan";
|
|
51
|
+
readonly url: "https://bscscan.com";
|
|
52
|
+
readonly apiUrl: "https://api.bscscan.com/api";
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
blockTime: 750;
|
|
56
|
+
contracts: {
|
|
57
|
+
readonly multicall3: {
|
|
58
|
+
readonly address: "0xca11bde05977b3631167028862be2a173976ca11";
|
|
59
|
+
readonly blockCreated: 15921452;
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
ensTlds?: readonly string[] | undefined;
|
|
63
|
+
id: 56;
|
|
64
|
+
name: "BNB Smart Chain";
|
|
65
|
+
nativeCurrency: {
|
|
66
|
+
readonly decimals: 18;
|
|
67
|
+
readonly name: "BNB";
|
|
68
|
+
readonly symbol: "BNB";
|
|
69
|
+
};
|
|
70
|
+
experimental_preconfirmationTime?: number | undefined | undefined;
|
|
71
|
+
rpcUrls: {
|
|
72
|
+
readonly default: {
|
|
73
|
+
readonly http: readonly ["https://56.rpc.thirdweb.com"];
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
sourceId?: number | undefined | undefined;
|
|
77
|
+
testnet?: boolean | undefined | undefined;
|
|
78
|
+
custom?: Record<string, unknown> | undefined;
|
|
79
|
+
extendSchema?: Record<string, unknown> | undefined;
|
|
80
|
+
fees?: import("viem").ChainFees<undefined> | undefined;
|
|
81
|
+
formatters?: undefined;
|
|
82
|
+
prepareTransactionRequest?: ((args: import("viem").PrepareTransactionRequestParameters, options: {
|
|
83
|
+
phase: "beforeFillTransaction" | "beforeFillParameters" | "afterFillParameters";
|
|
84
|
+
}) => Promise<import("viem").PrepareTransactionRequestParameters>) | [fn: ((args: import("viem").PrepareTransactionRequestParameters, options: {
|
|
85
|
+
phase: "beforeFillTransaction" | "beforeFillParameters" | "afterFillParameters";
|
|
86
|
+
}) => Promise<import("viem").PrepareTransactionRequestParameters>) | undefined, options: {
|
|
87
|
+
runAt: readonly ("beforeFillTransaction" | "beforeFillParameters" | "afterFillParameters")[];
|
|
88
|
+
}] | undefined;
|
|
89
|
+
serializers?: import("viem").ChainSerializers<undefined, import("viem").TransactionSerializable> | undefined;
|
|
90
|
+
verifyHash?: ((client: import("viem").Client, parameters: import("viem").VerifyHashActionParameters) => Promise<import("viem").VerifyHashActionReturnType>) | undefined;
|
|
91
|
+
};
|
|
92
|
+
readonly 'bsc-testnet': {
|
|
93
|
+
blockExplorers: {
|
|
94
|
+
readonly default: {
|
|
95
|
+
readonly name: "BscScan";
|
|
96
|
+
readonly url: "https://testnet.bscscan.com";
|
|
97
|
+
readonly apiUrl: "https://api-testnet.bscscan.com/api";
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
blockTime?: number | undefined | undefined;
|
|
101
|
+
contracts: {
|
|
102
|
+
readonly multicall3: {
|
|
103
|
+
readonly address: "0xca11bde05977b3631167028862be2a173976ca11";
|
|
104
|
+
readonly blockCreated: 17422483;
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
ensTlds?: readonly string[] | undefined;
|
|
108
|
+
id: 97;
|
|
109
|
+
name: "BNB Smart Chain Testnet";
|
|
110
|
+
nativeCurrency: {
|
|
111
|
+
readonly decimals: 18;
|
|
112
|
+
readonly name: "BNB";
|
|
113
|
+
readonly symbol: "tBNB";
|
|
114
|
+
};
|
|
115
|
+
experimental_preconfirmationTime?: number | undefined | undefined;
|
|
116
|
+
rpcUrls: {
|
|
117
|
+
readonly default: {
|
|
118
|
+
readonly http: readonly ["https://data-seed-prebsc-1-s1.bnbchain.org:8545"];
|
|
119
|
+
};
|
|
120
|
+
};
|
|
121
|
+
sourceId?: number | undefined | undefined;
|
|
122
|
+
testnet: true;
|
|
123
|
+
custom?: Record<string, unknown> | undefined;
|
|
124
|
+
extendSchema?: Record<string, unknown> | undefined;
|
|
125
|
+
fees?: import("viem").ChainFees<undefined> | undefined;
|
|
126
|
+
formatters?: undefined;
|
|
127
|
+
prepareTransactionRequest?: ((args: import("viem").PrepareTransactionRequestParameters, options: {
|
|
128
|
+
phase: "beforeFillTransaction" | "beforeFillParameters" | "afterFillParameters";
|
|
129
|
+
}) => Promise<import("viem").PrepareTransactionRequestParameters>) | [fn: ((args: import("viem").PrepareTransactionRequestParameters, options: {
|
|
130
|
+
phase: "beforeFillTransaction" | "beforeFillParameters" | "afterFillParameters";
|
|
131
|
+
}) => Promise<import("viem").PrepareTransactionRequestParameters>) | undefined, options: {
|
|
132
|
+
runAt: readonly ("beforeFillTransaction" | "beforeFillParameters" | "afterFillParameters")[];
|
|
133
|
+
}] | undefined;
|
|
134
|
+
serializers?: import("viem").ChainSerializers<undefined, import("viem").TransactionSerializable> | undefined;
|
|
135
|
+
verifyHash?: ((client: import("viem").Client, parameters: import("viem").VerifyHashActionParameters) => Promise<import("viem").VerifyHashActionReturnType>) | undefined;
|
|
136
|
+
};
|
|
137
|
+
};
|
|
138
|
+
export type SupportedChainName = keyof typeof CHAINS;
|
|
139
|
+
/**
|
|
140
|
+
* Sentinel "address" for native BNB in fourMM's DataStore and routing layers.
|
|
141
|
+
*
|
|
142
|
+
* Important: BNB is the native currency of BSC and has no contract address.
|
|
143
|
+
* We use the zero address as a convention. This matches:
|
|
144
|
+
* 1. Four.meme's own usage — Helper3.getTokenInfo.quote returns address(0)
|
|
145
|
+
* when the token is priced in BNB (confirmed via BSC mainnet reads)
|
|
146
|
+
* 2. The broader EVM convention for "native token placeholder"
|
|
147
|
+
*
|
|
148
|
+
* DO NOT confuse this with WBNB (0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c),
|
|
149
|
+
* which is a REAL ERC20 contract wrapping BNB. Using WBNB here would conflate
|
|
150
|
+
* native BNB transfers with WBNB token trades.
|
|
151
|
+
*/
|
|
152
|
+
export declare const NATIVE_BNB: Address;
|
|
153
|
+
/** Wrapped BNB on BSC mainnet */
|
|
154
|
+
export declare const WBNB: Address;
|
|
155
|
+
/** BUSD on BSC mainnet */
|
|
156
|
+
export declare const BUSD: Address;
|
|
157
|
+
/** USDT (BEP-20) on BSC mainnet */
|
|
158
|
+
export declare const USDT: Address;
|
|
159
|
+
/**
|
|
160
|
+
* Return true if an address has the Four.meme native-token signature.
|
|
161
|
+
* Four.meme deploys all protocol-native tokens at addresses ending in `4444`.
|
|
162
|
+
* This is a cheap sanity check before making an RPC call.
|
|
163
|
+
*/
|
|
164
|
+
export declare function isFourmemeNativeAddress(address: string): boolean;
|
|
165
|
+
//# sourceMappingURL=const.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"const.d.ts","sourceRoot":"","sources":["../../src/lib/const.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAMnC,2EAA2E;AAC3E,eAAO,MAAM,gBAAgB,EAAE,OACe,CAAA;AAE9C,sEAAsE;AACtE,eAAO,MAAM,gBAAgB,EAAE,OACe,CAAA;AAE9C;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,OACU,CAAA;AAE9C;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,OACe,CAAA;AAM9C,2CAA2C;AAC3C,eAAO,MAAM,iBAAiB,EAAE,OACc,CAAA;AAE9C,6BAA6B;AAC7B,eAAO,MAAM,kBAAkB,EAAE,OACa,CAAA;AAM9C;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,EAAE,OACa,CAAA;AAE9C;;;;;;GAMG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAMD,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAGT,CAAA;AAEV,MAAM,MAAM,kBAAkB,GAAG,MAAM,OAAO,MAAM,CAAA;AAMpD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,UAAU,EAAE,OAAsD,CAAA;AAE/E,iCAAiC;AACjC,eAAO,MAAM,IAAI,EAAE,OAAsD,CAAA;AAEzE,0BAA0B;AAC1B,eAAO,MAAM,IAAI,EAAE,OAAsD,CAAA;AAEzE,mCAAmC;AACnC,eAAO,MAAM,IAAI,EAAE,OAAsD,CAAA;AAMzE;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEhE"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* On-chain constants for fourMM.
|
|
3
|
+
*
|
|
4
|
+
* These addresses are immutable and come from the Four.meme protocol
|
|
5
|
+
* documentation (docs/API-Documents.03-03-2026.md) and public BSC infrastructure.
|
|
6
|
+
*
|
|
7
|
+
* DO NOT read them from config — hardcoding catches misconfiguration at
|
|
8
|
+
* import time instead of at runtime.
|
|
9
|
+
*/
|
|
10
|
+
import { bsc, bscTestnet } from 'viem/chains';
|
|
11
|
+
// ============================================================
|
|
12
|
+
// Four.meme (BSC mainnet)
|
|
13
|
+
// ============================================================
|
|
14
|
+
/** Legacy TokenManager (V1) — only for tokens created before 2024-09-05 */
|
|
15
|
+
export const TOKEN_MANAGER_V1 = '0xEC4549caDcE5DA21Df6E6422d448034B5233bFbC';
|
|
16
|
+
/** Current TokenManager (V2) — the default path for all new tokens */
|
|
17
|
+
export const TOKEN_MANAGER_V2 = '0x5c952063c7fc8610FFDB798152D69F0B9550762b';
|
|
18
|
+
/**
|
|
19
|
+
* TokenManagerHelper3 — wrapper around V1/V2 that normalizes queries.
|
|
20
|
+
* Always prefer this for reads. Do not hardcode V1/V2 directly in commands.
|
|
21
|
+
*/
|
|
22
|
+
export const TOKEN_MANAGER_HELPER3 = '0xF251F83e40a78868FcfA3FA4599Dad6494E46034';
|
|
23
|
+
/**
|
|
24
|
+
* AgentIdentifier — checks whether an address holds an Agent NFT.
|
|
25
|
+
* Tokens created by Agent wallets get aiCreator=true automatically.
|
|
26
|
+
*/
|
|
27
|
+
export const AGENT_IDENTIFIER = '0x09B44A633de9F9EBF6FB9Bdd5b5629d3DD2cef13';
|
|
28
|
+
// ============================================================
|
|
29
|
+
// PancakeSwap (post-graduation)
|
|
30
|
+
// ============================================================
|
|
31
|
+
/** PancakeSwap V2 Router on BSC mainnet */
|
|
32
|
+
export const PANCAKE_V2_ROUTER = '0x10ED43C718714eb63d5aA57B78B54704E256024E';
|
|
33
|
+
/** PancakeSwap V2 Factory */
|
|
34
|
+
export const PANCAKE_V2_FACTORY = '0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73';
|
|
35
|
+
// ============================================================
|
|
36
|
+
// fourMM contracts
|
|
37
|
+
// ============================================================
|
|
38
|
+
/**
|
|
39
|
+
* FourmemeMmRouter v2 — atomic router with reentrancy guard + approval hygiene.
|
|
40
|
+
*
|
|
41
|
+
* v2 changes: nonReentrant modifier, approval reset to 0 after sell,
|
|
42
|
+
* fee-on-transfer compat in volumePancake. BSCScan verified.
|
|
43
|
+
*
|
|
44
|
+
* v1 (0x5A3A9981...) is deprecated but still on-chain.
|
|
45
|
+
*/
|
|
46
|
+
export const FOURMEME_MM_ROUTER = '0xd62c2fd94176f98424af83e4b9a333d454b2216c';
|
|
47
|
+
/**
|
|
48
|
+
* Get the router address.
|
|
49
|
+
*
|
|
50
|
+
* Now that the router is deployed, this is a simple passthrough.
|
|
51
|
+
* Kept as a function (not direct import) so commands have a single
|
|
52
|
+
* call site to update if we ever redeploy.
|
|
53
|
+
*/
|
|
54
|
+
export function requireRouter() {
|
|
55
|
+
return FOURMEME_MM_ROUTER;
|
|
56
|
+
}
|
|
57
|
+
// ============================================================
|
|
58
|
+
// BSC chain configs
|
|
59
|
+
// ============================================================
|
|
60
|
+
export const CHAINS = {
|
|
61
|
+
bsc,
|
|
62
|
+
'bsc-testnet': bscTestnet,
|
|
63
|
+
};
|
|
64
|
+
// ============================================================
|
|
65
|
+
// Common tokens
|
|
66
|
+
// ============================================================
|
|
67
|
+
/**
|
|
68
|
+
* Sentinel "address" for native BNB in fourMM's DataStore and routing layers.
|
|
69
|
+
*
|
|
70
|
+
* Important: BNB is the native currency of BSC and has no contract address.
|
|
71
|
+
* We use the zero address as a convention. This matches:
|
|
72
|
+
* 1. Four.meme's own usage — Helper3.getTokenInfo.quote returns address(0)
|
|
73
|
+
* when the token is priced in BNB (confirmed via BSC mainnet reads)
|
|
74
|
+
* 2. The broader EVM convention for "native token placeholder"
|
|
75
|
+
*
|
|
76
|
+
* DO NOT confuse this with WBNB (0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c),
|
|
77
|
+
* which is a REAL ERC20 contract wrapping BNB. Using WBNB here would conflate
|
|
78
|
+
* native BNB transfers with WBNB token trades.
|
|
79
|
+
*/
|
|
80
|
+
export const NATIVE_BNB = '0x0000000000000000000000000000000000000000';
|
|
81
|
+
/** Wrapped BNB on BSC mainnet */
|
|
82
|
+
export const WBNB = '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c';
|
|
83
|
+
/** BUSD on BSC mainnet */
|
|
84
|
+
export const BUSD = '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56';
|
|
85
|
+
/** USDT (BEP-20) on BSC mainnet */
|
|
86
|
+
export const USDT = '0x55d398326f99059fF775485246999027B3197955';
|
|
87
|
+
// ============================================================
|
|
88
|
+
// Four.meme convention: all native tokens end in 4444
|
|
89
|
+
// ============================================================
|
|
90
|
+
/**
|
|
91
|
+
* Return true if an address has the Four.meme native-token signature.
|
|
92
|
+
* Four.meme deploys all protocol-native tokens at addresses ending in `4444`.
|
|
93
|
+
* This is a cheap sanity check before making an RPC call.
|
|
94
|
+
*/
|
|
95
|
+
export function isFourmemeNativeAddress(address) {
|
|
96
|
+
return address.toLowerCase().endsWith('4444');
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=const.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"const.js","sourceRoot":"","sources":["../../src/lib/const.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAG7C,+DAA+D;AAC/D,0BAA0B;AAC1B,+DAA+D;AAE/D,2EAA2E;AAC3E,MAAM,CAAC,MAAM,gBAAgB,GAC3B,4CAA4C,CAAA;AAE9C,sEAAsE;AACtE,MAAM,CAAC,MAAM,gBAAgB,GAC3B,4CAA4C,CAAA;AAE9C;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAChC,4CAA4C,CAAA;AAE9C;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAC3B,4CAA4C,CAAA;AAE9C,+DAA+D;AAC/D,gCAAgC;AAChC,+DAA+D;AAE/D,2CAA2C;AAC3C,MAAM,CAAC,MAAM,iBAAiB,GAC5B,4CAA4C,CAAA;AAE9C,6BAA6B;AAC7B,MAAM,CAAC,MAAM,kBAAkB,GAC7B,4CAA4C,CAAA;AAE9C,+DAA+D;AAC/D,mBAAmB;AACnB,+DAA+D;AAE/D;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAC7B,4CAA4C,CAAA;AAE9C;;;;;;GAMG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,kBAAkB,CAAA;AAC3B,CAAC;AAED,+DAA+D;AAC/D,oBAAoB;AACpB,+DAA+D;AAE/D,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,GAAG;IACH,aAAa,EAAE,UAAU;CACjB,CAAA;AAIV,+DAA+D;AAC/D,gBAAgB;AAChB,+DAA+D;AAE/D;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,UAAU,GAAY,4CAA4C,CAAA;AAE/E,iCAAiC;AACjC,MAAM,CAAC,MAAM,IAAI,GAAY,4CAA4C,CAAA;AAEzE,0BAA0B;AAC1B,MAAM,CAAC,MAAM,IAAI,GAAY,4CAA4C,CAAA;AAEzE,mCAAmC;AACnC,MAAM,CAAC,MAAM,IAAI,GAAY,4CAA4C,CAAA;AAEzE,+DAA+D;AAC/D,sDAAsD;AACtD,+DAA+D;AAE/D;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,OAAe;IACrD,OAAO,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;AAC/C,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secret / passphrase resolution helpers.
|
|
3
|
+
*
|
|
4
|
+
* Rule of thumb: passwords should NEVER live in command option schemas that
|
|
5
|
+
* agents can see in `--llms` or `--schema` output. They also shouldn't be
|
|
6
|
+
* global state (makes testing awkward and hides dependencies).
|
|
7
|
+
*
|
|
8
|
+
* Instead: commands accept an optional `--password` escape hatch (for local
|
|
9
|
+
* scripting), fall back to env vars, and pass the resolved password as an
|
|
10
|
+
* explicit function argument into the store layer.
|
|
11
|
+
*/
|
|
12
|
+
/** Resolve the in-house wallet store master password from arg or env */
|
|
13
|
+
export declare function resolveFourmmPassword(explicit?: string | undefined): string | undefined;
|
|
14
|
+
//# sourceMappingURL=env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/lib/env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,wEAAwE;AACxE,wBAAgB,qBAAqB,CACnC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAC5B,MAAM,GAAG,SAAS,CAGpB"}
|
package/dist/lib/env.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secret / passphrase resolution helpers.
|
|
3
|
+
*
|
|
4
|
+
* Rule of thumb: passwords should NEVER live in command option schemas that
|
|
5
|
+
* agents can see in `--llms` or `--schema` output. They also shouldn't be
|
|
6
|
+
* global state (makes testing awkward and hides dependencies).
|
|
7
|
+
*
|
|
8
|
+
* Instead: commands accept an optional `--password` escape hatch (for local
|
|
9
|
+
* scripting), fall back to env vars, and pass the resolved password as an
|
|
10
|
+
* explicit function argument into the store layer.
|
|
11
|
+
*/
|
|
12
|
+
/** Resolve the in-house wallet store master password from arg or env */
|
|
13
|
+
export function resolveFourmmPassword(explicit) {
|
|
14
|
+
if (explicit)
|
|
15
|
+
return explicit;
|
|
16
|
+
return process.env.FOURMM_PASSWORD || undefined;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/lib/env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,wEAAwE;AACxE,MAAM,UAAU,qBAAqB,CACnC,QAA6B;IAE7B,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAA;IAC7B,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,SAAS,CAAA;AACjD,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entry guards for trade / tools / transfer commands.
|
|
3
|
+
*
|
|
4
|
+
* The core invariant: every command that touches trading logic for a specific
|
|
5
|
+
* token MUST call `assertSupportedToken(ca)` before doing any signing or
|
|
6
|
+
* on-chain write. This is how fourMM enforces "TaxToken and X Mode are out of
|
|
7
|
+
* scope" without having to repeat the check inside each command body.
|
|
8
|
+
*
|
|
9
|
+
* Failure mode: `assertSupportedToken` throws `UnsupportedTokenError`, which
|
|
10
|
+
* command handlers can catch and return as a structured `c.error({...})`
|
|
11
|
+
* with a clean error code.
|
|
12
|
+
*/
|
|
13
|
+
import type { Address } from 'viem';
|
|
14
|
+
import { identifyToken, type IdentifyResult } from './identify.js';
|
|
15
|
+
import type { TokenVariant } from '../datastore/types.js';
|
|
16
|
+
/** The two variants that fourMM actively supports */
|
|
17
|
+
export type SupportedVariant = Extract<TokenVariant, 'standard' | 'anti-sniper-fee'>;
|
|
18
|
+
export declare class UnsupportedTokenError extends Error {
|
|
19
|
+
readonly variant: TokenVariant;
|
|
20
|
+
readonly ca: Address;
|
|
21
|
+
readonly reason: string;
|
|
22
|
+
readonly code: "UNSUPPORTED_TOKEN";
|
|
23
|
+
constructor(variant: TokenVariant, ca: Address, reason: string);
|
|
24
|
+
}
|
|
25
|
+
export declare class TokenNotFoundError extends Error {
|
|
26
|
+
readonly ca: Address;
|
|
27
|
+
readonly code: "TOKEN_NOT_FOUND";
|
|
28
|
+
constructor(ca: Address);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Throw if the token is a variant fourMM does not support OR the API says the
|
|
32
|
+
* token isn't on Four.meme at all.
|
|
33
|
+
*
|
|
34
|
+
* Returns the identification result so callers can avoid a second API call
|
|
35
|
+
* (e.g. `trade buy` can reuse `result.raw` for future slippage estimates).
|
|
36
|
+
*
|
|
37
|
+
* Network failures (source=fallback-network) are NOT treated as hard errors:
|
|
38
|
+
* we default to `standard` and let the downstream RPC layer (Helper3) be
|
|
39
|
+
* the arbiter. This keeps the CLI usable when Four.meme's API is degraded.
|
|
40
|
+
*/
|
|
41
|
+
export declare function assertSupportedToken(ca: Address, options?: Parameters<typeof identifyToken>[1]): Promise<IdentifyResult & {
|
|
42
|
+
variant: SupportedVariant;
|
|
43
|
+
}>;
|
|
44
|
+
//# sourceMappingURL=guards.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guards.d.ts","sourceRoot":"","sources":["../../src/lib/guards.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACnC,OAAO,EAAE,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAA;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAEzD,qDAAqD;AACrD,MAAM,MAAM,gBAAgB,GAAG,OAAO,CAAC,YAAY,EAAE,UAAU,GAAG,iBAAiB,CAAC,CAAA;AAEpF,qBAAa,qBAAsB,SAAQ,KAAK;IAG5C,QAAQ,CAAC,OAAO,EAAE,YAAY;IAC9B,QAAQ,CAAC,EAAE,EAAE,OAAO;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM;IAJzB,QAAQ,CAAC,IAAI,EAAG,mBAAmB,CAAS;gBAEjC,OAAO,EAAE,YAAY,EACrB,EAAE,EAAE,OAAO,EACX,MAAM,EAAE,MAAM;CAK1B;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAE/B,QAAQ,CAAC,EAAE,EAAE,OAAO;IADhC,QAAQ,CAAC,IAAI,EAAG,iBAAiB,CAAS;gBACrB,EAAE,EAAE,OAAO;CAOjC;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,oBAAoB,CACxC,EAAE,EAAE,OAAO,EACX,OAAO,CAAC,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC,GAC5C,OAAO,CAAC,cAAc,GAAG;IAAE,OAAO,EAAE,gBAAgB,CAAA;CAAE,CAAC,CA4BzD"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entry guards for trade / tools / transfer commands.
|
|
3
|
+
*
|
|
4
|
+
* The core invariant: every command that touches trading logic for a specific
|
|
5
|
+
* token MUST call `assertSupportedToken(ca)` before doing any signing or
|
|
6
|
+
* on-chain write. This is how fourMM enforces "TaxToken and X Mode are out of
|
|
7
|
+
* scope" without having to repeat the check inside each command body.
|
|
8
|
+
*
|
|
9
|
+
* Failure mode: `assertSupportedToken` throws `UnsupportedTokenError`, which
|
|
10
|
+
* command handlers can catch and return as a structured `c.error({...})`
|
|
11
|
+
* with a clean error code.
|
|
12
|
+
*/
|
|
13
|
+
import { identifyToken } from './identify.js';
|
|
14
|
+
export class UnsupportedTokenError extends Error {
|
|
15
|
+
variant;
|
|
16
|
+
ca;
|
|
17
|
+
reason;
|
|
18
|
+
code = 'UNSUPPORTED_TOKEN';
|
|
19
|
+
constructor(variant, ca, reason) {
|
|
20
|
+
super(`${variant} ${ca}: ${reason}`);
|
|
21
|
+
this.variant = variant;
|
|
22
|
+
this.ca = ca;
|
|
23
|
+
this.reason = reason;
|
|
24
|
+
this.name = 'UnsupportedTokenError';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export class TokenNotFoundError extends Error {
|
|
28
|
+
ca;
|
|
29
|
+
code = 'TOKEN_NOT_FOUND';
|
|
30
|
+
constructor(ca) {
|
|
31
|
+
super(`Token ${ca} is not registered with Four.meme (API returned not-found). ` +
|
|
32
|
+
`Either the address is wrong or the token predates the API we query.`);
|
|
33
|
+
this.ca = ca;
|
|
34
|
+
this.name = 'TokenNotFoundError';
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Throw if the token is a variant fourMM does not support OR the API says the
|
|
39
|
+
* token isn't on Four.meme at all.
|
|
40
|
+
*
|
|
41
|
+
* Returns the identification result so callers can avoid a second API call
|
|
42
|
+
* (e.g. `trade buy` can reuse `result.raw` for future slippage estimates).
|
|
43
|
+
*
|
|
44
|
+
* Network failures (source=fallback-network) are NOT treated as hard errors:
|
|
45
|
+
* we default to `standard` and let the downstream RPC layer (Helper3) be
|
|
46
|
+
* the arbiter. This keeps the CLI usable when Four.meme's API is degraded.
|
|
47
|
+
*/
|
|
48
|
+
export async function assertSupportedToken(ca, options) {
|
|
49
|
+
const result = await identifyToken(ca, options);
|
|
50
|
+
if (result.source === 'not-found') {
|
|
51
|
+
throw new TokenNotFoundError(ca);
|
|
52
|
+
}
|
|
53
|
+
if (result.variant === 'tax-token') {
|
|
54
|
+
throw new UnsupportedTokenError(result.variant, ca, 'TaxToken is not supported. fourMM refuses to market-make on TaxTokens — ' +
|
|
55
|
+
'each round-trip costs 2× the fee rate (e.g. 10% on a 5% tax token). ' +
|
|
56
|
+
'This is by design.');
|
|
57
|
+
}
|
|
58
|
+
if (result.variant === 'x-mode') {
|
|
59
|
+
throw new UnsupportedTokenError(result.variant, ca, 'X Mode token is not supported. fourMM does not implement the exclusive ' +
|
|
60
|
+
'Binance MPC Wallet purchase path (buyToken(bytes args, uint256 time, bytes signature)).');
|
|
61
|
+
}
|
|
62
|
+
// narrow type by returning a new object with the supported variant
|
|
63
|
+
return { ...result, variant: result.variant };
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=guards.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guards.js","sourceRoot":"","sources":["../../src/lib/guards.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,aAAa,EAAuB,MAAM,eAAe,CAAA;AAMlE,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IAGnC;IACA;IACA;IAJF,IAAI,GAAG,mBAA4B,CAAA;IAC5C,YACW,OAAqB,EACrB,EAAW,EACX,MAAc;QAEvB,KAAK,CAAC,GAAG,OAAO,IAAI,EAAE,KAAK,MAAM,EAAE,CAAC,CAAA;QAJ3B,YAAO,GAAP,OAAO,CAAc;QACrB,OAAE,GAAF,EAAE,CAAS;QACX,WAAM,GAAN,MAAM,CAAQ;QAGvB,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAA;IACrC,CAAC;CACF;AAED,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAEtB;IADZ,IAAI,GAAG,iBAA0B,CAAA;IAC1C,YAAqB,EAAW;QAC9B,KAAK,CACH,SAAS,EAAE,8DAA8D;YACvE,qEAAqE,CACxE,CAAA;QAJkB,OAAE,GAAF,EAAE,CAAS;QAK9B,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAA;IAClC,CAAC;CACF;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,EAAW,EACX,OAA6C;IAE7C,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;IAE/C,IAAI,MAAM,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;QAClC,MAAM,IAAI,kBAAkB,CAAC,EAAE,CAAC,CAAA;IAClC,CAAC;IAED,IAAI,MAAM,CAAC,OAAO,KAAK,WAAW,EAAE,CAAC;QACnC,MAAM,IAAI,qBAAqB,CAC7B,MAAM,CAAC,OAAO,EACd,EAAE,EACF,0EAA0E;YACxE,sEAAsE;YACtE,oBAAoB,CACvB,CAAA;IACH,CAAC;IAED,IAAI,MAAM,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;QAChC,MAAM,IAAI,qBAAqB,CAC7B,MAAM,CAAC,OAAO,EACd,EAAE,EACF,yEAAyE;YACvE,yFAAyF,CAC5F,CAAA;IACH,CAAC;IAED,mEAAmE;IACnE,OAAO,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAA;AAC/C,CAAC"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token variant identification.
|
|
3
|
+
*
|
|
4
|
+
* Four.meme has four variants: standard / anti-sniper-fee / tax-token / x-mode.
|
|
5
|
+
*
|
|
6
|
+
* We detect the variant via Four.meme's public REST API
|
|
7
|
+
* (`https://four.meme/meme-api/v1/private/token/get?address=...`). The endpoint
|
|
8
|
+
* is public despite its "/private/" path segment — it's a read API for token
|
|
9
|
+
* metadata and requires no auth.
|
|
10
|
+
*
|
|
11
|
+
* Why not on-chain? The documented method is to read
|
|
12
|
+
* `TokenManager2._tokenInfos[token].template` and check specific bits
|
|
13
|
+
* (creatorType == 5 → tax-token, bit 0x10000 → x-mode). But the full
|
|
14
|
+
* TokenInfo + TokenInfoEx1 struct layout isn't published, and reverse-
|
|
15
|
+
* engineering struct encoding is fragile. The REST API gives us the same
|
|
16
|
+
* signals with documented field names and typed JSON.
|
|
17
|
+
*
|
|
18
|
+
* Three response states (carried in `IdentifyResult.source`):
|
|
19
|
+
*
|
|
20
|
+
* - `api` → got a real classification from the API
|
|
21
|
+
* - `not-found` → API responded with code != 0 or data === null,
|
|
22
|
+
* meaning the token isn't on Four.meme at all
|
|
23
|
+
* - `fallback-network` → HTTP / timeout / connection error, couldn't tell
|
|
24
|
+
*
|
|
25
|
+
* Commands that need strict guarantees (`trade buy`, `tools volume`) should
|
|
26
|
+
* reject `not-found` explicitly — that's a malformed input, not a valid
|
|
27
|
+
* standard token. `fallback-network` is the degraded case where we couldn't
|
|
28
|
+
* reach the API but the token may still be valid; typically we default to
|
|
29
|
+
* `standard` and let Helper3 be the arbiter.
|
|
30
|
+
*/
|
|
31
|
+
import type { Address } from 'viem';
|
|
32
|
+
import type { TokenVariant } from '../datastore/types.js';
|
|
33
|
+
export type IdentifySource = 'api' | 'not-found' | 'fallback-network';
|
|
34
|
+
export type IdentifyResult = {
|
|
35
|
+
variant: TokenVariant;
|
|
36
|
+
/** Where the verdict came from */
|
|
37
|
+
source: IdentifySource;
|
|
38
|
+
/** Optional raw API payload for debugging / downstream use */
|
|
39
|
+
raw?: FourmemeTokenResponse | undefined;
|
|
40
|
+
};
|
|
41
|
+
/** Shape of the Four.meme token/get API response (fields we care about) */
|
|
42
|
+
export type FourmemeTokenResponse = {
|
|
43
|
+
code: number;
|
|
44
|
+
msg: string;
|
|
45
|
+
data: {
|
|
46
|
+
address: string;
|
|
47
|
+
name: string;
|
|
48
|
+
shortName: string;
|
|
49
|
+
symbol: string;
|
|
50
|
+
totalAmount: string;
|
|
51
|
+
saleAmount: string;
|
|
52
|
+
launchTime: number;
|
|
53
|
+
/** "V3" standard, "V8" X Mode exclusive */
|
|
54
|
+
version: string;
|
|
55
|
+
/** PANCAKE_SWAP | ... */
|
|
56
|
+
dexType: string;
|
|
57
|
+
/** Present only on AntiSniperFee tokens */
|
|
58
|
+
feePlan?: boolean;
|
|
59
|
+
/** Present only on TaxTokens */
|
|
60
|
+
taxInfo?: {
|
|
61
|
+
feeRate: number;
|
|
62
|
+
recipientRate: number;
|
|
63
|
+
burnRate: number;
|
|
64
|
+
divideRate: number;
|
|
65
|
+
liquidityRate: number;
|
|
66
|
+
recipientAddress: string;
|
|
67
|
+
minSharing: number;
|
|
68
|
+
};
|
|
69
|
+
/** Present only when created by an agent wallet */
|
|
70
|
+
aiCreator?: boolean;
|
|
71
|
+
} | null;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Identify a Four.meme token's variant.
|
|
75
|
+
*
|
|
76
|
+
* Never throws: on network or API errors this returns `{ variant: 'standard',
|
|
77
|
+
* source: 'fallback' }`. Callers that want a hard guard should wrap this in
|
|
78
|
+
* `assertSupportedToken` (see guards.ts) which re-checks `source` semantics.
|
|
79
|
+
*/
|
|
80
|
+
export declare function identifyToken(ca: Address, options?: {
|
|
81
|
+
timeoutMs?: number | undefined;
|
|
82
|
+
fetchImpl?: typeof fetch | undefined;
|
|
83
|
+
apiBaseUrl?: string | undefined;
|
|
84
|
+
}): Promise<IdentifyResult>;
|
|
85
|
+
//# sourceMappingURL=identify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identify.d.ts","sourceRoot":"","sources":["../../src/lib/identify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAEnC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAMzD,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,WAAW,GAAG,kBAAkB,CAAA;AAErE,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,EAAE,YAAY,CAAA;IACrB,kCAAkC;IAClC,MAAM,EAAE,cAAc,CAAA;IACtB,8DAA8D;IAC9D,GAAG,CAAC,EAAE,qBAAqB,GAAG,SAAS,CAAA;CACxC,CAAA;AAED,2EAA2E;AAC3E,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE;QACJ,OAAO,EAAE,MAAM,CAAA;QACf,IAAI,EAAE,MAAM,CAAA;QACZ,SAAS,EAAE,MAAM,CAAA;QACjB,MAAM,EAAE,MAAM,CAAA;QACd,WAAW,EAAE,MAAM,CAAA;QACnB,UAAU,EAAE,MAAM,CAAA;QAClB,UAAU,EAAE,MAAM,CAAA;QAClB,2CAA2C;QAC3C,OAAO,EAAE,MAAM,CAAA;QACf,yBAAyB;QACzB,OAAO,EAAE,MAAM,CAAA;QACf,2CAA2C;QAC3C,OAAO,CAAC,EAAE,OAAO,CAAA;QACjB,gCAAgC;QAChC,OAAO,CAAC,EAAE;YACR,OAAO,EAAE,MAAM,CAAA;YACf,aAAa,EAAE,MAAM,CAAA;YACrB,QAAQ,EAAE,MAAM,CAAA;YAChB,UAAU,EAAE,MAAM,CAAA;YAClB,aAAa,EAAE,MAAM,CAAA;YACrB,gBAAgB,EAAE,MAAM,CAAA;YACxB,UAAU,EAAE,MAAM,CAAA;SACnB,CAAA;QACD,mDAAmD;QACnD,SAAS,CAAC,EAAE,OAAO,CAAA;KACpB,GAAG,IAAI,CAAA;CACT,CAAA;AAYD;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,EAAE,EAAE,OAAO,EACX,OAAO,GAAE;IACP,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC9B,SAAS,CAAC,EAAE,OAAO,KAAK,GAAG,SAAS,CAAA;IACpC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC3B,GACL,OAAO,CAAC,cAAc,CAAC,CAwBzB"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token variant identification.
|
|
3
|
+
*
|
|
4
|
+
* Four.meme has four variants: standard / anti-sniper-fee / tax-token / x-mode.
|
|
5
|
+
*
|
|
6
|
+
* We detect the variant via Four.meme's public REST API
|
|
7
|
+
* (`https://four.meme/meme-api/v1/private/token/get?address=...`). The endpoint
|
|
8
|
+
* is public despite its "/private/" path segment — it's a read API for token
|
|
9
|
+
* metadata and requires no auth.
|
|
10
|
+
*
|
|
11
|
+
* Why not on-chain? The documented method is to read
|
|
12
|
+
* `TokenManager2._tokenInfos[token].template` and check specific bits
|
|
13
|
+
* (creatorType == 5 → tax-token, bit 0x10000 → x-mode). But the full
|
|
14
|
+
* TokenInfo + TokenInfoEx1 struct layout isn't published, and reverse-
|
|
15
|
+
* engineering struct encoding is fragile. The REST API gives us the same
|
|
16
|
+
* signals with documented field names and typed JSON.
|
|
17
|
+
*
|
|
18
|
+
* Three response states (carried in `IdentifyResult.source`):
|
|
19
|
+
*
|
|
20
|
+
* - `api` → got a real classification from the API
|
|
21
|
+
* - `not-found` → API responded with code != 0 or data === null,
|
|
22
|
+
* meaning the token isn't on Four.meme at all
|
|
23
|
+
* - `fallback-network` → HTTP / timeout / connection error, couldn't tell
|
|
24
|
+
*
|
|
25
|
+
* Commands that need strict guarantees (`trade buy`, `tools volume`) should
|
|
26
|
+
* reject `not-found` explicitly — that's a malformed input, not a valid
|
|
27
|
+
* standard token. `fallback-network` is the degraded case where we couldn't
|
|
28
|
+
* reach the API but the token may still be valid; typically we default to
|
|
29
|
+
* `standard` and let Helper3 be the arbiter.
|
|
30
|
+
*/
|
|
31
|
+
import { loadConfig } from './config.js';
|
|
32
|
+
// ============================================================
|
|
33
|
+
// Constants
|
|
34
|
+
// ============================================================
|
|
35
|
+
const DEFAULT_TIMEOUT_MS = 8_000;
|
|
36
|
+
// ============================================================
|
|
37
|
+
// Public API
|
|
38
|
+
// ============================================================
|
|
39
|
+
/**
|
|
40
|
+
* Identify a Four.meme token's variant.
|
|
41
|
+
*
|
|
42
|
+
* Never throws: on network or API errors this returns `{ variant: 'standard',
|
|
43
|
+
* source: 'fallback' }`. Callers that want a hard guard should wrap this in
|
|
44
|
+
* `assertSupportedToken` (see guards.ts) which re-checks `source` semantics.
|
|
45
|
+
*/
|
|
46
|
+
export async function identifyToken(ca, options = {}) {
|
|
47
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
48
|
+
const fetchFn = options.fetchImpl ?? globalThis.fetch;
|
|
49
|
+
const apiBase = options.apiBaseUrl ?? loadConfig().fourmemeApiUrl;
|
|
50
|
+
const url = `${apiBase}/v1/private/token/get?address=${ca}`;
|
|
51
|
+
const controller = new AbortController();
|
|
52
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
53
|
+
try {
|
|
54
|
+
const res = await fetchFn(url, { signal: controller.signal });
|
|
55
|
+
if (!res.ok) {
|
|
56
|
+
return { variant: 'standard', source: 'fallback-network' };
|
|
57
|
+
}
|
|
58
|
+
const json = (await res.json());
|
|
59
|
+
if (json.code !== 0 || !json.data) {
|
|
60
|
+
return { variant: 'standard', source: 'not-found', raw: json };
|
|
61
|
+
}
|
|
62
|
+
return { variant: classify(json.data), source: 'api', raw: json };
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return { variant: 'standard', source: 'fallback-network' };
|
|
66
|
+
}
|
|
67
|
+
finally {
|
|
68
|
+
clearTimeout(timer);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// ============================================================
|
|
72
|
+
// Classification rules
|
|
73
|
+
// ============================================================
|
|
74
|
+
function classify(data) {
|
|
75
|
+
// Priority:
|
|
76
|
+
// 1. tax-token (most specific)
|
|
77
|
+
// 2. x-mode (protocol-level exclusivity gate)
|
|
78
|
+
// 3. anti-sniper-fee (dynamic fee)
|
|
79
|
+
// 4. standard (default)
|
|
80
|
+
if (data.taxInfo)
|
|
81
|
+
return 'tax-token';
|
|
82
|
+
if (data.version === 'V8')
|
|
83
|
+
return 'x-mode';
|
|
84
|
+
if (data.feePlan === true)
|
|
85
|
+
return 'anti-sniper-fee';
|
|
86
|
+
return 'standard';
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=identify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identify.js","sourceRoot":"","sources":["../../src/lib/identify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAkDxC,+DAA+D;AAC/D,YAAY;AACZ,+DAA+D;AAE/D,MAAM,kBAAkB,GAAG,KAAK,CAAA;AAEhC,+DAA+D;AAC/D,aAAa;AACb,+DAA+D;AAE/D;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,EAAW,EACX,UAII,EAAE;IAEN,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,kBAAkB,CAAA;IACzD,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,IAAI,UAAU,CAAC,KAAK,CAAA;IACrD,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,IAAI,UAAU,EAAE,CAAC,cAAc,CAAA;IAEjE,MAAM,GAAG,GAAG,GAAG,OAAO,iCAAiC,EAAE,EAAE,CAAA;IAC3D,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAA;IACxC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,SAAS,CAAC,CAAA;IAE7D,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAAA;QAC7D,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAA;QAC5D,CAAC;QACD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA0B,CAAA;QACxD,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAClC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,IAAI,EAAE,CAAA;QAChE,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,CAAA;IACnE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAA;IAC5D,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,KAAK,CAAC,CAAA;IACrB,CAAC;AACH,CAAC;AAED,+DAA+D;AAC/D,uBAAuB;AACvB,+DAA+D;AAE/D,SAAS,QAAQ,CAAC,IAAgD;IAChE,YAAY;IACZ,iCAAiC;IACjC,gDAAgD;IAChD,qCAAqC;IACrC,0BAA0B;IAC1B,IAAI,IAAI,CAAC,OAAO;QAAE,OAAO,WAAW,CAAA;IACpC,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI;QAAE,OAAO,QAAQ,CAAA;IAC1C,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI;QAAE,OAAO,iBAAiB,CAAA;IACnD,OAAO,UAAU,CAAA;AACnB,CAAC"}
|