@rareprotocol/rare-cli 0.4.1 → 1.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 CHANGED
@@ -4,6 +4,8 @@ Command-line tool for the [RARE Protocol](https://superrare.com) on Ethereum. De
4
4
 
5
5
  ## Install
6
6
 
7
+ Requires Node.js 22+.
8
+
7
9
  ```bash
8
10
  npm install -g @rareprotocol/rare-cli
9
11
  ```
@@ -16,6 +18,8 @@ Verify installation:
16
18
  rare --help
17
19
  ```
18
20
 
21
+ See [CHANGELOG.md](./CHANGELOG.md) for release notes and migration guidance.
22
+
19
23
  ## Getting Started
20
24
 
21
25
  All examples below assume you installed the CLI globally and are running `rare` directly.
@@ -30,6 +34,14 @@ rare configure --chain sepolia --private-key 0xYourPrivateKeyHere
30
34
 
31
35
  > **Security note:** Your private key is stored in plaintext at `~/.rare/config.json`. Keep this file secure and never commit it to version control.
32
36
 
37
+ Or store the private key in 1Password and configure rare with a secret reference:
38
+
39
+ ```bash
40
+ rare configure --chain sepolia --private-key-ref op://Private/rare-sepolia/private-key
41
+ ```
42
+
43
+ The CLI runs `op read` once during configuration to derive and store the public wallet address. Later, it resolves the 1Password secret only when viem signs a message or transaction. The plaintext private key is never written to `~/.rare/config.json`.
44
+
33
45
  Or generate a new wallet:
34
46
 
35
47
  ```bash
@@ -56,6 +68,8 @@ You can set both at once:
56
68
 
57
69
  ```bash
58
70
  rare configure --chain sepolia --private-key 0x... --rpc-url https://your-rpc-endpoint.com
71
+ # or, without storing the key in plaintext:
72
+ rare configure --chain sepolia --private-key-ref op://Private/rare-sepolia/private-key --rpc-url https://your-rpc-endpoint.com
59
73
  ```
60
74
 
61
75
  ### 3. View your config
@@ -64,19 +78,106 @@ rare configure --chain sepolia --private-key 0x... --rpc-url https://your-rpc-en
64
78
  rare configure --show
65
79
  ```
66
80
 
67
- Private keys are masked in the output.
81
+ Private keys are masked in the output. Configured account addresses are shown.
68
82
 
69
83
  ## Usage
70
84
 
71
- All commands accept `--chain` to select a network. Defaults to `sepolia`.
85
+ Most chain-aware commands accept `--chain` or `--chain-id` to select a network. Defaults to the configured default chain, or `sepolia` when no default is configured.
86
+
87
+ Supported chains: `mainnet`, `sepolia`, `base`, `base-sepolia`
72
88
 
73
- Supported chains (including deploy, mint, import, and auction flows): `mainnet`, `sepolia`, `base`, `base-sepolia`
89
+ Feature deployment varies by chain. Batch listing, batch offer, RareMinter release, Liquid Edition, and swap flows are currently available on `mainnet` and `sepolia`; batch auction addresses are also configured for `base` and `base-sepolia`.
74
90
 
75
91
  ### Deploy an NFT Collection
76
92
 
77
93
  ```bash
78
- rare deploy erc721 "My Collection" "MC"
79
- rare deploy erc721 "My Collection" "MC" --max-tokens 1000
94
+ rare collection deploy erc721 "My Collection" "MC"
95
+ rare collection deploy erc721 "My Collection" "MC" --max-tokens 1000
96
+ ```
97
+
98
+ ### Deploy a Lazy ERC-721 Collection
99
+
100
+ For RareMinter release flows, deploy a Lazy ERC-721 collection. Buyers mint sequential token IDs through release sale settings.
101
+
102
+ ```bash
103
+ rare collection deploy lazy-erc721 "My Release" "MR" --max-tokens 1000
104
+ rare collection deploy lazy-erc721 "Guarded Release" "GR" --max-tokens 1000 --contract-type lazy-royalty-guard
105
+ ```
106
+
107
+ ### Deploy a Lazy Batch Mint Collection
108
+
109
+ For lazy minting flows, use the lazy batch mint factory instead. Tokens in a lazy collection aren't pre-minted — they're prepared and claimed/redeemed by buyers later.
110
+
111
+ ```bash
112
+ # Uncapped lazy collection (typical — leaves room for incremental lazy mints)
113
+ rare collection deploy lazy-batch-mint "My Lazy Collection" "MLC"
114
+
115
+ # Capped lazy collection (immutable supply ceiling)
116
+ rare collection deploy lazy-batch-mint "My Lazy Collection" "MLC" --max-tokens 100
117
+ ```
118
+
119
+ **Lazy vs standard batch mint**:
120
+
121
+ - `rare collection deploy erc721` deploys a SovereignBatchMint contract — tokens are minted directly via `rare collection mint` in the same tx as their creation. Use this for traditional editions where the artist mints up front.
122
+ - `rare collection deploy lazy-erc721` deploys a LazySovereignNFT contract — designed for RareMinter direct sale releases where buyers mint sequential token IDs.
123
+ - `rare collection deploy lazy-batch-mint` deploys a LazySovereignBatchMint contract — designed to feed the lazy mint preparation/redemption pipeline. Use this when buyers (not the artist) trigger the on-chain mint at purchase time.
124
+
125
+ The Lazy Sovereign and Lazy Batch Mint factories are currently deployed on **mainnet** and **sepolia** only.
126
+
127
+ Batch mint an owned Sovereign collection by passing the metadata base URI. Token metadata resolves as `baseUri/tokenId.json` on supported contracts.
128
+
129
+ ```bash
130
+ rare collection mint-batch --contract 0x... --base-uri ipfs://... --amount 100
131
+ ```
132
+
133
+ Prepare a Lazy Sovereign collection for collector minting. Pass `--minter` when a separate release or minting contract should be approved to mint from the prepared batch.
134
+
135
+ ```bash
136
+ rare collection prepare-lazy-mint --contract 0x... --base-uri ipfs://... --amount 100
137
+ rare collection prepare-lazy-mint --contract 0x... --base-uri ipfs://... --amount 100 --minter 0x...
138
+ ```
139
+
140
+ Build token-list Merkle artifacts for offline proof checks and for batch offer and batch auction root inputs. CSV files should include contract and token ID columns such as `contract_address,token_id`; JSON files can be an array of `{ "contractAddress": "0x...", "tokenId": "1" }` objects or a generated artifact. Pass `--chain-id` or include a `chain_id` column when the artifact should carry chain context.
141
+
142
+ ```bash
143
+ rare utils tree build --input batch-tokens.csv --chain-id 11155111 --output batch-token-artifact.json
144
+ rare utils tree proof --input batch-token-artifact.json --contract 0x... --token-id 1 --output proof.json
145
+ rare utils tree verify --input batch-token-artifact.json --contract 0x... --token-id 1 --proof proof.json
146
+ ```
147
+
148
+ Batch token artifacts use `type: "rare-batch-token-list"` and include `root`, `count`, optional `chainId`, canonical sorted `tokens`, and per-token `entries` with leaves and proofs. Proof artifacts use `type: "rare-batch-token-proof"` and include `root`, `contractAddress`, `tokenId`, optional `chainId`, `leaf`, `proof`, and `valid`.
149
+
150
+ Inspect creator and royalty data on Sovereign-style collections:
151
+
152
+ ```bash
153
+ rare collection creator --contract 0x... --token-id 1
154
+ rare collection royalty status --contract 0x... --token-id 1
155
+ ```
156
+
157
+ Owner wallets can update royalty receivers on Sovereign and Lazy Sovereign collections:
158
+
159
+ ```bash
160
+ rare collection royalty set-default-receiver --contract 0x... --receiver 0x...
161
+ rare collection royalty set-token-receiver --contract 0x... --token-id 1 --receiver 0x...
162
+ ```
163
+
164
+ The legacy protocol `RoyaltyRegistry` is also available under `collection royalty registry`. By default, the CLI reads the registry address from the configured Rare marketplace contract; pass `--registry 0x...` to target a specific registry.
165
+
166
+ ```bash
167
+ rare collection royalty registry status --contract 0x... --token-id 1
168
+ rare collection royalty registry set-receiver-override --receiver 0x...
169
+ rare collection royalty registry set-contract-receiver --contract 0x... --receiver 0x...
170
+ rare collection royalty registry set-token-receiver --contract 0x... --token-id 1 --receiver 0x...
171
+ rare collection royalty registry set-contract-percentage --contract 0x... --percentage 10
172
+ ```
173
+
174
+ Lazy Sovereign collections support mutable prepared metadata until the owner locks it:
175
+
176
+ ```bash
177
+ rare collection metadata status --contract 0x...
178
+ rare collection metadata update-base-uri --contract 0x... --base-uri ipfs://...
179
+ rare collection metadata update-token-uri --contract 0x... --token-id 1 --token-uri ipfs://.../1.json
180
+ rare collection metadata lock-base-uri --contract 0x...
80
181
  ```
81
182
 
82
183
  ### Import an Existing Collection
@@ -98,7 +199,7 @@ rare import erc721 --contract 0x... --chain sepolia
98
199
  Upload local media to IPFS and mint in one step:
99
200
 
100
201
  ```bash
101
- rare mint \
202
+ rare collection mint \
102
203
  --contract 0x... \
103
204
  --name "My NFT" \
104
205
  --description "A description" \
@@ -108,13 +209,13 @@ rare mint \
108
209
  Or mint with a pre-built metadata URI:
109
210
 
110
211
  ```bash
111
- rare mint --contract 0x... --token-uri ipfs://Qm...
212
+ rare collection mint --contract 0x... --token-uri ipfs://Qm...
112
213
  ```
113
214
 
114
215
  Additional options:
115
216
 
116
217
  ```bash
117
- rare mint \
218
+ rare collection mint \
118
219
  --contract 0x... \
119
220
  --name "My NFT" \
120
221
  --description "A cool piece" \
@@ -126,6 +227,98 @@ rare mint \
126
227
  --royalty-receiver 0x...
127
228
  ```
128
229
 
230
+ ### Direct Sale Releases
231
+
232
+ After creating and preparing a lazy collection, configure its RareMinter direct sale:
233
+
234
+ ```bash
235
+ rare listing release configure \
236
+ --contract 0x... \
237
+ --price 0.1 \
238
+ --max-mints 5
239
+
240
+ # Optional payout splits. If omitted, 100% goes to the configured wallet.
241
+ rare listing release configure \
242
+ --contract 0x... \
243
+ --price 100 \
244
+ --currency rare \
245
+ --start-time 2026-06-01T16:00:00Z \
246
+ --max-mints 5 \
247
+ --split 0x...artist=80 \
248
+ --split 0x...collaborator=20
249
+
250
+ # Check release status (read-only)
251
+ rare listing release status --contract 0x...
252
+
253
+ # Include account-specific mint and transaction usage
254
+ rare listing release status --contract 0x... --account 0x...
255
+
256
+ # Mint from the configured direct sale release
257
+ rare listing release mint \
258
+ --contract 0x... \
259
+ --quantity 1
260
+
261
+ # Mint during an active allowlist window with a proof file
262
+ rare listing release allowlist proof \
263
+ --input ./allowlist-artifact.json \
264
+ --account 0x... \
265
+ --output ./proof.json
266
+
267
+ rare listing release mint \
268
+ --contract 0x... \
269
+ --quantity 2 \
270
+ --proof ./proof.json
271
+ ```
272
+
273
+ Release configuration uses `RareMinter.prepareMintDirectSale`. It does not mint or modify protocol-admin settings.
274
+ `--max-mints 0` disables the per-transaction mint cap. Nonzero values must be between 1 and 100.
275
+ Release minting uses `RareMinter.mintDirectSale`; the contract mints to the connected wallet.
276
+
277
+ #### Release allowlists and limits
278
+
279
+ Allowlists are two-step. First, build a reusable proof artifact from creator-provided wallet input. CSV files can put wallet addresses in the first column or use an `address`/`wallet` header. JSON files can be an array of address strings, an array of objects with `address` or `wallet`, or an object with `wallets`/`addresses`.
280
+
281
+ ```bash
282
+ rare listing release allowlist build \
283
+ --input ./allowlist.csv \
284
+ --output ./allowlist-artifact.json
285
+ ```
286
+
287
+ The artifact contains the locally reproducible Merkle root plus one proof per wallet. In the normal flow, `allowlist set --input` submits the artifact wallet list to the Rare API and configures the API-returned canonical root on-chain with the allowlist end time:
288
+
289
+ ```bash
290
+ rare listing release allowlist set \
291
+ --contract 0x... \
292
+ --input ./allowlist-artifact.json \
293
+ --end-time 2026-06-01T16:00:00Z
294
+
295
+ # Or bypass artifact registration and set a known root directly
296
+ rare listing release allowlist set \
297
+ --contract 0x... \
298
+ --root 0x... \
299
+ --end-time 1767283200
300
+
301
+ # Read a reusable proof for an account
302
+ rare listing release allowlist proof \
303
+ --input ./allowlist-artifact.json \
304
+ --account 0x...
305
+ ```
306
+
307
+ Rare listing release minting checks the configured on-chain root while the allowlist window is active. The proof artifact is the portable file that maps each wallet to the proof needed by a mint client or service. Keep the artifact alongside release operations; the chain stores only the root and end timestamp. Use `--root` only when you already have a root that should be configured directly instead of registering an artifact through the Rare API.
308
+
309
+ Creator-facing RareMinter limits are configured separately and verified after each write:
310
+
311
+ ```bash
312
+ # Per-wallet token count across the release; 0 disables it.
313
+ rare listing release limits set-mint --contract 0x... --limit 2
314
+
315
+ # Per-wallet mint transaction count; 0 disables it.
316
+ rare listing release limits set-tx --contract 0x... --limit 1
317
+
318
+ # Verify release config, allowlist, and limits.
319
+ rare listing release status --contract 0x... --account 0x...
320
+ ```
321
+
129
322
  ### Auctions
130
323
 
131
324
  ```bash
@@ -133,11 +326,22 @@ rare mint \
133
326
  rare auction create \
134
327
  --contract 0x... \
135
328
  --token-id 1 \
136
- --starting-price 0.1 \
137
- --duration 86400
329
+ --price 0.1 \
330
+ --end-time 1778586400
331
+
332
+ # Create a scheduled auction with explicit seller splits
333
+ rare auction create \
334
+ --contract 0x... \
335
+ --token-id 1 \
336
+ --type scheduled \
337
+ --start-time 1778500000 \
338
+ --price 0.1 \
339
+ --end-time 1778586400 \
340
+ --split 0x...artist=70 \
341
+ --split 0x...collaborator=30
138
342
 
139
343
  # Place a bid
140
- rare auction bid --contract 0x... --token-id 1 --amount 0.5
344
+ rare auction bid --contract 0x... --token-id 1 --price 0.5
141
345
 
142
346
  # Settle after the auction ends
143
347
  rare auction settle --contract 0x... --token-id 1
@@ -149,17 +353,23 @@ rare auction cancel --contract 0x... --token-id 1
149
353
  rare auction status --contract 0x... --token-id 1
150
354
  ```
151
355
 
356
+ Reserve auctions start when the first valid bid meets the reserve. Scheduled auctions escrow the token when configured and become bid-ready at `--start-time`; their starting price can be zero. `--split <ADDR=RATIO>` is repeatable for up to 5 recipients, and ratios must sum to exactly 100.
357
+
152
358
  ### Offers
153
359
 
154
360
  ```bash
155
361
  # Create an offer on a token
156
- rare offer create --contract 0x... --token-id 1 --amount 0.5
362
+ rare offer create --contract 0x... --token-id 1 --price 0.5
157
363
 
158
364
  # Create an offer with ERC20 currency
159
- rare offer create --contract 0x... --token-id 1 --amount 100 --currency usdc
365
+ rare offer create --contract 0x... --token-id 1 --price 100 --currency usdc
160
366
 
161
367
  # Accept an offer on a token you own
162
- rare offer accept --contract 0x... --token-id 1 --amount 0.5
368
+ rare offer accept --contract 0x... --token-id 1 --price 0.5
369
+
370
+ # Accept with payout splits (must sum to 100; caller is NOT auto-included)
371
+ rare offer accept --contract 0x... --token-id 1 --price 0.5 \
372
+ --split 0xCollab=30 --split 0xMyWallet=70
163
373
 
164
374
  # Cancel your offer
165
375
  rare offer cancel --contract 0x... --token-id 1
@@ -168,6 +378,12 @@ rare offer cancel --contract 0x... --token-id 1
168
378
  rare offer status --contract 0x... --token-id 1
169
379
  ```
170
380
 
381
+ `--price` on `accept` is a slippage assertion: the on-chain offer must still match the value you pass, otherwise the tx reverts. Re-run `offer status` if you suspect drift.
382
+
383
+ `--split <ADDR=RATIO>` is repeatable for up to 5 recipients. Ratios must sum to exactly 100. If you omit `--split`, the SDK defaults to `[caller, 100]` (100% to your wallet). If you pass any `--split`, you must specify the complete list — the caller is **not** auto-appended.
384
+
385
+ NFT approval (`setApprovalForAll`) is checked by `offer accept`, `auction create`, and `listing create`. If approval is already in place, the command continues without a prompt; if approval is required, pass `--yes` or confirm the interactive `[y/N]` prompt.
386
+
171
387
  ### Listings
172
388
 
173
389
  ```bash
@@ -177,21 +393,125 @@ rare listing create --contract 0x... --token-id 1 --price 1.0
177
393
  # List with ERC20 currency or a targeted buyer
178
394
  rare listing create --contract 0x... --token-id 1 --price 100 --currency rare --target 0x...buyer
179
395
 
396
+ # List with payout splits (must sum to 100; caller is NOT auto-included)
397
+ rare listing create --contract 0x... --token-id 1 --price 1.0 \
398
+ --split 0xCollab=30 --split 0xMyWallet=70
399
+
180
400
  # Buy a listed token
181
- rare listing buy --contract 0x... --token-id 1 --amount 1.0
401
+ rare listing buy --contract 0x... --token-id 1 --price 1.0
182
402
 
183
403
  # Cancel a listing
184
404
  rare listing cancel --contract 0x... --token-id 1
185
405
 
186
- # Check listing status (read-only)
406
+ # Check listing status (read-only) — includes seller, amount, currency, target,
407
+ # split recipients, and whether the connected wallet can buy
187
408
  rare listing status --contract 0x... --token-id 1
188
409
  ```
189
410
 
411
+ `--split <ADDR=RATIO>` is repeatable. Ratios must sum to exactly 100. If you omit `--split`, the SDK defaults to `[caller, 100]` (100% to your wallet). If you pass any `--split`, you must specify the complete list — the caller is **not** auto-appended.
412
+
413
+ ### Batch Listings
414
+
415
+ Batch listings use Merkle artifacts: one root artifact describing the token set and listing config, and one proof artifact per token purchase.
416
+ Root artifacts are produced outside the CLI. Token sets and allowlists must each contain at least two entries because the batch listing contract rejects empty Merkle proofs. If no split is provided, registration defaults to 100% to the connected seller wallet.
417
+
418
+ ```bash
419
+ # Build a proof artifact for one token in the root
420
+ rare utils merkle proof \
421
+ --input ./root.json \
422
+ --contract 0x... \
423
+ --token-id 1 \
424
+ --output ./proof.json
425
+
426
+ # If the root has an allowlist, include the buyer when generating the proof
427
+ rare utils merkle proof \
428
+ --input ./root.json \
429
+ --contract 0x... \
430
+ --token-id 1 \
431
+ --buyer 0x... \
432
+ --output ./proof.json
433
+
434
+ # Register the batch listing from the root artifact
435
+ rare listing batch create --input ./root.json --yes
436
+
437
+ # Buy one token using a proof artifact
438
+ rare listing batch buy \
439
+ --proof ./proof.json \
440
+ --creator 0x...seller \
441
+ --currency usdc \
442
+ --price 25
443
+
444
+ # Inspect the listing config
445
+ rare listing batch status --root ./root.json --creator 0x...seller
446
+
447
+ # Narrow status to a specific token with its proof
448
+ rare listing batch status \
449
+ --root ./root.json \
450
+ --creator 0x...seller \
451
+ --contract 0x... \
452
+ --token-id 1 \
453
+ --proof ./proof.json
454
+
455
+ # Attach an allowlist config to an existing root
456
+ rare listing batch set-allowlist \
457
+ --input ./root.json
458
+
459
+ # Or pass explicit override values
460
+ rare listing batch set-allowlist \
461
+ --root 0x... \
462
+ --allowlist-root 0x... \
463
+ --end-time 1735689600
464
+
465
+ # Cancel the listing root
466
+ rare listing batch cancel --input ./root.json
467
+ ```
468
+
469
+ Named currencies are parsed with chain-aware decimals. Arbitrary ERC20 addresses are supported and their `decimals()` values are resolved from chain RPC when sending buys.
470
+
471
+ ### Batch Offers and Batch Auctions
472
+
473
+ Batch offers and batch auctions use token Merkle roots. You can pass a token-list artifact with `--input` or a known bytes32 root with `--root`.
474
+
475
+ ```bash
476
+ # Create a batch offer over a token set
477
+ rare offer batch create \
478
+ --input batch-token-artifact.json \
479
+ --price 1 \
480
+ --currency eth \
481
+ --end-time 1778586400 \
482
+ --yes
483
+
484
+ # Accept a batch offer for one token
485
+ rare offer batch accept \
486
+ --creator 0x...buyer \
487
+ --contract 0x... \
488
+ --token-id 1 \
489
+ --root 0x... \
490
+ --yes
491
+
492
+ # Create a batch reserve auction over a token set
493
+ rare auction batch create \
494
+ --input batch-token-artifact.json \
495
+ --price 0.1 \
496
+ --end-time 1778586400 \
497
+ --yes
498
+
499
+ # Bid on, inspect, settle, or cancel batch auctions
500
+ rare auction batch bid --creator 0x...seller --contract 0x... --token-id 1 --price 0.2
501
+ rare auction batch status --creator 0x...seller --contract 0x... --token-id 1
502
+ rare auction batch settle --contract 0x... --token-id 1
503
+ rare auction batch cancel --root 0x...
504
+ ```
505
+
506
+ Batch marketplace commands can resolve proofs through the Rare API when enough token, root, and creator context is provided. Pass local proof artifacts when you need a portable offline override.
507
+
190
508
  ### Currencies
191
509
 
192
510
  All marketplace commands (`auction`, `offer`, `listing`) accept `--currency` to specify a payment token. Named currencies (`eth`, `usdc`, `rare`) are resolved per-chain automatically. You can also pass any ERC20 address directly.
193
511
 
194
- ERC20 allowances are auto-approved when needed for bids, offers, and purchases.
512
+ SDK marketplace methods use the same currency contract: pass `eth`, `rare`, `usdc`, or an ERC20 address to `currency`, and use `rare.currency.list()`, `rare.currency.resolve(input)`, or `rare.currency.resolveDecimals(input)` to inspect the chain-aware mapping.
513
+
514
+ ERC20 allowances are auto-approved when needed for bids, offers, listing purchases, and batch-listing purchases.
195
515
 
196
516
  ```bash
197
517
  # List supported currencies and their addresses
@@ -199,38 +519,98 @@ rare currencies
199
519
  rare currencies --chain mainnet
200
520
  ```
201
521
 
522
+ ### Liquid Editions
523
+
524
+ Liquid Edition deployments support generated presets, custom curve files, metadata upload, preview-only output, and explicit transaction confirmation.
525
+
526
+ ```bash
527
+ # Preview a generated curve before deploying
528
+ rare liquid-edition deploy multicurve "My Liquid Edition" "MLE" \
529
+ --curve-preset medium-demand \
530
+ --description "A liquid edition" \
531
+ --image ./art.png \
532
+ --preview
533
+
534
+ # Submit the deployment
535
+ rare liquid-edition deploy multicurve "My Liquid Edition" "MLE" \
536
+ --curve-preset medium-demand \
537
+ --description "A liquid edition" \
538
+ --image ./art.png \
539
+ --initial-rare-liquidity 1000 \
540
+ --yes
541
+
542
+ # Inspect and maintain a Liquid Edition
543
+ rare liquid-edition status --contract 0x...
544
+ rare liquid-edition token-uri --contract 0x...
545
+ rare liquid-edition set-render-contract --contract 0x... --render-contract 0x...
546
+ ```
547
+
548
+ Use `--preview` to stop before deployment. Otherwise, the CLI resolves the curve config and asks for confirmation unless you pass `--yes`; in `--json` or non-interactive mode, pass `--yes` to submit a transaction.
549
+
550
+ ### Swaps
551
+
552
+ Swap commands quote before submitting. Use `--quote-only` to stop after the quote or `--yes` to submit without the interactive confirmation.
553
+
554
+ ```bash
555
+ # Buy an arbitrary token with ETH
556
+ rare swap buy-token --token 0x... --amount-in 0.1 --quote-only
557
+ rare swap buy-token --token 0x... --amount-in 0.1 --slippage-bps 50 --yes
558
+
559
+ # Sell a token for ETH
560
+ rare swap sell-token --token 0x... --amount-in 10 --quote-only
561
+
562
+ # Buy RARE with ETH through the canonical route
563
+ rare swap buy-rare --amount-in 0.1 --quote-only
564
+
565
+ # Execute a prebuilt raw liquid-router swap
566
+ rare swap tokens \
567
+ --token-in 0x... \
568
+ --amount-in 10 \
569
+ --token-out 0x... \
570
+ --min-amount-out 9.5 \
571
+ --commands 0x... \
572
+ --inputs-file ./router-inputs.json \
573
+ --yes
574
+ ```
575
+
576
+ `buy-token` and `sell-token` accept `--route auto`, `--route local`, `--route uniswap`, or `--route raw`. Raw route execution requires `--commands`, `--inputs-file`, and `--min-amount-out`.
577
+
202
578
  ### Search
203
579
 
204
580
  ```bash
205
581
  # Search all NFTs
206
- rare search tokens --query "portrait"
582
+ rare search nfts --query "portrait"
207
583
 
208
584
  # Search your own NFTs
209
- rare search tokens --mine
585
+ rare search nfts --mine
210
586
 
211
587
  # Search NFTs by owner
212
- rare search tokens --owner 0x...
588
+ rare search nfts --owner 0x...
213
589
 
214
- # Find active auctions (defaults to PENDING + RUNNING)
215
- rare search auctions
590
+ # Find NFTs with running auctions
591
+ rare search nfts --auction-state RUNNING
216
592
 
217
- # Filter by auction state
218
- rare search auctions --state SETTLED
593
+ # Find NFTs with listings or offers
594
+ rare search nfts --has-listing
595
+ rare search nfts --has-offer
219
596
 
220
- # Search your collections
221
- rare search collections
222
- ```
223
-
224
- All search commands support `--take <n>` and `--cursor <n>` for pagination.
597
+ # Search NFT events by token
598
+ rare search events --chain-id 1 --contract 0x... --token-id 1 --event-type CREATE_NFT
225
599
 
226
- ### List All Collections
600
+ # Search collection events by collection ID or by chain + contract
601
+ rare search events --collection-id 1-0x...
602
+ rare search events --chain-id 1 --contract 0x...
227
603
 
228
- Fetches every collection you own (auto-paginates):
604
+ # Search collections
605
+ rare search collections
229
606
 
230
- ```bash
231
- rare list-collections
607
+ # Fetch a specific NFT or user
608
+ rare nft get --contract 0x... --token-id 1
609
+ rare user get 0x...
232
610
  ```
233
611
 
612
+ All search commands support `--per-page <n>` and `--page <n>` for pagination.
613
+
234
614
  ### Query On-Chain Status
235
615
 
236
616
  ```bash
@@ -272,13 +652,32 @@ const walletClient = createWalletClient({
272
652
  const rare = createRareClient({ publicClient, walletClient });
273
653
  ```
274
654
 
655
+ Public package subpaths are intentionally scoped:
656
+
657
+ ```ts
658
+ import { createRareClient } from '@rareprotocol/rare-cli/client';
659
+ import { contractAddresses, supportedChains } from '@rareprotocol/rare-cli/contracts';
660
+ import { buildUtilsTree, getUtilsTreeProof } from '@rareprotocol/rare-cli/utils';
661
+ ```
662
+
663
+ Use `@rareprotocol/rare-cli/client` for app-level SDK workflows, `@rareprotocol/rare-cli/contracts` for lower-level viem contract metadata and ABIs, and `@rareprotocol/rare-cli/utils` for standalone pure artifact/proof helpers.
664
+
275
665
  ### Search
276
666
 
277
- `search.nfts` auto-applies the client chain unless you pass `chainIds`.
667
+ `RareClient` is bound to the chain on its `publicClient`. Client methods use that chain automatically; create a separate client with a different viem chain to query or write another network.
278
668
 
279
669
  ```ts
280
- const nfts = await rare.search.nfts({ query: 'portrait', take: 10 });
281
- const collections = await rare.search.collections({ ownerAddresses: [account.address] });
670
+ const nfts = await rare.search.nfts({ query: 'portrait', perPage: 10 });
671
+ const collections = await rare.search.collections({ ownerAddress: account.address });
672
+ const events = await rare.search.events({
673
+ contract: '0x...',
674
+ tokenId: '1',
675
+ eventType: ['CREATE_NFT', 'SETTLE_AUCTION'],
676
+ });
677
+ const nft = await rare.nft.get({
678
+ contract: '0x...',
679
+ tokenId: '1',
680
+ });
282
681
  ```
283
682
 
284
683
  ### Upload media and mint
@@ -298,7 +697,7 @@ const tokenUri = await rare.media.pinMetadata({
298
697
  tags: ['art'],
299
698
  });
300
699
 
301
- const minted = await rare.mint.mintTo({
700
+ const minted = await rare.collection.mint({
302
701
  contract: '0xYourContractAddress',
303
702
  tokenUri,
304
703
  to: '0xRecipientAddress',
@@ -307,6 +706,135 @@ const minted = await rare.mint.mintTo({
307
706
  console.log(minted.tokenId);
308
707
  ```
309
708
 
709
+ ### Deploy an ERC-721 collection
710
+
711
+ ```ts
712
+ const created = await rare.collection.deploy.erc721({
713
+ name: 'My Collection',
714
+ symbol: 'MC',
715
+ maxTokens: 1000,
716
+ });
717
+
718
+ console.log(created.contract);
719
+ ```
720
+
721
+ ### Deploy a Lazy ERC-721 collection
722
+
723
+ ```ts
724
+ const release = await rare.collection.deploy.lazyErc721({
725
+ name: 'My Release',
726
+ symbol: 'MR',
727
+ maxTokens: 1000,
728
+ contractType: 'lazy',
729
+ });
730
+
731
+ console.log(release.contract);
732
+ console.log(release.nextStep);
733
+ ```
734
+
735
+ ### Deploy a Lazy Batch Mint collection
736
+
737
+ ```ts
738
+ const lazyBatch = await rare.collection.deploy.lazyBatchMint({
739
+ name: 'My Lazy Collection',
740
+ symbol: 'MLC',
741
+ maxTokens: 1000,
742
+ });
743
+
744
+ console.log(lazyBatch.contract);
745
+ ```
746
+
747
+ ### Batch mint a Sovereign collection
748
+
749
+ ```ts
750
+ const batch = await rare.collection.mintBatch({
751
+ contract: '0xYourContractAddress',
752
+ baseUri: 'ipfs://your-metadata-directory',
753
+ amount: 100,
754
+ });
755
+
756
+ console.log(batch.fromTokenId, batch.toTokenId);
757
+ ```
758
+
759
+ ### Prepare a Lazy Sovereign mint
760
+
761
+ ```ts
762
+ const prepared = await rare.collection.prepareLazyMint({
763
+ contract: '0xYourContractAddress',
764
+ baseUri: 'ipfs://your-metadata-directory',
765
+ amount: 100,
766
+ minter: '0xOptionalMinterAddress',
767
+ });
768
+
769
+ console.log(prepared.tokenCount);
770
+ ```
771
+
772
+ ### Build utility token Merkle trees
773
+
774
+ ```ts
775
+ const tree = rare.utils.tree.build({
776
+ content: 'contract_address,token_id,chain_id\n0x1111111111111111111111111111111111111111,1,11155111\n',
777
+ format: 'csv',
778
+ });
779
+
780
+ const tokenProof = rare.utils.tree.proof({
781
+ artifact: tree,
782
+ contractAddress: '0x1111111111111111111111111111111111111111',
783
+ tokenId: 1,
784
+ });
785
+
786
+ const proofValid = rare.utils.tree.verify({
787
+ root: tree.root,
788
+ contractAddress: tokenProof.contractAddress,
789
+ tokenId: tokenProof.tokenId,
790
+ proof: tokenProof.proof,
791
+ });
792
+
793
+ console.log(tree.root, tokenProof.proof, proofValid);
794
+ ```
795
+
796
+ ### Liquid Edition and swap SDK methods
797
+
798
+ ```ts
799
+ const liquidStatus = await rare.liquidEdition.status({
800
+ contract: '0xLiquidEditionContract',
801
+ });
802
+
803
+ const buyQuote = await rare.swap.quoteBuyToken({
804
+ token: '0xTokenAddress',
805
+ amountIn: '0.1',
806
+ route: 'auto',
807
+ });
808
+
809
+ console.log(liquidStatus.currentPrice.rarePerToken, buyQuote.minAmountOut);
810
+ ```
811
+
812
+ ### Inspect and maintain collection owner settings
813
+
814
+ ```ts
815
+ const creator = await rare.collection.getTokenCreator({
816
+ contract: '0xYourContractAddress',
817
+ tokenId: 1,
818
+ });
819
+
820
+ const royalty = await rare.collection.royalty.status({
821
+ contract: '0xYourContractAddress',
822
+ tokenId: 1,
823
+ });
824
+
825
+ await rare.collection.setDefaultRoyaltyReceiver({
826
+ contract: '0xYourContractAddress',
827
+ receiver: '0xNewRoyaltyReceiver',
828
+ });
829
+
830
+ await rare.collection.updateBaseUri({
831
+ contract: '0xLazySovereignContractAddress',
832
+ baseUri: 'ipfs://updated-metadata-directory',
833
+ });
834
+
835
+ console.log(creator.creator, royalty.receiver);
836
+ ```
837
+
310
838
  ### Import an ERC-721 collection
311
839
 
312
840
  `import.erc721` derives `chainId` from the client. If `owner` is omitted, it defaults to the configured account.
@@ -319,12 +847,15 @@ await rare.import.erc721({
319
847
 
320
848
  ## Configuration
321
849
 
322
- Config is stored at `~/.rare/config.json`. Each chain has its own private key and RPC URL.
850
+ Config is stored at `~/.rare/config.json`. Each chain has its own key source and RPC URL. A key source can be a plaintext `privateKey` or a 1Password `privateKeyRef` plus a derived public address. `rare configure --show` prints the account address for configured key sources.
323
851
 
324
852
  ```bash
325
853
  # Set private key and RPC for a chain
326
854
  rare configure --chain sepolia --private-key 0x... --rpc-url https://...
327
855
 
856
+ # Set a 1Password-backed private key reference and RPC for a chain
857
+ rare configure --chain sepolia --private-key-ref op://Private/rare-sepolia/private-key --rpc-url https://...
858
+
328
859
  # Configure multiple chains
329
860
  rare configure --chain base --rpc-url https://your-base-rpc.com
330
861
  rare configure --chain base-sepolia --private-key 0x... --rpc-url https://your-base-sepolia-rpc.com
@@ -332,26 +863,61 @@ rare configure --chain base-sepolia --private-key 0x... --rpc-url https://your-b
332
863
  # Change default network
333
864
  rare configure --default-chain mainnet
334
865
 
335
- # View current config
866
+ # View current config, including derived account addresses
336
867
  rare configure --show
868
+
869
+ # Delete local config (prompts for confirmation)
870
+ rare configure delete
871
+
872
+ # Delete local config without prompting
873
+ rare configure delete --yes
874
+ ```
875
+
876
+ Merkle root and proof flows use `https://api.superrare.com` by default. Set `RARE_API_BASE_URL` to point the SDK and CLI at another rare-api deployment.
877
+
878
+ ```bash
879
+ RARE_API_BASE_URL=https://rare-api.example.com rare listing batch buy --contract 0x... --token-id 1 --creator 0x... --currency eth --price 1
337
880
  ```
338
881
 
339
882
  ## Best Practices
340
883
 
341
884
  - **Use sepolia for testing.** Default to sepolia and only switch to mainnet when you're ready.
342
885
  - **Set a reliable RPC endpoint.** Public endpoints throttle and drop requests. Services like Alchemy or Infura provide free tiers.
343
- - **Don't share your private key.** Keep `~/.rare/config.json` secure and never commit it to version control.
886
+ - **Prefer 1Password for private keys.** Install the 1Password CLI, run `op signin`, and configure keys with `--private-key-ref` to avoid storing plaintext keys in rare config.
887
+ - **Don't share your private key.** If you use `--private-key` or generated saved wallets, keep `~/.rare/config.json` secure and never commit it to version control.
344
888
  - **Check status before transacting.** Use `rare status` and `rare auction status` to inspect on-chain state before sending transactions.
345
889
  - **Back up your wallet.** If you lose your private key, you lose access to your assets. Store a copy somewhere safe.
346
890
 
891
+ ### 1Password Test Setup
892
+
893
+ The default test suite does not require access to a real 1Password vault. To run the optional live 1Password integration, sign in with `op signin` and provide a private-key secret reference:
894
+
895
+ ```bash
896
+ RARE_CLI_TEST_OP_PRIVATE_KEY_REF=op://Private/rare-sepolia/private-key \
897
+ npx vitest run test/integration/one-password.test.ts --config vitest.config.ts
898
+ ```
899
+
347
900
  ## Contract Addresses
348
901
 
349
- | Network | Factory | Auction |
350
- |---|---|---|
351
- | Sepolia | `0x3c7526a0975156299ceef369b8ff3c01cc670523` | `0xC8Edc7049b233641ad3723D6C60019D1c8771612` |
352
- | Mainnet | `0xAe8E375a268Ed6442bEaC66C6254d6De5AeD4aB1` | `0x6D7c44773C52D396F43c2D511B81aa168E9a7a42` |
353
- | Base Sepolia | `0x2b181ae0f1aea6fed75591b04991b1a3f9868d51` | `0x1f0c946f0ee87acb268d50ede6c9b4d010af65d2` |
354
- | Base | `0xf776204233bfb52ba0ddff24810cbdbf3dbf94dd` | `0x51c36ffb05e17ed80ee5c02fa83d7677c5613de2` |
902
+ These are the addresses embedded in the SDK under `@rareprotocol/rare-cli/contracts`.
903
+
904
+ Core collection and marketplace contracts:
905
+
906
+ | Network | Factory | Sovereign Factory | Lazy Sovereign Factory | Lazy Batch Mint Factory | Auction | RareMinter |
907
+ |---|---|---|---|---|---|---|
908
+ | Sepolia | `0x3c7526a0975156299ceef369b8ff3c01cc670523` | `0x46B2850ba7787734F648A6848b5eDE0815C1F8Bf` | `0xc5B8Ad9003673a23d005A6448C74d8955a1a38fA` | `0xE5efBA88D556aDA98124654fE505465b8d494858` | `0xC8Edc7049b233641ad3723D6C60019D1c8771612` | `0xd28Dc0B89104d7BBd902F338a0193fF063617ccE` |
909
+ | Mainnet | `0xAe8E375a268Ed6442bEaC66C6254d6De5AeD4aB1` | `0xe980ec62378529d95ba446433f4deb6324129c59` | `0xba798BD606d86D207ca2751510173532899117a1` | `0x40F9E4b420D5A8fF5aED32B5F72A37013c0739B6` | `0x6D7c44773C52D396F43c2D511B81aa168E9a7a42` | `0x5fa112EFeD8297bec0010b312208d223E0cE891E` |
910
+ | Base Sepolia | `0x2b181ae0f1aea6fed75591b04991b1a3f9868d51` | — | — | — | `0x1f0c946f0ee87acb268d50ede6c9b4d010af65d2` | — |
911
+ | Base | `0xf776204233bfb52ba0ddff24810cbdbf3dbf94dd` | — | — | — | `0x51c36ffb05e17ed80ee5c02fa83d7677c5613de2` | — |
912
+
913
+ Batch, approval, Liquid Edition, and swap infrastructure:
914
+
915
+ | Network | Batch Listing | BatchOfferCreator | BatchAuctionHouse | Marketplace Settings | ERC20 Approval Manager | ERC721 Approval Manager | Liquid Factory | Swap Router | V4 Quoter |
916
+ |---|---|---|---|---|---|---|---|---|---|
917
+ | Sepolia | `0xF2bE72d4343beD375Cb6d0E799a3c003163860e0` | `0x371cca54ef859bb0c7b910581a528ee47773fd56` | `0x293AE7701A7830B1d38A7608EdF86A106d9E2645` | `0x972dEe8fa339ad2D9c6cbDA31b67f98Fac242d13` | `0x4619eB29e84392CE91C27FC936A5c94d1D14b93f` | `0x5fa0a461d3a2Ea3bFDf03e8BD37CAbB4ae84205E` | `0xb1777091C953fa2aC1fD67f2b3e2f61343F5Ce5e` | `0x429c3Ee66E7f6CDA12C5BadE4104aF3277aA2305` | `0x61B3f2011A92d183C7dbaDBdA940a7555Ccf9227` |
918
+ | Mainnet | `0x6a190885A806D39A0A8C348bfA1ac762D72E608d` | `0xe15cf80b25272ade261532efdb7912f9104851d4` | `0x71742c7196f1c334C4c038ce6dcDcEE98097F9Da` | `0x61DBF87164d33FD3695256DC8Ba74D3B1d304170` | `0xa837a7eAff154Ab837617Cf7250648D3Ec0A4436` | `0x4bb0Deea6d1A30C601338aAB776d394C2AE5c0F8` | `0xbb4341CFd588a098e9aCE1D224178836426c4a8E` | `0xEBd58EdA8408d9EA409f2c2bE8898BD9738f3583` | `0x52F0E24D1c21C8A0cB1e5a5dD6198556BD9E1203` |
919
+ | Base Sepolia | — | — | `0x2b181ae0f1aea6fed75591b04991b1a3f9868d51` | — | — | — | — | — | — |
920
+ | Base | — | — | `0xf776204233bfb52ba0ddff24810cbdbf3dbf94dd` | — | — | — | — | — | — |
355
921
 
356
922
  ## Underlying Solidity Contracts
357
923
 
@@ -359,6 +925,10 @@ If you want to inspect the on-chain contracts used by this CLI:
359
925
 
360
926
  - Token contract used when minting NFTs: [`SovereignBatchMint.sol`](https://github.com/superrare/core/blob/main/src/v2/token/ERC721/sovereign/SovereignBatchMint.sol)
361
927
  - Factory used for collection deployments: [`SovereignBatchMintFactory.sol`](https://github.com/superrare/core/blob/main/src/v2/token/ERC721/sovereign/SovereignBatchMintFactory.sol)
928
+ - Token contract used for RareMinter releases: [`LazySovereignNFT.sol`](https://github.com/superrare/core/blob/main/src/token/ERC721/sovereign/lazy/LazySovereignNFT.sol)
929
+ - Factory used for Lazy ERC-721 release collection deployments: [`LazySovereignNFTFactory.sol`](https://github.com/superrare/core/blob/main/src/token/ERC721/sovereign/lazy/LazySovereignNFTFactory.sol)
930
+ - Token contract used for lazy batch mint drops: [`LazySovereignBatchMint.sol`](https://github.com/superrare/core/blob/main/src/v2/token/ERC721/sovereign/LazySovereignBatchMint.sol)
931
+ - Factory used for lazy batch mint collection deployments: [`LazySovereignBatchMintFactory.sol`](https://github.com/superrare/core/blob/main/src/v2/token/ERC721/sovereign/LazySovereignBatchMintFactory.sol)
362
932
  - Auction/market contract used for auction operations: [`SuperRareBazaar.sol`](https://github.com/superrare/core/blob/main/src/bazaar/SuperRareBazaar.sol)
363
933
 
364
934
  ## Development (Optional)