# Wallet and dApp

## Wallet + dApp Integration

This page focuses on “Ethereum-style” connectivity:

* dApps discover a `trac-peer` via a URL
* dApps fetch schema + context from the peer RPC
* wallets sign (they do not run peers)

### What a wallet signs (contract tx)

A `trac-peer` contract transaction is an MSB operation of `type = 12`.

The wallet signs a 32-byte hash (`tx`) computed from:

* MSB tx context (from `GET /v1/contract/tx/context`)
* the typed command `{ type, value }` (hashed as `ch`)
* a nonce (`in`)

Important: this is **not** a TNK transfer. There is no `to`/`amount` field in a contract tx.

Users can still pay MSB fees for the tx.

### Required RPC reads for signing

1. Contract schema (what exists):

* `GET /v1/contract/schema`

2. Nonce:

* `GET /v1/contract/nonce`

3. Tx context:

* `GET /v1/contract/tx/context`

This returns (names as used in MSB payloads):

* `networkId`
* `txv`
* `iw`
* `bs` (subnet bootstrap)
* `mbs` (MSB bootstrap)
* `operationType` (currently `12`)

### Wallet signing payload shape (recommended)

The wallet extension API used in this workspace exposes `window.tracnetwork`.

For contract tx signing, a typical payload is:

```json
{
  "prepared_command": { "type": "catch", "value": {} },
  "nonce": "<hex32>",
  "context": {
    "networkId": 918,
    "txv": "<hex32>",
    "iw": "<hex32>",
    "bs": "<hex32>",
    "mbs": "<hex32>",
    "operationType": 12
  }
}
```

The wallet should:

* compute `ch = blake3(JSON.stringify(prepared_command))`
* compute `tx = blake3(createMessage(networkId, txv, iw, ch, bs, mbs, nonce, operationType))`
* sign `tx` bytes with the active account’s private key

The dApp should also read the user’s public key (hex) via `window.tracnetwork.getPublicKey()` and use it as the `address` field when calling `POST /v1/contract/tx`.

### Simulate first, then broadcast

Recommended client flow:

1. submit the signed payload with `sim=true`
2. if OK, submit the same payload with `sim=false`

Both are `POST /v1/contract/tx`.

If `sim=true` fails due to missing MSB entry or insufficient fee balance, do not broadcast.

### Security model notes

* The peer validates signatures and MSB constraints. A dApp cannot “swap” the command type/value after the wallet signs, because that changes `ch` and `tx`.
* A contract tx cannot transfer TNK to a recipient. If you ever add native transfer support, it must be a different MSB operation type and the wallet UI must surface `to/amount`.
