# DROPS — NFT Marketplace on XRPL EVM > Create, collect, and trade NFTs on the XRP Ledger. Factory-deployed ERC-721 collections with Arweave permanent storage. Agent-friendly CLI. ## Networks | Network | Chain ID | RPC | Explorer | Shown on drops.market? | |---------|----------|-----|----------|------------------------| | Mainnet | 1440000 | https://rpc.xrplevm.org | https://explorer.xrplevm.org | **Yes** | | Testnet | 1449000 | https://rpc.testnet.xrplevm.org | https://explorer.testnet.xrplevm.org | **No** — headless | **Mainnet is the default everywhere — website and CLI.** It spends real XRP (from 1.01 XRP to deploy). Pass `--testnet` to spend worthless test XRP instead — the same deploy fee is charged there too, only the XRP is free. Note testnet is **not** indexed by drops.market: nothing you create there appears on the site, so verify with `drops info` / `drops tokens` and the block explorer instead. Arweave art/metadata URLs work on either network, at DROPS' expense. ## Contracts Platform contracts (Factory, Market, Offers, Auction) are **UUPS upgradeable proxies** owned by deployer `0x47f4A47f61c5d10fc24307eC54988046B3073F5E` — addresses are stable across upgrades. DropsLens is an immutable stateless view contract. User-deployed NFT contracts (DropsCollection, DropsDrop) are immutable. ### Mainnet (chain 1440000) — deployed 2026-05-11, block 5,808,802 | Contract | Address | Purpose | |----------|---------|---------| | DropsFactory | `0x00844CaE1ecfd0b73356f6d9cB7A7e421EC9c7A8` | Deploy collections + drops, mint NFTs | | DropsMarket | `0xb5D697C249f219E9D47969bCcEbE7E6A65291ccA` | Secondary marketplace (list/buy/cancel) | | DropsOffers | `0x917AA02C718EFbF0621FD72Dd39E70C074b6732d` | Offer/bid system with escrow | | DropsAuction | `0x4c73c939737Eaa3dAC015528cF967D52C9B344b7` | Timed auctions with anti-snipe | | DropsLens | `0x46E0bf48a18f44Dc25B74EdDA2795f7Baa6934af` | View aggregator (batch reads) | ### Testnet (chain 1449000) — deployed 2026-03-28, block 6,101,039 | Contract | Address | Purpose | |----------|---------|---------| | DropsFactory | `0x46E0bf48a18f44Dc25B74EdDA2795f7Baa6934af` | Deploy collections + drops, mint NFTs | | DropsMarket | `0x1689e3D5CfF83C865934bF9504940b08ca358dBF` | Secondary marketplace (list/buy/cancel) | | DropsOffers | `0x9DB977b941fDDdCC3Ab194e3cC83F2cDAc562C26` | Offer/bid system with escrow | | DropsAuction | `0x72BC803a23BBBB2f5B1e823a9b57F6F4a430dFAA` | Timed auctions with anti-snipe | | DropsLens | `0x7895DefEf770B588b46329E62E7d763Ff175dF5a` | View aggregator (batch reads) | ## Quick Start ```bash npx drops-market wallet new # 1. Get a wallet export WALLET_PRIVATE_KEY=0x... # 2. Set your key npx drops-market status # 3. Verify network + contracts npx drops-market balance # 4. Fund the wallet, then confirm it landed npx drops-market create collection --name "My Art" --symbol "ART" --price 1 --supply 100 --royalty 5 --image ./banner.png # --supply required; costs 2 XRP npx drops-market mint 0xCOLLECTION --image ./art.png --name "Piece #1" npx drops-market list-nft 0xCOLLECTION 1 10 # List for 10 XRP npx drops-market buy # IDs are global — read one from `list-nft --json` or `browse` npx drops-market help # Full command list ``` **Funding (step 4 is not optional).** A fresh wallet has 0 XRP and every write above needs gas. The deploy fee is **1 XRP + 0.01 XRP per declared token**, so budget by supply: ~1.02 XRP for a one-of-one, ~2.01 for 100 items, ~101 for 10,000. Mainnet has **no faucet** — a human has to send XRP to the address `wallet new` printed. On `--testnet`, claim from https://faucet.xrplevm.org (up to 90 XRP per claim; rate-limited, so expect to retry) — the same fee applies there, in test XRP. Arweave storage is separate and costs you nothing. Mainnet is the default; pass `--testnet` for headless testing in test XRP. `--json` for structured agent output. ## Fee Model | Action | Fee | |--------|-----| | Deploy collection | 1 XRP + 0.01 XRP per declared token | | Primary mint | 2.5% platform fee | | Secondary sale | 1% platform + 0-10% creator royalty (EIP-2981) | So a 1/1 costs 1.01 XRP, a 100-piece set 2 XRP, a 10,000-item drop 101 XRP. Read the exact price for any supply with `deployFeeFor(maxSupply)` on the factory, or `drops status`. **Uploading a whole drop?** Call `POST /upload/reserve` with `{maxSupply, plannedBytes}` first. Upload allowance is per-wallet and checked per request, so a large drop can be refused partway through with earlier batches already uploaded and wasted. One reservation checks the whole job before you spend, and raises your ceiling to match a supply you can pay to deploy. The CLI does it automatically. Details in skill.md. **Unlimited supply is not deployable** — `maxSupply` must be at least 1 on both collections and drops. An uncapped set has no way to price. Collections deployed unlimited before this change still work. The same fees apply on testnet, charged in test XRP. Testnet makes the XRP free, not the fees. Arweave storage is **platform-funded** — free to you. You need XRP only for gas and the fees above. The CLI signs a lightweight auth message with your wallet on each upload; no Turbo/Arweave credits required. Minting into your own collection is free (`creatorMint`) and works without opening public minting first. ## Rules That Catch Agents Out - **One listing per token.** Creating a listing retires any earlier listing for the same token (event `ListingSuperseded`); buying a retired one reverts — `ListingNotActive`, or `ListingStale` if it predates the rule. `activeListingOf(collection, tokenId)` names the live one. The rule exists because a listing cannot observe the token leaving the seller, so an old listing used to spring back to life at its old price when the token returned. It only fires on a new listing, so still cancel yours before you move a token. - **Listing IDs are global, not per-collection.** One counter for the whole marketplace — the first listing on your collection may be #37. Never guess or derive one. - **`admin reveal` is not idempotent.** `DropsDrop.reveal()` has no on-chain guard: it overwrites the base URI on every call, silently repointing the art for every token, with no undo. The CLI refuses a second reveal unless you pass `--force`. - **Before reveal, every token returns the same `hiddenMetadataURI`.** Identical `tokenURI` values across different IDs mean the drop is unrevealed, not broken. ## Documentation - [skill.md](/skill.md): **Start here** — Full agent playbook, CLI docs, contract calls, Arweave uploads - [npm: drops-market](https://www.npmjs.com/package/drops-market): CLI package on npm