@ton/mcp 0.1.12 → 0.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -43544,9 +43544,12 @@ function isFriendlyTonAddress(address) {
43544
43544
  *
43545
43545
  */
43546
43546
  function asHex(data) {
43547
- if (!/^0x[0-9a-fA-F]+$/.test(data) || data.length % 2 !== 0) throw new Error("Not a valid hex");
43547
+ if (!isHex(data)) throw new Error("Not a valid hex");
43548
43548
  return data;
43549
43549
  }
43550
+ function isHex(data) {
43551
+ return /^0x[0-9a-fA-F]+$/.test(data) && data.length % 2 === 0;
43552
+ }
43550
43553
 
43551
43554
  //#endregion
43552
43555
  //#region ../walletkit/dist/esm/errors/codes.js
@@ -45054,7 +45057,7 @@ function delay(ms) {
45054
45057
  * LICENSE file in the root directory of this source tree.
45055
45058
  *
45056
45059
  */
45057
- async function CallForSuccess(toCall, attempts = 20, delayMs = 100) {
45060
+ async function CallForSuccess(toCall, attempts = 20, delayMs = 100, shouldRetry) {
45058
45061
  if (typeof toCall !== "function") throw new Error("unknown input");
45059
45062
  let i = 0;
45060
45063
  let lastError;
@@ -45062,6 +45065,7 @@ async function CallForSuccess(toCall, attempts = 20, delayMs = 100) {
45062
45065
  return await toCall();
45063
45066
  } catch (err) {
45064
45067
  lastError = err;
45068
+ if (shouldRetry && !shouldRetry(err)) throw err;
45065
45069
  i++;
45066
45070
  await delay(delayMs);
45067
45071
  }
@@ -45350,6 +45354,16 @@ function isValidEventMethod(method) {
45350
45354
  ].includes(method);
45351
45355
  }
45352
45356
 
45357
+ //#endregion
45358
+ //#region ../walletkit/dist/esm/validation/address.js
45359
+ /**
45360
+ * Copyright (c) TonTech.
45361
+ *
45362
+ * This source code is licensed under the MIT license found in the
45363
+ * LICENSE file in the root directory of this source tree.
45364
+ *
45365
+ */
45366
+
45353
45367
  //#endregion
45354
45368
  //#region ../walletkit/dist/esm/validation/transaction.js
45355
45369
  /**
@@ -85721,13 +85735,11 @@ function getDeviceInfoWithDefaults(options) {
85721
85735
  */
85722
85736
  function getDeviceInfoForWallet(walletAdapter, deviceInfoOptions) {
85723
85737
  const baseDeviceInfo = getDeviceInfoWithDefaults(deviceInfoOptions);
85724
- if (walletAdapter?.getSupportedFeatures) {
85725
- const adapterFeatures = walletAdapter.getSupportedFeatures();
85726
- return addLegacySendTransactionFeature({
85727
- ...baseDeviceInfo,
85728
- features: adapterFeatures
85729
- });
85730
- }
85738
+ const walletSupportedFeatures = walletAdapter?.getSupportedFeatures();
85739
+ if (walletSupportedFeatures) return addLegacySendTransactionFeature({
85740
+ ...baseDeviceInfo,
85741
+ features: walletSupportedFeatures
85742
+ });
85731
85743
  return baseDeviceInfo;
85732
85744
  }
85733
85745
  function addLegacySendTransactionFeature(options) {
@@ -86890,6 +86902,7 @@ var AssetType;
86890
86902
  const Network = {
86891
86903
  mainnet: () => ({ chainId: "-239" }),
86892
86904
  testnet: () => ({ chainId: "-3" }),
86905
+ tetra: () => ({ chainId: "662387" }),
86893
86906
  custom: (chainId) => ({ chainId })
86894
86907
  };
86895
86908
 
@@ -87219,15 +87232,12 @@ var TransactionHandler = class extends BasicHandler {
87219
87232
  */
87220
87233
  validateNetwork(network, wallet) {
87221
87234
  let errors = [];
87222
- if (typeof network === "string") if (network === "-3" || network === "-239") {
87223
- const chain = network === "-3" ? CHAIN.TESTNET : CHAIN.MAINNET;
87224
- if (chain !== wallet.getNetwork().chainId) errors.push("Invalid network not equal to wallet network");
87225
- else return {
87226
- result: chain,
87227
- isValid: errors.length === 0,
87228
- errors
87229
- };
87230
- } else errors.push("Invalid network not a valid network");
87235
+ if (typeof network === "string") if (network !== wallet.getNetwork().chainId) errors.push("Invalid network not equal to wallet network");
87236
+ else return {
87237
+ result: network,
87238
+ isValid: errors.length === 0,
87239
+ errors
87240
+ };
87231
87241
  else errors.push("Invalid network not a string");
87232
87242
  return {
87233
87243
  result: void 0,
@@ -88428,25 +88438,21 @@ function parseDomain(url) {
88428
88438
  }
88429
88439
  }
88430
88440
  function toTonConnectSignDataPayload(payload) {
88431
- let network;
88432
- if (payload.network?.chainId === CHAIN.MAINNET) network = CHAIN.MAINNET;
88433
- else if (payload.network?.chainId === CHAIN.TESTNET) network = CHAIN.TESTNET;
88434
- else network = void 0;
88435
88441
  if (payload.data.type === "text") return {
88436
- network,
88442
+ network: payload.network?.chainId,
88437
88443
  from: payload.fromAddress,
88438
88444
  type: "text",
88439
88445
  text: payload.data.value.content
88440
88446
  };
88441
88447
  else if (payload.data.type === "cell") return {
88442
- network,
88448
+ network: payload.network?.chainId,
88443
88449
  from: payload.fromAddress,
88444
88450
  type: "cell",
88445
88451
  schema: payload.data.value.schema,
88446
88452
  cell: payload.data.value.content
88447
88453
  };
88448
88454
  else return {
88449
- network,
88455
+ network: payload.network?.chainId,
88450
88456
  from: payload.fromAddress,
88451
88457
  type: "binary",
88452
88458
  bytes: payload.data.value.content
@@ -89858,7 +89864,19 @@ function DefaultSignature(data, privateKey) {
89858
89864
  if (fullKey.length === 32) fullKey = (0, import_dist$1.keyPairFromSeed)(Buffer.from(fullKey)).secretKey;
89859
89865
  return Uint8ArrayToHex((0, import_dist$1.sign)(Buffer.from(Uint8Array.from(data)), Buffer.from(fullKey)));
89860
89866
  }
89861
- function createWalletSigner(privateKey) {
89867
+ function DefaultDomainSignature(data, privateKey, domain) {
89868
+ let fullKey = privateKey;
89869
+ if (fullKey.length === 32) fullKey = (0, import_dist$1.keyPairFromSeed)(Buffer.from(fullKey)).secretKey;
89870
+ return Uint8ArrayToHex((0, import_dist$2.domainSign)({
89871
+ data: Buffer.from(Uint8Array.from(data)),
89872
+ secretKey: Buffer.from(fullKey),
89873
+ domain
89874
+ }));
89875
+ }
89876
+ function createWalletSigner(privateKey, domain) {
89877
+ if (domain) return async (data) => {
89878
+ return DefaultDomainSignature(Uint8Array.from(data), privateKey, domain);
89879
+ };
89862
89880
  return async (data) => {
89863
89881
  return DefaultSignature(Uint8Array.from(data), privateKey);
89864
89882
  };
@@ -89887,10 +89905,10 @@ var Signer = class {
89887
89905
  * @param options - Optional configuration for mnemonic type
89888
89906
  * @returns Signer function with publicKey property
89889
89907
  */
89890
- static async fromMnemonic(mnemonic, options) {
89908
+ static async fromMnemonic(mnemonic, options, domain) {
89891
89909
  const keyPair = await MnemonicToKeyPair(mnemonic, options?.type ?? "ton");
89892
89910
  return {
89893
- sign: createWalletSigner(keyPair.secretKey),
89911
+ sign: createWalletSigner(keyPair.secretKey, domain),
89894
89912
  publicKey: Uint8ArrayToHex(keyPair.publicKey)
89895
89913
  };
89896
89914
  }
@@ -89899,11 +89917,11 @@ var Signer = class {
89899
89917
  * @param privateKey - Private key as hex string or Uint8Array
89900
89918
  * @returns Signer function with publicKey property
89901
89919
  */
89902
- static async fromPrivateKey(privateKey) {
89920
+ static async fromPrivateKey(privateKey, domain) {
89903
89921
  const privateKeyBytes = typeof privateKey === "string" ? Uint8Array.from(Buffer.from(privateKey.replace("0x", ""), "hex")) : privateKey;
89904
89922
  const keyPair = (0, import_dist$1.keyPairFromSeed)(Buffer.from(privateKeyBytes));
89905
89923
  return {
89906
- sign: createWalletSigner(keyPair.secretKey),
89924
+ sign: createWalletSigner(keyPair.secretKey, domain),
89907
89925
  publicKey: Uint8ArrayToHex(keyPair.publicKey)
89908
89926
  };
89909
89927
  }
@@ -90097,6 +90115,238 @@ async function getNftFromClient(client, address) {
90097
90115
  return result.nfts.length > 0 ? result.nfts[0] : null;
90098
90116
  }
90099
90117
 
90118
+ //#endregion
90119
+ //#region ../walletkit/dist/esm/utils/toncenter/getTxOpcode.js
90120
+ /**
90121
+ * Copyright (c) TonTech.
90122
+ *
90123
+ * This source code is licensed under the MIT license found in the
90124
+ * LICENSE file in the root directory of this source tree.
90125
+ *
90126
+ */
90127
+ /**
90128
+ * Returns the resolved opcode for a transaction.
90129
+ */
90130
+ const getTxOpcode = (tx) => {
90131
+ const msg = tx.in_msg;
90132
+ if (!msg) return null;
90133
+ return msg.opcode ?? null;
90134
+ };
90135
+
90136
+ //#endregion
90137
+ //#region ../walletkit/dist/esm/utils/toncenter/createTraceTypeDetector.js
90138
+ /**
90139
+ * Copyright (c) TonTech.
90140
+ *
90141
+ * This source code is licensed under the MIT license found in the
90142
+ * LICENSE file in the root directory of this source tree.
90143
+ *
90144
+ */
90145
+ /**
90146
+ * Generic factory function to create a trace type detector.
90147
+ * Returns true if the trace contains at least one transaction with ANY of the trigger opcodes.
90148
+ */
90149
+ const createTraceTypeDetector = (triggerOpcodes) => {
90150
+ return (transactions) => {
90151
+ for (const tx of Object.values(transactions)) {
90152
+ const opcode = getTxOpcode(tx);
90153
+ if (opcode && triggerOpcodes.has(opcode)) return true;
90154
+ }
90155
+ return false;
90156
+ };
90157
+ };
90158
+
90159
+ //#endregion
90160
+ //#region ../walletkit/dist/esm/utils/toncenter/isTransactionFailed.js
90161
+ /**
90162
+ * Copyright (c) TonTech.
90163
+ *
90164
+ * This source code is licensed under the MIT license found in the
90165
+ * LICENSE file in the root directory of this source tree.
90166
+ *
90167
+ */
90168
+ /**
90169
+ * Checks if a single transaction failed.
90170
+ * A transaction is considered failed if it was aborted, or if its compute
90171
+ * or action phases failed to execute successfully (including skipped actions).
90172
+ */
90173
+ const isTransactionFailed = (tx) => {
90174
+ const desc = tx.description;
90175
+ if (!desc) return false;
90176
+ if (desc.aborted) return true;
90177
+ if (desc.compute_ph?.success === false) return true;
90178
+ if (desc.action?.success === false) return true;
90179
+ if (desc.action && desc.action.skipped_actions > 0) return true;
90180
+ return false;
90181
+ };
90182
+
90183
+ //#endregion
90184
+ //#region ../walletkit/dist/esm/utils/toncenter/createFailureDetector.js
90185
+ /**
90186
+ * Copyright (c) TonTech.
90187
+ *
90188
+ * This source code is licensed under the MIT license found in the
90189
+ * LICENSE file in the root directory of this source tree.
90190
+ *
90191
+ */
90192
+ /**
90193
+ * Generic factory function to create a failure detector.
90194
+ * Checks if ANY transaction in the trace has aborted, EXCEPT those
90195
+ * explicitly listed in the `nonCriticalOpcodes` set.
90196
+ *
90197
+ * If a transaction opcode is in `nonCriticalOpcodes`, its failure is ignored.
90198
+ * If a transaction has an unknown opcode or an opcode not in the set, and it fails,
90199
+ * the entire trace is considered failed.
90200
+ */
90201
+ const createFailureDetector = (nonCriticalOpcodes) => {
90202
+ return (transactions) => {
90203
+ for (const tx of Object.values(transactions)) if (isTransactionFailed(tx)) {
90204
+ const opcode = getTxOpcode(tx);
90205
+ if (opcode && nonCriticalOpcodes.has(opcode)) continue;
90206
+ return true;
90207
+ }
90208
+ return false;
90209
+ };
90210
+ };
90211
+
90212
+ //#endregion
90213
+ //#region ../walletkit/dist/esm/utils/toncenter/isFailedTrace.js
90214
+ /**
90215
+ * Copyright (c) TonTech.
90216
+ *
90217
+ * This source code is licensed under the MIT license found in the
90218
+ * LICENSE file in the root directory of this source tree.
90219
+ *
90220
+ */
90221
+ const KNOWN_TRACE_TYPES = [{
90222
+ triggerOpcodes: new Set(["0x0f8a7ea5"]),
90223
+ safeToSkipOpcodes: new Set(["0x7362d09c", "0xd53276db"])
90224
+ }];
90225
+ /**
90226
+ * Determines if a transaction trace has failed.
90227
+ *
90228
+ * In TON, a single transaction triggers a tree of internal messages.
90229
+ * Some messages can fail (abort) or be skipped without affecting the main action.
90230
+ *
90231
+ * This function applies action-specific logic:
90232
+ * - Checks known trace types (like Jetton Transfers) against their specific allowed failures.
90233
+ * - **Unknown types**: checks if ANY transaction in the trace has failed.
90234
+ *
90235
+ * @param tx - The trace response from toncenter
90236
+ * @returns `true` if the trace is considered failed
90237
+ */
90238
+ const isFailedTrace = (tx) => {
90239
+ const trace = tx.traces?.[0];
90240
+ if (!trace) return false;
90241
+ const transactions = trace.transactions ?? {};
90242
+ if (Object.keys(transactions).length === 0) return false;
90243
+ for (const config of KNOWN_TRACE_TYPES) if (createTraceTypeDetector(config.triggerOpcodes)(transactions)) return createFailureDetector(config.safeToSkipOpcodes)(transactions);
90244
+ return createFailureDetector(/* @__PURE__ */ new Set())(transactions);
90245
+ };
90246
+
90247
+ //#endregion
90248
+ //#region ../walletkit/dist/esm/utils/toncenter/parseTraceResponse.js
90249
+ /**
90250
+ * Copyright (c) TonTech.
90251
+ *
90252
+ * This source code is licensed under the MIT license found in the
90253
+ * LICENSE file in the root directory of this source tree.
90254
+ *
90255
+ */
90256
+ /**
90257
+ * Helper to parse ToncenterTracesResponse into TransactionStatusResponse.
90258
+ * Returns null if no traces are found.
90259
+ */
90260
+ const parseTraceResponse = (response) => {
90261
+ if (!response.traces || response.traces.length === 0) return null;
90262
+ const traceInfo = response.traces[0].trace_info;
90263
+ const isEffectivelyCompleted = traceInfo.trace_state === "complete" || traceInfo.trace_state === "pending" && traceInfo.pending_messages === 0;
90264
+ let status = "pending";
90265
+ if (traceInfo.pending_messages === 0) {
90266
+ if (isFailedTrace(response)) status = "failed";
90267
+ else if (isEffectivelyCompleted) status = "completed";
90268
+ }
90269
+ return {
90270
+ status,
90271
+ totalMessages: traceInfo.messages,
90272
+ pendingMessages: traceInfo.pending_messages,
90273
+ onchainMessages: traceInfo.messages - traceInfo.pending_messages
90274
+ };
90275
+ };
90276
+
90277
+ //#endregion
90278
+ //#region ../walletkit/dist/esm/utils/getNormalizedExtMessageHash.js
90279
+ /**
90280
+ * Copyright (c) TonTech.
90281
+ *
90282
+ * This source code is licensed under the MIT license found in the
90283
+ * LICENSE file in the root directory of this source tree.
90284
+ *
90285
+ */
90286
+ /**
90287
+ * Generates a normalized hash of an "external-in" message for comparison.
90288
+ *
90289
+ * This function ensures consistent hashing of external-in messages by following [TEP-467].
90290
+ * See documentation: https://docs.ton.org/ecosystem/ton-connect/message-lookup#transaction-lookup-using-external-message-from-ton-connect
90291
+ *
90292
+ * @param params - An object containing the built BOC as a base64 string.
90293
+ * @returns An object containing the hash (Hex string) and the boc (Base64 string) of the normalized message.
90294
+ * @throws if the message type is not `external-in`.
90295
+ */
90296
+ function getNormalizedExtMessageHash(boc) {
90297
+ const message = (0, import_dist$2.loadMessage)(import_dist$2.Cell.fromBase64(boc).beginParse());
90298
+ if (message.info.type !== "external-in") throw new Error(`Message must be "external-in", got ${message.info.type}`);
90299
+ const info = {
90300
+ ...message.info,
90301
+ src: void 0,
90302
+ importFee: 0n
90303
+ };
90304
+ const normalizedMessage = {
90305
+ ...message,
90306
+ init: null,
90307
+ info
90308
+ };
90309
+ const normalizedCell = (0, import_dist$2.beginCell)().store((0, import_dist$2.storeMessage)(normalizedMessage, { forceRef: true })).endCell();
90310
+ return {
90311
+ hash: `0x${normalizedCell.hash().toString("hex")}`,
90312
+ boc: normalizedCell.toBoc().toString("base64")
90313
+ };
90314
+ }
90315
+
90316
+ //#endregion
90317
+ //#region ../walletkit/dist/esm/utils/toncenter/getTransactionStatus.js
90318
+ /**
90319
+ * Copyright (c) TonTech.
90320
+ *
90321
+ * This source code is licensed under the MIT license found in the
90322
+ * LICENSE file in the root directory of this source tree.
90323
+ *
90324
+ */
90325
+ /**
90326
+ * Get the status of a transaction by its BOC.
90327
+ *
90328
+ * In TON, a single external message triggers a tree of internal messages.
90329
+ * The transaction is "complete" only when the entire trace finishes.
90330
+ */
90331
+ async function getTransactionStatus(client, params) {
90332
+ const hashToSearch = params.boc ? getNormalizedExtMessageHash(params.boc).hash : params.normalizedHash;
90333
+ if (!hashToSearch) throw new Error("Either boc or normalizedHash must be provided");
90334
+ try {
90335
+ const pendingStatus = parseTraceResponse(await client.getPendingTrace({ externalMessageHash: [hashToSearch] }));
90336
+ if (pendingStatus) return pendingStatus;
90337
+ } catch (_e) {}
90338
+ try {
90339
+ const completedStatus = parseTraceResponse(await client.getTrace({ traceId: [hashToSearch] }));
90340
+ if (completedStatus) return completedStatus;
90341
+ } catch (_e) {}
90342
+ return {
90343
+ status: "unknown",
90344
+ totalMessages: 0,
90345
+ pendingMessages: 0,
90346
+ onchainMessages: 0
90347
+ };
90348
+ }
90349
+
90100
90350
  //#endregion
90101
90351
  //#region ../walletkit/dist/esm/utils/messageBuilders.js
90102
90352
  /**
@@ -90279,7 +90529,12 @@ var WalletTonClass = class {
90279
90529
  try {
90280
90530
  const boc = await this.getSignedSendTransaction(request);
90281
90531
  await CallForSuccess(() => this.getClient().sendBoc(boc));
90282
- return { boc };
90532
+ const { hash: normalizedHash, boc: normalizedBoc } = getNormalizedExtMessageHash(boc);
90533
+ return {
90534
+ boc,
90535
+ normalizedBoc,
90536
+ normalizedHash
90537
+ };
90283
90538
  } catch (error) {
90284
90539
  log$11.error("Failed to send transaction", { error });
90285
90540
  if (error instanceof WalletKitError) throw error;
@@ -92993,8 +93248,8 @@ var ApiClientToncenter = class {
92993
93248
  disableNetworkSend;
92994
93249
  constructor(config = {}) {
92995
93250
  this.network = config.network;
92996
- const dnsResolver = this.network?.chainId === CHAIN.MAINNET ? ROOT_DNS_RESOLVER_MAINNET : ROOT_DNS_RESOLVER_TESTNET;
92997
- const defaultEndpoint = this.network?.chainId === CHAIN.MAINNET ? "https://toncenter.com" : "https://testnet.toncenter.com";
93251
+ const dnsResolver = this.network?.chainId === Network.mainnet().chainId ? ROOT_DNS_RESOLVER_MAINNET : ROOT_DNS_RESOLVER_TESTNET;
93252
+ const defaultEndpoint = this.network?.chainId === Network.mainnet().chainId ? "https://toncenter.com" : "https://testnet.toncenter.com";
92998
93253
  this.dnsResolver = config.dnsResolver ?? dnsResolver;
92999
93254
  this.endpoint = config.endpoint ?? defaultEndpoint;
93000
93255
  this.apiKey = config.apiKey;
@@ -93030,7 +93285,7 @@ var ApiClientToncenter = class {
93030
93285
  }
93031
93286
  async sendBoc(boc) {
93032
93287
  if (this.disableNetworkSend) return "";
93033
- return Base64ToBigInt((await this.postJson("/api/v3/message", { boc })).message_hash_norm).toString(16);
93288
+ return `0x${Base64ToBigInt((await this.postJson("/api/v3/message", { boc })).message_hash_norm).toString(16)}`;
93034
93289
  }
93035
93290
  async runGetMethod(address, method, stack = [], seqno) {
93036
93291
  const props = {
@@ -93161,31 +93416,31 @@ var ApiClientToncenter = class {
93161
93416
  }));
93162
93417
  }
93163
93418
  async getTrace(request) {
93164
- const traceId = padBase64(Base64Normalize((request.traceId ? request.traceId[0] : void 0) || "").replace(/=/g, ""));
93165
- try {
93166
- const response = await CallForSuccess(() => this.getJson("/api/v3/traces", { tx_hash: traceId }));
93167
- if (response.traces.length > 0) return response;
93168
- } catch (error) {
93169
- log$5.error("Error fetching trace", { error });
93170
- }
93171
- try {
93172
- const response = await CallForSuccess(() => this.getJson("/api/v3/traces", { trace_id: traceId }));
93173
- if (response.traces.length > 0) return response;
93174
- } catch (error) {
93175
- log$5.error("Error fetching trace", { error });
93176
- }
93177
- try {
93178
- const response = await CallForSuccess(() => this.getJson("/api/v3/traces", { msg_hash: traceId }));
93179
- if (response.traces.length > 0) return response;
93180
- } catch (error) {
93181
- log$5.error("Error fetching pending trace", { error });
93182
- }
93419
+ const traceIdStr = (request.traceId ? request.traceId[0] : void 0) || "";
93420
+ const traceId = isHex(traceIdStr) ? traceIdStr : padBase64(Base64Normalize(traceIdStr).replace(/=/g, ""));
93421
+ const tryGetTrace = async (field) => {
93422
+ const response = await CallForSuccess(() => this.getJson("/api/v3/traces", { [field]: traceId }), void 0, void 0, (err) => err instanceof TonClientError ? err.status !== 422 : true);
93423
+ if (response?.traces?.length > 0) return response;
93424
+ throw new Error(`No traces found for ${field}`);
93425
+ };
93426
+ const results = await Promise.allSettled([
93427
+ tryGetTrace("tx_hash"),
93428
+ tryGetTrace("trace_id"),
93429
+ tryGetTrace("msg_hash")
93430
+ ]);
93431
+ const fulfilledResult = results.find((result) => result.status === "fulfilled");
93432
+ if (fulfilledResult) return fulfilledResult.value;
93433
+ results.forEach((result) => {
93434
+ if (result.status === "rejected") log$5.error("Error fetching trace", { error: result.reason });
93435
+ });
93183
93436
  throw new Error("Failed to fetch trace");
93184
93437
  }
93185
93438
  async getPendingTrace(request) {
93186
93439
  try {
93187
- const response = await CallForSuccess(() => this.getJson("/api/v3/pendingTraces", { ext_msg_hash: request.externalMessageHash }));
93188
- if (response.traces.length > 0) return response;
93440
+ const response = await CallForSuccess(() => {
93441
+ return this.getJson("/api/v3/pendingTraces", { ext_msg_hash: request.externalMessageHash });
93442
+ }, void 0, void 0, (err) => err instanceof TonClientError ? err.status !== 422 : true);
93443
+ if (response?.traces?.length > 0) return response;
93189
93444
  } catch (error) {
93190
93445
  log$5.error("Error fetching pending trace", { error });
93191
93446
  }
@@ -93324,7 +93579,7 @@ const log$4 = globalLogger.createChild("NetworkManager");
93324
93579
  /**
93325
93580
  * Manages multiple API clients for different networks
93326
93581
  *
93327
- * Each network (identified by CHAIN) has its own ApiClient instance.
93582
+ * Each network has its own ApiClient instance.
93328
93583
  * At least one network must be configured.
93329
93584
  */
93330
93585
  var KitNetworkManager = class {
@@ -93355,7 +93610,10 @@ var KitNetworkManager = class {
93355
93610
  */
93356
93611
  createClient(network, apiClientConfig, options) {
93357
93612
  if (this.isApiClient(apiClientConfig)) return apiClientConfig;
93358
- const defaultEndpoint = network.chainId === CHAIN.MAINNET ? "https://toncenter.com" : "https://testnet.toncenter.com";
93613
+ let defaultEndpoint;
93614
+ if (network.chainId == Network.mainnet().chainId) defaultEndpoint = "https://toncenter.com";
93615
+ else if (network.chainId == Network.tetra().chainId) defaultEndpoint = "https://tetra.tonapi.io";
93616
+ else defaultEndpoint = "https://testnet.toncenter.com";
93359
93617
  return new ApiClientToncenter({
93360
93618
  endpoint: apiClientConfig?.url || defaultEndpoint,
93361
93619
  apiKey: apiClientConfig?.key,
@@ -93371,7 +93629,7 @@ var KitNetworkManager = class {
93371
93629
  }
93372
93630
  /**
93373
93631
  * Get API client for a specific network
93374
- * @param chainId - The chain ID (CHAIN.MAINNET or CHAIN.TESTNET)
93632
+ * @param chainId - The chain ID
93375
93633
  * @returns The API client for the specified network
93376
93634
  * @throws WalletKitError if no client is configured for the network
93377
93635
  */
@@ -93489,7 +93747,7 @@ var TonWalletKit = class {
93489
93747
  items: [{
93490
93748
  name: "ton_addr",
93491
93749
  address: import_dist$2.Address.parse(walletAddress).toRawString(),
93492
- network: wallet.getNetwork().chainId === CHAIN.MAINNET ? CHAIN.MAINNET : CHAIN.TESTNET,
93750
+ network: wallet.getNetwork().chainId,
93493
93751
  walletStateInit,
93494
93752
  publicKey
93495
93753
  }]
@@ -109892,7 +110150,7 @@ var McpWalletService = class McpWalletService {
109892
110150
  * Get wallet network
109893
110151
  */
109894
110152
  getNetwork() {
109895
- return this.wallet.getNetwork().chainId === Network.mainnet().chainId ? "mainnet" : "testnet";
110153
+ return this.wallet.getNetwork().chainId === Network.mainnet().chainId ? "mainnet" : Network.tetra().chainId ? "tetra" : "testnet";
109896
110154
  }
109897
110155
  /**
109898
110156
  * Initialize TonWalletKit (for swap operations)
@@ -110008,10 +110266,11 @@ var McpWalletService = class McpWalletService {
110008
110266
  transferAmount: amountNano,
110009
110267
  comment
110010
110268
  });
110011
- await this.wallet.sendTransaction(tx);
110269
+ const response = await this.wallet.sendTransaction(tx);
110012
110270
  return {
110013
110271
  success: true,
110014
- message: `Successfully sent ${amountNano} nanoTON to ${toAddress}`
110272
+ message: `Successfully sent ${amountNano} nanoTON to ${toAddress}`,
110273
+ normalizedHash: response.normalizedHash
110015
110274
  };
110016
110275
  } catch (error) {
110017
110276
  return {
@@ -110031,10 +110290,11 @@ var McpWalletService = class McpWalletService {
110031
110290
  transferAmount: amountRaw,
110032
110291
  comment
110033
110292
  });
110034
- await this.wallet.sendTransaction(tx);
110293
+ const response = await this.wallet.sendTransaction(tx);
110035
110294
  return {
110036
110295
  success: true,
110037
- message: `Successfully sent jettons to ${toAddress}`
110296
+ message: `Successfully sent jettons to ${toAddress}`,
110297
+ normalizedHash: response.normalizedHash
110038
110298
  };
110039
110299
  } catch (error) {
110040
110300
  return {
@@ -110048,10 +110308,11 @@ var McpWalletService = class McpWalletService {
110048
110308
  */
110049
110309
  async sendRawTransaction(request) {
110050
110310
  try {
110051
- await this.wallet.sendTransaction(request);
110311
+ const tx = await this.wallet.sendTransaction(request);
110052
110312
  return {
110053
110313
  success: true,
110054
- message: `Successfully sent transaction with ${request.messages.length} message(s)`
110314
+ message: `Successfully sent transaction with ${request.messages.length} message(s)`,
110315
+ normalizedHash: tx.normalizedHash
110055
110316
  };
110056
110317
  } catch (error) {
110057
110318
  return {
@@ -110061,6 +110322,15 @@ var McpWalletService = class McpWalletService {
110061
110322
  }
110062
110323
  }
110063
110324
  /**
110325
+ * Get the status of a transaction by its normalized hash.
110326
+ *
110327
+ * In TON, a single external message triggers a tree of internal messages.
110328
+ * The transaction is "complete" only when the entire trace finishes.
110329
+ */
110330
+ async getTransactionStatus(normalizedHash) {
110331
+ return getTransactionStatus(this.wallet.getClient(), { normalizedHash });
110332
+ }
110333
+ /**
110064
110334
  * Get swap quote with transaction params ready to execute
110065
110335
  * @param fromToken Token to swap from ("TON" or jetton address)
110066
110336
  * @param toToken Token to swap to ("TON" or jetton address)
@@ -110174,10 +110444,11 @@ var McpWalletService = class McpWalletService {
110174
110444
  recipientAddress: toAddress,
110175
110445
  comment
110176
110446
  });
110177
- await this.wallet.sendTransaction(tx);
110447
+ const response = await this.wallet.sendTransaction(tx);
110178
110448
  return {
110179
110449
  success: true,
110180
- message: `Successfully sent NFT ${nftAddress} to ${toAddress}`
110450
+ message: `Successfully sent NFT ${nftAddress} to ${toAddress}`,
110451
+ normalizedHash: response.normalizedHash
110181
110452
  };
110182
110453
  } catch (error) {
110183
110454
  return {
@@ -113986,7 +114257,7 @@ const sendRawTransactionSchema = objectType({
113986
114257
  function createMcpTransferTools(service) {
113987
114258
  return {
113988
114259
  send_ton: {
113989
- description: "Send TON from the wallet to an address. Amount is in TON (e.g., \"1.5\" means 1.5 TON).",
114260
+ description: "Send TON from the wallet to an address. Amount is in TON (e.g., \"1.5\" means 1.5 TON). Returns normalizedHash. Default flow: poll get_transaction_status until completed or failed; user can skip.",
113990
114261
  inputSchema: sendTonSchema,
113991
114262
  handler: async (args) => {
113992
114263
  const rawAmount = toRawAmount(args.amount, TON_DECIMALS);
@@ -114009,14 +114280,15 @@ function createMcpTransferTools(service) {
114009
114280
  details: {
114010
114281
  to: args.toAddress,
114011
114282
  amount: `${args.amount} TON`,
114012
- comment: args.comment || null
114283
+ comment: args.comment || null,
114284
+ normalizedHash: result.normalizedHash
114013
114285
  }
114014
114286
  }, null, 2)
114015
114287
  }] };
114016
114288
  }
114017
114289
  },
114018
114290
  send_jetton: {
114019
- description: "Send Jettons (tokens) from the wallet to an address. Amount is in human-readable format.",
114291
+ description: "Send Jettons (tokens) from the wallet to an address. Amount is in human-readable format. Returns normalizedHash. Default flow: poll get_transaction_status until completed or failed; user can skip.",
114020
114292
  inputSchema: sendJettonSchema,
114021
114293
  handler: async (args) => {
114022
114294
  let decimals;
@@ -114070,14 +114342,15 @@ function createMcpTransferTools(service) {
114070
114342
  to: args.toAddress,
114071
114343
  jettonAddress: args.jettonAddress,
114072
114344
  amount: `${args.amount} ${symbol || "tokens"}`,
114073
- comment: args.comment || null
114345
+ comment: args.comment || null,
114346
+ normalizedHash: result.normalizedHash
114074
114347
  }
114075
114348
  }, null, 2)
114076
114349
  }] };
114077
114350
  }
114078
114351
  },
114079
114352
  send_raw_transaction: {
114080
- description: "Send a raw transaction with full control over messages. Amounts are in nanotons. Supports multiple messages in a single transaction.",
114353
+ description: "Send a raw transaction with full control over messages. Amounts are in nanotons. Supports multiple messages. Returns normalizedHash. Default flow: poll get_transaction_status until completed or failed; user can skip.",
114081
114354
  inputSchema: sendRawTransactionSchema,
114082
114355
  handler: async (args) => {
114083
114356
  const result = await service.sendRawTransaction({
@@ -114105,7 +114378,8 @@ function createMcpTransferTools(service) {
114105
114378
  messages: args.messages.map((m) => ({
114106
114379
  to: m.address,
114107
114380
  amount: `${m.amount} nanoTON`
114108
- }))
114381
+ })),
114382
+ normalizedHash: result.normalizedHash
114109
114383
  }
114110
114384
  }, null, 2)
114111
114385
  }] };
@@ -114335,7 +114609,7 @@ function createMcpNftTools(service) {
114335
114609
  }
114336
114610
  },
114337
114611
  send_nft: {
114338
- description: "Transfer an NFT from the wallet to another address.",
114612
+ description: "Transfer an NFT from the wallet to another address. Returns normalizedHash. Default flow: poll get_transaction_status until completed or failed; user can skip.",
114339
114613
  inputSchema: sendNftSchema,
114340
114614
  handler: async (args) => {
114341
114615
  try {
@@ -114347,7 +114621,8 @@ function createMcpNftTools(service) {
114347
114621
  success: result.success,
114348
114622
  message: result.message,
114349
114623
  nftAddress: args.nftAddress,
114350
- recipient: args.toAddress
114624
+ recipient: args.toAddress,
114625
+ normalizedHash: result.normalizedHash
114351
114626
  }, null, 2)
114352
114627
  }],
114353
114628
  isError: !result.success
@@ -114369,6 +114644,43 @@ function createMcpNftTools(service) {
114369
114644
  };
114370
114645
  }
114371
114646
 
114647
+ //#endregion
114648
+ //#region src/tools/transaction-tools.ts
114649
+ /**
114650
+ * Copyright (c) TonTech.
114651
+ *
114652
+ * This source code is licensed under the MIT license found in the
114653
+ * LICENSE file in the root directory of this source tree.
114654
+ *
114655
+ */
114656
+ const getTransactionStatusSchema = objectType({ normalizedHash: stringType().min(1).describe("Normalized hash of the external-in transaction (Hex string)") });
114657
+ function createMcpTransactionTools(service) {
114658
+ return { get_transaction_status: {
114659
+ description: "Get the status of a transaction by its normalized hash (pending, completed, or failed). Default flow after any send: poll until completed or failed; user can specify whether to check.",
114660
+ inputSchema: getTransactionStatusSchema,
114661
+ handler: async (args) => {
114662
+ try {
114663
+ const result = await service.getTransactionStatus(args.normalizedHash);
114664
+ return { content: [{
114665
+ type: "text",
114666
+ text: JSON.stringify(result, null, 2)
114667
+ }] };
114668
+ } catch (error) {
114669
+ return {
114670
+ content: [{
114671
+ type: "text",
114672
+ text: JSON.stringify({
114673
+ success: false,
114674
+ error: `Failed to get transaction status: ${error instanceof Error ? error.message : "Unknown error"}`
114675
+ })
114676
+ }],
114677
+ isError: true
114678
+ };
114679
+ }
114680
+ }
114681
+ } };
114682
+ }
114683
+
114372
114684
  //#endregion
114373
114685
  //#region src/tools/dns-tools.ts
114374
114686
  /**
@@ -114514,6 +114826,7 @@ async function createTonWalletMCP(config) {
114514
114826
  const knownJettonsTools = createMcpKnownJettonsTools();
114515
114827
  const nftTools = createMcpNftTools(walletService);
114516
114828
  const dnsTools = createMcpDnsTools(walletService);
114829
+ const transactionTools = createMcpTransactionTools(walletService);
114517
114830
  const registerTool = (name, tool) => {
114518
114831
  server.registerTool(name, {
114519
114832
  description: tool.description,
@@ -114528,6 +114841,7 @@ async function createTonWalletMCP(config) {
114528
114841
  registerTool("send_ton", transferTools.send_ton);
114529
114842
  registerTool("send_jetton", transferTools.send_jetton);
114530
114843
  registerTool("send_raw_transaction", transferTools.send_raw_transaction);
114844
+ registerTool("get_transaction_status", transactionTools.get_transaction_status);
114531
114845
  registerTool("get_swap_quote", swapTools.get_swap_quote);
114532
114846
  registerTool("get_known_jettons", knownJettonsTools.get_known_jettons);
114533
114847
  registerTool("get_nfts", nftTools.get_nfts);