Ordinals Marketplace
List, purchase, and cancel ordinal listings using @1sat/actions and the OrdLock script.
Actions
| Action | Description |
|---|---|
getOrdinals |
List ordinals in the wallet (with BEEF for spending) |
listOrdinal |
List an ordinal for sale at a price |
cancelListing |
Cancel an active listing |
purchaseOrdinal |
Purchase a listed ordinal |
deriveCancelAddress |
Get the cancel address for a listing |
Get Ordinals from Wallet
import { getOrdinals, createContext } from '@1sat/actions'
const ctx = createContext(wallet, { services })
const { outputs, BEEF } = await getOrdinals.execute(ctx, {
limit: 100,
})
// Each output has tags like:
// type:image/png, origin:txid_0, name:My NFT
for (const o of outputs) {
console.log(o.outpoint, o.tags)
}
List Ordinal for Sale
import { listOrdinal, getOrdinals, createContext } from '@1sat/actions'
const ctx = createContext(wallet, { services })
// 1. Get ordinal and BEEF
const { outputs, BEEF } = await getOrdinals.execute(ctx, {})
const ordinal = outputs[0]
// 2. List for sale
const result = await listOrdinal.execute(ctx, {
ordinal,
inputBEEF: Array.from(BEEF),
price: 100000, // Price in satoshis
payAddress: '1YourPaymentAddress...',
})
if (result.txid) {
console.log('Listed! txid:', result.txid)
}
How Listing Works
- Creates an OrdLock script that encodes the price and payment address
- The ordinal is locked in this script — only a valid purchase or cancel can spend it
- The listing is submitted to the marketplace overlay for indexing
- Tags are updated:
ordlocktag is added, basket remainsordinals
Purchase a Listed Ordinal
import { purchaseOrdinal, createContext } from '@1sat/actions'
const ctx = createContext(wallet, { services })
const result = await purchaseOrdinal.execute(ctx, {
outpoint: 'txid_0', // The listed ordinal's outpoint
marketplaceAddress: '1MarketplaceAddress...', // Optional marketplace fee address
marketplaceRate: 0.02, // Optional marketplace fee rate (2%)
})
if (result.txid) {
console.log('Purchased! txid:', result.txid)
}
How Purchase Works
- Fetches the listing BEEF from the overlay
- Reads the OrdLock script to extract price and payment address
- Builds a transaction that satisfies the OrdLock:
- Pays the seller the listed price
- Pays marketplace fee (if applicable)
- Transfers the ordinal to the buyer
- Signs and broadcasts
Cancel a Listing
import { cancelListing, getOrdinals, createContext } from '@1sat/actions'
const ctx = createContext(wallet, { services })
const { outputs, BEEF } = await getOrdinals.execute(ctx, {})
const listedOrdinal = outputs.find(o => o.tags?.includes('ordlock'))
const result = await cancelListing.execute(ctx, {
ordinal: listedOrdinal,
inputBEEF: Array.from(BEEF),
})
if (result.txid) {
console.log('Cancelled! txid:', result.txid)
}
How Cancel Works
- Derives the cancel key using the ordinal's custom instructions
- Signs the OrdLock input with the cancel key
- Transfers the ordinal back to the wallet (removes
ordlocktag) - Submits to overlay to clear the listing
Derive Cancel Address
import { deriveCancelAddress, createContext } from '@1sat/actions'
const ctx = createContext(wallet)
const result = await deriveCancelAddress.execute(ctx, {
ordinal: listedOrdinal,
})
console.log('Cancel address:', result.address)
OrdLock Script
The OrdLock script encodes a marketplace listing:
<lockPrefix> <payAddress> <price> <lockSuffix>
- The script is satisfied by either:
- Purchase: Transaction includes an output paying the seller at
payAddressforpricesatoshis - Cancel: Signed by the cancel key (derived from the ordinal's custom instructions)
- Purchase: Transaction includes an output paying the seller at
Browsing Marketplace via API
Use the 1sat-stack API to browse listings:
// Get ordinals by owner
const res = await fetch('https://api.1sat.app/1sat/owner/1Address.../txos')
const txos = await res.json()
// Filter for listings (have ordlock data)
const listings = txos.filter(t => t.data?.ordlock)
// Get specific ordinal content
const content = await fetch('https://api.1sat.app/1sat/content/txid_0')
Tags on Marketplace Outputs
| Tag | Meaning |
|---|---|
ordlock |
Currently listed for sale |
type:{contentType} |
MIME type of the inscription |
origin:{outpoint} |
Origin outpoint of the ordinal |
name:{value} |
Name from MAP metadata |
Requirements
bun add @1sat/actions @1sat/wallet @bsv/sdk
Marketplace operations require services for overlay submission and BEEF fetching.