Initial setup

Default path targets Plume Mainnet. You’ll end up with Mongo + API (Docker) and the product UI on the host.

Quick start: pnpm install && REUSE_TAP_FACTORY=1 pnpm bootstrap, set NEXT_PUBLIC_* in .env and app/.env.local, then pnpm app:dev. Server PRIVATE_KEY is optional for the wallet UI.

Secrets and env files

Three wallets / keys

These are easy to conflate. They are not the same wallet.

RoleWhat it controlsWhere it livesNeeded for golden path?
Factory ownerBeacon upgrades for that factory’s cap tables (updateCapTableImplementation)Cold / hardware / vault. Used only for rare deploy or upgrade CLI runsNo for day-to-day product work
Issuer ADMINThe wallet that called createCapTable — governance + day-to-day writes (admins count as operators onchain)Browser wallet in /appYes — connect an extension wallet
Server / operatorAPI process signing server-side txs (/*/create, API transfer, etc.). Often the address passed as operator at mintRoot .envPRIVATE_KEY (key) and NEXT_PUBLIC_OPERATOR_ADDRESS (address only)No if you only use the wallet UI + poller

What to do in practice

  • Wallet-first /app UI — ADMIN signs in the browser. Poller needs RPC only. Leave PRIVATE_KEY=UPDATE_ME (or unset). Server runs read-only for chain writes; that is expected. ADMIN alone is enough for the manage UI.
  • NEXT_PUBLIC_OPERATOR_ADDRESS — an address granted OPERATOR_ROLE on new mints (for server/automation later). Setting it does not put a key on the server. You only need that private key in .env if the API itself will sign as operator.
  • Factory owner key — never put this in the long-running Docker/API env. Compromise would let an attacker upgrade every cap table on that factory. Inject only for a one-shot pnpm deploy-factory or upgrade script (separate env file / CI secret), then remove.
  • Shared Plume demo factory (0xcd6…) — owner is TAP Admin (0x366a…), not your issuer wallet. Reusing it does not make you factory owner.
⚠️

PRIVATE_KEY in local .env is dev/demo only. Optional for the wallet-first path. Never put production or factory-owner keys here. Do not commit real keys.

1. Root .env

cp .env.example .env

.env.example defaults to Plume (CHAIN_ID=98866, RPC_URL=https://rpc.plume.org). Typical local values:

VariablePurpose
PRIVATE_KEYOptional for wallet UI. Funded dev key only if you need server-signed API routes or CLI deploy-factory from this machine. Demo placeholder is fine otherwise.
NEXT_PUBLIC_OPERATOR_ADDRESSAddress granted OPERATOR_ROLE on new cap tables (often a server/ops address; not a private key)
NEXT_PUBLIC_FACTORY_ADDRESSFactory the app mints against

2. Frontend app/.env.local

Host pnpm app:dev reads app/.env.local, not only root .env. Copy the same NEXT_PUBLIC_* values there. Bootstrap creates a starter file if missing.

Wallet connection is first-party (EIP-6963). Install a browser extension (Rabby, MetaMask, etc.) — no third-party cloud account required.

Bootstrap the stack

# Demo / issuer-dev: register TAP’s shared Plume factory in Mongo (owner is TAP Admin, not you)
REUSE_TAP_FACTORY=1 pnpm bootstrap
 
# Transfer-agent path: after bootstrap with no factory, deploy your own instead
# pnpm deploy-factory

Bootstrap is idempotent: deps, contract build (chain/out), Docker volume, compose up, API health, optional factory register.

ServiceURL
APIhttp://localhost:8293
Product UIpnpm app:devhttp://localhost:3000/app
MongoDBlocalhost:27017

Prefer host pnpm app:dev for wallet work. Docker app is optional.

Demo reuse vs your own factory

PathCommandYou own beacon upgrades?
Shared demo factoryREUSE_TAP_FACTORY=1 pnpm bootstrapNo (protocol builder / TAP Admin)
Your TA factorypnpm deploy-factoryYes

Issuers can mint cap tables on either factory (createCapTable is permissionless). Using the demo factory is normal for local product work; production transfer agents should deploy their own.

Anvil (local chain) alternate

For pure contract tests without Plume:

# .env: RPC_URL=http://127.0.0.1:8545 CHAIN_ID=31337 + Anvil PRIVATE_KEY
anvil
pnpm setup
pnpm deploy-factory
pnpm docker:up   # or bootstrap without REUSE_TAP_FACTORY

Anvil keys are test-only — never use them on mainnet.

Next: Run server / app and Deploy factory.