@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.
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/inscriptions/index.d.ts +2 -2
- package/dist/inscriptions/index.d.ts.map +1 -1
- package/dist/inscriptions/index.js +3 -6
- package/dist/inscriptions/index.js.map +1 -1
- package/dist/locks/index.d.ts +32 -3
- package/dist/locks/index.d.ts.map +1 -1
- package/dist/locks/index.js +76 -5
- package/dist/locks/index.js.map +1 -1
- package/dist/opns/index.d.ts +90 -65
- package/dist/opns/index.d.ts.map +1 -1
- package/dist/opns/index.js +517 -188
- package/dist/opns/index.js.map +1 -1
- package/dist/ordinals/index.d.ts +76 -42
- package/dist/ordinals/index.d.ts.map +1 -1
- package/dist/ordinals/index.js +219 -180
- package/dist/ordinals/index.js.map +1 -1
- package/dist/tokens/index.d.ts +5 -1
- package/dist/tokens/index.d.ts.map +1 -1
- package/dist/tokens/index.js +36 -18
- package/dist/tokens/index.js.map +1 -1
- package/dist/utils/createTrackedAction.js +1 -1
- package/dist/utils/internalizeBeef.d.ts.map +1 -1
- package/dist/utils/internalizeBeef.js +1 -25
- package/dist/utils/internalizeBeef.js.map +1 -1
- package/dist/utils/loadBasketOutput.d.ts +25 -0
- package/dist/utils/loadBasketOutput.d.ts.map +1 -0
- package/dist/utils/loadBasketOutput.js +50 -0
- package/dist/utils/loadBasketOutput.js.map +1 -0
- package/dist/utils/ordinalSeedTags.d.ts +8 -0
- package/dist/utils/ordinalSeedTags.d.ts.map +1 -0
- package/dist/utils/ordinalSeedTags.js +24 -0
- package/dist/utils/ordinalSeedTags.js.map +1 -0
- package/package.json +9 -9
- package/dist/utils/resolveBeef.d.ts +0 -20
- package/dist/utils/resolveBeef.d.ts.map +0 -1
- package/dist/utils/resolveBeef.js +0 -36
- package/dist/utils/resolveBeef.js.map +0 -1
package/dist/ordinals/index.js
CHANGED
|
@@ -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 {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
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
|
-
|
|
188
|
-
|
|
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
|
|
219
|
-
|
|
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
|
-
|
|
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
|
-
|
|
289
|
-
|
|
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
|
-
*
|
|
323
|
+
* Loads id once from the ordinals basket.
|
|
303
324
|
*/
|
|
304
325
|
export async function buildListOrdinal(ctx, request) {
|
|
305
|
-
const {
|
|
306
|
-
if (!
|
|
307
|
-
return { error: 'missing-
|
|
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
|
|
329
|
-
|
|
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
|
|
375
|
-
|
|
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
|
-
*
|
|
439
|
+
* List ordinals in the wallet. Metadata (tags/CI) by default; BEEF on demand.
|
|
415
440
|
*/
|
|
416
|
-
export const
|
|
441
|
+
export const listOrdinals = {
|
|
417
442
|
meta: {
|
|
418
|
-
name: '
|
|
419
|
-
description: '
|
|
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
|
-
|
|
439
|
-
|
|
440
|
-
|
|
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
|
|
501
|
+
export const sendOrdinals = {
|
|
454
502
|
meta: {
|
|
455
|
-
name: '
|
|
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
|
-
|
|
468
|
-
type: '
|
|
469
|
-
description: '
|
|
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: ['
|
|
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'
|
|
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
|
-
...
|
|
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 <
|
|
531
|
-
const
|
|
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 =
|
|
588
|
+
const logOutputs = sources.map((s, i) => ({
|
|
544
589
|
index: i,
|
|
545
590
|
protocolID: P1SAT_PROTOCOL,
|
|
546
|
-
keyID:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
637
|
+
export const sellOrdinal = {
|
|
591
638
|
meta: {
|
|
592
|
-
name: '
|
|
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
|
-
|
|
599
|
-
type: '
|
|
600
|
-
description: '
|
|
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
|
|
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: ['
|
|
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
|
-
|
|
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
|
-
...
|
|
673
|
+
...createArgs,
|
|
630
674
|
options: { randomizeOutputs: false },
|
|
631
675
|
}, input.fundingProvider, params.inputBEEF, async (tx) => {
|
|
632
|
-
const unlocking = await signOrdinalInput(ctx, tx, 0,
|
|
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: '
|
|
641
|
-
input: { outpoint:
|
|
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:
|
|
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('[
|
|
702
|
+
console.error('[sellOrdinal]', error);
|
|
659
703
|
if (ctx.debug && ctx.log) {
|
|
660
704
|
ctx.log({
|
|
661
705
|
timestamp: new Date().toISOString(),
|
|
662
|
-
action: '
|
|
663
|
-
input: {
|
|
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
|
|
722
|
+
export const cancelOrdinalListing = {
|
|
677
723
|
meta: {
|
|
678
|
-
name: '
|
|
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
|
-
|
|
685
|
-
type: '
|
|
686
|
-
description: '
|
|
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: ['
|
|
735
|
+
required: ['id'],
|
|
694
736
|
},
|
|
695
737
|
},
|
|
696
738
|
async execute(ctx, input) {
|
|
697
739
|
try {
|
|
698
|
-
|
|
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
|
|
716
|
-
|
|
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: '
|
|
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('[
|
|
819
|
+
console.error('[cancelOrdinalListing]', error);
|
|
782
820
|
if (ctx.debug && ctx.log) {
|
|
783
821
|
ctx.log({
|
|
784
822
|
timestamp: new Date().toISOString(),
|
|
785
|
-
action: '
|
|
786
|
-
input: {
|
|
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
|
|
839
|
+
export const buyOrdinal = {
|
|
800
840
|
meta: {
|
|
801
|
-
name: '
|
|
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
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
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
|
-
...(
|
|
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: '
|
|
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('[
|
|
999
|
+
console.error('[buyOrdinal]', error);
|
|
938
1000
|
if (ctx.debug && ctx.log) {
|
|
939
1001
|
ctx.log({
|
|
940
1002
|
timestamp: new Date().toISOString(),
|
|
941
|
-
action: '
|
|
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
|
-
|
|
1027
|
+
ids: {
|
|
964
1028
|
type: 'array',
|
|
965
|
-
description: '
|
|
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: ['
|
|
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
|
-
|
|
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
|
-
...
|
|
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 <
|
|
1002
|
-
const ordinal =
|
|
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
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1092
|
+
listOrdinals,
|
|
1093
|
+
sendOrdinals,
|
|
1094
|
+
sellOrdinal,
|
|
1095
|
+
cancelOrdinalListing,
|
|
1096
|
+
buyOrdinal,
|
|
1058
1097
|
burnOrdinals,
|
|
1059
1098
|
];
|
|
1060
1099
|
//# sourceMappingURL=index.js.map
|