@mint.club/v2-cli 2.0.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 ADDED
@@ -0,0 +1,255 @@
1
+ # Mint Club V2 CLI
2
+
3
+ A command-line client for protocol-native [Mint Club V2](https://mint.club) operations and bounded local Uniswap routing across ten mainnets and two testnets.
4
+
5
+ [npm package](https://www.npmjs.com/package/@mint.club/v2-cli) · [repository](https://github.com/Steemhunt/mint.club-v2-ai) · [MCP server](../mcp) · [ElizaOS plugin](../eliza-plugin)
6
+
7
+ The CLI calls the official contracts directly:
8
+
9
+ - `MCV2_Bond.mint` / `burn` for reserve-token trades
10
+ - `MCV2_ZapV2.zapMint` / `zapBurn` for routed exact-input trades
11
+ - `MCV2_Bond.createToken` for ERC-20 token creation
12
+
13
+ It does **not** provide a general-purpose DEX swap command or use an external routing API.
14
+
15
+ ## Install
16
+
17
+ ```bash
18
+ npm install -g @mint.club/v2-cli
19
+ mc --help
20
+ ```
21
+
22
+ Requires Node.js 18 or later. The installed executable is `mc`.
23
+
24
+ ## Wallet setup
25
+
26
+ ```bash
27
+ mc wallet --generate
28
+ ```
29
+
30
+ Generated keys are stored in `~/.mintclub/.env` with file mode `0600`; the directory is locked to `0700`. To use an existing key, provide `PRIVATE_KEY` through a trusted secret manager or place it in that file yourself with the same permissions. The CLI also loads `.env` from the current directory.
31
+
32
+ > Never put a private key in a command argument, commit it, or paste it into an agent conversation. Use a dedicated wallet with limited funds.
33
+
34
+ ## Chain selection
35
+
36
+ Base is the default. Put the global chain option before the command:
37
+
38
+ ```bash
39
+ mc --chain base info SIGNET
40
+ mc --chain arbitrum info 0xTOKEN
41
+ mc --chain robinhood wallet
42
+ ```
43
+
44
+ | Chain | CLI key | Chain ID | Known symbols |
45
+ |---|---|---:|---|
46
+ | Ethereum | `ethereum` | 1 | `ETH`, `WETH`, `USDC`, `USDT`, `DAI` |
47
+ | Optimism | `optimism` | 10 | `ETH`, `WETH`, `USDT` |
48
+ | Arbitrum One | `arbitrum` | 42161 | `ETH`, `WETH`, `USDT` |
49
+ | Avalanche C-Chain | `avalanche` | 43114 | `AVAX`, `WAVAX`, `USDT` |
50
+ | Base | `base` | 8453 | `ETH`, `WETH`, `USDC`, `HUNT`, `MT` |
51
+ | Polygon PoS | `polygon` | 137 | `POL`, `WPOL`, `USDT` |
52
+ | BNB Smart Chain | `bsc` | 56 | `BNB`, `WBNB`, `USDT` |
53
+ | Zora | `zora` | 7777777 | `ETH`, `WETH` |
54
+ | Unichain | `unichain` | 130 | `ETH`, `WETH`, `USDC` |
55
+ | Robinhood Chain | `robinhood` | 4663 | `ETH`, `WETH`, `USDG` |
56
+ | Sepolia | `sepolia` | 11155111 | `ETH`, `WETH` |
57
+ | Base Sepolia | `base-sepolia` | 84532 | `ETH`, `WETH` |
58
+
59
+ `NATIVE` resolves to the selected chain's native currency. Any ERC-20 or Mint Club token can also be supplied by contract address. Created and successfully transacted Mint Club token addresses are tracked per chain in `~/.mintclub/tokens.json`.
60
+
61
+ The published [`chain-registry.json`](./chain-registry.json) is consumed by the CLI, MCP server, and Eliza plugin. The CLI validates its IDs and capability flags against the full runtime configuration at startup.
62
+
63
+ ### RPC overrides
64
+
65
+ Each chain has public fallback RPC URLs. Override the first RPC without editing source:
66
+
67
+ ```bash
68
+ export MINTCLUB_RPC_ARBITRUM=https://your-rpc.example
69
+ export MINTCLUB_RPC_ROBINHOOD=https://your-rpc.example
70
+ export MINTCLUB_RPC_BASE_SEPOLIA=https://your-rpc.example
71
+ ```
72
+
73
+ The variable format is `MINTCLUB_RPC_<UPPERCASE_CLI_KEY>`, with non-alphanumeric separators replaced by underscores (`base-sepolia` becomes `BASE_SEPOLIA`).
74
+
75
+ ## Read operations
76
+
77
+ ```bash
78
+ mc --chain base info SIGNET
79
+ mc --chain ethereum price 0xTOKEN
80
+ mc --chain robinhood wallet
81
+ ```
82
+
83
+ USD pricing uses chain-specific DefiLlama feeds where available. This is independent of routing; route quotes use RPC calls only.
84
+
85
+ ## Bond mint and burn
86
+
87
+ Use these commands when paying or receiving the token's configured reserve ERC-20.
88
+
89
+ ```bash
90
+ # Mint an exact Mint Club token amount
91
+ mc --chain base buy SIGNET --amount 100
92
+ mc --chain arbitrum buy 0xTOKEN --amount 100 --max-cost 25
93
+
94
+ # Burn an exact Mint Club token amount
95
+ mc --chain base sell SIGNET --amount 100
96
+ mc --chain arbitrum sell 0xTOKEN --amount 100 --min-refund 20
97
+ ```
98
+
99
+ `--max-cost` and `--min-refund` are denominated in the reserve token and respect its on-chain decimals. If omitted, the current quote is used as the exact on-chain limit; provide an explicit limit to tolerate price movement before inclusion.
100
+
101
+ The Mint Club token may use the ERC-20 or ERC-1155 implementation. ERC-1155 Mint Club tokens have zero decimals, so their `--amount` must be a whole number.
102
+
103
+ ## ZapV2 routed mint and burn
104
+
105
+ ### Mint from an exact input amount
106
+
107
+ ```bash
108
+ mc --chain arbitrum zap-buy 0xMINT_CLUB_TOKEN \
109
+ --input-token USDT \
110
+ --input-amount 10 \
111
+ --slippage 1
112
+
113
+ mc --chain base zap-buy SIGNET \
114
+ --input-token 0xARBITRARY_ERC20 \
115
+ --input-amount 250 \
116
+ --min-tokens 100 \
117
+ --slippage 0.5
118
+ ```
119
+
120
+ `--input-amount` is exact. If `--min-tokens` is omitted, the CLI performs a read-only `zapMint` preview with zero token minimum, applies the requested slippage to the preview result, and simulates the final protected call before sending.
121
+
122
+ Native input is supported with `--input-token NATIVE` (or the native symbol such as `ETH`, `AVAX`, `POL`, or `BNB`). Routed input assets must be native currency or ERC-20 tokens; the Mint Club token being minted may be ERC-20 or ERC-1155. ERC-20 input is approved to ZapV2 only after an executable route has been found.
123
+
124
+ ### Burn an exact Mint Club token amount
125
+
126
+ ```bash
127
+ mc --chain unichain zap-sell 0xMINT_CLUB_TOKEN \
128
+ --amount 100 \
129
+ --output-token USDC \
130
+ --slippage 1
131
+
132
+ mc --chain robinhood zap-sell 0xMINT_CLUB_TOKEN \
133
+ --amount 100 \
134
+ --output-token NATIVE \
135
+ --min-output 0.02
136
+ ```
137
+
138
+ `--amount` is the exact Mint Club token amount to burn. The target may be an ERC-20 or ERC-1155 Mint Club token; use whole-number amounts for ERC-1155. The routed output must be native currency or an ERC-20 token. If `--min-output` is omitted, the selected route quote is reduced by the requested slippage. When the reserve token already equals the requested output token, no router command is emitted and the exact burn refund becomes the default minimum.
139
+
140
+ ### Deployment status
141
+
142
+ `MCV2_ZapV2` is deployed on all supported chains in this document. Blast is intentionally unsupported by this integration.
143
+
144
+ ## Local route discovery
145
+
146
+ The route engine:
147
+
148
+ 1. Enumerates a direct path and paths through at most one configured wrapped-native or stablecoin intermediary.
149
+ 2. Quotes homogeneous Uniswap V2, V3, and V4 paths by RPC where configured for the selected chain.
150
+ 3. Computes V2 output from factory/pair reserves, calls Quoter/QuoterV2 for V3, and calls V4Quoter for V4.
151
+ 4. Ignores expected missing-pool reverts independently, but surfaces RPC/transport failures.
152
+ 5. Chooses the greatest exact-input output; ties prefer fewer hops and then `V2 → V3 → V4` deterministically.
153
+ 6. Uses `@uniswap/universal-router-sdk` only to encode the selected route.
154
+
155
+ Universal Router encoding is pinned to V2.0 command semantics, uses router-held input (`payerIsUser = false`), sends swap output to ZapV2, rejects Permit2 ingress commands, and settles unused routed input directly back to the caller. Native V2/V3 refunds are unwrapped before delivery.
156
+
157
+ Deliberate limits:
158
+
159
+ - no split routes;
160
+ - no mixed-protocol path;
161
+ - no path longer than one intermediary;
162
+ - no arbitrary liquidity-graph search;
163
+ - no V4 hooks or dynamic-fee pools;
164
+ - V4 discovery checks hookless `(fee, tick spacing)` pairs `(100,1)`, `(500,10)`, `(3000,60)`, and `(10000,200)` only.
165
+
166
+ The selected result is the best **among enumerated candidates**, not a claim of global optimality.
167
+
168
+ ## Create a token
169
+
170
+ ```bash
171
+ mc --chain robinhood create \
172
+ --name "My Token" \
173
+ --symbol MYT \
174
+ --reserve USDG \
175
+ --max-supply 1000000 \
176
+ --curve exponential \
177
+ --initial-price 0.01 \
178
+ --final-price 10
179
+ ```
180
+
181
+ Curve presets: `linear`, `exponential`, `logarithmic`, and `flat`.
182
+
183
+ For a custom curve:
184
+
185
+ ```bash
186
+ mc --chain base create \
187
+ --name "My Token" \
188
+ --symbol MYT \
189
+ --reserve USDC \
190
+ --max-supply 1000000 \
191
+ --steps "100000:0.01,500000:0.05,1000000:0.1"
192
+ ```
193
+
194
+ Prices are encoded using the reserve token's actual decimals. Non-flat presets require the final price to exceed the initial price and automatically reduce the nominal 500 steps when reserve precision cannot represent 500 strictly increasing prices.
195
+
196
+ `create` deploys the configured ERC-20 implementation. Mint and burn royalties default to 100 basis points (1%) each; set them explicitly with `--mint-royalty` and `--burn-royalty` when different values are intended.
197
+
198
+ ## Transfer and balances
199
+
200
+ ```bash
201
+ mc --chain avalanche send 0xRECIPIENT --amount 0.01
202
+ mc --chain robinhood send 0xRECIPIENT --amount 100 --token USDG
203
+ mc --chain base send 0xRECIPIENT --amount 3 \
204
+ --token 0xERC1155_CONTRACT \
205
+ --token-id 0
206
+ mc --chain polygon wallet
207
+ ```
208
+
209
+ Native and ERC-20 amounts use their token decimals. ERC-1155 `--amount` is an integer quantity and requires both the contract address and `--token-id`.
210
+
211
+ ## Mint Club contract configuration
212
+
213
+ | Chain | MCV2 Bond | ERC-20 implementation | MCV2 ZapV2 |
214
+ |---|---|---|---|
215
+ | Ethereum | `0xc5a076cad94176c2996B32d8466Be1cE757FAa27` | `0xAa70bC79fD1cB4a6FBA717018351F0C3c64B79Df` | `0xf7e2cDe9E603F15118E6E389cF14f11f19C1afbc` |
216
+ | Optimism | `0xc5a076cad94176c2996B32d8466Be1cE757FAa27` | `0xAa70bC79fD1cB4a6FBA717018351F0C3c64B79Df` | `0x7B09b728ee8c6a714dC3F10367b5DF9b217FE633` |
217
+ | Arbitrum One | `0xc5a076cad94176c2996B32d8466Be1cE757FAa27` | `0xAa70bC79fD1cB4a6FBA717018351F0C3c64B79Df` | `0x3a8a4BFCC487d0FE9D342B6180bf0323989f251B` |
218
+ | Avalanche C-Chain | `0x3Fd5B4DcDa968C8e22898523f5343177F94ccfd1` | `0x5DaE94e149CF2112Ec625D46670047814aA9aC2a` | `0xD0586d5F4ae18650340fFc6f3b1307AB2Ca334f4` |
219
+ | Base | `0xc5a076cad94176c2996B32d8466Be1cE757FAa27` | `0xAa70bC79fD1cB4a6FBA717018351F0C3c64B79Df` | `0x96282046C0e19F727a92728198c0Dc4E260Ebe0b` |
220
+ | Polygon PoS | `0xc5a076cad94176c2996B32d8466Be1cE757FAa27` | `0xAa70bC79fD1cB4a6FBA717018351F0C3c64B79Df` | `0x664f626516c82772F0F492Ff64f6FA826C86F5e1` |
221
+ | BNB Smart Chain | `0xc5a076cad94176c2996B32d8466Be1cE757FAa27` | `0xAa70bC79fD1cB4a6FBA717018351F0C3c64B79Df` | `0x68f54a53d3E69e2191bCF586fB507c81E5353413` |
222
+ | Zora | `0xc5a076cad94176c2996B32d8466Be1cE757FAa27` | `0xAa70bC79fD1cB4a6FBA717018351F0C3c64B79Df` | `0x5b64cECC5cF3E4B1A668Abd895D16BdDC0c77a17` |
223
+ | Unichain | `0xc5a076cad94176c2996B32d8466Be1cE757FAa27` | `0xAa70bC79fD1cB4a6FBA717018351F0C3c64B79Df` | `0x06FD26c092Db44E5491abB7cDC580CE24D93030c` |
224
+ | Robinhood Chain | `0x91523b39813F3F4E406ECe406D0bEAaA9dE251fa` | `0xEb54dACB4C2ccb64F8074eceEa33b5eBb38E5387` | `0x621c335b4BD8f2165E120DC70d3AfcAfc6628681` |
225
+ | Sepolia | `0x8dce343A86Aa950d539eeE0e166AFfd0Ef515C0c` | `0x749bA94344521727f55a3007c777FbeB5F52C2Eb` | `0x69c94AF858FeCA41f97ff7888e3B5104b95D66D9` |
226
+ | Base Sepolia | `0x5dfA75b0185efBaEF286E80B847ce84ff8a62C2d` | `0x37F540de37afE8bDf6C722d87CB019F30e5E406a` | `0x60432191893c4F742205a2C834817a1891feC435` |
227
+
228
+ Uniswap factory/quoter addresses and intermediary tokens are kept in `src/config/chains.ts` and capability summaries in `chain-registry.json`.
229
+
230
+ ## Development
231
+
232
+ From the repository root:
233
+
234
+ ```bash
235
+ npm ci
236
+ npm run check
237
+ npm test
238
+ npm run test:integration
239
+ npm run test:fork
240
+ npm run build
241
+ ```
242
+
243
+ The default suite runs without external RPC dependencies. `npm run test:integration` runs the gated, read-only deployment and immutable checks on all supported networks.
244
+
245
+ `npm run test:fork` is an explicit, deterministic Base fork suite pinned to block `48,705,797`. It exercises direct Bond writes plus ZapV2 native/WETH, ERC-20, ERC-1155, routed buy/sell, and refund-sweep flows without changing live chain state.
246
+
247
+ The fork suite requires Anvil. It resolves `ANVIL_PATH` first and then `anvil` from `PATH`; an explicit run fails if neither is available. Override the public Base RPC when needed:
248
+
249
+ ```bash
250
+ BASE_FORK_RPC_URL=https://your-archive-base-rpc.example npm run test:fork
251
+ ```
252
+
253
+ ## License
254
+
255
+ MIT
package/build.sh ADDED
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ if command -v bun >/dev/null 2>&1; then
5
+ BUN_BIN="$(command -v bun)"
6
+ elif [[ -x "$HOME/.bun/bin/bun" ]]; then
7
+ BUN_BIN="$HOME/.bun/bin/bun"
8
+ elif [[ -x "./node_modules/.bin/bun" ]]; then
9
+ BUN_BIN="./node_modules/.bin/bun"
10
+ else
11
+ echo "bun executable not found; run npm ci from the repository root" >&2
12
+ exit 1
13
+ fi
14
+
15
+ rm -rf dist
16
+ "$BUN_BIN" build src/index.ts \
17
+ --outdir dist \
18
+ --target node \
19
+ --packages bundle \
20
+ --define "__VERSION__=\"$(node -p "require('./package.json').version")\""
@@ -0,0 +1,190 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "chains": [
4
+ {
5
+ "key": "ethereum",
6
+ "name": "Ethereum",
7
+ "chainId": 1,
8
+ "nativeSymbol": "ETH",
9
+ "aliases": ["ethereum mainnet", "ethereum", "mainnet", "eth"],
10
+ "capabilities": {
11
+ "bond": true,
12
+ "zapV2Configured": true,
13
+ "uniswapV2": true,
14
+ "uniswapV3": true,
15
+ "uniswapV4": true,
16
+ "stableIntermediary": true
17
+ }
18
+ },
19
+ {
20
+ "key": "optimism",
21
+ "name": "Optimism",
22
+ "chainId": 10,
23
+ "nativeSymbol": "ETH",
24
+ "aliases": ["optimism mainnet", "optimism", "op mainnet", "op"],
25
+ "capabilities": {
26
+ "bond": true,
27
+ "zapV2Configured": true,
28
+ "uniswapV2": true,
29
+ "uniswapV3": true,
30
+ "uniswapV4": true,
31
+ "stableIntermediary": true
32
+ }
33
+ },
34
+ {
35
+ "key": "arbitrum",
36
+ "name": "Arbitrum One",
37
+ "chainId": 42161,
38
+ "nativeSymbol": "ETH",
39
+ "aliases": ["arbitrum one", "arbitrum", "arb"],
40
+ "capabilities": {
41
+ "bond": true,
42
+ "zapV2Configured": true,
43
+ "uniswapV2": true,
44
+ "uniswapV3": true,
45
+ "uniswapV4": true,
46
+ "stableIntermediary": true
47
+ }
48
+ },
49
+ {
50
+ "key": "avalanche",
51
+ "name": "Avalanche C-Chain",
52
+ "chainId": 43114,
53
+ "nativeSymbol": "AVAX",
54
+ "aliases": ["avalanche c-chain", "avalanche", "avax c-chain", "avax"],
55
+ "capabilities": {
56
+ "bond": true,
57
+ "zapV2Configured": true,
58
+ "uniswapV2": true,
59
+ "uniswapV3": true,
60
+ "uniswapV4": true,
61
+ "stableIntermediary": true
62
+ }
63
+ },
64
+ {
65
+ "key": "base",
66
+ "name": "Base",
67
+ "chainId": 8453,
68
+ "nativeSymbol": "ETH",
69
+ "aliases": ["base mainnet", "base"],
70
+ "capabilities": {
71
+ "bond": true,
72
+ "zapV2Configured": true,
73
+ "uniswapV2": true,
74
+ "uniswapV3": true,
75
+ "uniswapV4": true,
76
+ "stableIntermediary": true
77
+ }
78
+ },
79
+ {
80
+ "key": "polygon",
81
+ "name": "Polygon PoS",
82
+ "chainId": 137,
83
+ "nativeSymbol": "POL",
84
+ "aliases": ["polygon pos", "polygon", "matic"],
85
+ "capabilities": {
86
+ "bond": true,
87
+ "zapV2Configured": true,
88
+ "uniswapV2": true,
89
+ "uniswapV3": true,
90
+ "uniswapV4": true,
91
+ "stableIntermediary": true
92
+ }
93
+ },
94
+ {
95
+ "key": "bsc",
96
+ "name": "BNB Smart Chain",
97
+ "chainId": 56,
98
+ "nativeSymbol": "BNB",
99
+ "aliases": ["binance smart chain", "bnb chain", "bsc", "bnb", "binance"],
100
+ "capabilities": {
101
+ "bond": true,
102
+ "zapV2Configured": true,
103
+ "uniswapV2": true,
104
+ "uniswapV3": true,
105
+ "uniswapV4": true,
106
+ "stableIntermediary": true
107
+ }
108
+ },
109
+ {
110
+ "key": "zora",
111
+ "name": "Zora",
112
+ "chainId": 7777777,
113
+ "nativeSymbol": "ETH",
114
+ "aliases": ["zora"],
115
+ "capabilities": {
116
+ "bond": true,
117
+ "zapV2Configured": true,
118
+ "uniswapV2": true,
119
+ "uniswapV3": true,
120
+ "uniswapV4": true,
121
+ "stableIntermediary": false
122
+ }
123
+ },
124
+ {
125
+ "key": "unichain",
126
+ "name": "Unichain",
127
+ "chainId": 130,
128
+ "nativeSymbol": "ETH",
129
+ "aliases": ["unichain"],
130
+ "capabilities": {
131
+ "bond": true,
132
+ "zapV2Configured": true,
133
+ "uniswapV2": true,
134
+ "uniswapV3": true,
135
+ "uniswapV4": true,
136
+ "stableIntermediary": true
137
+ }
138
+ },
139
+ {
140
+ "key": "robinhood",
141
+ "name": "Robinhood Chain",
142
+ "chainId": 4663,
143
+ "nativeSymbol": "ETH",
144
+ "aliases": ["robinhood chain", "robinhood", "rh"],
145
+ "capabilities": {
146
+ "bond": true,
147
+ "zapV2Configured": true,
148
+ "uniswapV2": true,
149
+ "uniswapV3": true,
150
+ "uniswapV4": true,
151
+ "stableIntermediary": true
152
+ }
153
+ },
154
+ {
155
+ "key": "sepolia",
156
+ "name": "Sepolia",
157
+ "chainId": 11155111,
158
+ "nativeSymbol": "ETH",
159
+ "aliases": ["ethereum sepolia", "sepolia"],
160
+ "capabilities": {
161
+ "bond": true,
162
+ "zapV2Configured": true,
163
+ "uniswapV2": true,
164
+ "uniswapV3": true,
165
+ "uniswapV4": true,
166
+ "stableIntermediary": false
167
+ }
168
+ },
169
+ {
170
+ "key": "base-sepolia",
171
+ "name": "Base Sepolia",
172
+ "chainId": 84532,
173
+ "nativeSymbol": "ETH",
174
+ "aliases": [
175
+ "base sepolia",
176
+ "basesepolia",
177
+ "base testnet",
178
+ "base sepolia testnet"
179
+ ],
180
+ "capabilities": {
181
+ "bond": true,
182
+ "zapV2Configured": true,
183
+ "uniswapV2": false,
184
+ "uniswapV3": true,
185
+ "uniswapV4": true,
186
+ "stableIntermediary": false
187
+ }
188
+ }
189
+ ]
190
+ }