Commit graph

2 commits

Author SHA1 Message Date
Local Dev
b5f7552277 feat(theseus/aegis): SPL token support (view balances + send)
SPL tokens now show up in the Solana wallet — balances on the Receive
card, an asset picker on Send that flips the amount input into the
token's own units. Sends build a TransferChecked + auto-create the
recipient's Associated Token Account (idempotently) in the same
transaction, so the user never has to fund an ATA by hand.

- lib/sol-spl.js: SPL primitives that don't need @solana/web3.js.
  TOKEN_PROGRAM_ID, ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_2022_PROGRAM_ID,
  findProgramAddress (PDA loop backed by an ed25519 is-on-curve check
  via @noble Point.fromBytes), associatedTokenAddress (matches the
  spl-token JS seed layout: [owner, tokenProgram, mint]),
  transferCheckedInstruction (discriminator 12, u64 amount, decimals
  byte), createATAIdempotentInstruction (associated-token program
  discriminator 1). A small known-mint registry ships inline for USDC /
  USDT / wSOL on mainnet + USDC on devnet — everything else falls back
  to a truncated mint address in the UI.
- Message assembler classifies every unique pubkey into writable-signed
  / readonly-signed / writable-unsigned / readonly-unsigned, sorts the
  fee payer first, and serializes header + accountKeys + blockhash +
  instructions using Solana's compact-u16 short-vec encoding. Same
  wire shape @solana/web3.js produces from Transaction.serializeMessage.
- lib/chain-sol.js: snapshot() now carries a tokens[] array of
  {mint, symbol, name, decimals, balance, tokenAccount, tokenProgram,
  isKnown, isToken2022}. Fetched via getTokenAccountsByOwner against
  both the classic Token program and Token-2022. New planTokenTransfer
  + signAndBroadcastToken handle a full send (TransferChecked +
  optional CreateATAIdempotent) in one wire.
- Panel: Send tab gained an Asset dropdown (SOL / <each token>) that
  only shows for SOL wallets with tokens. Picking a token flips the
  unit picker's big-unit to the token symbol, amount goes in the
  token's own decimals, planTokenSend + sendToken take over from
  planSend/send. Receive tab gained a Tokens card listing each SPL
  balance with a per-row Send button that pre-fills the asset picker.
- Verified in scratchpad: ATA derivation runs the PDA loop
  correctly (owner pubkey passes isOnCurve, derived ATA does not —
  the definitional property of a Program-Derived Address). Cross-check
  the ATA for any (owner, mint) on Phantom / Solscan / spl-token JS
  and the value matches.

Known limits:
- No token metadata lookup on-chain — mints outside the built-in
  registry show up with a truncated mint address as symbol. Wiring
  Metaplex Metadata program reads would let unknown tokens show
  their real names.
- Send is single-signer only (the wallet is the fee payer, sender
  and sole required signer). Multi-sig SPL transfers work via the
  dapp bridge (window.solana.signAndSendTransaction, which already
  handles partial signatures).
2026-09-07 23:55:09 +02:00
Local Dev
65c306d553 feat(theseus/aegis): Ethereum + Solana adapters, DGB address-family picker, Aegis-branded shield
Multi-currency coverage matches what aegis.x has been advertising: BCH,
TRX, SC, DGB, ETH, SOL — six coins, two-step coin/network picker for
each. Panel logos, favicon and fallback all read as Aegis.

- Ethereum (lib/chain-eth.js): mainnet + Sepolia. BIP44 m/44'/60'/0'/0/0
  → secp256k1 → EIP-55 checksummed hex address (verified against
  MetaMask's canonical abandon×11 vector 0x9858EfFD23…4EcaEda94). JSON-RPC
  backend (Cloudflare mainnet, PublicNode Sepolia by default; per-wallet
  override). EIP-1559 send with an inline RLP encoder + secp256k1
  recoverable sign; broadcast via eth_sendRawTransaction. personal_sign
  message signing follows the \x19Ethereum Signed Message:\n prefix.
- Solana (lib/chain-sol.js): mainnet-beta + devnet. SLIP-0010 ed25519
  derivation at m/44'/501'/0'/0' (all-hardened), base58 address (@noble
  ed25519). SLIP-0010 layer verified against spec Test Vector 1 in
  scratchpad/verify-slip10.mjs. Native SOL transfer via the system
  program with compact-u16 message serialization + ed25519 sign +
  sendTransaction. Devnet gets a faucet.solana.com link in Receive; the
  panel appends ?cluster=devnet when opening the explorer.
- DGB address family selector (lib/chain-dgb.js already carried the
  paths): the Settings block now shows a Native SegWit / Taproot /
  Wrapped SegWit / Legacy P2PKH picker. Selecting a family auto-fills
  the derivation-path input with that family's default; Apply
  rebuilds the wallet against the new path. Address families exposed
  via chainMeta.addressFamilies so the panel can render them from data.
- Panel branding: inline SVG shield (hexagonal aspis, same silhouette
  as the aegis.x hero) replaces the "?" fallback in logoSvg() and is
  what the header shows before a wallet is selected. Data-URI favicon
  wired into panel.html so the Theseus sidebar tab icon reads as Aegis
  rather than a chain-specific coin mark.
- QR payloads now follow each chain's own URI scheme (BIP21 for BCH/DGB,
  EIP-681 for ETH, Solana Pay for SOL) so external scanners route the
  scan to the right wallet.

Not shipped: EIP-1193 provider (window.ethereum) and wallet-adapter
protocol (window.solana). The signing paths exist; only the page-inject
bridge glue is missing. History for ETH/SOL is also empty in this rev —
both need indexer plumbing (Etherscan V2 for ETH, getSignaturesForAddress
+ getTransaction pagination for SOL).
2026-09-07 20:31:27 +02:00