@four-meme/four-meme-ai 1.0.6 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,21 +1,34 @@
1
1
  # Create Token Scripts (Four.meme)
2
2
 
3
- ## One-shot (create-token-instant)
3
+ **Recommended:** Use `fourmeme create-instant` for one-shot token creation (API + on-chain in one command). Use the step-by-step flow only when you need to inspect or modify the API output before submitting on-chain.
4
+
5
+ ## One-shot (create-instant) — recommended
4
6
 
5
7
  **create-token-instant.ts** runs API create + on-chain submit in one command. Same args as create-token-api; on success submits createToken and outputs `txHash`.
6
8
 
9
+ - All options as `--key=value`; no positionals.
10
+ - **Required**: `--image=`, `--name=`, `--short-name=`, `--desc=`, `--label=`.
11
+ - **Optional**: `--web-url=`, `--twitter-url=`, `--telegram-url=` (only sent when non-empty); `--pre-sale=0` (**presale in ether units**, e.g. `0.001` for 0.001 BNB, not wei); `--fee-plan=false`, `--tax-options=<path>`; `--value=<wei>` (default to be auto calculated, override BNB value sent; otherwise API output `creationFeeWei` is used).
12
+ - **Tax token**: `--tax-options=tax.json` or `--tax-token` with `--tax-fee-rate=5` `--tax-burn-rate=0` `--tax-divide-rate=0` `--tax-liquidity-rate=100` `--tax-recipient-rate=0` `--tax-recipient-address=` `--tax-min-sharing=100000` (burn+divide+liquidity+recipient=100).
13
+ - **Label** (exactly one): `Meme` | `AI` | `Defi` | `Games` | `Infra` | `De-Sci` | `Social` | `Depin` | `Charity` | `Others`.
14
+ - **Env**: `PRIVATE_KEY`; RPC via `BSC_RPC_URL`.
15
+ - **Flow**: nonce → login → upload image → GET public config → POST create → submit `TokenManager2.createToken` on BSC.
16
+ - **Output**: JSON `{ "txHash" }`.
17
+
7
18
  ```bash
8
- # Same as create-token-api, all --key=value
9
- npx tsx .../create-token-instant.ts --image=./logo.png --name=MyToken --short-name=MTK --desc="My desc" --label=AI
10
- # Or via CLI
19
+ # Via CLI (recommended)
11
20
  fourmeme create-instant --image=./logo.png --name=MyToken --short-name=MTK --desc="My desc" --label=AI
12
- ```
13
21
 
14
- Optional `--value=wei` overrides the value; otherwise API output `creationFeeWei` is used. Env: `PRIVATE_KEY`, optional `BSC_RPC_URL`.
22
+ # With presale (BNB, ether units)
23
+ fourmeme create-instant --image=./logo.png --name=MyToken --short-name=MTK --desc="My desc" --label=AI --pre-sale=0.001
24
+
25
+ # Tax token
26
+ fourmeme create-instant --image=./logo.png --name=TaxToken --short-name=TAX --desc="Tax" --label=Meme --tax-options=tax.json
27
+ ```
15
28
 
16
29
  ---
17
30
 
18
- ## Step-by-step flow
31
+ ## Step-by-step flow (create-api → create-chain)
19
32
 
20
33
  1. **get-public-config.ts** (optional)
21
34
  Fetches `raisedToken` from `https://four.meme/meme-api/v1/public/config`. Use when building the create body manually.
@@ -54,6 +67,13 @@ Optional `--value=wei` overrides the value; otherwise API output `creationFeeWei
54
67
  - `fee_rate` from TokenManager2 `_tradingFeeRate()` (basis points).
55
68
  - If the contract enforces a minimum fee per trade, use `max(computed trading_fee, minimum_fee)`.
56
69
 
70
+ ## Example (instant, recommended)
71
+
72
+ ```bash
73
+ export PRIVATE_KEY=your_hex_private_key
74
+ fourmeme create-instant --image=./logo.png --name=MyToken --short-name=MTK --desc="My desc" --label=AI
75
+ ```
76
+
57
77
  ## Example (piped)
58
78
 
59
79
  ```bash
@@ -4,19 +4,21 @@ Base: `https://four.meme/meme-api/v1`. Requests need `Accept: application/json`;
4
4
 
5
5
  ## 1. Token list (filter / paginate)
6
6
 
