import { Address, toNano } from '@ton/core'; import { Gift, Content, storeContent, storeNotification } from '../build/Gift/Gift_Gift'; import { createNetworkProvider, NetworkProvider, sleep, UIProvider } from '@ton/blueprint'; import { mnemonicToPrivateKey, sign } from '@ton/crypto'; import { TonClient, TonClientParameters, WalletContractV4, beginCell } from '@ton/ton'; import { signatureOf } from '@tact-lang/compiler'; import { Sign } from 'crypto'; import { decryptContent, encryptContent, getRecipientPublicKey } from './crypto/crypto'; export const client = new TonClient({ endpoint: 'https://testnet.toncenter.com/api/v2/jsonRPC', }); export async function getKeypair() { let kp = await mnemonicToPrivateKey(process.env.WALLET_MNEMONIC!!.split(' ')); return kp; } export async function getWallet(client: TonClient) { let kp = await getKeypair(); let walletContract = client.open( WalletContractV4.create({ workchain: 0, publicKey: kp.publicKey, }), ); return walletContract; } export function myAddress() { return Address.parse(process.env.WALLET_ADDRESS!!); } export async function deployGift(np: NetworkProvider, recipient: Address, content: string) { let kp = await getKeypair(); let walletContract = await getWallet(client); let recipientPublicKey = await getRecipientPublicKey(recipient); let encryptedContent = await encryptContent(kp.secretKey, recipientPublicKey, content); const gift = np.open( await Gift.fromInit( { $$type: 'Content' as const, content: Buffer.from(encryptedContent).toString('base64') }, recipient, ), ); await np.sender().send({ to: gift.address, value: toNano('0.05'), init: gift.init, }); // try 45 times with 2 seconds delay to get gift deployed for (let i = 0; i < 45; i++) { try { if ((await client.getContractState(gift.address)).state == 'active') { return gift; } } catch (e) { await new Promise((resolve) => setTimeout(resolve, 2000)); } } throw new Error('Gift deployment failed after multiple attempts'); } export async function getListOfGifts(address: Address) { let notificationHash = beginCell() .store(storeNotification({ $$type: 'Notification' })) .endCell() .hash(); let listOfGifts = await client .getTransactions(address, { limit: 50, }) .then((transactions) => transactions.filter( (tx) => tx.inMessage != null && tx.inMessage?.body.hash().equals(notificationHash) && tx.inMessage.info.src, ), ); return listOfGifts.map((tx) => { let giftContractAddress = tx.inMessage!.info.src! as Address; return { gift: Gift.fromAddress(giftContractAddress), address: giftContractAddress, time: tx.now || 0, }; }); } export async function readGift(gift: Gift) { let delay = 1000; let contentMethod = await client.runMethod(gift.address, 'content'); await sleep(delay); let content = contentMethod.stack.readString() || ''; let senderMethod = await client.runMethod(gift.address, 'owner'); await sleep(delay); let senderAddress = senderMethod.stack.readAddress(); let senderPublicKey = await getRecipientPublicKey(senderAddress); await sleep(delay); console.log(`Gift content (encrypted): ${content}`); await sleep(delay); return decryptContent((await getKeypair()).secretKey, senderPublicKey, Buffer.from(content, 'base64')); }