@1sat/wallet-toolbox 0.0.57 → 0.0.59
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/api/balance/index.js +13 -4
- package/dist/api/broadcast/index.js +7 -2
- package/dist/api/constants.js +4 -1
- package/dist/api/index.js +6 -6
- package/dist/api/inscriptions/index.js +20 -7
- package/dist/api/locks/index.js +19 -6
- package/dist/api/ordinals/index.d.ts +2 -2
- package/dist/api/ordinals/index.js +138 -40
- package/dist/api/payments/index.js +27 -8
- package/dist/api/signing/index.js +4 -2
- package/dist/api/sweep/index.d.ts +2 -2
- package/dist/api/sweep/index.js +55 -21
- package/dist/api/tokens/index.js +47 -15
- package/dist/backup/FileBackupProvider.d.ts +1 -1
- package/dist/backup/FileRestoreReader.d.ts +1 -1
- package/dist/cwi/chrome.d.ts +1 -1
- package/dist/cwi/chrome.js +10 -6
- package/dist/cwi/event.d.ts +1 -1
- package/dist/cwi/event.js +3 -3
- package/dist/cwi/factory.d.ts +2 -2
- package/dist/cwi/factory.js +1 -1
- package/dist/cwi/index.d.ts +4 -4
- package/dist/cwi/index.js +4 -4
- package/dist/indexers/Bsv21Indexer.js +1 -1
- package/dist/indexers/InscriptionIndexer.js +2 -1
- package/dist/indexers/MapIndexer.js +3 -1
- package/dist/indexers/OriginIndexer.js +4 -4
- package/dist/indexers/Outpoint.d.ts +1 -0
- package/dist/indexers/Outpoint.js +8 -0
- package/dist/services/OneSatServices.d.ts +1 -1
- package/dist/services/OneSatServices.js +1 -1
- package/dist/services/client/ChaintracksClient.js +2 -1
- package/dist/services/client/OverlayClient.d.ts +1 -1
- package/dist/sync/AddressManager.js +1 -1
- package/dist/sync/SyncManager.d.ts +2 -2
- package/dist/sync/SyncManager.js +27 -12
- package/dist/sync/index.d.ts +1 -1
- package/dist/sync/index.js +1 -1
- package/dist/wallet/factory.d.ts +2 -0
- package/dist/wallet/factory.js +6 -2
- package/package.json +6 -6
|
@@ -3,14 +3,15 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Skills for querying wallet balance and payment UTXOs.
|
|
5
5
|
*/
|
|
6
|
-
import { FUNDING_BASKET, WOC_MAINNET_URL, WOC_TESTNET_URL,
|
|
6
|
+
import { EXCHANGE_RATE_CACHE_TTL, FUNDING_BASKET, WOC_MAINNET_URL, WOC_TESTNET_URL, } from "../constants";
|
|
7
7
|
// Module-level cache for exchange rate
|
|
8
8
|
let exchangeRateCache = null;
|
|
9
9
|
// ============================================================================
|
|
10
10
|
// Internal helpers
|
|
11
11
|
// ============================================================================
|
|
12
12
|
async function fetchExchangeRate(chain, wocApiKey) {
|
|
13
|
-
if (exchangeRateCache &&
|
|
13
|
+
if (exchangeRateCache &&
|
|
14
|
+
Date.now() - exchangeRateCache.timestamp < EXCHANGE_RATE_CACHE_TTL) {
|
|
14
15
|
return exchangeRateCache.rate;
|
|
15
16
|
}
|
|
16
17
|
const baseUrl = chain === "main" ? WOC_MAINNET_URL : WOC_TESTNET_URL;
|
|
@@ -45,7 +46,10 @@ export const getBalance = {
|
|
|
45
46
|
},
|
|
46
47
|
async execute(ctx) {
|
|
47
48
|
const exchangeRate = await fetchExchangeRate(ctx.chain, ctx.wocApiKey);
|
|
48
|
-
const result = await ctx.wallet.listOutputs({
|
|
49
|
+
const result = await ctx.wallet.listOutputs({
|
|
50
|
+
basket: FUNDING_BASKET,
|
|
51
|
+
limit: 10000,
|
|
52
|
+
});
|
|
49
53
|
const satoshis = result.outputs.reduce((sum, o) => sum + o.satoshis, 0);
|
|
50
54
|
const bsv = satoshis / 100_000_000;
|
|
51
55
|
const usdInCents = Math.round(bsv * exchangeRate * 100);
|
|
@@ -132,4 +136,9 @@ export const getChainInfo = {
|
|
|
132
136
|
// Module exports
|
|
133
137
|
// ============================================================================
|
|
134
138
|
/** All balance skills for registry */
|
|
135
|
-
export const balanceSkills = [
|
|
139
|
+
export const balanceSkills = [
|
|
140
|
+
getBalance,
|
|
141
|
+
getPaymentUtxos,
|
|
142
|
+
getExchangeRate,
|
|
143
|
+
getChainInfo,
|
|
144
|
+
];
|
|
@@ -24,7 +24,10 @@ export const broadcast = {
|
|
|
24
24
|
description: "Transaction format (tx, beef, ef)",
|
|
25
25
|
enum: ["tx", "beef", "ef"],
|
|
26
26
|
},
|
|
27
|
-
description: {
|
|
27
|
+
description: {
|
|
28
|
+
type: "string",
|
|
29
|
+
description: "Description for wallet records",
|
|
30
|
+
},
|
|
28
31
|
},
|
|
29
32
|
required: ["rawtx"],
|
|
30
33
|
},
|
|
@@ -62,7 +65,9 @@ export const broadcast = {
|
|
|
62
65
|
return { txid };
|
|
63
66
|
}
|
|
64
67
|
catch (error) {
|
|
65
|
-
return {
|
|
68
|
+
return {
|
|
69
|
+
error: error instanceof Error ? error.message : "Unknown error",
|
|
70
|
+
};
|
|
66
71
|
}
|
|
67
72
|
},
|
|
68
73
|
};
|
package/dist/api/constants.js
CHANGED
|
@@ -23,7 +23,10 @@ export const LOCK_PREFIX = "20d37f4de0d1c735b4d51a5572df0f3d9104d1d9e99db8694fdd
|
|
|
23
23
|
export const LOCK_SUFFIX = "88ac7e7601207f75a9011488";
|
|
24
24
|
// Protocol IDs
|
|
25
25
|
export const ONESAT_PROTOCOL = [1, "onesat"];
|
|
26
|
-
export const MESSAGE_SIGNING_PROTOCOL = [
|
|
26
|
+
export const MESSAGE_SIGNING_PROTOCOL = [
|
|
27
|
+
1,
|
|
28
|
+
"message signing",
|
|
29
|
+
];
|
|
27
30
|
export const BSV21_PROTOCOL = [1, "bsv21"];
|
|
28
31
|
// Fee constants
|
|
29
32
|
export const BSV21_FEE_SATS = 1000;
|
package/dist/api/index.js
CHANGED
|
@@ -39,17 +39,17 @@ export * from "./signing";
|
|
|
39
39
|
export * from "./broadcast";
|
|
40
40
|
// Export sweep module (uses external signing, not skill-based)
|
|
41
41
|
export * from "./sweep";
|
|
42
|
-
// Register all skills with the global registry
|
|
43
|
-
import { skillRegistry } from "./skills/registry";
|
|
44
42
|
import { balanceSkills } from "./balance";
|
|
45
|
-
import {
|
|
46
|
-
import { ordinalsSkills } from "./ordinals";
|
|
47
|
-
import { tokensSkills } from "./tokens";
|
|
43
|
+
import { broadcastSkills } from "./broadcast";
|
|
48
44
|
import { inscriptionsSkills } from "./inscriptions";
|
|
49
45
|
import { locksSkills } from "./locks";
|
|
46
|
+
import { ordinalsSkills } from "./ordinals";
|
|
47
|
+
import { paymentsSkills } from "./payments";
|
|
50
48
|
import { signingSkills } from "./signing";
|
|
51
|
-
|
|
49
|
+
// Register all skills with the global registry
|
|
50
|
+
import { skillRegistry } from "./skills/registry";
|
|
52
51
|
import { sweepSkills } from "./sweep";
|
|
52
|
+
import { tokensSkills } from "./tokens";
|
|
53
53
|
skillRegistry.registerAll([
|
|
54
54
|
...balanceSkills,
|
|
55
55
|
...paymentsSkills,
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Skills for creating inscriptions.
|
|
5
5
|
*/
|
|
6
|
-
import { P2PKH, PublicKey, Script, Utils } from "@bsv/sdk";
|
|
7
6
|
import { Inscription } from "@bopen-io/templates";
|
|
8
|
-
import {
|
|
7
|
+
import { P2PKH, PublicKey, Script, Utils } from "@bsv/sdk";
|
|
8
|
+
import { MAX_INSCRIPTION_BYTES, ONESAT_PROTOCOL, ORDINALS_BASKET, } from "../constants";
|
|
9
9
|
// ============================================================================
|
|
10
10
|
// Internal helpers
|
|
11
11
|
// ============================================================================
|
|
@@ -35,8 +35,14 @@ export const inscribe = {
|
|
|
35
35
|
inputSchema: {
|
|
36
36
|
type: "object",
|
|
37
37
|
properties: {
|
|
38
|
-
base64Content: {
|
|
39
|
-
|
|
38
|
+
base64Content: {
|
|
39
|
+
type: "string",
|
|
40
|
+
description: "Base64 encoded content",
|
|
41
|
+
},
|
|
42
|
+
contentType: {
|
|
43
|
+
type: "string",
|
|
44
|
+
description: "Content type (MIME type)",
|
|
45
|
+
},
|
|
40
46
|
map: {
|
|
41
47
|
type: "object",
|
|
42
48
|
description: "Optional MAP metadata",
|
|
@@ -50,7 +56,9 @@ export const inscribe = {
|
|
|
50
56
|
try {
|
|
51
57
|
const decoded = Utils.toArray(input.base64Content, "base64");
|
|
52
58
|
if (decoded.length > MAX_INSCRIPTION_BYTES) {
|
|
53
|
-
return {
|
|
59
|
+
return {
|
|
60
|
+
error: `Inscription data too large: ${decoded.length} bytes (max ${MAX_INSCRIPTION_BYTES})`,
|
|
61
|
+
};
|
|
54
62
|
}
|
|
55
63
|
const keyID = Date.now().toString();
|
|
56
64
|
const { publicKey } = await ctx.wallet.getPublicKey({
|
|
@@ -87,10 +95,15 @@ export const inscribe = {
|
|
|
87
95
|
if (!result.txid) {
|
|
88
96
|
return { error: "no-txid-returned" };
|
|
89
97
|
}
|
|
90
|
-
return {
|
|
98
|
+
return {
|
|
99
|
+
txid: result.txid,
|
|
100
|
+
rawtx: result.tx ? Utils.toHex(result.tx) : undefined,
|
|
101
|
+
};
|
|
91
102
|
}
|
|
92
103
|
catch (error) {
|
|
93
|
-
return {
|
|
104
|
+
return {
|
|
105
|
+
error: error instanceof Error ? error.message : "unknown-error",
|
|
106
|
+
};
|
|
94
107
|
}
|
|
95
108
|
},
|
|
96
109
|
};
|
package/dist/api/locks/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Skills for time-locking BSV.
|
|
5
5
|
*/
|
|
6
6
|
import { Hash, PublicKey, Script, Transaction, TransactionSignature, Utils, } from "@bsv/sdk";
|
|
7
|
-
import { LOCK_BASKET, LOCK_PREFIX, LOCK_SUFFIX, MIN_UNLOCK_SATS, WOC_MAINNET_URL, WOC_TESTNET_URL } from "../constants";
|
|
7
|
+
import { LOCK_BASKET, LOCK_PREFIX, LOCK_SUFFIX, MIN_UNLOCK_SATS, WOC_MAINNET_URL, WOC_TESTNET_URL, } from "../constants";
|
|
8
8
|
// ============================================================================
|
|
9
9
|
// Constants
|
|
10
10
|
// ============================================================================
|
|
@@ -95,8 +95,14 @@ export const lockBsv = {
|
|
|
95
95
|
items: {
|
|
96
96
|
type: "object",
|
|
97
97
|
properties: {
|
|
98
|
-
satoshis: {
|
|
99
|
-
|
|
98
|
+
satoshis: {
|
|
99
|
+
type: "integer",
|
|
100
|
+
description: "Amount in satoshis to lock",
|
|
101
|
+
},
|
|
102
|
+
until: {
|
|
103
|
+
type: "integer",
|
|
104
|
+
description: "Block height until which to lock",
|
|
105
|
+
},
|
|
100
106
|
},
|
|
101
107
|
required: ["satoshis", "until"],
|
|
102
108
|
},
|
|
@@ -145,10 +151,15 @@ export const lockBsv = {
|
|
|
145
151
|
if (!result.txid) {
|
|
146
152
|
return { error: "no-txid-returned" };
|
|
147
153
|
}
|
|
148
|
-
return {
|
|
154
|
+
return {
|
|
155
|
+
txid: result.txid,
|
|
156
|
+
rawtx: result.tx ? Utils.toHex(result.tx) : undefined,
|
|
157
|
+
};
|
|
149
158
|
}
|
|
150
159
|
catch (error) {
|
|
151
|
-
return {
|
|
160
|
+
return {
|
|
161
|
+
error: error instanceof Error ? error.message : "unknown-error",
|
|
162
|
+
};
|
|
152
163
|
}
|
|
153
164
|
},
|
|
154
165
|
};
|
|
@@ -282,7 +293,9 @@ export const unlockBsv = {
|
|
|
282
293
|
};
|
|
283
294
|
}
|
|
284
295
|
catch (error) {
|
|
285
|
-
return {
|
|
296
|
+
return {
|
|
297
|
+
error: error instanceof Error ? error.message : "unknown-error",
|
|
298
|
+
};
|
|
286
299
|
}
|
|
287
300
|
},
|
|
288
301
|
};
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* Skills for managing ordinals/inscriptions.
|
|
5
5
|
* Returns WalletOutput[] directly from the SDK - no custom mapping needed.
|
|
6
6
|
*/
|
|
7
|
-
import { type
|
|
8
|
-
import type {
|
|
7
|
+
import { type CreateActionArgs, type WalletOutput } from "@bsv/sdk";
|
|
8
|
+
import type { OneSatContext, Skill } from "../skills/types";
|
|
9
9
|
type PubKeyHex = string;
|
|
10
10
|
export interface TransferItem {
|
|
11
11
|
/** The ordinal output to transfer (from listOutputs) */
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* Skills for managing ordinals/inscriptions.
|
|
5
5
|
* Returns WalletOutput[] directly from the SDK - no custom mapping needed.
|
|
6
6
|
*/
|
|
7
|
-
import { BigNumber, Hash, LockingScript, OP, P2PKH, PublicKey, Script, Transaction, TransactionSignature, UnlockingScript, Utils, } from "@bsv/sdk";
|
|
8
7
|
import { OrdLock } from "@bopen-io/templates";
|
|
9
|
-
import {
|
|
8
|
+
import { BigNumber, Hash, LockingScript, OP, P2PKH, PublicKey, Script, Transaction, TransactionSignature, UnlockingScript, Utils, } from "@bsv/sdk";
|
|
9
|
+
import { ONESAT_PROTOCOL, ORDINALS_BASKET, ORDLOCK_PREFIX, ORDLOCK_SUFFIX, } from "../constants";
|
|
10
10
|
// ============================================================================
|
|
11
11
|
// Helpers
|
|
12
12
|
// ============================================================================
|
|
@@ -27,7 +27,8 @@ function extractName(customInstructions) {
|
|
|
27
27
|
*/
|
|
28
28
|
async function signP2PKHInput(ctx, tx, inputIndex, protocolID, keyID) {
|
|
29
29
|
const txInput = tx.inputs[inputIndex];
|
|
30
|
-
const sourceLockingScript = txInput.sourceTransaction?.outputs[txInput.sourceOutputIndex]
|
|
30
|
+
const sourceLockingScript = txInput.sourceTransaction?.outputs[txInput.sourceOutputIndex]
|
|
31
|
+
?.lockingScript;
|
|
31
32
|
if (!sourceLockingScript) {
|
|
32
33
|
return { error: `missing-source-locking-script-for-input-${inputIndex}` };
|
|
33
34
|
}
|
|
@@ -40,7 +41,9 @@ async function signP2PKHInput(ctx, tx, inputIndex, protocolID, keyID) {
|
|
|
40
41
|
sourceOutputIndex: txInput.sourceOutputIndex,
|
|
41
42
|
sourceSatoshis: 1,
|
|
42
43
|
transactionVersion: tx.version,
|
|
43
|
-
otherInputs: tx.inputs
|
|
44
|
+
otherInputs: tx.inputs
|
|
45
|
+
.filter((_, idx) => idx !== inputIndex)
|
|
46
|
+
.map((inp) => ({
|
|
44
47
|
sourceTXID: inp.sourceTXID ?? inp.sourceTransaction?.id("hex") ?? "",
|
|
45
48
|
sourceOutputIndex: inp.sourceOutputIndex,
|
|
46
49
|
sequence: inp.sequence ?? 0xffffffff,
|
|
@@ -64,7 +67,10 @@ async function signP2PKHInput(ctx, tx, inputIndex, protocolID, keyID) {
|
|
|
64
67
|
keyID,
|
|
65
68
|
forSelf: true,
|
|
66
69
|
});
|
|
67
|
-
const sigWithHashtype = [
|
|
70
|
+
const sigWithHashtype = [
|
|
71
|
+
...signature,
|
|
72
|
+
TransactionSignature.SIGHASH_ALL | TransactionSignature.SIGHASH_FORKID,
|
|
73
|
+
];
|
|
68
74
|
return new UnlockingScript()
|
|
69
75
|
.writeBin(sigWithHashtype)
|
|
70
76
|
.writeBin(Utils.toArray(publicKey, "hex"))
|
|
@@ -175,12 +181,18 @@ export async function buildTransferOrdinals(ctx, request) {
|
|
|
175
181
|
// Preserve important tags from source output
|
|
176
182
|
const tags = [];
|
|
177
183
|
for (const tag of ordinal.tags ?? []) {
|
|
178
|
-
if (tag.startsWith("type:") ||
|
|
184
|
+
if (tag.startsWith("type:") ||
|
|
185
|
+
tag.startsWith("origin:") ||
|
|
186
|
+
tag.startsWith("name:")) {
|
|
179
187
|
tags.push(tag);
|
|
180
188
|
}
|
|
181
189
|
}
|
|
182
190
|
const sourceName = extractName(ordinal.customInstructions);
|
|
183
|
-
inputs.push({
|
|
191
|
+
inputs.push({
|
|
192
|
+
outpoint,
|
|
193
|
+
inputDescription: "Ordinal to transfer",
|
|
194
|
+
unlockingScriptLength: 108,
|
|
195
|
+
});
|
|
184
196
|
// Only track output in wallet when transferring to a counterparty (wallet can derive keys to spend it)
|
|
185
197
|
// External address transfers are NOT tracked since the wallet cannot spend them
|
|
186
198
|
if (counterparty) {
|
|
@@ -208,7 +220,9 @@ export async function buildTransferOrdinals(ctx, request) {
|
|
|
208
220
|
}
|
|
209
221
|
}
|
|
210
222
|
return {
|
|
211
|
-
description: transfers.length === 1
|
|
223
|
+
description: transfers.length === 1
|
|
224
|
+
? "Transfer ordinal"
|
|
225
|
+
: `Transfer ${transfers.length} ordinals`,
|
|
212
226
|
inputBEEF,
|
|
213
227
|
inputs,
|
|
214
228
|
outputs,
|
|
@@ -232,7 +246,11 @@ export async function buildListOrdinal(ctx, request) {
|
|
|
232
246
|
const sourceName = extractName(ordinal.customInstructions);
|
|
233
247
|
const cancelAddress = await deriveCancelAddressInternal(ctx, outpoint);
|
|
234
248
|
const lockingScript = buildOrdLockScript(cancelAddress, payAddress, price);
|
|
235
|
-
const tags = [
|
|
249
|
+
const tags = [
|
|
250
|
+
"ordlock",
|
|
251
|
+
`origin:${originOutpoint}`,
|
|
252
|
+
`price:${price}`,
|
|
253
|
+
];
|
|
236
254
|
if (typeTag)
|
|
237
255
|
tags.push(typeTag);
|
|
238
256
|
if (nameTag)
|
|
@@ -240,7 +258,13 @@ export async function buildListOrdinal(ctx, request) {
|
|
|
240
258
|
return {
|
|
241
259
|
description: `List ordinal for ${price} sats`,
|
|
242
260
|
inputBEEF,
|
|
243
|
-
inputs: [
|
|
261
|
+
inputs: [
|
|
262
|
+
{
|
|
263
|
+
outpoint,
|
|
264
|
+
inputDescription: "Ordinal to list",
|
|
265
|
+
unlockingScriptLength: 108,
|
|
266
|
+
},
|
|
267
|
+
],
|
|
244
268
|
outputs: [
|
|
245
269
|
{
|
|
246
270
|
lockingScript: lockingScript.toHex(),
|
|
@@ -268,8 +292,14 @@ export const getOrdinals = {
|
|
|
268
292
|
inputSchema: {
|
|
269
293
|
type: "object",
|
|
270
294
|
properties: {
|
|
271
|
-
limit: {
|
|
272
|
-
|
|
295
|
+
limit: {
|
|
296
|
+
type: "integer",
|
|
297
|
+
description: "Max ordinals to return (default: 100)",
|
|
298
|
+
},
|
|
299
|
+
offset: {
|
|
300
|
+
type: "integer",
|
|
301
|
+
description: "Offset for pagination (default: 0)",
|
|
302
|
+
},
|
|
273
303
|
},
|
|
274
304
|
},
|
|
275
305
|
},
|
|
@@ -278,7 +308,7 @@ export const getOrdinals = {
|
|
|
278
308
|
basket: ORDINALS_BASKET,
|
|
279
309
|
includeTags: true,
|
|
280
310
|
includeCustomInstructions: true,
|
|
281
|
-
include:
|
|
311
|
+
include: "entire transactions",
|
|
282
312
|
limit: input.limit ?? 100,
|
|
283
313
|
offset: input.offset ?? 0,
|
|
284
314
|
});
|
|
@@ -299,7 +329,10 @@ export const deriveCancelAddress = {
|
|
|
299
329
|
inputSchema: {
|
|
300
330
|
type: "object",
|
|
301
331
|
properties: {
|
|
302
|
-
outpoint: {
|
|
332
|
+
outpoint: {
|
|
333
|
+
type: "string",
|
|
334
|
+
description: "Outpoint of the ordinal listing",
|
|
335
|
+
},
|
|
303
336
|
},
|
|
304
337
|
required: ["outpoint"],
|
|
305
338
|
},
|
|
@@ -325,14 +358,26 @@ export const transferOrdinals = {
|
|
|
325
358
|
items: {
|
|
326
359
|
type: "object",
|
|
327
360
|
properties: {
|
|
328
|
-
ordinal: {
|
|
329
|
-
|
|
330
|
-
|
|
361
|
+
ordinal: {
|
|
362
|
+
type: "object",
|
|
363
|
+
description: "WalletOutput from listOutputs",
|
|
364
|
+
},
|
|
365
|
+
counterparty: {
|
|
366
|
+
type: "string",
|
|
367
|
+
description: "Recipient identity public key (hex)",
|
|
368
|
+
},
|
|
369
|
+
address: {
|
|
370
|
+
type: "string",
|
|
371
|
+
description: "Recipient P2PKH address",
|
|
372
|
+
},
|
|
331
373
|
},
|
|
332
374
|
required: ["ordinal"],
|
|
333
375
|
},
|
|
334
376
|
},
|
|
335
|
-
inputBEEF: {
|
|
377
|
+
inputBEEF: {
|
|
378
|
+
type: "array",
|
|
379
|
+
description: "BEEF from listOutputs with include: 'entire transactions'",
|
|
380
|
+
},
|
|
336
381
|
},
|
|
337
382
|
required: ["transfers", "inputBEEF"],
|
|
338
383
|
},
|
|
@@ -345,9 +390,14 @@ export const transferOrdinals = {
|
|
|
345
390
|
}
|
|
346
391
|
console.log("[transferOrdinals] params:", JSON.stringify({
|
|
347
392
|
description: params.description,
|
|
348
|
-
inputBEEF: params.inputBEEF
|
|
393
|
+
inputBEEF: params.inputBEEF
|
|
394
|
+
? `[${params.inputBEEF.length} bytes]`
|
|
395
|
+
: "undefined",
|
|
349
396
|
inputs: params.inputs,
|
|
350
|
-
outputs: params.outputs?.map(o => ({
|
|
397
|
+
outputs: params.outputs?.map((o) => ({
|
|
398
|
+
...o,
|
|
399
|
+
lockingScript: o.lockingScript?.slice(0, 20) + "...",
|
|
400
|
+
})),
|
|
351
401
|
}, null, 2));
|
|
352
402
|
// Debug: Check if BEEF contains the source transactions
|
|
353
403
|
try {
|
|
@@ -376,7 +426,9 @@ export const transferOrdinals = {
|
|
|
376
426
|
const { ordinal } = input.transfers[i];
|
|
377
427
|
console.log(`[transferOrdinals] Input ${i}: outpoint=${ordinal.outpoint}, customInstructions=${ordinal.customInstructions}`);
|
|
378
428
|
if (!ordinal.customInstructions) {
|
|
379
|
-
return {
|
|
429
|
+
return {
|
|
430
|
+
error: `missing-custom-instructions-for-${ordinal.outpoint}`,
|
|
431
|
+
};
|
|
380
432
|
}
|
|
381
433
|
const { protocolID, keyID } = JSON.parse(ordinal.customInstructions);
|
|
382
434
|
console.log(`[transferOrdinals] Input ${i}: protocolID=${JSON.stringify(protocolID)}, keyID=${keyID}`);
|
|
@@ -399,7 +451,9 @@ export const transferOrdinals = {
|
|
|
399
451
|
};
|
|
400
452
|
}
|
|
401
453
|
catch (error) {
|
|
402
|
-
return {
|
|
454
|
+
return {
|
|
455
|
+
error: error instanceof Error ? error.message : "unknown-error",
|
|
456
|
+
};
|
|
403
457
|
}
|
|
404
458
|
},
|
|
405
459
|
};
|
|
@@ -414,10 +468,19 @@ export const listOrdinal = {
|
|
|
414
468
|
inputSchema: {
|
|
415
469
|
type: "object",
|
|
416
470
|
properties: {
|
|
417
|
-
ordinal: {
|
|
418
|
-
|
|
471
|
+
ordinal: {
|
|
472
|
+
type: "object",
|
|
473
|
+
description: "WalletOutput from listOutputs",
|
|
474
|
+
},
|
|
475
|
+
inputBEEF: {
|
|
476
|
+
type: "array",
|
|
477
|
+
description: "BEEF from listOutputs with include: 'entire transactions'",
|
|
478
|
+
},
|
|
419
479
|
price: { type: "integer", description: "Price in satoshis" },
|
|
420
|
-
payAddress: {
|
|
480
|
+
payAddress: {
|
|
481
|
+
type: "string",
|
|
482
|
+
description: "Address to receive payment on purchase",
|
|
483
|
+
},
|
|
421
484
|
},
|
|
422
485
|
required: ["ordinal", "inputBEEF", "price", "payAddress"],
|
|
423
486
|
},
|
|
@@ -457,7 +520,9 @@ export const listOrdinal = {
|
|
|
457
520
|
};
|
|
458
521
|
}
|
|
459
522
|
catch (error) {
|
|
460
|
-
return {
|
|
523
|
+
return {
|
|
524
|
+
error: error instanceof Error ? error.message : "unknown-error",
|
|
525
|
+
};
|
|
461
526
|
}
|
|
462
527
|
},
|
|
463
528
|
};
|
|
@@ -472,8 +537,14 @@ export const cancelListing = {
|
|
|
472
537
|
inputSchema: {
|
|
473
538
|
type: "object",
|
|
474
539
|
properties: {
|
|
475
|
-
listing: {
|
|
476
|
-
|
|
540
|
+
listing: {
|
|
541
|
+
type: "object",
|
|
542
|
+
description: "WalletOutput of the listing (must include lockingScript)",
|
|
543
|
+
},
|
|
544
|
+
inputBEEF: {
|
|
545
|
+
type: "array",
|
|
546
|
+
description: "BEEF from listOutputs with include: 'entire transactions'",
|
|
547
|
+
},
|
|
477
548
|
},
|
|
478
549
|
required: ["listing", "inputBEEF"],
|
|
479
550
|
},
|
|
@@ -485,7 +556,7 @@ export const cancelListing = {
|
|
|
485
556
|
if (!listing.customInstructions) {
|
|
486
557
|
return { error: "missing-custom-instructions" };
|
|
487
558
|
}
|
|
488
|
-
const { protocolID, keyID, name: listingName } = JSON.parse(listing.customInstructions);
|
|
559
|
+
const { protocolID, keyID, name: listingName, } = JSON.parse(listing.customInstructions);
|
|
489
560
|
const typeTag = listing.tags?.find((t) => t.startsWith("type:"));
|
|
490
561
|
const originTag = listing.tags?.find((t) => t.startsWith("origin:"));
|
|
491
562
|
const nameTag = listing.tags?.find((t) => t.startsWith("name:"));
|
|
@@ -514,7 +585,11 @@ export const cancelListing = {
|
|
|
514
585
|
outputDescription: "Cancelled listing",
|
|
515
586
|
basket: ORDINALS_BASKET,
|
|
516
587
|
tags,
|
|
517
|
-
customInstructions: JSON.stringify({
|
|
588
|
+
customInstructions: JSON.stringify({
|
|
589
|
+
protocolID,
|
|
590
|
+
keyID,
|
|
591
|
+
...(listingName && { name: listingName }),
|
|
592
|
+
}),
|
|
518
593
|
},
|
|
519
594
|
],
|
|
520
595
|
options: { signAndProcess: false, randomizeOutputs: false },
|
|
@@ -527,7 +602,8 @@ export const cancelListing = {
|
|
|
527
602
|
}
|
|
528
603
|
const tx = Transaction.fromBEEF(createResult.signableTransaction.tx);
|
|
529
604
|
const txInput = tx.inputs[0];
|
|
530
|
-
const lockingScript = txInput.sourceTransaction?.outputs[txInput.sourceOutputIndex]
|
|
605
|
+
const lockingScript = txInput.sourceTransaction?.outputs[txInput.sourceOutputIndex]
|
|
606
|
+
?.lockingScript;
|
|
531
607
|
if (!lockingScript) {
|
|
532
608
|
return { error: "missing-locking-script" };
|
|
533
609
|
}
|
|
@@ -582,7 +658,9 @@ export const cancelListing = {
|
|
|
582
658
|
};
|
|
583
659
|
}
|
|
584
660
|
catch (error) {
|
|
585
|
-
return {
|
|
661
|
+
return {
|
|
662
|
+
error: error instanceof Error ? error.message : "unknown-error",
|
|
663
|
+
};
|
|
586
664
|
}
|
|
587
665
|
},
|
|
588
666
|
};
|
|
@@ -598,11 +676,26 @@ export const purchaseOrdinal = {
|
|
|
598
676
|
inputSchema: {
|
|
599
677
|
type: "object",
|
|
600
678
|
properties: {
|
|
601
|
-
outpoint: {
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
679
|
+
outpoint: {
|
|
680
|
+
type: "string",
|
|
681
|
+
description: "Outpoint of the listing to purchase",
|
|
682
|
+
},
|
|
683
|
+
marketplaceAddress: {
|
|
684
|
+
type: "string",
|
|
685
|
+
description: "Marketplace address for fees",
|
|
686
|
+
},
|
|
687
|
+
marketplaceRate: {
|
|
688
|
+
type: "number",
|
|
689
|
+
description: "Marketplace fee rate (0-1)",
|
|
690
|
+
},
|
|
691
|
+
contentType: {
|
|
692
|
+
type: "string",
|
|
693
|
+
description: "Content type (auto-detected if not provided)",
|
|
694
|
+
},
|
|
695
|
+
origin: {
|
|
696
|
+
type: "string",
|
|
697
|
+
description: "Origin outpoint (auto-detected if not provided)",
|
|
698
|
+
},
|
|
606
699
|
},
|
|
607
700
|
required: ["outpoint"],
|
|
608
701
|
},
|
|
@@ -628,8 +721,11 @@ export const purchaseOrdinal = {
|
|
|
628
721
|
if (name === undefined && metadata.map) {
|
|
629
722
|
const mapName = metadata.map.name;
|
|
630
723
|
const subTypeData = metadata.map.subTypeData;
|
|
631
|
-
name =
|
|
632
|
-
(typeof
|
|
724
|
+
name =
|
|
725
|
+
(typeof mapName === "string" ? mapName : undefined) ??
|
|
726
|
+
(typeof subTypeData?.name === "string"
|
|
727
|
+
? subTypeData.name
|
|
728
|
+
: undefined);
|
|
633
729
|
}
|
|
634
730
|
}
|
|
635
731
|
const beef = await ctx.services.getBeefForTxid(txid);
|
|
@@ -728,7 +824,9 @@ export const purchaseOrdinal = {
|
|
|
728
824
|
};
|
|
729
825
|
}
|
|
730
826
|
catch (error) {
|
|
731
|
-
return {
|
|
827
|
+
return {
|
|
828
|
+
error: error instanceof Error ? error.message : "unknown-error",
|
|
829
|
+
};
|
|
732
830
|
}
|
|
733
831
|
},
|
|
734
832
|
};
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Skills for sending BSV payments.
|
|
5
5
|
*/
|
|
6
|
-
import { P2PKH, Script, Utils } from "@bsv/sdk";
|
|
7
6
|
import { Inscription } from "@bopen-io/templates";
|
|
7
|
+
import { P2PKH, Script, Utils } from "@bsv/sdk";
|
|
8
8
|
import { FUNDING_BASKET } from "../constants";
|
|
9
9
|
// ============================================================================
|
|
10
10
|
// Internal helpers
|
|
@@ -41,10 +41,19 @@ export const sendBsv = {
|
|
|
41
41
|
items: {
|
|
42
42
|
type: "object",
|
|
43
43
|
properties: {
|
|
44
|
-
address: {
|
|
45
|
-
|
|
44
|
+
address: {
|
|
45
|
+
type: "string",
|
|
46
|
+
description: "Destination P2PKH address",
|
|
47
|
+
},
|
|
48
|
+
paymail: {
|
|
49
|
+
type: "string",
|
|
50
|
+
description: "Destination paymail address",
|
|
51
|
+
},
|
|
46
52
|
satoshis: { type: "integer", description: "Amount in satoshis" },
|
|
47
|
-
script: {
|
|
53
|
+
script: {
|
|
54
|
+
type: "string",
|
|
55
|
+
description: "Custom locking script (hex)",
|
|
56
|
+
},
|
|
48
57
|
data: {
|
|
49
58
|
type: "array",
|
|
50
59
|
description: "OP_RETURN data elements",
|
|
@@ -107,10 +116,15 @@ export const sendBsv = {
|
|
|
107
116
|
if (!result.txid) {
|
|
108
117
|
return { error: "no-txid-returned" };
|
|
109
118
|
}
|
|
110
|
-
return {
|
|
119
|
+
return {
|
|
120
|
+
txid: result.txid,
|
|
121
|
+
rawtx: result.tx ? Utils.toHex(result.tx) : undefined,
|
|
122
|
+
};
|
|
111
123
|
}
|
|
112
124
|
catch (error) {
|
|
113
|
-
return {
|
|
125
|
+
return {
|
|
126
|
+
error: error instanceof Error ? error.message : "unknown-error",
|
|
127
|
+
};
|
|
114
128
|
}
|
|
115
129
|
},
|
|
116
130
|
};
|
|
@@ -172,10 +186,15 @@ export const sendAllBsv = {
|
|
|
172
186
|
if (!result.txid) {
|
|
173
187
|
return { error: "no-txid-returned" };
|
|
174
188
|
}
|
|
175
|
-
return {
|
|
189
|
+
return {
|
|
190
|
+
txid: result.txid,
|
|
191
|
+
rawtx: result.tx ? Utils.toHex(result.tx) : undefined,
|
|
192
|
+
};
|
|
176
193
|
}
|
|
177
194
|
catch (error) {
|
|
178
|
-
return {
|
|
195
|
+
return {
|
|
196
|
+
error: error instanceof Error ? error.message : "unknown-error",
|
|
197
|
+
};
|
|
179
198
|
}
|
|
180
199
|
},
|
|
181
200
|
};
|