# dra.gd agent guide

Use dra.gd to publish one complete HTML file as Ethereum contract bytecode. The application does not require a backend.

## Contracts

- Ethereum mainnet HTMLFactory: `0xff228259deeedba7047c758cf5b798bdb0f70787`.
- Arbitrum One HTMLFactory: `0xa8ca4d705d61d3ab438dbf0aae0b8ad147d0b45f`.
- HTML contains the exact HTML bytes as runtime bytecode.
- HTMLViewer owns a current HTML address and its version history. Call `html()` to read the current document.

The maximum HTML size is 24,576 UTF-8 bytes.

## Publish with curl and Node.js

Install Node.js 20 or later and install `ethers` in the current directory:

```sh
npm install ethers
```

Set the deployment values:

```sh
export RPC_URL=https://eth.drpc.org
export PRIVATE_KEY=0x...
export HTML_FACTORY_ADDRESS=0xff228259deeedba7047c758cf5b798bdb0f70787
```

Inspect `https://dra.gd/deploy.mjs` before you run it. Then publish an HTML file:

```sh
curl -fsSL https://dra.gd/deploy.mjs \
  | node --input-type=module - ./index.html
```

The command writes transaction hashes to standard error. It writes the new HTMLViewer address to standard output.

To revise an existing page, set its HTMLViewer address and run the same command:

```sh
export VIEWER_ADDRESS=0x...
curl -fsSL https://dra.gd/deploy.mjs \
  | node --input-type=module - ./index.html
```

A new publication uses one transaction. A revision uses two transactions. Never put a private key in an HTML file or command argument. Use a test wallet first.

## Read HTML

Call `html()` on an HTMLViewer with an Ethereum RPC. The function selector is `0x33c34ac3`.

```sh
cast call VIEWER_ADDRESS 'html()(string)' -r https://eth.drpc.org
```

## Connecting domain names

Create a small `index.html` file that calls `html()` on the HTMLViewer. Use a public RPC URL that permits browser CORS requests.

```html
<!doctype html>
<meta charset="utf-8">
<body id="status">Load HTML from Ethereum.</body>
<script>
const viewer = "0x...";
const rpc = "https://eth.drpc.org";

(async () => {
  const response = await fetch(rpc, {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify({
      jsonrpc: "2.0",
      id: 1,
      method: "eth_call",
      params: [{ to: viewer, data: "0x33c34ac3" }, "latest"]
    })
  });
  const reply = await response.json();
  if (reply.error) throw new Error(reply.error.message);

  const data = reply.result.slice(2);
  const offset = Number(BigInt("0x" + data.slice(0, 64))) * 2;
  const length = Number(BigInt("0x" + data.slice(offset, offset + 64)));
  const bytes = new Uint8Array(length);
  for (let i = 0; i < length; i++) {
    bytes[i] = parseInt(data.slice(offset + 64 + i * 2, offset + 66 + i * 2), 16);
  }

  document.open();
  document.write(new TextDecoder().decode(bytes));
  document.close();
})().catch((error) => { document.getElementById("status").textContent = error.message; });
</script>
```

Replace `viewer` with the HTMLViewer address. Replace `rpc` if the HTMLViewer is on another network. Host this file at the domain root. The file reads and shows the stored HTML without an iframe or backend.
