@truecarry/mcp 0.1.4 → 0.1.6
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 +447 -82
- package/dist/factory.d.ts.map +1 -1
- package/dist/index.cjs +447 -82
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +447 -82
- package/dist/services/McpWalletService.d.ts +66 -13
- package/dist/services/McpWalletService.d.ts.map +1 -1
- package/dist/tools/dns-tools.d.ts +49 -0
- package/dist/tools/dns-tools.d.ts.map +1 -0
- package/dist/tools/index.d.ts +2 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/known-jettons-tools.d.ts +44 -0
- package/dist/tools/known-jettons-tools.d.ts.map +1 -0
- package/dist/tools/nft-tools.d.ts +85 -0
- package/dist/tools/nft-tools.d.ts.map +1 -0
- package/dist/tools/swap-tools.d.ts +0 -18
- package/dist/tools/swap-tools.d.ts.map +1 -1
- package/dist/tools/transfer-tools.d.ts +80 -0
- package/dist/tools/transfer-tools.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -71004,7 +71004,7 @@ async function dnsLookup(client, domain, category, resolver) {
|
|
|
71004
71004
|
type: "int",
|
|
71005
71005
|
value: toTonDnsCategory(category)
|
|
71006
71006
|
}];
|
|
71007
|
-
const { stack, exitCode } = await client.runGetMethod(asAddressFriendly(resolver), "dnsresolve", SerializeStack(param));
|
|
71007
|
+
const { stack, exitCode } = await CallForSuccess(() => client.runGetMethod(asAddressFriendly(resolver), "dnsresolve", SerializeStack(param)));
|
|
71008
71008
|
if (stack?.length !== 2) return null;
|
|
71009
71009
|
const parsedStack = ParseStack(stack);
|
|
71010
71010
|
if (exitCode !== 0) return null;
|
|
@@ -88324,7 +88324,24 @@ var McpWalletService = class McpWalletService {
|
|
|
88324
88324
|
}
|
|
88325
88325
|
}
|
|
88326
88326
|
/**
|
|
88327
|
-
*
|
|
88327
|
+
* Send a raw transaction request directly
|
|
88328
|
+
*/
|
|
88329
|
+
async sendRawTransaction(request) {
|
|
88330
|
+
try {
|
|
88331
|
+
await this.wallet.sendTransaction(request);
|
|
88332
|
+
return {
|
|
88333
|
+
success: true,
|
|
88334
|
+
message: `Successfully sent transaction with ${request.messages.length} message(s)`
|
|
88335
|
+
};
|
|
88336
|
+
} catch (error) {
|
|
88337
|
+
return {
|
|
88338
|
+
success: false,
|
|
88339
|
+
message: error instanceof Error ? error.message : "Unknown error"
|
|
88340
|
+
};
|
|
88341
|
+
}
|
|
88342
|
+
}
|
|
88343
|
+
/**
|
|
88344
|
+
* Get swap quote with transaction params ready to execute
|
|
88328
88345
|
*/
|
|
88329
88346
|
async getSwapQuote(fromToken, toToken, amount, slippageBps) {
|
|
88330
88347
|
const network = this.wallet.getNetwork();
|
|
@@ -88343,32 +88360,95 @@ var McpWalletService = class McpWalletService {
|
|
|
88343
88360
|
slippageBps
|
|
88344
88361
|
};
|
|
88345
88362
|
const quote = await kit.swap.getQuote(params);
|
|
88346
|
-
|
|
88363
|
+
const swapParams = {
|
|
88347
88364
|
quote,
|
|
88365
|
+
userAddress: this.wallet.getAddress()
|
|
88366
|
+
};
|
|
88367
|
+
const tx = await kit.swap.buildSwapTransaction(swapParams);
|
|
88368
|
+
return {
|
|
88348
88369
|
fromToken: quote.fromToken.type === "ton" ? "TON" : quote.fromToken.value,
|
|
88349
88370
|
toToken: quote.toToken.type === "ton" ? "TON" : quote.toToken.value,
|
|
88350
88371
|
fromAmount: quote.fromAmount,
|
|
88351
88372
|
toAmount: quote.toAmount,
|
|
88352
88373
|
minReceived: quote.minReceived,
|
|
88353
88374
|
provider: quote.providerId,
|
|
88354
|
-
expiresAt: quote.expiresAt
|
|
88375
|
+
expiresAt: quote.expiresAt,
|
|
88376
|
+
transaction: {
|
|
88377
|
+
messages: tx.messages.map((m) => ({
|
|
88378
|
+
address: m.address,
|
|
88379
|
+
amount: m.amount.toString(),
|
|
88380
|
+
stateInit: m.stateInit,
|
|
88381
|
+
payload: m.payload
|
|
88382
|
+
})),
|
|
88383
|
+
validUntil: tx.validUntil
|
|
88384
|
+
}
|
|
88385
|
+
};
|
|
88386
|
+
}
|
|
88387
|
+
/**
|
|
88388
|
+
* Get all NFTs
|
|
88389
|
+
*/
|
|
88390
|
+
async getNfts(limit = 20, offset = 0) {
|
|
88391
|
+
return (await this.wallet.getNfts({ pagination: {
|
|
88392
|
+
limit,
|
|
88393
|
+
offset
|
|
88394
|
+
} })).nfts.map((nft) => ({
|
|
88395
|
+
address: nft.address,
|
|
88396
|
+
name: nft.info?.name,
|
|
88397
|
+
description: nft.info?.description,
|
|
88398
|
+
image: typeof nft.info?.image === "string" ? nft.info.image : nft.info?.image?.url,
|
|
88399
|
+
collection: nft.collection ? {
|
|
88400
|
+
address: nft.collection.address,
|
|
88401
|
+
name: nft.collection.name
|
|
88402
|
+
} : void 0,
|
|
88403
|
+
attributes: nft.attributes?.map((attr) => ({
|
|
88404
|
+
trait_type: attr.traitType,
|
|
88405
|
+
value: attr.value
|
|
88406
|
+
})),
|
|
88407
|
+
ownerAddress: nft.ownerAddress,
|
|
88408
|
+
isOnSale: nft.isOnSale,
|
|
88409
|
+
isSoulbound: nft.isSoulbound,
|
|
88410
|
+
saleContractAddress: nft.saleContractAddress
|
|
88411
|
+
}));
|
|
88412
|
+
}
|
|
88413
|
+
/**
|
|
88414
|
+
* Get a specific NFT by address
|
|
88415
|
+
*/
|
|
88416
|
+
async getNft(nftAddress) {
|
|
88417
|
+
const nft = await this.wallet.getNft(nftAddress);
|
|
88418
|
+
if (!nft) return null;
|
|
88419
|
+
return {
|
|
88420
|
+
address: nft.address,
|
|
88421
|
+
name: nft.info?.name,
|
|
88422
|
+
description: nft.info?.description,
|
|
88423
|
+
image: typeof nft.info?.image === "string" ? nft.info.image : nft.info?.image?.url,
|
|
88424
|
+
collection: nft.collection ? {
|
|
88425
|
+
address: nft.collection.address,
|
|
88426
|
+
name: nft.collection.name
|
|
88427
|
+
} : void 0,
|
|
88428
|
+
attributes: nft.attributes?.map((attr) => ({
|
|
88429
|
+
trait_type: attr.traitType,
|
|
88430
|
+
value: attr.value
|
|
88431
|
+
})),
|
|
88432
|
+
ownerAddress: nft.ownerAddress,
|
|
88433
|
+
isOnSale: nft.isOnSale,
|
|
88434
|
+
isSoulbound: nft.isSoulbound,
|
|
88435
|
+
saleContractAddress: nft.saleContractAddress
|
|
88355
88436
|
};
|
|
88356
88437
|
}
|
|
88357
88438
|
/**
|
|
88358
|
-
*
|
|
88439
|
+
* Send NFT
|
|
88359
88440
|
*/
|
|
88360
|
-
async
|
|
88441
|
+
async sendNft(nftAddress, toAddress, comment) {
|
|
88361
88442
|
try {
|
|
88362
|
-
const
|
|
88363
|
-
|
|
88364
|
-
|
|
88365
|
-
|
|
88366
|
-
};
|
|
88367
|
-
const tx = await kit.swap.buildSwapTransaction(params);
|
|
88443
|
+
const tx = await this.wallet.createTransferNftTransaction({
|
|
88444
|
+
nftAddress,
|
|
88445
|
+
recipientAddress: toAddress,
|
|
88446
|
+
comment
|
|
88447
|
+
});
|
|
88368
88448
|
await this.wallet.sendTransaction(tx);
|
|
88369
88449
|
return {
|
|
88370
88450
|
success: true,
|
|
88371
|
-
message: `Successfully
|
|
88451
|
+
message: `Successfully sent NFT ${nftAddress} to ${toAddress}`
|
|
88372
88452
|
};
|
|
88373
88453
|
} catch (error) {
|
|
88374
88454
|
return {
|
|
@@ -88385,6 +88465,18 @@ var McpWalletService = class McpWalletService {
|
|
|
88385
88465
|
return this.config.contacts.resolve("default", name);
|
|
88386
88466
|
}
|
|
88387
88467
|
/**
|
|
88468
|
+
* Resolve a TON DNS domain (e.g., "wallet.ton") to a wallet address
|
|
88469
|
+
*/
|
|
88470
|
+
async resolveDns(domain) {
|
|
88471
|
+
return this.wallet.getClient().resolveDnsWallet(domain);
|
|
88472
|
+
}
|
|
88473
|
+
/**
|
|
88474
|
+
* Reverse resolve a wallet address to a TON DNS domain
|
|
88475
|
+
*/
|
|
88476
|
+
async backResolveDns(address) {
|
|
88477
|
+
return this.wallet.getClient().backResolveDnsWallet(address);
|
|
88478
|
+
}
|
|
88479
|
+
/**
|
|
88388
88480
|
* Close and cleanup
|
|
88389
88481
|
*/
|
|
88390
88482
|
async close() {
|
|
@@ -88589,6 +88681,17 @@ const sendJettonSchema = z.object({
|
|
|
88589
88681
|
amount: z.string().min(1).describe("Amount of tokens to send in human-readable format"),
|
|
88590
88682
|
comment: z.string().optional().describe("Optional comment/memo for the transaction")
|
|
88591
88683
|
});
|
|
88684
|
+
const transactionMessageSchema = z.object({
|
|
88685
|
+
address: z.string().min(1).describe("Recipient wallet address"),
|
|
88686
|
+
amount: z.string().min(1).describe("Amount to transfer in nanotons"),
|
|
88687
|
+
stateInit: z.string().optional().describe("Initial state for deploying a new contract (Base64)"),
|
|
88688
|
+
payload: z.string().optional().describe("Message payload data (Base64)")
|
|
88689
|
+
});
|
|
88690
|
+
const sendRawTransactionSchema = z.object({
|
|
88691
|
+
messages: z.array(transactionMessageSchema).min(1).describe("Array of messages to include in the transaction"),
|
|
88692
|
+
validUntil: z.number().optional().describe("Unix timestamp after which the transaction becomes invalid"),
|
|
88693
|
+
fromAddress: z.string().optional().describe("Sender wallet address")
|
|
88694
|
+
});
|
|
88592
88695
|
function createMcpTransferTools(service) {
|
|
88593
88696
|
return {
|
|
88594
88697
|
send_ton: {
|
|
@@ -88681,6 +88784,41 @@ function createMcpTransferTools(service) {
|
|
|
88681
88784
|
}, null, 2)
|
|
88682
88785
|
}] };
|
|
88683
88786
|
}
|
|
88787
|
+
},
|
|
88788
|
+
send_raw_transaction: {
|
|
88789
|
+
description: "Send a raw transaction with full control over messages. Amounts are in nanotons. Supports multiple messages in a single transaction.",
|
|
88790
|
+
inputSchema: sendRawTransactionSchema,
|
|
88791
|
+
handler: async (args) => {
|
|
88792
|
+
const result = await service.sendRawTransaction({
|
|
88793
|
+
messages: args.messages,
|
|
88794
|
+
validUntil: args.validUntil,
|
|
88795
|
+
fromAddress: args.fromAddress
|
|
88796
|
+
});
|
|
88797
|
+
if (!result.success) return {
|
|
88798
|
+
content: [{
|
|
88799
|
+
type: "text",
|
|
88800
|
+
text: JSON.stringify({
|
|
88801
|
+
success: false,
|
|
88802
|
+
error: result.message
|
|
88803
|
+
})
|
|
88804
|
+
}],
|
|
88805
|
+
isError: true
|
|
88806
|
+
};
|
|
88807
|
+
return { content: [{
|
|
88808
|
+
type: "text",
|
|
88809
|
+
text: JSON.stringify({
|
|
88810
|
+
success: true,
|
|
88811
|
+
message: result.message,
|
|
88812
|
+
details: {
|
|
88813
|
+
messageCount: args.messages.length,
|
|
88814
|
+
messages: args.messages.map((m) => ({
|
|
88815
|
+
to: m.address,
|
|
88816
|
+
amount: `${m.amount} nanoTON`
|
|
88817
|
+
}))
|
|
88818
|
+
}
|
|
88819
|
+
}, null, 2)
|
|
88820
|
+
}] };
|
|
88821
|
+
}
|
|
88684
88822
|
}
|
|
88685
88823
|
};
|
|
88686
88824
|
}
|
|
@@ -88694,49 +88832,153 @@ function createMcpTransferTools(service) {
|
|
|
88694
88832
|
* LICENSE file in the root directory of this source tree.
|
|
88695
88833
|
*
|
|
88696
88834
|
*/
|
|
88697
|
-
const quoteCache = /* @__PURE__ */ new Map();
|
|
88698
|
-
function generateQuoteId() {
|
|
88699
|
-
return `quote_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
88700
|
-
}
|
|
88701
|
-
function cleanExpiredQuotes() {
|
|
88702
|
-
const now = Date.now();
|
|
88703
|
-
for (const [id, data] of quoteCache.entries()) if (data.expiresAt < now) quoteCache.delete(id);
|
|
88704
|
-
}
|
|
88705
88835
|
const getSwapQuoteSchema = z.object({
|
|
88706
88836
|
fromToken: z.string().min(1).describe("Token to swap from (\"TON\" or jetton address)"),
|
|
88707
88837
|
toToken: z.string().min(1).describe("Token to swap to (\"TON\" or jetton address)"),
|
|
88708
88838
|
amount: z.string().min(1).describe("Amount to swap in raw units"),
|
|
88709
88839
|
slippageBps: z.number().optional().describe("Slippage tolerance in basis points (default 100 = 1%)")
|
|
88710
88840
|
});
|
|
88711
|
-
const executeSwapSchema = z.object({ quoteId: z.string().min(1).describe("Quote ID returned from get_swap_quote") });
|
|
88712
88841
|
function createMcpSwapTools(service) {
|
|
88842
|
+
return { get_swap_quote: {
|
|
88843
|
+
description: "Get a quote for swapping tokens. Returns quote details and transaction params. If user confirms, use send_raw_transaction to execute.",
|
|
88844
|
+
inputSchema: getSwapQuoteSchema,
|
|
88845
|
+
handler: async (args) => {
|
|
88846
|
+
try {
|
|
88847
|
+
const result = await service.getSwapQuote(args.fromToken, args.toToken, args.amount, args.slippageBps);
|
|
88848
|
+
return { content: [{
|
|
88849
|
+
type: "text",
|
|
88850
|
+
text: JSON.stringify({
|
|
88851
|
+
success: true,
|
|
88852
|
+
quote: {
|
|
88853
|
+
fromToken: result.fromToken,
|
|
88854
|
+
toToken: result.toToken,
|
|
88855
|
+
fromAmount: result.fromAmount,
|
|
88856
|
+
toAmount: result.toAmount,
|
|
88857
|
+
minReceived: result.minReceived,
|
|
88858
|
+
provider: result.provider,
|
|
88859
|
+
expiresAt: result.expiresAt ? (/* @__PURE__ */ new Date(result.expiresAt * 1e3)).toISOString() : null
|
|
88860
|
+
},
|
|
88861
|
+
transaction: result.transaction,
|
|
88862
|
+
note: "If user confirms, use send_raw_transaction with the transaction params to execute the swap."
|
|
88863
|
+
}, null, 2)
|
|
88864
|
+
}] };
|
|
88865
|
+
} catch (error) {
|
|
88866
|
+
return {
|
|
88867
|
+
content: [{
|
|
88868
|
+
type: "text",
|
|
88869
|
+
text: JSON.stringify({
|
|
88870
|
+
success: false,
|
|
88871
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
88872
|
+
})
|
|
88873
|
+
}],
|
|
88874
|
+
isError: true
|
|
88875
|
+
};
|
|
88876
|
+
}
|
|
88877
|
+
}
|
|
88878
|
+
} };
|
|
88879
|
+
}
|
|
88880
|
+
|
|
88881
|
+
//#endregion
|
|
88882
|
+
//#region src/tools/known-jettons-tools.ts
|
|
88883
|
+
/**
|
|
88884
|
+
* Copyright (c) TonTech.
|
|
88885
|
+
*
|
|
88886
|
+
* This source code is licensed under the MIT license found in the
|
|
88887
|
+
* LICENSE file in the root directory of this source tree.
|
|
88888
|
+
*
|
|
88889
|
+
*/
|
|
88890
|
+
const getKnownJettonsSchema = z.object({});
|
|
88891
|
+
const KNOWN_JETTONS = [
|
|
88892
|
+
{
|
|
88893
|
+
symbol: "USD₮",
|
|
88894
|
+
name: "Tether USD",
|
|
88895
|
+
address: "EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs",
|
|
88896
|
+
decimals: 6
|
|
88897
|
+
},
|
|
88898
|
+
{
|
|
88899
|
+
symbol: "NOT",
|
|
88900
|
+
name: "Notcoin",
|
|
88901
|
+
address: "EQAvlWFDxGF2lXm67y4yzC17wYKD9A0guwPkMs1gOsM__NOT",
|
|
88902
|
+
decimals: 9
|
|
88903
|
+
},
|
|
88904
|
+
{
|
|
88905
|
+
symbol: "DOGS",
|
|
88906
|
+
name: "Dogs",
|
|
88907
|
+
address: "EQCvxJy4eG8hyHBFsZ7eePxrRsUQSFE_jpptRAYBmcG_DOGS",
|
|
88908
|
+
decimals: 9
|
|
88909
|
+
},
|
|
88910
|
+
{
|
|
88911
|
+
symbol: "DUST",
|
|
88912
|
+
name: "DeDust",
|
|
88913
|
+
address: "EQBlqsm144Dq6SjbPI4jjZvA1hqTIP3CvHovbIfW_t-SCALE",
|
|
88914
|
+
decimals: 9
|
|
88915
|
+
},
|
|
88916
|
+
{
|
|
88917
|
+
symbol: "GRAM",
|
|
88918
|
+
name: "Gram",
|
|
88919
|
+
address: "EQC47093oX5Xhb0xuk2lCr2RhS8rj-vul61u4W2UH5ORmG_O",
|
|
88920
|
+
decimals: 9
|
|
88921
|
+
}
|
|
88922
|
+
];
|
|
88923
|
+
function createMcpKnownJettonsTools() {
|
|
88924
|
+
return { get_known_jettons: {
|
|
88925
|
+
description: "Get a list of known/popular Jettons (tokens) on TON with their addresses and metadata. Useful for looking up token addresses for swaps or transfers.",
|
|
88926
|
+
inputSchema: getKnownJettonsSchema,
|
|
88927
|
+
handler: async () => {
|
|
88928
|
+
return { content: [{
|
|
88929
|
+
type: "text",
|
|
88930
|
+
text: JSON.stringify({
|
|
88931
|
+
success: true,
|
|
88932
|
+
jettons: KNOWN_JETTONS,
|
|
88933
|
+
count: KNOWN_JETTONS.length
|
|
88934
|
+
}, null, 2)
|
|
88935
|
+
}] };
|
|
88936
|
+
}
|
|
88937
|
+
} };
|
|
88938
|
+
}
|
|
88939
|
+
|
|
88940
|
+
//#endregion
|
|
88941
|
+
//#region src/tools/nft-tools.ts
|
|
88942
|
+
/**
|
|
88943
|
+
* Copyright (c) TonTech.
|
|
88944
|
+
*
|
|
88945
|
+
* This source code is licensed under the MIT license found in the
|
|
88946
|
+
* LICENSE file in the root directory of this source tree.
|
|
88947
|
+
*
|
|
88948
|
+
*/
|
|
88949
|
+
const getNftsSchema = z.object({
|
|
88950
|
+
limit: z.number().min(1).max(100).optional().describe("Maximum number of NFTs to return (default: 20, max: 100)"),
|
|
88951
|
+
offset: z.number().min(0).optional().describe("Offset for pagination (default: 0)")
|
|
88952
|
+
});
|
|
88953
|
+
const getNftSchema = z.object({ nftAddress: z.string().min(1).describe("NFT item contract address") });
|
|
88954
|
+
const sendNftSchema = z.object({
|
|
88955
|
+
nftAddress: z.string().min(1).describe("NFT item contract address to transfer"),
|
|
88956
|
+
toAddress: z.string().min(1).describe("Recipient TON address"),
|
|
88957
|
+
comment: z.string().optional().describe("Optional comment/memo for the transaction")
|
|
88958
|
+
});
|
|
88959
|
+
function createMcpNftTools(service) {
|
|
88713
88960
|
return {
|
|
88714
|
-
|
|
88715
|
-
description: "
|
|
88716
|
-
inputSchema:
|
|
88961
|
+
get_nfts: {
|
|
88962
|
+
description: "List all NFTs (non-fungible tokens) in the wallet with their metadata, collection info, and attributes.",
|
|
88963
|
+
inputSchema: getNftsSchema,
|
|
88717
88964
|
handler: async (args) => {
|
|
88718
88965
|
try {
|
|
88719
|
-
|
|
88720
|
-
const result = await service.getSwapQuote(args.fromToken, args.toToken, args.amount, args.slippageBps);
|
|
88721
|
-
const quoteId = generateQuoteId();
|
|
88722
|
-
const expiresAt = result.expiresAt ? result.expiresAt * 1e3 : Date.now() + 6e4;
|
|
88723
|
-
quoteCache.set(quoteId, {
|
|
88724
|
-
quote: result.quote,
|
|
88725
|
-
expiresAt
|
|
88726
|
-
});
|
|
88966
|
+
const nfts = await service.getNfts(args.limit ?? 20, args.offset ?? 0);
|
|
88727
88967
|
return { content: [{
|
|
88728
88968
|
type: "text",
|
|
88729
88969
|
text: JSON.stringify({
|
|
88730
88970
|
success: true,
|
|
88731
|
-
|
|
88732
|
-
|
|
88733
|
-
|
|
88734
|
-
|
|
88735
|
-
|
|
88736
|
-
|
|
88737
|
-
|
|
88738
|
-
|
|
88739
|
-
|
|
88971
|
+
nfts: nfts.map((nft) => ({
|
|
88972
|
+
address: nft.address,
|
|
88973
|
+
name: nft.name,
|
|
88974
|
+
description: nft.description,
|
|
88975
|
+
image: nft.image,
|
|
88976
|
+
collection: nft.collection,
|
|
88977
|
+
attributes: nft.attributes,
|
|
88978
|
+
isOnSale: nft.isOnSale,
|
|
88979
|
+
isSoulbound: nft.isSoulbound
|
|
88980
|
+
})),
|
|
88981
|
+
count: nfts.length
|
|
88740
88982
|
}, null, 2)
|
|
88741
88983
|
}] };
|
|
88742
88984
|
} catch (error) {
|
|
@@ -88753,61 +88995,175 @@ function createMcpSwapTools(service) {
|
|
|
88753
88995
|
}
|
|
88754
88996
|
}
|
|
88755
88997
|
},
|
|
88756
|
-
|
|
88757
|
-
description: "
|
|
88758
|
-
inputSchema:
|
|
88998
|
+
get_nft: {
|
|
88999
|
+
description: "Get detailed information about a specific NFT by its address.",
|
|
89000
|
+
inputSchema: getNftSchema,
|
|
88759
89001
|
handler: async (args) => {
|
|
88760
|
-
|
|
88761
|
-
|
|
88762
|
-
|
|
88763
|
-
|
|
89002
|
+
try {
|
|
89003
|
+
const nft = await service.getNft(args.nftAddress);
|
|
89004
|
+
if (!nft) return {
|
|
89005
|
+
content: [{
|
|
89006
|
+
type: "text",
|
|
89007
|
+
text: JSON.stringify({
|
|
89008
|
+
success: false,
|
|
89009
|
+
error: "NFT not found"
|
|
89010
|
+
})
|
|
89011
|
+
}],
|
|
89012
|
+
isError: true
|
|
89013
|
+
};
|
|
89014
|
+
return { content: [{
|
|
88764
89015
|
type: "text",
|
|
88765
89016
|
text: JSON.stringify({
|
|
88766
|
-
success:
|
|
88767
|
-
|
|
88768
|
-
|
|
88769
|
-
|
|
88770
|
-
|
|
88771
|
-
|
|
88772
|
-
|
|
88773
|
-
|
|
89017
|
+
success: true,
|
|
89018
|
+
nft: {
|
|
89019
|
+
address: nft.address,
|
|
89020
|
+
name: nft.name,
|
|
89021
|
+
description: nft.description,
|
|
89022
|
+
image: nft.image,
|
|
89023
|
+
collection: nft.collection,
|
|
89024
|
+
attributes: nft.attributes,
|
|
89025
|
+
ownerAddress: nft.ownerAddress,
|
|
89026
|
+
isOnSale: nft.isOnSale,
|
|
89027
|
+
isSoulbound: nft.isSoulbound,
|
|
89028
|
+
saleContractAddress: nft.saleContractAddress
|
|
89029
|
+
}
|
|
89030
|
+
}, null, 2)
|
|
89031
|
+
}] };
|
|
89032
|
+
} catch (error) {
|
|
88774
89033
|
return {
|
|
88775
89034
|
content: [{
|
|
88776
89035
|
type: "text",
|
|
88777
89036
|
text: JSON.stringify({
|
|
88778
89037
|
success: false,
|
|
88779
|
-
error:
|
|
89038
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
88780
89039
|
})
|
|
88781
89040
|
}],
|
|
88782
89041
|
isError: true
|
|
88783
89042
|
};
|
|
88784
89043
|
}
|
|
88785
|
-
|
|
88786
|
-
|
|
88787
|
-
|
|
88788
|
-
|
|
89044
|
+
}
|
|
89045
|
+
},
|
|
89046
|
+
send_nft: {
|
|
89047
|
+
description: "Transfer an NFT from the wallet to another address.",
|
|
89048
|
+
inputSchema: sendNftSchema,
|
|
89049
|
+
handler: async (args) => {
|
|
89050
|
+
try {
|
|
89051
|
+
const result = await service.sendNft(args.nftAddress, args.toAddress, args.comment);
|
|
89052
|
+
return {
|
|
89053
|
+
content: [{
|
|
89054
|
+
type: "text",
|
|
89055
|
+
text: JSON.stringify({
|
|
89056
|
+
success: result.success,
|
|
89057
|
+
message: result.message,
|
|
89058
|
+
nftAddress: args.nftAddress,
|
|
89059
|
+
recipient: args.toAddress
|
|
89060
|
+
}, null, 2)
|
|
89061
|
+
}],
|
|
89062
|
+
isError: !result.success
|
|
89063
|
+
};
|
|
89064
|
+
} catch (error) {
|
|
89065
|
+
return {
|
|
89066
|
+
content: [{
|
|
89067
|
+
type: "text",
|
|
89068
|
+
text: JSON.stringify({
|
|
89069
|
+
success: false,
|
|
89070
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
89071
|
+
})
|
|
89072
|
+
}],
|
|
89073
|
+
isError: true
|
|
89074
|
+
};
|
|
89075
|
+
}
|
|
89076
|
+
}
|
|
89077
|
+
}
|
|
89078
|
+
};
|
|
89079
|
+
}
|
|
89080
|
+
|
|
89081
|
+
//#endregion
|
|
89082
|
+
//#region src/tools/dns-tools.ts
|
|
89083
|
+
/**
|
|
89084
|
+
* Copyright (c) TonTech.
|
|
89085
|
+
*
|
|
89086
|
+
* This source code is licensed under the MIT license found in the
|
|
89087
|
+
* LICENSE file in the root directory of this source tree.
|
|
89088
|
+
*
|
|
89089
|
+
*/
|
|
89090
|
+
const resolveDnsSchema = z.object({ domain: z.string().min(1).describe("TON DNS domain to resolve (e.g., \"foundation.ton\")") });
|
|
89091
|
+
const backResolveDnsSchema = z.object({ address: z.string().min(1).describe("TON wallet address to reverse resolve") });
|
|
89092
|
+
function createMcpDnsTools(service) {
|
|
89093
|
+
return {
|
|
89094
|
+
resolve_dns: {
|
|
89095
|
+
description: "Resolve a TON DNS domain (e.g., \"foundation.ton\") to a wallet address. Use this when the user provides a .ton domain instead of a raw address.",
|
|
89096
|
+
inputSchema: resolveDnsSchema,
|
|
89097
|
+
handler: async (args) => {
|
|
89098
|
+
try {
|
|
89099
|
+
const address = await service.resolveDns(args.domain);
|
|
89100
|
+
if (!address) return {
|
|
89101
|
+
content: [{
|
|
89102
|
+
type: "text",
|
|
89103
|
+
text: JSON.stringify({
|
|
89104
|
+
success: false,
|
|
89105
|
+
error: `Could not resolve domain "${args.domain}". The domain may not exist or may not have a wallet record.`
|
|
89106
|
+
})
|
|
89107
|
+
}],
|
|
89108
|
+
isError: true
|
|
89109
|
+
};
|
|
89110
|
+
return { content: [{
|
|
88789
89111
|
type: "text",
|
|
88790
89112
|
text: JSON.stringify({
|
|
88791
|
-
success:
|
|
88792
|
-
|
|
89113
|
+
success: true,
|
|
89114
|
+
domain: args.domain,
|
|
89115
|
+
address
|
|
89116
|
+
}, null, 2)
|
|
89117
|
+
}] };
|
|
89118
|
+
} catch (error) {
|
|
89119
|
+
return {
|
|
89120
|
+
content: [{
|
|
89121
|
+
type: "text",
|
|
89122
|
+
text: JSON.stringify({
|
|
89123
|
+
success: false,
|
|
89124
|
+
error: `Failed to resolve domain: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
89125
|
+
})
|
|
89126
|
+
}],
|
|
89127
|
+
isError: true
|
|
89128
|
+
};
|
|
89129
|
+
}
|
|
89130
|
+
}
|
|
89131
|
+
},
|
|
89132
|
+
back_resolve_dns: {
|
|
89133
|
+
description: "Reverse resolve a TON wallet address to its DNS domain (e.g., find the .ton domain associated with an address).",
|
|
89134
|
+
inputSchema: backResolveDnsSchema,
|
|
89135
|
+
handler: async (args) => {
|
|
89136
|
+
try {
|
|
89137
|
+
const domain = await service.backResolveDns(args.address);
|
|
89138
|
+
if (!domain) return { content: [{
|
|
89139
|
+
type: "text",
|
|
89140
|
+
text: JSON.stringify({
|
|
89141
|
+
success: true,
|
|
89142
|
+
address: args.address,
|
|
89143
|
+
domain: null,
|
|
89144
|
+
message: "No DNS domain found for this address."
|
|
88793
89145
|
})
|
|
88794
|
-
}]
|
|
88795
|
-
|
|
88796
|
-
|
|
88797
|
-
|
|
88798
|
-
|
|
88799
|
-
|
|
88800
|
-
|
|
88801
|
-
|
|
88802
|
-
|
|
88803
|
-
|
|
88804
|
-
|
|
88805
|
-
|
|
88806
|
-
|
|
88807
|
-
|
|
88808
|
-
|
|
88809
|
-
|
|
88810
|
-
|
|
89146
|
+
}] };
|
|
89147
|
+
return { content: [{
|
|
89148
|
+
type: "text",
|
|
89149
|
+
text: JSON.stringify({
|
|
89150
|
+
success: true,
|
|
89151
|
+
address: args.address,
|
|
89152
|
+
domain
|
|
89153
|
+
}, null, 2)
|
|
89154
|
+
}] };
|
|
89155
|
+
} catch (error) {
|
|
89156
|
+
return {
|
|
89157
|
+
content: [{
|
|
89158
|
+
type: "text",
|
|
89159
|
+
text: JSON.stringify({
|
|
89160
|
+
success: false,
|
|
89161
|
+
error: `Failed to reverse resolve address: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
89162
|
+
})
|
|
89163
|
+
}],
|
|
89164
|
+
isError: true
|
|
89165
|
+
};
|
|
89166
|
+
}
|
|
88811
89167
|
}
|
|
88812
89168
|
}
|
|
88813
89169
|
};
|
|
@@ -88864,6 +89220,9 @@ async function createTonWalletMCP(config) {
|
|
|
88864
89220
|
const balanceTools = createMcpBalanceTools(walletService);
|
|
88865
89221
|
const transferTools = createMcpTransferTools(walletService);
|
|
88866
89222
|
const swapTools = createMcpSwapTools(walletService);
|
|
89223
|
+
const knownJettonsTools = createMcpKnownJettonsTools();
|
|
89224
|
+
const nftTools = createMcpNftTools(walletService);
|
|
89225
|
+
const dnsTools = createMcpDnsTools(walletService);
|
|
88867
89226
|
const registerTool = (name, tool) => {
|
|
88868
89227
|
server.registerTool(name, {
|
|
88869
89228
|
description: tool.description,
|
|
@@ -88876,8 +89235,14 @@ async function createTonWalletMCP(config) {
|
|
|
88876
89235
|
registerTool("get_transactions", balanceTools.get_transactions);
|
|
88877
89236
|
registerTool("send_ton", transferTools.send_ton);
|
|
88878
89237
|
registerTool("send_jetton", transferTools.send_jetton);
|
|
89238
|
+
registerTool("send_raw_transaction", transferTools.send_raw_transaction);
|
|
88879
89239
|
registerTool("get_swap_quote", swapTools.get_swap_quote);
|
|
88880
|
-
registerTool("
|
|
89240
|
+
registerTool("get_known_jettons", knownJettonsTools.get_known_jettons);
|
|
89241
|
+
registerTool("get_nfts", nftTools.get_nfts);
|
|
89242
|
+
registerTool("get_nft", nftTools.get_nft);
|
|
89243
|
+
registerTool("send_nft", nftTools.send_nft);
|
|
89244
|
+
registerTool("resolve_dns", dnsTools.resolve_dns);
|
|
89245
|
+
registerTool("back_resolve_dns", dnsTools.back_resolve_dns);
|
|
88881
89246
|
return server;
|
|
88882
89247
|
}
|
|
88883
89248
|
|
package/dist/factory.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAQlE;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAChC;;;OAGG;IACH,MAAM,EAAE,aAAa,CAAC;IAEtB;;OAEG;IACH,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAE5B;;OAEG;IACH,QAAQ,CAAC,EAAE;QACP,OAAO,CAAC,EAAE,aAAa,CAAC;QACxB,OAAO,CAAC,EAAE,aAAa,CAAC;KAC3B,CAAC;CACL;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,SAAS,CAAC,CAuDxF;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,gBAAgB,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAE1F"}
|