ceres_wallet_onchain 0.1.1
ceres_wallet_onchain: ^0.1.1 copied to clipboard
A pure Dart multi-chain RPC SDK covering EVM, Tron, Solana, and Sui.
ceres_wallet_onchain #
A pure Dart multi-chain RPC SDK covering EVM / Tron / Solana / Sui with complete RPC method coverage, typed response parsing, ABI encoding, and a DApp codec layer.
Features #
| Category | What's included |
|---|---|
| EVM RPC | 49 typed methods — eth_, net_, web3_ namespaces |
| Tron HTTP | 65 typed endpoints — accounts, transactions, staking, TRC-20 contracts |
| Solana RPC | 50 typed methods — accounts, SPL tokens, blocks, staking, fees |
| Sui RPC | 39 typed methods — sui_ and suix_ namespaces |
| ABI codec | Encode/decode address, uint/int, bool, bytes, string, tuple, arrays |
| Function selector | keccak256-based 4-byte selector computation |
| EIP-712 / EIP-191 | Parse typed data → TypedDataV4, compute 32-byte digest for MPC/signing |
| Solana tx codec | Decode/encode legacy + v0 transactions (wire bytes), compact-u16, AltResolver, ComputeBudgetDecoder |
| Unified exceptions | RpcException hierarchy with automatic retry and timeout |
| Pure Dart | No Flutter dependency — works in any Dart environment |
Installation #
dependencies:
ceres_wallet_onchain: ^0.1.1
dart pub add ceres_wallet_onchain
import 'package:ceres_wallet_onchain/ceres_wallet_onchain.dart';
Quick Start #
EVM #
final client = EvmRpcClient(
transport: JsonRpcTransport(
config: RpcClientConfig(baseUrl: 'https://mainnet.infura.io/v3/YOUR_KEY'),
),
);
final balance = await client.getBalance(
EvmAddress('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'),
);
print('Balance: $balance wei');
final gasPrice = await client.gasPrice();
final chainId = await client.chainId();
client.close();
Tron #
final client = TronHttpClient(
transport: RestTransport(
config: RpcClientConfig(baseUrl: 'https://api.trongrid.io'),
),
);
final account = await client.getAccount(
TronAddress('TLsV52sRDL79HXGGm9yzwKibb6BeruhUzy'),
);
print('Balance: ${account?.balance} sun');
client.close();
Solana #
final client = SolanaRpcClient(
transport: JsonRpcTransport(
config: RpcClientConfig(baseUrl: 'https://api.mainnet-beta.solana.com'),
),
);
final balance = await client.getBalance(SolanaAddress('11111111111111111111111111111111'));
final blockhash = await client.getLatestBlockhash();
print('$balance lamports, blockhash: ${blockhash.blockhash}');
client.close();
Sui #
final client = SuiRpcClient(
transport: JsonRpcTransport(
config: RpcClientConfig(baseUrl: 'https://fullnode.mainnet.sui.io'),
),
);
final balance = await client.getBalance(SuiAddress('0xabc...'));
print('Total SUI: ${balance.totalBalance}');
client.close();
ABI Encoding #
// Encode a transfer(address,uint256) call
final selector = FunctionSelector.fromSignature('transfer(address,uint256)');
final params = AbiCoder.encode(
[AbiParam(type: 'address'), AbiParam(type: 'uint256')],
['0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', BigInt.from(1000000)],
);
final calldata = [...selector.bytes, ...params];
// Decode a uint256 return value
final decoded = AbiCoder.decode([AbiParam(type: 'uint256')], params);
print('Value: ${decoded[0]}');
DApp Codec Layer #
EIP-712 (signTypedData_v4 pre-hash) #
// Parse raw JSON payload from WalletConnect / MetaMask
final typedData = EIP712Parser.parse(rawJsonMap);
// Compute the 32-byte digest — pass to your signer
final digest = EIP712Hasher.digest(typedData);
// Access structured fields for approval UI
print(typedData.primaryType); // 'Permit'
print(typedData.message['spender']); // '0x...'
EIP-191 (personal_sign pre-hash) #
final digest = EIP191Hasher.digest('Hello Ethereum');
// Pass digest to your signing backend
Solana Transaction Codec #
// Decode wire bytes from WalletConnect payload
final tx = SolanaTxDecoder.decode(wireBytes);
print(tx.version); // null (legacy) or 0 (v0)
print(tx.instructions.length);
// Re-encode after approval (e.g. after attaching signature)
final reEncoded = SolanaTxEncoder.encode(tx);
// Resolve Address Lookup Table accounts for v0 transactions
final allAccounts = await AltResolver.resolve(
tx,
(pubkey) => solanaClient.getAccountInfo(SolanaAddress(pubkey)),
);
// Decode ComputeBudget instructions
for (final ix in tx.instructions) {
final budget = ComputeBudgetDecoder.decode(ix, tx.staticAccountKeys);
if (budget is SetComputeUnitPrice) {
print('Priority fee: ${budget.microLamports} microLamports');
}
}
Error Handling #
final client = EvmRpcClient(
transport: JsonRpcTransport(
config: RpcClientConfig(
baseUrl: 'https://mainnet.infura.io/v3/YOUR_KEY',
timeout: Duration(seconds: 10),
maxRetries: 2,
),
),
);
try {
final balance = await client.getBalance(EvmAddress('0x000...'));
print('Balance: $balance');
} on RpcTimeoutException catch (e) {
print('Timeout: ${e.message}');
} on RpcResponseException catch (e) {
print('RPC error ${e.code}: ${e.message}');
} on RpcException catch (e) {
print('Error: ${e.message}');
} finally {
client.close();
}
Supported Chains #
| Chain | Client | Transport | Methods |
|---|---|---|---|
| EVM | EvmRpcClient |
JsonRpcTransport |
49 |
| Tron | TronHttpClient |
RestTransport |
65 |
| Solana | SolanaRpcClient |
JsonRpcTransport |
50 |
| Sui | SuiRpcClient |
JsonRpcTransport |
39 |
Signing Boundary #
This package handles RPC calls, ABI encoding, and pre-hash digest computation only. Transaction signing and key management must be done externally.
sendRawTransaction(EVM),broadcastHex(Tron),sendTransaction(Solana),executeTransactionBlock(Sui) — all accept pre-signed payloads.EIP712Hasher.digest()andEIP191Hasher.digest()produce the hash for your external signer; they do not sign.
API Reference #
Full documentation: pub.flutter-io.cn/documentation/ceres_wallet_onchain/latest
License #
MIT — see LICENSE for details.