.env files, protected only by file permissions: no encryption at rest and no backup to restore in another wallet or a hardware device.
gives you an encrypted local vault, BIP-39 and CAIP-2 chain identifiers. One mnemonic derives on every chain, Cosmos, Solana, Bitcoin, Tron, and more, and OWS surfaces them. Everything stays local: no cloud, no remote services.
OWS is optional. Use the helpers below to manage wallets. The raw-key path keeps working unchanged.
Multi-chain accounts from one mnemonic
A mnemonic-derived wallet generates accounts across every OWS-supported chain family from a single 12- or 24-word phrase. The exact set depends on the installed OWS release.
The SDK guarantees an account entry for every protocol-recognized EVM chain (
SUPPORTED_CHAIN_IDS). If OWS doesn’t return one, it’s synthesized from the wallet’s primary EVM address, which is identical across all EVM chains:
Each account is exposed as a CAIP-10 account ID (
eip155:3338:0x...), so a single peaqOS wallet can sign on peaq, (for bridgeNft), and any other supported chain without ever exporting the key. The wallet’s Solana account also signs for a machine homed on Solana, through PeaqosClient.solanaSignerFromWallet(name, passphrase) in JS and solana_signer_from_wallet(name, passphrase, chain_id=...) in Python; see Solana onboarding.
Vault layout
The vault lives at~/.ows/. The SDK helpers take a different directory through vaultPath (JS WalletOptions) or vault_path (Python); the CLI always uses ~/.ows/. Structure is set by OWS; peaqOS uses it as-is. The SDK and CLI wallet helpers write only the wallets/ directory:
id(UUID v4) andnamekey_type:"mnemonic"or"private_key"accounts[]with one entry per supported chain (CAIP-10, address, derivation path)cryptowithaes-256-gcmciphertext,scryptKDF params, IV, salt, and auth tagcreated_at(ISO 8601)
SDK methods
JavaScript / TypeScript
Available as both module-level imports and static methods onPeaqosClient.
WalletOptions arg with vaultPath to point at a vault directory other than ~/.ows/. falls back to OWS_PASSPHRASE when omitted; if both are missing, the call throws PeaqosError. importWallet validates the hex shape eagerly and throws ValidationError for malformed keys; importWalletMnemonic accepts an optional index (default 0) before the WalletOptions arg to derive a non-default account.
WalletInfo carries id, name, createdAt, keyType, peaqAddress (convenience), and accounts: readonly AccountInfo[] with every chain. AccountInfo has accountId (CAIP-10), address, chainId (CAIP-2), network (human-readable name like "peaq", "base", "solana"), and derivationPath. Both shapes are deep-frozen.
Building a client straight from a vault wallet
PeaqosClient.fromWallet skips the manual private-key plumbing. It loads a wallet from the vault and returns a configured client whose account is the wallet’s peaq address.
fromWallet(nameOrId, passphrase, owsSigning, config, options?). owsSigning defaults to true. In OWS-native mode the SDK never holds the private key, and the client’s signMessage and signTypedData throw PeaqosError. Switch to raw-key mode if you need either.
OWS signing surfaces typed errors via OwsSigningErrorCode (WALLET_NOT_FOUND, INVALID_PASSPHRASE, INVALID_INPUT, POLICY_DENIED, CHAIN_NOT_SUPPORTED). INVALID_INPUT becomes a ValidationError; the rest become PeaqosError with the original error preserved as .cause.
Python
Available underpeaq_os_sdk.wallet and as @staticmethods on PeaqosClient.
vault_path keyword for a custom vault directory. Passphrase falls back to the OWS_PASSPHRASE env var when None; missing both raises PeaqosError.
On the Python side, WalletInfo carries id, name, created_at, key_type, peaq_address (convenience), and accounts: list[AccountInfo] with every chain. AccountInfo has account_id (CAIP-10), address, chain_id (CAIP-2), network (human-readable name), and derivation_path.
Building a client straight from a vault wallet
PeaqosClient.from_wallet mirrors the JS factory above. It loads the wallet and returns a configured client whose address is the wallet’s peaq address. With the default ows_signing=True a wrong passphrase surfaces on the first sign call; ows_signing=False decrypts the key at construction and rejects it there.
from_wallet(name_or_id, passphrase=None, ows_signing=True, vault_path=None, **config_kwargs). passphrase falls back to OWS_PASSPHRASE. In OWS-native mode the SDK never holds the private key: OWSAccount hands each sign_transaction call to OWS, which decrypts per sign and wipes the key. ows_signing=False exports and decrypts the key at construction time, behaving identically to a raw-key client. Each transaction’s chainId drives both the CAIP-2 OWS arg and the EIP-155 v, so the same client transparently signs both peaq (eip155:3338) and Base (eip155:8453) .
OWS signing surfaces the same five error codes as JS. INVALID_INPUT raises ValidationError; the rest raise PeaqosError. See SDK errors: OWS signing error codes.
Pulling the peaq address out of a wallet
peaq_address / peaqAddress is already populated by every wallet method, so most callers never need anything else. If you’re working with a raw accounts list (e.g. building a wallet response by hand in tests, or reading a vault file directly), use the helper:
eip155:3338 account if present, otherwise the first eip155:* account (EVM addresses match across EVM chains), and raises PeaqosError when no EVM account exists.
From the CLI
Every SDK wallet helper is also exposed throughpeaqos wallet. Install the optional extra to get them:
peaqos init also offers wallet as a third Private key source choice and writes PEAQOS_OWS_WALLET instead of PEAQOS_PRIVATE_KEY. Once a wallet is active, peaqos activate, peaqos qualify event, and the rest of the command surface sign through it. peaqos activate --chain solana signs with two wallets: the operator wallet’s peaq account signs registration (gas only, about 0.01 PEAQ, once per owner wallet), and the owner wallet’s Solana account signs request, finalise, native_onboarding, linkage and cancel_request and pays the bond on Solana. --operator-wallet and --owner-wallet name them, in the one-command run or with --phase; either one left out falls back to PEAQOS_OWS_WALLET. See peaqOS CLI: wallet for the full command reference.
Security model
- Vault encryption. AES-256-GCM with scrypt KDF (
n=65536, r=8, p=1). - Passphrase handling. Sourced from the explicit argument or the
OWS_PASSPHRASEenv var; if neither is set, the SDK raisesPeaqosErrorrather than prompting. Never stored on disk. In CI, pass via secret manager or env injection. - Mnemonic exposure. Never returned by
createWallet/create_wallet. TheWalletInforesponse only carries addresses and metadata. To recover the seed phrase you must callexportWallet/export_walletwith the vault passphrase. - Single-mnemonic blast radius. One phrase controls accounts on every supported chain. Treat exported phrases accordingly: anyone with the phrase has access to every chain account.
- Audit log. The OWS standard defines an append-only audit log at
~/.ows/logs/audit.jsonl, written by the OWS CLI. The SDK andpeaqos wallethelpers do not write it.
See also
peaqOS CLI
The full peaqOS CLI command reference.
Install
The
[ows] extra and the raw-key flow side-by-side.OWS specification
Full upstream Open Wallet Standard spec.

