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.
Files changed (78) hide show
  1. package/CHANGELOG.md +124 -0
  2. package/README.md +233 -4
  3. package/dist/index.js +120082 -54669
  4. package/index.ts +1196 -88
  5. package/next-env.d.ts +6 -0
  6. package/package.json +58 -15
  7. package/prompts/bsvSdk/index.ts +5 -5
  8. package/prompts/bsvSdk/transaction.ts +2 -2
  9. package/prompts/bsvSdk/wallet.ts +1 -1
  10. package/prompts/index.ts +1 -1
  11. package/resources/bitcom.ts +132 -0
  12. package/resources/resources.ts +7 -3
  13. package/smithery.yaml +3 -0
  14. package/test-mcp-server.ts +157 -0
  15. package/tools/a2b/discover.ts +13 -13
  16. package/tools/bap/friend.ts +266 -0
  17. package/tools/bap/generate.test.ts +350 -0
  18. package/tools/bap/generate.ts +431 -0
  19. package/tools/bap/getCurrentAddress.ts +69 -0
  20. package/tools/bap/getId.test.ts +121 -0
  21. package/tools/bap/getId.ts +169 -0
  22. package/tools/bap/index.ts +111 -0
  23. package/tools/bap/types.ts +66 -0
  24. package/tools/bap/utils.ts +33 -0
  25. package/tools/bsocial/bmapFollow.ts +121 -0
  26. package/tools/bsocial/bmapLikes.ts +111 -0
  27. package/tools/bsocial/bmapReadPosts.ts +148 -0
  28. package/tools/bsocial/createPost.ts +136 -0
  29. package/tools/bsocial/index.ts +45 -0
  30. package/tools/bsocial/readPosts.ts +255 -0
  31. package/tools/bsv/decodeTransaction.ts +7 -6
  32. package/tools/bsv/explore.ts +2 -3
  33. package/tools/bsv/getPrice.ts +1 -9
  34. package/tools/bsv/token.ts +14 -26
  35. package/tools/constants.ts +21 -0
  36. package/tools/index.ts +91 -18
  37. package/tools/mnee/getBalance.ts +2 -4
  38. package/tools/mnee/index.ts +8 -0
  39. package/tools/mnee/parseTx.ts +4 -4
  40. package/tools/mnee/sendMnee.ts +6 -6
  41. package/tools/ordinals/getInscription.ts +2 -3
  42. package/tools/ordinals/getTokenByIdOrTicker.ts +6 -3
  43. package/tools/ordinals/marketListings.ts +2 -18
  44. package/tools/ordinals/marketSales.ts +2 -4
  45. package/tools/ordinals/searchInscriptions.ts +2 -4
  46. package/tools/utils/aip.ts +46 -0
  47. package/tools/utils/conversion.ts +1 -0
  48. package/tools/utils/errorHandler.ts +76 -0
  49. package/tools/utils/index.ts +56 -14
  50. package/tools/utils/installAgentMaster.ts +84 -0
  51. package/tools/utils/logger.ts +20 -0
  52. package/tools/utils/toolConfig.ts +80 -0
  53. package/tools/utils/toolRegistration.ts +66 -0
  54. package/tools/utils/transactionBuilder.ts +196 -0
  55. package/tools/wallet/a2bPublishAgent.ts +25 -30
  56. package/tools/wallet/a2bPublishMcp.ts +43 -44
  57. package/tools/wallet/createOrdinals.ts +13 -20
  58. package/tools/wallet/fetchPaymentUtxos.ts +48 -39
  59. package/tools/wallet/gatherCollectionInfo.ts +370 -0
  60. package/tools/wallet/getAddress.ts +14 -30
  61. package/tools/wallet/getBalance.ts +54 -0
  62. package/tools/wallet/getBalanceDroplet.ts +48 -0
  63. package/tools/wallet/getPublicKey.ts +3 -16
  64. package/tools/wallet/integratedWallet.ts +120 -0
  65. package/tools/wallet/mintCollection.ts +373 -0
  66. package/tools/wallet/purchaseListing.ts +21 -31
  67. package/tools/wallet/refreshUtxos.ts +2 -14
  68. package/tools/wallet/schemas.ts +18 -249
  69. package/tools/wallet/sendOrdinals.ts +14 -21
  70. package/tools/wallet/sendToAddress.ts +2 -18
  71. package/tools/wallet/setupDroplet.ts +161 -0
  72. package/tools/wallet/tools.ts +55 -210
  73. package/tools/wallet/transactionHelper.ts +121 -0
  74. package/tools/wallet/transferOrdToken.ts +19 -24
  75. package/tools/wallet/utxo.ts +62 -0
  76. package/tools/wallet/wallet.ts +237 -234
  77. package/vite.config.ts +15 -0
  78. package/tools/a2b/call.ts +0 -32
