Docs Técnicas
atlas-wallet
atlas-wallet is a hybrid package that combines three roles:
Summary
atlas-wallet is a hybrid package that combines three roles:
- a reusable Rust library for local identity, vault, profile, and signing logic
- a Wasm bridge consumed by browser wallet frontends
- a small set of helper/demo binaries around key generation, vault loading, and a gRPC probe
In practice, the Wasm surface is the crate's most important application boundary today. That is what the browser wallet frontend and the copied Wasm package in the bank-admin frontend actually consume.
Why This Crate Exists
- generate deterministic wallet identities from seed material or mnemonic phrases
- persist wallet secrets locally inside an encrypted vault blob
- model the two-profile wallet shape used in Atlas:
exposedandhidden - sign transfers, arbitrary transaction payloads, and arbitrary messages locally
- synchronize local wallet state from the node REST API
- verify and import portable KYC envelopes inside the wallet boundary
- expose all of the above through a Wasm contract that frontend code can call directly
Current Role In The Workspace
atlas-wallet currently owns five related concerns:
- identity generation and profile derivation
- encrypted vault serialization and session loading
- in-memory wallet state, active-profile switching, and signing flows
- Wasm exports used by browser-facing frontends
- auxiliary CLI/demo binaries that support local development more than production operations
This crate is not the ledger, mempool, or network client. It depends on Atlas APIs as sources of truth for balance and nonce state, but custody and signing stay local to the wallet.
Public Surface
Top-Level Modules
errorsidentityprofilesessionvaultwalletwasm
Main Reexports
wallet::create_vaultwallet::import_vaultwallet::Walletwallet::AccountDatawallet::WalletData
Important Wasm Exports
create_vault(...)restore_vault(...)load_vault(...)get_data()selected_account()sing_transfer(...)sign_transaction_payload(...)sign_message(...)get_public_key_hex()switch_profile()synchronize(...)import_portable_kyc(...)
Package Targets
- library target
atlas_walletwith crate typescdylibandrlib - binary target
atlas-wallet - binary target
vault_cli - implicit binary target
gen_keyfrom `src/bin/gen_key.rs`
Key Modules
- `lib.rs`: crate root and public module surface
- `identity/identity.rs`:
Identity,IdentityBundle, and deterministic exposed/hidden profile generation - `profile/data.rs`: shared profile state, permissions, signing, and signature validation
- `session/session.rs`: active wallet session, in-memory signing keys, profile switching, and transfer construction
- `vault/vault.rs`: encrypted vault encoding and bundle load/save logic
- `wallet/factory.rs`: high-level vault creation and mnemonic-based restore helpers
- `wallet/manager.rs`: main
Walletstate holder and public method surface - `wallet/actions.rs`: vault load, signing flows, and active-profile switching
- `wallet/queries.rs`: wallet snapshot reads and signature validation helpers
- `wallet/auth.rs`: adapter for
atlas_common::auth::Authenticator - `wasm.rs`: browser-facing Wasm boundary and portable-KYC import path
- `main.rs`: demo gRPC wallet CLI entrypoint
Inputs And Outputs
Inputs
- raw seed bytes or BIP39 mnemonic phrases
- wallet passwords for vault encryption and decryption
- encoded vault blobs
- transaction payload JSON and externally supplied nonces
- node/admin API base URLs for synchronization and KYC flows
- portable KYC JSON plus issuer public key material
Outputs
- encrypted vault blobs
- exposed and hidden wallet addresses
- mnemonic recovery phrases
- in-memory
Sessionstate with the active profile and signing key SignedTransactionvalues and signature-derived ids- wallet snapshots serialized as
WalletData - Wasm
JsValueresponses consumed by frontend code - verified portable-KYC payloads returned to the browser side
Internal Dependencies
Workspace Dependencies
atlas-commonatlas-kyc
atlas-wallet deliberately disables atlas-common default features, which keeps the Wasm-oriented build surface lighter.
External Dependencies That Shape The Design
ed25519-dalekfor signing keys and signature verificationargon2plusaes-gcmfor password-based vault encryptionbip39for mnemonic generation and restorewasm-bindgen,serde-wasm-bindgen,js-sys, andweb-sysfor the browser-facing contractreqwestfor wallet synchronization over HTTP
Used By
No other core workspace crate depends directly on atlas-wallet as a Rust library.
The package is still actively consumed in three ways:
- `bins/demo-seed/src/app/bootstrap.rs`: uses wallet identity and vault logic to generate and load demo signer material
- `bins/demo-seed/src/bin/verify_blob.rs`: reads a demo vault blob and extracts the exposed address
- `scripts/build_wasm.sh`: builds the generated Wasm package and copies it into multiple frontend packages
Operationally, the Wasm output is consumed by:
- `crates/application/atlas-wallet/frontend`
- `crates/application/atlas-bank-admin/frontend`
And the wallet frontend is launched in the demo stack from:
- `start_demo_dev.sh`
- `start_demo_prod.sh`
Identity And Vault Model
generate(...) in `identity/identity.rs` deterministically derives two Ed25519 profiles from a single 32-byte seed:
exposedhidden
Each profile gets:
- its own signing keypair
- its own address encoding
- its own permission list
- its own encrypted secret-key payload inside profile data
The higher-level factory flow in `wallet/factory.rs` adds the user-facing ergonomics:
create_vault(...)creates a fresh 12-word mnemonic, derives a seed, generates both profiles, and returns the encrypted vault blob plus both addressesimport_vault(...)reconstructs the same identity from the mnemonic phrase
Vault persistence itself lives in `vault/vault.rs`:
- the
IdentityBundleis serialized withbincode - the password is stretched with Argon2 parameters stored inside the vault record
- the serialized payload is encrypted with AES-256-GCM
- the result is returned as an encoded binary blob for callers to store
Session And Signing Model
The main runtime object is Wallet in `wallet/manager.rs`.
It stores:
- an optional loaded
Session - a mutex-protected
transfer_mapkeyed by signature hex
Session in `session/session.rs` loads both derived signing keys into memory and starts on the exposed profile by default. switch_profile() flips the active profile between exposed and hidden and swaps the active signing key along with it.
The main signing paths are:
sing_transfer(...)for transferssign_transaction_payload(...)for arbitrary Atlas transaction payloads like KYC, alias, or institution registrationsign_message(...)for wallet-auth and generic message signing
An important boundary choice appears here: nonce management is not local. The caller is expected to provide the nonce, which matches the current Atlas design where the node or ledger API is the source of truth.
Wasm And Frontend Boundary
`wasm.rs` is the crate's most important application-facing entrypoint.
The module keeps a thread-local singleton wallet:
thread_local! { static WALLET: RefCell<Wallet> = RefCell::new(Wallet::new()); }
That singleton is what browser-side code talks to through Wasm exports.
Browser Wallet Features
The Wasm contract supports:
- wallet creation and restore
- vault load into memory
- reading the exposed/hidden account snapshot
- switching between profiles
- signing transfers and arbitrary transaction payloads
- synchronizing balances and nonces from the node REST API
- importing and verifying portable KYC envelopes
Portable KYC Import
import_portable_kyc(...) in `wasm.rs` is the place where atlas-wallet actually consumes atlas-kyc.
The function:
- parses the portable-KYC JSON
- resolves the issuer public key from either the argument or the embedded certificate field
- verifies the envelope with
atlas_kyc::verify_portable_kyc(...) - returns the verified cleartext payload back to JavaScript
That makes the wallet a verification boundary for user-imported KYC artifacts, not just a signing tool.
Runtime And Binary Model
The package's binary story is mixed and clearly development-oriented.
`atlas-wallet`
`main.rs` is a small demo gRPC client:
- with the
grpcfeature enabled, it connects tohttp://127.0.0.1:50051 - it submits a hardcoded demo transaction request
- without
grpc, it only prints a message telling the user to enable the feature
So the main package binary is not a full wallet CLI today. The real wallet UX lives on the Wasm/frontend side.
`vault_cli`
`src/bin/vault_cli.rs` is intended as a save/load helper around VaultData.
`gen_key`
`src/bin/gen_key.rs` generates a random exposed-profile seed and prints the derived address.
Testing
This crate has a healthy amount of unit coverage spread across:
- identity generation
- profile creation and permission checks
- session switching and signature validation
- vault save/load roundtrips
- wallet query and signing helpers
- Wasm sync-helper parsing
- CLI argument parsing
Most tests are local and serialization-oriented. There is not much end-to-end coverage here for:
- browser persistence behavior
- compatibility between the Wasm contract and frontend consumers
- compatibility between wallet sync code and the current node API shape
Risks Or Design Tension
One Package Owns Too Many Roles
atlas-wallet is simultaneously:
- a crypto/vault library
- a session manager
- a Wasm bridge
- a frontend contract
- a demo CLI package
That makes the crate useful, but it also makes its architectural boundary blurry.
Native Sync And Wasm Sync Have Drifted
The native sync path in `wallet/sync.rs` calls /api/balance?address=..., while the Wasm path in `wasm.rs` calls /api/balance?query=....
The current node handler in `accounts.rs` reads query, not address, so the native sync implementation looks stale relative to the current API contract.
Legacy Naming Is Still Visible
Several names suggest this crate still carries older project history:
NimbleError"Mel Blockchain - Wallet CLI"in `main.rs`- method names like
sing_transferandvalidade
That does not break functionality directly, but it makes the surface feel less intentional and harder to document cleanly.
The Wasm Wallet Is A Singleton
The browser-facing runtime uses a thread-local singleton wallet, which means one active in-memory wallet per Wasm runtime. That is simple for the current UI, but it limits multi-wallet and multi-session patterns.
Auxiliary Binaries Show Signs Of Incompleteness
Two concrete examples stand out:
- `src/bin/vault_cli.rs` accepts a
pathforsave, but the current implementation never writes the encoded vault bytes to disk - `src/bin_gen.rs` is a useful helper for generating a SeedBank admin blob, but it is not part of the package target graph today