Skip to content

feat(stdlib): add jetton support #2509

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

Draft
wants to merge 34 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
9f93595
add stub jetton stdlib
Kaladin13 Mar 26, 2025
9b2a47f
add jetton tester
Kaladin13 Mar 27, 2025
49839ae
add moduled jetton resolver
Kaladin13 Mar 27, 2025
7279401
jetton sender tests
Kaladin13 Mar 27, 2025
8a1f5c9
add draft comments
Kaladin13 Mar 27, 2025
feeba36
spell
Kaladin13 Mar 27, 2025
260b6e5
more spell
Kaladin13 Mar 27, 2025
8c63780
Merge remote-tracking branch 'origin/main' into kaladin13/jetton-std
Kaladin13 Mar 27, 2025
1da3dfb
rollback
Kaladin13 Mar 27, 2025
0a64ba3
change export
Kaladin13 Mar 27, 2025
f6a4d77
Merge remote-tracking branch 'origin/main' into kaladin13/jetton-std
Kaladin13 Mar 27, 2025
fe3a7c3
refactor benchmarks to use stdlib jettons
Kaladin13 Mar 27, 2025
947c20d
add tep-74 and tep-89 code docs
Kaladin13 Mar 28, 2025
adaca18
add more docs to jetton messages
Kaladin13 Mar 28, 2025
b50e3e5
fix more naming
Kaladin13 Mar 28, 2025
94fb7e5
stdlib
Kaladin13 Mar 28, 2025
da9d1da
edit jetton cookbook page
Kaladin13 Mar 28, 2025
2a32d8a
add stdlib entry
Kaladin13 Mar 28, 2025
34516e2
Merge branch 'main' into kaladin13/jetton-std
Kaladin13 Mar 28, 2025
9128f88
fix doc code blocks
Kaladin13 Mar 28, 2025
6a9b809
Merge remote-tracking branch 'origin/main' into kaladin13/jetton-std
Kaladin13 Apr 1, 2025
250a2d8
paths
Kaladin13 Apr 1, 2025
cae9d88
Merge branch 'main' into kaladin13/jetton-std
novusnota Apr 2, 2025
07be5ce
Merge branch 'main' into kaladin13/jetton-std
novusnota Apr 3, 2025
84ec297
YEA$$$$$$$$$$$$$$$$$$
novusnota Apr 3, 2025
7f3150f
Merge remote-tracking branch 'origin/main' into kaladin13/jetton-std
novusnota Apr 9, 2025
a867ba1
benches!
novusnota Apr 9, 2025
049666b
suggestions from the code review
novusnota Apr 10, 2025
a7cb13f
Merge branch 'main' into kaladin13/jetton-std
novusnota Apr 10, 2025
be49c8f
apply suggestions from the code review
novusnota Apr 11, 2025
22400d4
Merge branch 'main' into kaladin13/jetton-std
novusnota Apr 11, 2025
8ce60a2
apply suggestions from the code review
novusnota Apr 11, 2025
a7d52e6
Merge branch 'main' into kaladin13/jetton-std
novusnota Apr 11, 2025
6046c00
port opcode from the governance jetton
novusnota May 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,10 @@ export default defineConfig({
{ slug: 'ref/stdlib-content' },
{ slug: 'ref/stdlib-deploy' },
{ slug: 'ref/stdlib-dns' },
{
slug: 'ref/stdlib-jetton-interface',
badge: { variant: 'tip', text: 'new' },
},
{ slug: 'ref/stdlib-ownable' },
{ slug: 'ref/stdlib-stoppable' },
],
Expand Down
4 changes: 2 additions & 2 deletions docs/src/content/docs/book/cells.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,8 @@ To give a real-world example, imagine that you need to notice and react to inbou
```tact /remaining/
message(0x7362d09c) JettonTransferNotification {
// Unique identifier used to trace transactions across multiple contracts
// Defaults to 0, which means we don't mark messages to trace their chains
queryId: Int as uint64 = 0;
// Setting it to 0 means we don't mark messages to trace requests
queryId: Int as uint64;

// Amount of Jettons transferred
amount: Int as coins;
Expand Down
95 changes: 22 additions & 73 deletions docs/src/content/docs/book/learn-tact-in-y-minutes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -1228,18 +1228,22 @@ For more, refer to the following resources:
#### JettonWallet

```tact
/// This library provides primary and auxiliary structures
/// and utilities for working with the Jetton standard.
import "@stdlib/jetton-interface";

/// Child contract per each holder of N amount of given Jetton (token)
contract JettonWallet(
/// Balance in Jettons.
balance: Int as coins,

/// Address of the user's wallet which owns this JettonWallet, and messages
/// from whom should be recognized and fully processed.
owner: Address,

/// Address of the main minting contract,
/// which deployed this Jetton wallet for the specific user's wallet.
master: Address,

/// Balance in Jettons.
balance: Int as coins,
) {
/// Registers a binary receiver of the JettonTransfer message body.
/// Transfers Jettons from the current owner to the target user's JettonWallet.
Expand Down Expand Up @@ -1271,11 +1275,11 @@ contract JettonWallet(

// Transfer Jetton from the current owner to the target user's JettonWallet.
// If that wallet does not exist, it is deployed on-chain in the same transfer.
deploy(DeployParameters{
deploy(DeployParameters {
value: 0,
mode: SendRemainingValue,
bounce: true,
body: JettonTransferInternal{
body: JettonTransferInternal {
queryId: msg.queryId,
amount: msg.amount,
sender: self.owner,
Expand All @@ -1285,7 +1289,7 @@ contract JettonWallet(
}.toCell(),
// Notice that we do not need to explicitly specify the Address,
// because it will be computed on the fly from the initial package.
init: initOf JettonWallet(0, msg.destination, self.master),
init: initOf JettonWallet(msg.destination, self.master, 0),
});
}

Expand All @@ -1297,7 +1301,7 @@ contract JettonWallet(

// This message should come only from JettonMinter,
// or from other JettonWallet.
let wallet: StateInit = initOf JettonWallet(0, msg.sender, self.master);
let wallet: StateInit = initOf JettonWallet(msg.sender, self.master, 0);
if (sender() != contractAddress(wallet)) {
require(self.master == sender(), "Incorrect sender");
}
Expand All @@ -1311,12 +1315,12 @@ contract JettonWallet(
if (msg.forwardTonAmount > 0) {
let fwdFee: Int = ctx.readForwardFee();
msgValue -= msg.forwardTonAmount + fwdFee;
message(MessageParameters{
message(MessageParameters {
to: self.owner,
value: msg.forwardTonAmount,
mode: SendPayGasSeparately,
bounce: false,
body: JettonNotification{
body: JettonTransferNotification {
queryId: msg.queryId,
amount: msg.amount,
sender: msg.sender,
Expand All @@ -1331,12 +1335,12 @@ contract JettonWallet(

// And forward excesses (cashback) to the original sender.
if (msg.responseDestination != null && msgValue > 0) {
message(MessageParameters{
message(MessageParameters {
to: msg.responseDestination!!,
value: msgValue,
mode: SendRemainingBalance + SendIgnoreErrors,
bounce: false,
body: JettonExcesses{ queryId: msg.queryId }.toCell(),
body: JettonExcesses { queryId: msg.queryId }.toCell(),
});
}
}
Expand All @@ -1361,12 +1365,12 @@ contract JettonWallet(

// Send a message to the JettonMinter to reduce the total supply
// of the Jettons. That is, to burn some.
message(MessageParameters{
message(MessageParameters {
to: self.master,
value: 0,
mode: SendRemainingValue,
bounce: true,
body: JettonBurnNotification{
body: JettonBurnNotification {
queryId: msg.queryId,
amount: msg.amount,
sender: self.owner,
Expand All @@ -1378,80 +1382,25 @@ contract JettonWallet(
/// Registers a bounced binary receiver of messages
/// with the JettonTransferInternal opcode.
/// It handles such outgoing messages that bounced back to this contract.
bounced(msg: bounced<JettonTransferInternal>) { self.balance += msg.amount; }
bounced(msg: bounced<JettonTransferInternal>) { self.balance += msg.amount }

/// Registers a bounced binary receiver of messages
/// with the JettonBurnNotification opcode.
/// It handles such outgoing messages that bounced back to this contract.
bounced(msg: bounced<JettonBurnNotification>) { self.balance += msg.amount; }
bounced(msg: bounced<JettonBurnNotification>) { self.balance += msg.amount }

/// An off-chain getter function which returns useful data about this wallet.
get fun get_wallet_data(): JettonWalletData {
return JettonWalletData{
return JettonWalletData {
balance: self.balance,
owner: self.owner,
master: self.master,
minter: self.master,
code: myCode(),
};
}
}

//
// Helper structs, message structs and constants,
// which would otherwise be imported from another file
//

struct JettonWalletData {
balance: Int;
owner: Address;
master: Address;
code: Cell;
}

message(0xf8a7ea5) JettonTransfer {
queryId: Int as uint64;
amount: Int as coins;
destination: Address;
responseDestination: Address?;
customPayload: Cell?;
forwardTonAmount: Int as coins;
forwardPayload: Slice as remaining;
}

message(0x178d4519) JettonTransferInternal {
queryId: Int as uint64;
amount: Int as coins;
sender: Address;
responseDestination: Address?;
forwardTonAmount: Int as coins;
forwardPayload: Slice as remaining;
}

message(0x7362d09c) JettonNotification {
queryId: Int as uint64;
amount: Int as coins;
sender: Address;
forwardPayload: Slice as remaining;
}

message(0x595f07bc) JettonBurn {
queryId: Int as uint64;
amount: Int as coins;
responseDestination: Address?;
customPayload: Cell?;
}

message(0x7bdd97de) JettonBurnNotification {
queryId: Int as uint64;
amount: Int as coins;
sender: Address;
responseDestination: Address?;
}

message(0xd53276db) JettonExcesses {
queryId: Int as uint64;
}

// Helper constants, which would otherwise be imported from another file
const GAS_FOR_BURN: Int = 6000;
const GAS_FOR_TRANSFER: Int = 8000;
const MIN_TONCOIN_FOR_STORAGE: Int = ton("0.01");
Expand Down
6 changes: 3 additions & 3 deletions docs/src/content/docs/cookbook/dexes/dedust.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ The guides below use the [Jetton vault](https://docs.dedust.io/docs/concepts#vau
/// https://docs.dedust.io/reference/tlb-schemes#message-swap
message(0xea06185d) NativeSwap {
// Unique identifier used to trace transactions across multiple contracts
// Defaults to 0, which means we don't mark messages to trace their chains
// Defaults to 0, which means we don't mark messages to trace requests
queryId: Int as uint64 = 0;

// Toncoin amount for the swap
Expand Down Expand Up @@ -156,7 +156,7 @@ fun swapJetton(targetJettonWalletAddress: Address) {
value: ton("0.3"),
body: JettonTransfer{
// Unique identifier used to trace transactions across multiple contracts.
// Set to 0, which means we don't mark messages to trace their chains.
// Set to 0, which means we don't mark messages to trace requests.
queryId: 0,
// Jetton amount for the swap.
amount: 10, // NOTE: change to your amount
Expand Down Expand Up @@ -260,7 +260,7 @@ message(0x40e108d6) JettonDepositLiquidity {
/// https://docs.dedust.io/reference/tlb-schemes#message-deposit_liquidity
message(0xd55e4686) NativeDepositLiquidity {
// Unique identifier used to trace transactions across multiple contracts
// Defaults to 0, which means messages are not marked to trace their chains
// Defaults to 0, which means messages are not marked to trace requests
queryId: Int as uint64 = 0;

// Toncoin amount for the deposit
Expand Down
2 changes: 1 addition & 1 deletion docs/src/content/docs/cookbook/dexes/stonfi.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ To swap Toncoin to Jetton, STON.fi requires the use of a so-called proxy Toncoin
/// https://github.com/ston-fi/sdk/blob/786ece758794bd5c575db8b38f5e5de19f43f0d1/packages/sdk/src/contracts/pTON/v2_1/PtonV2_1.ts
message(0x01f3835d) ProxyToncoinTransfer {
// Unique identifier used to trace transactions across multiple contracts
// Defaults to 0, which means we don't mark messages to trace their chains
// Defaults to 0, which means we don't mark messages to trace requests
queryId: Int as uint64 = 0;

// Toncoin amount for the swap
Expand Down
Loading