Эй, я пытаюсь передать 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()
}
```
Оригинал вопроса