85 lines
3.9 KiB
Markdown
85 lines
3.9 KiB
Markdown
# Contractless Browser Core
|
|
|
|
The `core` directory contains the deterministic cryptography and transaction
|
|
codec layer for the Contractless Web3 wallet. Its Rust crate and generated
|
|
WASM package retain the name `contractless-browser-core`.
|
|
|
|
The crate is intentionally independent from the Contractless node runtime. It
|
|
does not connect to RPC servers, broadcast transactions, access PostgreSQL or
|
|
Sled, run Tokio tasks, or read files from the operating system.
|
|
|
|
The browser wallet is responsible for:
|
|
|
|
- obtaining wallet files through browser file APIs;
|
|
- keeping decrypted private keys inside the extension;
|
|
- presenting transaction details for user approval;
|
|
- calling this package to hash, sign, verify, and encode transactions; and
|
|
- sending signed transaction bytes to a configured Contractless PHP API.
|
|
|
|
The initial API exposes:
|
|
|
|
- Skein-128, Skein-256, and Skein-512 hashing;
|
|
- FN-DSA signing and verification;
|
|
- public-key to short-address derivation; and
|
|
- short-address byte encoding and decoding.
|
|
- signed transfer creation and fixed 750-byte transfer decoding.
|
|
- strict inspection and signing for every externally submitted transaction type;
|
|
- signer-role checks against the wallet public key;
|
|
- staged signing for swaps and loans; and
|
|
- exact fixed-width wire encoding for completed transactions.
|
|
- domain-separated website message signing and verification.
|
|
- browser-native wallet generation and AES-256-GCM encrypted storage;
|
|
- direct import from existing Contractless private-key images;
|
|
- direct import from hexadecimal FN-DSA private keys;
|
|
- export compatibility with existing Contractless wallet images; and
|
|
- wallet-registration payload creation.
|
|
|
|
Browser transfer inputs use decimal strings for `value` and `txfee`. This
|
|
prevents JavaScript's numeric precision limit from changing a signed `u64`
|
|
value.
|
|
|
|
Fixed transaction codecs will be added individually and tested against the
|
|
native Contractless implementation before they are used by the wallet.
|
|
|
|
## Wallet storage
|
|
|
|
New browser wallets encrypt their FN-DSA private key with AES-256-GCM. The key
|
|
is derived from the wallet password with PBKDF2-SHA256 and a unique random
|
|
salt. Only the encrypted wallet JSON is stored persistently by the extension.
|
|
|
|
Existing Contractless wallet files can be imported with their encryption key.
|
|
Browser wallets can also be exported back to the existing wallet image format
|
|
for use with the CLI or desktop wallet. The encrypted browser-wallet backup and
|
|
its password are both required for recovery.
|
|
|
|
## Transaction request flow
|
|
|
|
Websites submit unsigned transaction JSON to `inspect_transaction_request`.
|
|
The core rejects unsupported types, missing fields, extra fields, invalid
|
|
addresses, incorrect fixed-width values, and malformed numeric values. The
|
|
returned review object is the canonical data the wallet must show to the user.
|
|
|
|
After approval, `sign_transaction_request` receives the wallet private and
|
|
public keys. The public key determines the wallet address, and that address
|
|
must match the signer role stored in the transaction.
|
|
|
|
For swaps and loans, signer two must also provide signer one's registered
|
|
public key. The core verifies the first signature before adding the second.
|
|
Only a complete transaction receives `bytes_hex` suitable for broadcasting.
|
|
|
|
Genesis and mining reward transactions are intentionally excluded from the
|
|
signing registry because users and websites must never create them.
|
|
|
|
## Website message proofs
|
|
|
|
`sign_message_request` signs a short-lived website proof without creating a
|
|
transaction. The signed payload contains the requesting origin, wallet
|
|
address, message, random nonce, issue time, and expiration time.
|
|
|
|
Message proofs use a Contractless-specific domain prefix. Their signatures
|
|
cannot be reused as transaction signatures. Proofs are limited to 15 minutes,
|
|
and production origins must use HTTPS.
|
|
|
|
`verify_message_proof` verifies the public key, derived wallet address,
|
|
signature, expected origin, expected nonce, and current validity window.
|