bsv-mcp 0.0.36 → 0.2.7
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/CHANGELOG.md +124 -0
- package/README.md +233 -4
- package/dist/index.js +120082 -54669
- package/index.ts +1196 -88
- package/next-env.d.ts +6 -0
- package/package.json +58 -15
- package/prompts/bsvSdk/index.ts +5 -5
- package/prompts/bsvSdk/transaction.ts +2 -2
- package/prompts/bsvSdk/wallet.ts +1 -1
- package/prompts/index.ts +1 -1
- package/resources/bitcom.ts +132 -0
- package/resources/resources.ts +7 -3
- package/smithery.yaml +3 -0
- package/test-mcp-server.ts +157 -0
- package/tools/a2b/discover.ts +13 -13
- package/tools/bap/friend.ts +266 -0
- package/tools/bap/generate.test.ts +350 -0
- package/tools/bap/generate.ts +431 -0
- package/tools/bap/getCurrentAddress.ts +69 -0
- package/tools/bap/getId.test.ts +121 -0
- package/tools/bap/getId.ts +169 -0
- package/tools/bap/index.ts +111 -0
- package/tools/bap/types.ts +66 -0
- package/tools/bap/utils.ts +33 -0
- package/tools/bsocial/bmapFollow.ts +121 -0
- package/tools/bsocial/bmapLikes.ts +111 -0
- package/tools/bsocial/bmapReadPosts.ts +148 -0
- package/tools/bsocial/createPost.ts +136 -0
- package/tools/bsocial/index.ts +45 -0
- package/tools/bsocial/readPosts.ts +255 -0
- package/tools/bsv/decodeTransaction.ts +7 -6
- package/tools/bsv/explore.ts +2 -3
- package/tools/bsv/getPrice.ts +1 -9
- package/tools/bsv/token.ts +14 -26
- package/tools/constants.ts +21 -0
- package/tools/index.ts +91 -18
- package/tools/mnee/getBalance.ts +2 -4
- package/tools/mnee/index.ts +8 -0
- package/tools/mnee/parseTx.ts +4 -4
- package/tools/mnee/sendMnee.ts +6 -6
- package/tools/ordinals/getInscription.ts +2 -3
- package/tools/ordinals/getTokenByIdOrTicker.ts +6 -3
- package/tools/ordinals/marketListings.ts +2 -18
- package/tools/ordinals/marketSales.ts +2 -4
- package/tools/ordinals/searchInscriptions.ts +2 -4
- package/tools/utils/aip.ts +46 -0
- package/tools/utils/conversion.ts +1 -0
- package/tools/utils/errorHandler.ts +76 -0
- package/tools/utils/index.ts +56 -14
- package/tools/utils/installAgentMaster.ts +84 -0
- package/tools/utils/logger.ts +20 -0
- package/tools/utils/toolConfig.ts +80 -0
- package/tools/utils/toolRegistration.ts +66 -0
- package/tools/utils/transactionBuilder.ts +196 -0
- package/tools/wallet/a2bPublishAgent.ts +25 -30
- package/tools/wallet/a2bPublishMcp.ts +43 -44
- package/tools/wallet/createOrdinals.ts +13 -20
- package/tools/wallet/fetchPaymentUtxos.ts +48 -39
- package/tools/wallet/gatherCollectionInfo.ts +370 -0
- package/tools/wallet/getAddress.ts +14 -30
- package/tools/wallet/getBalance.ts +54 -0
- package/tools/wallet/getBalanceDroplet.ts +48 -0
- package/tools/wallet/getPublicKey.ts +3 -16
- package/tools/wallet/integratedWallet.ts +120 -0
- package/tools/wallet/mintCollection.ts +373 -0
- package/tools/wallet/purchaseListing.ts +21 -31
- package/tools/wallet/refreshUtxos.ts +2 -14
- package/tools/wallet/schemas.ts +18 -249
- package/tools/wallet/sendOrdinals.ts +14 -21
- package/tools/wallet/sendToAddress.ts +2 -18
- package/tools/wallet/setupDroplet.ts +161 -0
- package/tools/wallet/tools.ts +55 -210
- package/tools/wallet/transactionHelper.ts +121 -0
- package/tools/wallet/transferOrdToken.ts +19 -24
- package/tools/wallet/utxo.ts +62 -0
- package/tools/wallet/wallet.ts +237 -234
- package/vite.config.ts +15 -0
- package/tools/a2b/call.ts +0 -32
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import { PrivateKey
|
|
1
|
+
import type { PrivateKey } from "@bsv/sdk";
|
|
2
|
+
import { Utils } from "@bsv/sdk";
|
|
2
3
|
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
3
4
|
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
4
5
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
5
|
-
import type { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js";
|
|
6
6
|
import type {
|
|
7
7
|
ClientNotification,
|
|
8
8
|
ClientRequest,
|
|
9
9
|
ServerNotification,
|
|
10
10
|
ServerRequest,
|
|
11
11
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
12
|
-
import { createOrdinals } from "js-1sat-ord";
|
|
13
12
|
import type {
|
|
14
13
|
ChangeResult,
|
|
15
14
|
CreateOrdinalsConfig,
|
|
@@ -18,9 +17,12 @@ import type {
|
|
|
18
17
|
LocalSigner,
|
|
19
18
|
PreMAP,
|
|
20
19
|
} from "js-1sat-ord";
|
|
21
|
-
import {
|
|
20
|
+
import { createOrdinals } from "js-1sat-ord";
|
|
22
21
|
import { z } from "zod";
|
|
22
|
+
import packageJson from "../../package.json";
|
|
23
|
+
import { V5Broadcaster } from "../../utils/broadcaster";
|
|
23
24
|
import type { Wallet } from "./wallet";
|
|
25
|
+
|
|
24
26
|
const { toArray, toBase64 } = Utils;
|
|
25
27
|
|
|
26
28
|
// API endpoint for the A2B Overlay service
|
|
@@ -134,7 +136,7 @@ async function fetchMcpMetadata(
|
|
|
134
136
|
// Create and connect a client
|
|
135
137
|
client = new Client({
|
|
136
138
|
name: "metadata-fetcher",
|
|
137
|
-
version:
|
|
139
|
+
version: packageJson.version,
|
|
138
140
|
});
|
|
139
141
|
|
|
140
142
|
await client.connect(transport);
|
|
@@ -186,33 +188,23 @@ async function fetchMcpMetadata(
|
|
|
186
188
|
export function registerA2bPublishMcpTool(
|
|
187
189
|
server: McpServer,
|
|
188
190
|
wallet: Wallet,
|
|
191
|
+
identityPk: PrivateKey | undefined,
|
|
189
192
|
config: { disableBroadcasting: boolean },
|
|
190
193
|
) {
|
|
191
194
|
server.tool(
|
|
192
195
|
"wallet_a2bPublishMcp",
|
|
193
196
|
"Publish an MCP tool configuration record on-chain via Ordinal inscription. This creates a permanent, immutable, and discoverable tool definition that can be accessed by other MCP servers. The tool is published as a JSON inscription with metadata and optional digital signatures for authenticity verification.",
|
|
194
|
-
{
|
|
195
|
-
async (
|
|
196
|
-
{ args }: { args: A2bPublishMcpArgs },
|
|
197
|
-
extra: RequestHandlerExtra<ServerRequest, ServerNotification>,
|
|
198
|
-
) => {
|
|
197
|
+
{ ...a2bPublishMcpArgsSchema.shape },
|
|
198
|
+
async ({ toolName, command, args, keywords, env, description, destinationAddress }) => {
|
|
199
199
|
try {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
try {
|
|
205
|
-
identityPk = PrivateKey.fromWif(identityKeyWif);
|
|
206
|
-
} catch (e) {
|
|
207
|
-
console.warn(
|
|
208
|
-
"Warning: Invalid IDENTITY_KEY_WIF environment variable; sigma signing disabled",
|
|
209
|
-
e,
|
|
210
|
-
);
|
|
211
|
-
}
|
|
200
|
+
if (!identityPk) {
|
|
201
|
+
console.warn(
|
|
202
|
+
"Warning: No identity key provided; sigma signing disabled for A2B MCP publish",
|
|
203
|
+
);
|
|
212
204
|
}
|
|
213
205
|
|
|
214
|
-
const paymentPk = wallet.
|
|
215
|
-
if (!paymentPk) throw new Error("No private key available");
|
|
206
|
+
const paymentPk = wallet.getPaymentKey();
|
|
207
|
+
if (!paymentPk) throw new Error("No payment private key available");
|
|
216
208
|
|
|
217
209
|
const { paymentUtxos } = await wallet.getUtxos();
|
|
218
210
|
if (!paymentUtxos?.length)
|
|
@@ -221,20 +213,20 @@ export function registerA2bPublishMcpTool(
|
|
|
221
213
|
const walletAddress = paymentPk.toAddress().toString();
|
|
222
214
|
|
|
223
215
|
// Fetch MCP metadata (tools, prompts, resources)
|
|
224
|
-
const metadata = await fetchMcpMetadata(
|
|
216
|
+
const metadata = await fetchMcpMetadata(command, args);
|
|
225
217
|
// console.log(`Discovered ${metadata.tools.length} tools, ${metadata.prompts.length} prompts, and ${metadata.resources.length} resources`);
|
|
226
218
|
|
|
227
219
|
// Assemble tool configuration
|
|
228
220
|
const toolConfig: McpConfig = {
|
|
229
|
-
command
|
|
230
|
-
args
|
|
221
|
+
command,
|
|
222
|
+
args,
|
|
231
223
|
tools: metadata.tools,
|
|
232
224
|
prompts: metadata.prompts,
|
|
233
225
|
resources: metadata.resources,
|
|
234
|
-
env:
|
|
235
|
-
?
|
|
236
|
-
(acc, { key, description }) => {
|
|
237
|
-
acc[key] =
|
|
226
|
+
env: env
|
|
227
|
+
? env.reduce(
|
|
228
|
+
(acc, { key, description: desc }) => {
|
|
229
|
+
acc[key] = desc;
|
|
238
230
|
return acc;
|
|
239
231
|
},
|
|
240
232
|
{} as Record<string, string>,
|
|
@@ -248,9 +240,9 @@ export function registerA2bPublishMcpTool(
|
|
|
248
240
|
// Prepare the full configuration with metadata
|
|
249
241
|
const fullConfig = {
|
|
250
242
|
mcpServers: {
|
|
251
|
-
[
|
|
252
|
-
description:
|
|
253
|
-
keywords:
|
|
243
|
+
[toolName]: {
|
|
244
|
+
description: description || "",
|
|
245
|
+
keywords: keywords || [],
|
|
254
246
|
tools: metadata.tools || [],
|
|
255
247
|
prompts: metadata.prompts || [],
|
|
256
248
|
resources: metadata.resources || [],
|
|
@@ -269,7 +261,7 @@ export function registerA2bPublishMcpTool(
|
|
|
269
261
|
};
|
|
270
262
|
|
|
271
263
|
// Destination for the ordinal
|
|
272
|
-
const targetAddress =
|
|
264
|
+
const targetAddress = destinationAddress ?? walletAddress;
|
|
273
265
|
const destinations: Destination[] = [
|
|
274
266
|
{ address: targetAddress, inscription },
|
|
275
267
|
];
|
|
@@ -284,20 +276,27 @@ export function registerA2bPublishMcpTool(
|
|
|
284
276
|
changeAddress: walletAddress,
|
|
285
277
|
metaData,
|
|
286
278
|
} as CreateOrdinalsConfig;
|
|
279
|
+
|
|
280
|
+
// Use the passed identityPk for signing if available
|
|
287
281
|
if (identityPk) {
|
|
288
282
|
createOrdinalsConfig.signer = {
|
|
289
283
|
idKey: identityPk,
|
|
290
284
|
} as LocalSigner;
|
|
291
285
|
}
|
|
292
|
-
// Inscribe the ordinal on-chain via js-1sat-ord
|
|
293
|
-
const result = await createOrdinals(createOrdinalsConfig);
|
|
294
286
|
|
|
295
|
-
|
|
287
|
+
// Inscribe the ordinal on-chain via js-1sat-ord
|
|
288
|
+
let result: ChangeResult | undefined;
|
|
289
|
+
if (!config.disableBroadcasting) {
|
|
290
|
+
result = await createOrdinals(createOrdinalsConfig);
|
|
291
|
+
} else {
|
|
292
|
+
console.warn("Broadcasting disabled. Transaction not created.");
|
|
293
|
+
}
|
|
296
294
|
|
|
297
295
|
// Broadcast the transaction
|
|
298
|
-
if (!config.disableBroadcasting) {
|
|
299
|
-
|
|
300
|
-
|
|
296
|
+
if (!config.disableBroadcasting && result) {
|
|
297
|
+
const broadcaster = new V5Broadcaster();
|
|
298
|
+
await result.tx.broadcast(broadcaster);
|
|
299
|
+
const txid = result.tx.id("hex");
|
|
301
300
|
|
|
302
301
|
setTimeout(async () => {
|
|
303
302
|
// Call the ingest endpoint to process the transaction
|
|
@@ -331,12 +330,12 @@ export function registerA2bPublishMcpTool(
|
|
|
331
330
|
txid,
|
|
332
331
|
outpoint,
|
|
333
332
|
onchainUrl,
|
|
334
|
-
toolName
|
|
333
|
+
toolName,
|
|
335
334
|
toolCount: metadata.tools.length,
|
|
336
335
|
promptCount: metadata.prompts.length,
|
|
337
336
|
resourceCount: metadata.resources.length,
|
|
338
337
|
description:
|
|
339
|
-
|
|
338
|
+
description || `MCP Tool: ${toolName}`,
|
|
340
339
|
address: targetAddress,
|
|
341
340
|
},
|
|
342
341
|
null,
|
|
@@ -350,7 +349,7 @@ export function registerA2bPublishMcpTool(
|
|
|
350
349
|
content: [
|
|
351
350
|
{
|
|
352
351
|
type: "text",
|
|
353
|
-
text:
|
|
352
|
+
text: result?.tx.toHex() || "",
|
|
354
353
|
},
|
|
355
354
|
],
|
|
356
355
|
};
|
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
import { PrivateKey } from "@bsv/sdk";
|
|
2
2
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
-
import type {
|
|
4
|
-
import type {
|
|
5
|
-
CallToolResult,
|
|
6
|
-
ServerNotification,
|
|
7
|
-
ServerRequest,
|
|
8
|
-
} from "@modelcontextprotocol/sdk/types.js";
|
|
9
|
-
import { createOrdinals } from "js-1sat-ord";
|
|
3
|
+
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
10
4
|
import type {
|
|
11
5
|
ChangeResult,
|
|
12
6
|
CreateOrdinalsCollectionItemMetadata,
|
|
@@ -17,8 +11,9 @@ import type {
|
|
|
17
11
|
LocalSigner,
|
|
18
12
|
PreMAP,
|
|
19
13
|
} from "js-1sat-ord";
|
|
20
|
-
import {
|
|
14
|
+
import { createOrdinals } from "js-1sat-ord";
|
|
21
15
|
import { z } from "zod";
|
|
16
|
+
import { V5Broadcaster } from "../../utils/broadcaster";
|
|
22
17
|
import type { Wallet } from "./wallet";
|
|
23
18
|
|
|
24
19
|
/**
|
|
@@ -52,11 +47,8 @@ export function registerCreateOrdinalsTool(server: McpServer, wallet: Wallet) {
|
|
|
52
47
|
server.tool(
|
|
53
48
|
"wallet_createOrdinals",
|
|
54
49
|
"Creates and inscribes ordinals (NFTs) on the Bitcoin SV blockchain. This tool lets you mint new digital artifacts by encoding data directly into the blockchain. Supports various content types including images, text, JSON, and HTML. The tool handles transaction creation, fee calculation, and broadcasting.",
|
|
55
|
-
{
|
|
56
|
-
async (
|
|
57
|
-
{ args }: { args: CreateOrdinalsArgs },
|
|
58
|
-
extra: RequestHandlerExtra<ServerRequest, ServerNotification>,
|
|
59
|
-
): Promise<CallToolResult> => {
|
|
50
|
+
{ ...createOrdinalsArgsSchema.shape },
|
|
51
|
+
async ({ dataB64, contentType, destinationAddress, metadata }): Promise<CallToolResult> => {
|
|
60
52
|
try {
|
|
61
53
|
// Load optional identity key for sigma signing
|
|
62
54
|
const identityKeyWif = process.env.IDENTITY_KEY_WIF;
|
|
@@ -91,14 +83,14 @@ export function registerCreateOrdinalsTool(server: McpServer, wallet: Wallet) {
|
|
|
91
83
|
|
|
92
84
|
// 4. Create the inscription object
|
|
93
85
|
const inscription: Inscription = {
|
|
94
|
-
dataB64:
|
|
95
|
-
contentType:
|
|
86
|
+
dataB64: dataB64,
|
|
87
|
+
contentType: contentType,
|
|
96
88
|
};
|
|
97
89
|
|
|
98
90
|
// 5. Create the destination
|
|
99
91
|
const destinations: Destination[] = [
|
|
100
92
|
{
|
|
101
|
-
address:
|
|
93
|
+
address: destinationAddress || walletAddress,
|
|
102
94
|
inscription,
|
|
103
95
|
},
|
|
104
96
|
];
|
|
@@ -108,7 +100,7 @@ export function registerCreateOrdinalsTool(server: McpServer, wallet: Wallet) {
|
|
|
108
100
|
destinations,
|
|
109
101
|
paymentPk,
|
|
110
102
|
changeAddress: walletAddress,
|
|
111
|
-
metaData:
|
|
103
|
+
metaData: metadata as
|
|
112
104
|
| PreMAP
|
|
113
105
|
| CreateOrdinalsCollectionMetadata
|
|
114
106
|
| CreateOrdinalsCollectionItemMetadata,
|
|
@@ -129,7 +121,8 @@ export function registerCreateOrdinalsTool(server: McpServer, wallet: Wallet) {
|
|
|
129
121
|
|
|
130
122
|
const disableBroadcasting = process.env.DISABLE_BROADCASTING === "true";
|
|
131
123
|
if (!disableBroadcasting) {
|
|
132
|
-
|
|
124
|
+
const broadcaster = new V5Broadcaster();
|
|
125
|
+
await changeResult.tx.broadcast(broadcaster);
|
|
133
126
|
|
|
134
127
|
// 8. Refresh the wallet's UTXOs after spending
|
|
135
128
|
try {
|
|
@@ -150,8 +143,8 @@ export function registerCreateOrdinalsTool(server: McpServer, wallet: Wallet) {
|
|
|
150
143
|
txid: changeResult.tx.id("hex"),
|
|
151
144
|
spentOutpoints: changeResult.spentOutpoints,
|
|
152
145
|
payChange: changeResult.payChange,
|
|
153
|
-
inscriptionAddress:
|
|
154
|
-
contentType:
|
|
146
|
+
inscriptionAddress: destinationAddress || walletAddress,
|
|
147
|
+
contentType: contentType,
|
|
155
148
|
}),
|
|
156
149
|
},
|
|
157
150
|
],
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { P2PKH, Transaction, Utils } from "@bsv/sdk";
|
|
2
2
|
import type { Utxo } from "js-1sat-ord";
|
|
3
|
-
|
|
3
|
+
import { V5_API_URL } from "../constants";
|
|
4
|
+
import { getBeefTransactionById, getTransactionById } from "./utxo";
|
|
5
|
+
|
|
6
|
+
const { toBase64, toHex, toArray } = Utils;
|
|
4
7
|
|
|
5
8
|
/**
|
|
6
9
|
* Type definition for WhatsOnChain UTXO response
|
|
@@ -56,13 +59,10 @@ export async function fetchPaymentUtxos(
|
|
|
56
59
|
const utxos: (Utxo | null)[] = await Promise.all(
|
|
57
60
|
data.map(async (utxo: WhatsOnChainUtxo) => {
|
|
58
61
|
// Get the transaction hex to extract the correct script
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
utxo.tx_pos,
|
|
62
|
-
);
|
|
63
|
-
|
|
62
|
+
const tx = await getBeefTransactionById(utxo.tx_hash);
|
|
63
|
+
const script = tx?.outputs[utxo.tx_pos]?.lockingScript.toHex();
|
|
64
64
|
if (!script) {
|
|
65
|
-
console.
|
|
65
|
+
console.error(
|
|
66
66
|
`Could not get script for UTXO: ${utxo.tx_hash}:${utxo.tx_pos}`,
|
|
67
67
|
);
|
|
68
68
|
return null;
|
|
@@ -72,7 +72,7 @@ export async function fetchPaymentUtxos(
|
|
|
72
72
|
txid: utxo.tx_hash,
|
|
73
73
|
vout: utxo.tx_pos,
|
|
74
74
|
satoshis: utxo.value,
|
|
75
|
-
script
|
|
75
|
+
script,
|
|
76
76
|
};
|
|
77
77
|
}),
|
|
78
78
|
);
|
|
@@ -87,44 +87,53 @@ export async function fetchPaymentUtxos(
|
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
90
|
+
type V5Utxo = {
|
|
91
|
+
outpoint: string;
|
|
92
|
+
height: number;
|
|
93
|
+
idx: number;
|
|
94
|
+
satoshis: number;
|
|
95
|
+
script: string;
|
|
96
|
+
owners: string[];
|
|
97
|
+
data: Record<string, unknown>;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
export async function fetchPaymentUtxosFromV5(
|
|
101
|
+
address: string,
|
|
102
|
+
): Promise<Utxo[] | undefined> {
|
|
101
103
|
try {
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
);
|
|
105
|
-
|
|
104
|
+
const url = `${V5_API_URL}/own/${address}/utxos?refresh=true&txo=true&script=true&limit=250&tags=p2pkh`;
|
|
105
|
+
console.error(`Fetching UTXOs from V5: ${url}`);
|
|
106
|
+
const response = await fetch(url);
|
|
106
107
|
if (!response.ok) {
|
|
107
|
-
console.error(
|
|
108
|
-
`WhatsOnChain API error fetching tx hex: ${response.status} ${response.statusText}`,
|
|
109
|
-
);
|
|
108
|
+
console.error(`V5 UTXO fetch failed: ${response.status} ${response.statusText}`);
|
|
110
109
|
return undefined;
|
|
111
110
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
const output = tx.outputs[vout];
|
|
116
|
-
|
|
117
|
-
if (!output) {
|
|
118
|
-
console.error(`Output index ${vout} not found in transaction ${txid}`);
|
|
111
|
+
const data = (await response.json()) as V5Utxo[] | null;
|
|
112
|
+
if (!Array.isArray(data)) {
|
|
113
|
+
console.error(`V5 UTXO response was not an array: ${typeof data}`);
|
|
119
114
|
return undefined;
|
|
120
115
|
}
|
|
121
|
-
|
|
122
|
-
|
|
116
|
+
const utxos: Utxo[] = [];
|
|
117
|
+
for (const utxo of data) {
|
|
118
|
+
if (!utxo.data.p2pkh) {
|
|
119
|
+
// Skip if not a P2PKH
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
const [txid, vout] = utxo.outpoint.split("_");
|
|
123
|
+
if (!txid || !vout) {
|
|
124
|
+
console.error(`Invalid outpoint: ${utxo.outpoint}`);
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
utxos.push({
|
|
128
|
+
txid,
|
|
129
|
+
vout: Number.parseInt(vout),
|
|
130
|
+
satoshis: utxo.satoshis,
|
|
131
|
+
script: toHex(toArray(utxo.script, "base64")),
|
|
132
|
+
} as Utxo);
|
|
133
|
+
}
|
|
134
|
+
return utxos;
|
|
123
135
|
} catch (error) {
|
|
124
|
-
console.error(
|
|
125
|
-
`Error getting script for transaction ${txid}:${vout}:`,
|
|
126
|
-
error,
|
|
127
|
-
);
|
|
136
|
+
console.error("Error fetching payment UTXOs from V5:", error);
|
|
128
137
|
return undefined;
|
|
129
138
|
}
|
|
130
139
|
}
|