@ton/mcp 0.1.11 → 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.
@@ -27889,9 +27889,12 @@ function isFriendlyTonAddress(address) {
27889
27889
  *
27890
27890
  */
27891
27891
  function asHex(data) {
27892
- if (!/^0x[0-9a-fA-F]+$/.test(data) || data.length % 2 !== 0) throw new Error("Not a valid hex");
27892
+ if (!isHex(data)) throw new Error("Not a valid hex");
27893
27893
  return data;
27894
27894
  }
27895
+ function isHex(data) {
27896
+ return /^0x[0-9a-fA-F]+$/.test(data) && data.length % 2 === 0;
27897
+ }
27895
27898
 
27896
27899
  //#endregion
27897
27900
  //#region ../walletkit/dist/esm/errors/codes.js
@@ -29399,7 +29402,7 @@ function delay(ms) {
29399
29402
  * LICENSE file in the root directory of this source tree.
29400
29403
  *
29401
29404
  */
29402
- async function CallForSuccess(toCall, attempts = 20, delayMs = 100) {
29405
+ async function CallForSuccess(toCall, attempts = 20, delayMs = 100, shouldRetry) {
29403
29406
  if (typeof toCall !== "function") throw new Error("unknown input");
29404
29407
  let i = 0;
29405
29408
  let lastError;
@@ -29407,6 +29410,7 @@ async function CallForSuccess(toCall, attempts = 20, delayMs = 100) {
29407
29410
  return await toCall();
29408
29411
  } catch (err) {
29409
29412
  lastError = err;
29413
+ if (shouldRetry && !shouldRetry(err)) throw err;
29410
29414
  i++;
29411
29415
  await delay(delayMs);
29412
29416
  }
@@ -29695,6 +29699,16 @@ function isValidEventMethod(method) {
29695
29699
  ].includes(method);
29696
29700
  }
29697
29701
 
29702
+ //#endregion
29703
+ //#region ../walletkit/dist/esm/validation/address.js
29704
+ /**
29705
+ * Copyright (c) TonTech.
29706
+ *
29707
+ * This source code is licensed under the MIT license found in the
29708
+ * LICENSE file in the root directory of this source tree.
29709
+ *
29710
+ */
29711
+
29698
29712
  //#endregion
29699
29713
  //#region ../walletkit/dist/esm/validation/transaction.js
29700
29714
  /**
@@ -70066,13 +70080,11 @@ function getDeviceInfoWithDefaults(options) {
70066
70080
  */
70067
70081
  function getDeviceInfoForWallet(walletAdapter, deviceInfoOptions) {
70068
70082
  const baseDeviceInfo = getDeviceInfoWithDefaults(deviceInfoOptions);
70069
- if (walletAdapter?.getSupportedFeatures) {
70070
- const adapterFeatures = walletAdapter.getSupportedFeatures();
70071
- return addLegacySendTransactionFeature({
70072
- ...baseDeviceInfo,
70073
- features: adapterFeatures
70074
- });
70075
- }
70083
+ const walletSupportedFeatures = walletAdapter?.getSupportedFeatures();
70084
+ if (walletSupportedFeatures) return addLegacySendTransactionFeature({
70085
+ ...baseDeviceInfo,
70086
+ features: walletSupportedFeatures
70087
+ });
70076
70088
  return baseDeviceInfo;
70077
70089
  }
70078
70090
  function addLegacySendTransactionFeature(options) {
@@ -71235,6 +71247,7 @@ var AssetType;
71235
71247
  const Network = {
71236
71248
  mainnet: () => ({ chainId: "-239" }),
71237
71249
  testnet: () => ({ chainId: "-3" }),
71250
+ tetra: () => ({ chainId: "662387" }),
71238
71251
  custom: (chainId) => ({ chainId })
71239
71252
  };
71240
71253
 
@@ -71564,15 +71577,12 @@ var TransactionHandler = class extends BasicHandler {
71564
71577
  */
71565
71578
  validateNetwork(network, wallet) {
71566
71579
  let errors = [];
71567
- if (typeof network === "string") if (network === "-3" || network === "-239") {
71568
- const chain = network === "-3" ? CHAIN.TESTNET : CHAIN.MAINNET;
71569
- if (chain !== wallet.getNetwork().chainId) errors.push("Invalid network not equal to wallet network");
71570
- else return {
71571
- result: chain,
71572
- isValid: errors.length === 0,
71573
- errors
71574
- };
71575
- } else errors.push("Invalid network not a valid network");
71580
+ if (typeof network === "string") if (network !== wallet.getNetwork().chainId) errors.push("Invalid network not equal to wallet network");
71581
+ else return {
71582
+ result: network,
71583
+ isValid: errors.length === 0,
71584
+ errors
71585
+ };
71576
71586
  else errors.push("Invalid network not a string");
71577
71587
  return {
71578
71588
  result: void 0,
@@ -72773,25 +72783,21 @@ function parseDomain(url) {
72773
72783
  }
72774
72784
  }
72775
72785
  function toTonConnectSignDataPayload(payload) {
72776
- let network;
72777
- if (payload.network?.chainId === CHAIN.MAINNET) network = CHAIN.MAINNET;
72778
- else if (payload.network?.chainId === CHAIN.TESTNET) network = CHAIN.TESTNET;
72779
- else network = void 0;
72780
72786
  if (payload.data.type === "text") return {
72781
- network,
72787
+ network: payload.network?.chainId,
72782
72788
  from: payload.fromAddress,
72783
72789
  type: "text",
72784
72790
  text: payload.data.value.content
72785
72791
  };
72786
72792
  else if (payload.data.type === "cell") return {
72787
- network,
72793
+ network: payload.network?.chainId,
72788
72794
  from: payload.fromAddress,
72789
72795
  type: "cell",
72790
72796
  schema: payload.data.value.schema,
72791
72797
  cell: payload.data.value.content
72792
72798
  };
72793
72799
  else return {
72794
- network,
72800
+ network: payload.network?.chainId,
72795
72801
  from: payload.fromAddress,
72796
72802
  type: "binary",
72797
72803
  bytes: payload.data.value.content
@@ -74203,7 +74209,19 @@ function DefaultSignature(data, privateKey) {
74203
74209
  if (fullKey.length === 32) fullKey = (0, import_dist$2.keyPairFromSeed)(Buffer.from(fullKey)).secretKey;
74204
74210
  return Uint8ArrayToHex((0, import_dist$2.sign)(Buffer.from(Uint8Array.from(data)), Buffer.from(fullKey)));
74205
74211
  }
74206
- function createWalletSigner(privateKey) {
74212
+ function DefaultDomainSignature(data, privateKey, domain) {
74213
+ let fullKey = privateKey;
74214
+ if (fullKey.length === 32) fullKey = (0, import_dist$2.keyPairFromSeed)(Buffer.from(fullKey)).secretKey;
74215
+ return Uint8ArrayToHex((0, import_dist$3.domainSign)({
74216
+ data: Buffer.from(Uint8Array.from(data)),
74217
+ secretKey: Buffer.from(fullKey),
74218
+ domain
74219
+ }));
74220
+ }
74221
+ function createWalletSigner(privateKey, domain) {
74222
+ if (domain) return async (data) => {
74223
+ return DefaultDomainSignature(Uint8Array.from(data), privateKey, domain);
74224
+ };
74207
74225
  return async (data) => {
74208
74226
  return DefaultSignature(Uint8Array.from(data), privateKey);
74209
74227
  };
@@ -74232,10 +74250,10 @@ var Signer = class {
74232
74250
  * @param options - Optional configuration for mnemonic type
74233
74251
  * @returns Signer function with publicKey property
74234
74252
  */
74235
- static async fromMnemonic(mnemonic, options) {
74253
+ static async fromMnemonic(mnemonic, options, domain) {
74236
74254
  const keyPair = await MnemonicToKeyPair(mnemonic, options?.type ?? "ton");
74237
74255
  return {
74238
- sign: createWalletSigner(keyPair.secretKey),
74256
+ sign: createWalletSigner(keyPair.secretKey, domain),
74239
74257
  publicKey: Uint8ArrayToHex(keyPair.publicKey)
74240
74258
  };
74241
74259
  }
@@ -74244,11 +74262,11 @@ var Signer = class {
74244
74262
  * @param privateKey - Private key as hex string or Uint8Array
74245
74263
  * @returns Signer function with publicKey property
74246
74264
  */
74247
- static async fromPrivateKey(privateKey) {
74265
+ static async fromPrivateKey(privateKey, domain) {
74248
74266
  const privateKeyBytes = typeof privateKey === "string" ? Uint8Array.from(Buffer.from(privateKey.replace("0x", ""), "hex")) : privateKey;
74249
74267
  const keyPair = (0, import_dist$2.keyPairFromSeed)(Buffer.from(privateKeyBytes));
74250
74268
  return {
74251
- sign: createWalletSigner(keyPair.secretKey),
74269
+ sign: createWalletSigner(keyPair.secretKey, domain),
74252
74270
  publicKey: Uint8ArrayToHex(keyPair.publicKey)
74253
74271
  };
74254
74272
  }
@@ -74442,6 +74460,238 @@ async function getNftFromClient(client, address) {
74442
74460
  return result.nfts.length > 0 ? result.nfts[0] : null;
74443
74461
  }
74444
74462
 
74463
+ //#endregion
74464
+ //#region ../walletkit/dist/esm/utils/toncenter/getTxOpcode.js
74465
+ /**
74466
+ * Copyright (c) TonTech.
74467
+ *
74468
+ * This source code is licensed under the MIT license found in the
74469
+ * LICENSE file in the root directory of this source tree.
74470
+ *
74471
+ */
74472
+ /**
74473
+ * Returns the resolved opcode for a transaction.
74474
+ */
74475
+ const getTxOpcode = (tx) => {
74476
+ const msg = tx.in_msg;
74477
+ if (!msg) return null;
74478
+ return msg.opcode ?? null;
74479
+ };
74480
+
74481
+ //#endregion
74482
+ //#region ../walletkit/dist/esm/utils/toncenter/createTraceTypeDetector.js
74483
+ /**
74484
+ * Copyright (c) TonTech.
74485
+ *
74486
+ * This source code is licensed under the MIT license found in the
74487
+ * LICENSE file in the root directory of this source tree.
74488
+ *
74489
+ */
74490
+ /**
74491
+ * Generic factory function to create a trace type detector.
74492
+ * Returns true if the trace contains at least one transaction with ANY of the trigger opcodes.
74493
+ */
74494
+ const createTraceTypeDetector = (triggerOpcodes) => {
74495
+ return (transactions) => {
74496
+ for (const tx of Object.values(transactions)) {
74497
+ const opcode = getTxOpcode(tx);
74498
+ if (opcode && triggerOpcodes.has(opcode)) return true;
74499
+ }
74500
+ return false;
74501
+ };
74502
+ };
74503
+
74504
+ //#endregion
74505
+ //#region ../walletkit/dist/esm/utils/toncenter/isTransactionFailed.js
74506
+ /**
74507
+ * Copyright (c) TonTech.
74508
+ *
74509
+ * This source code is licensed under the MIT license found in the
74510
+ * LICENSE file in the root directory of this source tree.
74511
+ *
74512
+ */
74513
+ /**
74514
+ * Checks if a single transaction failed.
74515
+ * A transaction is considered failed if it was aborted, or if its compute
74516
+ * or action phases failed to execute successfully (including skipped actions).
74517
+ */
74518
+ const isTransactionFailed = (tx) => {
74519
+ const desc = tx.description;
74520
+ if (!desc) return false;
74521
+ if (desc.aborted) return true;
74522
+ if (desc.compute_ph?.success === false) return true;
74523
+ if (desc.action?.success === false) return true;
74524
+ if (desc.action && desc.action.skipped_actions > 0) return true;
74525
+ return false;
74526
+ };
74527
+
74528
+ //#endregion
74529
+ //#region ../walletkit/dist/esm/utils/toncenter/createFailureDetector.js
74530
+ /**
74531
+ * Copyright (c) TonTech.
74532
+ *
74533
+ * This source code is licensed under the MIT license found in the
74534
+ * LICENSE file in the root directory of this source tree.
74535
+ *
74536
+ */
74537
+ /**
74538
+ * Generic factory function to create a failure detector.
74539
+ * Checks if ANY transaction in the trace has aborted, EXCEPT those
74540
+ * explicitly listed in the `nonCriticalOpcodes` set.
74541
+ *
74542
+ * If a transaction opcode is in `nonCriticalOpcodes`, its failure is ignored.
74543
+ * If a transaction has an unknown opcode or an opcode not in the set, and it fails,
74544
+ * the entire trace is considered failed.
74545
+ */
74546
+ const createFailureDetector = (nonCriticalOpcodes) => {
74547
+ return (transactions) => {
74548
+ for (const tx of Object.values(transactions)) if (isTransactionFailed(tx)) {
74549
+ const opcode = getTxOpcode(tx);
74550
+ if (opcode && nonCriticalOpcodes.has(opcode)) continue;
74551
+ return true;
74552
+ }
74553
+ return false;
74554
+ };
74555
+ };
74556
+
74557
+ //#endregion
74558
+ //#region ../walletkit/dist/esm/utils/toncenter/isFailedTrace.js
74559
+ /**
74560
+ * Copyright (c) TonTech.
74561
+ *
74562
+ * This source code is licensed under the MIT license found in the
74563
+ * LICENSE file in the root directory of this source tree.
74564
+ *
74565
+ */
74566
+ const KNOWN_TRACE_TYPES = [{
74567
+ triggerOpcodes: new Set(["0x0f8a7ea5"]),
74568
+ safeToSkipOpcodes: new Set(["0x7362d09c", "0xd53276db"])
74569
+ }];
74570
+ /**
74571
+ * Determines if a transaction trace has failed.
74572
+ *
74573
+ * In TON, a single transaction triggers a tree of internal messages.
74574
+ * Some messages can fail (abort) or be skipped without affecting the main action.
74575
+ *
74576
+ * This function applies action-specific logic:
74577
+ * - Checks known trace types (like Jetton Transfers) against their specific allowed failures.
74578
+ * - **Unknown types**: checks if ANY transaction in the trace has failed.
74579
+ *
74580
+ * @param tx - The trace response from toncenter
74581
+ * @returns `true` if the trace is considered failed
74582
+ */
74583
+ const isFailedTrace = (tx) => {
74584
+ const trace = tx.traces?.[0];
74585
+ if (!trace) return false;
74586
+ const transactions = trace.transactions ?? {};
74587
+ if (Object.keys(transactions).length === 0) return false;
74588
+ for (const config of KNOWN_TRACE_TYPES) if (createTraceTypeDetector(config.triggerOpcodes)(transactions)) return createFailureDetector(config.safeToSkipOpcodes)(transactions);
74589
+ return createFailureDetector(/* @__PURE__ */ new Set())(transactions);
74590
+ };
74591
+
74592
+ //#endregion
74593
+ //#region ../walletkit/dist/esm/utils/toncenter/parseTraceResponse.js
74594
+ /**
74595
+ * Copyright (c) TonTech.
74596
+ *
74597
+ * This source code is licensed under the MIT license found in the
74598
+ * LICENSE file in the root directory of this source tree.
74599
+ *
74600
+ */
74601
+ /**
74602
+ * Helper to parse ToncenterTracesResponse into TransactionStatusResponse.
74603
+ * Returns null if no traces are found.
74604
+ */
74605
+ const parseTraceResponse = (response) => {
74606
+ if (!response.traces || response.traces.length === 0) return null;
74607
+ const traceInfo = response.traces[0].trace_info;
74608
+ const isEffectivelyCompleted = traceInfo.trace_state === "complete" || traceInfo.trace_state === "pending" && traceInfo.pending_messages === 0;
74609
+ let status = "pending";
74610
+ if (traceInfo.pending_messages === 0) {
74611
+ if (isFailedTrace(response)) status = "failed";
74612
+ else if (isEffectivelyCompleted) status = "completed";
74613
+ }
74614
+ return {
74615
+ status,
74616
+ totalMessages: traceInfo.messages,
74617
+ pendingMessages: traceInfo.pending_messages,
74618
+ onchainMessages: traceInfo.messages - traceInfo.pending_messages
74619
+ };
74620
+ };
74621
+
74622
+ //#endregion
74623
+ //#region ../walletkit/dist/esm/utils/getNormalizedExtMessageHash.js
74624
+ /**
74625
+ * Copyright (c) TonTech.
74626
+ *
74627
+ * This source code is licensed under the MIT license found in the
74628
+ * LICENSE file in the root directory of this source tree.
74629
+ *
74630
+ */
74631
+ /**
74632
+ * Generates a normalized hash of an "external-in" message for comparison.
74633
+ *
74634
+ * This function ensures consistent hashing of external-in messages by following [TEP-467].
74635
+ * See documentation: https://docs.ton.org/ecosystem/ton-connect/message-lookup#transaction-lookup-using-external-message-from-ton-connect
74636
+ *
74637
+ * @param params - An object containing the built BOC as a base64 string.
74638
+ * @returns An object containing the hash (Hex string) and the boc (Base64 string) of the normalized message.
74639
+ * @throws if the message type is not `external-in`.
74640
+ */
74641
+ function getNormalizedExtMessageHash(boc) {
74642
+ const message = (0, import_dist$3.loadMessage)(import_dist$3.Cell.fromBase64(boc).beginParse());
74643
+ if (message.info.type !== "external-in") throw new Error(`Message must be "external-in", got ${message.info.type}`);
74644
+ const info = {
74645
+ ...message.info,
74646
+ src: void 0,
74647
+ importFee: 0n
74648
+ };
74649
+ const normalizedMessage = {
74650
+ ...message,
74651
+ init: null,
74652
+ info
74653
+ };
74654
+ const normalizedCell = (0, import_dist$3.beginCell)().store((0, import_dist$3.storeMessage)(normalizedMessage, { forceRef: true })).endCell();
74655
+ return {
74656
+ hash: `0x${normalizedCell.hash().toString("hex")}`,
74657
+ boc: normalizedCell.toBoc().toString("base64")
74658
+ };
74659
+ }
74660
+
74661
+ //#endregion
74662
+ //#region ../walletkit/dist/esm/utils/toncenter/getTransactionStatus.js
74663
+ /**
74664
+ * Copyright (c) TonTech.
74665
+ *
74666
+ * This source code is licensed under the MIT license found in the
74667
+ * LICENSE file in the root directory of this source tree.
74668
+ *
74669
+ */
74670
+ /**
74671
+ * Get the status of a transaction by its BOC.
74672
+ *
74673
+ * In TON, a single external message triggers a tree of internal messages.
74674
+ * The transaction is "complete" only when the entire trace finishes.
74675
+ */
74676
+ async function getTransactionStatus(client, params) {
74677
+ const hashToSearch = params.boc ? getNormalizedExtMessageHash(params.boc).hash : params.normalizedHash;
74678
+ if (!hashToSearch) throw new Error("Either boc or normalizedHash must be provided");
74679
+ try {
74680
+ const pendingStatus = parseTraceResponse(await client.getPendingTrace({ externalMessageHash: [hashToSearch] }));
74681
+ if (pendingStatus) return pendingStatus;
74682
+ } catch (_e) {}
74683
+ try {
74684
+ const completedStatus = parseTraceResponse(await client.getTrace({ traceId: [hashToSearch] }));
74685
+ if (completedStatus) return completedStatus;
74686
+ } catch (_e) {}
74687
+ return {
74688
+ status: "unknown",
74689
+ totalMessages: 0,
74690
+ pendingMessages: 0,
74691
+ onchainMessages: 0
74692
+ };
74693
+ }
74694
+
74445
74695
  //#endregion
74446
74696
  //#region ../walletkit/dist/esm/utils/messageBuilders.js
74447
74697
  /**
@@ -74624,7 +74874,12 @@ var WalletTonClass = class {
74624
74874
  try {
74625
74875
  const boc = await this.getSignedSendTransaction(request);
74626
74876
  await CallForSuccess(() => this.getClient().sendBoc(boc));
74627
- return { boc };
74877
+ const { hash: normalizedHash, boc: normalizedBoc } = getNormalizedExtMessageHash(boc);
74878
+ return {
74879
+ boc,
74880
+ normalizedBoc,
74881
+ normalizedHash
74882
+ };
74628
74883
  } catch (error) {
74629
74884
  log$11.error("Failed to send transaction", { error });
74630
74885
  if (error instanceof WalletKitError) throw error;
@@ -77338,8 +77593,8 @@ var ApiClientToncenter = class {
77338
77593
  disableNetworkSend;
77339
77594
  constructor(config = {}) {
77340
77595
  this.network = config.network;
77341
- const dnsResolver = this.network?.chainId === CHAIN.MAINNET ? ROOT_DNS_RESOLVER_MAINNET : ROOT_DNS_RESOLVER_TESTNET;
77342
- const defaultEndpoint = this.network?.chainId === CHAIN.MAINNET ? "https://toncenter.com" : "https://testnet.toncenter.com";
77596
+ const dnsResolver = this.network?.chainId === Network.mainnet().chainId ? ROOT_DNS_RESOLVER_MAINNET : ROOT_DNS_RESOLVER_TESTNET;
77597
+ const defaultEndpoint = this.network?.chainId === Network.mainnet().chainId ? "https://toncenter.com" : "https://testnet.toncenter.com";
77343
77598
  this.dnsResolver = config.dnsResolver ?? dnsResolver;
77344
77599
  this.endpoint = config.endpoint ?? defaultEndpoint;
77345
77600
  this.apiKey = config.apiKey;
@@ -77375,7 +77630,7 @@ var ApiClientToncenter = class {
77375
77630
  }
77376
77631
  async sendBoc(boc) {
77377
77632
  if (this.disableNetworkSend) return "";
77378
- return Base64ToBigInt((await this.postJson("/api/v3/message", { boc })).message_hash_norm).toString(16);
77633
+ return `0x${Base64ToBigInt((await this.postJson("/api/v3/message", { boc })).message_hash_norm).toString(16)}`;
77379
77634
  }
77380
77635
  async runGetMethod(address, method, stack = [], seqno) {
77381
77636
  const props = {
@@ -77506,31 +77761,31 @@ var ApiClientToncenter = class {
77506
77761
  }));
77507
77762
  }
77508
77763
  async getTrace(request) {
77509
- const traceId = padBase64(Base64Normalize((request.traceId ? request.traceId[0] : void 0) || "").replace(/=/g, ""));
77510
- try {
77511
- const response = await CallForSuccess(() => this.getJson("/api/v3/traces", { tx_hash: traceId }));
77512
- if (response.traces.length > 0) return response;
77513
- } catch (error) {
77514
- log$5.error("Error fetching trace", { error });
77515
- }
77516
- try {
77517
- const response = await CallForSuccess(() => this.getJson("/api/v3/traces", { trace_id: traceId }));
77518
- if (response.traces.length > 0) return response;
77519
- } catch (error) {
77520
- log$5.error("Error fetching trace", { error });
77521
- }
77522
- try {
77523
- const response = await CallForSuccess(() => this.getJson("/api/v3/traces", { msg_hash: traceId }));
77524
- if (response.traces.length > 0) return response;
77525
- } catch (error) {
77526
- log$5.error("Error fetching pending trace", { error });
77527
- }
77764
+ const traceIdStr = (request.traceId ? request.traceId[0] : void 0) || "";
77765
+ const traceId = isHex(traceIdStr) ? traceIdStr : padBase64(Base64Normalize(traceIdStr).replace(/=/g, ""));
77766
+ const tryGetTrace = async (field) => {
77767
+ const response = await CallForSuccess(() => this.getJson("/api/v3/traces", { [field]: traceId }), void 0, void 0, (err) => err instanceof TonClientError ? err.status !== 422 : true);
77768
+ if (response?.traces?.length > 0) return response;
77769
+ throw new Error(`No traces found for ${field}`);
77770
+ };
77771
+ const results = await Promise.allSettled([
77772
+ tryGetTrace("tx_hash"),
77773
+ tryGetTrace("trace_id"),
77774
+ tryGetTrace("msg_hash")
77775
+ ]);
77776
+ const fulfilledResult = results.find((result) => result.status === "fulfilled");
77777
+ if (fulfilledResult) return fulfilledResult.value;
77778
+ results.forEach((result) => {
77779
+ if (result.status === "rejected") log$5.error("Error fetching trace", { error: result.reason });
77780
+ });
77528
77781
  throw new Error("Failed to fetch trace");
77529
77782
  }
77530
77783
  async getPendingTrace(request) {
77531
77784
  try {
77532
- const response = await CallForSuccess(() => this.getJson("/api/v3/pendingTraces", { ext_msg_hash: request.externalMessageHash }));
77533
- if (response.traces.length > 0) return response;
77785
+ const response = await CallForSuccess(() => {
77786
+ return this.getJson("/api/v3/pendingTraces", { ext_msg_hash: request.externalMessageHash });
77787
+ }, void 0, void 0, (err) => err instanceof TonClientError ? err.status !== 422 : true);
77788
+ if (response?.traces?.length > 0) return response;
77534
77789
  } catch (error) {
77535
77790
  log$5.error("Error fetching pending trace", { error });
77536
77791
  }
@@ -77669,7 +77924,7 @@ const log$4 = globalLogger.createChild("NetworkManager");
77669
77924
  /**
77670
77925
  * Manages multiple API clients for different networks
77671
77926
  *
77672
- * Each network (identified by CHAIN) has its own ApiClient instance.
77927
+ * Each network has its own ApiClient instance.
77673
77928
  * At least one network must be configured.
77674
77929
  */
77675
77930
  var KitNetworkManager = class {
@@ -77700,7 +77955,10 @@ var KitNetworkManager = class {
77700
77955
  */
77701
77956
  createClient(network, apiClientConfig, options) {
77702
77957
  if (this.isApiClient(apiClientConfig)) return apiClientConfig;
77703
- const defaultEndpoint = network.chainId === CHAIN.MAINNET ? "https://toncenter.com" : "https://testnet.toncenter.com";
77958
+ let defaultEndpoint;
77959
+ if (network.chainId == Network.mainnet().chainId) defaultEndpoint = "https://toncenter.com";
77960
+ else if (network.chainId == Network.tetra().chainId) defaultEndpoint = "https://tetra.tonapi.io";
77961
+ else defaultEndpoint = "https://testnet.toncenter.com";
77704
77962
  return new ApiClientToncenter({
77705
77963
  endpoint: apiClientConfig?.url || defaultEndpoint,
77706
77964
  apiKey: apiClientConfig?.key,
@@ -77716,7 +77974,7 @@ var KitNetworkManager = class {
77716
77974
  }
77717
77975
  /**
77718
77976
  * Get API client for a specific network
77719
- * @param chainId - The chain ID (CHAIN.MAINNET or CHAIN.TESTNET)
77977
+ * @param chainId - The chain ID
77720
77978
  * @returns The API client for the specified network
77721
77979
  * @throws WalletKitError if no client is configured for the network
77722
77980
  */
@@ -77834,7 +78092,7 @@ var TonWalletKit = class {
77834
78092
  items: [{
77835
78093
  name: "ton_addr",
77836
78094
  address: import_dist$3.Address.parse(walletAddress).toRawString(),
77837
- network: wallet.getNetwork().chainId === CHAIN.MAINNET ? CHAIN.MAINNET : CHAIN.TESTNET,
78095
+ network: wallet.getNetwork().chainId,
77838
78096
  walletStateInit,
77839
78097
  publicKey
77840
78098
  }]
@@ -110964,7 +111222,7 @@ var McpWalletService = class McpWalletService {
110964
111222
  * Get wallet network
110965
111223
  */
110966
111224
  getNetwork() {
110967
- return this.wallet.getNetwork().chainId === Network.mainnet().chainId ? "mainnet" : "testnet";
111225
+ return this.wallet.getNetwork().chainId === Network.mainnet().chainId ? "mainnet" : Network.tetra().chainId ? "tetra" : "testnet";
110968
111226
  }
110969
111227
  /**
110970
111228
  * Initialize TonWalletKit (for swap operations)
@@ -111080,10 +111338,11 @@ var McpWalletService = class McpWalletService {
111080
111338
  transferAmount: amountNano,
111081
111339
  comment
111082
111340
  });
111083
- await this.wallet.sendTransaction(tx);
111341
+ const response = await this.wallet.sendTransaction(tx);
111084
111342
  return {
111085
111343
  success: true,
111086
- message: `Successfully sent ${amountNano} nanoTON to ${toAddress}`
111344
+ message: `Successfully sent ${amountNano} nanoTON to ${toAddress}`,
111345
+ normalizedHash: response.normalizedHash
111087
111346
  };
111088
111347
  } catch (error) {
111089
111348
  return {
@@ -111103,10 +111362,11 @@ var McpWalletService = class McpWalletService {
111103
111362
  transferAmount: amountRaw,
111104
111363
  comment
111105
111364
  });
111106
- await this.wallet.sendTransaction(tx);
111365
+ const response = await this.wallet.sendTransaction(tx);
111107
111366
  return {
111108
111367
  success: true,
111109
- message: `Successfully sent jettons to ${toAddress}`
111368
+ message: `Successfully sent jettons to ${toAddress}`,
111369
+ normalizedHash: response.normalizedHash
111110
111370
  };
111111
111371
  } catch (error) {
111112
111372
  return {
@@ -111120,10 +111380,11 @@ var McpWalletService = class McpWalletService {
111120
111380
  */
111121
111381
  async sendRawTransaction(request) {
111122
111382
  try {
111123
- await this.wallet.sendTransaction(request);
111383
+ const tx = await this.wallet.sendTransaction(request);
111124
111384
  return {
111125
111385
  success: true,
111126
- message: `Successfully sent transaction with ${request.messages.length} message(s)`
111386
+ message: `Successfully sent transaction with ${request.messages.length} message(s)`,
111387
+ normalizedHash: tx.normalizedHash
111127
111388
  };
111128
111389
  } catch (error) {
111129
111390
  return {
@@ -111133,6 +111394,15 @@ var McpWalletService = class McpWalletService {
111133
111394
  }
111134
111395
  }
111135
111396
  /**
111397
+ * Get the status of a transaction by its normalized hash.
111398
+ *
111399
+ * In TON, a single external message triggers a tree of internal messages.
111400
+ * The transaction is "complete" only when the entire trace finishes.
111401
+ */
111402
+ async getTransactionStatus(normalizedHash) {
111403
+ return getTransactionStatus(this.wallet.getClient(), { normalizedHash });
111404
+ }
111405
+ /**
111136
111406
  * Get swap quote with transaction params ready to execute
111137
111407
  * @param fromToken Token to swap from ("TON" or jetton address)
111138
111408
  * @param toToken Token to swap to ("TON" or jetton address)
@@ -111246,10 +111516,11 @@ var McpWalletService = class McpWalletService {
111246
111516
  recipientAddress: toAddress,
111247
111517
  comment
111248
111518
  });
111249
- await this.wallet.sendTransaction(tx);
111519
+ const response = await this.wallet.sendTransaction(tx);
111250
111520
  return {
111251
111521
  success: true,
111252
- message: `Successfully sent NFT ${nftAddress} to ${toAddress}`
111522
+ message: `Successfully sent NFT ${nftAddress} to ${toAddress}`,
111523
+ normalizedHash: response.normalizedHash
111253
111524
  };
111254
111525
  } catch (error) {
111255
111526
  return {
@@ -115058,7 +115329,7 @@ const sendRawTransactionSchema = objectType({
115058
115329
  function createMcpTransferTools(service) {
115059
115330
  return {
115060
115331
  send_ton: {
115061
- description: "Send TON from the wallet to an address. Amount is in TON (e.g., \"1.5\" means 1.5 TON).",
115332
+ 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.",
115062
115333
  inputSchema: sendTonSchema,
115063
115334
  handler: async (args) => {
115064
115335
  const rawAmount = toRawAmount(args.amount, TON_DECIMALS);
@@ -115081,14 +115352,15 @@ function createMcpTransferTools(service) {
115081
115352
  details: {
115082
115353
  to: args.toAddress,
115083
115354
  amount: `${args.amount} TON`,
115084
- comment: args.comment || null
115355
+ comment: args.comment || null,
115356
+ normalizedHash: result.normalizedHash
115085
115357
  }
115086
115358
  }, null, 2)
115087
115359
  }] };
115088
115360
  }
115089
115361
  },
115090
115362
  send_jetton: {
115091
- description: "Send Jettons (tokens) from the wallet to an address. Amount is in human-readable format.",
115363
+ 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.",
115092
115364
  inputSchema: sendJettonSchema,
115093
115365
  handler: async (args) => {
115094
115366
  let decimals;
@@ -115142,14 +115414,15 @@ function createMcpTransferTools(service) {
115142
115414
  to: args.toAddress,
115143
115415
  jettonAddress: args.jettonAddress,
115144
115416
  amount: `${args.amount} ${symbol || "tokens"}`,
115145
- comment: args.comment || null
115417
+ comment: args.comment || null,
115418
+ normalizedHash: result.normalizedHash
115146
115419
  }
115147
115420
  }, null, 2)
115148
115421
  }] };
115149
115422
  }
115150
115423
  },
115151
115424
  send_raw_transaction: {
115152
- description: "Send a raw transaction with full control over messages. Amounts are in nanotons. Supports multiple messages in a single transaction.",
115425
+ 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.",
115153
115426
  inputSchema: sendRawTransactionSchema,
115154
115427
  handler: async (args) => {
115155
115428
  const result = await service.sendRawTransaction({
@@ -115177,7 +115450,8 @@ function createMcpTransferTools(service) {
115177
115450
  messages: args.messages.map((m) => ({
115178
115451
  to: m.address,
115179
115452
  amount: `${m.amount} nanoTON`
115180
- }))
115453
+ })),
115454
+ normalizedHash: result.normalizedHash
115181
115455
  }
115182
115456
  }, null, 2)
115183
115457
  }] };
@@ -115407,7 +115681,7 @@ function createMcpNftTools(service) {
115407
115681
  }
115408
115682
  },
115409
115683
  send_nft: {
115410
- description: "Transfer an NFT from the wallet to another address.",
115684
+ 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.",
115411
115685
  inputSchema: sendNftSchema,
115412
115686
  handler: async (args) => {
115413
115687
  try {
@@ -115419,7 +115693,8 @@ function createMcpNftTools(service) {
115419
115693
  success: result.success,
115420
115694
  message: result.message,
115421
115695
  nftAddress: args.nftAddress,
115422
- recipient: args.toAddress
115696
+ recipient: args.toAddress,
115697
+ normalizedHash: result.normalizedHash
115423
115698
  }, null, 2)
115424
115699
  }],
115425
115700
  isError: !result.success
@@ -115441,6 +115716,43 @@ function createMcpNftTools(service) {
115441
115716
  };
115442
115717
  }
115443
115718
 
115719
+ //#endregion
115720
+ //#region src/tools/transaction-tools.ts
115721
+ /**
115722
+ * Copyright (c) TonTech.
115723
+ *
115724
+ * This source code is licensed under the MIT license found in the
115725
+ * LICENSE file in the root directory of this source tree.
115726
+ *
115727
+ */
115728
+ const getTransactionStatusSchema = objectType({ normalizedHash: stringType().min(1).describe("Normalized hash of the external-in transaction (Hex string)") });
115729
+ function createMcpTransactionTools(service) {
115730
+ return { get_transaction_status: {
115731
+ 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.",
115732
+ inputSchema: getTransactionStatusSchema,
115733
+ handler: async (args) => {
115734
+ try {
115735
+ const result = await service.getTransactionStatus(args.normalizedHash);
115736
+ return { content: [{
115737
+ type: "text",
115738
+ text: JSON.stringify(result, null, 2)
115739
+ }] };
115740
+ } catch (error) {
115741
+ return {
115742
+ content: [{
115743
+ type: "text",
115744
+ text: JSON.stringify({
115745
+ success: false,
115746
+ error: `Failed to get transaction status: ${error instanceof Error ? error.message : "Unknown error"}`
115747
+ })
115748
+ }],
115749
+ isError: true
115750
+ };
115751
+ }
115752
+ }
115753
+ } };
115754
+ }
115755
+
115444
115756
  //#endregion
115445
115757
  //#region src/tools/dns-tools.ts
115446
115758
  /**
@@ -115586,6 +115898,7 @@ async function createTonWalletMCP(config) {
115586
115898
  const knownJettonsTools = createMcpKnownJettonsTools();
115587
115899
  const nftTools = createMcpNftTools(walletService);
115588
115900
  const dnsTools = createMcpDnsTools(walletService);
115901
+ const transactionTools = createMcpTransactionTools(walletService);
115589
115902
  const registerTool = (name, tool) => {
115590
115903
  server.registerTool(name, {
115591
115904
  description: tool.description,
@@ -115600,6 +115913,7 @@ async function createTonWalletMCP(config) {
115600
115913
  registerTool("send_ton", transferTools.send_ton);
115601
115914
  registerTool("send_jetton", transferTools.send_jetton);
115602
115915
  registerTool("send_raw_transaction", transferTools.send_raw_transaction);
115916
+ registerTool("get_transaction_status", transactionTools.get_transaction_status);
115603
115917
  registerTool("get_swap_quote", swapTools.get_swap_quote);
115604
115918
  registerTool("get_known_jettons", knownJettonsTools.get_known_jettons);
115605
115919
  registerTool("get_nfts", nftTools.get_nfts);