@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,198 +1,198 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Four.meme - execute buy on TokenManager2 (BSC only).
4
- * Usage:
5
- * npx tsx execute-buy.ts <tokenAddress> amount <amountWei> <maxFundsWei> # buy fixed token amount
6
- * npx tsx execute-buy.ts <tokenAddress> funds <fundsWei> <minAmountWei> # spend fixed quote (e.g. BNB)
7
- * Env: PRIVATE_KEY. Only V2 tokens (version 2 from getTokenInfo).
8
- */
9
-
10
- import { createPublicClient, createWalletClient, http } from 'viem';
11
- import { privateKeyToAccount } from 'viem/accounts';
12
- import { bsc } from 'viem/chains';
13
-
14
- const HELPER_ADDRESS = '0xF251F83e40a78868FcfA3FA4599Dad6494E46034' as const;
15
- const ZERO = '0x0000000000000000000000000000000000000000' as const;
16
-
17
- const HELPER_ABI = [
18
- {
19
- name: 'getTokenInfo',
20
- type: 'function',
21
- stateMutability: 'view',
22
- inputs: [{ name: 'token', type: 'address' }],
23
- outputs: [
24
- { name: 'version', type: 'uint256' },
25
- { name: 'tokenManager', type: 'address' },
26
- { name: 'quote', type: 'address' },
27
- { name: 'lastPrice', type: 'uint256' },
28
- { name: 'tradingFeeRate', type: 'uint256' },
29
- { name: 'minTradingFee', type: 'uint256' },
30
- { name: 'launchTime', type: 'uint256' },
31
- { name: 'offers', type: 'uint256' },
32
- { name: 'maxOffers', type: 'uint256' },
33
- { name: 'funds', type: 'uint256' },
34
- { name: 'maxFunds', type: 'uint256' },
35
- { name: 'liquidityAdded', type: 'bool' },
36
- ],
37
- },
38
- {
39
- name: 'tryBuy',
40
- type: 'function',
41
- stateMutability: 'view',
42
- inputs: [
43
- { name: 'token', type: 'address' },
44
- { name: 'amount', type: 'uint256' },
45
- { name: 'funds', type: 'uint256' },
46
- ],
47
- outputs: [
48
- { name: 'tokenManager', type: 'address' },
49
- { name: 'quote', type: 'address' },
50
- { name: 'estimatedAmount', type: 'uint256' },
51
- { name: 'estimatedCost', type: 'uint256' },
52
- { name: 'estimatedFee', type: 'uint256' },
53
- { name: 'amountMsgValue', type: 'uint256' },
54
- { name: 'amountApproval', type: 'uint256' },
55
- { name: 'amountFunds', type: 'uint256' },
56
- ],
57
- },
58
- ] as const;
59
-
60
- const TM2_ABI = [
61
- {
62
- name: 'buyToken',
63
- type: 'function',
64
- stateMutability: 'payable',
65
- inputs: [
66
- { name: 'token', type: 'address' },
67
- { name: 'amount', type: 'uint256' },
68
- { name: 'maxFunds', type: 'uint256' },
69
- ],
70
- outputs: [],
71
- },
72
- {
73
- name: 'buyTokenAMAP',
74
- type: 'function',
75
- stateMutability: 'payable',
76
- inputs: [
77
- { name: 'token', type: 'address' },
78
- { name: 'funds', type: 'uint256' },
79
- { name: 'minAmount', type: 'uint256' },
80
- ],
81
- outputs: [],
82
- },
83
- ] as const;
84
-
85
- const ERC20_ABI = [
86
- {
87
- name: 'approve',
88
- type: 'function',
89
- stateMutability: 'nonpayable',
90
- inputs: [
91
- { name: 'spender', type: 'address' },
92
- { name: 'amount', type: 'uint256' },
93
- ],
94
- outputs: [{ type: 'bool' }],
95
- },
96
- ] as const;
97
-
98
- const RPC_URL = process.env.BSC_RPC_URL || 'https://bsc-dataseed.binance.org';
99
-
100
- async function main() {
101
- const pk = process.env.PRIVATE_KEY;
102
- if (!pk) {
103
- console.error('Set PRIVATE_KEY');
104
- process.exit(1);
105
- }
106
- const account = privateKeyToAccount(
107
- (pk.startsWith('0x') ? pk : '0x' + pk) as `0x${string}`
108
- );
109
-
110
- const tokenAddress = process.argv[2] as `0x${string}`;
111
- const mode = process.argv[3]; // 'amount' | 'funds'
112
- const arg1 = process.argv[4];
113
- const arg2 = process.argv[5];
114
-
115
- if (!tokenAddress || !mode || !arg1 || !arg2) {
116
- console.error('Usage:');
117
- console.error(' execute-buy.ts <token> amount <amountWei> <maxFundsWei>');
118
- console.error(' execute-buy.ts <token> funds <fundsWei> <minAmountWei>');
119
- process.exit(1);
120
- }
121
-
122
- const publicClient = createPublicClient({
123
- chain: bsc,
124
- transport: http(RPC_URL),
125
- });
126
- const walletClient = createWalletClient({
127
- account,
128
- chain: bsc,
129
- transport: http(RPC_URL),
130
- });
131
-
132
- const [version, tokenManager, quote] = await publicClient.readContract({
133
- address: HELPER_ADDRESS,
134
- abi: HELPER_ABI,
135
- functionName: 'getTokenInfo',
136
- args: [tokenAddress],
137
- }).then((r) => [r[0], r[1], r[2]] as const);
138
-
139
- if (Number(version) !== 2) {
140
- console.error('Only TokenManager2 (V2) tokens are supported. This token is version', version);
141
- process.exit(1);
142
- }
143
-
144
- const amountWei = mode === 'amount' ? BigInt(arg1) : 0n;
145
- const maxFundsWei = mode === 'amount' ? BigInt(arg2) : 0n;
146
- const fundsWei = mode === 'funds' ? BigInt(arg1) : 0n;
147
- const minAmountWei = mode === 'funds' ? BigInt(arg2) : 0n;
148
-
149
- const tryBuyResult = await publicClient.readContract({
150
- address: HELPER_ADDRESS,
151
- abi: HELPER_ABI,
152
- functionName: 'tryBuy',
153
- args: [tokenAddress, amountWei, fundsWei],
154
- });
155
- const amountMsgValue = tryBuyResult[5];
156
- const amountApproval = tryBuyResult[6];
157
-
158
- if (quote !== ZERO && amountApproval > 0n) {
159
- const approveHash = await walletClient.writeContract({
160
- address: quote,
161
- abi: ERC20_ABI,
162
- functionName: 'approve',
163
- args: [tokenManager, amountApproval],
164
- });
165
- console.error('Approved quote token. Tx:', approveHash);
166
- const receipt = await publicClient.waitForTransactionReceipt({ hash: approveHash });
167
- if (receipt.status !== 'success') {
168
- console.error('Approve failed');
169
- process.exit(1);
170
- }
171
- }
172
-
173
- let hash: `0x${string}`;
174
- if (mode === 'amount') {
175
- hash = await walletClient.writeContract({
176
- address: tokenManager as `0x${string}`,
177
- abi: TM2_ABI,
178
- functionName: 'buyToken',
179
- args: [tokenAddress, amountWei, maxFundsWei],
180
- value: amountMsgValue,
181
- });
182
- } else {
183
- hash = await walletClient.writeContract({
184
- address: tokenManager as `0x${string}`,
185
- abi: TM2_ABI,
186
- functionName: 'buyTokenAMAP',
187
- args: [tokenAddress, fundsWei, minAmountWei],
188
- value: amountMsgValue,
189
- });
190
- }
191
-
192
- console.log(JSON.stringify({ txHash: hash }, null, 2));
193
- }
194
-
195
- main().catch((e) => {
196
- console.error(e.message || e);
197
- process.exit(1);
198
- });
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Four.meme - execute buy on TokenManager2 (BSC only).
4
+ * Usage:
5
+ * npx tsx execute-buy.ts <tokenAddress> amount <amountWei> <maxFundsWei> # buy fixed token amount
6
+ * npx tsx execute-buy.ts <tokenAddress> funds <fundsWei> <minAmountWei> # spend fixed quote (e.g. BNB)
7
+ * Env: PRIVATE_KEY. Only V2 tokens (version 2 from getTokenInfo).
8
+ */
9
+
10
+ import { createPublicClient, createWalletClient, http } from 'viem';
11
+ import { privateKeyToAccount } from 'viem/accounts';
12
+ import { bsc } from 'viem/chains';
13
+
14
+ const HELPER_ADDRESS = '0xF251F83e40a78868FcfA3FA4599Dad6494E46034' as const;
15
+ const ZERO = '0x0000000000000000000000000000000000000000' as const;
16
+
17
+ const HELPER_ABI = [
18
+ {
19
+ name: 'getTokenInfo',
20
+ type: 'function',
21
+ stateMutability: 'view',
22
+ inputs: [{ name: 'token', type: 'address' }],
23
+ outputs: [
24
+ { name: 'version', type: 'uint256' },
25
+ { name: 'tokenManager', type: 'address' },
26
+ { name: 'quote', type: 'address' },
27
+ { name: 'lastPrice', type: 'uint256' },
28
+ { name: 'tradingFeeRate', type: 'uint256' },
29
+ { name: 'minTradingFee', type: 'uint256' },
30
+ { name: 'launchTime', type: 'uint256' },
31
+ { name: 'offers', type: 'uint256' },
32
+ { name: 'maxOffers', type: 'uint256' },
33
+ { name: 'funds', type: 'uint256' },
34
+ { name: 'maxFunds', type: 'uint256' },
35
+ { name: 'liquidityAdded', type: 'bool' },
36
+ ],
37
+ },
38
+ {
39
+ name: 'tryBuy',
40
+ type: 'function',
41
+ stateMutability: 'view',
42
+ inputs: [
43
+ { name: 'token', type: 'address' },
44
+ { name: 'amount', type: 'uint256' },
45
+ { name: 'funds', type: 'uint256' },
46
+ ],
47
+ outputs: [
48
+ { name: 'tokenManager', type: 'address' },
49
+ { name: 'quote', type: 'address' },
50
+ { name: 'estimatedAmount', type: 'uint256' },
51
+ { name: 'estimatedCost', type: 'uint256' },
52
+ { name: 'estimatedFee', type: 'uint256' },
53
+ { name: 'amountMsgValue', type: 'uint256' },
54
+ { name: 'amountApproval', type: 'uint256' },
55
+ { name: 'amountFunds', type: 'uint256' },
56
+ ],
57
+ },
58
+ ] as const;
59
+
60
+ const TM2_ABI = [
61
+ {
62
+ name: 'buyToken',
63
+ type: 'function',
64
+ stateMutability: 'payable',
65
+ inputs: [
66
+ { name: 'token', type: 'address' },
67
+ { name: 'amount', type: 'uint256' },
68
+ { name: 'maxFunds', type: 'uint256' },
69
+ ],
70
+ outputs: [],
71
+ },
72
+ {
73
+ name: 'buyTokenAMAP',
74
+ type: 'function',
75
+ stateMutability: 'payable',
76
+ inputs: [
77
+ { name: 'token', type: 'address' },
78
+ { name: 'funds', type: 'uint256' },
79
+ { name: 'minAmount', type: 'uint256' },
80
+ ],
81
+ outputs: [],
82
+ },
83
+ ] as const;
84
+
85
+ const ERC20_ABI = [
86
+ {
87
+ name: 'approve',
88
+ type: 'function',
89
+ stateMutability: 'nonpayable',
90
+ inputs: [
91
+ { name: 'spender', type: 'address' },
92
+ { name: 'amount', type: 'uint256' },
93
+ ],
94
+ outputs: [{ type: 'bool' }],
95
+ },
96
+ ] as const;
97
+
98
+ const RPC_URL = process.env.BSC_RPC_URL || 'https://bsc-dataseed.binance.org';
99
+
100
+ async function main() {
101
+ const pk = process.env.PRIVATE_KEY;
102
+ if (!pk) {
103
+ console.error('Set PRIVATE_KEY');
104
+ process.exit(1);
105
+ }
106
+ const account = privateKeyToAccount(
107
+ (pk.startsWith('0x') ? pk : '0x' + pk) as `0x${string}`
108
+ );
109
+
110
+ const tokenAddress = process.argv[2] as `0x${string}`;
111
+ const mode = process.argv[3]; // 'amount' | 'funds'
112
+ const arg1 = process.argv[4];
113
+ const arg2 = process.argv[5];
114
+
115
+ if (!tokenAddress || !mode || !arg1 || !arg2) {
116
+ console.error('Usage:');
117
+ console.error(' execute-buy.ts <token> amount <amountWei> <maxFundsWei>');
118
+ console.error(' execute-buy.ts <token> funds <fundsWei> <minAmountWei>');
119
+ process.exit(1);
120
+ }
121
+
122
+ const publicClient = createPublicClient({
123
+ chain: bsc,
124
+ transport: http(RPC_URL),
125
+ });
126
+ const walletClient = createWalletClient({
127
+ account,
128
+ chain: bsc,
129
+ transport: http(RPC_URL),
130
+ });
131
+
132
+ const [version, tokenManager, quote] = await publicClient.readContract({
133
+ address: HELPER_ADDRESS,
134
+ abi: HELPER_ABI,
135
+ functionName: 'getTokenInfo',
136
+ args: [tokenAddress],
137
+ }).then((r) => [r[0], r[1], r[2]] as const);
138
+
139
+ if (Number(version) !== 2) {
140
+ console.error('Only TokenManager2 (V2) tokens are supported. This token is version', version);
141
+ process.exit(1);
142
+ }
143
+
144
+ const amountWei = mode === 'amount' ? BigInt(arg1) : 0n;
145
+ const maxFundsWei = mode === 'amount' ? BigInt(arg2) : 0n;
146
+ const fundsWei = mode === 'funds' ? BigInt(arg1) : 0n;
147
+ const minAmountWei = mode === 'funds' ? BigInt(arg2) : 0n;
148
+
149
+ const tryBuyResult = await publicClient.readContract({
150
+ address: HELPER_ADDRESS,
151
+ abi: HELPER_ABI,
152
+ functionName: 'tryBuy',
153
+ args: [tokenAddress, amountWei, fundsWei],
154
+ });
155
+ const amountMsgValue = tryBuyResult[5];
156
+ const amountApproval = tryBuyResult[6];
157
+
158
+ if (quote !== ZERO && amountApproval > 0n) {
159
+ const approveHash = await walletClient.writeContract({
160
+ address: quote,
161
+ abi: ERC20_ABI,
162
+ functionName: 'approve',
163
+ args: [tokenManager, amountApproval],
164
+ });
165
+ console.error('Approved quote token. Tx:', approveHash);
166
+ const receipt = await publicClient.waitForTransactionReceipt({ hash: approveHash });
167
+ if (receipt.status !== 'success') {
168
+ console.error('Approve failed');
169
+ process.exit(1);
170
+ }
171
+ }
172
+
173
+ let hash: `0x${string}`;
174
+ if (mode === 'amount') {
175
+ hash = await walletClient.writeContract({
176
+ address: tokenManager as `0x${string}`,
177
+ abi: TM2_ABI,
178
+ functionName: 'buyToken',
179
+ args: [tokenAddress, amountWei, maxFundsWei],
180
+ value: amountMsgValue,
181
+ });
182
+ } else {
183
+ hash = await walletClient.writeContract({
184
+ address: tokenManager as `0x${string}`,
185
+ abi: TM2_ABI,
186
+ functionName: 'buyTokenAMAP',
187
+ args: [tokenAddress, fundsWei, minAmountWei],
188
+ value: amountMsgValue,
189
+ });
190
+ }
191
+
192
+ console.log(JSON.stringify({ txHash: hash }, null, 2));
193
+ }
194
+
195
+ main().catch((e) => {
196
+ console.error(e.message || e);
197
+ process.exit(1);
198
+ });