Add root Cargo workspace with 9 crates: salvium-crypto (extended), salvium-types, salvium-consensus, salvium-wallet, salvium-tx, salvium-rpc, salvium-miner (extended), salvium-cli, salvium-multisig. New modules: chain_state, block_weight, alt_chain, validation, offline signing, stake lifecycle, wallet sync/query/encryption/utxo, randomx utilities, and full multisig crate with CARROT support. Delete 188 JS test/helper/debug files; archive integration test scripts to test/legacy-js/ for live testnet use. Testnet integration tests (transfer, stake, burn, convert, sweep) remain as #[ignore]- gated Rust tests runnable with --ignored against a live daemon.
7.9 KiB
Salvium-JS Testnet Testing Plan
Status: Pending - to be executed near project completion
Security: No Secrets in Git
Pre-commit hook installed: .githooks/pre-commit scans for potential secrets before commit.
Setup: Run git config core.hooksPath .githooks to enable.
Protected patterns:
- 25-word mnemonic phrases
- 64-character hex strings (potential keys)
- Files matching
*.env,*.key,wallet*.json, etc.
Git history audit (2026-01-25): No real wallet credentials found in history. Only test patterns (bacon bacon..., abbey abbey...) which are recognizable fake mnemonics.
Prerequisites
Testnet Setup
- Testnet daemon URL (or run local testnet node)
- Testnet wallet with funds (need testnet SAL faucet or mining)
- Second wallet for receiving transactions
Environment Variables
CRITICAL: All wallet secrets MUST come from environment variables. Never hardcode mnemonics, master keys, view keys, or spend keys in test files.
# Primary wallet (choose one method)
export WALLET_SEED="testnet wallet 25 word mnemonic"
# OR
export MASTER_KEY="64-character-hex-master-key"
# OR (for view-only testing)
export VIEW_SECRET_KEY="64-char-hex"
export SPEND_PUBLIC_KEY="64-char-hex"
# Secondary wallet for receiving
export WALLET_SEED_2="second wallet mnemonic for receiving"
# Daemon
export DAEMON_URL="http://localhost:28081" # Testnet port
Supported Key Formats
| Variable | Format | Description |
|---|---|---|
WALLET_SEED |
25 words | Full wallet from mnemonic |
MASTER_KEY |
64 hex chars | Raw 32-byte seed |
VIEW_SECRET_KEY |
64 hex chars | View-only: view secret |
SPEND_PUBLIC_KEY |
64 hex chars | View-only: spend pubkey |
SPEND_SECRET_KEY |
64 hex chars | Optional: spend secret |
Test Categories
1. Wallet Sync & Balance Detection
Test: Full sync from genesis
WALLET_SEED="..." bun test/integration-sync.test.js
Verify:
- CN outputs detected correctly
- CARROT outputs detected correctly
- Subaddress outputs detected (both CN and CARROT)
- Integrated address outputs detected
- Key images computed correctly
- Spent outputs marked as spent
- Balance matches expected value
- Stake/yield outputs identified
Test: Partial sync (resume from height)
START_HEIGHT=10000 WALLET_SEED="..." bun test/integration-sync.test.js
2. TRANSFER Transaction
Test: Send SAL to standard address
WALLET_SEED="..." \
RECIPIENT="SLVx..." \
AMOUNT=1.0 \
DRY_RUN=false \
bun test/transfer-integration.test.js
Verify:
- Transaction builds without error
- CLSAG signatures valid
- Bulletproofs+ range proofs valid
- Transaction accepted by daemon
- Transaction appears in mempool
- Transaction confirmed in block
- Recipient wallet detects the output
- Change output returns to sender
Test: Send to subaddress
- CN subaddress recipient
- CARROT subaddress recipient
Test: Send to integrated address
- Payment ID embedded correctly
- Recipient detects with payment ID
3. STAKE Transaction
Test: Create stake
WALLET_SEED="..." \
STAKE_AMOUNT=100.0 \
DRY_RUN=false \
bun test/stake-integration.test.js
Verify:
- txType = 6 (STAKE)
- unlock_time = current_height + STAKE_LOCK_PERIOD
- source_asset_type = "SAL"
- destination_asset_type = "SAL"
- Transaction accepted by daemon
- Stake output locked until unlock_time
- After unlock, RETURN transaction received
- Yield amount correct per consensus rules
Test: Verify lock period
- Mainnet: 21600 blocks (~30 days)
- Testnet: 20 blocks (for quick testing)
4. BURN Transaction
Test: Burn SAL
WALLET_SEED="..." \
BURN_AMOUNT=0.1 \
DRY_RUN=false \
bun test/burn-integration.test.js
Verify:
- txType = 5 (BURN)
- destination_asset_type = "BURN"
- amount_burnt matches requested amount
- unlock_time = 0 (no lock)
- Transaction accepted by daemon
- Burned coins permanently removed from supply
- Change output returns correctly
Test: Burn SAL1 (if available)
ASSET_TYPE=SAL1 WALLET_SEED="..." BURN_AMOUNT=0.1 bun test/burn-integration.test.js
5. CONVERT Transaction (When Implemented)
Test: Convert SAL to SAL1
WALLET_SEED="..." \
FROM_ASSET=SAL \
TO_ASSET=SAL1 \
AMOUNT=10.0 \
DRY_RUN=false \
bun test/convert-integration.test.js
Verify:
- txType = 4 (CONVERT)
- source_asset_type correct
- destination_asset_type correct
- Oracle price used correctly
- Slippage limit enforced
- Transaction accepted by daemon
- Converted amount received
6. AUDIT Transaction (When Implemented)
Test: Create audit disclosure
WALLET_SEED="..." \
AUDIT_TYPE=full \
DRY_RUN=false \
bun test/audit-integration.test.js
Verify:
- txType = 8 (AUDIT)
- Disclosure data correct
- Transaction accepted by daemon
7. Address Generation
Test: All address types generate correctly
bun test/address-integration.test.js
Verify:
- Legacy (CN) main address - starts with SLVx
- Legacy subaddress - starts with SLVs
- Legacy integrated address - starts with SLVi
- CARROT main address - starts with salv
- CARROT subaddress - starts with salvs
- CARROT integrated address - starts with salvi
- All addresses decode back to correct keys
8. Signature Verification
Test: Verify our signatures against daemon
bun test/signature-verification.test.js
Verify:
- CLSAG signatures we create pass daemon verification
- Bulletproofs+ we create pass daemon verification
- Message signatures verify correctly
9. RPC Methods
Test: All daemon RPC methods work
bun test/rpc.integration.js $DAEMON_URL
Verify:
- getInfo
- getBlockCount
- getBlock / getBlockByHeight
- getTransactions
- sendRawTransaction
- getOuts (for ring member selection)
- getOutputDistribution
- Salvium-specific: getSupplyInfo, getYieldInfo
10. Edge Cases
Multi-input transactions:
- Transaction with 2+ inputs
- Mixed CN and CARROT inputs (if applicable)
Dust handling:
- Very small outputs
- sweepDust function (when implemented)
Error handling:
- Insufficient funds error
- Invalid address error
- Network errors (daemon unreachable)
- Invalid transaction rejection
Test Execution Order
- Wallet Sync - Verify we can scan blockchain correctly
- Address Generation - Verify addresses work
- TRANSFER - Basic send/receive
- STAKE - Staking functionality
- BURN - Burning functionality
- CONVERT - Asset conversion (when ready)
- AUDIT - Compliance features (when ready)
- Edge Cases - Stress testing
Integration Test Scripts Needed
| Script | Status | Description |
|---|---|---|
integration-sync.test.js |
✅ Exists | Wallet sync |
transfer-integration.test.js |
❌ TODO | Send transactions |
stake-integration.test.js |
✅ Exists | Stake creation |
burn-integration.test.js |
✅ Exists | Burn transactions |
convert-integration.test.js |
✅ Exists | Asset conversion (gated at HF v255) |
audit-integration.test.js |
❌ TODO | Audit transactions (only during AUDIT HF) |
address-integration.test.js |
❌ TODO | Address roundtrip |
signature-verification.test.js |
❌ TODO | Sig verification |
Success Criteria
All tests pass with:
- Zero transaction rejections
- Zero balance discrepancies
- Zero parsing errors
- All transaction types confirmed on-chain
- Recipient wallets detect all sent outputs
Notes
- Always use testnet first - never test with real mainnet funds
- Keep test amounts small (0.01-1 SAL)
- Document any daemon version requirements
- Record block heights of test transactions for debugging