# Contractless Web3 Wallet

This repository contains the Contractless browser wallet, its browser-safe
cryptography and transaction codecs, and the JavaScript SDK used by websites
to communicate with the wallet.

## Repository Structure

```text
web3_wallet/
|-- core/       Rust and WebAssembly wallet cryptography and transaction codecs
|-- extension/  Browser extension source and distributable wallet interface
|-- sdk/        JavaScript library for website and application integration
|-- tests/      Integration tests and complete working SDK usage examples
`-- mockups/    Design references used while developing the wallet interface
```

The components remain separated internally because they have different
responsibilities:

- `core` handles deterministic hashing, keys, wallet encryption, transaction
  inspection, encoding, signing, and message proofs.
- `extension` owns wallet storage, approvals, application sessions, API
  communication, and the browser interface.
- `sdk` gives websites a stable interface for detecting, connecting to, and
  requesting actions from the installed wallet.
- `tests` verifies wallet integration and provides complete working example
  code for every supported SDK operation.

The SDK can be published independently later without separating the wallet's
source today.

## Build the Browser Extensions

Install Rust, `wasm-pack`, Node.js, and pnpm. From `extension`:

```text
pnpm install
pnpm run build
```

The build compiles separate testnet and mainnet versions of `core` to
`extension/src/wasm/testnet` and `extension/src/wasm/mainnet`. Both cores are
bundled into each browser package so the wallet can enforce the selected
network's address format and transaction codecs locally. Vite then creates
separate unpacked packages:

```text
extension/dist/chrome/
extension/dist/firefox/
```

Build a single browser target with:

```text
pnpm run build:chrome
pnpm run build:firefox
```

The wallet stores testnet and mainnet API URLs separately. Testnet defaults to
`https://api.contractless.dev`; mainnet remains unconfigured until a mainnet
API is available. Wallets and active website sessions are isolated by network,
and changing networks locks the active wallet.

See `extension/README.md` for temporary installation, Firefox validation,
packaging, and Mozilla source-submission instructions.

## Development Checks

Run the Rust tests from `core`:

```text
cargo test
```

Run the TypeScript check from `extension`:

```text
pnpm run check
```

## Website Integration

Websites should use `sdk/contractless.js` instead of communicating with the
injected browser provider directly. See `sdk/README.md` for connection,
session, message-signing, and transaction-signing examples.

Private keys remain inside the extension. Websites receive only approved
addresses, signatures, signed transaction bytes, and session-scoped access
keys.

## Integration Test

The `tests/tests.html` page verifies that a website can detect the extension,
request a connection, retrieve the authorized wallet address, and disconnect
the temporary application session. It also contains editable, copyable,
end-to-end transaction examples for transfers, tokens, NFTs/RWAs, marketing,
burning, and vanity addresses. Successful requests display the
returned transaction ID, complete signed bytes, byte count, and API broadcast
reply.

The tests are also the complete example-code documentation for using the SDK.
Each available wallet action includes working source that developers can view,
copy, and adapt directly for their own applications. This covers wallet
detection, connection and session handling, address and balance requests,
message signing, single-signature transactions, data transactions, and the
complete dual-signature swap and loan process.

The dual-signature examples use the included PHP JSON storage endpoint. Serve
the repository from its root directory with PHP:

```text
php -S 127.0.0.1:8080 -t .
```

Then open:

```text
http://127.0.0.1:8080/tests/tests.html
```

PHP creates `tests/storage/dual-signatures/<transaction-hash>.json` when the
first wallet signs. The second wallet loads and updates that record, and the
broadcast example loads both signatures from it. The web-server user must be
able to write to `tests/storage`. JSON is used only to keep the example easy
to follow; applications can use any backend language or database.

The unpacked browser extension must be installed and the wallet must be
unlocked before approving the connection request. Opening the page through a
`file://` URL is intentionally unsupported because it has no trustworthy
website origin.
