-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to create jetton transfer? #44
Comments
I think this is useful for you. import { beginCell, Address, TonClient, WalletContractV4, internal, external, storeMessage, toNano } from '@ton/ton';
import nacl from 'tweetnacl';
const apiKey = '...';
const client = new TonClient({ endpoint: 'https://toncenter.com/api/v2/jsonRPC', apiKey });
const usdtTokenContractAddress = 'EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs';
const toAddress = 'UQBcGtGIHLIQJuUHRRfWLhQxUJF4p49ywJyBdDr7UKTK60p9';
async function getUserJettonWalletAddress(userAddress: string, jettonMasterAddress: string) {
const userAddressCell = beginCell().storeAddress(Address.parse(userAddress)).endCell();
const response = await client.runMethod(Address.parse(jettonMasterAddress), 'get_wallet_address', [
{ type: 'slice', cell: userAddressCell },
]);
return response.stack.readAddress();
}
(async () => {
// Generate keyPair from mnemonic/secret key
const keyPair = nacl.sign.keyPair.fromSecretKey(Buffer.from('SecretKey', 'hex'));
const secretKey = Buffer.from(keyPair.secretKey);
const publicKey = Buffer.from(keyPair.publicKey);
const workchain = 0; // Usually you need a workchain 0
const wallet = WalletContractV4.create({ workchain, publicKey });
const address = wallet.address.toString({ urlSafe: true, bounceable: false, testOnly: false });
const contract = client.open(wallet);
const balance = await contract.getBalance();
console.log({ address, balance });
const seqno = await contract.getSeqno();
console.log({ address, seqno });
const { init } = contract;
const contractDeployed = await client.isContractDeployed(Address.parse(address));
let neededInit: null | typeof init = null;
if (init && !contractDeployed) {
neededInit = init;
}
const jettonWalletAddress = await getUserJettonWalletAddress(address, usdtTokenContractAddress);
// Comment payload
// const forwardPayload = beginCell()
// .storeUint(0, 32) // 0 opcode means we have a comment
// .storeStringTail('Hello, TON!')
// .endCell();
const messageBody = beginCell()
.storeUint(0x0f8a7ea5, 32) // opcode for jetton transfer
.storeUint(0, 64) // query id
.storeCoins(5001) // jetton amount, amount * 10^9
.storeAddress(toAddress)
.storeAddress(toAddress) // response destination
.storeBit(0) // no custom payload
.storeCoins(0) // forward amount - if > 0, will send notification message
.storeBit(0) // we store forwardPayload as a reference, set 1 and uncomment next line for have a comment
// .storeRef(forwardPayload)
.endCell();
const internalMessage = internal({
to: jettonWalletAddress,
value: toNano('0.1'),
bounce: true,
body: messageBody,
});
const body = wallet.createTransfer({
seqno,
secretKey,
messages: [internalMessage],
});
const externalMessage = external({
to: address,
init: neededInit,
body,
});
const externalMessageCell = beginCell().store(storeMessage(externalMessage)).endCell();
const signedTransaction = externalMessageCell.toBoc();
const hash = externalMessageCell.hash().toString('hex');
console.log('hash:', hash);
await client.sendFile(signedTransaction);
})(); |
If you need sync method of getUserJettonWalletAddress look: https://docs.ton.org/develop/dapps/cookbook#how-to-calculate-users-jetton-wallet-address-offline |
Error
|
If you still cant transfer jettons, here is project which do it. |
@vserpokryl Hello, I have a question about Jetton transfer code, why do I need to use |
@LI-YONG-QI const externalMessage = external({
to: address,
init: neededInit,
body: wallet.createTransfer({
seqno,
secretKey,
messages: [internalMessage],
}),
}); |
@vserpokryl Thanks for your response Here is the source code of export function createWalletTransferV4<T extends Wallet4SendArgsSignable | Wallet4SendArgsSigned>(
args: T & { sendMode: number, walletId: number }
) {
// Check number of messages
if (args.messages.length > 4) {
throw Error("Maximum number of messages in a single transfer is 4");
}
let signingMessage = beginCell()
.storeUint(args.walletId, 32);
if (args.seqno === 0) {
for (let i = 0; i < 32; i++) {
signingMessage.storeBit(1);
}
} else {
signingMessage.storeUint(args.timeout || Math.floor(Date.now() / 1e3) + 60, 32); // Default timeout: 60 seconds
}
signingMessage.storeUint(args.seqno, 32);
signingMessage.storeUint(0, 8); // Simple order
for (let m of args.messages) {
signingMessage.storeUint(args.sendMode, 8);
signingMessage.storeRef(beginCell().store(storeMessageRelaxed(m)));
}
return signPayload(
args,
signingMessage,
packSignatureToFront,
) as T extends Wallet4SendArgsSignable ? Promise<Cell> : Cell;
} I knew the Cell was serialized by TL-B scheme in TON, but I don't know what is TL-B scheme of this Cell in |
import "@stdlib/deploy"; contract InitiateJettonTransfer with Deployable {
} I tried this but my transaction still failed how to fix? |
When you run the above code, the following error occurs. contractDeployed false; |
I solved the problem Thank you |
You are great!!! |
Hello I need urgent help on how to import my Jetton transaction history |
@Omokami, hello! You can use https://tonapi.io for this. For example getAccountJettonsHistory - https://tonapi.io/api-v2#operations-Accounts-getAccountJettonsHistory |
Thank you but, I would appreciate it if you could explain how to get the account ID and jetton ID. |
@Omokami If you need all history of jetton transfers for all tokens use getAccountJettonsHistory (/v2/accounts/{account_id}/jettons/history) |
@Omokami |
Thank you very much |
Could you please provide sample code (in the Readme?) how to create jetton/token transfer transactio?
The text was updated successfully, but these errors were encountered: