0xf06c7567) and any available Toncoin amount to specified addresses. Plugins are separate smart contracts that can implement their own custom logic.
Here you can view wallet V4 source code.
Plugins
Installing third-party plugins can be dangerous and may lead to wallet drainage. Only install plugins from trusted sources and ensure you understand their functionality before installation.
Due to security reasons mentioned above, it is not possible to install plugins using TonConnect.
Plugin interaction flow
Persistent memory layout
Here we will break down wallet V4 storage structure.seqno: 32-bit long sequence number.wallet_id: 32-bit long wallet_id. This is a number that allows you to create multiple wallets with the same private key but different addresses.public_key: 256-bit long public key.plugins: dictionary containing plugins (may be empty).
Default value for wallet_id is
698983191 in V4, it is a partial hash of TON Mainnet zero state.Receiving internal messages
All previous versions of wallets had a straightforward implementation for receiving internal messages. They simply accepted incoming funds from any sender, ignoring the internal message body if present, or in other words, they had an emptyrecv_internal method. However, as mentioned earlier, the fourth version of the wallet introduces two additional available operations. Let’s take a look at the internal message body layout:
opcode(optional): 32-bit long operation code. This is an optional field. Any message containing less than 32 bits in the message body, an incorrect opcode, or a sender address that isn’t registered as a plugin will be considered a simple transfer, similar to previous wallet versions.query_id: 64-bit long integer. This field has no effect on the smart contract’s behavior; it is used to track chains of messages between contracts.
- opcode =
0x706c7567, request funds operation.amount: Coins amount of requested Toncoin.extra_currencies: dictionary containing the amount of requested extra currencies (may be empty).
- opcode =
0x64737472, request removal of the plugin that sent this message from the allowed list.
External message body layout
signature: 512-bit long Ed25519 signature.wallet_id: 32-bit long subwallet ID.valid_until: 32-bit long Unix time integer.msg_seqno: 32-bit long sequence number.opcode: 32-bit long operation code.- other data depending on the opcode
Simple send (opcode = 0x0)
The simple send operation processes a chain of messages, where each message contains a mode and a reference to the actual message cell: Processing logic:mode: up to four 8-bit integers defining the sending mode for each message.out_msg: up to four references to cells containing messages.
Deploy and install plugin (opcode = 0x1)
workchain: 8-bit workchain ID where the plugin will be deployedbalance: Initial Toncoin balance for the plugin contractstate_init: Cell reference containing the plugin’s initial state and codebody: Cell reference containing the deployment message body
Install plugin (opcode = 0x2)
wc_n_address: Combined 8-bit workchain ID and 256-bit plugin addressbalance: Toncoin amount to send during installationquery_id: 64-bit identifier for tracking the operation
Remove plugin (opcode = 0x3)
wc_n_address: Combined 8-bit workchain ID and 256-bit plugin addressbalance: Toncoin amountquery_id: 64-bit identifier for tracking the operation
0x0 opcode, similar to previous versions (see wallet overview for details on message layout). The 0x2 and 0x3 operations allow manipulation of the plugin dictionary.
Exit codes
| Exit code | Description |
|---|---|
| 33 | seqno check failed, replay protection triggered |
| 34 | wallet_id does not match the stored one |
| 35 | signature check failed |
| 36 | valid_until check failed, transaction attempted too late |
| 39 | Plugins dictionary manipulation failed (0x1-0x3 recv_external opcodes) |
| 80 | Not enough funds for the plugin funds request |
| 0 | Standard successful execution exit code. |
Get methods
int seqno()returns current stored seqno.int get_public_key()returns current stored public key.int get_subwallet_id()returns current subwallet ID.int is_plugin_installed(int wc, int addr_hash)checks if plugin with defined workchain_id and address hash is installed. Returns-1(true) if the plugin is installed,0(false) if not installed.tuple get_plugin_list()returns list of plugins.