Wallet
The wallet module handles local wallet persistence, note tracking, and field element serialization. Wallet state is stored as JSON at ~/.r14/wallet.json.
Structs
WalletData
pub struct WalletData {
pub secret_key: String, // hex-encoded Fr
pub owner: String, // hex-encoded owner_hash(sk)
pub stellar_secret: String, // Stellar signing key (S...)
pub network: String, // "testnet" | "standalone" | passphrase
pub indexer_url: String, // e.g. "http://localhost:3001"
pub contracts: R14Contracts, // core + transfer contract IDs
pub notes: Vec<NoteEntry>, // all known notes (live + spent)
}
NoteEntry
pub struct NoteEntry {
pub value: u64,
pub app_tag: u32,
pub owner: String, // hex Fr
pub nonce: String, // hex Fr
pub commitment: String, // hex Fr - Poseidon(value, app_tag, owner, nonce)
pub leaf_index: Option<u64>, // set after sync with indexer
pub spent: bool, // true after successful transfer
}
leaf_index starts as None. After calling R14Client::sync_notes, it is populated with the on-chain Merkle tree position. A note with spent: true has had its nullifier published and cannot be used again.
Functions
wallet_path
pub fn wallet_path() -> PathBuf
Returns ~/.r14/wallet.json. Creates the ~/.r14/ directory if it does not exist.
load_wallet
pub fn load_wallet() -> R14Result<WalletData>
Reads and deserializes ~/.r14/wallet.json. Returns R14Error::Config if the file is missing or malformed.
let wallet = r14_sdk::wallet::load_wallet()?;
println!("owner: {}", wallet.owner);
println!("notes: {}", wallet.notes.len());
save_wallet
pub fn save_wallet(wallet: &WalletData) -> R14Result<()>
Serializes and writes the wallet to ~/.r14/wallet.json with pretty-printed JSON. Creates parent directories if needed.
wallet.notes.push(deposit_result.note_entry);
r14_sdk::wallet::save_wallet(&wallet)?;
fr_to_hex
pub fn fr_to_hex(f: &Fr) -> String
Converts an arkworks Fr field element to a 64-character lowercase hex string (big-endian byte order, no 0x prefix).
let hex = r14_sdk::wallet::fr_to_hex(&commitment);
assert_eq!(hex.len(), 64);
hex_to_fr
pub fn hex_to_fr(hex: &str) -> R14Result<Fr>
Parses a 64-character hex string back into an Fr. Returns R14Error::Config on invalid input.
let fr = r14_sdk::wallet::hex_to_fr(¬e_entry.nonce)?;
crypto_rng
pub fn crypto_rng() -> impl CryptoRng + RngCore
Returns an OS-seeded cryptographically secure RNG. Use this for generating secret keys and nonces.
let mut rng = r14_sdk::wallet::crypto_rng();
let sk = SecretKey::random(&mut rng);
Wallet JSON Example
{
"secret_key": "0a1b2c3d4e5f...64 hex chars...",
"owner": "1f2e3d4c5b6a...64 hex chars...",
"stellar_secret": "SCZANGBA...",
"network": "testnet",
"indexer_url": "http://localhost:3001",
"contracts": {
"core": "CABCDEFG...",
"transfer": "CDEFGHIJ..."
},
"notes": [
{
"value": 1000000,
"app_tag": 0,
"owner": "1f2e3d4c5b6a...64 hex chars...",
"nonce": "7a8b9c0d1e2f...64 hex chars...",
"commitment": "3c4d5e6f7a8b...64 hex chars...",
"leaf_index": 0,
"spent": false
},
{
"value": 500000,
"app_tag": 0,
"owner": "1f2e3d4c5b6a...64 hex chars...",
"nonce": "9f8e7d6c5b4a...64 hex chars...",
"commitment": "2b3c4d5e6f7a...64 hex chars...",
"leaf_index": null,
"spent": false
}
]
}
The first note has been synced (leaf_index: 0). The second is pending sync (leaf_index: null).