Skip to main content

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 (DeadlineInPast revert 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:

  1. Your wallet signs the reserve amount using personal_sign (no gas).
  2. The app encrypts the signed payload via TDH2 into a CDR ciphertext (via the /api/encrypt-bid server route — CDR's WASM runs server-side).
  3. 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

SituationUse
Your IP isn't on Story yetMint and list
Your IP is on Story but terms aren't attachedAttach terms via Story tooling, then come here
Your IP is on Story with terms attachedThis page
You want to list the same IP under different termsAttach 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.