Wallets & AddressesAddresses

Addresses

The Address class and its EvmSigner / SvmSigner specializations — the on-chain identity carrying publicKey, vm and network that signs messages, builds/simulates/sends transactions and lowers transfers.

An Address is a single on-chain identity: a public key bound to one virtual machine (vm) and one Network. A Wallet holds one Address per (vm, network), and the address is where the operations live — signing messages, building and sending transactions, and lowering chain-agnostic transfers. The sealed private key is never exposed on the address; every signing method routes through internal custody that holds the decrypted key only while the account is unlocked.

You never construct an Address directly; you read one off a wallet:

address.ts
const acc = await ws.accounts.create("Desk", "wsp-pwd", MNEMONIC);

const evm = acc.wallets[0].addresses.find((a) => a.vm === "evm");
const svm = acc.wallets[0].addresses.find((a) => a.vm === "svm");

Identity fields

Every Address carries the same read-only identity fields, all fixed at construction:

FieldTypeDescription
publicKeyEvmAddress | SvmAddress | SuiAddressthe canonical public address string
vmVmTokenthe virtual machine — "evm", "svm", "sui", or a registered custom VM
networkNetworkthe network this identity is active on
assetsAssetCollectionthe assets tracked on this address
evm.publicKey;          // "0x9858EfFD232B4033E47d90003D41EC34EcaEda94"
evm.vm;                 // "evm"
evm.network.chainId;    // 1
String(evm);            // same as evm.publicKey (toString returns it)

The publicKey is canonicalized at the storage boundary (EVM checksum casing, SVM base58), so every downstream comparison — ownership checks, JSON snapshots, nonce keys — sees one byte-form regardless of how a caller typed it.

EvmSigner and SvmSigner

EvmSigner and SvmSigner are the per-chain specializations of Address that wallet.evm and wallet.svm return. They inherit Address's full surface verbatim — the subclass exists so the accessors hand back a named, per-chain type rather than the base union, giving callers a signer they can pass to chain-specific code without re-narrowing.

const signer = acc.wallets[0].evm; // EvmSigner | null
signer?.signTypedData(typedData, 1);
VMInstance returnedSigner type
"evm"EvmSignersecp256k1
"svm"SvmSignered25519
"sui"base Addressnone in this build

Method map

The address is the single entry point for its identity's operations. The signing methods are documented on Message & Typed-Data Signing; the transaction methods on Transactions.

MethodReturnsDocumented at
signMessage(message)stringSigning
signMessageEncoded(message, encoding){ signature, messageHash }Signing
signTypedData(typedData, chainId){ signature, domainSeparator, structHash } — EVM onlySigning
buildTransaction(params)EvmTransaction / SvmTransactionTransactions
buildTransferPayload(req)TransferPayloadTransfers
signTransaction(tx)the same tx (signing runs asynchronously)Transactions
sendTransaction(tx)TransactionTrackerTransactions
simulateTransaction(tx)Promise<SimulationResult>Transactions

Building a transaction

buildTransaction returns the concrete per-chain transaction (an EvmTransaction for an EVM address, an SvmTransaction for SVM) with the address already bound, so it can be signed, simulated and sent. The EVM shape, taken from the example tests:

build-tx.ts
import { Network } from "wative-core";

const tx = await evm.buildTransaction({
  to: "0x1234567890123456789012345678901234567890",
  value: 1_000_000_000_000_000n,
  chainId: 1,
  nonce: 0,
  gasLimit: 21000n,
  maxFeePerGas: 50_000_000_000n,
  maxPriorityFeePerGas: 1_000_000_000n,
  type: 2,
  network: Network.Ethereum,
});

tx.from.toLowerCase() === evm.publicKey.toLowerCase(); // true

Ownership

signTransaction, sendTransaction and simulateTransaction all enforce that the transaction's from matches this address's publicKey; a foreign from throws a PARAMETER_ERROR synchronously. See Transactions for the tracker and simulation shapes.

Last updated on