Подпишись на канал фаундера и разработчика экосистемы tonpie
SyntaxError: Неожиданный токен при попытке передачи JETTONS
-
Эй, я пытаюсь передать 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() } ```