@@ -5,286 +5,289 @@
5
5
  *
6
6
  * See: https://github.com/bitcoin-sv/ts-sdk/blob/main/src/wallet/Wallet.interfaces.ts
7
7
  */
8
- import { LockingScript, PrivateKey, ProtoWallet, Transaction } from "@bsv/sdk";
9
- import type {
10
- AbortActionArgs,
11
- AbortActionResult,
12
- AcquireCertificateArgs,
13
- AuthenticatedResult,
14
- CreateActionArgs,
15
- CreateActionResult,
16
- DiscoverByAttributesArgs,
17
- DiscoverByIdentityKeyArgs,
18
- DiscoverCertificatesResult,
19
- GetHeaderArgs,
20
- GetHeaderResult,
21
- GetHeightResult,
22
- GetNetworkResult,
23
- GetPublicKeyArgs,
24
- GetPublicKeyResult,
25
- GetVersionResult,
26
- InternalizeActionArgs,
27
- InternalizeActionResult,
28
- ListActionsArgs,
29
- ListActionsResult,
30
- ListCertificatesArgs,
31
- ListCertificatesResult,
32
- ListOutputsArgs,
33
- ListOutputsResult,
34
- ProveCertificateArgs,
35
- ProveCertificateResult,
36
- PubKeyHex,
37
- RelinquishCertificateArgs,
38
- RelinquishCertificateResult,
39
- RelinquishOutputArgs,
40
- RelinquishOutputResult,
41
- RevealCounterpartyKeyLinkageArgs,
42
- RevealCounterpartyKeyLinkageResult,
43
- RevealSpecificKeyLinkageArgs,
44
- RevealSpecificKeyLinkageResult,
45
- SignActionArgs,
46
- SignActionResult,
47
- WalletCertificate,
48
- WalletInterface,
8
+
9
+ import type { GetPublicKeyArgs, GetPublicKeyResult, PubKeyHex } from "@bsv/sdk";
10
+ import {
11
+ Beef,
12
+ type BroadcastFailure,
13
+ type BroadcastResponse,
14
+ fromUtxo,
15
+ isBroadcastFailure,
16
+ isBroadcastResponse,
17
+ P2PKH,
18
+ PrivateKey,
19
+ type PublicKey,
20
+ SatoshisPerKilobyte,
21
+ Script,
22
+ Transaction,
23
+ Utils,
49
24
  } from "@bsv/sdk";
50
- import { type NftUtxo, type Utxo, fetchNftUtxos } from "js-1sat-ord";
51
- import { fetchPaymentUtxos } from "./fetchPaymentUtxos";
25
+ import { fetchNftUtxos, type NftUtxo, type Utxo } from "js-1sat-ord";
26
+ import { V5Broadcaster } from "../../utils/broadcaster";
27
+ import { fetchPaymentUtxosFromV5 } from "./fetchPaymentUtxos";
28
+
29
+ // Local interface for what encrypt/decrypt expect, will be mapped from Zod schema
30
+ interface InternalEncryptionArgs {
31
+ data: number[];
32
+ recipientPublicKey?: PublicKey; // For encryption
33
+ }
34
+
35
+ interface InternalDecryptionArgs {
36
+ data: number[];
37
+ }
52
38
 
53
- export class Wallet extends ProtoWallet implements WalletInterface {
39
+ export class Wallet {
54
40
  private paymentUtxos: Utxo[] = [];
55
41
  private nftUtxos: NftUtxo[] = [];
56
42
  private lastUtxoFetch = 0;
57
43
  private readonly utxoRefreshIntervalMs = 5 * 60 * 1000; // 5 minutes
58
- private privateKey?: PrivateKey;
44
+ private paymentKey?: PrivateKey;
45
+ private identityKey?: PrivateKey;
46
+ constructor(paymentKey?: PrivateKey, identityKey?: PrivateKey) {
47
+ this.paymentKey = paymentKey;
48
+ this.identityKey = identityKey;
59
49
 
60
- constructor(privKey?: PrivateKey) {
61
- super(privKey);
62
- this.privateKey = privKey;
63
- // Initialize UTXOs
64
- this.refreshUtxos().catch((err) =>
65
- console.error("Error initializing UTXOs:", err),
66
- );
50
+ if (this.paymentKey) {
51
+ this.refreshUtxos().catch((err) =>
52
+ console.error("Error initializing UTXOs:", err),
53
+ );
54
+ }
67
55
  }
68
56
 
69
- /**
70
- * Refresh UTXOs from the network
71
- */
72
57
  async refreshUtxos(): Promise<void> {
73
- try {
74
- const privateKey = this.getPrivateKey();
75
- if (!privateKey) {
76
- return; // Silent fail if no private key, keep existing UTXOs
77
- }
78
-
79
- const address = privateKey.toAddress().toString();
80
- this.lastUtxoFetch = Date.now();
58
+ const currentPaymentKey = this.getPaymentKey();
59
+ if (!currentPaymentKey) {
60
+ console.error("Wallet: refreshUtxos called without a payment key.");
61
+ return;
62
+ }
63
+ const address = currentPaymentKey.toAddress();
64
+ this.lastUtxoFetch = Date.now();
65
+ console.error(`Wallet: Refreshing UTXOs for address ${address}...`);
81
66
 
82
- // Payment UTXOs
83
- let newPaymentUtxos: Utxo[] | undefined = undefined;
84
- try {
85
- newPaymentUtxos = await fetchPaymentUtxos(address);
86
- // Only update if we successfully got UTXOs
87
- if (Array.isArray(newPaymentUtxos)) {
88
- this.paymentUtxos = newPaymentUtxos;
89
- }
90
- } catch (error) {
91
- // Keep existing UTXOs, don't clear them on error
67
+ try {
68
+ const newPaymentUtxos = await fetchPaymentUtxosFromV5(address);
69
+ if (Array.isArray(newPaymentUtxos)) {
70
+ this.paymentUtxos = newPaymentUtxos;
71
+ console.error(
72
+ `Wallet: Fetched ${this.paymentUtxos.length} payment UTXOs.`,
73
+ );
74
+ } else {
75
+ console.error(
76
+ "Wallet: fetchPaymentUtxos did not return an array. Keeping existing payment UTXOs.",
77
+ );
92
78
  }
79
+ } catch (error) {
80
+ console.error("Wallet: Error fetching payment UTXOs:", error);
81
+ // Keep existing UTXOs on error
82
+ }
93
83
 
94
- // NFT UTXOs - keep existing if fetch fails
95
- let newNftUtxos: NftUtxo[] = [];
96
- try {
97
- newNftUtxos = await fetchNftUtxos(address);
98
- // Only update if we successfully got UTXOs
99
- if (Array.isArray(newNftUtxos)) {
100
- this.nftUtxos = newNftUtxos;
101
- }
102
- } catch (error) {
103
- // Keep existing UTXOs, don't clear them on error
84
+ try {
85
+ const newNftUtxos = await fetchNftUtxos(address);
86
+ if (Array.isArray(newNftUtxos)) {
87
+ this.nftUtxos = newNftUtxos;
88
+ console.error(`Wallet: Fetched ${this.nftUtxos.length} NFT UTXOs.`);
89
+ } else {
90
+ console.error(
91
+ "Wallet: fetchNftUtxos did not return an array. Keeping existing NFT UTXOs.",
92
+ );
104
93
  }
105
94
  } catch (error) {
106
- // Silent global error, preserve existing UTXOs
95
+ console.error("Wallet: Error fetching NFT UTXOs:", error);
96
+ // Keep existing UTXOs on error
107
97
  }
108
98
  }
109
99
 
110
- /**
111
- * Get payment and NFT UTXOs, refreshing if needed
112
- */
113
100
  async getUtxos(): Promise<{ paymentUtxos: Utxo[]; nftUtxos: NftUtxo[] }> {
114
101
  const now = Date.now();
102
+ if (!this.paymentKey) {
103
+ // If there's no private key, UTXOs can't be fetched or belong to anyone.
104
+ return { paymentUtxos: [], nftUtxos: [] };
105
+ }
115
106
  if (now - this.lastUtxoFetch > this.utxoRefreshIntervalMs) {
116
107
  await this.refreshUtxos();
117
108
  }
118
109
  return { paymentUtxos: this.paymentUtxos, nftUtxos: this.nftUtxos };
119
110
  }
120
111
 
121
- /**
122
- * Get the private key if available
123
- */
124
- getPrivateKey(): PrivateKey | undefined {
125
- // Try to get private key from environment if not already set
126
- if (!this.privateKey) {
112
+ getIdentityKey(): PrivateKey | undefined {
113
+ if (this.identityKey) {
114
+ return this.identityKey;
115
+ }
116
+ const wif = process.env.IDENTITY_KEY_WIF;
117
+ if (wif) {
118
+ try {
119
+ this.identityKey = PrivateKey.fromWif(wif);
120
+ return this.identityKey;
121
+ } catch (e) {
122
+ console.error(
123
+ "Wallet: Invalid Identity Key WIF from environment variable.",
124
+ e,
125
+ );
126
+ }
127
+ }
128
+ return undefined;
129
+ }
130
+
131
+ getPaymentKey(): PrivateKey | undefined {
132
+ if (!this.paymentKey) {
127
133
  const wif = process.env.PRIVATE_KEY_WIF;
128
134
  if (wif) {
129
- this.privateKey = PrivateKey.fromWif(wif);
135
+ try {
136
+ this.paymentKey = PrivateKey.fromWif(wif);
137
+ } catch (e) {
138
+ console.error("Wallet: Invalid WIF from environment variable.", e);
139
+ }
130
140
  }
131
141
  }
132
- return this.privateKey;
142
+ return this.paymentKey;
133
143
  }
134
144
 
135
- async getPublicKey(args: GetPublicKeyArgs): Promise<GetPublicKeyResult> {
136
- const privateKey = this.getPrivateKey();
137
- if (!privateKey) {
138
- throw new Error("No private key available");
139
- }
145
+ getAddress(): string | undefined {
146
+ return this.getPaymentKey()?.toAddress();
147
+ }
140
148
 
141
- const publicKey = privateKey.toPublicKey();
149
+ async getPublicKey(args?: GetPublicKeyArgs): Promise<GetPublicKeyResult> {
150
+ const currentPaymentKey = this.getPaymentKey();
151
+ if (!currentPaymentKey) {
152
+ throw new Error("No payment key available to derive public key.");
153
+ }
154
+ const publicKey = currentPaymentKey.toPublicKey();
142
155
  return {
143
156
  publicKey: publicKey.toDER("hex") as PubKeyHex,
144
157
  };
145
158
  }
146
- async revealCounterpartyKeyLinkage(
147
- args: RevealCounterpartyKeyLinkageArgs,
148
- ): Promise<RevealCounterpartyKeyLinkageResult> {
149
- return Promise.reject(new Error("Not implemented"));
150
- }
151
- async revealSpecificKeyLinkage(
152
- args: RevealSpecificKeyLinkageArgs,
153
- ): Promise<RevealSpecificKeyLinkageResult> {
154
- return Promise.reject(new Error("Not implemented"));
155
- }
156
- // Implemented by ProtoWallet
157
- // async encrypt(args: WalletEncryptArgs): Promise<WalletEncryptResult> {
158
- // return this.encrypt(args);
159
- // }
160
- // async decrypt(args: WalletDecryptArgs): Promise<WalletDecryptResult> {
161
- // return this.decrypt(args);
162
- // }
163
- // async createHmac(args: CreateHmacArgs): Promise<CreateHmacResult> {
164
- // return this.createHmac(args);
165
- // }
166
- // async verifyHmac(args: VerifyHmacArgs): Promise<VerifyHmacResult> {
167
- // return this.verifyHmac(args);
168
- // }
169
- // async createSignature(
170
- // args: CreateSignatureArgs,
171
- // ): Promise<CreateSignatureResult> {
172
- // return Promise.reject(new Error("Not implemented"));
159
+
160
+ // async encrypt(args: {
161
+ // data: Buffer;
162
+ // recipientPublicKeyHex: string;
163
+ // }): Promise<Buffer> {
164
+ // const senderPaymentKey = this.getPaymentKey();
165
+ // if (!senderPaymentKey) {
166
+ // throw new Error("Cannot encrypt: Wallet payment key is not available.");
167
+ // }
168
+ // if (!args.recipientPublicKeyHex) {
169
+ // throw new Error(
170
+ // "Cannot encrypt: Recipient's public key hex is required.",
171
+ // );
172
+ // }
173
+ // let recipientPublicKey: PublicKey;
174
+ // try {
175
+ // recipientPublicKey = PublicKey.fromString(args.recipientPublicKeyHex);
176
+ // } catch (e) {
177
+ // throw new Error(
178
+ // `Invalid recipient public key hex: ${args.recipientPublicKeyHex}`,
179
+ // );
180
+ // }
181
+ // // TODO: Find the correct ECIES encryption method in @bsv/sdk
182
+ // // return senderPaymentKey.encrypt(args.data, recipientPublicKey);
183
+ // throw new Error("Encryption not implemented pending ECIES investigation.");
173
184
  // }
174
- // async verifySignature(
175
- // args: VerifySignatureArgs,
176
- // ): Promise<VerifySignatureResult> {
177
- // return Promise.reject(new Error("Not implemented"));
185
+
186
+ // async decrypt(args: { data: Buffer }): Promise<Buffer> {
187
+ // const walletPaymentKey = this.getPaymentKey();
188
+ // if (!walletPaymentKey) {
189
+ // throw new Error("Cannot decrypt: Wallet payment key is not available.");
190
+ // }
191
+ // // TODO: Find the correct ECIES decryption method in @bsv/sdk
192
+ // // return walletPaymentKey.decrypt(args.data);
193
+ // throw new Error("Decryption not implemented pending ECIES investigation.");
178
194
  // }
179
- async createAction(args: CreateActionArgs): Promise<CreateActionResult> {
195
+
196
+ async sendToAddress(
197
+ address: string,
198
+ amountSatoshis: number,
199
+ ): Promise<{ txid: string; rawTx?: string }> {
200
+ const pk = this.getPaymentKey();
201
+ if (!pk) throw new Error("Payment key not available to send transaction.");
202
+
180
203
  const tx = new Transaction();
204
+ tx.addOutput({
205
+ lockingScript: new P2PKH().lock(address),
206
+ satoshis: amountSatoshis,
207
+ });
181
208
 
182
- // Add outputs
183
- if (args.outputs) {
184
- for (const output of args.outputs) {
185
- const lockingScript = LockingScript.fromHex(output.lockingScript);
186
- tx.addOutput({
187
- lockingScript,
188
- satoshis: output.satoshis,
189
- });
190
- }
209
+ const { paymentUtxos } = await this.getUtxos();
210
+ if (paymentUtxos.length === 0)
211
+ throw new Error("No UTXOs available to send.");
212
+
213
+ let totalInputSats = 0n;
214
+ const feeModel = new SatoshisPerKilobyte(10);
215
+ let estimatedFee = await feeModel.computeFee(tx);
216
+
217
+ for (const utxo of paymentUtxos) {
218
+ if (totalInputSats >= BigInt(amountSatoshis) + BigInt(estimatedFee))
219
+ break;
220
+
221
+ const unlockingScriptTemplate = new P2PKH().unlock(
222
+ pk,
223
+ "all",
224
+ false,
225
+ utxo.satoshis,
226
+ Script.fromBinary(Utils.toArray(utxo.script, "hex")),
227
+ );
228
+ const input = fromUtxo(utxo, unlockingScriptTemplate);
229
+ tx.addInput(input);
230
+ totalInputSats += BigInt(utxo.satoshis);
231
+ estimatedFee = await feeModel.computeFee(tx);
191
232
  }
192
233
 
193
- // Add inputs (if provided)
194
- if (args.inputs) {
195
- for (const input of args.inputs) {
196
- const [txid, outputIndexStr] = input.outpoint.split(".");
197
- tx.addInput({
198
- sourceTXID: txid,
199
- sourceOutputIndex: Number.parseInt(outputIndexStr || "0", 10),
200
- });
201
- }
234
+ if (totalInputSats < BigInt(amountSatoshis) + BigInt(estimatedFee)) {
235
+ throw new Error(
236
+ `Not enough funds. Required: ${BigInt(amountSatoshis) + BigInt(estimatedFee)}, Available: ${totalInputSats}`,
237
+ );
202
238
  }
203
239
 
204
- // Set lockTime and version if provided
205
- if (args.lockTime !== undefined) tx.lockTime = args.lockTime;
206
- if (args.version !== undefined) tx.version = args.version;
240
+ const change =
241
+ totalInputSats - (BigInt(amountSatoshis) + BigInt(estimatedFee));
242
+ if (change > 0) {
243
+ const changeAddress = this.getAddress();
244
+ if (!changeAddress)
245
+ throw new Error("Could not determine change address.");
246
+ tx.addOutput({
247
+ lockingScript: new P2PKH().lock(changeAddress),
248
+ satoshis: Number(change),
249
+ change: true,
250
+ });
251
+ }
207
252
 
208
- // Serialize the transaction using Utils
209
- const txid = tx.hash("hex") as string;
210
- const txArray = tx.toBinary();
253
+ await tx.fee(feeModel);
254
+ await tx.sign();
211
255
 
212
- return {
213
- txid,
214
- tx: txArray,
215
- signableTransaction: undefined,
216
- };
217
- }
218
- async signAction(args: SignActionArgs): Promise<SignActionResult> {
219
- return Promise.reject(new Error("Not implemented"));
220
- }
221
- async abortAction(args: AbortActionArgs): Promise<AbortActionResult> {
222
- return Promise.reject(new Error("Not implemented"));
223
- }
224
- async listActions(args: ListActionsArgs): Promise<ListActionsResult> {
225
- return Promise.reject(new Error("Not implemented"));
226
- }
227
- async internalizeAction(
228
- args: InternalizeActionArgs,
229
- ): Promise<InternalizeActionResult> {
230
- return Promise.reject(new Error("Not implemented"));
231
- }
232
- async listOutputs(args: ListOutputsArgs): Promise<ListOutputsResult> {
233
- return Promise.reject(new Error("Not implemented"));
234
- }
235
- async relinquishOutput(
236
- args: RelinquishOutputArgs,
237
- ): Promise<RelinquishOutputResult> {
238
- return Promise.reject(new Error("Not implemented"));
239
- }
240
- async acquireCertificate(
241
- args: AcquireCertificateArgs,
242
- ): Promise<WalletCertificate> {
243
- return Promise.reject(new Error("Not implemented"));
244
- }
245
- async listCertificates(
246
- args: ListCertificatesArgs,
247
- ): Promise<ListCertificatesResult> {
248
- return Promise.reject(new Error("Not implemented"));
249
- }
250
- async proveCertificate(
251
- args: ProveCertificateArgs,
252
- ): Promise<ProveCertificateResult> {
253
- return Promise.reject(new Error("Not implemented"));
254
- }
255
- async relinquishCertificate(
256
- args: RelinquishCertificateArgs,
257
- ): Promise<RelinquishCertificateResult> {
258
- return Promise.reject(new Error("Not implemented"));
259
- }
260
- async discoverByIdentityKey(
261
- args: DiscoverByIdentityKeyArgs,
262
- ): Promise<DiscoverCertificatesResult> {
263
- return Promise.reject(new Error("Not implemented"));
264
- }
265
- async discoverByAttributes(
266
- args: DiscoverByAttributesArgs,
267
- ): Promise<DiscoverCertificatesResult> {
268
- return Promise.reject(new Error("Not implemented"));
269
- }
270
- async isAuthenticated(args: object): Promise<AuthenticatedResult> {
271
- return Promise.reject(new Error("Not implemented"));
272
- }
273
- async waitForAuthentication(args: object): Promise<AuthenticatedResult> {
274
- return Promise.reject(new Error("Not implemented"));
275
- }
276
- async getHeight(args: object): Promise<GetHeightResult> {
277
- return Promise.reject(new Error("Not implemented"));
278
- }
279
- async getHeaderForHeight(args: GetHeaderArgs): Promise<GetHeaderResult> {
280
- return Promise.reject(new Error("Not implemented"));
281
- }
282
- async getNetwork(args: object): Promise<GetNetworkResult> {
283
- return Promise.reject(new Error("Not implemented"));
284
- }
285
- async getVersion(args: object): Promise<GetVersionResult> {
286
- return Promise.reject(new Error("Not implemented"));
256
+ const rawTx = tx.toHex();
257
+ const txidFromTxObject = tx.id("hex");
258
+
259
+ try {
260
+ const broadcaster = new V5Broadcaster();
261
+ const broadcastResult: BroadcastResponse | BroadcastFailure =
262
+ await tx.broadcast(broadcaster);
263
+
264
+ if (isBroadcastResponse(broadcastResult)) {
265
+ console.error(
266
+ `Transaction broadcasted successfully: ${broadcastResult.txid}. Message: ${broadcastResult.message}`,
267
+ );
268
+ return { txid: broadcastResult.txid, rawTx };
269
+ }
270
+ if (isBroadcastFailure(broadcastResult)) {
271
+ console.error(
272
+ `Transaction broadcast failed: ${broadcastResult.description} (Code: ${broadcastResult.code}). TXID from object (if available): ${broadcastResult.txid ?? txidFromTxObject}`,
273
+ );
274
+ throw new Error(
275
+ `Broadcast failed: ${broadcastResult.description} (Code: ${broadcastResult.code})`,
276
+ );
277
+ }
278
+ console.error(
279
+ `Transaction broadcast status uncertain. TXID from tx object: ${txidFromTxObject}. Unexpected broadcast result: `,
280
+ broadcastResult,
281
+ );
282
+ return { txid: txidFromTxObject, rawTx };
283
+ } catch (error) {
284
+ console.error(
285
+ "Failed to broadcast transaction (exception caught):",
286
+ error,
287
+ );
288
+ throw new Error(
289
+ `Failed to broadcast transaction ${txidFromTxObject}: ${error instanceof Error ? error.message : String(error)}`,
290
+ );
291
+ }
287
292
  }
288
293
  }
289
-
290
- export default Wallet;
package/vite.config.ts ADDED
@@ -0,0 +1,15 @@
1
+ import { resolve } from "node:path";
2
+ import { defineConfig } from "vite";
3
+ import { viteSingleFile } from "vite-plugin-singlefile";
4
+
5
+ export default defineConfig({
6
+ root: resolve(__dirname, "src/views"),
7
+ plugins: [viteSingleFile()],
8
+ build: {
9
+ rollupOptions: {
10
+ input: resolve(__dirname, "src/views/app.html"),
11
+ },
12
+ outDir: resolve(__dirname, "dist"),
13
+ emptyOutDir: false,
14
+ },
15
+ });
package/tools/a2b/call.ts DELETED
@@ -1,32 +0,0 @@
1
- import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- import type { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js";
3
- import { z } from "zod";
4
-
5
- // Schema for invoking another agent via A2A protocol
6
- export const a2aCallArgsSchema = z.object({
7
- url: z.string().url().describe("Full agent-to-agent endpoint URL"),
8
- method: z.string().describe("A2A method name to invoke"),
9
- params: z
10
- .record(z.any())
11
- .optional()
12
- .describe("Payload parameters for the A2A call"),
13
- });
14
- export type A2aCallArgs = z.infer<typeof a2aCallArgsSchema>;
15
-
16
- /**
17
- * Registers the a2a_call tool for agent-to-agent HTTP/SSE calls
18
- */
19
- export function registerA2aCallTool(server: McpServer) {
20
- server.tool(
21
- "a2a_call",
22
- "Invoke a remote agent's A2A endpoint via HTTP/SSE",
23
- { args: a2aCallArgsSchema },
24
- async ({ args }: { args: A2aCallArgs }, extra: RequestHandlerExtra) => {
25
- // TODO: implement HTTP request logic (e.g., fetch, SSE)
26
- return {
27
- content: [{ type: "text", text: "Not implemented" }],
28
- isError: true,
29
- };
30
- },
31
- );
32
- }