7
- **GET** `/private/token/query`
8
-
9
- | Parameter | Description | Example |
10
- |-----------|-------------|---------|
11
- | orderBy | Sort order | Hot, Time, ... |
12
- | tokenName | Filter by token name | Empty or name |
13
- | symbol | Filter by symbol | Empty or symbol |
14
- | labels | Filter by label | Empty or label |
15
- | listedPancake | Listed on Pancake | false / true |
16
- | pageIndex | Page number | 1 |
17
- | pageSize | Page size | 30 |
18
-
19
- CLI: `fourmeme token-list [--orderBy=Hot] [--pageIndex=1] [--pageSize=30] [--tokenName=] [--symbol=] [--labels=] [--listedPancake=false]`
7
+ **POST** `/public/token/search`
8
+ JSON body: `type`, `listType`, `pageIndex`, `pageSize`, `status`, `sort`, optional `keyword`, `symbol`, `tag` (array), `version`.
9
+
10
+ | Parameter | Description |
11
+ |-----------|-------------|
12
+ | type | Ranking sort context: NEW, HOT, PROGRESS, VOL, LAST, CAP, DEX, BURN, … |
13
+ | listType | NOR, NOR_DEX, BIN, USD1, BIN_DEX, USD1_DEX, ADV |
14
+ | status | PUBLISH, TRADE, ALL |
15
+ | sort | DESC, ASC |
16
+ | keyword | Search keyword |
17
+ | symbol | Quote symbol (e.g. BNB, USDT) |
18
+ | tag | Label filters (e.g. Meme, AI) |
19
+ | version | V9 (tax), V10 (AI); omit for all |
20
+
21
+ CLI: `fourmeme token-list` — legacy flags still map to the above (e.g. `--orderBy` → `type`, `--tokenName` → `keyword`, `--labels` → `tag`, `--listedPancake=false` → `status=PUBLISH`). See script header for full list.
20
22
 
21
23
  ## 2. Token detail and trading info
22
24
 
