@1sat/actions 0.0.191 → 0.0.193
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/apply/applyIntent.d.ts +18 -0
- package/dist/apply/applyIntent.d.ts.map +1 -0
- package/dist/apply/applyIntent.js +32 -0
- package/dist/apply/applyIntent.js.map +1 -0
- package/dist/apply/index.d.ts +9 -0
- package/dist/apply/index.d.ts.map +1 -0
- package/dist/apply/index.js +8 -0
- package/dist/apply/index.js.map +1 -0
- package/dist/apply/inscribeSigma.d.ts +15 -0
- package/dist/apply/inscribeSigma.d.ts.map +1 -0
- package/dist/apply/inscribeSigma.js +92 -0
- package/dist/apply/inscribeSigma.js.map +1 -0
- package/dist/apply/opnsRegister.d.ts +7 -0
- package/dist/apply/opnsRegister.d.ts.map +1 -0
- package/dist/apply/opnsRegister.js +29 -0
- package/dist/apply/opnsRegister.js.map +1 -0
- package/dist/apply/prepare.d.ts +12 -0
- package/dist/apply/prepare.d.ts.map +1 -0
- package/dist/apply/prepare.js +26 -0
- package/dist/apply/prepare.js.map +1 -0
- package/dist/apply/registry.d.ts +8 -0
- package/dist/apply/registry.d.ts.map +1 -0
- package/dist/apply/registry.js +31 -0
- package/dist/apply/registry.js.map +1 -0
- package/dist/apply/stampScriptTags.d.ts +19 -0
- package/dist/apply/stampScriptTags.d.ts.map +1 -0
- package/dist/apply/stampScriptTags.js +47 -0
- package/dist/apply/stampScriptTags.js.map +1 -0
- package/dist/apply/validateOnly.d.ts +7 -0
- package/dist/apply/validateOnly.d.ts.map +1 -0
- package/dist/apply/validateOnly.js +8 -0
- package/dist/apply/validateOnly.js.map +1 -0
- package/dist/collections/index.d.ts.map +1 -1
- package/dist/collections/index.js +9 -5
- package/dist/collections/index.js.map +1 -1
- package/dist/constants.d.ts +1 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +1 -1
- package/dist/constants.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/inscriptions/index.d.ts.map +1 -1
- package/dist/inscriptions/index.js +23 -58
- package/dist/inscriptions/index.js.map +1 -1
- package/dist/locks/index.d.ts.map +1 -1
- package/dist/locks/index.js +16 -7
- package/dist/locks/index.js.map +1 -1
- package/dist/opns/index.d.ts +0 -26
- package/dist/opns/index.d.ts.map +1 -1
- package/dist/opns/index.js +75 -62
- package/dist/opns/index.js.map +1 -1
- package/dist/ordinals/index.d.ts +3 -21
- package/dist/ordinals/index.d.ts.map +1 -1
- package/dist/ordinals/index.js +69 -65
- package/dist/ordinals/index.js.map +1 -1
- package/dist/signing/aip.d.ts +3 -4
- package/dist/signing/aip.d.ts.map +1 -1
- package/dist/signing/aip.js +8 -14
- package/dist/signing/aip.js.map +1 -1
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +13 -1
- package/dist/sync/index.js.map +1 -1
- package/dist/tokens/index.d.ts +1 -5
- package/dist/tokens/index.d.ts.map +1 -1
- package/dist/tokens/index.js +79 -162
- package/dist/tokens/index.js.map +1 -1
- package/dist/types.d.ts +9 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -1
- package/dist/utils/createTrackedAction.d.ts +9 -0
- package/dist/utils/createTrackedAction.d.ts.map +1 -1
- package/dist/utils/createTrackedAction.js +24 -9
- package/dist/utils/createTrackedAction.js.map +1 -1
- package/dist/utils/resolveDestination.d.ts +8 -0
- package/dist/utils/resolveDestination.d.ts.map +1 -1
- package/dist/utils/resolveDestination.js +1 -1
- package/dist/utils/resolveDestination.js.map +1 -1
- package/dist/utils/signOrdinalInput.d.ts.map +1 -1
- package/dist/utils/signOrdinalInput.js +56 -4
- package/dist/utils/signOrdinalInput.js.map +1 -1
- package/package.json +7 -7
package/dist/tokens/index.d.ts
CHANGED
|
@@ -115,7 +115,7 @@ export interface MintBsv21Response extends TokenOperationResponse {
|
|
|
115
115
|
/** Outpoint of the new auth UTXO, if one was emitted. */
|
|
116
116
|
authOutpoint?: string;
|
|
117
117
|
}
|
|
118
|
-
/** Input for
|
|
118
|
+
/** Input for listBsv21 action */
|
|
119
119
|
export interface ListTokensInput {
|
|
120
120
|
/** Max number of tokens to return */
|
|
121
121
|
limit?: number;
|
|
@@ -124,8 +124,6 @@ export interface ListTokensInput {
|
|
|
124
124
|
* List BSV21 token outputs from the wallet.
|
|
125
125
|
*/
|
|
126
126
|
export declare const listBsv21: Action<ListTokensInput, WalletOutput[]>;
|
|
127
|
-
/** @deprecated Use listBsv21 */
|
|
128
|
-
export declare const listTokens: Action<ListTokensInput, WalletOutput[]>;
|
|
129
127
|
/** Input for getBsv21Balances action (no required params) */
|
|
130
128
|
export type GetBsv21BalancesInput = Record<string, never>;
|
|
131
129
|
/**
|
|
@@ -165,7 +163,5 @@ export declare const deployBsv21Auth: Action<DeployBsv21AuthInput, DeployBsv21Au
|
|
|
165
163
|
*/
|
|
166
164
|
export declare const mintBsv21: Action<MintBsv21Input, MintBsv21Response>;
|
|
167
165
|
/** All token actions for registry */
|
|
168
|
-
/** @deprecated Use buyBsv21 */
|
|
169
|
-
export declare const purchaseBsv21: Action<PurchaseBsv21Request, TokenOperationResponse>;
|
|
170
166
|
export declare const tokensActions: (Action<ListTokensInput, WalletOutput[]> | Action<GetBsv21BalancesInput, Bsv21Balance[]> | Action<SendBsv21Input, TokenOperationResponse> | Action<PurchaseBsv21Request, TokenOperationResponse> | Action<DeployBsv21MintInput, DeployBsv21Response> | Action<MintBsv21Input, MintBsv21Response>)[];
|
|
171
167
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tokens/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACN,KAAK,WAAW,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tokens/index.ts"],"names":[],"mappings":"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"}
|
package/dist/tokens/index.js
CHANGED
|
@@ -4,14 +4,28 @@
|
|
|
4
4
|
* Actions for managing BSV21 tokens.
|
|
5
5
|
*/
|
|
6
6
|
import { BSV21, OrdLock, P2MS } from '@1sat/templates';
|
|
7
|
-
import { buildInputAssetLabel, buildTokenLabel, readAssetIdTag, } from '@1sat/types';
|
|
7
|
+
import { BSV21_DEPLOY_TAG, P1SAT_INTENTS, buildInputAssetLabel, buildTokenLabel, readAssetIdTag, } from '@1sat/types';
|
|
8
8
|
import { parseOutpoint } from '@1sat/utils';
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
9
|
+
import { BigNumber, LockingScript, OP, P2PKH, PublicKey, TransactionSignature, UnlockingScript, Utils, } from '@bsv/sdk';
|
|
10
|
+
import { prepareP1SatArgs } from '../apply';
|
|
11
|
+
import { BSV21_AUTH_BASKET, BSV21_BASKET, P1SAT_PROTOCOL, } from '../constants';
|
|
11
12
|
import { executeTrackedAction } from '../utils/createTrackedAction';
|
|
12
13
|
import { getDisplayValue } from '../utils/displayValue';
|
|
13
14
|
import { resolveDestination } from '../utils/resolveDestination';
|
|
14
15
|
import { signP2PKHInput } from '../utils/signP2PKH';
|
|
16
|
+
/** tokenId from tags, or deploy outpoint when tagged bsv21:deploy. */
|
|
17
|
+
function tokenIdFromOutput(o) {
|
|
18
|
+
const idTag = o.tags?.find((t) => t.startsWith('bsv21:') && t !== BSV21_DEPLOY_TAG);
|
|
19
|
+
if (idTag)
|
|
20
|
+
return idTag.slice(6);
|
|
21
|
+
if (o.tags?.includes(BSV21_DEPLOY_TAG)) {
|
|
22
|
+
return o.outpoint.replace('.', '_');
|
|
23
|
+
}
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
function matchesTokenId(o, tokenId) {
|
|
27
|
+
return tokenIdFromOutput(o) === tokenId;
|
|
28
|
+
}
|
|
15
29
|
// ============================================================================
|
|
16
30
|
// Internal helpers
|
|
17
31
|
// ============================================================================
|
|
@@ -90,8 +104,6 @@ export const listBsv21 = {
|
|
|
90
104
|
return listTokensInternal(ctx, input.limit);
|
|
91
105
|
},
|
|
92
106
|
};
|
|
93
|
-
/** @deprecated Use listBsv21 */
|
|
94
|
-
export const listTokens = listBsv21;
|
|
95
107
|
/**
|
|
96
108
|
* Get aggregated BSV21 token balances.
|
|
97
109
|
*/
|
|
@@ -109,11 +121,10 @@ export const getBsv21Balances = {
|
|
|
109
121
|
const outputs = await listTokensInternal(ctx);
|
|
110
122
|
const balanceMap = new Map();
|
|
111
123
|
for (const o of outputs) {
|
|
112
|
-
const
|
|
124
|
+
const tokenId = tokenIdFromOutput(o);
|
|
113
125
|
const amtTag = o.tags?.find((t) => t.startsWith('amt:'))?.slice(4);
|
|
114
|
-
if (!
|
|
126
|
+
if (!tokenId || !amtTag)
|
|
115
127
|
continue;
|
|
116
|
-
const tokenId = idTag.slice(6);
|
|
117
128
|
const amt = BigInt(amtTag);
|
|
118
129
|
const dec = Number.parseInt(o.tags?.find((t) => t.startsWith('dec:'))?.slice(4) || '0', 10);
|
|
119
130
|
const symTag = getDisplayValue(o, 'sym', 'sym');
|
|
@@ -215,12 +226,7 @@ export const sendBsv21 = {
|
|
|
215
226
|
include: 'entire transactions',
|
|
216
227
|
limit: 10000,
|
|
217
228
|
});
|
|
218
|
-
const tokenUtxos = listResult.outputs.filter((o) =>
|
|
219
|
-
const idTag = o.tags?.find((t) => t.startsWith('bsv21:'));
|
|
220
|
-
if (!idTag)
|
|
221
|
-
return false;
|
|
222
|
-
return idTag.slice(6) === tokenId;
|
|
223
|
-
});
|
|
229
|
+
const tokenUtxos = listResult.outputs.filter((o) => matchesTokenId(o, tokenId));
|
|
224
230
|
// Batch-validate all candidate outpoints against the overlay
|
|
225
231
|
const validOutpoints = new Set();
|
|
226
232
|
let overlayValidated = false;
|
|
@@ -284,13 +290,19 @@ export const sendBsv21 = {
|
|
|
284
290
|
...(isSelf && {
|
|
285
291
|
basket: BSV21_BASKET,
|
|
286
292
|
tags: [...tokenTags, `amt:${r.amount}`],
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
293
|
+
// Only when the wallet actually derived the key. A literal
|
|
294
|
+
// address or lockingScript destination has no derivation, and
|
|
295
|
+
// inventing a keyID here would record a triple that was never
|
|
296
|
+
// used to lock this output — leaving it unspendable from its
|
|
297
|
+
// own record.
|
|
298
|
+
...(recipientResolved.customInstructions?.keyID && {
|
|
299
|
+
customInstructions: JSON.stringify({
|
|
300
|
+
protocolID: P1SAT_PROTOCOL,
|
|
301
|
+
keyID: recipientResolved.customInstructions.keyID,
|
|
302
|
+
counterparty: 'self',
|
|
303
|
+
...(tokenDetails.token.sym && {
|
|
304
|
+
sym: tokenDetails.token.sym,
|
|
305
|
+
}),
|
|
294
306
|
}),
|
|
295
307
|
}),
|
|
296
308
|
}),
|
|
@@ -342,7 +354,7 @@ export const sendBsv21 = {
|
|
|
342
354
|
lockingScript: p2pkh.lock(fee_address).toHex(),
|
|
343
355
|
satoshis: fee_per_output * tokenOutputCount,
|
|
344
356
|
outputDescription: 'Overlay processing fee',
|
|
345
|
-
tags: [],
|
|
357
|
+
tags: ['fee:overlay'],
|
|
346
358
|
});
|
|
347
359
|
const symbol = tokenDetails.token.sym || tokenId.slice(0, 8);
|
|
348
360
|
let inputBEEF = listResult.BEEF;
|
|
@@ -363,7 +375,7 @@ export const sendBsv21 = {
|
|
|
363
375
|
.map((o) => readAssetIdTag(o.tags))
|
|
364
376
|
.filter((id) => Boolean(id))
|
|
365
377
|
.map((id) => buildInputAssetLabel(BSV21_BASKET, id));
|
|
366
|
-
const
|
|
378
|
+
const sendArgs = await prepareP1SatArgs(ctx, {
|
|
367
379
|
description: `Send ${symbol} to ${resolved.length} recipient${resolved.length > 1 ? 's' : ''}`,
|
|
368
380
|
labels: [buildTokenLabel(tokenId), ...inputLabels],
|
|
369
381
|
inputBEEF,
|
|
@@ -374,7 +386,8 @@ export const sendBsv21 = {
|
|
|
374
386
|
})),
|
|
375
387
|
outputs,
|
|
376
388
|
options: { randomizeOutputs: false },
|
|
377
|
-
},
|
|
389
|
+
}, P1SAT_INTENTS.BSV21_TRANSFER);
|
|
390
|
+
const result = await executeTrackedAction(ctx.wallet, sendArgs, input.fundingProvider, inputBEEF, async (tx) => {
|
|
378
391
|
const spends = {};
|
|
379
392
|
for (let i = 0; i < selected.length; i++) {
|
|
380
393
|
const utxo = selected[i];
|
|
@@ -493,7 +506,7 @@ export const buyBsv21 = {
|
|
|
493
506
|
await ctx.services.bsv21.validateOutput(tokenId, outpoint);
|
|
494
507
|
}
|
|
495
508
|
catch (e) {
|
|
496
|
-
console.error('[
|
|
509
|
+
console.error('[buyBsv21] overlay validation error:', e);
|
|
497
510
|
return { error: 'listing-not-found-in-overlay' };
|
|
498
511
|
}
|
|
499
512
|
const tokenDetails = await ctx.services.bsv21.getTokenDetails(tokenId);
|
|
@@ -572,11 +585,11 @@ export const buyBsv21 = {
|
|
|
572
585
|
lockingScript: p2pkh.lock(tokenDetails.status.fee_address).toHex(),
|
|
573
586
|
satoshis: tokenDetails.status.fee_per_output,
|
|
574
587
|
outputDescription: 'Overlay processing fee',
|
|
575
|
-
tags: [],
|
|
588
|
+
tags: ['fee:overlay'],
|
|
576
589
|
});
|
|
577
590
|
}
|
|
578
591
|
const beefBinary = beef.toBinary();
|
|
579
|
-
const
|
|
592
|
+
const buyArgs = await prepareP1SatArgs(ctx, {
|
|
580
593
|
description: `Purchase ${tokenAmount} tokens for ${payoutSatoshis} sats`,
|
|
581
594
|
labels: [buildTokenLabel(tokenId)],
|
|
582
595
|
inputBEEF: beefBinary,
|
|
@@ -589,7 +602,8 @@ export const buyBsv21 = {
|
|
|
589
602
|
],
|
|
590
603
|
outputs,
|
|
591
604
|
options: { randomizeOutputs: false },
|
|
592
|
-
},
|
|
605
|
+
}, P1SAT_INTENTS.BSV21_PURCHASE);
|
|
606
|
+
const result = await executeTrackedAction(ctx.wallet, buyArgs, input.fundingProvider, beefBinary, async (tx) => {
|
|
593
607
|
const unlockingScript = await buildPurchaseUnlockingScript(tx, 0, listingOutput.satoshis ?? 1, listingOutput.lockingScript);
|
|
594
608
|
return { 0: { unlockingScript: unlockingScript.toHex() } };
|
|
595
609
|
});
|
|
@@ -597,16 +611,16 @@ export const buyBsv21 = {
|
|
|
597
611
|
if (result.tx && ctx.services) {
|
|
598
612
|
try {
|
|
599
613
|
const overlayResult = await ctx.services.overlay.submitBsv21(result.tx, tokenId);
|
|
600
|
-
console.log('[
|
|
614
|
+
console.log('[buyBsv21] Overlay submission result:', overlayResult);
|
|
601
615
|
}
|
|
602
616
|
catch (overlayError) {
|
|
603
|
-
console.warn('[
|
|
617
|
+
console.warn('[buyBsv21] Overlay submission failed:', overlayError);
|
|
604
618
|
}
|
|
605
619
|
}
|
|
606
620
|
if (ctx.debug && ctx.log) {
|
|
607
621
|
ctx.log({
|
|
608
622
|
timestamp: new Date().toISOString(),
|
|
609
|
-
action: '
|
|
623
|
+
action: 'buyBsv21',
|
|
610
624
|
input: { tokenId, outpoint, amount: tokenAmount.toString() },
|
|
611
625
|
txid: result.txid,
|
|
612
626
|
rawtx: result.tx ? Utils.toHex(result.tx) : undefined,
|
|
@@ -624,11 +638,11 @@ export const buyBsv21 = {
|
|
|
624
638
|
return result;
|
|
625
639
|
}
|
|
626
640
|
catch (error) {
|
|
627
|
-
console.error('[
|
|
641
|
+
console.error('[buyBsv21]', error);
|
|
628
642
|
if (ctx.debug && ctx.log) {
|
|
629
643
|
ctx.log({
|
|
630
644
|
timestamp: new Date().toISOString(),
|
|
631
|
-
action: '
|
|
645
|
+
action: 'buyBsv21',
|
|
632
646
|
input: {
|
|
633
647
|
tokenId: input.tokenId,
|
|
634
648
|
outpoint: input.outpoint,
|
|
@@ -643,116 +657,13 @@ export const buyBsv21 = {
|
|
|
643
657
|
}
|
|
644
658
|
},
|
|
645
659
|
};
|
|
646
|
-
/** Miner fee rate used for manual deploy tx fee calculation. */
|
|
647
|
-
const DEPLOY_FEE_PER_KB = 100;
|
|
648
|
-
/**
|
|
649
|
-
* Estimate the byte size of the manually-built deploy tx (1 input, 1 output, no
|
|
650
|
-
* change). Conservative — sized for a typical signed P2PKH unlocking script.
|
|
651
|
-
*/
|
|
652
|
-
function estimateDeployTxSize(deployScriptBytes) {
|
|
653
|
-
const overhead = 10; // version(4) + locktime(4) + inCount(1) + outCount(1)
|
|
654
|
-
const input = 148; // P2PKH spend: txid(32)+vout(4)+scriptLen(1)+script(~107)+seq(4)
|
|
655
|
-
const scriptLenVarint = deployScriptBytes < 0xfd ? 1 : deployScriptBytes < 0x10000 ? 3 : 5;
|
|
656
|
-
const output = 8 + scriptLenVarint + deployScriptBytes;
|
|
657
|
-
return overhead + input + output;
|
|
658
|
-
}
|
|
659
660
|
/**
|
|
660
|
-
*
|
|
661
|
-
*
|
|
662
|
-
*
|
|
663
|
-
* 3. Synchronously broadcast the deploy via services.postBeef and require a
|
|
664
|
-
* success/processing arcade status before continuing. internalize alone
|
|
665
|
-
* only QUEUES a tx for later background broadcast — silent drops there
|
|
666
|
-
* have left tokens in a half-deployed state.
|
|
667
|
-
* 4. internalizeAction adopts the deploy into the wallet basket so the auth
|
|
668
|
-
* UTXO becomes spendable.
|
|
669
|
-
*
|
|
670
|
-
* Used by both deployBsv21Mint and deployBsv21Auth — they only differ in the
|
|
671
|
-
* deploy script (BSV21.deployMint vs BSV21.deployAuth) and target basket.
|
|
661
|
+
* Single createAction deploy. Tags include `bsv21:deploy` + metadata;
|
|
662
|
+
* tokenId is the resulting outpoint (`txid_0`). Balance queries treat
|
|
663
|
+
* deploy rows as that token when outpoint matches.
|
|
672
664
|
*/
|
|
673
665
|
async function executeBsv21Deploy(args) {
|
|
674
666
|
const { ctx, symbol, deployScript, basket } = args;
|
|
675
|
-
const deployScriptBin = deployScript.toBinary();
|
|
676
|
-
const txSize = estimateDeployTxSize(deployScriptBin.length);
|
|
677
|
-
const fee = Math.ceil((txSize * DEPLOY_FEE_PER_KB) / 1000);
|
|
678
|
-
// 1 sat for the deploy output + computed fee + small buffer for unlocking
|
|
679
|
-
// script size variance (low-S signatures can be a byte shorter, etc.)
|
|
680
|
-
const fundingValue = 1 + fee + 5;
|
|
681
|
-
const fundingKeyID = `bsv21-deploy-fund-${symbol}-${Date.now()}`;
|
|
682
|
-
const { publicKey: fundingPubKey } = await ctx.wallet.getPublicKey({
|
|
683
|
-
protocolID: P1SAT_PROTOCOL,
|
|
684
|
-
keyID: fundingKeyID,
|
|
685
|
-
counterparty: 'self',
|
|
686
|
-
forSelf: true,
|
|
687
|
-
});
|
|
688
|
-
const fundingAddress = PublicKey.fromString(fundingPubKey).toAddress();
|
|
689
|
-
const fundingScript = new P2PKH().lock(fundingAddress);
|
|
690
|
-
const fundingResult = await ctx.wallet.createAction({
|
|
691
|
-
description: `${args.description} (funding)`,
|
|
692
|
-
outputs: [
|
|
693
|
-
{
|
|
694
|
-
lockingScript: fundingScript.toHex(),
|
|
695
|
-
satoshis: fundingValue,
|
|
696
|
-
outputDescription: 'Deploy funding intermediate',
|
|
697
|
-
basket: BSV21_DEPLOY_FUNDING_BASKET,
|
|
698
|
-
customInstructions: JSON.stringify({
|
|
699
|
-
protocolID: P1SAT_PROTOCOL,
|
|
700
|
-
keyID: fundingKeyID,
|
|
701
|
-
}),
|
|
702
|
-
},
|
|
703
|
-
],
|
|
704
|
-
options: { randomizeOutputs: false },
|
|
705
|
-
});
|
|
706
|
-
if (!fundingResult.txid || !fundingResult.tx) {
|
|
707
|
-
return { error: 'funding-failed' };
|
|
708
|
-
}
|
|
709
|
-
const fundingBeef = Beef.fromBinary(Array.from(fundingResult.tx));
|
|
710
|
-
const fundingTx = fundingBeef.findAtomicTransaction(fundingResult.txid);
|
|
711
|
-
if (!fundingTx) {
|
|
712
|
-
return { error: 'funding-tx-not-in-beef' };
|
|
713
|
-
}
|
|
714
|
-
const deployTx = new Transaction();
|
|
715
|
-
deployTx.addInput({
|
|
716
|
-
sourceTransaction: fundingTx,
|
|
717
|
-
// Setting sourceTXID is required so BeefTx.updateInputTxids picks up
|
|
718
|
-
// the dependency. Without it, the deploy's inputTxids is empty and
|
|
719
|
-
// Beef.sortTxs orders the deploy before its ancestors, which then get
|
|
720
|
-
// trimmed by toBinaryAtomic.
|
|
721
|
-
sourceTXID: fundingResult.txid,
|
|
722
|
-
sourceOutputIndex: 0,
|
|
723
|
-
unlockingScript: new UnlockingScript(),
|
|
724
|
-
sequence: 0xffffffff,
|
|
725
|
-
});
|
|
726
|
-
deployTx.addOutput({
|
|
727
|
-
lockingScript: deployScript,
|
|
728
|
-
satoshis: 1,
|
|
729
|
-
});
|
|
730
|
-
const sigResult = await signP2PKHInput(ctx, deployTx, 0, P1SAT_PROTOCOL, fundingKeyID);
|
|
731
|
-
if (typeof sigResult !== 'string') {
|
|
732
|
-
return { error: sigResult.error };
|
|
733
|
-
}
|
|
734
|
-
deployTx.inputs[0].unlockingScript = UnlockingScript.fromHex(sigResult);
|
|
735
|
-
const deployTxid = deployTx.id('hex');
|
|
736
|
-
const tokenId = `${deployTxid}_0`;
|
|
737
|
-
fundingBeef.mergeTransaction(deployTx);
|
|
738
|
-
const deployBeefBin = fundingBeef.toBinaryAtomic(deployTxid);
|
|
739
|
-
// Synchronous broadcast — internalize alone queues for background
|
|
740
|
-
// broadcast and has been observed to silently drop the deploy tx,
|
|
741
|
-
// stranding the funding output and leaving the wallet with a
|
|
742
|
-
// "deployed" record for a tx that never reached the network.
|
|
743
|
-
if (!ctx.services) {
|
|
744
|
-
return { error: 'broadcast-services-unavailable' };
|
|
745
|
-
}
|
|
746
|
-
const broadcastResults = await ctx.services.postBeef(fundingBeef, [
|
|
747
|
-
deployTxid,
|
|
748
|
-
]);
|
|
749
|
-
const broadcastFailure = broadcastResults.find((r) => r.status !== 'success');
|
|
750
|
-
if (broadcastFailure) {
|
|
751
|
-
const reason = broadcastFailure.error?.message ??
|
|
752
|
-
broadcastFailure.error?.code ??
|
|
753
|
-
'broadcast-failed';
|
|
754
|
-
return { error: `deploy-broadcast-failed: ${reason}` };
|
|
755
|
-
}
|
|
756
667
|
const customInstructions = args.destinationCustomInstructions
|
|
757
668
|
? JSON.stringify({
|
|
758
669
|
protocolID: args.destinationCustomInstructions.protocolID,
|
|
@@ -763,25 +674,32 @@ async function executeBsv21Deploy(args) {
|
|
|
763
674
|
sym: symbol,
|
|
764
675
|
})
|
|
765
676
|
: undefined;
|
|
766
|
-
|
|
767
|
-
|
|
677
|
+
const tags = args.buildTags();
|
|
678
|
+
if (!tags.includes(BSV21_DEPLOY_TAG))
|
|
679
|
+
tags.push(BSV21_DEPLOY_TAG);
|
|
680
|
+
const caArgs = {
|
|
681
|
+
description: args.description,
|
|
768
682
|
outputs: [
|
|
769
683
|
{
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
},
|
|
684
|
+
lockingScript: deployScript.toHex(),
|
|
685
|
+
satoshis: 1,
|
|
686
|
+
outputDescription: args.outputDescription,
|
|
687
|
+
basket,
|
|
688
|
+
tags,
|
|
689
|
+
customInstructions,
|
|
777
690
|
},
|
|
778
691
|
],
|
|
779
|
-
|
|
780
|
-
}
|
|
692
|
+
options: { randomizeOutputs: false },
|
|
693
|
+
};
|
|
694
|
+
const prepared = await prepareP1SatArgs(ctx, caArgs, P1SAT_INTENTS.BSV21_DEPLOY);
|
|
695
|
+
const result = await executeTrackedAction(ctx.wallet, prepared, args.fundingProvider);
|
|
696
|
+
if (!result.txid) {
|
|
697
|
+
return { error: 'deploy-no-txid' };
|
|
698
|
+
}
|
|
781
699
|
return {
|
|
782
|
-
txid:
|
|
783
|
-
tx:
|
|
784
|
-
tokenId
|
|
700
|
+
txid: result.txid,
|
|
701
|
+
tx: result.tx,
|
|
702
|
+
tokenId: `${result.txid}_0`,
|
|
785
703
|
};
|
|
786
704
|
}
|
|
787
705
|
/**
|
|
@@ -836,9 +754,9 @@ export const deployBsv21Mint = {
|
|
|
836
754
|
basket: BSV21_BASKET,
|
|
837
755
|
description: `Deploy ${symbol} (${amount} fixed supply)`,
|
|
838
756
|
outputDescription: `Deploy ${symbol}`,
|
|
839
|
-
buildTags: (
|
|
757
|
+
buildTags: () => {
|
|
840
758
|
const tags = [
|
|
841
|
-
|
|
759
|
+
BSV21_DEPLOY_TAG,
|
|
842
760
|
`amt:${amount}`,
|
|
843
761
|
`dec:${decimals}`,
|
|
844
762
|
`sym:${symbol}`,
|
|
@@ -946,8 +864,8 @@ export const deployBsv21Auth = {
|
|
|
946
864
|
basket: BSV21_AUTH_BASKET,
|
|
947
865
|
description: `Deploy ${symbol} (mintable)`,
|
|
948
866
|
outputDescription: `Deploy ${symbol} auth`,
|
|
949
|
-
buildTags: (
|
|
950
|
-
const tags = [
|
|
867
|
+
buildTags: () => {
|
|
868
|
+
const tags = [BSV21_DEPLOY_TAG, `dec:${decimals}`, `sym:${symbol}`];
|
|
951
869
|
if (icon)
|
|
952
870
|
tags.push(`icon:${icon}`);
|
|
953
871
|
return tags;
|
|
@@ -1151,7 +1069,7 @@ export const mintBsv21 = {
|
|
|
1151
1069
|
.toHex(),
|
|
1152
1070
|
satoshis: tokenDetails.status.fee_per_output * tokenOutputCount,
|
|
1153
1071
|
outputDescription: 'Overlay processing fee',
|
|
1154
|
-
tags: [],
|
|
1072
|
+
tags: ['fee:overlay'],
|
|
1155
1073
|
});
|
|
1156
1074
|
}
|
|
1157
1075
|
let inputBEEF = authList.BEEF;
|
|
@@ -1161,7 +1079,7 @@ export const mintBsv21 = {
|
|
|
1161
1079
|
}
|
|
1162
1080
|
const symbol = tokenDetails.token.sym || tokenId.slice(0, 8);
|
|
1163
1081
|
const authInputId = readAssetIdTag(authUtxo.tags);
|
|
1164
|
-
const
|
|
1082
|
+
const mintArgs = await prepareP1SatArgs(ctx, {
|
|
1165
1083
|
description: mint
|
|
1166
1084
|
? `Mint ${mintAmount} ${symbol}`
|
|
1167
1085
|
: `Re-issue ${symbol} authority`,
|
|
@@ -1181,7 +1099,8 @@ export const mintBsv21 = {
|
|
|
1181
1099
|
],
|
|
1182
1100
|
outputs,
|
|
1183
1101
|
options: { randomizeOutputs: false },
|
|
1184
|
-
},
|
|
1102
|
+
}, P1SAT_INTENTS.BSV21_MINT);
|
|
1103
|
+
const result = await executeTrackedAction(ctx.wallet, mintArgs, input.fundingProvider, inputBEEF, async (tx) => {
|
|
1185
1104
|
if (authCI.multiSig === true) {
|
|
1186
1105
|
// 1-of-N P2MS auth: this wallet contributes its single
|
|
1187
1106
|
// portion. For M > 1 the prepare/finalize flow collects
|
|
@@ -1254,8 +1173,6 @@ export const mintBsv21 = {
|
|
|
1254
1173
|
// Module exports
|
|
1255
1174
|
// ============================================================================
|
|
1256
1175
|
/** All token actions for registry */
|
|
1257
|
-
/** @deprecated Use buyBsv21 */
|
|
1258
|
-
export const purchaseBsv21 = buyBsv21;
|
|
1259
1176
|
export const tokensActions = [
|
|
1260
1177
|
listBsv21,
|
|
1261
1178
|
getBsv21Balances,
|