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,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Four.meme token creation (REST API side).
|
|
3
|
+
*
|
|
4
|
+
* POST /v1/private/token/create → returns { createArg, signature }
|
|
5
|
+
* which are then passed to TokenManager2.createToken() on-chain.
|
|
6
|
+
*/
|
|
7
|
+
export type CreateTokenParams = {
|
|
8
|
+
name: string;
|
|
9
|
+
symbol: string;
|
|
10
|
+
description: string;
|
|
11
|
+
imageUrl: string;
|
|
12
|
+
launchTime?: number | undefined;
|
|
13
|
+
category?: string | undefined;
|
|
14
|
+
twitter?: string | undefined;
|
|
15
|
+
website?: string | undefined;
|
|
16
|
+
telegram?: string | undefined;
|
|
17
|
+
/** BNB amount for preset dev-buy (creator buys at launch). "0" to skip. */
|
|
18
|
+
preSale?: string | undefined;
|
|
19
|
+
};
|
|
20
|
+
export type CreateTokenResult = {
|
|
21
|
+
createArg: string;
|
|
22
|
+
signature: string;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Register a new token with Four.meme's REST API.
|
|
26
|
+
* Returns the createArg + signature needed for the on-chain createToken call.
|
|
27
|
+
*/
|
|
28
|
+
export declare function createTokenOnApi(params: CreateTokenParams, accessToken: string, options?: {
|
|
29
|
+
fetchImpl?: typeof fetch | undefined;
|
|
30
|
+
}): Promise<CreateTokenResult>;
|
|
31
|
+
//# sourceMappingURL=create.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/fourmeme/create.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC/B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7B,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC5B,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC5B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7B,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC7B,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAmDD;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,iBAAiB,EACzB,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,KAAK,GAAG,SAAS,CAAA;CAAO,GACrD,OAAO,CAAC,iBAAiB,CAAC,CAmE5B"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Four.meme token creation (REST API side).
|
|
3
|
+
*
|
|
4
|
+
* POST /v1/private/token/create → returns { createArg, signature }
|
|
5
|
+
* which are then passed to TokenManager2.createToken() on-chain.
|
|
6
|
+
*/
|
|
7
|
+
import { loadConfig } from '../lib/config.js';
|
|
8
|
+
/**
|
|
9
|
+
* Fetch the platform's raisedToken config for BSC/BNB.
|
|
10
|
+
* This gives us the fixed params (b0Amount, totalBAmount, tradeLevel, etc.)
|
|
11
|
+
* that must be included in the create request.
|
|
12
|
+
*/
|
|
13
|
+
async function fetchRaisedTokenConfig(apiBase, fetchFn) {
|
|
14
|
+
try {
|
|
15
|
+
const res = await fetchFn(`${apiBase}/v1/public/config`, {
|
|
16
|
+
method: 'GET',
|
|
17
|
+
headers: { 'Content-Type': 'application/json' },
|
|
18
|
+
});
|
|
19
|
+
if (res.ok) {
|
|
20
|
+
const json = (await res.json());
|
|
21
|
+
if (json.code === 0 && json.data) {
|
|
22
|
+
// data is an array of raisedToken configs
|
|
23
|
+
if (Array.isArray(json.data)) {
|
|
24
|
+
const bnb = json.data.find((t) => t.symbol === 'BNB' && t.networkCode === 'BSC');
|
|
25
|
+
if (bnb)
|
|
26
|
+
return bnb;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
catch { /* use hardcoded defaults */ }
|
|
32
|
+
// Hardcoded defaults from API docs (02-02-2026)
|
|
33
|
+
return {
|
|
34
|
+
symbol: 'BNB',
|
|
35
|
+
nativeSymbol: 'BNB',
|
|
36
|
+
symbolAddress: '0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c',
|
|
37
|
+
deployCost: '0',
|
|
38
|
+
buyFee: '0.01',
|
|
39
|
+
sellFee: '0.01',
|
|
40
|
+
minTradeFee: '0',
|
|
41
|
+
b0Amount: '8',
|
|
42
|
+
totalBAmount: '18',
|
|
43
|
+
totalAmount: '1000000000',
|
|
44
|
+
logoUrl: 'https://static.four.meme/market/68b871b6-96f7-408c-b8d0-388d804b34275092658264263839640.png',
|
|
45
|
+
tradeLevel: ['0.1', '0.5', '1'],
|
|
46
|
+
status: 'PUBLISH',
|
|
47
|
+
buyTokenLink: 'https://pancakeswap.finance/swap',
|
|
48
|
+
reservedNumber: 10,
|
|
49
|
+
saleRate: '0.8',
|
|
50
|
+
networkCode: 'BSC',
|
|
51
|
+
platform: 'MEME',
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Register a new token with Four.meme's REST API.
|
|
56
|
+
* Returns the createArg + signature needed for the on-chain createToken call.
|
|
57
|
+
*/
|
|
58
|
+
export async function createTokenOnApi(params, accessToken, options = {}) {
|
|
59
|
+
const fetchFn = options.fetchImpl ?? globalThis.fetch;
|
|
60
|
+
const config = loadConfig();
|
|
61
|
+
const apiBase = config.fourmemeApiUrl;
|
|
62
|
+
const raisedToken = await fetchRaisedTokenConfig(apiBase, fetchFn);
|
|
63
|
+
const body = {
|
|
64
|
+
name: params.name,
|
|
65
|
+
shortName: params.symbol,
|
|
66
|
+
symbol: 'BNB',
|
|
67
|
+
desc: params.description,
|
|
68
|
+
imgUrl: params.imageUrl,
|
|
69
|
+
launchTime: params.launchTime ?? Date.now(),
|
|
70
|
+
label: params.category ?? 'Meme',
|
|
71
|
+
lpTradingFee: 0.0025,
|
|
72
|
+
...(params.website ? { webUrl: params.website } : {}),
|
|
73
|
+
...(params.twitter ? { twitterUrl: params.twitter } : {}),
|
|
74
|
+
...(params.telegram ? { telegramUrl: params.telegram } : {}),
|
|
75
|
+
preSale: params.preSale ?? '0',
|
|
76
|
+
onlyMPC: false,
|
|
77
|
+
feePlan: false,
|
|
78
|
+
// Fixed platform parameters
|
|
79
|
+
totalSupply: 1000000000,
|
|
80
|
+
raisedAmount: 18,
|
|
81
|
+
saleRate: 0.8,
|
|
82
|
+
reserveRate: 0,
|
|
83
|
+
funGroup: false,
|
|
84
|
+
clickFun: false,
|
|
85
|
+
raisedToken,
|
|
86
|
+
};
|
|
87
|
+
const res = await fetchFn(`${apiBase}/v1/private/token/create`, {
|
|
88
|
+
method: 'POST',
|
|
89
|
+
headers: {
|
|
90
|
+
'Content-Type': 'application/json',
|
|
91
|
+
'meme-web-access': accessToken,
|
|
92
|
+
},
|
|
93
|
+
body: JSON.stringify(body),
|
|
94
|
+
});
|
|
95
|
+
if (!res.ok) {
|
|
96
|
+
const text = await res.text().catch(() => '');
|
|
97
|
+
throw new Error(`Four.meme token/create failed: HTTP ${res.status} ${text}`);
|
|
98
|
+
}
|
|
99
|
+
const json = (await res.json());
|
|
100
|
+
if (json.code !== 0 || !json.data) {
|
|
101
|
+
throw new Error(`Four.meme token/create error: ${json.msg || JSON.stringify(json)}`);
|
|
102
|
+
}
|
|
103
|
+
if (!json.data.createArg || !json.data.signature) {
|
|
104
|
+
throw new Error('Four.meme token/create: missing createArg or signature in response');
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
createArg: json.data.createArg,
|
|
108
|
+
signature: json.data.signature,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=create.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/fourmeme/create.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Four.meme image upload.
|
|
3
|
+
*
|
|
4
|
+
* POST /v1/private/token/upload with multipart form data.
|
|
5
|
+
* Returns the uploaded image URL for use in token creation.
|
|
6
|
+
*/
|
|
7
|
+
export type UploadResult = {
|
|
8
|
+
imageUrl: string;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Upload a token logo image to Four.meme.
|
|
12
|
+
*/
|
|
13
|
+
export declare function uploadTokenImage(imagePath: string, accessToken: string, options?: {
|
|
14
|
+
fetchImpl?: typeof fetch | undefined;
|
|
15
|
+
}): Promise<UploadResult>;
|
|
16
|
+
//# sourceMappingURL=upload.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/fourmeme/upload.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,KAAK,GAAG,SAAS,CAAA;CAAO,GACrD,OAAO,CAAC,YAAY,CAAC,CA8CvB"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Four.meme image upload.
|
|
3
|
+
*
|
|
4
|
+
* POST /v1/private/token/upload with multipart form data.
|
|
5
|
+
* Returns the uploaded image URL for use in token creation.
|
|
6
|
+
*/
|
|
7
|
+
import fs from 'node:fs';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
import { loadConfig } from '../lib/config.js';
|
|
10
|
+
/**
|
|
11
|
+
* Upload a token logo image to Four.meme.
|
|
12
|
+
*/
|
|
13
|
+
export async function uploadTokenImage(imagePath, accessToken, options = {}) {
|
|
14
|
+
const fetchFn = options.fetchImpl ?? globalThis.fetch;
|
|
15
|
+
const config = loadConfig();
|
|
16
|
+
const apiBase = config.fourmemeApiUrl;
|
|
17
|
+
if (!fs.existsSync(imagePath)) {
|
|
18
|
+
throw new Error(`Image file not found: ${imagePath}`);
|
|
19
|
+
}
|
|
20
|
+
const fileBuffer = fs.readFileSync(imagePath);
|
|
21
|
+
const fileName = path.basename(imagePath);
|
|
22
|
+
// Detect MIME type from extension so the server accepts the upload
|
|
23
|
+
const mimeTypes = {
|
|
24
|
+
'.png': 'image/png',
|
|
25
|
+
'.jpg': 'image/jpeg',
|
|
26
|
+
'.jpeg': 'image/jpeg',
|
|
27
|
+
'.gif': 'image/gif',
|
|
28
|
+
'.webp': 'image/webp',
|
|
29
|
+
'.svg': 'image/svg+xml',
|
|
30
|
+
};
|
|
31
|
+
const ext = path.extname(imagePath).toLowerCase();
|
|
32
|
+
const mimeType = mimeTypes[ext] ?? 'application/octet-stream';
|
|
33
|
+
const blob = new Blob([fileBuffer], { type: mimeType });
|
|
34
|
+
const formData = new FormData();
|
|
35
|
+
formData.append('file', blob, fileName);
|
|
36
|
+
const res = await fetchFn(`${apiBase}/v1/private/token/upload`, {
|
|
37
|
+
method: 'POST',
|
|
38
|
+
headers: {
|
|
39
|
+
'meme-web-access': accessToken,
|
|
40
|
+
},
|
|
41
|
+
body: formData,
|
|
42
|
+
});
|
|
43
|
+
if (!res.ok) {
|
|
44
|
+
throw new Error(`Four.meme upload failed: HTTP ${res.status}`);
|
|
45
|
+
}
|
|
46
|
+
const json = (await res.json());
|
|
47
|
+
if (json.code !== 0 || !json.data) {
|
|
48
|
+
throw new Error(`Four.meme upload error: ${JSON.stringify(json)}`);
|
|
49
|
+
}
|
|
50
|
+
return { imageUrl: json.data };
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=upload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../../src/fourmeme/upload.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAM7C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,SAAiB,EACjB,WAAmB,EACnB,UAAoD,EAAE;IAEtD,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,IAAI,UAAU,CAAC,KAAK,CAAA;IACrD,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;IAC3B,MAAM,OAAO,GAAG,MAAM,CAAC,cAAc,CAAA;IAErC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,yBAAyB,SAAS,EAAE,CAAC,CAAA;IACvD,CAAC;IAED,MAAM,UAAU,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,CAAA;IAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAA;IAEzC,mEAAmE;IACnE,MAAM,SAAS,GAA2B;QACxC,MAAM,EAAE,WAAW;QACnB,MAAM,EAAE,YAAY;QACpB,OAAO,EAAE,YAAY;QACrB,MAAM,EAAE,WAAW;QACnB,OAAO,EAAE,YAAY;QACrB,MAAM,EAAE,eAAe;KACxB,CAAA;IACD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAA;IACjD,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,0BAA0B,CAAA;IAC7D,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,UAAU,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAA;IAEvD,MAAM,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAA;IAC/B,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAA;IAEvC,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,OAAO,0BAA0B,EAAE;QAC9D,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,iBAAiB,EAAE,WAAW;SAC/B;QACD,IAAI,EAAE,QAAQ;KACf,CAAC,CAAA;IAEF,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,iCAAiC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAA;IAChE,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAmC,CAAA;IACjE,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,2BAA2B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACpE,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,CAAA;AAChC,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BSC bundle submission via BlockRazor / Flashbots-compatible API.
|
|
3
|
+
*
|
|
4
|
+
* Bundles multiple signed transactions into a single atomic submission.
|
|
5
|
+
* All txs in a bundle execute in the same block, or none do.
|
|
6
|
+
*
|
|
7
|
+
* Requires an RPC that supports `eth_sendBundle` (e.g. BlockRazor).
|
|
8
|
+
*/
|
|
9
|
+
import { type Address, type Hex, type PublicClient } from 'viem';
|
|
10
|
+
import { type PrivateKeyAccount } from 'viem/accounts';
|
|
11
|
+
export type BundleTx = {
|
|
12
|
+
/** Signed raw transaction hex */
|
|
13
|
+
signedTx: Hex;
|
|
14
|
+
};
|
|
15
|
+
export type BundleResult = {
|
|
16
|
+
success: boolean;
|
|
17
|
+
bundleHash?: string | undefined;
|
|
18
|
+
error?: string | undefined;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Sign a transaction offline without broadcasting.
|
|
22
|
+
* Returns the raw signed tx hex for bundle inclusion.
|
|
23
|
+
*/
|
|
24
|
+
export declare function signRawTx(account: PrivateKeyAccount, params: {
|
|
25
|
+
to: Address;
|
|
26
|
+
data: Hex;
|
|
27
|
+
value: bigint;
|
|
28
|
+
nonce: number;
|
|
29
|
+
gasLimit: bigint;
|
|
30
|
+
gasPrice: bigint;
|
|
31
|
+
chainId?: number;
|
|
32
|
+
}): Promise<Hex>;
|
|
33
|
+
/**
|
|
34
|
+
* Submit a bundle of signed transactions to the RPC's eth_sendBundle endpoint.
|
|
35
|
+
*
|
|
36
|
+
* @param signedTxs Array of signed raw tx hex strings
|
|
37
|
+
* @param targetBlock Target block number (bundle valid for this block only)
|
|
38
|
+
* @param rpcUrl RPC endpoint that supports eth_sendBundle (defaults to config.rpcUrl)
|
|
39
|
+
*/
|
|
40
|
+
export declare function sendBundle(signedTxs: Hex[], targetBlock: bigint, rpcUrl?: string): Promise<BundleResult>;
|
|
41
|
+
/**
|
|
42
|
+
* Convenience: sign multiple buy txs from different wallets and submit as bundle.
|
|
43
|
+
*/
|
|
44
|
+
export declare function sendBundledBuys(client: PublicClient, accounts: PrivateKeyAccount[], params: {
|
|
45
|
+
tokenManager: Address;
|
|
46
|
+
token: Address;
|
|
47
|
+
bnbPerWallet: bigint;
|
|
48
|
+
minAmounts: bigint[];
|
|
49
|
+
buyFunctionData: Hex[];
|
|
50
|
+
}): Promise<BundleResult>;
|
|
51
|
+
//# sourceMappingURL=bundle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["../../src/lib/bundle.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,GAAG,EACR,KAAK,YAAY,EAIlB,MAAM,MAAM,CAAA;AACb,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAItD,MAAM,MAAM,QAAQ,GAAG;IACrB,iCAAiC;IACjC,QAAQ,EAAE,GAAG,CAAA;CACd,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,OAAO,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC/B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC3B,CAAA;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAC7B,OAAO,EAAE,iBAAiB,EAC1B,MAAM,EAAE;IACN,EAAE,EAAE,OAAO,CAAA;IACX,IAAI,EAAE,GAAG,CAAA;IACT,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,GACA,OAAO,CAAC,GAAG,CAAC,CAwBd;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC9B,SAAS,EAAE,GAAG,EAAE,EAChB,WAAW,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,YAAY,CAAC,CA+BvB;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,YAAY,EACpB,QAAQ,EAAE,iBAAiB,EAAE,EAC7B,MAAM,EAAE;IACN,YAAY,EAAE,OAAO,CAAA;IACrB,KAAK,EAAE,OAAO,CAAA;IACd,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,eAAe,EAAE,GAAG,EAAE,CAAA;CACvB,GACA,OAAO,CAAC,YAAY,CAAC,CAuBvB"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BSC bundle submission via BlockRazor / Flashbots-compatible API.
|
|
3
|
+
*
|
|
4
|
+
* Bundles multiple signed transactions into a single atomic submission.
|
|
5
|
+
* All txs in a bundle execute in the same block, or none do.
|
|
6
|
+
*
|
|
7
|
+
* Requires an RPC that supports `eth_sendBundle` (e.g. BlockRazor).
|
|
8
|
+
*/
|
|
9
|
+
import { encodeFunctionData, serializeTransaction, parseEther, } from 'viem';
|
|
10
|
+
import {} from 'viem/accounts';
|
|
11
|
+
import { bsc } from 'viem/chains';
|
|
12
|
+
import { loadConfig } from './config.js';
|
|
13
|
+
/**
|
|
14
|
+
* Sign a transaction offline without broadcasting.
|
|
15
|
+
* Returns the raw signed tx hex for bundle inclusion.
|
|
16
|
+
*/
|
|
17
|
+
export async function signRawTx(account, params) {
|
|
18
|
+
const serialized = serializeTransaction({
|
|
19
|
+
to: params.to,
|
|
20
|
+
data: params.data,
|
|
21
|
+
value: params.value,
|
|
22
|
+
nonce: params.nonce,
|
|
23
|
+
gas: params.gasLimit,
|
|
24
|
+
gasPrice: params.gasPrice,
|
|
25
|
+
chainId: params.chainId ?? bsc.id,
|
|
26
|
+
type: 'legacy',
|
|
27
|
+
});
|
|
28
|
+
const signature = await account.signTransaction({
|
|
29
|
+
to: params.to,
|
|
30
|
+
data: params.data,
|
|
31
|
+
value: params.value,
|
|
32
|
+
nonce: params.nonce,
|
|
33
|
+
gas: params.gasLimit,
|
|
34
|
+
gasPrice: params.gasPrice,
|
|
35
|
+
chainId: params.chainId ?? bsc.id,
|
|
36
|
+
type: 'legacy',
|
|
37
|
+
});
|
|
38
|
+
return signature;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Submit a bundle of signed transactions to the RPC's eth_sendBundle endpoint.
|
|
42
|
+
*
|
|
43
|
+
* @param signedTxs Array of signed raw tx hex strings
|
|
44
|
+
* @param targetBlock Target block number (bundle valid for this block only)
|
|
45
|
+
* @param rpcUrl RPC endpoint that supports eth_sendBundle (defaults to config.rpcUrl)
|
|
46
|
+
*/
|
|
47
|
+
export async function sendBundle(signedTxs, targetBlock, rpcUrl) {
|
|
48
|
+
const config = loadConfig();
|
|
49
|
+
const url = rpcUrl ?? config.rpcUrl;
|
|
50
|
+
const res = await fetch(url, {
|
|
51
|
+
method: 'POST',
|
|
52
|
+
headers: { 'Content-Type': 'application/json' },
|
|
53
|
+
body: JSON.stringify({
|
|
54
|
+
jsonrpc: '2.0',
|
|
55
|
+
id: 1,
|
|
56
|
+
method: 'eth_sendBundle',
|
|
57
|
+
params: [{
|
|
58
|
+
txs: signedTxs,
|
|
59
|
+
blockNumber: `0x${targetBlock.toString(16)}`,
|
|
60
|
+
}],
|
|
61
|
+
}),
|
|
62
|
+
});
|
|
63
|
+
const json = (await res.json());
|
|
64
|
+
if (json.error) {
|
|
65
|
+
return { success: false, error: json.error.message };
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
success: true,
|
|
69
|
+
bundleHash: json.result?.bundleHash,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Convenience: sign multiple buy txs from different wallets and submit as bundle.
|
|
74
|
+
*/
|
|
75
|
+
export async function sendBundledBuys(client, accounts, params) {
|
|
76
|
+
const gasPrice = await client.getGasPrice();
|
|
77
|
+
const currentBlock = await client.getBlockNumber();
|
|
78
|
+
const targetBlock = currentBlock + 2n; // target 2 blocks ahead
|
|
79
|
+
const signedTxs = [];
|
|
80
|
+
for (let i = 0; i < accounts.length; i++) {
|
|
81
|
+
const account = accounts[i];
|
|
82
|
+
const nonce = await client.getTransactionCount({ address: account.address });
|
|
83
|
+
const signed = await signRawTx(account, {
|
|
84
|
+
to: params.tokenManager,
|
|
85
|
+
data: params.buyFunctionData[i],
|
|
86
|
+
value: params.bnbPerWallet,
|
|
87
|
+
nonce,
|
|
88
|
+
gasLimit: 300000n,
|
|
89
|
+
gasPrice,
|
|
90
|
+
});
|
|
91
|
+
signedTxs.push(signed);
|
|
92
|
+
}
|
|
93
|
+
return sendBundle(signedTxs, targetBlock);
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=bundle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundle.js","sourceRoot":"","sources":["../../src/lib/bundle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fourMM configuration management.
|
|
3
|
+
*
|
|
4
|
+
* Stored at ~/.fourmm/config.json. Supports env var overrides for RPC and
|
|
5
|
+
* sensitive values (so users don't have to write secrets to disk).
|
|
6
|
+
*
|
|
7
|
+
* Precedence: env var > config file > default.
|
|
8
|
+
*
|
|
9
|
+
* Paths are exposed as functions (not constants) so that tests can redirect
|
|
10
|
+
* HOME via `process.env.HOME = tmpDir` before each test — `os.homedir()`
|
|
11
|
+
* re-reads the HOME env var on each call, so lazy functions see the change.
|
|
12
|
+
*/
|
|
13
|
+
export type Network = 'bsc' | 'bsc-testnet';
|
|
14
|
+
export type CliConfig = {
|
|
15
|
+
/** BSC RPC endpoint URL */
|
|
16
|
+
rpcUrl: string;
|
|
17
|
+
/** Fallback RPC endpoints (tried on primary failure) */
|
|
18
|
+
fallbackRpcUrls: string[];
|
|
19
|
+
/** Network selection */
|
|
20
|
+
network: Network;
|
|
21
|
+
/** Default slippage in basis points (100 = 1%) */
|
|
22
|
+
defaultSlippageBps: number;
|
|
23
|
+
/** Default gas price multiplier applied to RPC estimate (1.0 = no multiplier) */
|
|
24
|
+
gasPriceMultiplier: number;
|
|
25
|
+
/** Default priority fee in gwei */
|
|
26
|
+
defaultPriorityFeeGwei: number;
|
|
27
|
+
/** Output format default */
|
|
28
|
+
outputFormat: 'toon' | 'json' | 'yaml' | 'md' | 'jsonl';
|
|
29
|
+
/** BSCScan API key (optional, for verification workflows) */
|
|
30
|
+
bscscanApiKey: string;
|
|
31
|
+
/** GeckoTerminal base URL (override for rate limit bypass) */
|
|
32
|
+
geckoTerminalUrl: string;
|
|
33
|
+
/** Four.meme REST API base URL (used for token variant identification) */
|
|
34
|
+
fourmemeApiUrl: string;
|
|
35
|
+
};
|
|
36
|
+
/** Root directory for fourMM state */
|
|
37
|
+
export declare function fourmDir(): string;
|
|
38
|
+
/** Config file location */
|
|
39
|
+
export declare function configFile(): string;
|
|
40
|
+
/** Encrypted wallet groups store directory */
|
|
41
|
+
export declare function walletsDir(): string;
|
|
42
|
+
/** DataStore root (token info, holdings, balances, transactions) */
|
|
43
|
+
export declare function dataDir(): string;
|
|
44
|
+
/** Logs directory */
|
|
45
|
+
export declare function logsDir(): string;
|
|
46
|
+
/** Ensure ~/.fourmm and subdirs exist with tight permissions */
|
|
47
|
+
export declare function ensureFourmmDirs(): void;
|
|
48
|
+
/** Load config from ~/.fourmm/config.json (or defaults if absent) */
|
|
49
|
+
export declare function loadConfig(): CliConfig;
|
|
50
|
+
/** Save config to disk */
|
|
51
|
+
export declare function saveConfig(config: CliConfig): void;
|
|
52
|
+
/** Initialize config (write defaults + any overrides) */
|
|
53
|
+
export declare function initConfig(overrides?: Partial<CliConfig>): CliConfig;
|
|
54
|
+
/** Get a single config value by key */
|
|
55
|
+
export declare function getConfigValue(key: string): unknown;
|
|
56
|
+
/** Set a single config value with type coercion */
|
|
57
|
+
export declare function setConfigValue(key: string, rawValue: string): void;
|
|
58
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAUH,MAAM,MAAM,OAAO,GAAG,KAAK,GAAG,aAAa,CAAA;AAE3C,MAAM,MAAM,SAAS,GAAG;IACtB,2BAA2B;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,wDAAwD;IACxD,eAAe,EAAE,MAAM,EAAE,CAAA;IACzB,wBAAwB;IACxB,OAAO,EAAE,OAAO,CAAA;IAChB,kDAAkD;IAClD,kBAAkB,EAAE,MAAM,CAAA;IAC1B,iFAAiF;IACjF,kBAAkB,EAAE,MAAM,CAAA;IAC1B,mCAAmC;IACnC,sBAAsB,EAAE,MAAM,CAAA;IAC9B,4BAA4B;IAC5B,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,OAAO,CAAA;IACvD,6DAA6D;IAC7D,aAAa,EAAE,MAAM,CAAA;IACrB,8DAA8D;IAC9D,gBAAgB,EAAE,MAAM,CAAA;IACxB,0EAA0E;IAC1E,cAAc,EAAE,MAAM,CAAA;CACvB,CAAA;AA4BD,sCAAsC;AACtC,wBAAgB,QAAQ,IAAI,MAAM,CAEjC;AAED,2BAA2B;AAC3B,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,8CAA8C;AAC9C,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,oEAAoE;AACpE,wBAAgB,OAAO,IAAI,MAAM,CAEhC;AAED,qBAAqB;AACrB,wBAAgB,OAAO,IAAI,MAAM,CAEhC;AAED,gEAAgE;AAChE,wBAAgB,gBAAgB,IAAI,IAAI,CAMvC;AAoBD,qEAAqE;AACrE,wBAAgB,UAAU,IAAI,SAAS,CAgBtC;AAED,0BAA0B;AAC1B,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAMlD;AAED,yDAAyD;AACzD,wBAAgB,UAAU,CAAC,SAAS,GAAE,OAAO,CAAC,SAAS,CAAM,GAAG,SAAS,CAKxE;AAmBD,uCAAuC;AACvC,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAInD;AAED,mDAAmD;AACnD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAWlE"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fourMM configuration management.
|
|
3
|
+
*
|
|
4
|
+
* Stored at ~/.fourmm/config.json. Supports env var overrides for RPC and
|
|
5
|
+
* sensitive values (so users don't have to write secrets to disk).
|
|
6
|
+
*
|
|
7
|
+
* Precedence: env var > config file > default.
|
|
8
|
+
*
|
|
9
|
+
* Paths are exposed as functions (not constants) so that tests can redirect
|
|
10
|
+
* HOME via `process.env.HOME = tmpDir` before each test — `os.homedir()`
|
|
11
|
+
* re-reads the HOME env var on each call, so lazy functions see the change.
|
|
12
|
+
*/
|
|
13
|
+
import fs from 'node:fs';
|
|
14
|
+
import os from 'node:os';
|
|
15
|
+
import path from 'node:path';
|
|
16
|
+
// ============================================================
|
|
17
|
+
// Defaults
|
|
18
|
+
// ============================================================
|
|
19
|
+
const DEFAULT_CONFIG = {
|
|
20
|
+
// bsc.publicnode.com tends to be faster and more stable than Binance's own
|
|
21
|
+
// hosted nodes during our Week-1 testing. Users can override via config or
|
|
22
|
+
// BSC_RPC_URL env var.
|
|
23
|
+
rpcUrl: 'https://meme.bsc.blockrazor.xyz',
|
|
24
|
+
fallbackRpcUrls: [
|
|
25
|
+
'https://bsc.publicnode.com',
|
|
26
|
+
],
|
|
27
|
+
network: 'bsc',
|
|
28
|
+
defaultSlippageBps: 300,
|
|
29
|
+
gasPriceMultiplier: 1.1,
|
|
30
|
+
defaultPriorityFeeGwei: 1,
|
|
31
|
+
outputFormat: 'toon',
|
|
32
|
+
bscscanApiKey: '',
|
|
33
|
+
geckoTerminalUrl: 'https://api.geckoterminal.com/api/v2',
|
|
34
|
+
fourmemeApiUrl: 'https://four.meme/meme-api',
|
|
35
|
+
};
|
|
36
|
+
// ============================================================
|
|
37
|
+
// Paths (lazy — respect HOME env var changes)
|
|
38
|
+
// ============================================================
|
|
39
|
+
/** Root directory for fourMM state */
|
|
40
|
+
export function fourmDir() {
|
|
41
|
+
return path.join(os.homedir(), '.fourmm');
|
|
42
|
+
}
|
|
43
|
+
/** Config file location */
|
|
44
|
+
export function configFile() {
|
|
45
|
+
return path.join(fourmDir(), 'config.json');
|
|
46
|
+
}
|
|
47
|
+
/** Encrypted wallet groups store directory */
|
|
48
|
+
export function walletsDir() {
|
|
49
|
+
return path.join(fourmDir(), 'wallets');
|
|
50
|
+
}
|
|
51
|
+
/** DataStore root (token info, holdings, balances, transactions) */
|
|
52
|
+
export function dataDir() {
|
|
53
|
+
return path.join(fourmDir(), 'data');
|
|
54
|
+
}
|
|
55
|
+
/** Logs directory */
|
|
56
|
+
export function logsDir() {
|
|
57
|
+
return path.join(fourmDir(), 'logs');
|
|
58
|
+
}
|
|
59
|
+
/** Ensure ~/.fourmm and subdirs exist with tight permissions */
|
|
60
|
+
export function ensureFourmmDirs() {
|
|
61
|
+
for (const dir of [fourmDir(), walletsDir(), dataDir(), logsDir()]) {
|
|
62
|
+
if (!fs.existsSync(dir)) {
|
|
63
|
+
fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// ============================================================
|
|
68
|
+
// Load / Save
|
|
69
|
+
// ============================================================
|
|
70
|
+
/** Apply environment variable overrides */
|
|
71
|
+
function applyEnvOverrides(config) {
|
|
72
|
+
const envRpc = process.env.BSC_RPC_URL;
|
|
73
|
+
const envBscscan = process.env.BSCSCAN_API_KEY;
|
|
74
|
+
const envGecko = process.env.GECKOTERMINAL_URL;
|
|
75
|
+
return {
|
|
76
|
+
...config,
|
|
77
|
+
...(envRpc ? { rpcUrl: envRpc } : {}),
|
|
78
|
+
...(envBscscan ? { bscscanApiKey: envBscscan } : {}),
|
|
79
|
+
...(envGecko ? { geckoTerminalUrl: envGecko } : {}),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/** Load config from ~/.fourmm/config.json (or defaults if absent) */
|
|
83
|
+
export function loadConfig() {
|
|
84
|
+
ensureFourmmDirs();
|
|
85
|
+
const file = configFile();
|
|
86
|
+
if (!fs.existsSync(file)) {
|
|
87
|
+
return applyEnvOverrides({ ...DEFAULT_CONFIG });
|
|
88
|
+
}
|
|
89
|
+
try {
|
|
90
|
+
const raw = fs.readFileSync(file, 'utf-8');
|
|
91
|
+
const fileConfig = JSON.parse(raw);
|
|
92
|
+
const merged = { ...DEFAULT_CONFIG, ...fileConfig };
|
|
93
|
+
return applyEnvOverrides(merged);
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return applyEnvOverrides({ ...DEFAULT_CONFIG });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/** Save config to disk */
|
|
100
|
+
export function saveConfig(config) {
|
|
101
|
+
ensureFourmmDirs();
|
|
102
|
+
fs.writeFileSync(configFile(), JSON.stringify(config, null, 2), {
|
|
103
|
+
encoding: 'utf-8',
|
|
104
|
+
mode: 0o600,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
/** Initialize config (write defaults + any overrides) */
|
|
108
|
+
export function initConfig(overrides = {}) {
|
|
109
|
+
ensureFourmmDirs();
|
|
110
|
+
const config = { ...DEFAULT_CONFIG, ...overrides };
|
|
111
|
+
saveConfig(config);
|
|
112
|
+
return config;
|
|
113
|
+
}
|
|
114
|
+
// ============================================================
|
|
115
|
+
// Key / Value helpers
|
|
116
|
+
// ============================================================
|
|
117
|
+
const VALID_KEYS = new Set([
|
|
118
|
+
'rpcUrl',
|
|
119
|
+
'fallbackRpcUrls',
|
|
120
|
+
'network',
|
|
121
|
+
'defaultSlippageBps',
|
|
122
|
+
'gasPriceMultiplier',
|
|
123
|
+
'defaultPriorityFeeGwei',
|
|
124
|
+
'outputFormat',
|
|
125
|
+
'bscscanApiKey',
|
|
126
|
+
'geckoTerminalUrl',
|
|
127
|
+
'fourmemeApiUrl',
|
|
128
|
+
]);
|
|
129
|
+
/** Get a single config value by key */
|
|
130
|
+
export function getConfigValue(key) {
|
|
131
|
+
const config = loadConfig();
|
|
132
|
+
if (!VALID_KEYS.has(key))
|
|
133
|
+
return undefined;
|
|
134
|
+
return config[key];
|
|
135
|
+
}
|
|
136
|
+
/** Set a single config value with type coercion */
|
|
137
|
+
export function setConfigValue(key, rawValue) {
|
|
138
|
+
if (!VALID_KEYS.has(key)) {
|
|
139
|
+
throw new Error(`Unknown config key "${key}". Valid keys: ${[...VALID_KEYS].join(', ')}`);
|
|
140
|
+
}
|
|
141
|
+
const config = loadConfig();
|
|
142
|
+
const coerced = coerceValue(key, rawValue);
|
|
143
|
+
config[key] = coerced;
|
|
144
|
+
saveConfig(config);
|
|
145
|
+
}
|
|
146
|
+
function coerceValue(key, raw) {
|
|
147
|
+
// Number fields
|
|
148
|
+
if (key === 'defaultSlippageBps' || key === 'defaultPriorityFeeGwei') {
|
|
149
|
+
const n = Number.parseInt(raw, 10);
|
|
150
|
+
if (Number.isNaN(n) || n < 0) {
|
|
151
|
+
throw new Error(`${key} must be a non-negative integer, got "${raw}"`);
|
|
152
|
+
}
|
|
153
|
+
return n;
|
|
154
|
+
}
|
|
155
|
+
if (key === 'gasPriceMultiplier') {
|
|
156
|
+
const n = Number.parseFloat(raw);
|
|
157
|
+
if (Number.isNaN(n) || n <= 0) {
|
|
158
|
+
throw new Error(`${key} must be a positive number, got "${raw}"`);
|
|
159
|
+
}
|
|
160
|
+
return n;
|
|
161
|
+
}
|
|
162
|
+
// Enum fields
|
|
163
|
+
if (key === 'network') {
|
|
164
|
+
if (raw !== 'bsc' && raw !== 'bsc-testnet') {
|
|
165
|
+
throw new Error(`network must be "bsc" or "bsc-testnet", got "${raw}"`);
|
|
166
|
+
}
|
|
167
|
+
return raw;
|
|
168
|
+
}
|
|
169
|
+
if (key === 'outputFormat') {
|
|
170
|
+
const valid = ['toon', 'json', 'yaml', 'md', 'jsonl'];
|
|
171
|
+
if (!valid.includes(raw)) {
|
|
172
|
+
throw new Error(`outputFormat must be one of ${valid.join(', ')}, got "${raw}"`);
|
|
173
|
+
}
|
|
174
|
+
return raw;
|
|
175
|
+
}
|
|
176
|
+
// Array fields
|
|
177
|
+
if (key === 'fallbackRpcUrls') {
|
|
178
|
+
return raw.split(',').map((s) => s.trim()).filter(Boolean);
|
|
179
|
+
}
|
|
180
|
+
// String fields
|
|
181
|
+
return raw;
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
|