Skip to content

Latest commit

 

History

History
135 lines (97 loc) · 6.12 KB

File metadata and controls

135 lines (97 loc) · 6.12 KB

Deployment runbook — Coston2

End-to-end order of operations. Steps are sequential; each depends on the previous one.

0. Prerequisites

  • Foundry, Docker, Go ≥ 1.23, Node ≥ 22, an HTTPS tunnel (ngrok or cloudflared)
  • A Coston2-funded key: faucet
  • Coston2 indexer DB credentials from Flare support — the extension proxy cannot start without them, and they are issued by a human. Request them first; everything else can proceed while you wait, except steps 3+.
  • The FCC scaffold: git clone https://github.com/flare-foundation/fce-extension-scaffold.git

1. Deploy WraithOrders

Both registry constructor args are the FlareTeeManager diamond proxy — the diamond serves the extension-registry and machine-registry facets from one address. The scaffold does the same (tools/pkg/utils/instructions.go: "Both registry args are the FlareTeeManager diamond proxy").

On Coston2 that address is:

0x1a9C4A0f9D76c0b1D91d22E24E573a9b377618aE

It is read from the scaffold's config/coston2/deployed-addresses.json. FCC is pre-release, so it is not in the FlareContractRegistry yet and can change between deployments — re-check it if deployment reverts.

cd contracts
export TEE_EXTENSION_REGISTRY=0x1a9C4A0f9D76c0b1D91d22E24E573a9b377618aE
export TEE_MACHINE_REGISTRY=0x1a9C4A0f9D76c0b1D91d22E24E573a9b377618aE
export BLAZESWAP_ROUTER=0x8D29b61C41CF318d15d031BE2928F79630e068e6   # enables swap settlement
export FXRP_ASSET_MANAGER=0xc1Ca88b937d0b528842F95d5731ffB586f4fbDFA # enables redeem settlement

forge script script/Deploy.s.sol \
  --rpc-url https://coston2-api.flare.network/ext/C/rpc \
  --broadcast --private-key $DEPLOYER_KEY

Resolve AssetManagerFXRP yourself rather than trusting a copied address — it is in the registry, and its fAsset() tells you the FXRP token in the same breath:

REG=0xaD67FE66660Fb8dFE9d6b1b4240d8650e30F6019
AM=$(cast call $REG 'getContractAddressByName(string)(address)' AssetManagerFXRP --rpc-url $COSTON2_RPC)
cast call $AM 'fAsset()(address)' --rpc-url $COSTON2_RPC   # → 0x0b6A3645c240605887a5532109323A3E12273dc7

If the deploy ran without those two optional vars, wire them afterwards — both are owner-only:

cast send $WRAITH 'setAssetManager(address)' $AM        --rpc-url $COSTON2_RPC --private-key $DEPLOYER_KEY
cast send $WRAITH 'setRouter(address)'       $ROUTER    --rpc-url $COSTON2_RPC --private-key $DEPLOYER_KEY

Cross-chain and consensus orders additionally need the FDC verifier. It lives in the registry, so resolve it rather than pasting an address:

FDC=$(cast call $REG 'getContractAddressByName(string)(address)' FdcVerification --rpc-url $COSTON2_RPC)
cast send $WRAITH 'setFdcVerification(address)' $FDC --rpc-url $COSTON2_RPC --private-key $DEPLOYER_KEY

Without it, tickAttested and tickAttestedWeb2 revert with FDC verification not set and the two attested kinds never fire — deliberately, since an order that asked for a verified second source must not settle without one.

contracts/.env.deploy holds these for local use and is gitignored. Source it with set -a && . ./.env.deploy && set +a.

2. Graft the extension onto the scaffold

Follow extension/README.md: copy the Wraith OPType/OPCommand into the scaffold's config, route WRAITH/EVAL_ORDER to the Wraith handler, and point the scaffold's registration at the deployed WraithOrders address (it is its own InstructionSender).

3. Register and start the TEE stack

In the scaffold, with .env configured (SIMULATED_TEE=true, LOCAL_MODE=false, tunnel URL in EXT_PROXY_URL, indexer credentials in the proxy TOML):

./scripts/pre-build.sh          # registers the extension → extension ID
./scripts/start-services.sh --chain coston2
./scripts/post-build.sh         # registers the TEE machine

Do not re-run pre-build.sh --force casually — it mints a new extension ID while the TEE machine stays bound to the old one (MachineManager.TooMany()).

4. Wire the contract to the running stack

# Once registration is confirmed on-chain:
cast send $WRAITH "setExtensionId()" --rpc-url $RPC --private-key $DEPLOYER_KEY

# No TEE address to register — execute() reads the active machine set from
# TeeMachineRegistry directly, so post-build.sh registering the machine is
# the only step needed. Confirm it landed:
cast call $TEE_MACHINE_REGISTRY "getActiveTeeMachines(uint256)(address[],string[])" \
  $EXTENSION_ID --rpc-url $RPC

5. Start the keeper

cd keeper && npm install
export WRAITH_ADDRESS=$WRAITH KEEPER_PRIVATE_KEY=0x... EXT_PROXY_URL=https://<tunnel>

# Optional: the second oracle consensus orders need. Unset, they never fire.
export FDC_API_URL=https://api.coingecko.com/api/v3/simple/price
export FDC_QUERY_PARAMS='{"ids":"flare-networks","vs_currencies":"usd","include_last_updated_at":"true"}'
# No API key needed on Coston2: the verifier and DA Layer both accept Flare's
# published key, and the keeper defaults to it.

npm start

6. Start the frontend

cd frontend && npm install
cp .env.example .env.local      # fill in WRAITH_ADDRESS, FXRP, TOKEN_OUT, proxy URL
npm run dev

To offer gasless order creation, fund a separate key with C2FLR and set both halves — the server key that signs, and the public flag that reveals the option:

RELAYER_PRIVATE_KEY=0x...          # server-side only, never NEXT_PUBLIC_
NEXT_PUBLIC_RELAYER_ENABLED=true

The relayer reimburses itself out of the escrowed token, so it needs only enough C2FLR for gas. Leaving the flag unset hides the option, which is the right default: offering a gasless path that then fails is worse than not offering one.

Smoke test

  1. Create an order in the UI with a trigger that is currently false. Confirm the explorer shows only ciphertext.
  2. Watch the keeper tick it; confirm no execution (the TEE returns a no-op).
  3. Create an order whose trigger is already true. Confirm the keeper relays the signed result and execute() settles it.
  4. cast call $WRAITH "getOrder(uint256)" <id> — confirm executed == true and the actionId cannot be replayed.