Skip to main content
peaqOS supports the Open Wallet Standard v1.3 for generation, encrypted storage, , and display. The current raw-key flow uses hex in .env files, protected only by file permissions. That works, but it has limits:
  • No encryption at rest
  • No backup or recovery
  • No multi-chain visibility. One secp256k1 key derives on every chain, Cosmos, Solana, Bitcoin, Tron, and more, but nothing surfaces them
  • No standard import / export to wallets like MetaMask or hardware devices
  • No audit log of key creation, signing, or export events
solves all of these with an encrypted local vault, BIP-39 , CAIP-2 chain identifiers, and an append-only audit log: fully 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 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.

Vault layout

The vault lives at ~/.ows/ (override with OWS_VAULT_PATH). Structure is set by OWS; peaqOS uses it as-is.
Each wallet file holds:
  • id (UUID v4) and name
  • key_type: "mnemonic" or "private_key"
  • accounts[] with one entry per supported chain (CAIP-10, address, derivation path)
  • crypto with aes-256-gcm ciphertext, scrypt KDF params, IV, salt, and auth tag
  • created_at (ISO 8601)

SDK methods

Wallet lifecycle is exposed through the SDKs.

JavaScript / TypeScript

Available as both module-level imports and static methods on PeaqosClient. Pick whichever matches your style.
Every function takes an optional final 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.
Signature: fromWallet(nameOrId, passphrase, owsSigning, config, options?). owsSigning defaults to true. In OWS-native mode the SDK never holds the private key: signMessage and signTypedData throw because OWS only exposes signTransaction. 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 under peaq_os_sdk.wallet and as @staticmethods on PeaqosClient.
Each function accepts a final 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, verifies the passphrase, and returns a fully configured client.
Signature: 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 decrypts it inside the OWS Rust FFI for each sign_transaction call and wipes it immediately. 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 typed errors via 5 OWS error codes (WALLET_NOT_FOUND, INVALID_PASSPHRASE, INVALID_INPUT, POLICY_DENIED, CHAIN_NOT_SUPPORTED). 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:
It returns the 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 through peaqos wallet. Install the optional extra to get them:
Then:
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. 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_PASSPHRASE env var; if neither is set, the SDK raises PeaqosError rather than prompting. Never stored on disk. In CI, pass via secret manager or env injection.
  • Mnemonic exposure. Never returned by createWallet / create_wallet. The WalletInfo response only carries addresses and metadata. To recover the seed phrase you must call exportWallet / export_wallet with 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. Every wallet operation (create, import, export, delete) appends to ~/.ows/logs/audit.jsonl.

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 v1.3 spec.