Branch: web-wallet/create-seedelf, created from seedelf-web-wallet after PR #251 (chunk 7) is merged. It ends with a PR back into seedelf-web-wallet.
This is the first script spend in the web wallet. Every Seedelf spend in chunks 9 and 10 (transfer, sweep, remove) reuses what this chunk builds: owned contract inputs with Schnorr proofs, a one-time key, reference scripts, giveme.my collateral, and evaluation through Ogmios.
git checkout seedelf-web-wallet && git pull
git log --oneline HEAD..origin/main # merge main first if this lists anything
git checkout -b web-wallet/create-seedelf
seedelf-cli/src/commands/util/mint.rs (about 500 lines), and the helpers it uses in seedelf-core/src/transaction.rs (seedelf_token_name, extract_budgets, total_computation_fee, seedelf_minimum_lovelace, collateral_input, reference_utxo), seedelf-core/src/data_structures.rs (the redeemers), and seedelf-cli/src/commands/fee.rs (the collateral output and even rounding).extension/.preprod-test-wallet.txt (gitignored). The user funds its receive_0 from the faucet.npm run build && node e2e/live/move-in.mjs 10.util mint does todayseedelf-cli/src/commands/util/mint.rs, which becomes network-free builders plus a thin run():
collect_wallet_utxos, which skips UTxOs holding a Seedelf) worth the Seedelf minimum (about 1.5 ADA) plus a fee guess.seedelf_token_name(label, inputs), which is 5eed0e1f ‖ the label (at most 15 bytes) ‖ the index of the lexicographically smallest input ‖ its tx id, cut to 32 bytes.pkh is a required signer, and so is COLLATERAL_HASH.create_proof(register, sk, pkh) gives (z, g_r). The proof is bound to pkh, which is the rollback-replay defence.evaluate_transaction (Koios /ogmios, JSON-RPC evaluateTransaction) gives budgets.extract_budgets reads them in response order, and split_last treats the last one as the mint.(seedelf_size + wallet_size) × 15.{ tx: cbor } to giveme.my. It answers { witness }, whose last 64 bytes are the collateral key’s signature. Sign with the one-time key, add that signature, then submit.| Decision | Suggestion | Notes |
|---|---|---|
| Label (personal tag) | Optional; printable ASCII, at most 15 characters, with a live preview of how it will read | On chain it’s any bytes, cut to 15. Multi-byte text could be cut mid-character, and the wallet reads tags back as printable ASCII (seedelfLabel in chain.ts). |
| When giveme.my is contacted | At Send, not at Review | Draft, evaluate and finalize happen at Review, so the user sees the real fee. The collateral witness is fetched only once the user commits. |
| The Seedelf’s register | A fresh re-randomization of the user’s own base register | The CLI can also mint to someone else’s register (--generator/--public-value). The web wallet doesn’t need that in v1. |
| Which UTxOs pay | Automatic, from the Seedelf balance (as in the CLI’s select) |
Privacy: few inputs, and never the Cardano account (privacy rule 5). |
| Minimum balance | Show the cost up front: about 1.5 ADA locked with the Seedelf, plus about 0.3–0.6 ADA in fees | Only remove gets the locked ADA back (chunk 10). |
seedelf-core/src/build.rs)script_fee(size, budgets, …) helper.draft(…) -> StagingTransaction with placeholder ex-units, then finalize(draft, budgets) -> BuiltTransaction.validator.purpose (spend or mint) and validator.index, not by response order. Check how Ogmios orders the result on a real response, and keep extract_budgets working for the CLI.build::mint_*: extracted from util mint. The CLI’s run() becomes thin, and seedelf-cli/tests/cli/mint.rs must stay green.seedelf-core/tests/):
pkh (schnorr::prove).SeedelfSpend (or MintBuilder) object that lives in the worker for one mint:
new(key, requestJson): makes the one-time key inside WASM, the proofs, and the draft. Returns the draft CBOR.finalize(ogmiosJson): returns the final unsigned CBOR plus a summary (token name, fee parts, change).sign(collateralWitnessJson):
COLLATERAL_PUBLIC_KEY over the tx hash before adding it.free(): drops the one-time key.evaluate(cborHex) via POST /ogmios with the JSON-RPC body above. Surface Ogmios script errors in plain words.collateral.ts: the giveme.my client, POST { tx } to NETWORKS[network].collateral. The host permission is already in the manifest.move-in.ts:
balances.ts does), run the builder, evaluate, finalize. Keep the builder until Send, or rebuild if the worker restarted; a builder is in-memory only.pending-tx watch.mint especially). seedelf-wasm native tests: proofs verify, the collateral witness check refuses a wrong signature, and the one-time key signs.evaluate, the giveme.my client, and the mint service over fakes. Fixtures:
seedelf-cli/tests/cli/harness.rs mocks both and is a good reference.seedelf-platform/CLAUDE.md (what’s extracted now), and the READMEs.collateral_output errors if 1.5 × fee > 5 ADA.Transfer (chunk 9), sweep and remove (chunk 10), minting to someone else’s register, and the CLI’s create (paid by an outside wallet, which links it).