Repository navigation
Expand file tree
/
Copy pathrender.yaml
More file actions
102 lines (100 loc) · 5.29 KB
/
Copy pathrender.yaml
File metadata and controls
102 lines (100 loc) · 5.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# Render Blueprint — combined VELA backend + Postgres (free tier).
#
# Deploys the single-process backend (@vellar/all-in-one: gateway + wallet +
# lifecycle + policy) as one free web service, plus a free Postgres.
#
# MAINNET since 2026-09-20 (see docs/decisions.md): the x402 payment gate on
# /lifecycle/execute and /verification/:contractId settles real mainnet USDC,
# so every Stellar endpoint below (RPC, Horizon, passphrase, network, relayer)
# must point at mainnet, not testnet.
#
# Free-tier caveats (STILL APPLY on mainnet — this is about Render's plan,
# not the Stellar network):
# - the web service SLEEPS after 15 min idle (~1 min cold start on next hit)
# — a real cost/UX risk now: a paying caller can hit a cold-starting
# instance. See docs/decisions.md for the 2026-09-19 hibernation incident.
# - the free Postgres EXPIRES 30 days after creation (14-day grace)
# For a non-expiring DB, swap in an external Postgres (e.g. Neon) and set
# DATABASE_URL as a secret instead.
#
# Secrets NOT in this file (set them in the Render dashboard, marked sync:false):
# RELAYER_API_KEY, SPONSOR_SECRET_KEY, SPONSOR_PUBLIC_KEY
# ⚠ VERIFY THESE ARE MAINNET CREDENTIALS after this cutover. Flipping
# RELAYER_BASE_URL/network config here does NOT change what's already set
# in the Render dashboard — a leftover testnet API key or sponsor secret
# paired with mainnet endpoints will fail (or worse, silently mismatch)
# rather than fixing anything. Confirm in the dashboard before relying on
# wallet creation/submission after this deploy.
services:
- type: web
name: vellar-backend
runtime: node
plan: free
# CD gate (security-audit.md M9 / FIX 11): do NOT auto-deploy on every push
# to the tracked branch. Deploy manually (or from a tagged release) AFTER CI
# is green, so an unreviewed/broken commit can't ship a tsx-run backend with
# live signing keys before the checks run.
autoDeploy: false
# Render runs from the repo root; install the workspace, then start the
# combined backend. (The SDK is a published npm dep — nothing to pre-build.)
# The backend runs under tsx, which strips types WITHOUT checking them, so
# there is no compile step to catch a type error. Typecheck all-in-one and
# every workspace package it depends on as part of the build, so a commit
# that doesn't typecheck fails the deploy instead of shipping.
buildCommand: "corepack enable && pnpm install --frozen-lockfile && pnpm exec turbo run typecheck --filter=@vellar/all-in-one..."
startCommand: "pnpm --filter @vellar/all-in-one start"
healthCheckPath: /health
envVars:
- key: NODE_VERSION
value: "20"
# NOTE: Render injects PORT automatically; the gateway reads it via
# portFromEnv("PORT", …) and binds 0.0.0.0. Do not hardcode PORT here.
# Mainnet endpoints (cutover 2026-09-20): the x402 payment gate on
# /lifecycle/execute and /verification/:contractId requires real mainnet
# USDC (stellar:pubnet), but this file was never flipped when that gate
# shipped -- lifecycle-service's account lookups ran against testnet
# Horizon while payments settled on mainnet, so a mainnet accountId
# verified against a paid request 404'd with account_not_found even
# though the account genuinely exists (just not on the network this
# service was configured for). See docs/decisions.md.
# Confirmed against OpenZeppelin's own docs (docs.openzeppelin.com/relayer/1.3.x/guides/stellar-channels-guide):
# mainnet is the BARE host, no /mainnet path segment -- only testnet
# gets a path suffix ("https://channels.openzeppelin.com/testnet").
- key: RELAYER_BASE_URL
value: "https://channels.openzeppelin.com"
- key: STELLAR_RPC_URL
value: "https://mainnet.sorobanrpc.com"
- key: STELLAR_NETWORK_PASSPHRASE
value: "Public Global Stellar Network ; September 2015"
# RA-10: the EXPLICIT network signal. The worker refuses to boot without it
# (no default), and cross-checks it against the passphrase + RPC above.
# Must agree with them — flip all three together for a testnet rollback.
- key: STELLAR_NETWORK
value: "mainnet"
- key: HORIZON_URL
value: "https://horizon.stellar.org"
# Allow the deployed frontend origin (update to the real vellar.xyz once live).
- key: CORS_ORIGIN
value: "https://vellar.xyz"
# Origin permission cache lifetime: 5 minutes (valid range: 1 second to 24 hours).
- key: PERMISSION_CACHE_TTL_MS
value: "300000"
# Wire the Postgres created below.
- key: DATABASE_URL
fromDatabase:
name: vellar-db
property: connectionString
# Secrets — set these in the dashboard (sync:false keeps them out of git).
- key: RELAYER_API_KEY
sync: false
- key: SPONSOR_SECRET_KEY
sync: false
# §8 Q3: the PUBLIC account SPONSOR_SECRET_KEY must sign as. Required on
# mainnet — wallet-service and policy-service refuse to boot without it,
# or if the secret signs as a different account. Confirm it is a mainnet
# account first: tsx scripts/verify-signing-keys.ts --network mainnet --sponsor G...
- key: SPONSOR_PUBLIC_KEY
sync: false
databases:
- name: vellar-db
plan: free