List an existing IP
Use this path when your IP is already registered on Story — minted via another tool, imported from a prior project, or registered manually through the SPG contracts.
Two paths to the form
On sealedip.com/create, pick List existing IP.
If you've connected your wallet, the form opens in picker mode: a grid of IPs your wallet owns, loaded from Story's v4 API. Pick a card.
If you'd rather paste an address (or the picker doesn't show your IP for some reason), click Paste an address instead to flip to manual mode.
Picker mode
The picker calls SealedIP's /api/owner-ips route, which proxies Story's
POST /assets with where.ownerAddress = <your wallet>. The grid shows up
to 50 IPs sorted by registration recency.
Each card shows:
- A thumbnail (deterministic gradient if no image, or the NFT cover image if available)
- The IP title
- The short address
- The first attached terms id if known
Clicking a card fills the form's IP address and (when available) auto-fills the License terms ID. If the IP has multiple attached terms, the picker shows them as click-to-fill chips. The Storyscan link next to the chips opens the LicenseRegistry's read tab so you can verify.
Manual mode
Two fields:
- IP asset address — the Story IP account address (
0x+ 40 hex chars). - License terms ID — the numeric PIL terms id already attached to the IP.
The form pre-fills both as you type. If you don't know the terms id, the helper offers:
- Click-to-fill chips for common ids:
#1(Story canonical NC Social Remixing) and#2834(SealedIP demo locked-down) - An on-chain reader that queries
LicenseRegistry.getAttachedLicenseTerms(ipId, 0)and surfaces the result as a chip - A direct Storyscan link to the LicenseRegistry's read tab where you can paste the IP address and read out the answer
What happens at submit — two steps
Step 1 — Open the auction
Your wallet signs:
SealedAuction.createAuction(ipId, licenseTermsId, deadline)
The contract:
- Validates the deadline is in the future (
DeadlineInPastrevert otherwise) - Allocates a fresh
auctionId - Allocates a seller-side CDR vault for your reserve (
reserveUuid) - Stores the auction record with you as
seller - Emits
AuctionCreated(auctionId, seller, ipId, licenseTermsId, reserveUuid, deadline)
There is no reservePrice argument. The reserve is sealed in the next step.
There's no on-chain check that the terms id is actually attached to the IP. If you pass an unattached terms id, the auction will proceed but the license mint will fail at settle. You won't lose money — the whole settle reverts, deposits stay escrowed, and the orchestrator retries with the correct config.
To be safe: use the picker (which only surfaces attached terms) or verify on Storyscan before submitting.
Step 2 — Seal your reserve
After the auction is created, the app prompts you to seal your reserve price:
- Your wallet signs the reserve amount using
personal_sign(no gas). - The app encrypts the signed payload via TDH2 into a CDR ciphertext (via the
/api/encrypt-bidserver route — CDR's WASM runs server-side). - Your wallet sends
SealedAuction.submitEncryptedReserve(auctionId, ciphertext).
Once confirmed, reserveHasCiphertext is set to true in contract storage.
Bidders see a "reserve sealed" indicator on the auction card but never see
the amount. The amount is decrypted only at settle, then verified against
your signature on-chain.
If you skip sealing: the reserve defaults to 0, meaning any bid can win. The app will prompt you to seal before you navigate away, but there's no on-chain enforcement forcing you to seal.
Reserve + deadline
Fields shown before the two confirmations:
- Reserve price — your minimum acceptable bid in WIP. Sealed and private to bidders.
- Bidding window — 5 min / 1 hour / 24 hours / 7 days / 30 days.
The "What you take home" panel shows:
- Marketplace fee (0%)
- What you receive if the reserve is met
- Royalty note ("Determined by the PIL terms already attached to your IP")
- The two steps that come next
When to use this vs. mint-and-list
| Situation | Use |
|---|---|
| Your IP isn't on Story yet | Mint and list |
| Your IP is on Story but terms aren't attached | Attach terms via Story tooling, then come here |
| Your IP is on Story with terms attached | This page |
| You want to list the same IP under different terms | Attach the new terms via LicensingModule, then come here with the new terms id |
Why we don't bundle "list existing + attach new terms"
The LicensingModule's attachLicenseTerms call needs to come from a wallet
with permission over the IP. We could bundle it into a single seller flow,
but that would require either:
- A custom periphery contract that batches both calls (extra surface to audit)
- Two wallet confirmations even on the "existing" path (worse UX than "mint and list")
For now: the seller attaches terms with Story's standard tooling, and SealedIP handles the listing. If demand for the bundled flow grows, a custom periphery contract is the path forward.