@1sat/actions 0.0.189 → 0.0.191

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/index.d.ts +2 -1
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +2 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/inscriptions/index.d.ts +2 -2
  6. package/dist/inscriptions/index.d.ts.map +1 -1
  7. package/dist/inscriptions/index.js +3 -6
  8. package/dist/inscriptions/index.js.map +1 -1
  9. package/dist/locks/index.d.ts +32 -3
  10. package/dist/locks/index.d.ts.map +1 -1
  11. package/dist/locks/index.js +76 -5
  12. package/dist/locks/index.js.map +1 -1
  13. package/dist/opns/index.d.ts +90 -65
  14. package/dist/opns/index.d.ts.map +1 -1
  15. package/dist/opns/index.js +517 -188
  16. package/dist/opns/index.js.map +1 -1
  17. package/dist/ordinals/index.d.ts +76 -42
  18. package/dist/ordinals/index.d.ts.map +1 -1
  19. package/dist/ordinals/index.js +219 -180
  20. package/dist/ordinals/index.js.map +1 -1
  21. package/dist/tokens/index.d.ts +5 -1
  22. package/dist/tokens/index.d.ts.map +1 -1
  23. package/dist/tokens/index.js +36 -18
  24. package/dist/tokens/index.js.map +1 -1
  25. package/dist/utils/createTrackedAction.js +1 -1
  26. package/dist/utils/internalizeBeef.d.ts.map +1 -1
  27. package/dist/utils/internalizeBeef.js +1 -25
  28. package/dist/utils/internalizeBeef.js.map +1 -1
  29. package/dist/utils/loadBasketOutput.d.ts +25 -0
  30. package/dist/utils/loadBasketOutput.d.ts.map +1 -0
  31. package/dist/utils/loadBasketOutput.js +50 -0
  32. package/dist/utils/loadBasketOutput.js.map +1 -0
  33. package/dist/utils/ordinalSeedTags.d.ts +8 -0
  34. package/dist/utils/ordinalSeedTags.d.ts.map +1 -0
  35. package/dist/utils/ordinalSeedTags.js +24 -0
  36. package/dist/utils/ordinalSeedTags.js.map +1 -0
  37. package/package.json +9 -9
  38. package/dist/utils/resolveBeef.d.ts +0 -20
  39. package/dist/utils/resolveBeef.d.ts.map +0 -1
  40. package/dist/utils/resolveBeef.js +0 -36
  41. package/dist/utils/resolveBeef.js.map +0 -1
@@ -11,7 +11,8 @@ import { parseOutpoint } from '@1sat/utils';
11
11
  import { Beef, BigNumber, LockingScript, OP, P2PKH, PublicKey, Script, TransactionSignature, UnlockingScript, Utils, } from '@bsv/sdk';
12
12
  import { OPNS_BASKET, ORDINALS_BASKET, ORD_LOCK_PREFIX, ORD_LOCK_SUFFIX, P1SAT_PROTOCOL, } from '../constants';
13
13
  import { executeTrackedAction } from '../utils/createTrackedAction';
14
- import { resolveBeef } from '../utils/resolveBeef';
14
+ import { loadBasketOutputBeef } from '../utils/loadBasketOutput';
15
+ import { ordinalSeedTags } from '../utils/ordinalSeedTags';
15
16
  import { signOrdinalInput, unlockingScriptLengthForInstructions, } from '../utils/signOrdinalInput';
16
17
  // ============================================================================
17
18
  // Helpers
