This skill should be used when working with 1Sat Ordinals marketplace operations — listing ordinals for sale, purchasing listings, canceling listings, browsing available ordinals, or managing OrdLock marketplace scripts. Triggers on 'list ordinal', 'sell NFT', 'buy ordinal', 'purchase listing', 'cancel listing', 'marketplace', 'OrdLock', 'ordinal price', or 'browse ordinals'. Uses @1sat/actions ordinals module.
List, purchase, and cancel ordinal listings using @1sat/actions and the OrdLock script.
| Action | Description |
|---|---|
getOrdinals | List ordinals in the wallet (with BEEF for spending) |
transferOrdinals | Transfer ordinals to new owners |
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 |
inputBEEF provides the SPV proof chain for the inputs being spent. Whether it's required depends on who owns the input:
listOutputsinputBEEFimport { 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)
}
import { transferOrdinals, 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. Transfer — inputBEEF is optional (auto-resolved from wallet via ID tag)
const result = await transferOrdinals.execute(ctx, {
transfers: [
{ ordinal, counterparty: '02abc...' },
],
})
// Or transfer by address (external — not tracked in recipient's wallet)
const result2 = await transferOrdinals.execute(ctx, {
transfers: [
{ ordinal, address: '1Recipient...' },
],
})
// Batch transfer multiple ordinals
const result3 = await transferOrdinals.execute(ctx, {
transfers: [
{ ordinal: outputs[0], counterparty: '02abc...' },
{ ordinal: outputs[1], address: '1Bob...' },
],
})
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 — inputBEEF is optional (auto-resolved from wallet)
const result = await listOrdinal.execute(ctx, {
ordinal,
price: 100000, // Price in satoshis
payAddress: '1YourPaymentAddress...',
})
if (result.txid) {
console.log('Listed! txid:', result.txid)
}
ordlock tag is added, basket remains ordinalsimport { 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)
}
import { cancelListing, createContext } from '@1sat/actions'
const ctx = createContext(wallet, { services })
// Get the listed ordinal from wallet — filter by 'ordlock' tag
const { outputs } = await ctx.wallet.listOutputs({
basket: '1sat',
includeTags: true,
includeCustomInstructions: true,
tagsJSON: JSON.stringify(['ordlock']),
})
const listing = outputs[0]
// Cancel — inputBEEF is optional (auto-resolved from wallet via ID tag)
const result = await cancelListing.execute(ctx, { listing })
if (result.txid) {
console.log('Cancelled! txid:', result.txid)
}
OrdLock.cancelWithWallet from @1sat/templatesordlock tag)import { deriveCancelAddress, createContext } from '@1sat/actions'
const ctx = createContext(wallet)
const result = await deriveCancelAddress.execute(ctx, {
ordinal: listedOrdinal,
})
console.log('Cancel address:', result.address)
The OrdLock script encodes a marketplace listing:
<lockPrefix> <payAddress> <price> <lockSuffix>
payAddress for price satoshisUse 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')
| 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 |
bun add @1sat/actions @1sat/wallet @bsv/sdk
Marketplace operations require services for overlay submission and BEEF fetching.