@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/cli.js CHANGED
@@ -27975,9 +27975,12 @@ function isFriendlyTonAddress(address) {
27975
27975
  *
27976
27976
  */
27977
27977
  function asHex(data) {
27978
- if (!/^0x[0-9a-fA-F]+$/.test(data) || data.length % 2 !== 0) throw new Error("Not a valid hex");
27978
+ if (!isHex(data)) throw new Error("Not a valid hex");
27979
27979
  return data;
27980
27980
  }
27981
+ function isHex(data) {
27982
+ return /^0x[0-9a-fA-F]+$/.test(data) && data.length % 2 === 0;
27983
+ }
27981
27984
 
27982
27985
  //#endregion
27983
27986
  //#region ../walletkit/dist/esm/errors/codes.js
@@ -29485,7 +29488,7 @@ function delay(ms) {
29485
29488
  * LICENSE file in the root directory of this source tree.
29486
29489
  *
29487
29490
  */
29488
- async function CallForSuccess(toCall, attempts = 20, delayMs = 100) {
29491
+ async function CallForSuccess(toCall, attempts = 20, delayMs = 100, shouldRetry) {
29489
29492
  if (typeof toCall !== "function") throw new Error("unknown input");
29490
29493
  let i = 0;
29491
29494
  let lastError;
@@ -29493,6 +29496,7 @@ async function CallForSuccess(toCall, attempts = 20, delayMs = 100) {
29493
29496
  return await toCall();
29494
29497
  } catch (err) {
29495
29498
  lastError = err;
29499
+ if (shouldRetry && !shouldRetry(err)) throw err;
29496
29500
  i++;
29497
29501
  await delay(delayMs);
29498
29502
  }
@@ -29781,6 +29785,16 @@ function isValidEventMethod(method) {
29781
29785
  ].includes(method);
29782
29786
  }
29783
29787
 
29788
+ //#endregion
29789
+ //#region ../walletkit/dist/esm/validation/address.js
29790
+ /**
29791
+ * Copyright (c) TonTech.
29792
+ *
29793
+ * This source code is licensed under the MIT license found in the
29794
+ * LICENSE file in the root directory of this source tree.
29795
+ *
29796
+ */
29797
+
29784
29798
  //#endregion
29785
29799
  //#region ../walletkit/dist/esm/validation/transaction.js
29786
29800
  /**
@@ -70152,13 +70166,11 @@ function getDeviceInfoWithDefaults(options) {
70152
70166
  */
70153
70167
  function getDeviceInfoForWallet(walletAdapter, deviceInfoOptions) {
70154
70168
  const baseDeviceInfo = getDeviceInfoWithDefaults(deviceInfoOptions);
70155
- if (walletAdapter?.getSupportedFeatures) {
70156
- const adapterFeatures = walletAdapter.getSupportedFeatures();
70157
- return addLegacySendTransactionFeature({
70158
- ...baseDeviceInfo,
70159
- features: adapterFeatures
70160
- });
70161
- }
70169
+ const walletSupportedFeatures = walletAdapter?.getSupportedFeatures();
70170
+ if (walletSupportedFeatures) return addLegacySendTransactionFeature({
70171
+ ...baseDeviceInfo,
70172
+ features: walletSupportedFeatures
70173
+ });
70162
70174
  return baseDeviceInfo;
70163
70175
  }
70164
70176
  function addLegacySendTransactionFeature(options) {
@@ -71321,6 +71333,7 @@ var AssetType;
71321
71333
  const Network = {
71322
71334
  mainnet: () => ({ chainId: "-239" }),
71323
71335
  testnet: () => ({ chainId: "-3" }),
71336
+ tetra: () => ({ chainId: "662387" }),
71324
71337
  custom: (chainId) => ({ chainId })
71325
71338
  };
71326
71339
 
@@ -71650,15 +71663,12 @@ var TransactionHandler = class extends BasicHandler {
71650
71663
  */
71651
71664
  validateNetwork(network, wallet) {
71652
71665
  let errors = [];
71653
- if (typeof network === "string") if (network === "-3" || network === "-239") {
71654
- const chain = network === "-3" ? CHAIN.TESTNET : CHAIN.MAINNET;
71655
- if (chain !== wallet.getNetwork().chainId) errors.push("Invalid network not equal to wallet network");
71656
- else return {
71657
- result: chain,
71658
- isValid: errors.length === 0,
71659
- errors
71660
- };
71661
- } else errors.push("Invalid network not a valid network");
71666
+ if (typeof network === "string") if (network !== wallet.getNetwork().chainId) errors.push("Invalid network not equal to wallet network");
71667
+ else return {
71668
+ result: network,
71669
+ isValid: errors.length === 0,
71670
+ errors
71671
+ };
71662
71672
  else errors.push("Invalid network not a string");
71663
71673
  return {
71664
71674
  result: void 0,
@@ -72859,25 +72869,21 @@ function parseDomain(url) {
72859
72869
  }
72860
72870
  }
72861
72871
  function toTonConnectSignDataPayload(payload) {
72862
- let network;
72863
- if (payload.network?.chainId === CHAIN.MAINNET) network = CHAIN.MAINNET;
72864
- else if (payload.network?.chainId === CHAIN.TESTNET) network = CHAIN.TESTNET;
72865
- else network = void 0;
72866
72872
  if (payload.data.type === "text") return {
72867
- network,
72873
+ network: payload.network?.chainId,
72868
72874
  from: payload.fromAddress,
72869
72875
  type: "text",
72870
72876
  text: payload.data.value.content
72871
72877
  };
72872
72878
  else if (payload.data.type === "cell") return {
72873
- network,
72879
+ network: payload.network?.chainId,
72874
72880
  from: payload.fromAddress,
72875
72881
  type: "cell",
72876
72882
  schema: payload.data.value.schema,
72877
72883
  cell: payload.data.value.content
72878
72884
  };
72879
72885
  else return {
72880
- network,
72886
+ network: payload.network?.chainId,
72881
72887
  from: payload.fromAddress,
72882
72888
  type: "binary",
72883
72889
  bytes: payload.data.value.content
@@ -74289,7 +74295,19 @@ function DefaultSignature(data, privateKey) {
74289
74295
  if (fullKey.length === 32) fullKey = (0, import_dist$2.keyPairFromSeed)(Buffer.from(fullKey)).secretKey;
74290
74296
  return Uint8ArrayToHex((0, import_dist$2.sign)(Buffer.from(Uint8Array.from(data)), Buffer.from(fullKey)));
74291
74297
  }
74292
- function createWalletSigner(privateKey) {
74298
+ function DefaultDomainSignature(data, privateKey, domain) {
74299
+ let fullKey = privateKey;
74300
+ if (fullKey.length === 32) fullKey = (0, import_dist$2.keyPairFromSeed)(Buffer.from(fullKey)).secretKey;
74301
+ return Uint8ArrayToHex((0, import_dist$3.domainSign)({
74302
+ data: Buffer.from(Uint8Array.from(data)),
74303
+ secretKey: Buffer.from(fullKey),
74304
+ domain
74305
+ }));
74306
+ }
74307
+ function createWalletSigner(privateKey, domain) {
74308
+ if (domain) return async (data) => {
74309
+ return DefaultDomainSignature(Uint8Array.from(data), privateKey, domain);
74310
+ };
74293
74311
  return async (data) => {
74294
74312
  return DefaultSignature(Uint8Array.from(data), privateKey);
74295
74313
  };
@@ -74318,10 +74336,10 @@ var Signer = class {
74318
74336
  * @param options - Optional configuration for mnemonic type
74319
74337
  * @returns Signer function with publicKey property
74320
74338
  */
74321
- static async fromMnemonic(mnemonic, options) {
74339
+ static async fromMnemonic(mnemonic, options, domain) {
74322
74340
  const keyPair = await MnemonicToKeyPair(mnemonic, options?.type ?? "ton");
74323
74341
  return {
74324
- sign: createWalletSigner(keyPair.secretKey),
74342
+ sign: createWalletSigner(keyPair.secretKey, domain),
74325
74343
  publicKey: Uint8ArrayToHex(keyPair.publicKey)
74326
74344
  };
74327
74345
  }
@@ -74330,11 +74348,11 @@ var Signer = class {
74330
74348
  * @param privateKey - Private key as hex string or Uint8Array
74331
74349
  * @returns Signer function with publicKey property
74332
74350
  */
74333
- static async fromPrivateKey(privateKey) {
74351
+ static async fromPrivateKey(privateKey, domain) {
74334
74352
  const privateKeyBytes = typeof privateKey === "string" ? Uint8Array.from(Buffer.from(privateKey.replace("0x", ""), "hex")) : privateKey;
74335
74353
  const keyPair = (0, import_dist$2.keyPairFromSeed)(Buffer.from(privateKeyBytes));
74336
74354
  return {
74337
- sign: createWalletSigner(keyPair.secretKey),
74355
+ sign: createWalletSigner(keyPair.secretKey, domain),
74338
74356
  publicKey: Uint8ArrayToHex(keyPair.publicKey)
74339
74357
  };
74340
74358
  }
@@ -74528,6 +74546,238 @@ async function getNftFromClient(client, address) {
74528
74546
  return result.nfts.length > 0 ? result.nfts[0] : null;
74529
74547
  }
74530
74548
 
74549
+ //#endregion
74550
+ //#region ../walletkit/dist/esm/utils/toncenter/getTxOpcode.js
74551
+ /**
74552
+ * Copyright (c) TonTech.
74553
+ *
74554
+ * This source code is licensed under the MIT license found in the
74555
+ * LICENSE file in the root directory of this source tree.
74556
+ *
74557
+ */
74558
+ /**
74559
+ * Returns the resolved opcode for a transaction.
74560
+ */
74561
+ const getTxOpcode = (tx) => {
74562
+ const msg = tx.in_msg;
74563
+ if (!msg) return null;
74564
+ return msg.opcode ?? null;
74565
+ };
74566
+
74567
+ //#endregion
74568
+ //#region ../walletkit/dist/esm/utils/toncenter/createTraceTypeDetector.js
74569
+ /**
74570
+ * Copyright (c) TonTech.
74571
+ *
74572
+ * This source code is licensed under the MIT license found in the
74573
+ * LICENSE file in the root directory of this source tree.
74574
+ *
74575
+ */
74576
+ /**
74577
+ * Generic factory function to create a trace type detector.
74578
+ * Returns true if the trace contains at least one transaction with ANY of the trigger opcodes.
74579
+ */
74580
+ const createTraceTypeDetector = (triggerOpcodes) => {
74581
+ return (transactions) => {
74582
+ for (const tx of Object.values(transactions)) {
74583
+ const opcode = getTxOpcode(tx);
74584
+ if (opcode && triggerOpcodes.has(opcode)) return true;
74585
+ }
74586
+ return false;
74587
+ };
74588
+ };
74589
+
74590
+ //#endregion
74591
+ //#region ../walletkit/dist/esm/utils/toncenter/isTransactionFailed.js
74592
+ /**
74593
+ * Copyright (c) TonTech.
74594
+ *
74595
+ * This source code is licensed under the MIT license found in the
74596
+ * LICENSE file in the root directory of this source tree.
74597
+ *
74598
+ */
74599
+ /**
74600
+ * Checks if a single transaction failed.
74601
+ * A transaction is considered failed if it was aborted, or if its compute
74602
+ * or action phases failed to execute successfully (including skipped actions).
74603
+ */
74604
+ const isTransactionFailed = (tx) => {
74605
+ const desc = tx.description;
74606
+ if (!desc) return false;
74607
+ if (desc.aborted) return true;
74608
+ if (desc.compute_ph?.success === false) return true;
74609
+ if (desc.action?.success === false) return true;
74610
+ if (desc.action && desc.action.skipped_actions > 0) return true;
74611
+ return false;
74612
+ };
74613
+
74614
+ //#endregion
74615
+ //#region ../walletkit/dist/esm/utils/toncenter/createFailureDetector.js
74616
+ /**
74617
+ * Copyright (c) TonTech.
74618
+ *
74619
+ * This source code is licensed under the MIT license found in the
74620
+ * LICENSE file in the root directory of this source tree.
74621
+ *
74622
+ */
74623
+ /**
74624
+ * Generic factory function to create a failure detector.
74625
+ * Checks if ANY transaction in the trace has aborted, EXCEPT those
74626
+ * explicitly listed in the `nonCriticalOpcodes` set.
74627
+ *
74628
+ * If a transaction opcode is in `nonCriticalOpcodes`, its failure is ignored.
74629
+ * If a transaction has an unknown opcode or an opcode not in the set, and it fails,
74630
+ * the entire trace is considered failed.
74631
+ */
74632
+ const createFailureDetector = (nonCriticalOpcodes) => {
74633
+ return (transactions) => {
74634
+ for (const tx of Object.values(transactions)) if (isTransactionFailed(tx)) {
74635
+ const opcode = getTxOpcode(tx);
74636
+ if (opcode && nonCriticalOpcodes.has(opcode)) continue;
74637
+ return true;
74638
+ }
74639
+ return false;
74640
+ };
74641
+ };
74642
+
74643
+ //#endregion
74644
+ //#region ../walletkit/dist/esm/utils/toncenter/isFailedTrace.js
74645
+ /**
74646
+ * Copyright (c) TonTech.
74647
+ *
74648
+ * This source code is licensed under the MIT license found in the
74649
+ * LICENSE file in the root directory of this source tree.
74650
+ *
74651
+ */
74652
+ const KNOWN_TRACE_TYPES = [{
74653
+ triggerOpcodes: new Set(["0x0f8a7ea5"]),
74654
+ safeToSkipOpcodes: new Set(["0x7362d09c", "0xd53276db"])
74655
+ }];
74656
+ /**
74657
+ * Determines if a transaction trace has failed.
74658
+ *
74659
+ * In TON, a single transaction triggers a tree of internal messages.
74660
+ * Some messages can fail (abort) or be skipped without affecting the main action.
74661
+ *
74662
+ * This function applies action-specific logic:
74663
+ * - Checks known trace types (like Jetton Transfers) against their specific allowed failures.
74664
+ * - **Unknown types**: checks if ANY transaction in the trace has failed.
74665
+ *
74666
+ * @param tx - The trace response from toncenter
74667
+ * @returns `true` if the trace is considered failed
74668
+ */
74669
+ const isFailedTrace = (tx) => {
74670
+ const trace = tx.traces?.[0];
74671
+ if (!trace) return false;
74672
+ const transactions = trace.transactions ?? {};
74673
+ if (Object.keys(transactions).length === 0) return false;
74674
+ for (const config of KNOWN_TRACE_TYPES) if (createTraceTypeDetector(config.triggerOpcodes)(transactions)) return createFailureDetector(config.safeToSkipOpcodes)(transactions);
74675
+ return createFailureDetector(/* @__PURE__ */ new Set())(transactions);
74676
+ };
74677
+
74678
+ //#endregion
74679
+ //#region ../walletkit/dist/esm/utils/toncenter/parseTraceResponse.js
74680
+ /**
74681
+ * Copyright (c) TonTech.
74682
+ *
74683
+ * This source code is licensed under the MIT license found in the
74684
+ * LICENSE file in the root directory of this source tree.
74685
+ *
74686
+ */
74687
+ /**
74688
+ * Helper to parse ToncenterTracesResponse into TransactionStatusResponse.
74689
+ * Returns null if no traces are found.
74690
+ */
74691
+ const parseTraceResponse = (response) => {
74692
+ if (!response.traces || response.traces.length === 0) return null;
74693
+ const traceInfo = response.traces[0].trace_info;
74694
+ const isEffectivelyCompleted = traceInfo.trace_state === "complete" || traceInfo.trace_state === "pending" && traceInfo.pending_messages === 0;
74695
+ let status = "pending";
74696
+ if (traceInfo.pending_messages === 0) {
74697
+ if (isFailedTrace(response)) status = "failed";
74698
+ else if (isEffectivelyCompleted) status = "completed";
74699
+ }
74700
+ return {
74701
+ status,
74702
+ totalMessages: traceInfo.messages,
74703
+ pendingMessages: traceInfo.pending_messages,
74704
+ onchainMessages: traceInfo.messages - traceInfo.pending_messages
74705
+ };
74706
+ };
74707
+
74708
+ //#endregion
74709
+ //#region ../walletkit/dist/esm/utils/getNormalizedExtMessageHash.js
74710
+ /**
74711
+ * Copyright (c) TonTech.
74712
+ *
74713
+ * This source code is licensed under the MIT license found in the
74714
+ * LICENSE file in the root directory of this source tree.
74715
+ *
74716
+ */
74717
+ /**
74718
+ * Generates a normalized hash of an "external-in" message for comparison.
74719
+ *
74720
+ * This function ensures consistent hashing of external-in messages by following [TEP-467].
74721
+ * See documentation: https://docs.ton.org/ecosystem/ton-connect/message-lookup#transaction-lookup-using-external-message-from-ton-connect
74722
+ *
74723
+ * @param params - An object containing the built BOC as a base64 string.
74724
+ * @returns An object containing the hash (Hex string) and the boc (Base64 string) of the normalized message.
74725
+ * @throws if the message type is not `external-in`.
74726
+ */
74727
+ function getNormalizedExtMessageHash(boc) {
74728
+ const message = (0, import_dist$3.loadMessage)(import_dist$3.Cell.fromBase64(boc).beginParse());
74729
+ if (message.info.type !== "external-in") throw new Error(`Message must be "external-in", got ${message.info.type}`);
74730
+ const info = {
74731
+ ...message.info,
74732
+ src: void 0,
74733
+ importFee: 0n
74734
+ };
74735
+ const normalizedMessage = {
74736
+ ...message,
74737
+ init: null,
74738
+ info
74739
+ };
74740
+ const normalizedCell = (0, import_dist$3.beginCell)().store((0, import_dist$3.storeMessage)(normalizedMessage, { forceRef: true })).endCell();
74741
+ return {
74742
+ hash: `0x${normalizedCell.hash().toString("hex")}`,
74743
+ boc: normalizedCell.toBoc().toString("base64")
74744
+ };
74745
+ }
74746
+
74747
+ //#endregion
74748
+ //#region ../walletkit/dist/esm/utils/toncenter/getTransactionStatus.js
74749
+ /**
74750
+ * Copyright (c) TonTech.
74751
+ *
74752
+ * This source code is licensed under the MIT license found in the
74753
+ * LICENSE file in the root directory of this source tree.
74754
+ *
74755
+ */
74756
+ /**
74757
+ * Get the status of a transaction by its BOC.
74758
+ *
74759
+ * In TON, a single external message triggers a tree of internal messages.
74760
+ * The transaction is "complete" only when the entire trace finishes.
74761
+ */
74762
+ async function getTransactionStatus(client, params) {
74763
+ const hashToSearch = params.boc ? getNormalizedExtMessageHash(params.boc).hash : params.normalizedHash;
74764
+ if (!hashToSearch) throw new Error("Either boc or normalizedHash must be provided");
74765
+ try {
74766
+ const pendingStatus = parseTraceResponse(await client.getPendingTrace({ externalMessageHash: [hashToSearch] }));
74767
+ if (pendingStatus) return pendingStatus;
74768
+ } catch (_e) {}
74769
+ try {
74770
+ const completedStatus = parseTraceResponse(await client.getTrace({ traceId: [hashToSearch] }));
74771
+ if (completedStatus) return completedStatus;
74772
+ } catch (_e) {}
74773
+ return {
74774
+ status: "unknown",
74775
+ totalMessages: 0,
74776
+ pendingMessages: 0,
74777
+ onchainMessages: 0
74778
+ };
74779
+ }
74780
+
74531
74781
  //#endregion
74532
74782
  //#region ../walletkit/dist/esm/utils/messageBuilders.js
74533
74783
  /**
@@ -74710,7 +74960,12 @@ var WalletTonClass = class {
74710
74960
  try {
74711
74961
  const boc = await this.getSignedSendTransaction(request);
74712
74962
  await CallForSuccess(() => this.getClient().sendBoc(boc));
74713
- return { boc };
74963
+ const { hash: normalizedHash, boc: normalizedBoc } = getNormalizedExtMessageHash(boc);
74964
+ return {
74965
+ boc,
74966
+ normalizedBoc,
74967
+ normalizedHash
74968
+ };
74714
74969
  } catch (error) {
74715
74970
  log$13.error("Failed to send transaction", { error });
74716
74971
  if (error instanceof WalletKitError) throw error;
@@ -77424,8 +77679,8 @@ var ApiClientToncenter = class {
77424
77679
  disableNetworkSend;
77425
77680
  constructor(config = {}) {
77426
77681
  this.network = config.network;
77427
- const dnsResolver = this.network?.chainId === CHAIN.MAINNET ? ROOT_DNS_RESOLVER_MAINNET : ROOT_DNS_RESOLVER_TESTNET;
77428
- const defaultEndpoint = this.network?.chainId === CHAIN.MAINNET ? "https://toncenter.com" : "https://testnet.toncenter.com";
77682
+ const dnsResolver = this.network?.chainId === Network.mainnet().chainId ? ROOT_DNS_RESOLVER_MAINNET : ROOT_DNS_RESOLVER_TESTNET;
77683
+ const defaultEndpoint = this.network?.chainId === Network.mainnet().chainId ? "https://toncenter.com" : "https://testnet.toncenter.com";
77429
77684
  this.dnsResolver = config.dnsResolver ?? dnsResolver;
77430
77685
  this.endpoint = config.endpoint ?? defaultEndpoint;
77431
77686
  this.apiKey = config.apiKey;
@@ -77461,7 +77716,7 @@ var ApiClientToncenter = class {
77461
77716
  }
77462
77717
  async sendBoc(boc) {
77463
77718
  if (this.disableNetworkSend) return "";
77464
- return Base64ToBigInt((await this.postJson("/api/v3/message", { boc })).message_hash_norm).toString(16);
77719
+ return `0x${Base64ToBigInt((await this.postJson("/api/v3/message", { boc })).message_hash_norm).toString(16)}`;
77465
77720
  }
77466
77721
  async runGetMethod(address, method, stack = [], seqno) {
77467
77722
  const props = {
@@ -77592,31 +77847,31 @@ var ApiClientToncenter = class {
77592
77847
  }));
77593
77848
  }
77594
77849
  async getTrace(request) {
77595
- const traceId = padBase64(Base64Normalize((request.traceId ? request.traceId[0] : void 0) || "").replace(/=/g, ""));
77596
- try {
77597
- const response = await CallForSuccess(() => this.getJson("/api/v3/traces", { tx_hash: traceId }));
77598
- if (response.traces.length > 0) return response;
77599
- } catch (error) {
77600
- log$7.error("Error fetching trace", { error });
77601
- }
77602
- try {
77603
- const response = await CallForSuccess(() => this.getJson("/api/v3/traces", { trace_id: traceId }));
77604
- if (response.traces.length > 0) return response;
77605
- } catch (error) {
77606
- log$7.error("Error fetching trace", { error });
77607
- }
77608
- try {
77609
- const response = await CallForSuccess(() => this.getJson("/api/v3/traces", { msg_hash: traceId }));
77610
- if (response.traces.length > 0) return response;
77611
- } catch (error) {
77612
- log$7.error("Error fetching pending trace", { error });
77613
- }
77850
+ const traceIdStr = (request.traceId ? request.traceId[0] : void 0) || "";
77851
+ const traceId = isHex(traceIdStr) ? traceIdStr : padBase64(Base64Normalize(traceIdStr).replace(/=/g, ""));
77852
+ const tryGetTrace = async (field) => {
77853
+ const response = await CallForSuccess(() => this.getJson("/api/v3/traces", { [field]: traceId }), void 0, void 0, (err) => err instanceof TonClientError ? err.status !== 422 : true);
77854
+ if (response?.traces?.length > 0) return response;
77855
+ throw new Error(`No traces found for ${field}`);
77856
+ };
77857
+ const results = await Promise.allSettled([
77858
+ tryGetTrace("tx_hash"),
77859
+ tryGetTrace("trace_id"),
77860
+ tryGetTrace("msg_hash")
77861
+ ]);
77862
+ const fulfilledResult = results.find((result) => result.status === "fulfilled");
77863
+ if (fulfilledResult) return fulfilledResult.value;
77864
+ results.forEach((result) => {
77865
+ if (result.status === "rejected") log$7.error("Error fetching trace", { error: result.reason });
77866
+ });
77614
77867
  throw new Error("Failed to fetch trace");
77615
77868
  }
77616
77869
  async getPendingTrace(request) {
77617
77870
  try {
77618
- const response = await CallForSuccess(() => this.getJson("/api/v3/pendingTraces", { ext_msg_hash: request.externalMessageHash }));
77619
- if (response.traces.length > 0) return response;
77871
+ const response = await CallForSuccess(() => {
77872
+ return this.getJson("/api/v3/pendingTraces", { ext_msg_hash: request.externalMessageHash });
77873
+ }, void 0, void 0, (err) => err instanceof TonClientError ? err.status !== 422 : true);
77874
+ if (response?.traces?.length > 0) return response;
77620
77875
  } catch (error) {
77621
77876
  log$7.error("Error fetching pending trace", { error });
77622
77877
  }
@@ -77755,7 +78010,7 @@ const log$6 = globalLogger.createChild("NetworkManager");
77755
78010
  /**
77756
78011
  * Manages multiple API clients for different networks
77757
78012
  *
77758
- * Each network (identified by CHAIN) has its own ApiClient instance.
78013
+ * Each network has its own ApiClient instance.
77759
78014
  * At least one network must be configured.
77760
78015
  */
77761
78016
  var KitNetworkManager = class {
@@ -77786,7 +78041,10 @@ var KitNetworkManager = class {
77786
78041
  */
77787
78042
  createClient(network, apiClientConfig, options) {
77788
78043
  if (this.isApiClient(apiClientConfig)) return apiClientConfig;
77789
- const defaultEndpoint = network.chainId === CHAIN.MAINNET ? "https://toncenter.com" : "https://testnet.toncenter.com";
78044
+ let defaultEndpoint;
78045
+ if (network.chainId == Network.mainnet().chainId) defaultEndpoint = "https://toncenter.com";
78046
+ else if (network.chainId == Network.tetra().chainId) defaultEndpoint = "https://tetra.tonapi.io";
78047
+ else defaultEndpoint = "https://testnet.toncenter.com";
77790
78048
  return new ApiClientToncenter({
77791
78049
  endpoint: apiClientConfig?.url || defaultEndpoint,
77792
78050
  apiKey: apiClientConfig?.key,
@@ -77802,7 +78060,7 @@ var KitNetworkManager = class {
77802
78060
  }
77803
78061
  /**
77804
78062
  * Get API client for a specific network
77805
- * @param chainId - The chain ID (CHAIN.MAINNET or CHAIN.TESTNET)
78063
+ * @param chainId - The chain ID
77806
78064
  * @returns The API client for the specified network
77807
78065
  * @throws WalletKitError if no client is configured for the network
77808
78066
  */
@@ -77920,7 +78178,7 @@ var TonWalletKit = class {
77920
78178
  items: [{
77921
78179
  name: "ton_addr",
77922
78180
  address: import_dist$3.Address.parse(walletAddress).toRawString(),
77923
- network: wallet.getNetwork().chainId === CHAIN.MAINNET ? CHAIN.MAINNET : CHAIN.TESTNET,
78181
+ network: wallet.getNetwork().chainId,
77924
78182
  walletStateInit,
77925
78183
  publicKey
77926
78184
  }]
@@ -111338,7 +111596,7 @@ var McpWalletService = class McpWalletService {
111338
111596
  * Get wallet network
111339
111597
  */
111340
111598
  getNetwork() {
111341
- return this.wallet.getNetwork().chainId === Network.mainnet().chainId ? "mainnet" : "testnet";
111599
+ return this.wallet.getNetwork().chainId === Network.mainnet().chainId ? "mainnet" : Network.tetra().chainId ? "tetra" : "testnet";
111342
111600
  }
111343
111601
  /**
111344
111602
  * Initialize TonWalletKit (for swap operations)
@@ -111454,10 +111712,11 @@ var McpWalletService = class McpWalletService {
111454
111712
  transferAmount: amountNano,
111455
111713
  comment
111456
111714
  });
111457
- await this.wallet.sendTransaction(tx);
111715
+ const response = await this.wallet.sendTransaction(tx);
111458
111716
  return {
111459
111717
  success: true,
111460
- message: `Successfully sent ${amountNano} nanoTON to ${toAddress}`
111718
+ message: `Successfully sent ${amountNano} nanoTON to ${toAddress}`,
111719
+ normalizedHash: response.normalizedHash
111461
111720
  };
111462
111721
  } catch (error) {
111463
111722
  return {
@@ -111477,10 +111736,11 @@ var McpWalletService = class McpWalletService {
111477
111736
  transferAmount: amountRaw,
111478
111737
  comment
111479
111738
  });
111480
- await this.wallet.sendTransaction(tx);
111739
+ const response = await this.wallet.sendTransaction(tx);
111481
111740
  return {
111482
111741
  success: true,
111483
- message: `Successfully sent jettons to ${toAddress}`
111742
+ message: `Successfully sent jettons to ${toAddress}`,
111743
+ normalizedHash: response.normalizedHash
111484
111744
  };
111485
111745
  } catch (error) {
111486
111746
  return {
@@ -111494,10 +111754,11 @@ var McpWalletService = class McpWalletService {
111494
111754
  */
111495
111755
  async sendRawTransaction(request) {
111496
111756
  try {
111497
- await this.wallet.sendTransaction(request);
111757
+ const tx = await this.wallet.sendTransaction(request);
111498
111758
  return {
111499
111759
  success: true,
111500
- message: `Successfully sent transaction with ${request.messages.length} message(s)`
111760
+ message: `Successfully sent transaction with ${request.messages.length} message(s)`,
111761
+ normalizedHash: tx.normalizedHash
111501
111762
  };
111502
111763
  } catch (error) {
111503
111764
  return {
@@ -111507,6 +111768,15 @@ var McpWalletService = class McpWalletService {
111507
111768
  }
111508
111769
  }
111509
111770
  /**
111771
+ * Get the status of a transaction by its normalized hash.
111772
+ *
111773
+ * In TON, a single external message triggers a tree of internal messages.
111774
+ * The transaction is "complete" only when the entire trace finishes.
111775
+ */
111776
+ async getTransactionStatus(normalizedHash) {
111777
+ return getTransactionStatus(this.wallet.getClient(), { normalizedHash });
111778
+ }
111779
+ /**
111510
111780
  * Get swap quote with transaction params ready to execute
111511
111781
  * @param fromToken Token to swap from ("TON" or jetton address)
111512
111782
  * @param toToken Token to swap to ("TON" or jetton address)
@@ -111620,10 +111890,11 @@ var McpWalletService = class McpWalletService {
111620
111890
  recipientAddress: toAddress,
111621
111891
  comment
111622
111892
  });
111623
- await this.wallet.sendTransaction(tx);
111893
+ const response = await this.wallet.sendTransaction(tx);
111624
111894
  return {
111625
111895
  success: true,
111626
- message: `Successfully sent NFT ${nftAddress} to ${toAddress}`
111896
+ message: `Successfully sent NFT ${nftAddress} to ${toAddress}`,
111897
+ normalizedHash: response.normalizedHash
111627
111898
  };
111628
111899
  } catch (error) {
111629
111900
  return {
@@ -115432,7 +115703,7 @@ const sendRawTransactionSchema = objectType({
115432
115703
  function createMcpTransferTools(service) {
115433
115704
  return {
115434
115705
  send_ton: {
115435
- description: "Send TON from the wallet to an address. Amount is in TON (e.g., \"1.5\" means 1.5 TON).",
115706
+ 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.",
115436
115707
  inputSchema: sendTonSchema,
115437
115708
  handler: async (args) => {
115438
115709
  const rawAmount = toRawAmount(args.amount, TON_DECIMALS);
@@ -115455,14 +115726,15 @@ function createMcpTransferTools(service) {
115455
115726
  details: {
115456
115727
  to: args.toAddress,
115457
115728
  amount: `${args.amount} TON`,
115458
- comment: args.comment || null
115729
+ comment: args.comment || null,
115730
+ normalizedHash: result.normalizedHash
115459
115731
  }
115460
115732
  }, null, 2)
115461
115733
  }] };
115462
115734
  }
115463
115735
  },
115464
115736
  send_jetton: {
115465
- description: "Send Jettons (tokens) from the wallet to an address. Amount is in human-readable format.",
115737
+ 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.",
115466
115738
  inputSchema: sendJettonSchema,
115467
115739
  handler: async (args) => {
115468
115740
  let decimals;
@@ -115516,14 +115788,15 @@ function createMcpTransferTools(service) {
115516
115788
  to: args.toAddress,
115517
115789
  jettonAddress: args.jettonAddress,
115518
115790
  amount: `${args.amount} ${symbol || "tokens"}`,
115519
- comment: args.comment || null
115791
+ comment: args.comment || null,
115792
+ normalizedHash: result.normalizedHash
115520
115793
  }
115521
115794
  }, null, 2)
115522
115795
  }] };
115523
115796
  }
115524
115797
  },
115525
115798
  send_raw_transaction: {
115526
- description: "Send a raw transaction with full control over messages. Amounts are in nanotons. Supports multiple messages in a single transaction.",
115799
+ 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.",
115527
115800
  inputSchema: sendRawTransactionSchema,
115528
115801
  handler: async (args) => {
115529
115802
  const result = await service.sendRawTransaction({
@@ -115551,7 +115824,8 @@ function createMcpTransferTools(service) {
115551
115824
  messages: args.messages.map((m) => ({
115552
115825
  to: m.address,
115553
115826
  amount: `${m.amount} nanoTON`
115554
- }))
115827
+ })),
115828
+ normalizedHash: result.normalizedHash
115555
115829
  }
115556
115830
  }, null, 2)
115557
115831
  }] };
@@ -115781,7 +116055,7 @@ function createMcpNftTools(service) {
115781
116055
  }
115782
116056
  },
115783
116057
  send_nft: {
115784
- description: "Transfer an NFT from the wallet to another address.",
116058
+ 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.",
115785
116059
  inputSchema: sendNftSchema,
115786
116060
  handler: async (args) => {
115787
116061
  try {
@@ -115793,7 +116067,8 @@ function createMcpNftTools(service) {
115793
116067
  success: result.success,
115794
116068
  message: result.message,
115795
116069
  nftAddress: args.nftAddress,
115796
- recipient: args.toAddress
116070
+ recipient: args.toAddress,
116071
+ normalizedHash: result.normalizedHash
115797
116072
  }, null, 2)
115798
116073
  }],
115799
116074
  isError: !result.success
@@ -115815,6 +116090,43 @@ function createMcpNftTools(service) {
115815
116090
  };
115816
116091
  }
115817
116092
 
116093
+ //#endregion
116094
+ //#region src/tools/transaction-tools.ts
116095
+ /**
116096
+ * Copyright (c) TonTech.
116097
+ *
116098
+ * This source code is licensed under the MIT license found in the
116099
+ * LICENSE file in the root directory of this source tree.
116100
+ *
116101
+ */
116102
+ const getTransactionStatusSchema = objectType({ normalizedHash: stringType().min(1).describe("Normalized hash of the external-in transaction (Hex string)") });
116103
+ function createMcpTransactionTools(service) {
116104
+ return { get_transaction_status: {
116105
+ 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.",
116106
+ inputSchema: getTransactionStatusSchema,
116107
+ handler: async (args) => {
116108
+ try {
116109
+ const result = await service.getTransactionStatus(args.normalizedHash);
116110
+ return { content: [{
116111
+ type: "text",
116112
+ text: JSON.stringify(result, null, 2)
116113
+ }] };
116114
+ } catch (error) {
116115
+ return {
116116
+ content: [{
116117
+ type: "text",
116118
+ text: JSON.stringify({
116119
+ success: false,
116120
+ error: `Failed to get transaction status: ${error instanceof Error ? error.message : "Unknown error"}`
116121
+ })
116122
+ }],
116123
+ isError: true
116124
+ };
116125
+ }
116126
+ }
116127
+ } };
116128
+ }
116129
+
115818
116130
  //#endregion
115819
116131
  //#region src/tools/dns-tools.ts
115820
116132
  /**
@@ -115960,6 +116272,7 @@ async function createTonWalletMCP(config) {
115960
116272
  const knownJettonsTools = createMcpKnownJettonsTools();
115961
116273
  const nftTools = createMcpNftTools(walletService);
115962
116274
  const dnsTools = createMcpDnsTools(walletService);
116275
+ const transactionTools = createMcpTransactionTools(walletService);
115963
116276
  const registerTool = (name, tool) => {
115964
116277
  server.registerTool(name, {
115965
116278
  description: tool.description,
@@ -115974,6 +116287,7 @@ async function createTonWalletMCP(config) {
115974
116287
  registerTool("send_ton", transferTools.send_ton);
115975
116288
  registerTool("send_jetton", transferTools.send_jetton);
115976
116289
  registerTool("send_raw_transaction", transferTools.send_raw_transaction);
116290
+ registerTool("get_transaction_status", transactionTools.get_transaction_status);
115977
116291
  registerTool("get_swap_quote", swapTools.get_swap_quote);
115978
116292
  registerTool("get_known_jettons", knownJettonsTools.get_known_jettons);
115979
116293
  registerTool("get_nfts", nftTools.get_nfts);