@@ -102,7 +103,8 @@ export async function resolveOrdinalTags(ctx, outpoint, source) {
102
103
  // ============================================================================
103
104
  // Internal helpers
104
105
  // ============================================================================
105
- async function deriveCancelAddressInternal(ctx, outpoint) {
106
+ /** Cancel/list key address for an outpoint (P1SAT self). */
107
+ export async function deriveCancelAddressInternal(ctx, outpoint) {
106
108
  const result = await ctx.wallet.getPublicKey({
107
109
  protocolID: P1SAT_PROTOCOL,
108
110
  keyID: outpoint,
@@ -110,7 +112,17 @@ async function deriveCancelAddressInternal(ctx, outpoint) {
110
112
  });
111
113
  return PublicKey.fromString(result.publicKey).toAddress();
112
114
  }
113
- function buildOrdLockScript(ordAddress, payAddress, price) {
115
+ /** Default OrdLock payment address: P1SAT keyID `1sat 0`, self. */
116
+ export async function defaultPayAddress(ctx) {
117
+ const result = await ctx.wallet.getPublicKey({
118
+ protocolID: P1SAT_PROTOCOL,
119
+ keyID: '1sat 0',
120
+ counterparty: 'self',
121
+ forSelf: true,
122
+ });
123
+ return PublicKey.fromString(result.publicKey).toAddress();
124
+ }
125
+ export function buildOrdLockScript(ordAddress, payAddress, price) {
114
126
  const cancelPkh = Utils.fromBase58Check(ordAddress).data;
115
127
  const payPkh = Utils.fromBase58Check(payAddress).data;
116
128
  const payoutScript = new P2PKH().lock(payPkh).toBinary();
@@ -172,9 +184,26 @@ async function buildPurchaseUnlockingScript(tx, inputIndex, sourceSatoshis, lock
172
184
  // ============================================================================
173
185
  // Builder functions (utilities for advanced use)
174
186
  // ============================================================================
187
+ async function loadOrdinalSpend(ctx, id) {
188
+ return loadBasketOutputBeef(ctx.wallet, ORDINALS_BASKET, id);
189
+ }
190
+ function nameFromOutput(output, tags) {
191
+ if (output.customInstructions) {
192
+ try {
193
+ const n = JSON.parse(output.customInstructions).name;
194
+ if (typeof n === 'string' && n)
195
+ return n.slice(0, 64);
196
+ }
197
+ catch { }
198
+ }
199
+ const fromTags = (tags ?? output.tags)
200
+ ?.find((t) => t.startsWith('name:'))
201
+ ?.slice(5);
202
+ return fromTags?.slice(0, 64);
203
+ }
175
204
  /**
176
205
  * Build CreateActionArgs for transferring one or more ordinals.
177
- * Does NOT execute - returns params for createAction.
206
+ * Loads each id once from the ordinals basket.
178
207
  */
179
208
  export async function buildTransferOrdinals(ctx, request) {
180
209
  const { transfers } = request;
@@ -184,11 +213,21 @@ export async function buildTransferOrdinals(ctx, request) {
184
213
  const inputs = [];
185
214
  const outputs = [];
186
215
  const labels = [];
187
- let resolvedBasket = ORDINALS_BASKET;
188
- for (const { ordinal, counterparty, address, map, extraTags } of transfers) {
216
+ const sources = [];
217
+ const beefParts = [];
218
+ for (const item of transfers) {
219
+ const { id, counterparty, address, map } = item;
220
+ if (!id)
221
+ return { error: 'missing-id' };
189
222
  if (!counterparty && !address) {
190
223
  return { error: 'must-provide-counterparty-or-address' };
191
224
  }
225
+ const loaded = await loadOrdinalSpend(ctx, id);
226
+ if ('error' in loaded)
227
+ return loaded;
228
+ const { output: ordinal, beef } = loaded;
229
+ sources.push(ordinal);
230
+ beefParts.push(beef);
192
231
  const outpoint = ordinal.outpoint;
193
232
  const sourceType = ordinal.tags
194
233
  ?.find((t) => t.startsWith('type:'))
@@ -215,24 +254,16 @@ export async function buildTransferOrdinals(ctx, request) {
215
254
  else {
216
255
  return { error: 'must-provide-counterparty-or-address' };
217
256
  }
218
- const { tags, basket } = await resolveOrdinalTags(ctx, outpoint, {
219
- tags: ordinal.tags,
220
- });
221
- if (extraTags)
222
- tags.push(...extraTags);
223
- resolvedBasket = basket;
257
+ const tags = ordinalSeedTags(ordinal);
258
+ const basket = ORDINALS_BASKET;
224
259
  inputs?.push({
225
260
  outpoint,
226
261
  inputDescription: 'Ordinal to transfer',
227
262
  unlockingScriptLength: unlockingScriptLengthForInstructions(ordinal.customInstructions),
228
263
  });
229
- // Emit a per-ordinal input label so the 1Sat permission module can
230
- // resolve the source output's id-tagged record in wallet storage and
231
- // render trusted metadata (origin / contentType / name).
232
264
  const inputId = readAssetIdTag(ordinal.tags);
233
265
  if (inputId)
234
266
  labels.push(buildInputAssetLabel(basket, inputId));
235
- // Build locking script — append MAP metadata when provided
236
267
  const p2pkhScript = new P2PKH().lock(recipientAddress);
237
268
  let lockingScript;
238
269
  if (map && Object.keys(map).length > 0) {
@@ -247,20 +278,8 @@ export async function buildTransferOrdinals(ctx, request) {
247
278
  else {
248
279
  lockingScript = p2pkhScript.toHex();
249
280
  }
250
- // Carry forward the name from CI, else from resolved tags.
251
- let sourceName;
252
- if (ordinal.customInstructions) {
253
- try {
254
- sourceName = JSON.parse(ordinal.customInstructions).name;
255
- }
256
- catch { }
257
- }
258
- if (!sourceName) {
259
- sourceName = tags.find((t) => t.startsWith('name:'))?.slice(5);
260
- }
281
+ const sourceName = nameFromOutput(ordinal, tags);
261
282
  if (isSelf) {
262
- // Keep the ordinal in our wallet with full labeling (register/deregister,
263
- // self-retags). External sends must not basket on the sender side.
264
283
  outputs?.push({
265
284
  lockingScript,
266
285
  satoshis: 1,
@@ -285,8 +304,9 @@ export async function buildTransferOrdinals(ctx, request) {
285
304
  });
286
305
  }
287
306
  }
288
- const inputBEEF = request.inputBEEF ??
289
- (await resolveBeef(ctx.wallet, resolvedBasket, transfers[0].ordinal));
307
+ if (!beefParts.length)
308
+ return { error: 'missing-input-beef' };
309
+ const inputBEEF = beefParts[0];
290
310
  return {
291
311
  description: transfers.length === 1
292
312
  ? 'Transfer ordinal'
@@ -295,18 +315,24 @@ export async function buildTransferOrdinals(ctx, request) {
295
315
  inputs,
296
316
  outputs,
297
317
  labels,
318
+ sources,
298
319
  };
299
320
  }
300
321
  /**
301
322
  * Build CreateActionArgs for listing an ordinal for sale.
302
- * Does NOT execute - returns params for createAction.
323
+ * Loads id once from the ordinals basket.
303
324
  */
304
325
  export async function buildListOrdinal(ctx, request) {
305
- const { ordinal, price, payAddress, map } = request;
306
- if (!payAddress)
307
- return { error: 'missing-pay-address' };
326
+ const { id, price, map } = request;
327
+ if (!id)
328
+ return { error: 'missing-id' };
308
329
  if (price <= 0)
309
330
  return { error: 'invalid-price' };
331
+ const loaded = await loadOrdinalSpend(ctx, id);
332
+ if ('error' in loaded)
333
+ return loaded;
334
+ const { output: ordinal, beef } = loaded;
335
+ const payAddress = request.payAddress ?? (await defaultPayAddress(ctx));
310
336
  const outpoint = ordinal.outpoint;
311
337
  const cancelAddress = await deriveCancelAddressInternal(ctx, outpoint);
312
338
  const ordLockScript = buildOrdLockScript(cancelAddress, payAddress, price);
@@ -325,23 +351,14 @@ export async function buildListOrdinal(ctx, request) {
325
351
  else {
326
352
  lockingScript = ordLockScript.toHex();
327
353
  }
328
- const { tags, basket } = await resolveOrdinalTags(ctx, outpoint, {
329
- tags: ordinal.tags,
330
- });
331
- tags.push('ordlock', `price:${price}`);
332
- let sourceName;
333
- if (ordinal.customInstructions) {
334
- try {
335
- sourceName = JSON.parse(ordinal.customInstructions).name;
336
- }
337
- catch { }
338
- }
339
- const inputBEEF = request.inputBEEF ?? (await resolveBeef(ctx.wallet, basket, ordinal));
354
+ const tags = [...ordinalSeedTags(ordinal), 'ordlock', `price:${price}`];
355
+ const basket = ORDINALS_BASKET;
356
+ const sourceName = nameFromOutput(ordinal, tags);
340
357
  const inputId = readAssetIdTag(ordinal.tags);
341
358
  const labels = inputId ? [buildInputAssetLabel(basket, inputId)] : undefined;
342
359
  return {
343
360
  description: `List ordinal for ${price} sats`,
344
- inputBEEF,
361
+ inputBEEF: beef,
345
362
  ...(labels && { labels }),
346
363
  inputs: [
347
364
  {
@@ -364,6 +381,7 @@ export async function buildListOrdinal(ctx, request) {
364
381
  }),
365
382
  },
366
383
  ],
384
+ source: ordinal,
367
385
  };
368
386
  }
369
387
  /**
@@ -371,17 +389,23 @@ export async function buildListOrdinal(ctx, request) {
371
389
  * Does NOT execute - returns params for createAction.
372
390
  */
373
391
  export async function buildBurnOrdinals(ctx, request) {
374
- const { ordinals } = request;
375
- if (!ordinals.length) {
392
+ const ordinals = [];
393
+ const beefParts = [];
394
+ if (!request.ids?.length) {
376
395
  return { error: 'no-ordinals' };
377
396
  }
397
+ for (const id of request.ids) {
398
+ const loaded = await loadOrdinalSpend(ctx, id);
399
+ if ('error' in loaded)
400
+ return loaded;
401
+ ordinals.push(loaded.output);
402
+ beefParts.push(loaded.beef);
403
+ }
378
404
  const inputs = ordinals.map((ordinal) => ({
379
405
  outpoint: ordinal.outpoint,
380
406
  inputDescription: 'Ordinal to burn',
381
407
  unlockingScriptLength: unlockingScriptLengthForInstructions(ordinal.customInstructions),
382
408
  }));
383
- const inputBEEF = request.inputBEEF ??
384
- (await resolveBeef(ctx.wallet, ORDINALS_BASKET, ordinals[0]));
385
409
  const mapScript = MAPTemplate.set({
386
410
  app: request.app ?? '1sat',
387
411
  type: 'ord',
@@ -398,7 +422,7 @@ export async function buildBurnOrdinals(ctx, request) {
398
422
  description: ordinals.length === 1
399
423
  ? 'Burn ordinal'
400
424
  : `Burn ${ordinals.length} ordinals`,
401
- inputBEEF,
425
+ inputBEEF: beefParts[0],
402
426
  ...(labels.length > 0 && { labels }),
403
427
  inputs,
404
428
  outputs: [
@@ -408,19 +432,27 @@ export async function buildBurnOrdinals(ctx, request) {
408
432
  outputDescription: 'Burn ordinals',
409
433
  },
410
434
  ],
435
+ sources: ordinals,
411
436
  };
412
437
  }
413
438
  /**
414
- * Get ordinals from the wallet with BEEF for spending.
439
+ * List ordinals in the wallet. Metadata (tags/CI) by default; BEEF on demand.
415
440
  */
416
- export const getOrdinals = {
441
+ export const listOrdinals = {
417
442
  meta: {
418
- name: 'getOrdinals',
419
- description: 'Get ordinals/inscriptions from the wallet with BEEF for spending',
443
+ name: 'listOrdinals',
444
+ description: 'List ordinals/inscriptions (metadata by default; optional BEEF)',
420
445
  category: 'ordinals',
421
446
  inputSchema: {
422
447
  type: 'object',
423
448
  properties: {
449
+ tags: { type: 'array', items: { type: 'string' } },
450
+ tagQueryMode: { type: 'string', enum: ['all', 'any'] },
451
+ ids: { type: 'array', items: { type: 'string' } },
452
+ include: {
453
+ type: 'string',
454
+ enum: ['locking scripts', 'entire transactions'],
455
+ },
424
456
  limit: {
425
457
  type: 'integer',
426
458
  description: 'Max ordinals to return (default: 100)',
@@ -433,26 +465,42 @@ export const getOrdinals = {
433
465
  },
434
466
  },
435
467
  async execute(ctx, input) {
468
+ const tags = [...(input.tags ?? [])];
469
+ for (const id of input.ids ?? []) {
470
+ if (id)
471
+ tags.push(id.startsWith('id:') ? id : `id:${id}`);
472
+ }
473
+ const filtering = tags.length > 0;
436
474
  const result = await ctx.wallet.listOutputs({
437
475
  basket: ORDINALS_BASKET,
438
- includeTags: true,
439
- includeCustomInstructions: true,
440
- include: 'entire transactions',
476
+ ...(filtering && {
477
+ tags,
478
+ tagQueryMode: input.tagQueryMode ?? 'any',
479
+ }),
480
+ ...(input.include && { include: input.include }),
481
+ includeTags: input.includeTags ?? true,
482
+ includeCustomInstructions: input.includeCustomInstructions ?? true,
483
+ ...(input.includeLabels != null && {
484
+ includeLabels: input.includeLabels,
485
+ }),
441
486
  limit: input.limit ?? 100,
442
487
  offset: input.offset ?? 0,
443
488
  });
444
489
  return {
445
490
  outputs: result.outputs,
446
491
  BEEF: result.BEEF,
492
+ totalOutputs: result.totalOutputs,
447
493
  };
448
494
  },
449
495
  };
496
+ /** @deprecated Use listOrdinals */
497
+ export const getOrdinals = listOrdinals;
450
498
  /**
451
499
  * Transfer an ordinal to a new owner.
452
500
  */
453
- export const transferOrdinals = {
501
+ export const sendOrdinals = {
454
502
  meta: {
455
- name: 'transferOrdinals',
503
+ name: 'sendOrdinals',
456
504
  description: 'Transfer one or more ordinals to new owners',
457
505
  category: 'ordinals',
458
506
  inputSchema: {
@@ -464,9 +512,9 @@ export const transferOrdinals = {
464
512
  items: {
465
513
  type: 'object',
466
514
  properties: {
467
- ordinal: {
468
- type: 'object',
469
- description: 'WalletOutput from listOutputs',
515
+ id: {
516
+ type: 'string',
517
+ description: 'Tracking id in the ordinals basket',
470
518
  },
471
519
  counterparty: {
472
520
  type: 'string',
@@ -481,15 +529,11 @@ export const transferOrdinals = {
481
529
  description: 'Optional MAP metadata to append to the output script',
482
530
  },
483
531
  },
484
- required: ['ordinal'],
532
+ required: ['id'],
485
533
  },
486
534
  },
487
- inputBEEF: {
488
- type: 'array',
489
- description: "BEEF from listOutputs with include: 'entire transactions'",
490
- },
491
535
  },
492
- required: ['transfers', 'inputBEEF'],
536
+ required: ['transfers'],
493
537
  },
494
538
  },
495
539
  async execute(ctx, input) {
@@ -522,13 +566,14 @@ export const transferOrdinals = {
522
566
  catch (e) {
523
567
  console.log('[transferOrdinals] BEEF parse error:', e);
524
568
  }
569
+ const { sources, ...createArgs } = params;
525
570
  const result = await executeTrackedAction(ctx.wallet, {
526
- ...params,
571
+ ...createArgs,
527
572
  options: { randomizeOutputs: false },
528
573
  }, input.fundingProvider, params.inputBEEF, async (tx) => {
529
574
  const spends = {};
530
- for (let i = 0; i < input.transfers.length; i++) {
531
- const { ordinal } = input.transfers[i];
575
+ for (let i = 0; i < sources.length; i++) {
576
+ const ordinal = sources[i];
532
577
  if (!ordinal.customInstructions) {
533
578
  throw new Error(`missing-custom-instructions-for-${ordinal.outpoint}`);
534
579
  }
@@ -540,10 +585,10 @@ export const transferOrdinals = {
540
585
  return spends;
541
586
  });
542
587
  if (ctx.debug && ctx.log) {
543
- const logOutputs = input.transfers.map((t, i) => ({
588
+ const logOutputs = sources.map((s, i) => ({
544
589
  index: i,
545
590
  protocolID: P1SAT_PROTOCOL,
546
- keyID: t.ordinal.outpoint,
591
+ keyID: s.outpoint,
547
592
  basket: ORDINALS_BASKET,
548
593
  satoshis: 1,
549
594
  }));
@@ -552,7 +597,7 @@ export const transferOrdinals = {
552
597
  action: 'transferOrdinals',
553
598
  input: {
554
599
  transfers: input.transfers.map((t) => ({
555
- outpoint: t.ordinal.outpoint,
600
+ id: t.id,
556
601
  counterparty: t.counterparty,
557
602
  address: t.address,
558
603
  })),
@@ -572,7 +617,7 @@ export const transferOrdinals = {
572
617
  action: 'transferOrdinals',
573
618
  input: {
574
619
  transfers: input.transfers.map((t) => ({
575
- outpoint: t.ordinal.outpoint,
620
+ id: t.id,
576
621
  })),
577
622
  },
578
623
  error: error instanceof Error ? error.message : 'unknown-error',
@@ -584,36 +629,34 @@ export const transferOrdinals = {
584
629
  }
585
630
  },
586
631
  };
632
+ /** @deprecated Use sendOrdinals */
633
+ export const transferOrdinals = sendOrdinals;
587
634
  /**
588
635
  * List an ordinal for sale on the global orderbook.
589
636
  */
590
- export const listOrdinal = {
637
+ export const sellOrdinal = {
591
638
  meta: {
592
- name: 'listOrdinal',
639
+ name: 'sellOrdinal',
593
640
  description: 'List an ordinal for sale on the global orderbook',
594
641
  category: 'ordinals',
595
642
  inputSchema: {
596
643
  type: 'object',
597
644
  properties: {
598
- ordinal: {
599
- type: 'object',
600
- description: 'WalletOutput from listOutputs',
601
- },
602
- inputBEEF: {
603
- type: 'array',
604
- description: "BEEF from listOutputs with include: 'entire transactions'",
645
+ id: {
646
+ type: 'string',
647
+ description: 'Tracking id in the ordinals basket',
605
648
  },
606
649
  price: { type: 'integer', description: 'Price in satoshis' },
607
650
  payAddress: {
608
651
  type: 'string',
609
- description: 'Address to receive payment on purchase',
652
+ description: 'Address to receive payment (default: P1SAT keyID 1sat 0)',
610
653
  },
611
654
  map: {
612
655
  type: 'object',
613
656
  description: 'Optional MAP metadata to append to the listing output script',
614
657
  },
615
658
  },
616
- required: ['ordinal', 'inputBEEF', 'price', 'payAddress'],
659
+ required: ['id', 'price'],
617
660
  },
618
661
  },
619
662
  async execute(ctx, input) {
@@ -622,14 +665,15 @@ export const listOrdinal = {
622
665
  if ('error' in params) {
623
666
  return params;
624
667
  }
625
- if (!input.ordinal.customInstructions) {
668
+ const { source, ...createArgs } = params;
669
+ if (!source.customInstructions) {
626
670
  return { error: 'missing-custom-instructions' };
627
671
  }
628
672
  const result = await executeTrackedAction(ctx.wallet, {
629
- ...params,
673
+ ...createArgs,
630
674
  options: { randomizeOutputs: false },
631
675
  }, input.fundingProvider, params.inputBEEF, async (tx) => {
632
- const unlocking = await signOrdinalInput(ctx, tx, 0, input.ordinal.customInstructions);
676
+ const unlocking = await signOrdinalInput(ctx, tx, 0, source.customInstructions);
633
677
  if (typeof unlocking !== 'string')
634
678
  throw new Error(unlocking.error);
635
679
  return { 0: { unlockingScript: unlocking } };
@@ -637,15 +681,15 @@ export const listOrdinal = {
637
681
  if (ctx.debug && ctx.log) {
638
682
  ctx.log({
639
683
  timestamp: new Date().toISOString(),
640
- action: 'listOrdinal',
641
- input: { outpoint: input.ordinal.outpoint, price: input.price },
684
+ action: 'sellOrdinal',
685
+ input: { outpoint: source.outpoint, price: input.price },
642
686
  txid: result.txid,
643
687
  rawtx: result.tx ? Utils.toHex(result.tx) : undefined,
644
688
  outputs: [
645
689
  {
646
690
  index: 0,
647
691
  protocolID: P1SAT_PROTOCOL,
648
- keyID: input.ordinal.outpoint,
692
+ keyID: source.outpoint,
649
693
  basket: ORDINALS_BASKET,
650
694
  satoshis: 1,
651
695
  },
@@ -655,12 +699,12 @@ export const listOrdinal = {
655
699
  return result;
656
700
  }
657
701
  catch (error) {
658
- console.error('[listOrdinal]', error);
702
+ console.error('[sellOrdinal]', error);
659
703
  if (ctx.debug && ctx.log) {
660
704
  ctx.log({
661
705
  timestamp: new Date().toISOString(),
662
- action: 'listOrdinal',
663
- input: { outpoint: input.ordinal.outpoint, price: input.price },
706
+ action: 'sellOrdinal',
707
+ input: { price: input.price },
664
708
  error: error instanceof Error ? error.message : 'unknown-error',
665
709
  });
666
710
  }
@@ -670,32 +714,35 @@ export const listOrdinal = {
670
714
  }
671
715
  },
672
716
  };
717
+ /** @deprecated Use sellOrdinal */
718
+ export const listOrdinal = sellOrdinal;
673
719
  /**
674
720
  * Cancel an ordinal listing.
675
721
  */
676
- export const cancelListing = {
722
+ export const cancelOrdinalListing = {
677
723
  meta: {
678
- name: 'cancelListing',
724
+ name: 'cancelOrdinalListing',
679
725
  description: 'Cancel an ordinal listing and return the ordinal to the wallet',
680
726
  category: 'ordinals',
681
727
  inputSchema: {
682
728
  type: 'object',
683
729
  properties: {
684
- listing: {
685
- type: 'object',
686
- description: 'WalletOutput of the listing (must include lockingScript)',
687
- },
688
- inputBEEF: {
689
- type: 'array',
690
- description: 'BEEF — resolved automatically via ID tag if omitted',
730
+ id: {
731
+ type: 'string',
732
+ description: 'Tracking id of the listing in the ordinals basket',
691
733
  },
692
734
  },
693
- required: ['listing'],
735
+ required: ['id'],
694
736
  },
695
737
  },
696
738
  async execute(ctx, input) {
697
739
  try {
698
- const { listing } = input;
740
+ if (!input.id)
741
+ return { error: 'missing-id' };
742
+ const loaded = await loadOrdinalSpend(ctx, input.id);
743
+ if ('error' in loaded)
744
+ return loaded;
745
+ const { output: listing, beef: inputBEEF } = loaded;
699
746
  const outpoint = listing.outpoint;
700
747
  if (!listing.customInstructions) {
701
748
  return { error: 'missing-custom-instructions' };
@@ -712,18 +759,9 @@ export const cancelListing = {
712
759
  // derivation so the next spend reproduces the same key.
713
760
  const newKeyID = outpoint;
714
761
  const cancelAddress = await deriveCancelAddressInternal(ctx, newKeyID);
715
- const { tags, basket } = await resolveOrdinalTags(ctx, outpoint, {
716
- tags: listing.tags,
717
- });
718
- const inputBEEF = input.inputBEEF ?? (await resolveBeef(ctx.wallet, basket, listing));
719
- let sourceName;
720
- try {
721
- sourceName = JSON.parse(listing.customInstructions).name;
722
- }
723
- catch { }
724
- if (!sourceName) {
725
- sourceName = tags.find((t) => t.startsWith('name:'))?.slice(5);
726
- }
762
+ const tags = ordinalSeedTags(listing);
763
+ const basket = ORDINALS_BASKET;
764
+ const sourceName = nameFromOutput(listing, tags);
727
765
  const cancelUnlock = OrdLock.cancelWithWallet(ctx.wallet, signProtocolID, signKeyID, signCounterparty);
728
766
  const inputId = readAssetIdTag(listing.tags);
729
767
  const result = await executeTrackedAction(ctx.wallet, {
@@ -761,7 +799,7 @@ export const cancelListing = {
761
799
  if (ctx.debug && ctx.log) {
762
800
  ctx.log({
763
801
  timestamp: new Date().toISOString(),
764
- action: 'cancelListing',
802
+ action: 'cancelOrdinalListing',
765
803
  input: { outpoint, signKeyID },
766
804
  txid: result.txid,
767
805
  rawtx: result.tx ? Utils.toHex(result.tx) : undefined,
@@ -778,12 +816,12 @@ export const cancelListing = {
778
816
  return result;
779
817
  }
780
818
  catch (error) {
781
- console.error('[cancelListing]', error);
819
+ console.error('[cancelOrdinalListing]', error);
782
820
  if (ctx.debug && ctx.log) {
783
821
  ctx.log({
784
822
  timestamp: new Date().toISOString(),
785
- action: 'cancelListing',
786
- input: { outpoint: input.listing.outpoint },
823
+ action: 'cancelOrdinalListing',
824
+ input: { id: input.id },
787
825
  error: error instanceof Error ? error.message : 'unknown-error',
788
826
  });
789
827
  }
@@ -793,12 +831,14 @@ export const cancelListing = {
793
831
  }
794
832
  },
795
833
  };
834
+ /** @deprecated Use cancelOrdinalListing */
835
+ export const cancelListing = cancelOrdinalListing;
796
836
  /**
797
837
  * Purchase an ordinal from the global orderbook.
798
838
  */
799
- export const purchaseOrdinal = {
839
+ export const buyOrdinal = {
800
840
  meta: {
801
- name: 'purchaseOrdinal',
841
+ name: 'buyOrdinal',
802
842
  description: 'Purchase an ordinal from the global orderbook',
803
843
  category: 'ordinals',
804
844
  requiresServices: true,
@@ -809,6 +849,11 @@ export const purchaseOrdinal = {
809
849
  type: 'string',
810
850
  description: 'Outpoint of the listing to purchase',
811
851
  },
852
+ inputBEEF: {
853
+ type: 'array',
854
+ description: 'BEEF for listing tx; else services fetch',
855
+ items: { type: 'integer' },
856
+ },
812
857
  marketplaceAddress: {
813
858
  type: 'string',
814
859
  description: 'Marketplace address for fees',
@@ -832,16 +877,32 @@ export const purchaseOrdinal = {
832
877
  async execute(ctx, input) {
833
878
  try {
834
879
  const { outpoint, marketplaceAddress, marketplaceRate } = input;
835
- if (!ctx.services) {
836
- return { error: 'services-required-for-purchase' };
837
- }
838
880
  const { txid, vout } = parseOutpoint(outpoint);
839
- const { tags, basket } = await resolveOrdinalTags(ctx, outpoint, {
840
- contentType: input.contentType,
841
- origin: input.origin,
842
- name: input.name,
843
- });
844
- const beef = await ctx.services.getBeefForTxid(txid);
881
+ let tags;
882
+ let basket;
883
+ if (input.tags?.length) {
884
+ basket = input.basket ?? ORDINALS_BASKET;
885
+ tags = input.tags;
886
+ }
887
+ else {
888
+ const resolved = await resolveOrdinalTags(ctx, outpoint, {
889
+ contentType: input.contentType,
890
+ origin: input.origin,
891
+ name: input.name,
892
+ });
893
+ tags = resolved.tags;
894
+ basket = input.basket ?? resolved.basket;
895
+ }
896
+ let beef;
897
+ if (input.inputBEEF) {
898
+ beef = Beef.fromBinary(input.inputBEEF);
899
+ }
900
+ else {
901
+ if (!ctx.services) {
902
+ return { error: 'services-required-for-purchase' };
903
+ }
904
+ beef = await ctx.services.getBeefForTxid(txid);
905
+ }
845
906
  const listingBeefTx = beef.findTxid(txid);
846
907
  if (!listingBeefTx?.tx) {
847
908
  return { error: 'listing-transaction-not-found' };
@@ -862,6 +923,7 @@ export const purchaseOrdinal = {
862
923
  });
863
924
  const ourOrdAddress = PublicKey.fromString(publicKey).toAddress();
864
925
  const outputs = [];
926
+ const name = input.name ?? tags.find((t) => t.startsWith('name:'))?.slice(5);
865
927
  outputs.push({
866
928
  lockingScript: new P2PKH().lock(ourOrdAddress).toHex(),
867
929
  satoshis: 1,
@@ -871,7 +933,7 @@ export const purchaseOrdinal = {
871
933
  customInstructions: JSON.stringify({
872
934
  protocolID: P1SAT_PROTOCOL,
873
935
  keyID: outpoint,
874
- ...(input.name && { name: input.name }),
936
+ ...(name && { name }),
875
937
  }),
876
938
  });
877
939
  const payoutReader = new Utils.Reader(ordLockData.payout);
@@ -916,7 +978,7 @@ export const purchaseOrdinal = {
916
978
  if (ctx.debug && ctx.log) {
917
979
  ctx.log({
918
980
  timestamp: new Date().toISOString(),
919
- action: 'purchaseOrdinal',
981
+ action: 'buyOrdinal',
920
982
  input: { outpoint },
921
983
  txid: result.txid,
922
984
  rawtx: result.tx ? Utils.toHex(result.tx) : undefined,
@@ -934,11 +996,11 @@ export const purchaseOrdinal = {
934
996
  return result;
935
997
  }
936
998
  catch (error) {
937
- console.error('[purchaseOrdinal]', error);
999
+ console.error('[buyOrdinal]', error);
938
1000
  if (ctx.debug && ctx.log) {
939
1001
  ctx.log({
940
1002
  timestamp: new Date().toISOString(),
941
- action: 'purchaseOrdinal',
1003
+ action: 'buyOrdinal',
942
1004
  input: { outpoint: input.outpoint },
943
1005
  error: error instanceof Error ? error.message : 'unknown-error',
944
1006
  });
@@ -949,6 +1011,8 @@ export const purchaseOrdinal = {
949
1011
  }
950
1012
  },
951
1013
  };
1014
+ /** @deprecated Use buyOrdinal */
1015
+ export const purchaseOrdinal = buyOrdinal;
952
1016
  /**
953
1017
  * Burn one or more ordinals (send to OP_FALSE OP_RETURN).
954
1018
  */
@@ -960,20 +1024,13 @@ export const burnOrdinals = {
960
1024
  inputSchema: {
961
1025
  type: 'object',
962
1026
  properties: {
963
- ordinals: {
1027
+ ids: {
964
1028
  type: 'array',
965
- description: 'WalletOutputs to burn',
966
- items: {
967
- type: 'object',
968
- description: 'WalletOutput from listOutputs',
969
- },
970
- },
971
- inputBEEF: {
972
- type: 'array',
973
- description: 'BEEF — resolved automatically via ID tag if omitted',
1029
+ description: 'Tracking ids in the ordinals basket',
1030
+ items: { type: 'string' },
974
1031
  },
975
1032
  },
976
- required: ['ordinals'],
1033
+ required: ['ids'],
977
1034
  },
978
1035
  },
979
1036
  async execute(ctx, input) {
@@ -982,24 +1039,14 @@ export const burnOrdinals = {
982
1039
  if ('error' in params) {
983
1040
  return params;
984
1041
  }
985
- console.log('[burnOrdinals] params:', JSON.stringify({
986
- description: params.description,
987
- inputBEEF: params.inputBEEF
988
- ? `[${params.inputBEEF.length} bytes]`
989
- : 'undefined',
990
- inputs: params.inputs,
991
- outputs: params.outputs?.map((o) => ({
992
- ...o,
993
- lockingScript: `${o.lockingScript?.slice(0, 20)}...`,
994
- })),
995
- }, null, 2));
1042
+ const { sources, ...createArgs } = params;
996
1043
  const result = await executeTrackedAction(ctx.wallet, {
997
- ...params,
1044
+ ...createArgs,
998
1045
  options: { randomizeOutputs: false },
999
1046
  }, input.fundingProvider, params.inputBEEF, async (tx) => {
1000
1047
  const spends = {};
1001
- for (let i = 0; i < input.ordinals.length; i++) {
1002
- const ordinal = input.ordinals[i];
1048
+ for (let i = 0; i < sources.length; i++) {
1049
+ const ordinal = sources[i];
1003
1050
  if (!ordinal.customInstructions) {
1004
1051
  throw new Error(`missing-custom-instructions-for-${ordinal.outpoint}`);
1005
1052
  }
@@ -1014,11 +1061,7 @@ export const burnOrdinals = {
1014
1061
  ctx.log({
1015
1062
  timestamp: new Date().toISOString(),
1016
1063
  action: 'burnOrdinals',
1017
- input: {
1018
- ordinals: input.ordinals.map((o) => ({
1019
- outpoint: o.outpoint,
1020
- })),
1021
- },
1064
+ input: { ids: input.ids },
1022
1065
  txid: result.txid,
1023
1066
  rawtx: result.tx ? Utils.toHex(result.tx) : undefined,
1024
1067
  });
@@ -1031,11 +1074,7 @@ export const burnOrdinals = {
1031
1074
  ctx.log({
1032
1075
  timestamp: new Date().toISOString(),
1033
1076
  action: 'burnOrdinals',
1034
- input: {
1035
- ordinals: input.ordinals.map((o) => ({
1036
- outpoint: o.outpoint,
1037
- })),
1038
- },
1077
+ input: { ids: input.ids },
1039
1078
  error: error instanceof Error ? error.message : 'unknown-error',
1040
1079
  });
1041
1080
  }
@@ -1050,11 +1089,11 @@ export const burnOrdinals = {
1050
1089
  // ============================================================================
1051
1090
  /** All ordinals actions for registry */
1052
1091
  export const ordinalsActions = [
1053
- getOrdinals,
1054
- transferOrdinals,
1055
- listOrdinal,
1056
- cancelListing,
1057
- purchaseOrdinal,
1092
+ listOrdinals,
1093
+ sendOrdinals,
1094
+ sellOrdinal,
1095
+ cancelOrdinalListing,
1096
+ buyOrdinal,
1058
1097
  burnOrdinals,
1059
1098
  ];
1060
1099
  //# sourceMappingURL=index.js.map