SignData in TON via TonConnect - A Developer Guide
Learn how to use SignData method in TonConnect to request cryptographic signatures from user wallets for secure off-chain and on-chain verification.
When it comes to critical actions, a simple button press just doesn't cut it. Real consent feels like your wallet standing tall and declaring: "Yes, it's me! And I approve this!"
A signature is the real deal: cryptographic, verifiable, secure. You can sign anything — text, bytes, or cells. The signature can be verified off-chain in your dApp or passed into a smart contract for on-chain logic.
What is SignData and Why It Matters
Any action where the user must consciously and explicitly confirm their intent – like updating public profile information, linking a new email or phone number, or accepting DAO terms – deserves something more robust than just a click.
SignData lets your dApp request a cryptographic signature – from the user's wallet – on arbitrary content. The user sees exactly what they are signing and can either approve or decline. The signature is generated using the same private key that signs TON transactions, but it provides no direct access to funds.
For a dApp, this signature is a way to secure critical actions, verify a user's real intent, and – if needed – pass validated data into a smart contract for on-chain use.
If you don't clearly get what an Cell, TL-B, or public key is? Read the glossary below
Choosing the Right Format
1. Text
Use this when the data is human-readable.
Pros:
- The user sees exactly what they are signing.
- Simple to implement.
- Perfect for off-chain confirmations.
Example:
{
type: 'text',
text: 'I confirm deletion of my account and all associated data.'
}2. Binary
Use this when signing a hash, arbitrary bytes, or a file.
Pros:
- Useful for generating digital receipts, hashed content references, etc.
- Works when the content isn't human-readable or shouldn't be shown.
Example:
{
type: 'binary',
bytes: '1Z/SGh+3HFMKlVHSkN91DpcCzT4C5jzHT3sA/24C5A=='
}3. Cell
Use this if the signed data should be verifiable and restorable inside a smart contract.
Pros:
- Smart contracts can validate the signature during execution.
- Supports structured data via TL-B schemas.
Example:
{
type: 'cell',
schema: 'message#_ text:string = Message;',
cell: 'te6ccgEBAQEAVwAAqg+KfqVUbeTvKqB4h0AcnDgIAZucsOi6TLrf...'
}Clarification on Root Type: If the TL-B schema provided in SignData.cell.schema defines multiple types (for example, one primary type along with auxiliary helper types), the last type definition in the schema is treated as the root type for serialization and deserialization. In practice, this means the cell's content is parsed as an instance of the final type declared in the schema.
How to Request a Signature via TonConnect
const result = await tonConnectUi.signData({
type: 'text',
text: 'I confirm this action.',
});TonConnect handles the request and shows the prompt in the user's wallet. They either sign or decline.
You receive:
{
signature: 'base64-ed25519-signature',
address: '0:9a...',
timestamp: 1710000000,
domain: 'your-app.com',
payload: {
type: 'text',
text: 'I confirm this action.'
}
}How the Signature Is Built
For text and binary
- The message is constructed:
0xffff ++ "ton-connect/sign-data/" ++ Address ++ AppDomain ++ Timestamp ++ Payload- Components:
Address: wallet address (workchain + hash)AppDomain: dApp domain as UTF-8 string with lengthTimestamp: time of signingPayload:- Prefix
txt/bin - Length
- Text (utf-8 encoded) or bytes
- Prefix
- Then:
Ed25519.sign(sha256(message), privateKey)For cell
- A Cell is built:
beginCell()
.storeUint(0x75569022, 32)
.storeUint(crc32(schema), 32)
.storeUint(timestamp, 64)
.storeAddress(userWalletAddress)
.storeStringRefTail(appDomain)
.storeRef(cell)- The hash of this Cell is signed:
Ed25519.sign(payload.hash(), privateKey)🔥 Example signing in JS: https://github.com/mois-ilya/ton-sign-data-reference
How to Verify the Signature
In JavaScript (off-chain)
For text and binary, you can reconstruct the message:
- Rebuild the byte array exactly as described above.
- Retrieve the public key (from TonConnect or known in advance).
- Verify:
import nacl from 'tweetnacl';
const isValid = await nacl.sign.detached.verify(hash, signature, publicKey);Important: Always ensure that result.address matches the wallet you requested the signature from. Otherwise, an attacker could swap in a valid signature from a different wallet.
🔥 Example verification in JS: https://github.com/mois-ilya/ton-sign-data-reference
In a Smart Contract (on-chain)
For the cell format, smart contracts can verify the signature directly.
They must validate:
- Prefix:
0x75569022 - Schema hash matches
- Timestamp is recent
- Address matches
- App domain matches
- Signature is valid using
ed25519
📄 check_signature in standard library
🔥 On-chain example in FunC: https://github.com/p0lunin/sign-data-contract-verify-example
TL;DR
The SignData method in TonConnect is a secure way for a dApp to request a user's cryptographic signature on text, bytes, or TON cells – directly through their wallet. It's not a transaction, but a confirmation that can be verified off-chain or on-chain.
- Users see what they sign (if it's text or a proper TL-B schema).
- Signature uses the same key as for transactions, but doesn't send anything.
- Verification works anywhere – on your backend or inside a smart contract.
| Format | What's Signed | Wallet UI | Use Case |
|---|---|---|---|
text | Human-readable message | Displayed as-is | Action confirmation, agreements |
binary | Bytes / hashes / identifiers | Shows warning | Document hashes, TX IDs |
cell | Cell with TL-B schema | Schema + warning or content | Smart contract validation |
If you're building a dApp that needs real user consent and want to verify it without extra hassle – SignData gets the job done.
Useful Links
- Demo dApp to test
signDatatonkeeper.github.io/demo-dapp-with-wallet - JS signature verification example github.com/mois-ilya/ton-sign-data-reference
- Smart contract verification example github.com/p0lunin/sign-data-contract-verify-example
- Tonkeeper's SignData spec github.com/tonkeeper/ton-connect-docs – SignData
- FunC
check_signaturestandard lib docs.ton.org – check_signature