mint.club-cli 1.3.4 โ†’ 1.3.6

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.
Files changed (3) hide show
  1. package/README.md +160 -171
  2. package/dist/index.js +2 -2
  3. package/package.json +5 -3
package/README.md CHANGED
@@ -1,20 +1,15 @@
1
- # ๐Ÿช™ mint.club-cli
1
+ # ๐Ÿช™ Mint Club CLI
2
2
 
3
- > The command-line interface for [Mint Club V2](https://mint.club) โ€” create and trade bonding curve tokens from your terminal.
3
+ > Trade bonding curve tokens on **Base** from your terminal.
4
4
 
5
- [![npm version](https://img.shields.io/npm/v/mint.club-cli.svg)](https://www.npmjs.com/package/mint.club-cli)
6
- [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
5
+ [![npm](https://img.shields.io/npm/v/mint.club-cli.svg?style=flat-square)](https://www.npmjs.com/package/mint.club-cli)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square)](https://opensource.org/licenses/MIT)
7
7
 
8
- ## What is Mint Club?
8
+ ---
9
9
 
10
- [Mint Club V2](https://mint.club) is a permissionless bonding curve protocol for creating and trading tokens with automated pricing. Anyone can launch a token backed by a reserve asset โ€” no liquidity pool needed. The bonding curve guarantees instant buy/sell at deterministic prices.
10
+ [Mint Club V2](https://mint.club) is a permissionless bonding curve protocol โ€” launch a token backed by any reserve asset with automated pricing. No liquidity pool required.
11
11
 
12
- - ๐ŸŒ **App**: [mint.club](https://mint.club)
13
- - ๐Ÿ“– **Docs**: [docs.mint.club](https://docs.mint.club)
14
- - ๐Ÿฆ **Twitter**: [@MintClubPro](https://twitter.com/MintClubPro)
15
- - ๐Ÿ’ฌ **Chat**: [OnChat](https://onchat.sebayaki.com/mintclub)
16
- - ๐Ÿ“ฆ **SDK**: [mint.club-v2-sdk](https://www.npmjs.com/package/mint.club-v2-sdk)
17
- - ๐Ÿ”— **GitHub**: [github.com/Steemhunt](https://github.com/Steemhunt)
12
+ This CLI gives you full access from the command line: check prices, buy, sell, zap through Uniswap, create tokens, and manage your wallet.
18
13
 
19
14
  ## Install
20
15
 
@@ -22,258 +17,252 @@
22
17
  npm install -g mint.club-cli
23
18
  ```
24
19
 
25
- Requires Node.js 18+.
20
+ Requires Node.js 18+. After install, the `mc` command is available globally.
26
21
 
27
- ## Quick Start
22
+ ## Setup
28
23
 
29
24
  ```bash
30
- # Set up a wallet
25
+ # Generate a new wallet
31
26
  mc wallet --generate
32
27
 
33
- # Check your wallet & balances
34
- mc wallet
35
-
36
- # Look up a token
37
- mc info 0xYourTokenAddress --chain base
38
-
39
- # Buy tokens
40
- mc buy 0xYourTokenAddress -a 100 --chain base
28
+ # Or import an existing key
29
+ mc wallet --set-private-key 0xYourPrivateKey
41
30
  ```
42
31
 
43
- ## Commands
32
+ Your private key is stored at `~/.mintclub/.env`. **Back it up securely** โ€” if lost, your funds are gone forever.
44
33
 
45
- ### `mc wallet`
34
+ ## Commands
46
35
 
47
- Manage your wallet and check balances.
36
+ ### ๐Ÿ’ฑ `mc price <token>`
48
37
 
49
- ```bash
50
- # Show wallet address and token balances
51
- mc wallet
38
+ Get current token price in reserve and USD.
52
39
 
53
- # Show balances on a specific chain
54
- mc wallet --chain arbitrum
40
+ ```
41
+ $ mc price 0xDF2B...79c9
55
42
 
56
- # Generate a new wallet (saves to ~/.mintclub/.env)
57
- mc wallet --generate
43
+ ๐Ÿ’ฑ SIGNET (0xDF2B...79c9)
58
44
 
59
- # Import an existing private key
60
- mc wallet --set-private-key 0xYourPrivateKey
45
+ Price: 1.170000 HUNT
46
+ Price (USD): $0.0061
47
+ Reserve: 126,819.23 HUNT (~$660.34)
48
+ Market Cap: ~$3,159.60
61
49
  ```
62
50
 
63
- ### `mc info <token>`
51
+ Uses the bonding curve for reserve pricing and [1inch Spot Price Aggregator](https://1inch.io) for USD conversion.
64
52
 
65
- Get detailed token information โ€” name, supply, reserve, royalties, and bonding curve summary.
53
+ ---
66
54
 
67
- ```bash
68
- mc info 0xTokenAddress --chain base
69
- ```
55
+ ### ๐Ÿ” `mc info <token>`
56
+
57
+ Detailed token info โ€” name, supply, reserve, royalties, bonding curve, and pricing.
70
58
 
71
59
  ```
60
+ $ mc info 0xDF2B...79c9
61
+
72
62
  ๐Ÿช™ Token: SIGNET (SIGNET)
73
63
  ๐Ÿ“ Address: 0xDF2B...79c9
74
64
  ๐Ÿ‘ค Creator: 0x980C...92E4
75
- ๐Ÿ’ฐ Reserve Token: 0x37f0...064C
76
- ๐Ÿ’Ž Reserve Balance: 126819.23
77
- ๐Ÿ“Š Supply: 517963.04 / 1000000
78
- ๐Ÿ’ธ Mint Royalty: 0.30%
79
- ๐Ÿ”ฅ Burn Royalty: 0.30%
65
+ ๐Ÿ’ฐ Reserve Token: 0x37f0...064C (HUNT)
66
+ ๐Ÿ’Ž Reserve Balance: 126,819.23
67
+ ๐Ÿ“Š Supply: 517,963.04 / 1,000,000
68
+ ๐Ÿ’ธ Mint Royalty: 0.30% | ๐Ÿ”ฅ Burn Royalty: 0.30%
80
69
  ๐Ÿ“ˆ Bonding Curve: 500 steps, 0.01 โ†’ 99.99 per token (+10000x)
81
- ๐Ÿ’ฑ Current Price: 1.17 reserve per 1 SIGNET
70
+
71
+ ๐Ÿ’ฑ Current Price: 1.17 reserve per 1 SIGNET (~$0.0061)
72
+ ๐Ÿ’ต Reserve Value: ~$660.34
73
+ ๐Ÿ“Š Market Cap: ~$3,159.60
82
74
  ```
83
75
 
84
- ### `mc buy <token>`
76
+ ---
85
77
 
86
- Buy (mint) tokens by paying the reserve token along the bonding curve.
78
+ ### ๐Ÿ›’ `mc buy <token>`
79
+
80
+ Buy (mint) tokens with the reserve token along the bonding curve.
87
81
 
88
82
  ```bash
89
- mc buy 0xTokenAddress -a 100 # Buy 100 tokens
90
- mc buy 0xTokenAddress -a 100 -m 500 # Buy 100 tokens, max cost 500 reserve
91
- mc buy 0xTokenAddress -a 100 --chain polygon
83
+ mc buy 0xTokenAddress -a 100 # Buy 100 tokens
84
+ mc buy 0xTokenAddress -a 100 -m 500 # Max cost 500 reserve
92
85
  ```
93
86
 
94
87
  | Option | Description |
95
88
  |--------|-------------|
96
- | `-a, --amount <n>` | Number of tokens to buy (required) |
97
- | `-m, --max-cost <n>` | Maximum reserve tokens to spend |
98
- | `-c, --chain <chain>` | Target chain (default: `base`) |
89
+ | `-a, --amount <n>` | Tokens to buy **(required)** |
90
+ | `-m, --max-cost <n>` | Max reserve to spend |
91
+
92
+ ---
99
93
 
100
- ### `mc sell <token>`
94
+ ### ๐Ÿ”ฅ `mc sell <token>`
101
95
 
102
- Sell (burn) tokens back to the bonding curve for reserve tokens.
96
+ Sell (burn) tokens back to the bonding curve.
103
97
 
104
98
  ```bash
105
- mc sell 0xTokenAddress -a 50 # Sell 50 tokens
106
- mc sell 0xTokenAddress -a 50 -m 10 # Sell 50 tokens, minimum refund 10
99
+ mc sell 0xTokenAddress -a 50 # Sell 50 tokens
100
+ mc sell 0xTokenAddress -a 50 -m 10 # Min refund 10 reserve
107
101
  ```
108
102
 
109
103
  | Option | Description |
110
104
  |--------|-------------|
111
- | `-a, --amount <n>` | Number of tokens to sell (required) |
112
- | `-m, --min-refund <n>` | Minimum reserve tokens to receive |
113
- | `-c, --chain <chain>` | Target chain (default: `base`) |
105
+ | `-a, --amount <n>` | Tokens to sell **(required)** |
106
+ | `-m, --min-refund <n>` | Min reserve to receive |
114
107
 
115
- ### `mc create`
108
+ ---
116
109
 
117
- Create a new bonding curve token. Use a **curve preset** for easy setup, or define **custom steps** for full control.
110
+ ### โšก `mc zap-buy <token>`
118
111
 
119
- #### Using curve presets (recommended)
112
+ Buy tokens with **any token** โ€” auto-routes through Uniswap V3 into the reserve, then mints.
120
113
 
121
114
  ```bash
122
- mc create \
123
- -n "My Token" \
124
- -s MTK \
125
- -r 0xReserveTokenAddress \
126
- -x 1000000 \
127
- --curve exponential \
128
- --initial-price 0.01 \
129
- --final-price 100
115
+ # Buy with ETH (auto-finds best route)
116
+ mc zap-buy 0xTokenAddress -i ETH -a 0.01
117
+
118
+ # Buy with USDC (manual path)
119
+ mc zap-buy 0xTokenAddress -i 0xUSDC -a 50 -p "0xUSDC,3000,0xHUNT"
130
120
  ```
131
121
 
132
- Available curves:
133
- - **`linear`** โ€” price increases steadily from start to end
134
- - **`exponential`** โ€” slow start, accelerating growth (most common)
135
- - **`logarithmic`** โ€” fast early growth, flattens toward the end
136
- - **`flat`** โ€” constant price (initial and final price must match)
122
+ | Option | Description |
123
+ |--------|-------------|
124
+ | `-i, --input-token <addr>` | Token to pay with โ€” use `ETH` for native ETH **(required)** |
125
+ | `-a, --amount <n>` | Amount of input token to spend **(required)** |
126
+ | `-p, --path <p>` | Manual swap path: `token,fee,token,...` (optional โ€” auto-routes if omitted) |
127
+ | `-m, --min-tokens <n>` | Min tokens to receive |
128
+
129
+ ---
137
130
 
138
- #### Using custom steps
131
+ ### โšก `mc zap-sell <token>`
132
+
133
+ Sell tokens and receive **any token** โ€” burns for reserve, then swaps to your desired output.
139
134
 
140
135
  ```bash
141
- mc create \
142
- -n "My Token" \
143
- -s MTK \
144
- -r 0xReserveTokenAddress \
145
- -x 1000000 \
146
- -t "500000:0.01,1000000:1.0"
136
+ # Sell to ETH
137
+ mc zap-sell 0xTokenAddress -a 100 -o ETH
138
+
139
+ # Sell to USDC
140
+ mc zap-sell 0xTokenAddress -a 100 -o 0xUSDC
147
141
  ```
148
142
 
149
143
  | Option | Description |
150
144
  |--------|-------------|
151
- | `-n, --name <name>` | Token name (required) |
152
- | `-s, --symbol <sym>` | Token symbol (required) |
153
- | `-r, --reserve <addr>` | Reserve token address (required) |
154
- | `-x, --max-supply <n>` | Maximum supply (required) |
155
- | `--curve <type>` | Curve preset: `linear`, `exponential`, `logarithmic`, `flat` |
156
- | `--initial-price <n>` | Starting price (required with `--curve`) |
157
- | `--final-price <n>` | Final price (required with `--curve`) |
158
- | `-t, --steps <s>` | Custom steps as `range:price,...` (alternative to `--curve`) |
159
- | `--mint-royalty <bp>` | Mint royalty in basis points (default: 0) |
160
- | `--burn-royalty <bp>` | Burn royalty in basis points (default: 0) |
161
- | `-c, --chain <chain>` | Target chain (default: `base`) |
162
-
163
- ### `mc zap-buy <token>` โšก
164
-
165
- Buy tokens with **any** token โ€” automatically swaps through Uniswap V3 into the reserve token, then mints. Currently available on **Base** only.
145
+ | `-a, --amount <n>` | Tokens to sell **(required)** |
146
+ | `-o, --output-token <addr>` | Token to receive โ€” use `ETH` for native ETH **(required)** |
147
+ | `-p, --path <p>` | Manual swap path (optional โ€” auto-routes if omitted) |
148
+ | `-m, --min-output <n>` | Min output to receive |
149
+
150
+ ---
151
+
152
+ ### ๐Ÿช™ `mc create`
153
+
154
+ Create a new bonding curve token with presets or custom steps.
166
155
 
167
156
  ```bash
168
- mc zap-buy 0xTokenAddress \
169
- -i 0xInputToken \
170
- -a 1.0 \
171
- -p "0xInputToken,3000,0xReserveToken"
157
+ # Exponential curve from 0.01 to 100
158
+ mc create -n "My Token" -s MTK \
159
+ -r 0xReserveToken -x 1000000 \
160
+ --curve exponential --initial-price 0.01 --final-price 100
161
+
162
+ # Custom steps
163
+ mc create -n "My Token" -s MTK \
164
+ -r 0xReserveToken -x 1000000 \
165
+ -t "500000:0.01,1000000:1.0"
172
166
  ```
173
167
 
168
+ **Curve presets:** `linear` ยท `exponential` ยท `logarithmic` ยท `flat`
169
+
174
170
  | Option | Description |
175
171
  |--------|-------------|
176
- | `-i, --input-token <addr>` | Token you're paying with (use `0x0` for ETH) (required) |
177
- | `-a, --input-amount <n>` | Amount of input token (required) |
178
- | `-p, --path <p>` | Uniswap V3 swap path: `token,fee,token,...` (required) |
179
- | `-m, --min-tokens <n>` | Minimum tokens to receive |
180
- | `-c, --chain <chain>` | Target chain (default: `base`) |
172
+ | `-n, --name <name>` | Token name **(required)** |
173
+ | `-s, --symbol <sym>` | Token symbol **(required)** |
174
+ | `-r, --reserve <addr>` | Reserve token address **(required)** |
175
+ | `-x, --max-supply <n>` | Max supply **(required)** |
176
+ | `--curve <type>` | Curve preset |
177
+ | `--initial-price <n>` | Start price (with `--curve`) |
178
+ | `--final-price <n>` | End price (with `--curve`) |
179
+ | `-t, --steps <s>` | Custom steps as `range:price,...` |
180
+ | `--mint-royalty <bp>` | Mint royalty in bps (default: `100` = 1%) |
181
+ | `--burn-royalty <bp>` | Burn royalty in bps (default: `100` = 1%) |
182
+ | `-y, --yes` | Skip confirmation |
181
183
 
182
- ### `mc zap-sell <token>` โšก
184
+ ---
183
185
 
184
- Sell tokens and receive **any** token โ€” burns tokens for reserve, then swaps to your desired output. Currently available on **Base** only.
186
+ ### ๐Ÿ‘› `mc wallet`
187
+
188
+ View balances with USD values, or manage keys.
185
189
 
186
- ```bash
187
- mc zap-sell 0xTokenAddress \
188
- -a 100 \
189
- -o 0xOutputToken \
190
- -p "0xReserveToken,3000,0xOutputToken"
191
190
  ```
191
+ $ mc wallet
192
192
 
193
- | Option | Description |
194
- |--------|-------------|
195
- | `-a, --amount <n>` | Tokens to sell (required) |
196
- | `-o, --output-token <addr>` | Token you want to receive (required) |
197
- | `-p, --path <p>` | Uniswap V3 swap path: `token,fee,token,...` (required) |
198
- | `-m, --min-output <n>` | Minimum output tokens to receive |
199
- | `-c, --chain <chain>` | Target chain (default: `base`) |
193
+ ๐Ÿ‘› Wallet: 0x5831...E316
200
194
 
201
- ### `mc send <to>`
195
+ ๐Ÿ’ฐ Balances on Base:
202
196
 
203
- Send ETH, ERC-20 tokens, or ERC-1155 tokens to another wallet.
197
+ ETH: 0.008749 (~$17.13)
198
+ HUNT: 1,000.00 (~$5.20)
204
199
 
205
- ```bash
206
- # Send ETH
207
- mc send 0xRecipient -a 0.1
200
+ ๐Ÿช™ Mint Club Tokens:
208
201
 
209
- # Send ERC-20 tokens
210
- mc send 0xRecipient -a 100 -t 0xTokenAddress
202
+ SIGNET: 500.00 (~$2.93)
203
+ ONCHAT: 1,200.00 (~$8.40)
211
204
 
212
- # Send ERC-1155 NFT
213
- mc send 0xRecipient -a 1 -t 0xNFTAddress --token-id 42
205
+ ๐Ÿ’ต Total: ~$33.66
214
206
  ```
215
207
 
208
+ Tokens you've traded via `buy`/`sell`/`zap-buy`/`zap-sell` are automatically tracked in `~/.mintclub/tokens.json` and shown here.
209
+
216
210
  | Option | Description |
217
211
  |--------|-------------|
218
- | `-a, --amount <n>` | Amount to send (required) |
219
- | `-t, --token <addr>` | Token contract address (omit for ETH) |
220
- | `--token-id <id>` | ERC-1155 token ID |
221
- | `-c, --chain <chain>` | Target chain (default: `base`) |
212
+ | `-g, --generate` | Generate a new wallet |
213
+ | `-s, --set-private-key <key>` | Import a private key |
222
214
 
223
- ## Configuration
215
+ ---
224
216
 
225
- Your private key is stored at `~/.mintclub/.env`:
217
+ ### ๐Ÿ“ค `mc send <to>`
226
218
 
227
- ```
228
- PRIVATE_KEY=0xYourPrivateKeyHere
219
+ Send ETH, ERC-20, or ERC-1155 tokens.
220
+
221
+ ```bash
222
+ mc send 0xRecipient -a 0.1 # Send ETH
223
+ mc send 0xRecipient -a 100 -t 0xToken # Send ERC-20
224
+ mc send 0xRecipient -a 1 -t 0xNFT --token-id 42 # Send ERC-1155
229
225
  ```
230
226
 
231
- You can set it up via:
232
- - `mc wallet --generate` โ€” create a brand new wallet
233
- - `mc wallet --set-private-key 0x...` โ€” import an existing key
227
+ | Option | Description |
228
+ |--------|-------------|
229
+ | `-a, --amount <n>` | Amount **(required)** |
230
+ | `-t, --token <addr>` | Token address (omit for ETH) |
231
+ | `--token-id <id>` | ERC-1155 token ID |
234
232
 
235
- > โš ๏ธ **Back up your private key in a secure, encrypted location!** If you lose it, your funds are gone forever. If it's leaked, anyone can drain your wallet immediately.
233
+ ---
236
234
 
237
- ## Supported Chains
235
+ ### โฌ†๏ธ `mc upgrade`
238
236
 
239
- | Chain | Name | Zap Support |
240
- |-------|------|:-----------:|
241
- | Base | `base` | โœ… |
242
- | Ethereum | `mainnet` | โ€” |
243
- | Arbitrum | `arbitrum` | โ€” |
244
- | Optimism | `optimism` | โ€” |
245
- | Polygon | `polygon` | โ€” |
246
- | BNB Chain | `bsc` | โ€” |
247
- | Avalanche | `avalanche` | โ€” |
248
- | Blast | `blast` | โ€” |
249
- | Degen | `degen` | โ€” |
250
- | Kaia | `kaia` | โ€” |
251
- | Cyber | `cyber` | โ€” |
252
- | Ham | `ham` | โ€” |
253
- | Mode | `mode` | โ€” |
254
- | Zora | `zora` | โ€” |
237
+ Update to the latest version.
255
238
 
256
- Default chain is `base`. Use `--chain <name>` on any command to switch.
239
+ ```bash
240
+ mc upgrade
241
+ ```
257
242
 
258
- ## Swap Path Format
243
+ ## Swap Routing
259
244
 
260
- For zap commands, the `--path` flag uses Uniswap V3 path encoding:
245
+ Zap commands auto-find the best Uniswap V3 route through WETH, USDC, and USDbC. You can also specify a manual path:
261
246
 
262
247
  ```
263
- tokenAddress,fee,tokenAddress,fee,tokenAddress
248
+ tokenAddress,fee,tokenAddress[,fee,tokenAddress]
264
249
  ```
265
250
 
266
- Common fee tiers: `100` (0.01%), `500` (0.05%), `3000` (0.3%), `10000` (1%)
251
+ **Fee tiers:** `100` (0.01%) ยท `500` (0.05%) ยท `3000` (0.3%) ยท `10000` (1%)
267
252
 
268
- Example multi-hop: `0xUSDC,500,0xWETH,3000,0xHUNT`
253
+ **Example:** `0xUSDC,500,0xWETH,3000,0xHUNT` (USDC โ†’ WETH โ†’ HUNT)
269
254
 
270
255
  ## Links
271
256
 
272
- - **Mint Club App**: [mint.club](https://mint.club)
273
- - **Documentation**: [docs.mint.club](https://docs.mint.club)
274
- - **SDK**: [mint.club-v2-sdk](https://www.npmjs.com/package/mint.club-v2-sdk)
275
- - **Smart Contracts**: [github.com/Steemhunt/mint.club-v2-contract](https://github.com/Steemhunt/mint.club-v2-contract)
276
- - **Hunt Town**: [hunt.town](https://hunt.town) โ€” the onchain co-op behind Mint Club
257
+ | | |
258
+ |---|---|
259
+ | ๐ŸŒ **App** | [mint.club](https://mint.club) |
260
+ | ๐Ÿ“– **Docs** | [docs.mint.club](https://docs.mint.club) |
261
+ | ๐Ÿ“ฆ **SDK** | [mint.club-v2-sdk](https://www.npmjs.com/package/mint.club-v2-sdk) |
262
+ | ๐Ÿ”— **Contracts** | [github.com/Steemhunt/mint.club-v2-contract](https://github.com/Steemhunt/mint.club-v2-contract) |
263
+ | ๐Ÿ’ฌ **Chat** | [OnChat](https://onchat.sebayaki.com/mintclub) |
264
+ | ๐Ÿฆ **Twitter** | [@MintClubPro](https://twitter.com/MintClubPro) |
265
+ | ๐Ÿ—๏ธ **Hunt Town** | [hunt.town](https://hunt.town) |
277
266
 
278
267
  ## License
279
268
 
package/dist/index.js CHANGED
@@ -72,7 +72,7 @@ ${xG(M)}`;super($.shortMessage,{cause:$,docsPath:Q,metaMessages:[...$.metaMessag
72
72
  \uD83D\uDCB1 Current Price: ${s(O)} reserve per 1 ${N}`,z=await L8(M);if(z!==null){let L=Number(O)/1000000000000000000*z;H+=` (~$${L<0.01?L.toExponential(2):L.toFixed(4)})`;let U=Number(w)/1000000000000000000*z;if(H+=`
73
73
  \uD83D\uDCB5 Reserve Value: ~$${U.toFixed(2)}`,Y.result){let C=Number(Y.result)/1000000000000000000*L;H+=`
74
74
  \uD83D\uDCCA Market Cap: ~$${C.toFixed(2)}`}}console.log(H)}catch{console.log(`
75
- โš ๏ธ Could not fetch current price`)}}import{resolve as Jq}from"path";import{homedir as Qq}from"os";import{existsSync as HN,readFileSync as LN,writeFileSync as SN,mkdirSync as RN}from"fs";var x7=Jq(Qq(),".mintclub","tokens.json");function y7(){if(!HN(x7))return[];try{return JSON.parse(LN(x7,"utf-8"))}catch{return[]}}function S8($){let J=y7(),Q=x$($);if(J.some((X)=>X.toLowerCase()===Q.toLowerCase()))return;J.push(Q),RN(Jq(Qq(),".mintclub"),{recursive:!0}),SN(x7,JSON.stringify(J,null,2)+`
75
+ โš ๏ธ Could not fetch current price`)}}import{resolve as Jq}from"path";import{homedir as Qq}from"os";import{existsSync as HN,readFileSync as LN,writeFileSync as SN,mkdirSync as RN}from"fs";var x7=Jq(Qq(),".mintclub","tokens.json");function y7(){if(!HN(x7))return[];try{let $=JSON.parse(LN(x7,"utf-8"));return Array.isArray($)?$:[]}catch{return[]}}function S8($){let J=y7(),Q=x$($);if(J.some((X)=>X.toLowerCase()===Q.toLowerCase()))return;J.push(Q),RN(Jq(Qq(),".mintclub"),{recursive:!0}),SN(x7,JSON.stringify(J,null,2)+`
76
76
  `)}async function Xq($,J,Q,X){let Y=B0(),Z=_$(X),W=Z.account,G=_0(J);console.log(`\uD83D\uDED2 Buying ${J} tokens of ${$} on Base...`);let[K,V]=await Y.readContract({address:X0,abi:Y0,functionName:"getReserveForToken",args:[$,G]}),q=K+V;if(console.log(` Reserve: ${s(K)} | Royalty: ${s(V)} | Total: ${s(q)}`),Q&&q>_0(Q))throw Error(`Cost ${s(q)} exceeds max ${Q}`);let D=[$,G,q,W.address];await Y.simulateContract({account:W,address:X0,abi:Y0,functionName:"mint",args:D}),console.log("\uD83D\uDCE4 Sending...");let M=await Z.writeContract({address:X0,abi:Y0,functionName:"mint",args:D});console.log(` TX: ${Z$(M)}`),console.log(` ${W$(M)}`);let w=await Y.waitForTransactionReceipt({hash:M});if(w.status==="success")S8($),console.log(`โœ… Bought ${J} tokens for ${s(q)} reserve (block ${w.blockNumber})`);else throw Error("Transaction failed")}async function Yq($,J,Q,X){let Y=B0(),Z=_$(X),W=Z.account,G=_0(J);console.log(`\uD83D\uDD25 Selling ${J} tokens of ${$} on Base...`);let[K,V]=await Y.readContract({address:X0,abi:Y0,functionName:"getRefundForTokens",args:[$,G]}),q=K-V;if(console.log(` Refund: ${s(K)} | Royalty: ${s(V)} | Net: ${s(q)}`),Q&&q<_0(Q))throw Error(`Refund ${s(q)} below minimum ${Q}`);let D=Q?_0(Q):0n,M=[$,G,D,W.address];await Y.simulateContract({account:W,address:X0,abi:Y0,functionName:"burn",args:M}),console.log("\uD83D\uDCE4 Sending...");let w=await Z.writeContract({address:X0,abi:Y0,functionName:"burn",args:M});console.log(` TX: ${Z$(w)}`),console.log(` ${W$(w)}`);let O=await Y.waitForTransactionReceipt({hash:w});if(O.status==="success")S8($),console.log(`โœ… Sold ${J} tokens for ${s(q)} reserve (block ${O.blockNumber})`);else throw Error("Transaction failed")}import{createInterface as IN}from"readline";var BN=500;function Zq($,J,Q,X){let Y=O8(J,18),Z=parseFloat(Q),W=parseFloat(X);if(Z<=0||W<=0)throw Error("Prices must be positive");if($==="flat"&&Z!==W)throw Error("Flat curve requires initial and final price to be the same");let G=[],K=[],V=$==="flat"?1:BN;for(let q=0;q<V;q++){let D=V===1?1:(q+1)/V,M=Y*BigInt(q+1)/BigInt(V),w;switch($){case"linear":w=Z+(W-Z)*D;break;case"exponential":w=Z*Math.pow(W/Z,D);break;case"logarithmic":w=Z+(W-Z)*Math.log(1+D*(Math.E-1));break;case"flat":w=Z;break}G.push(M),K.push(O8(w.toFixed(18),18))}return{ranges:G,prices:K}}function Wq($){return["linear","exponential","logarithmic","flat"].includes($)}function Gq($,J,Q=[10,25,50,75,100]){let X=$[$.length-1],Y=[];for(let Z of Q){let W=X*BigInt(Z)/100n,G=0n,K=0n;for(let V=0;V<$.length;V++){let q=K,D=$[V],M=J[V];if(W<=q)break;let O=(W<D?W:D)-q;if(G+=O*M/10n**18n,K=D,W<=D)break}Y.push({milestone:Z,supply:W,cost:G})}return Y}function v7($,J=18){let Q=Number($)/1000000000000000000;if(Q>=1e9)return`${(Q/1e9).toFixed(2)}B`;if(Q>=1e6)return`${(Q/1e6).toFixed(2)}M`;if(Q>=1000)return`${(Q/1000).toFixed(2)}K`;if(Q>=1)return Q.toFixed(2);if(Q>=0.001)return Q.toFixed(4);return Q.toFixed(6)}function EN($){let J=IN({input:process.stdin,output:process.stdout});return new Promise((Q)=>{J.question($,(X)=>{J.close(),Q(X.toLowerCase()==="y"||X.toLowerCase()==="yes")})})}async function Kq($,J,Q,X,Y,Z){let W=B0(),G=_$(Y),K=G.account,V,q;if(Z.curve){if(!Wq(Z.curve))throw Error(`Invalid curve: ${Z.curve}. Options: linear, exponential, logarithmic, flat`);if(!Z.initialPrice||!Z.finalPrice)throw Error("--initial-price and --final-price are required with --curve");({ranges:V,prices:q}=Zq(Z.curve,X,Z.initialPrice,Z.finalPrice)),console.log(`\uD83D\uDE80 Creating "${$}" (${J}) on Base...`),console.log(` Reserve: ${Q} | Max supply: ${X}`),console.log(` Curve: ${Z.curve} | ${Z.initialPrice} โ†’ ${Z.finalPrice} | ${V.length} steps`)}else if(Z.steps)({ranges:V,prices:q}=rV(Z.steps)),console.log(`\uD83D\uDE80 Creating "${$}" (${J}) on Base...`),console.log(` Reserve: ${Q} | Max supply: ${X} | Steps: ${V.length}`);else throw Error("Provide either --steps or --curve (with --initial-price and --final-price)");let D=Z.mintRoyalty??0,M=Z.burnRoyalty??0;console.log(` Royalties: mint ${D/100}% / burn ${M/100}%`);let w=await W.readContract({address:X0,abi:Y0,functionName:"creationFee"});if(w>0n)console.log(` Creation fee: ${s(w)} ETH`);console.log(`
77
77
  \uD83D\uDCCA Price Range: ${s(q[0])} โ†’ ${s(q[q.length-1])} reserve per token`);let O=Gq(V,q),N=O[O.length-1].cost;if(console.log(`
78
78
  \uD83D\uDCB0 Accumulated reserve required to mint:`),console.log(` ${O.map((R)=>`${R.milestone}%`.padStart(12)).join("")}`),console.log(` ${O.map((R)=>v7(R.cost).padStart(12)).join("")}`),console.log(`
@@ -102,4 +102,4 @@ ${xG(M)}`;super($.shortMessage,{cause:$,docsPath:Q,metaMessages:[...$.metaMessag
102
102
  `),H=!0;let C=` ${N[z*3+1].status==="success"?N[z*3+1].result:O[z].slice(0,10)}: ${y0(L,18)}`;if(N[z*3+2].status==="success"){let[,,,,R]=N[z*3+2].result;try{let[B]=await Y.readContract({address:X0,abi:Y0,functionName:"getReserveForToken",args:[O[z],10n**18n]}),I=await L8(R);if(I!==null){let T=t0.find((P)=>P.address.toLowerCase()===R.toLowerCase())?.decimals??18,f=Number(B)/10**T*I,E=Number(L)/1000000000000000000*f;V+=E,C+=` (~$${K(E)})`}}catch{}}console.log(C)}}if(V>0)console.log(`
103
103
  \uD83D\uDCB5 Total: ~$${K(V)}`)}var PN=[{type:"function",name:"safeTransferFrom",stateMutability:"nonpayable",inputs:[{name:"from",type:"address"},{name:"to",type:"address"},{name:"id",type:"uint256"},{name:"amount",type:"uint256"},{name:"data",type:"bytes"}],outputs:[]}];async function Rq($,J,Q,X){let Y=B0(),Z=_$(Q),W=Z.account;if(X.token&&X.tokenId){let q=BigInt(X.tokenId),D=BigInt(J);console.log(`\uD83D\uDCE6 Sending ${D} of ERC-1155 #${q} (${H8(X.token)}) to ${H8($)} on Base...`);let M=await Z.writeContract({address:X.token,abi:PN,functionName:"safeTransferFrom",args:[W.address,$,q,D,"0x"]});console.log(` TX: ${Z$(M)}`),console.log(` ${W$(M)}`);let w=await Y.waitForTransactionReceipt({hash:M});if(w.status==="success")console.log(`โœ… Sent (block ${w.blockNumber})`);else throw Error("Transaction failed");return}if(X.token){let[q,D]=await Promise.all([Y.readContract({address:X.token,abi:r0,functionName:"decimals"}),Y.readContract({address:X.token,abi:r0,functionName:"symbol"}).catch(()=>"tokens")]),M=_0(J,q);console.log(`\uD83D\uDCB8 Sending ${J} ${D} (${H8(X.token)}) to ${H8($)} on Base...`);let w=await Z.writeContract({address:X.token,abi:[{type:"function",name:"transfer",stateMutability:"nonpayable",inputs:[{name:"to",type:"address"},{name:"amount",type:"uint256"}],outputs:[{type:"bool"}]}],functionName:"transfer",args:[$,M]});console.log(` TX: ${Z$(w)}`),console.log(` ${W$(w)}`);let O=await Y.waitForTransactionReceipt({hash:w});if(O.status==="success")console.log(`โœ… Sent (block ${O.blockNumber})`);else throw Error("Transaction failed");return}let G=z7(J);console.log(`\uD83D\uDCB8 Sending ${J} ETH to ${H8($)} on Base...`);let K=await Z.sendTransaction({to:$,value:G});console.log(` TX: ${Z$(K)}`),console.log(` ${W$(K)}`);let V=await Y.waitForTransactionReceipt({hash:K});if(V.status==="success")console.log(`โœ… Sent (block ${V.blockNumber})`);else throw Error("Transaction failed")}async function Bq($){let J=B0(),[Q,X,Y]=await J.multicall({contracts:[{address:$,abi:r0,functionName:"symbol"},{address:$,abi:r0,functionName:"totalSupply"},{address:X0,abi:Y0,functionName:"tokenBond",args:[$]}]});if(Y.status==="failure")throw Error("Not a Mint Club token");let Z=Q.result??"Unknown",W=X.result??0n,[,,,,G,K]=Y.result,V=t0.find((N)=>N.address.toLowerCase()===G.toLowerCase()),q=V?.symbol??"RESERVE",D=V?.decimals??18;if(!V)try{let[N,H]=await J.multicall({contracts:[{address:G,abi:r0,functionName:"symbol"},{address:G,abi:[{type:"function",name:"decimals",stateMutability:"view",inputs:[],outputs:[{type:"uint8"}]}],functionName:"decimals"}]});if(N.status==="success")q=N.result;if(H.status==="success")D=H.result}catch{}if(console.log(`\uD83D\uDCB1 ${Z} (${$})
104
104
  `),W===0n){console.log(" No supply yet โ€” token has not been minted.");return}let[M]=await J.readContract({address:X0,abi:Y0,functionName:"getReserveForToken",args:[$,10n**BigInt(18)]}),w=y0(M,D);console.log(` Price: ${w} ${q}`);let O=await L8(G);if(O!==null){let N=Number(M)/10**D*O,H=(L)=>L<0.01?L.toExponential(2):L.toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:4});console.log(` Price (USD): $${H(N)}`),console.log(` Reserve: ${y0(K,D)} ${q} (~$${H(Number(K)/10**D*O)})`);let z=Number(W)/1000000000000000000*N;console.log(` Market Cap: ~$${H(z)}`)}else console.log(` Reserve: ${y0(K,D)} ${q}`),console.log(" โš ๏ธ Could not fetch USD price for reserve token")}import{resolve as kN}from"path";import{homedir as fN}from"os";m7.config({path:kN(fN(),".mintclub",".env")});m7.config();function EX(){let $=process.env.PRIVATE_KEY;if(!$)console.error("โŒ Set PRIVATE_KEY in ~/.mintclub/.env or export it"),process.exit(1);return $.startsWith("0x")?$:`0x${$}`}function qJ($){if($.toUpperCase()==="ETH")return"0x0000000000000000000000000000000000000000";if(!$.startsWith("0x")||$.length!==42)console.error("โŒ Invalid token address"),process.exit(1);return x$($)}function R8($){iV($.chain??"base")}function xN($){if(!($ instanceof Error))return String($);let J=$.message,Q=J.match(/insufficient funds.*have (\d+) want (\d+)/);if(Q)return`Insufficient funds: have ${(Number(Q[1])/1000000000000000000).toFixed(4)} ETH, need ${(Number(Q[2])/1000000000000000000).toFixed(4)} ETH`;let X=J.match(/reverted with the following reason:\s*\n?\s*(.+?)(?:\n|$)/);if(X&&X[1].trim())return`Transaction reverted: ${X[1].trim()}`;let Y=J.match(/execution reverted[:\s]*(.+?)(?:\n|$)/);if(Y)return`Transaction reverted: ${Y[1].trim()}`;let Z=J.match(/Details:\s*(.+?)(?:\n|$)/);if(Z)return Z[1].trim();return J.split(`
105
- `).find((W)=>W.trim().length>0)?.trim()??J}function uJ($){return async()=>{try{await $()}catch(J){console.error("โŒ",xN(J)),process.exit(1)}}}var u$=new Z4().name("mc").description("Mint Club V2 CLI โ€” bonding curve tokens on Base").version("1.3.4");u$.command("price").description("Get token price in reserve and USD").argument("<token>","Token address").action(($,J)=>uJ(()=>Bq(qJ($)))());u$.command("info").description("Get token info").argument("<token>","Token address or symbol").option("-c, --chain <chain>","Chain","base").action(($,J)=>uJ(()=>{return R8(J),$q(qJ($))})());u$.command("buy").description("Buy (mint) tokens with reserve token").argument("<token>","Token address or symbol").requiredOption("-a, --amount <n>","Tokens to buy").option("-m, --max-cost <n>","Max reserve cost").option("-c, --chain <chain>","Chain","base").action(($,J)=>uJ(()=>{return R8(J),Xq(qJ($),J.amount,J.maxCost,EX())})());u$.command("sell").description("Sell (burn) tokens for reserve token").argument("<token>","Token address or symbol").requiredOption("-a, --amount <n>","Tokens to sell").option("-m, --min-refund <n>","Min reserve refund").option("-c, --chain <chain>","Chain","base").action(($,J)=>uJ(()=>{return R8(J),Yq(qJ($),J.amount,J.minRefund,EX())})());u$.command("create").description("Create a bonding curve token").requiredOption("-n, --name <name>","Token name").requiredOption("-s, --symbol <sym>","Token symbol").requiredOption("-r, --reserve <addr>","Reserve token address").requiredOption("-x, --max-supply <n>","Max supply").option("-t, --steps <s>",'Custom steps: "range:price,range:price,..."').option("--curve <type>","Curve preset: linear, exponential, logarithmic, flat").option("--initial-price <n>","Starting price (with --curve)").option("--final-price <n>","Final price (with --curve)").option("--mint-royalty <bp>","Mint royalty (bps)","100").option("--burn-royalty <bp>","Burn royalty (bps)","100").option("-c, --chain <chain>","Chain","base").option("-y, --yes","Skip confirmation prompt").action(($)=>uJ(()=>{return R8($),Kq($.name,$.symbol,qJ($.reserve),$.maxSupply,EX(),{steps:$.steps,curve:$.curve,initialPrice:$.initialPrice,finalPrice:$.finalPrice,mintRoyalty:parseInt($.mintRoyalty),burnRoyalty:parseInt($.burnRoyalty),yes:$.yes})})());u$.command("zap-buy").description("Buy tokens with any token via ZapV2 (auto-routes swap)").argument("<token>","Token address or symbol").requiredOption("-i, --input-token <addr>","Input token (ETH or address/symbol)").requiredOption("-a, --amount <n>","Amount of input token to spend (e.g. 0.01 ETH)").option("-p, --path <p>","Manual swap path: token,fee,token,...").option("-m, --min-tokens <n>","Min tokens out").option("-c, --chain <chain>","Chain","base").action(($,J)=>uJ(()=>{return R8(J),Nq(qJ($),qJ(J.inputToken),J.amount,J.minTokens,J.path,EX())})());u$.command("zap-sell").description("Sell tokens for any token via ZapV2 (auto-routes swap)").argument("<token>","Token address or symbol").requiredOption("-a, --amount <n>","Tokens to sell").requiredOption("-o, --output-token <addr>","Output token (ETH or address/symbol)").option("-p, --path <p>","Manual swap path: token,fee,token,...").option("-m, --min-output <n>","Min output").option("-c, --chain <chain>","Chain","base").action(($,J)=>uJ(()=>{return R8(J),zq(qJ($),J.amount,qJ(J.outputToken),J.minOutput,J.path,EX())})());u$.command("send").description("Send ETH, ERC-20, or ERC-1155 tokens").argument("<to>","Recipient address").requiredOption("-a, --amount <n>","Amount to send").option("-t, --token <addr>","Token contract (omit for ETH)").option("--token-id <id>","ERC-1155 token ID").option("-c, --chain <chain>","Chain","base").action(($,J)=>uJ(()=>{return R8(J),Rq($,J.amount,EX(),{token:J.token?qJ(J.token):void 0,tokenId:J.tokenId})})());u$.command("wallet").description("Show wallet address and balances, or generate/import a key").option("-g, --generate","Generate a new wallet").option("-s, --set-private-key <key>","Import an existing private key").option("-c, --chain <chain>","Chain","base").action(($)=>uJ(()=>{return R8($),Sq($)})());u$.command("upgrade").description("Upgrade mint.club-cli to the latest version").action(()=>{let{execSync:$}=p$("child_process");console.log("โฌ†๏ธ Upgrading mint.club-cli...");try{let J=$("mc --version",{encoding:"utf-8"}).trim();$("npm install -g mint.club-cli@latest",{stdio:"pipe"});let Q=$("mc --version",{encoding:"utf-8"}).trim();console.log(J===Q?`โœ… Already on latest (v${Q})`:`โœ… Upgraded: v${J} โ†’ v${Q}`)}catch{console.error("โŒ Upgrade failed. Try: npm update -g mint.club-cli"),process.exit(1)}});u$.parse();
105
+ `).find((W)=>W.trim().length>0)?.trim()??J}function uJ($){return async()=>{try{await $()}catch(J){console.error("โŒ",xN(J)),process.exit(1)}}}var u$=new Z4().name("mc").description("Mint Club V2 CLI โ€” bonding curve tokens on Base").version("1.3.6");u$.command("price").description("Get token price in reserve and USD").argument("<token>","Token address").action(($,J)=>uJ(()=>Bq(qJ($)))());u$.command("info").description("Get token info").argument("<token>","Token address or symbol").option("-c, --chain <chain>","Chain","base").action(($,J)=>uJ(()=>{return R8(J),$q(qJ($))})());u$.command("buy").description("Buy (mint) tokens with reserve token").argument("<token>","Token address or symbol").requiredOption("-a, --amount <n>","Tokens to buy").option("-m, --max-cost <n>","Max reserve cost").option("-c, --chain <chain>","Chain","base").action(($,J)=>uJ(()=>{return R8(J),Xq(qJ($),J.amount,J.maxCost,EX())})());u$.command("sell").description("Sell (burn) tokens for reserve token").argument("<token>","Token address or symbol").requiredOption("-a, --amount <n>","Tokens to sell").option("-m, --min-refund <n>","Min reserve refund").option("-c, --chain <chain>","Chain","base").action(($,J)=>uJ(()=>{return R8(J),Yq(qJ($),J.amount,J.minRefund,EX())})());u$.command("create").description("Create a bonding curve token").requiredOption("-n, --name <name>","Token name").requiredOption("-s, --symbol <sym>","Token symbol").requiredOption("-r, --reserve <addr>","Reserve token address").requiredOption("-x, --max-supply <n>","Max supply").option("-t, --steps <s>",'Custom steps: "range:price,range:price,..."').option("--curve <type>","Curve preset: linear, exponential, logarithmic, flat").option("--initial-price <n>","Starting price (with --curve)").option("--final-price <n>","Final price (with --curve)").option("--mint-royalty <bp>","Mint royalty (bps)","100").option("--burn-royalty <bp>","Burn royalty (bps)","100").option("-c, --chain <chain>","Chain","base").option("-y, --yes","Skip confirmation prompt").action(($)=>uJ(()=>{return R8($),Kq($.name,$.symbol,qJ($.reserve),$.maxSupply,EX(),{steps:$.steps,curve:$.curve,initialPrice:$.initialPrice,finalPrice:$.finalPrice,mintRoyalty:parseInt($.mintRoyalty),burnRoyalty:parseInt($.burnRoyalty),yes:$.yes})})());u$.command("zap-buy").description("Buy tokens with any token via ZapV2 (auto-routes swap)").argument("<token>","Token address or symbol").requiredOption("-i, --input-token <addr>","Input token (ETH or address/symbol)").requiredOption("-a, --amount <n>","Amount of input token to spend (e.g. 0.01 ETH)").option("-p, --path <p>","Manual swap path: token,fee,token,...").option("-m, --min-tokens <n>","Min tokens out").option("-c, --chain <chain>","Chain","base").action(($,J)=>uJ(()=>{return R8(J),Nq(qJ($),qJ(J.inputToken),J.amount,J.minTokens,J.path,EX())})());u$.command("zap-sell").description("Sell tokens for any token via ZapV2 (auto-routes swap)").argument("<token>","Token address or symbol").requiredOption("-a, --amount <n>","Tokens to sell").requiredOption("-o, --output-token <addr>","Output token (ETH or address/symbol)").option("-p, --path <p>","Manual swap path: token,fee,token,...").option("-m, --min-output <n>","Min output").option("-c, --chain <chain>","Chain","base").action(($,J)=>uJ(()=>{return R8(J),zq(qJ($),J.amount,qJ(J.outputToken),J.minOutput,J.path,EX())})());u$.command("send").description("Send ETH, ERC-20, or ERC-1155 tokens").argument("<to>","Recipient address").requiredOption("-a, --amount <n>","Amount to send").option("-t, --token <addr>","Token contract (omit for ETH)").option("--token-id <id>","ERC-1155 token ID").option("-c, --chain <chain>","Chain","base").action(($,J)=>uJ(()=>{return R8(J),Rq($,J.amount,EX(),{token:J.token?qJ(J.token):void 0,tokenId:J.tokenId})})());u$.command("wallet").description("Show wallet address and balances, or generate/import a key").option("-g, --generate","Generate a new wallet").option("-s, --set-private-key <key>","Import an existing private key").option("-c, --chain <chain>","Chain","base").action(($)=>uJ(()=>{return R8($),Sq($)})());u$.command("upgrade").description("Upgrade mint.club-cli to the latest version").action(()=>{let{execSync:$}=p$("child_process");console.log("โฌ†๏ธ Upgrading mint.club-cli...");try{let J=$("mc --version",{encoding:"utf-8"}).trim();$("npm install -g mint.club-cli@latest",{stdio:"pipe"});let Q=$("mc --version",{encoding:"utf-8"}).trim();console.log(J===Q?`โœ… Already on latest (v${Q})`:`โœ… Upgraded: v${J} โ†’ v${Q}`)}catch{console.error("โŒ Upgrade failed. Try: npm update -g mint.club-cli"),process.exit(1)}});u$.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mint.club-cli",
3
- "version": "1.3.4",
3
+ "version": "1.3.6",
4
4
  "description": "CLI for Mint Club V2 bonding curve tokens",
5
5
  "main": "dist/index.js",
6
6
  "files": [
@@ -15,7 +15,8 @@
15
15
  "build": "bash build.sh",
16
16
  "prepublishOnly": "bash build.sh",
17
17
  "start": "bun src/index.ts",
18
- "check": "tsc --noEmit"
18
+ "check": "tsc --noEmit",
19
+ "test": "npx vitest run test/cli.test.ts"
19
20
  },
20
21
  "keywords": [
21
22
  "mint",
@@ -34,7 +35,8 @@
34
35
  },
35
36
  "devDependencies": {
36
37
  "@types/node": "^22.10.2",
37
- "typescript": "^5.7.3"
38
+ "typescript": "^5.7.3",
39
+ "vitest": "^4.0.18"
38
40
  },
39
41
  "engines": {
40
42
  "node": ">=18.0.0"