105 lines
3.6 KiB
TypeScript
105 lines
3.6 KiB
TypeScript
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'));
|
|
}
|