Pure-PHP TON Wallet v4r2 — address derivation, transfer assembly, and a TON address parser for The Open Network.
A pure-PHP implementation of the TON Wallet v4r2 contract for The Open Network (TON): derive the wallet address, assemble signed transfers with the standard InternalMessage envelope, and parse / serialize TON addresses in every form. Address derivation matches @ton/ton's WalletContractV4 byte-for-byte, so a wallet built here lands at the same on-chain address as the JavaScript SDK. Broadcasting is decoupled behind a tiny RPC interface, so the same wallet object signs offline and ships through any backend.
WalletV4R2::address() reproduces the exact state-init hash @ton/ton computes; same keys, same address.createTransfer() builds and signs the external-in message body without any network I/O; broadcast is a separate step.InternalMessages in a single signed external message, with a per-message sendMode.Address::parse() handles user-friendly UQ… / EQ… (bounceable + non-bounceable, mainnet + testnet, url-safe + standard base64) and raw workchain:hex forms, with CRC16 validation.Address::toString() flags or toTonscanFormat().WalletRpcInterface (getSeqno + sendBoc) once and broadcast through toncenter, a custom node, or a test double.olifanton/ton covers parts of the TON wallet surface, but this package keeps the wallet contract, the transfer builder, and the address parser as small final readonly value objects with PHPStan level 9 across the board, and pins address derivation to a cross-checked @ton/ton parity vector. Broadcasting is never baked in — you bring the transport.
composer require amashukov/ton-wallet-php
use Amashukov\TonCrypto\Mnemonic;
use Amashukov\TonWallet\WalletV4R2;
$keys = Mnemonic::toKeyPair('word1 word2 ... word24');
$wallet = new WalletV4R2($keys);
echo $wallet->address()->toString(); // user-friendly UQ… (non-bounceable)
echo $wallet->address()->toString(userFriendly: false); // raw 0:abc… (for RPC calls)
InternalMessage values are decimal-string nano-TON. validUntil is a UNIX
timestamp after which an unconfirmed external message is dropped by the network.
use Amashukov\TonWallet\Address;
use Amashukov\TonWallet\InternalMessage;
use Amashukov\TonWallet\WalletV4R2;
$wallet = new WalletV4R2($keys);
$messages = [
new InternalMessage(
dest: Address::parse('UQ...'),
value: '1000000000', // 1 TON in nano-TON
bounce: false,
),
];
// One-shot: read seqno, sign, broadcast — through your WalletRpcInterface.
$wallet->sendTransfer($rpc, $messages, validUntil: time() + 60);
use Amashukov\TonCell\Boc;
$seqno = 0; // read out-of-band, or via $wallet->getSeqno($rpc)
$body = $wallet->createTransfer($seqno, time() + 60, $messages);
$ext = $wallet->wrapExternalInMessage($body);
$signedBocBase64 = Boc::encodeBase64($ext); // hand to any broadcaster
use Amashukov\TonWallet\Address;
$addr = Address::parse('EQDrjaLahLkMB-hMCmkzOyBuHJ139ZUYmPHu6RRBKnbdLIYI');
$addr->wc; // 0
$addr->toString(userFriendly: false); // 0:eb8d… raw workchain:hex
$addr->toTonscanFormat(); // bounceable url-safe EQ…
Address::isValid('not-an-address'); // false
ext-sodium (Ed25519 signing)ext-bcmath| Package | Role |
|---|---|
| amashukov/ton-cell-php | TLB Cell / Builder / BOC layer (dependency) |
| amashukov/ton-crypto-php | Mnemonic + Ed25519 KeyPair (dependency) |
| amashukov/toncenter-client-php | Typed toncenter v2 client + ready WalletRpcInterface adapter |
| amashukov/ton-php | TON meta-package |
| amashukov/blockchain-context-bundle | Symfony bundle wiring the whole family |
@PER-CS ruleset.@ton/ton WalletContractV4 parity vector.MIT — see LICENSE.
How can I help you explore Laravel packages today?