Эй, я пытаюсь передать Jettons с помощью функции firebase. Однако я действительно страдаю от завершения функции. Я не уверен, чего мне не хватает, может быть, каких-то адресов? Я также не уверен, как мне прочитать эту ошибку.
Вот несколько адресов (я использую openmask, а мнемоника - начальная фраза main_wallet) main_wallet_address: 0QBdd6N85lIBz193LTHESG8m9XVlH0owI6nn4hdXGy6S2u7N (с jettons) jetton_wallet: EQBh5qTitSdsZmHuHutn5_cqdwaPVHzYgSc3dRoRzAwR4dTr jetton_minter: EQAtwEufBNdM_YkCaz6fEA4AkddgcEouTrEwZJB4NNUyz3Te (символ: ТЕСТ)
Прямо сейчас я получаю:
{"severity":"INFO","message":"my address 0:5d77a37ce65201cf5f772d31c4486f26f575651f4a3023a9e7e217571b2e92da"}
>  SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON
>      at JSON.parse (<anonymous>)
>      at parseJSONFromBytes (node:internal/deps/undici/undici:5418:19)
>      at successSteps (node:internal/deps/undici/undici:5389:27)
>      at fullyReadBody (node:internal/deps/undici/undici:1500:9)
>      at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
>      at async specConsumeBody (node:internal/deps/undici/undici:5398:7)
>      at async HttpProvider.call2 (C:\Users\style\Desktop\tonstars\functions\node_modules\tonweb\src\providers\index.js:149:24)
>      at async JettonMinter.getJettonData (C:\Users\style\Desktop\tonstars\functions\node_modules\tonweb\src\contract\token\ft\JettonMinter.js:87:24)
>      at async SendTokens (C:\Users\style\Desktop\tonstars\functions\lib\index.js:76:16)
>      at async C:\Users\style\Desktop\tonstars\functions\lib\index.js:53:15
>  {"severity":"ERROR","message":"SyntaxError: Unexpected token '<', \"<!DOCTYPE \"... is not valid JSON\n    at JSON.parse (<anonymous>)\n    at parseJSONFromBytes (node:internal/deps/undici/undici:5418:19)\n    at successSteps (node:internal/deps/undici/undici:5389:27)\n    at fullyReadBody (node:internal/deps/undici/undici:1500:9)\n    at process.processTicksAndRejections (nodt async HttpProvider.call2 (C:\\Users\\style\\Desktop\\tonsumeBody (node:internal/deps/undici/undici:5398:7)\n    at async HttpProvider.call2 (C:\\Users\\style\\Desktop\\tonstars\\functions\\nstars\\functions\\node_modules\\tonweb\\src\\providers\\   at async JettonMinter.getJettonData (C:\\Users\\style\\Desktop\\tonstars\\functions\\node_modules\\tonweb\\src\\contract\\token\\ftindex.js:149:24)\n    at async JettonMinter.getJettonDataers\\style\\Desktop\\tonstars\\functions\\lib\\index.js:76:16)\n    at async C:\\Users\\style\\Desktop\\tonstars\\functions\\lib\\inde (C:\\Users\\style\\Desktop\\tonstars\\functions\\node_modules\\tonweb\\src\\contract\\token\\ft\\JettonMinter.js:rror: Unexpected token '<', \"<!DOCTYPE \"... is not valid JSON\n    at JSON.parse (<anonymous>)\n    at parseJSONFromBytes (node:inte87:24)\n    at async SendTokens (C:\\Users\\style\\Desktode:internal/deps/undici/undici:5389:27)\n    at fullyReadBody (node:internal/deps/undici/undici:1500:9)\n    at process.processTicksAnp\\tonstars\\functions\\lib\\index.js:76:16)\n    at asyn at async specConsumeBody (node:internal/deps/undici/undici:5398:7)\n    at async HttpProvider.call2 (C:\\Users\\style\\Desktop\\tonstc C:\\Users\\style\\Desktop\\tonstars\\functions\\lib\\inex.js:149:24)\n    at async JettonMinter.getJettonData (C:\\Users\\style\\Desktop\\tonstars\\functions\\node_modules\\tonweb\\src\\condex.js:53:15"}
и вот код
import TonWeb from "tonweb";
import { mnemonicToKeyPair, KeyPair } from "tonweb-mnemonic";
import { onCall } from "firebase-functions/v2/https";
import * as logger from "firebase-functions/logger";
import { defineString } from "firebase-functions/params";
import {mnemonicToWalletKey} from "@ton/crypto";
import admin from "firebase-admin";
import { WalletV3ContractR2 } from "tonweb/dist/types/contract/wallet/v3/wallet-v3-contract-r2";
const app = admin.initializeApp()
const db = admin.firestore(app);
const walletMnemonic = defineString("WALLET_MNEMONIC");  // main wallet mnemonic
const walletPassword = defineString("WALLET_PASSWORD");  // main wallet password
const apiKey = defineString("API_KEY");                  // api key
type WithdrawJettonsRequest = {
    boc: string;
}
type TransactionData = {
    amount: number;
    nanoAmount: number;
    jettonsAmount: number;
    jettonsNanoAmount: number;
    toAddress: string;
    status: "pending" | "success" | "failed";
    timestamp: number;
};
exports.withdrawJettons = onCall(async (request) => {
    const data = request.data as WithdrawJettonsRequest;
    const transactionRef = db.collection("transactions").doc(data.boc);
    const transactionSnapshot = await transactionRef.get();
    if (!transactionSnapshot.exists) {
        throw new Error(`Transaction ${data.boc} not found`);
    }
    const transactionData = transactionSnapshot.data() as TransactionData;
    if (transactionData.status !== "pending") {
        throw new Error(`Transaction ${data.boc} is not pending`);
    }
    const tonweb = new TonWeb(new TonWeb.HttpProvider("https://testnet.toncenter.com/api/v2/jsonRPC", { apiKey: apiKey.value() }));
    const r = await SendTokens(transactionData, tonweb);
    await transactionRef.update({
        status: "success",
    })
    logger.info("Transaction updated")
    return r
});
export const SendTokens = async (transactionData: TransactionData, tonweb: TonWeb) => {
    console.log(walletMnemonic.value())
    const keyPair = await mnemonicToWalletKey(walletMnemonic.value().split(" "));
  
    const WalletClass = tonweb.wallet.all.v3R2;
  
    const wallet = new WalletClass(tonweb.provider, {
      publicKey: keyPair.publicKey
    });
  
    const address = await wallet.getAddress();
  
    logger.info("my address", address.toString());
  
    const jettonMinter = new TonWeb.token.jetton.JettonMinter(tonweb.provider, {
      adminAddress: address,
      jettonContentUri: "",
      jettonWalletCodeHex: "TEST",
      address: "0:2dc04b9f04d74cfd89026b3e9f100e0091d760704a2e4eb13064907834d532cf"
    });
  
    let data;
    try {
        data = await jettonMinter.getJettonData();
    } catch (e) {
        console.log(e)
        logger.error(e);
        throw e;
    }
  
    logger.info('Total supply:', data.totalSupply.toString());
    logger.info('URI to off-chain metadata:', data.jettonContentUri);
    // logger.info('Owner address:', data.adminAddress(true, true, true));
  
    const jettonWalletAddress = await jettonMinter.getJettonWalletAddress(address);
  
    logger.info("jetton wallet address", jettonWalletAddress.toString())
  
    const jettonWallet = new TonWeb.token.jetton.JettonWallet(tonweb.provider, {
      address: jettonWalletAddress
    });
  
    const jettonData = await jettonWallet.getData();
  
    logger.info("minter address", jettonData.jettonMinterAddress.toString());
    logger.info('Jetton wallet address:', address.toString(true, true, true));
  
    const seqno = (await wallet.methods.seqno().call()) || 0;
  
    logger.info('Secno:', seqno);
  
    const comment = new Uint8Array([... new Uint8Array(4), ... new TextEncoder().encode('TS pre-sale')]);
  
    await wallet.methods.transfer({
      secretKey: keyPair.secretKey,
      toAddress: jettonWalletAddress, // address of Jetton wallet of Jetton sender
      amount: TonWeb.utils.toNano('0.05'), // total amount of TONs attached to the transfer message
      seqno: seqno,
      payload: await jettonWallet.createTransferBody({
        queryId: seqno,
        jettonAmount: transactionData.jettonsNanoAmount, // Jetton amount (in basic indivisible units)
        toAddress: new TonWeb.utils.Address(transactionData.toAddress), // recepient user's wallet address (not Jetton wallet)
        forwardAmount: TonWeb.utils.toNano('0.01'), // some amount of TONs to invoke Transfer notification message
        forwardPayload: comment, // text comment for Transfer notification message
        responseAddress: address // return the TONs after deducting commissions back to the sender's wallet address
      }),
      sendMode: 3,
    }).send()
  }
	```
Оригинал вопроса