@@ -24,17 +26,19 @@ CLI: `fourmeme token-list [--orderBy=Hot] [--pageIndex=1] [--pageSize=30] [--tok
24
26
 
25
27
  CLI: `fourmeme token-get <tokenAddress>`
26
28
 
27
- ## 3. Rankings (advanced)
29
+ ## 3. Rankings
30
+
31
+ **POST** `/public/token/ranking`
32
+ JSON body: `type` (required RankingType), `pageSize`, optional `rankingKind`, `version`, `symbol`, `minCap`, `maxCap`, `minVol`, `maxVol`, `minHold`, `maxHold`.
28
33
 
29
- **POST** `/private/token/query/advanced`
30
- Body (JSON): `{ "orderBy": "<value>" }` or `{ "orderBy": "TradingDesc", "barType": "HOUR24" }`
34
+ | Legacy CLI orderBy | Maps to type |
35
+ |--------------------|--------------|
36
+ | Time | NEW |
37
+ | ProgressDesc | PROGRESS |
38
+ | TradingDesc | VOL_DAY_1 (default); `--barType` selects VOL_HOUR_1, VOL_HOUR_4, VOL_MIN_30, VOL_MIN_5, … |
39
+ | Hot | HOT |
40
+ | Graduated | DEX |
31
41
 
32
- | orderBy | Description |
33
- |---------|-------------|
34
- | Time | Newest tokens |
35
- | ProgressDesc | Fundraise progress ranking |
36
- | TradingDesc | 24h trading volume (can use barType: HOUR24) |
37
- | Hot | Hot ranking |
38
- | Graduated | Recently graduated / launched |
42
+ You may also pass a native `type` as the first argument (e.g. `VOL_DAY_1`, `CAP`, `BURN`).
39
43
 
40
- CLI: `fourmeme token-rankings <orderBy> [--barType=HOUR24]`
44
+ CLI: `fourmeme token-rankings <orderBy|type> [--barType=HOUR24] [--pageSize=20] [--symbol=] [--version=] …`
@@ -1,52 +1,52 @@
1
- #!/usr/bin/env node
2
- /**
3
- * EIP-8004 NFT – query balance (number of identity NFTs owned by address).
4
- *
5
- * Usage:
6
- * npx tsx 8004-balance.ts <ownerAddress>
7
- *
8
- * Optional env: BSC_RPC_URL, 8004_NFT_ADDRESS.
9
- * Default contract: 0x8004A169FB4a3325136EB29fA0ceB6D2e539a432 (BSC).
10
- */
11
-
12
- import { createPublicClient, http, parseAbi } from 'viem';
13
- import { bsc } from 'viem/chains';
14
-
15
- const DEFAULT_8004_NFT = '0x8004A169FB4a3325136EB29fA0ceB6D2e539a432' as const;
16
-
17
- const ABI = parseAbi(['function balanceOf(address owner) view returns (uint256)']);
18
-
19
- function isAddress(s: string): boolean {
20
- return /^0x[0-9a-fA-F]{40}$/.test(s);
21
- }
22
-
23
- async function main() {
24
- const ownerAddress = process.argv[2];
25
- if (!ownerAddress || !isAddress(ownerAddress)) {
26
- console.error('Usage: 8004-balance.ts <ownerAddress>');
27
- console.error(' ownerAddress: 0x... wallet address');
28
- process.exit(1);
29
- }
30
-
31
- const contractAddress = (process.env['8004_NFT_ADDRESS'] || process.env.EIP8004_NFT_ADDRESS || DEFAULT_8004_NFT) as `0x${string}`;
32
- const rpcUrl = process.env.BSC_RPC_URL || 'https://bsc-dataseed.binance.org';
33
-
34
- const client = createPublicClient({
35
- chain: bsc,
36
- transport: http(rpcUrl),
37
- });
38
-
39
- const balance = await client.readContract({
40
- address: contractAddress,
41
- abi: ABI,
42
- functionName: 'balanceOf',
43
- args: [ownerAddress as `0x${string}`],
44
- });
45
-
46
- console.log(JSON.stringify({ owner: ownerAddress, balance: Number(balance) }, null, 2));
47
- }
48
-
49
- main().catch((e) => {
50
- console.error(e.message || e);
51
- process.exit(1);
52
- });
1
+ #!/usr/bin/env node
2
+ /**
3
+ * EIP-8004 NFT – query balance (number of identity NFTs owned by address).
4
+ *
5
+ * Usage:
6
+ * npx tsx 8004-balance.ts <ownerAddress>
7
+ *
8
+ * Optional env: BSC_RPC_URL, 8004_NFT_ADDRESS.
9
+ * Default contract: 0x8004A169FB4a3325136EB29fA0ceB6D2e539a432 (BSC).
10
+ */
11
+
12
+ import { createPublicClient, http, parseAbi } from 'viem';
13
+ import { bsc } from 'viem/chains';
14
+
15
+ const DEFAULT_8004_NFT = '0x8004A169FB4a3325136EB29fA0ceB6D2e539a432' as const;
16
+
17
+ const ABI = parseAbi(['function balanceOf(address owner) view returns (uint256)']);
18
+
19
+ function isAddress(s: string): boolean {
20
+ return /^0x[0-9a-fA-F]{40}$/.test(s);
21
+ }
22
+
23
+ async function main() {
24
+ const ownerAddress = process.argv[2];
25
+ if (!ownerAddress || !isAddress(ownerAddress)) {
26
+ console.error('Usage: 8004-balance.ts <ownerAddress>');
27
+ console.error(' ownerAddress: 0x... wallet address');
28
+ process.exit(1);
29
+ }
30
+
31
+ const contractAddress = (process.env['8004_NFT_ADDRESS'] || process.env.EIP8004_NFT_ADDRESS || DEFAULT_8004_NFT) as `0x${string}`;
32
+ const rpcUrl = process.env.BSC_RPC_URL || 'https://bsc-dataseed.binance.org';
33
+
34
+ const client = createPublicClient({
35
+ chain: bsc,
36
+ transport: http(rpcUrl),
37
+ });
38
+
39
+ const balance = await client.readContract({
40
+ address: contractAddress,
41
+ abi: ABI,
42
+ functionName: 'balanceOf',
43
+ args: [ownerAddress as `0x${string}`],
44
+ });
45
+
46
+ console.log(JSON.stringify({ owner: ownerAddress, balance: Number(balance) }, null, 2));
47
+ }
48
+
49
+ main().catch((e) => {
50
+ console.error(e.message || e);
51
+ process.exit(1);
52
+ });
@@ -1,108 +1,108 @@
1
- #!/usr/bin/env node
2
- /**
3
- * EIP-8004 NFT – register agent (mint identity NFT).
4
- * Builds agentURI as data:application/json;base64,<payload> and calls contract.register(agentURI).
5
- *
6
- * Usage:
7
- * npx tsx 8004-register.ts <name> [imageUrl] [description]
8
- * - name: required
9
- * - imageUrl: optional (URL string)
10
- * - description: optional
11
- *
12
- * Env: PRIVATE_KEY. Optional: BSC_RPC_URL, 8004_NFT_ADDRESS.
13
- * Default contract: 0x8004A169FB4a3325136EB29fA0ceB6D2e539a432 (BSC).
14
- */
15
-
16
- import { createPublicClient, createWalletClient, decodeEventLog, http, parseAbi } from 'viem';
17
- import { privateKeyToAccount } from 'viem/accounts';
18
- import { bsc } from 'viem/chains';
19
-
20
- const DEFAULT_8004_NFT = '0x8004A169FB4a3325136EB29fA0ceB6D2e539a432' as const;
21
-
22
- const REGISTRATION_TYPE = 'https://eips.ethereum.org/EIPS/eip-8004#registration-v1';
23
-
24
- const ABI = parseAbi([
25
- 'function register(string agentURI) returns (uint256 agentId)',
26
- 'event Registered(uint256 indexed agentId, string agentURI, address indexed owner)',
27
- ]);
28
-
29
- function buildAgentURI(name: string, imageUrl: string, description: string): string {
30
- const payload = {
31
- type: REGISTRATION_TYPE,
32
- name: name || '',
33
- description: description || 'I\'m four.meme trading agent',
34
- image: imageUrl || '',
35
- active: true,
36
- supportedTrust: [''],
37
- };
38
- const json = JSON.stringify(payload);
39
- const base64 = Buffer.from(json, 'utf8').toString('base64');
40
- return `data:application/json;base64,${base64}`;
41
- }
42
-
43
- async function main() {
44
- const privateKey = process.env.PRIVATE_KEY;
45
- if (!privateKey) {
46
- console.error('Set PRIVATE_KEY');
47
- process.exit(1);
48
- }
49
- const pk = privateKey.startsWith('0x') ? (privateKey as `0x${string}`) : (`0x${privateKey}` as `0x${string}`);
50
- const account = privateKeyToAccount(pk);
51
-
52
- const name = process.argv[2];
53
- const imageUrl = process.argv[3] ?? '';
54
- const description = process.argv[4] ?? '';
55
-
56
- if (!name || name.trim() === '') {
57
- console.error('Usage: 8004-register.ts <name> [imageUrl] [description]');
58
- console.error(' name: required. imageUrl and description are optional.');
59
- process.exit(1);
60
- }
61
-
62
- const agentURI = buildAgentURI(name.trim(), imageUrl.trim(), description.trim());
63
- const contractAddress = (process.env['8004_NFT_ADDRESS'] || process.env.EIP8004_NFT_ADDRESS || DEFAULT_8004_NFT) as `0x${string}`;
64
- const rpcUrl = process.env.BSC_RPC_URL || 'https://bsc-dataseed.binance.org';
65
-
66
- const wallet = createWalletClient({
67
- account,
68
- chain: bsc,
69
- transport: http(rpcUrl),
70
- });
71
- const publicClient = createPublicClient({
72
- chain: bsc,
73
- transport: http(rpcUrl),
74
- });
75
-
76
- const txHash = await wallet.writeContract({
77
- address: contractAddress,
78
- abi: ABI,
79
- functionName: 'register',
80
- args: [agentURI],
81
- });
82
-
83
- const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
84
- let agentId: number | null = null;
85
- for (const l of receipt.logs) {
86
- if (l.address.toLowerCase() !== contractAddress.toLowerCase()) continue;
87
- try {
88
- const d = decodeEventLog({
89
- abi: ABI,
90
- data: l.data,
91
- topics: l.topics,
92
- });
93
- if (d.eventName === 'Registered') {
94
- agentId = Number((d.args as { agentId: bigint }).agentId);
95
- break;
96
- }
97
- } catch {
98
- /* ignore */
99
- }
100
- }
101
-
102
- console.log(JSON.stringify({ txHash, agentId, agentURI }, null, 2));
103
- }
104
-
105
- main().catch((e) => {
106
- console.error(e.message || e);
107
- process.exit(1);
108
- });
1
+ #!/usr/bin/env node
2
+ /**
3
+ * EIP-8004 NFT – register agent (mint identity NFT).
4
+ * Builds agentURI as data:application/json;base64,<payload> and calls contract.register(agentURI).
5
+ *
6
+ * Usage:
7
+ * npx tsx 8004-register.ts <name> [imageUrl] [description]
8
+ * - name: required
9
+ * - imageUrl: optional (URL string)
10
+ * - description: optional
11
+ *
12
+ * Env: PRIVATE_KEY. Optional: BSC_RPC_URL, 8004_NFT_ADDRESS.
13
+ * Default contract: 0x8004A169FB4a3325136EB29fA0ceB6D2e539a432 (BSC).
14
+ */
15
+
16
+ import { createPublicClient, createWalletClient, decodeEventLog, http, parseAbi } from 'viem';
17
+ import { privateKeyToAccount } from 'viem/accounts';
18
+ import { bsc } from 'viem/chains';
19
+
20
+ const DEFAULT_8004_NFT = '0x8004A169FB4a3325136EB29fA0ceB6D2e539a432' as const;
21
+
22
+ const REGISTRATION_TYPE = 'https://eips.ethereum.org/EIPS/eip-8004#registration-v1';
23
+
24
+ const ABI = parseAbi([
25
+ 'function register(string agentURI) returns (uint256 agentId)',
26
+ 'event Registered(uint256 indexed agentId, string agentURI, address indexed owner)',
27
+ ]);
28
+
29
+ function buildAgentURI(name: string, imageUrl: string, description: string): string {
30
+ const payload = {
31
+ type: REGISTRATION_TYPE,
32
+ name: name || '',
33
+ description: description || 'I\'m four.meme trading agent',
34
+ image: imageUrl || '',
35
+ active: true,
36
+ supportedTrust: [''],
37
+ };
38
+ const json = JSON.stringify(payload);
39
+ const base64 = Buffer.from(json, 'utf8').toString('base64');
40
+ return `data:application/json;base64,${base64}`;
41
+ }
42
+
43
+ async function main() {
44
+ const privateKey = process.env.PRIVATE_KEY;
45
+ if (!privateKey) {
46
+ console.error('Set PRIVATE_KEY');
47
+ process.exit(1);
48
+ }
49
+ const pk = privateKey.startsWith('0x') ? (privateKey as `0x${string}`) : (`0x${privateKey}` as `0x${string}`);
50
+ const account = privateKeyToAccount(pk);
51
+
52
+ const name = process.argv[2];
53
+ const imageUrl = process.argv[3] ?? '';
54
+ const description = process.argv[4] ?? '';
55
+
56
+ if (!name || name.trim() === '') {
57
+ console.error('Usage: 8004-register.ts <name> [imageUrl] [description]');
58
+ console.error(' name: required. imageUrl and description are optional.');
59
+ process.exit(1);
60
+ }
61
+
62
+ const agentURI = buildAgentURI(name.trim(), imageUrl.trim(), description.trim());
63
+ const contractAddress = (process.env['8004_NFT_ADDRESS'] || process.env.EIP8004_NFT_ADDRESS || DEFAULT_8004_NFT) as `0x${string}`;
64
+ const rpcUrl = process.env.BSC_RPC_URL || 'https://bsc-dataseed.binance.org';
65
+
66
+ const wallet = createWalletClient({
67
+ account,
68
+ chain: bsc,
69
+ transport: http(rpcUrl),
70
+ });
71
+ const publicClient = createPublicClient({
72
+ chain: bsc,
73
+ transport: http(rpcUrl),
74
+ });
75
+
76
+ const txHash = await wallet.writeContract({
77
+ address: contractAddress,
78
+ abi: ABI,
79
+ functionName: 'register',
80
+ args: [agentURI],
81
+ });
82
+
83
+ const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
84
+ let agentId: number | null = null;
85
+ for (const l of receipt.logs) {
86
+ if (l.address.toLowerCase() !== contractAddress.toLowerCase()) continue;
87
+ try {
88
+ const d = decodeEventLog({
89
+ abi: ABI,
90
+ data: l.data,
91
+ topics: l.topics,
92
+ });
93
+ if (d.eventName === 'Registered') {
94
+ agentId = Number((d.args as { agentId: bigint }).agentId);
95
+ break;
96
+ }
97
+ } catch {
98
+ /* ignore */
99
+ }
100
+ }
101
+
102
+ console.log(JSON.stringify({ txHash, agentId, agentURI }, null, 2));
103
+ }
104
+
105
+ main().catch((e) => {
106
+ console.error(e.message || e);
107
+ process.exit(1);
108
+ });