# Advanced: automate setup from the command line

**The recommended way is the dashboard**: create your handle and product at https://sub3.dev/sandbox/dashboard
first, then the same on https://sub3.dev/dashboard when you go live. Do it yourself, with your own wallet: it
decides where the money goes and who controls it. This page is for people who want to script the same setup.

`sub3.mjs` is the optional management CLI: one file whose only dependency is `viem`. Every sub3 site serves it at
`/sub3.mjs`, set to that site's network; the source is [cli/sub3.mjs](cli/sub3.mjs). It signs with the owner
wallet's private key, so run it in your own terminal and never hand the key to a coding agent.

```sh
curl -fsSO https://sub3.dev/sub3.mjs && npm install viem
export SUB3_ENVIRONMENT=sandbox    # build and test on the sandbox first; production when you go live
node sub3.mjs help
```

Handles are registered separately on the sandbox and on production: register your production handle early to
keep the name.

## 1. Register the merchant handle

The handle (`acme`) is permanent and costs $20, paid once to sub3. The owner wallet can later change the website
and the payout address, and can transfer the merchant.

```sh
export SUB3_PRIVATE_KEY=0x…        # the owner wallet; keep it out of prompts, files and git
node sub3.mjs merchant register acme --url https://acme.com --pay-to 0xYourPayoutAddress
# prints the plan and simulates the approval of the $20 fee; nothing is sent
node sub3.mjs merchant register acme --url https://acme.com --pay-to 0xYourPayoutAddress --send
```

Without `SUB3_PRIVATE_KEY` the CLI still validates and prints the transaction (`to`, `data`, `chainId`) for
another signer; `--from <address>` simulates as that wallet.

## 2. Create a product and its items

```sh
node sub3.mjs product create acme/app --name "Acme App" \
  --tier basic:1:5:Basic --tier pro:2:20:Pro \
  --lifetime forever:99:Forever \
  --pack credits:5:1000:"1000 credits"
```

| Option       | Format                          | Meaning                                                                            |
| ------------ | ------------------------------- | ---------------------------------------------------------------------------------- |
| `--tier`     | `key:level:monthlyPrice[:name]` | A subscription. 12 months cost 10. One tier per user; a higher level is an upgrade |
| `--lifetime` | `key:price[:name]`              | Bought once, owned forever                                                         |
| `--pack`     | `key:price:credits[:name]`      | Bought any number of times; your backend credits each receipt once                 |

Prices are dollars (`5`, `4.99`, at least `0.10`); the CLI converts them with the stablecoin's decimals (6 to 18, from `GET /v1/network`). Keys use `a-z`, `0-9` and inner `-`: handles 3–32 characters,
product and item keys 1–32. **Handles and keys never change**; names and prices can. A product has at most 32
items. The CLI checks all of this, and that the signer owns the merchant, before simulating.

Change items later. Existing memberships keep their end date; a new price applies to later payments:

```sh
node sub3.mjs item set acme/app tier pro:2:25:Pro --send        # change a price, or add a new item
node sub3.mjs item disable acme/app basic --send                # stop selling; nothing already bought changes
node sub3.mjs product show acme/app
```

An item never changes kind; use a new key instead. `item set` on a disabled item puts it back on sale.

## 3. Verify the domain

Publish `https://acme.com/.well-known/sub3.json` (on the host of the merchant URL; each product site serves its
own copy too, and never needs the merchant URL changed):

```json
{ "merchant": "acme", "logo": "/logo.png" }
```

The logo is a path on that host or an `https://` URL on any host; PNG, JPEG, WebP or SVG; at most 256 KB. Then:

```sh
node sub3.mjs verify acme        # explains exactly what is wrong; sub3 caches results for 10 minutes
```

Verified merchants show their logo, `@acme` and ✓ on the hosted sign-in and checkout pages.

## 4. Watch it

```sh
node sub3.mjs merchant show acme
node sub3.mjs stats acme/app
```

## Environment

| Variable           | Meaning                                                                                             |
| ------------------ | --------------------------------------------------------------------------------------------------- |
| `SUB3_ENVIRONMENT` | `production`, `sandbox` or `local` (default: the site the file came from; `production` from source) |
| `SUB3_API`         | Use this API origin instead; the network, contract and token come from its `GET /v1/network`        |
| `SUB3_PRIVATE_KEY` | The owner wallet. Needed for `--send`                                                               |
| `SUB3_RPC_URL`     | Optional RPC for simulating and sending; defaults to the network's public RPC                       |
| `SUB3_SITE`        | Optional, for the checkout link printed after `product create` with a custom `SUB3_API`             |

Agents: setup is the developer's job, not yours. Never ask for or handle `SUB3_PRIVATE_KEY`, and never run
`--send`. If the developer's product does not exist yet, ask them to create it in the dashboard.
