diff --git a/.env b/.env index 59d8209..e71526f 100644 --- a/.env +++ b/.env @@ -1,4 +1,4 @@ -XIOND_VERSION="20.0.0" +XIOND_VERSION="28.1.0" CHAIN_ID="xion-devnet-1" DAEMON_HOME="/home/xiond/.xiond" @@ -22,14 +22,19 @@ SOURCE_CHAIN_API="https://api.xion-testnet-2.burnt.com:443" # first should be account, second should be treasury, more can be appended code ids are assigned sequentially starting from 1 SOURCE_CHAIN_CODE_IDS="1 1260" +STYTCH_AUD="project-test-1aa439cd-842b-4d3b-b2a6-37899cf83ca9" +STYTCH_JWK='{"alg":"RS256","e":"AQAB","kid":"jwk-test-a93974ec-5fb7-4970-957d-7d3439077841","kty":"RSA","n":"80EHR58Nopm1CeGWBTx_yGO3REn9mCfktSyb00Rf2x12WIiZhkVKcsXIA6GyUJJfrRomKWWPbPeTz1NMx3Oz6VY8nWpZIhZ93QEFqXmjLMJeuf1UNLTzyI9UM32GYu9EEne7LW39i7-ke0Hd9q0Ru-eBA86qNQ7M3sz_VhYZFQCSKZPUFtTXLEzZVAcvCP0yZEIXyxvSjxAIgY7p0mvF7WPsPSkqBXzwgnPd5P1A8hldCH2qeCwqmoZLmPLniRRTlSUO1Nog7YyxTCPp1bRskSAxkawqeB3hzRZPnDEHM9HrE3eamiKAGpBfkkfmkGT0MpA8J5de-BH2bLk_SxZERQ","use":"sig"}' + MODIFY_GENESIS_JQ=' - # .genesis_time = "2025-01-28T16:00:00Z" | .app_state.gov.params.expedited_voting_period = "0h1m0s" | .app_state.feeabs.epochs = [] | .app_state.feeabs.params.native_ibced_in_osmosis = "" | - .app_state.feeabs.params.chain_name = "" - # .app_state.abstractaccount.params.allowed_code_ids = ["1"] - # .app_state.jwk.audienceList = [{"aud": env.JWK_AUD, "key": env.JWK_KEY, "admin": env.JWK_ADMIN}] + .app_state.feeabs.params.chain_name = "" | + .app_state.abstractaccount.params.allowed_code_ids = ["1"] | + .app_state.abstractaccount.params.allow_all_code_ids = false | + .app_state.jwk.audienceList = [{"aud": $stytch_aud, "key": $stytch_jwk, "admin": $abstraxion_addr}] ' + +RELAYER_MNEMONIC="abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art" diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..69b952a --- /dev/null +++ b/.env.example @@ -0,0 +1,63 @@ +# ═══════════════════════════════════════════════════════════════════════════ +# Xion Devnet — Environment Variables +# ═══════════════════════════════════════════════════════════════════════════ + +# --- Xion Chain --- +XIOND_VERSION="28.1.0" +CHAIN_ID="xion-devnet-1" +DAEMON_HOME="/home/xiond/.xiond" +DAEMON_NAME="xiond" +DEFAULT_DENOM="uxion" +DENOM_METADATA_NAME="xion" +GENESIS_AMOUNT="1000000000000" +GENTX_AMOUNT="1000000" +NUM_VALIDATORS=3 + +# Devnet mnemonic (NOT SENSITIVE — do not use in production) +MNEMONIC="decorate corn happy degree artist trouble color mountain shadow hazard canal zone hunt unfold deny glove famous area arrow cup under sadness salute item" +ABSTRAXION_ADDRESS="xion1e2fuwe3uhq8zd9nkkk876nawrwdulgv460vzg7" + +# --- Source Chain (genesis import) --- +SOURCE_CHAIN_ID="xion-testnet-2" +SOURCE_CHAIN_RPC="https://rpc.xion-testnet-2.burnt.com:443" +SOURCE_CHAIN_API="https://api.xion-testnet-2.burnt.com:443" +SOURCE_CHAIN_CODE_IDS="1 1260" + +# --- Faucet --- +FAUCET_ACCOUNTS="10" +FAUCET_AMOUNT="100000000" + +# --- Stytch / JWK (used in genesis modifications) --- +STYTCH_AUD="project-test-1aa439cd-842b-4d3b-b2a6-37899cf83ca9" +STYTCH_JWK='{"alg":"RS256","e":"AQAB","kid":"jwk-test-a93974ec-5fb7-4970-957d-7d3439077841","kty":"RSA","n":"80EHR58Nopm1CeGWBTx_yGO3REn9mCfktSyb00Rf2x12WIiZhkVKcsXIA6GyUJJfrRomKWWPbPeTz1NMx3Oz6VY8nWpZIhZ93QEFqXmjLMJeuf1UNLTzyI9UM32GYu9EEne7LW39i7-ke0Hd9q0Ru-eBA86qNQ7M3sz_VhYZFQCSKZPUFtTXLEzZVAcvCP0yZEIXyxvSjxAIgY7p0mvF7WPsPSkqBXzwgnPd5P1A8hldCH2qeCwqmoZLmPLniRRTlSUO1Nog7YyxTCPp1bRskSAxkawqeB3hzRZPnDEHM9HrE3eamiKAGpBfkkfmkGT0MpA8J5de-BH2bLk_SxZERQ","use":"sig"}' + +# --- Genesis Modifications --- +MODIFY_GENESIS_JQ=' + .app_state.gov.params.expedited_voting_period = "0h1m0s" | + .app_state.feeabs.epochs = [] | + .app_state.feeabs.params.native_ibced_in_osmosis = "" | + .app_state.feeabs.params.chain_name = "" | + .app_state.abstractaccount.params.allowed_code_ids = ["1"] | + .app_state.abstractaccount.params.allow_all_code_ids = false | + .app_state.jwk.audienceList = [{"aud": $stytch_aud, "key": $stytch_jwk, "admin": $abstraxion_addr}] +' + +# --- Postgres --- +POSTGRES_USER=postgres +POSTGRES_PASSWORD=postgres +POSTGRES_DB=postgres + +# --- Indexer --- +SUB_COMMAND=forceClean + +# --- Dashboard --- +STYTCH_PUBLIC_TOKEN=public-token-test-823bab5f-5fe6-4a3f-b49a-ca59763be42a +NUMIA_TOKEN=placeholder +FEE_GRANTER_ADDRESS= +ZKEMAIL_FLAG=false + +# --- IBC Relayer --- +RELAYER_MNEMONIC="abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art" + +STYTCH_PROJECT_ID=project-test-1aa439cd-842b-4d3b-b2a6-37899cf83ca9 +STYTCH_SECRET=PLACEHOLDER_NEED_SECRET diff --git a/.gitmodules b/.gitmodules index cd4821b..d921824 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,7 +1,7 @@ [submodule "xion"] path = xion url = https://github.com/burnt-labs/xion.git - branch = release/v20 + branch = release/v28 [submodule "xion-dashboard-app"] path = xion-dashboard-app url = https://github.com/burnt-labs/xion-dashboard-app.git @@ -9,7 +9,7 @@ [submodule "xion-explorer"] path = xion-explorer url = https://github.com/burnt-labs/xion-explorer.git - branch = xion/mainnet + branch = chore/devnet [submodule "xion-faucet"] path = xion-faucet url = https://github.com/burnt-labs/xion-faucet.git @@ -25,4 +25,32 @@ [submodule "xion-assets"] path = xion-assets url = https://github.com/burnt-labs/xion-assets.git + branch = main +[submodule "account-abstraction-api"] + path = account-abstraction-api + url = https://github.com/burnt-labs/account-abstraction-api.git + branch = chore/devnet +[submodule "oauth2-api-service"] + path = oauth2-api-service + url = https://github.com/burnt-labs/oauth2-api-service.git + branch = chore/devnet +[submodule "oauth2-clients-dashboard"] + path = oauth2-clients-dashboard + url = https://github.com/burnt-labs/oauth2-clients-dashboard.git + branch = chore/devnet +[submodule "zk-email-backend"] + path = zk-email-backend + url = https://github.com/burnt-labs/zk-email-backend.git + branch = chore/devnet +[submodule "zk-email-prover"] + path = zk-email-prover + url = https://github.com/burnt-labs/zk-email-prover.git + branch = chore/devnet +[submodule "zk-email-worker"] + path = zk-email-worker + url = https://github.com/burnt-labs/zk-email-worker.git + branch = chore/devnet +[submodule "xion-indexer-proxy"] + path = xion-indexer-proxy + url = https://github.com/burnt-labs/xion-indexer-proxy.git branch = chore/devnet diff --git a/Makefile b/Makefile index abe849d..ab37f20 100644 --- a/Makefile +++ b/Makefile @@ -1,24 +1,53 @@ -singleton: - . .env && ./scripts/docker-run.sh +# Xion Devnet — Makefile +PROFILE ?= core +COMMIT ?= $(shell cd ./xion && git rev-parse --short HEAD 2>/dev/null || echo "unknown") + +.PHONY: build build-no-cache start stop down clean purge logs status singleton core apps oauth zk ibc full build: - COMMIT=$$(cd ./xion && git rev-parse --short HEAD) docker compose build --pull + COMMIT=$(COMMIT) docker compose --profile $(PROFILE) build --pull build-no-cache: - COMMIT=$$(cd ./xion && git rev-parse --short HEAD) docker compose build --pull --no-cache + COMMIT=$(COMMIT) docker compose --profile $(PROFILE) build --pull --no-cache -start: - docker compose up -d +start up: + docker compose --profile $(PROFILE) up -d stop: - docker compose stop + docker compose --profile $(PROFILE) stop down: - docker compose down + docker compose --profile $(PROFILE) down clean: - docker compose rm -f -s -v + docker compose --profile $(PROFILE) rm -f -s -v purge: - docker compose rm -f -s -v - docker volume rm -f devnet_shared + docker compose --profile $(PROFILE) down -v --remove-orphans + +logs: + docker compose --profile $(PROFILE) logs -f + +status: + docker compose --profile $(PROFILE) ps + +core: + $(MAKE) start PROFILE=core + +apps: + $(MAKE) start PROFILE=apps + +oauth: + $(MAKE) start PROFILE=oauth + +zk: + $(MAKE) start PROFILE=zk + +ibc: + $(MAKE) start PROFILE=ibc + +full: + $(MAKE) start PROFILE=full + +singleton: + . .env && ./scripts/docker-run.sh diff --git a/README.md b/README.md index f55c5e0..df4c28c 100644 --- a/README.md +++ b/README.md @@ -1,113 +1,58 @@ -# Xion Devnet +# Xion Devnet — Full Stack -Xion Devnet is a multi-validator sandbox environment orchestrated with Docker Compose for local development and testing. - -## Prerequisites - -- [Docker](https://www.docker.com/) (version 20.10 or higher) -- [Docker Compose](https://github.com/docker/compose) (version 2.0 or higher) -- [Make](https://www.gnu.org/software/make/) (for using Makefile commands) +Run the entire Xion ecosystem locally with Docker Compose. ## Quick Start -The easiest way to get started is using the provided Makefile commands: - -```sh -# Build devnet images with commit ID -make build - -# Start devnet in background -make start - -# Stop devnet (preserves state) -make stop - -# Stop and remove containers -make down - -# Clean up containers -make clean - -# Complete purge (removes containers and shared volume) -make purge - -# Start singleton validator from .env configuration -make singleton +```bash +git clone --recurse-submodules -b chore/devnet-v28 https://github.com/burnt-labs/devnet.git +cd devnet +cp .env.example .env +make core # chain + haproxy + explorer + faucet +make full # everything ``` -## Manual Docker Compose Commands - -If you prefer to use Docker Compose directly: - -```sh -# Build images with commit ID -COMMIT=$(cd ./xion && git rev-parse --short HEAD) docker compose build --pull --no-cache - -# Start devnet -docker compose up -d - -# Stop devnet (preserves blockchain state) -docker compose stop - -# Stop and remove containers -docker compose down - -# View logs -docker compose logs -f - -# Complete cleanup and reset -docker compose rm -f -s -v -docker volume rm -f devnet_shared - -# Restart from previous height -docker compose start +## Profiles + +| Profile | Services | +|---------|----------| +| `core` | Xion (3 validators), HAProxy, Explorer, Faucet | +| `apps` | Core + AA API, Dashboard, Staking, Dev Portal, Indexer, Assets | +| `oauth` | Apps + OAuth3, OAuth2 API, OAuth2 Clients Dashboard | +| `zk` | Apps + ZK Email Backend, Prover, Worker | +| `ibc` | Core + Osmosis, Noble, Hermes relayer | +| `full` | Everything | + +## Ports + +| Port | Service | Port | Service | +|------|---------|------|---------| +| 1317 | Xion REST | 8001 | Indexer Proxy | +| 9090 | Xion gRPC | 8002 | OAuth2 API | +| 26657 | Xion RPC | 8003 | OAuth2 Clients | +| 3000 | Faucet | 8080 | OAuth3 | +| 3001 | AA API | 8081 | ZK Email Prover | +| 3002 | Indexer GraphQL | 8082 | ZK Email Worker | +| 3003 | Developer Portal | 8788 | Staking | +| 3004 | Assets | 26757 | Osmosis RPC | +| 4173 | Dashboard | 26857 | Noble RPC | +| 5173 | Explorer | 9190/9290 | Osmosis/Noble gRPC | +| 8444 | HAProxy Stats | 26656 | Xion P2P | + +## Commands + +```bash +make build PROFILE=apps # Build images +make start PROFILE=apps # Start +make logs PROFILE=apps # Follow logs +make status # Container status +make purge # Remove everything ``` -## Configuration Options - -- **NUM_VALIDATORS**: Number of validator nodes (default: 3) -- **XIOND_VERSION**: Version tag for the xion docker image (default: latest) -- **COMMIT**: Git commit hash passed to build (automatically set by Makefile) -- **DAEMON_NAME**: Name of the daemon process (configured in .env) - -## Network Information - -Once running, the devnet exposes the following services through HAProxy: - -- **RPC Endpoint**: `http://localhost:26657` -- **API Endpoint**: `http://localhost:1317` -- **gRPC Endpoint**: `http://localhost:9090` -- **Xion Explorer**: `http://localhost:5173` -- **Xion Faucet**: `http://localhost:3000` -- **Additional RPC**: `http://localhost:26658` +## IBC -The setup includes: - -- **Xion validators**: Configurable number of validator nodes (default: 3) -- **HAProxy**: Load balancer and reverse proxy -- **Xion Explorer**: Web interface for blockchain exploration -- **Xion Faucet**: Token distribution service - -## Submodules - -This devnet environment includes several Xion ecosystem components as git submodules: - -- **[xion](https://github.com/burnt-labs/xion)** - Core Xion blockchain node and validator software -- **[xion-explorer](https://github.com/burnt-labs/xion-explorer)** - Web-based blockchain explorer for viewing transactions and blocks -- **[xion-faucet](https://github.com/burnt-labs/xion-faucet)** - Token distribution service for testnet XION tokens -- **[xion-staking](https://github.com/burnt-labs/xion-staking)** - Staking interface for validators and delegators -- **[xion-assets](https://github.com/burnt-labs/xion-assets)** - Static assets and branding resources - -To update all submodules to their latest commits: - -```sh -git submodule update --remote --recursive -``` +The `ibc` profile starts Osmosis (v28.0.0) and Noble (v11.3.0) with a Hermes relayer (v1.12.0). Channels are auto-created for `transfer` on both pairs. Noble includes USDC minting via `fiat-tokenfactory`. -## Troubleshooting +## Environment -- **Port conflicts**: Ensure ports 26657, 1317, 9090, 5173, and 3000 are available -- **Storage issues**: Use `make purge` to reset blockchain state and volumes -- **Build failures**: Try `make build` to rebuild images with commit ID -- **Permission errors**: Ensure Docker daemon is running and user has permissions -- **Service startup**: Check `docker compose logs -f` for detailed error messages +See `.env.example` for all variables. Key ones: `XIOND_VERSION`, `NUM_VALIDATORS`, `RELAYER_MNEMONIC`, `STYTCH_PUBLIC_TOKEN`, `FEE_GRANTER_ADDRESS`. diff --git a/account-abstraction-api b/account-abstraction-api new file mode 160000 index 0000000..df1694e --- /dev/null +++ b/account-abstraction-api @@ -0,0 +1 @@ +Subproject commit df1694e63d598478ce2c4080f3257fff46c696c7 diff --git a/config/haproxy-ibc.cfg b/config/haproxy-ibc.cfg new file mode 100644 index 0000000..7a978af --- /dev/null +++ b/config/haproxy-ibc.cfg @@ -0,0 +1,48 @@ +# HAProxy IBC chain additions +# Append to or include from main haproxy.cfg + +# ─── Osmosis ──────────────────────────────── + +listen osmosis_rpc + bind *:26757 + mode http + http-response set-header Access-Control-Allow-Origin "*" + http-response set-header Access-Control-Allow-Methods "GET, POST, OPTIONS" + http-response set-header Access-Control-Allow-Headers "Content-Type" + server osmosis osmosis:26657 check resolvers default + +listen osmosis_api + bind *:1417 + mode http + http-response set-header Access-Control-Allow-Origin "*" + http-response set-header Access-Control-Allow-Methods "GET, POST, OPTIONS" + http-response set-header Access-Control-Allow-Headers "Content-Type" + server osmosis osmosis:1317 check resolvers default + +listen osmosis_grpc + bind *:9190 + mode tcp + server osmosis osmosis:9090 check resolvers default + +# ─── Noble ────────────────────────────────── + +listen noble_rpc + bind *:26857 + mode http + http-response set-header Access-Control-Allow-Origin "*" + http-response set-header Access-Control-Allow-Methods "GET, POST, OPTIONS" + http-response set-header Access-Control-Allow-Headers "Content-Type" + server noble noble:26657 check resolvers default + +listen noble_api + bind *:1517 + mode http + http-response set-header Access-Control-Allow-Origin "*" + http-response set-header Access-Control-Allow-Methods "GET, POST, OPTIONS" + http-response set-header Access-Control-Allow-Headers "Content-Type" + server noble noble:1317 check resolvers default + +listen noble_grpc + bind *:9290 + mode tcp + server noble noble:9090 check resolvers default diff --git a/config/haproxy.cfg b/config/haproxy.cfg index 6747182..75c5242 100644 --- a/config/haproxy.cfg +++ b/config/haproxy.cfg @@ -1,6 +1,5 @@ global log stdout format raw daemon debug - #stats socket /var/lib/haproxy/haproxy.sock level admin defaults log global @@ -9,6 +8,17 @@ defaults timeout client 30s timeout server 30s +resolvers default + nameserver dns 127.0.0.11:53 + resolve_retries 3 + timeout resolve 1s + timeout retry 1s + hold other 10s + hold refused 10s + hold nx 10s + hold timeout 10s + hold valid 10s + frontend stats bind *:8444 mode http @@ -16,12 +26,16 @@ frontend stats stats uri / stats refresh 10s +# ═══════════════════════════════════════════════════════════════════════════ +# CORE — Xion Chain +# ═══════════════════════════════════════════════════════════════════════════ + listen rest bind *:1317 + mode http http-response set-header Access-Control-Allow-Origin "*" http-response set-header Access-Control-Allow-Methods "GET, POST, OPTIONS" http-response set-header Access-Control-Allow-Headers "Content-Type" - mode http server-template s 10 xion:1317 check init-addr last,none resolvers default listen grpc @@ -37,10 +51,14 @@ listen rpc http-response set-header Access-Control-Allow-Headers "Content-Type" server-template s 10 xion:26657 check init-addr last,none resolvers default -listen client - bind *:26658 +listen p2p + bind *:26656 mode tcp - server-template s 10 xion:26658 check init-addr last,none resolvers default + server-template s 10 xion:26656 check init-addr last,none resolvers default + +# ═══════════════════════════════════════════════════════════════════════════ +# CORE — Faucet & Explorer +# ═══════════════════════════════════════════════════════════════════════════ listen faucet bind *:3000 @@ -51,3 +69,99 @@ listen explorer bind *:5173 mode http server xion-explorer xion-explorer:5173 check resolvers default + +# ═══════════════════════════════════════════════════════════════════════════ +# APPS +# ═══════════════════════════════════════════════════════════════════════════ + +listen aa-api + bind *:3001 + mode http + server account-abstraction-api account-abstraction-api:3001 check resolvers default + +listen indexer + bind *:3002 + mode http + server xion-indexer-graphql xion-indexer-graphql:3000 check resolvers default + +listen developer-portal + bind *:3003 + mode http + server xion-developer-portal xion-developer-portal:3002 check resolvers default + +listen dashboard + bind *:4173 + mode http + server xion-dashboard-app xion-dashboard-app:4173 check resolvers default + +listen indexer-proxy + bind *:8001 + mode http + server xion-indexer-proxy xion-indexer-proxy:8001 check resolvers default + +listen staking + bind *:8788 + mode http + server xion-staking xion-staking:8788 check resolvers default + +listen assets + bind *:3004 + mode http + server xion-assets xion-assets:3003 check resolvers default + +# ═══════════════════════════════════════════════════════════════════════════ +# OAUTH +# ═══════════════════════════════════════════════════════════════════════════ + +listen oauth3 + bind *:8080 + mode http + server oauth3 oauth3:8080 check resolvers default + +listen oauth2-api + bind *:8002 + mode http + server oauth2-api-service oauth2-api-service:8002 check resolvers default + +listen oauth2-clients + bind *:8003 + mode http + server oauth2-clients-dashboard oauth2-clients-dashboard:8003 check resolvers default + +# ═══════════════════════════════════════════════════════════════════════════ +# ZK +# ═══════════════════════════════════════════════════════════════════════════ + +listen zk-email-prover + bind *:8081 + mode http + server zk-email-prover zk-email-prover:8081 check resolvers default + +listen zk-email-worker + bind *:8082 + mode http + server zk-email-worker zk-email-worker:8082 check resolvers default + +# ═══════════════════════════════════════════════════════════════════════════ +# IBC — Osmosis & Noble +# ═══════════════════════════════════════════════════════════════════════════ + +listen osmosis-rpc + bind *:26757 + mode http + server osmosis osmosis:26657 check resolvers default + +listen osmosis-grpc + bind *:9190 + mode tcp + server osmosis osmosis:9090 check resolvers default + +listen noble-rpc + bind *:26857 + mode http + server noble noble:26657 check resolvers default + +listen noble-grpc + bind *:9290 + mode tcp + server noble noble:9090 check resolvers default diff --git a/config/hermes/config.toml b/config/hermes/config.toml new file mode 100644 index 0000000..fa8c6b7 --- /dev/null +++ b/config/hermes/config.toml @@ -0,0 +1,99 @@ +# Hermes IBC Relayer Configuration +# Three-chain relay: Xion ↔ Osmosis, Xion ↔ Noble + +[global] +log_level = 'info' + +[mode] +[mode.clients] +enabled = true +refresh = true +misbehaviour = false + +[mode.connections] +enabled = false + +[mode.channels] +enabled = false + +[mode.packets] +enabled = true +clear_interval = 100 +clear_on_start = true +tx_confirmation = false + +[rest] +enabled = false +host = '127.0.0.1' +port = 3000 + +[telemetry] +enabled = false +host = '127.0.0.1' +port = 3001 + +# ─── Xion ─────────────────────────────────── +[[chains]] +id = 'xion-devnet-1' +type = 'CosmosSdk' +rpc_addr = 'http://xion:26657' +grpc_addr = 'http://xion:9090' +event_source = { mode = 'push', url = 'ws://xion:26657/websocket', batch_delay = '500ms' } +account_prefix = 'xion' +key_name = 'relayer' +key_store_type = 'Test' +store_prefix = 'ibc' +default_gas = 400000 +max_gas = 3000000 +gas_price = { price = 0.0, denom = 'uxion' } +gas_multiplier = 1.3 +max_msg_num = 30 +max_tx_size = 180000 +clock_drift = '15s' +trusting_period = '14days' +trust_threshold = { numerator = '1', denominator = '3' } +address_type = { derivation = 'cosmos' } + +# ─── Osmosis ──────────────────────────────── +[[chains]] +id = 'localosmo-1' +type = 'CosmosSdk' +rpc_addr = 'http://osmosis:26657' +grpc_addr = 'http://osmosis:9090' +event_source = { mode = 'push', url = 'ws://osmosis:26657/websocket', batch_delay = '500ms' } +account_prefix = 'osmo' +key_name = 'relayer' +key_store_type = 'Test' +store_prefix = 'ibc' +default_gas = 400000 +max_gas = 3000000 +gas_price = { price = 0.0025, denom = 'uosmo' } +gas_multiplier = 1.3 +max_msg_num = 30 +max_tx_size = 180000 +clock_drift = '15s' +trusting_period = '14days' +trust_threshold = { numerator = '1', denominator = '3' } +address_type = { derivation = 'cosmos' } + +# ─── Noble ────────────────────────────────── +[[chains]] +id = 'noble-devnet-1' +type = 'CosmosSdk' +rpc_addr = 'http://noble:26657' +grpc_addr = 'http://noble:9090' +event_source = { mode = 'push', url = 'ws://noble:26657/websocket', batch_delay = '500ms' } +account_prefix = 'noble' +key_name = 'relayer' +key_store_type = 'Test' +store_prefix = 'ibc' +default_gas = 400000 +max_gas = 3000000 +gas_price = { price = 0.0, denom = 'ustake' } +gas_multiplier = 1.3 +max_msg_num = 30 +max_tx_size = 180000 +clock_drift = '15s' +trusting_period = '14days' +trust_threshold = { numerator = '1', denominator = '3' } +address_type = { derivation = 'cosmos' } diff --git a/docker-compose.yml b/docker-compose.yml index 772ce8f..6aba1cd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,65 +1,145 @@ +############################################################################### +# Xion Devnet — Full Stack Docker Compose +# +# Profiles: +# core — xion (3 validators) + haproxy + explorer + faucet +# apps — core + AA API + dashboard + staking + dev-portal + indexer + assets +# oauth — apps + oauth2-api-service + oauth2-clients-dashboard +# zk — apps + zk-email-backend + zk-email-prover + zk-email-worker +# ibc — core + osmosis + noble + hermes relayer +# full — everything +# +# Usage: +# docker compose --profile core up -d +# docker compose --profile full up -d +############################################################################### + services: + + # ═══════════════════════════════════════════════════════════════════════════ + # CORE PROFILE + # ═══════════════════════════════════════════════════════════════════════════ + + init-scripts: + image: busybox:1.37 + profiles: ["core", "apps", "oauth", "zk", "ibc", "full"] + command: > + sh -c "cp -R /source/. /target/ && chmod +x /target/*.sh" + volumes: + - ./scripts/init:/source:ro + - init-scripts:/target + restart: "no" + haproxy: image: haproxy:3.2-alpine - command: > - haproxy -f /usr/local/etc/haproxy/haproxy.cfg + profiles: ["core", "apps", "oauth", "zk", "ibc", "full"] + command: haproxy -f /usr/local/etc/haproxy/haproxy.cfg depends_on: - xion - networks: - - default ports: - - 1317:1317 - - 3000:3000 - - 5173:5173 - - 9090:9090 - - 26657:26657 - - 26658:26658 + - "1317:1317" # Xion REST/LCD + - "9090:9090" # Xion gRPC + - "26657:26657" # Xion RPC + - "26656:26656" # Xion P2P + - "3000:3000" # Faucet + - "3001:3001" # AA API + - "3002:3002" # Indexer GraphQL + - "3003:3003" # Developer Portal + - "3004:3004" # Assets + - "4173:4173" # Dashboard + - "5173:5173" # Explorer + - "8001:8001" # Indexer Proxy + - "8002:8002" # OAuth2 API Service + - "8003:8003" # OAuth2 Clients Dashboard + - "8080:8080" # OAuth3 + - "8081:8081" # ZK Email Prover + - "8082:8082" # ZK Email Worker + - "8788:8788" # Staking + - "8444:8444" # HAProxy stats + - "26757:26757" # Osmosis RPC + - "9190:9190" # Osmosis gRPC + - "26857:26857" # Noble RPC + - "9290:9290" # Noble gRPC volumes: - ./config/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro + healthcheck: + test: ["CMD-SHELL", "haproxy -c -f /usr/local/etc/haproxy/haproxy.cfg"] + interval: 10s + timeout: 5s + retries: 3 + networks: + - devnet xion: image: ghcr.io/burnt-labs/xion/xion:${XIOND_VERSION:-latest} + profiles: ["core", "apps", "oauth", "zk", "ibc", "full"] + depends_on: + init-scripts: + condition: service_completed_successfully build: context: ./xion args: - VERSION=${XIOND_VERSION} - COMMIT=${COMMIT} - command: > - /usr/bin/cosmovisor run start \ - --api.address tcp://0.0.0.0:1317 \ - --api.enable true \ - --api.enabled-unsafe-cors true \ - --api.swagger true \ - --grpc.enable true \ - --grpc.address 0.0.0.0:9090 \ - --grpc-web.enable \ - --minimum-gas-prices 0.001uxion \ - --rpc.laddr tcp://0.0.0.0:26657 entrypoint: /home/xiond/init/entrypoint.sh + command: > + /usr/bin/cosmovisor run start + --api.address tcp://0.0.0.0:1317 + --api.enable true + --api.enabled-unsafe-cors true + --api.swagger true + --grpc.enable true + --grpc.address 0.0.0.0:9090 + --grpc-web.enable + --minimum-gas-prices 0.001uxion + --rpc.laddr tcp://0.0.0.0:26657 deploy: replicas: ${NUM_VALIDATORS:-3} env_file: - .env ports: - - 1317 - - 9090 - - 26656 - - 26657 + - "1317" + - "9090" + - "26656" + - "26657" healthcheck: - test: ["CMD-SHELL", "curl http://localhost:26657/status"] + test: ["CMD-SHELL", "curl -sf http://localhost:26657/status"] interval: 5s timeout: 5s - retries: 5 + retries: 10 user: root working_dir: /home/${DAEMON_NAME} - networks: - - default volumes: - /home/${DAEMON_NAME} - shared:/home/${DAEMON_NAME}/.shared - - ./scripts/init:/home/${DAEMON_NAME}/init + - init-scripts:/home/${DAEMON_NAME}/init:ro + networks: + - devnet + + deploy-contracts: + image: ghcr.io/burnt-labs/xion/xion:${XIOND_VERSION:-latest} + profiles: ["apps", "oauth", "zk", "full"] + entrypoint: /home/${DAEMON_NAME}/init/deploy-contracts.sh + env_file: + - .env + environment: + - XION_RPC=http://xion:26657 + - OUTPUT_FILE=/home/${DAEMON_NAME}/.shared/deploy-contracts.env + depends_on: + init-scripts: + condition: service_completed_successfully + xion: + condition: service_healthy + working_dir: /home/${DAEMON_NAME} + volumes: + - shared:/home/${DAEMON_NAME}/.shared + - init-scripts:/home/${DAEMON_NAME}/init:ro + networks: + - devnet + restart: "no" xion-explorer: + profiles: ["core", "apps", "oauth", "zk", "ibc", "full"] build: context: xion-explorer/ args: @@ -67,10 +147,16 @@ services: image: ghcr.io/burnt-labs/xion/xion-explorer:latest ports: - "5173" + healthcheck: + test: ["CMD-SHELL", "wget -qO- http://localhost:5173/ || exit 1"] + interval: 15s + timeout: 5s + retries: 5 networks: - - default + - devnet xion-faucet: + profiles: ["core", "apps", "oauth", "zk", "ibc", "full"] build: context: xion-faucet/ args: @@ -80,11 +166,457 @@ services: - ./xion-faucet/.env.example ports: - "3000" + healthcheck: + test: ["CMD-SHELL", "wget -qO- http://localhost:3000/ || exit 1"] + interval: 15s + timeout: 5s + retries: 5 + networks: + - devnet + + # ═══════════════════════════════════════════════════════════════════════════ + # APPS PROFILE + # ═══════════════════════════════════════════════════════════════════════════ + + account-abstraction-api: + profiles: ["apps", "oauth", "zk", "full"] + build: + context: account-abstraction-api/ + image: ghcr.io/burnt-labs/xion/account-abstraction-api:latest + environment: + - XION_RPC_URL=http://haproxy:26657 + - XION_API_URL=http://haproxy:1317 + - XION_GRPC_URL=haproxy:9090 + - CHAIN_ID=xion-devnet-1 + - STYTCH_PROJECT_ID=${STYTCH_PROJECT_ID:-project-test-1aa439cd-842b-4d3b-b2a6-37899cf83ca9} + - STYTCH_SECRET=${STYTCH_SECRET:-PLACEHOLDER_NEED_SECRET} + ports: + - "3001" + depends_on: + xion: + condition: service_healthy + healthcheck: + test: ["CMD-SHELL", "wget -qO- http://localhost:3001/health || exit 1"] + interval: 15s + timeout: 5s + retries: 5 + networks: + - devnet + + # --- Indexer (SubQuery) --- + + postgresql: + image: postgres:16-alpine + profiles: ["apps", "oauth", "zk", "full"] + environment: + POSTGRES_USER: ${POSTGRES_USER:-postgres} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres} + POSTGRES_DB: ${POSTGRES_DB:-postgres} + ports: + - "5432" + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 5s + timeout: 5s + retries: 10 + volumes: + - postgres-data:/var/lib/postgresql/data + networks: + - devnet + + # --- Dashboard (Primary App) --- + + xion-dashboard-app: + profiles: ["apps", "oauth", "zk", "full"] + build: + context: xion-dashboard-app/ + args: + NETWORK_NAME: devnet + image: ghcr.io/burnt-labs/xion/xion-dashboard-app:latest + environment: + - VITE_NETWORK=devnet + - VITE_CHAIN_ID=xion-devnet-1 + - VITE_XION_API_URL=http://haproxy:1317 + - VITE_XION_RPC_URL=http://haproxy:26657 + - VITE_ABSTRAXION_API_URL=http://account-abstraction-api:3001 + - VITE_STYTCH_PUBLIC_TOKEN=${STYTCH_PUBLIC_TOKEN:-public-token-test-823bab5f-5fe6-4a3f-b49a-ca59763be42a} + - VITE_NUMIA_TOKEN=${NUMIA_TOKEN:-placeholder} + - VITE_FEE_GRANTER_ADDRESS=${FEE_GRANTER_ADDRESS:-} + - VITE_DEFAULT_ACCOUNT_CONTRACT_CODE_ID=1 + - VITE_ZKEMAIL_FLAG=${ZKEMAIL_FLAG:-false} + - VITE_ZKEMAIL_BACKEND_URL=http://zk-email-backend:4500 + ports: + - "4173" + depends_on: + - account-abstraction-api + healthcheck: + test: ["CMD-SHELL", "wget -qO- http://localhost:4173/ || exit 1"] + interval: 15s + timeout: 5s + retries: 5 + networks: + - devnet + + # --- Staking --- + + xion-staking: + profiles: ["apps", "oauth", "zk", "full"] + build: + context: xion-staking/ + dockerfile: Dockerfile + image: ghcr.io/burnt-labs/xion/xion-staking:latest + environment: + - NEXT_PUBLIC_CHAIN_ID=xion-devnet-1 + - NEXT_PUBLIC_RPC_URL=http://haproxy:26657 + - NEXT_PUBLIC_API_URL=http://haproxy:1317 + ports: + - "8788" + depends_on: + xion: + condition: service_healthy + healthcheck: + test: ["CMD-SHELL", "wget -qO- http://localhost:8788/ || exit 1"] + interval: 15s + timeout: 5s + retries: 5 + networks: + - devnet + + # --- Developer Portal --- + + xion-developer-portal: + profiles: ["apps", "oauth", "zk", "full"] + build: + context: xion-developer-portal/ + dockerfile: Dockerfile + image: ghcr.io/burnt-labs/xion/xion-developer-portal:latest + environment: + - VITE_CHAIN_ID=xion-devnet-1 + - VITE_RPC_URL=http://haproxy:26657 + - VITE_API_URL=http://haproxy:1317 + ports: + - "3000" + depends_on: + xion: + condition: service_healthy + healthcheck: + test: ["CMD-SHELL", "wget -qO- http://localhost:3000/ || exit 1"] + interval: 15s + timeout: 5s + retries: 5 + networks: + - devnet + + # --- Assets --- + + xion-assets: + profiles: ["apps", "oauth", "zk", "full"] + build: + context: xion-assets/ + dockerfile: Dockerfile + image: ghcr.io/burnt-labs/xion/xion-assets:latest + environment: + - VITE_CHAIN_ID=xion-devnet-1 + ports: + - "3000" + depends_on: + xion: + condition: service_healthy + healthcheck: + test: ["CMD-SHELL", "wget -qO- http://localhost:3000/ || exit 1"] + interval: 15s + timeout: 5s + retries: 5 networks: - - default + - devnet + + # ═══════════════════════════════════════════════════════════════════════════ + + xion-indexer-proxy: + profiles: ["apps", "oauth", "zk", "full"] + build: + context: xion-indexer-proxy/ + dockerfile: Dockerfile + image: ghcr.io/burnt-labs/xion/xion-indexer-proxy:latest + environment: + - XION_RPC_URL=http://haproxy:26657 + - XION_API_URL=http://haproxy:1317 + - CHAIN_ID=xion-devnet-1 + ports: + - "8001:8000" + depends_on: + xion: + condition: service_healthy + healthcheck: + test: ["CMD-SHELL", "wget -qO- http://localhost:8000/ || exit 1"] + interval: 15s + timeout: 5s + retries: 5 + networks: + - devnet + + # OAUTH PROFILE + # ═══════════════════════════════════════════════════════════════════════════ + + + oauth2-api-service: + profiles: ["oauth", "full"] + build: + context: oauth2-api-service/ + dockerfile: Dockerfile + image: ghcr.io/burnt-labs/xion/oauth2-api-service:latest + environment: + - XION_RPC_URL=http://haproxy:26657 + - CHAIN_ID=xion-devnet-1 + ports: + - "8002" + depends_on: + xion: + condition: service_healthy + healthcheck: + test: ["CMD-SHELL", "wget -qO- http://localhost:8002/ || exit 1"] + interval: 15s + timeout: 5s + retries: 5 + networks: + - devnet + + oauth2-clients-dashboard: + profiles: ["oauth", "full"] + build: + context: oauth2-clients-dashboard/ + dockerfile: Dockerfile + image: ghcr.io/burnt-labs/xion/oauth2-clients-dashboard:latest + environment: + - VITE_OAUTH2_API_URL=http://oauth2-api-service:8002 + - VITE_CHAIN_ID=xion-devnet-1 + ports: + - "8003" + depends_on: + - oauth2-api-service + healthcheck: + test: ["CMD-SHELL", "wget -qO- http://localhost:8003/ || exit 1"] + interval: 15s + timeout: 5s + retries: 5 + networks: + - devnet + + # ═══════════════════════════════════════════════════════════════════════════ + # ZK PROFILE + # ═══════════════════════════════════════════════════════════════════════════ + + zk-email-backend: + profiles: ["zk", "full"] + build: + context: zk-email-backend/ + dockerfile: Dockerfile + image: ghcr.io/burnt-labs/xion/zk-email-backend:latest + environment: + - XION_RPC_URL=http://haproxy:26657 + - XION_API_URL=http://haproxy:1317 + - CHAIN_ID=xion-devnet-1 + ports: + - "4500" + volumes: + - ./zk-email-backend/config.json:/usr/src/app/config.json:ro + depends_on: + xion: + condition: service_healthy + healthcheck: + test: ["CMD-SHELL", "wget -qO- http://localhost:4500/health || exit 1"] + interval: 15s + timeout: 5s + retries: 5 + networks: + - devnet + + zk-email-prover: + profiles: ["zk", "full"] + build: + context: zk-email-prover/ + dockerfile: Dockerfile.rapidsnark + image: ghcr.io/burnt-labs/xion/zk-email-prover:latest + environment: + - BACKEND_URL=http://zk-email-backend:4500 + ports: + - "8081" + depends_on: + - zk-email-backend + healthcheck: + test: ["CMD-SHELL", "wget -qO- http://localhost:8081/health || exit 1"] + interval: 15s + timeout: 10s + retries: 5 + networks: + - devnet + + zk-email-worker: + profiles: ["zk", "full"] + build: + context: zk-email-worker/ + dockerfile: Dockerfile + image: ghcr.io/burnt-labs/xion/zk-email-worker:latest + environment: + - PROVER_URL=http://zk-email-prover:8081 + - BACKEND_URL=http://zk-email-backend:4500 + - XION_RPC_URL=http://haproxy:26657 + - CHAIN_ID=xion-devnet-1 + ports: + - "8082" + depends_on: + - zk-email-prover + healthcheck: + test: ["CMD-SHELL", "wget -qO- http://localhost:8082/ || exit 1"] + interval: 15s + timeout: 5s + retries: 5 + networks: + - devnet + + # ═══════════════════════════════════════════════════════════════════════════ + # IBC PROFILE + # ═══════════════════════════════════════════════════════════════════════════ + + osmosis: + image: ghcr.io/strangelove-ventures/heighliner/osmosis:v28.0.0 + profiles: ["ibc", "full"] + user: "1025:1025" + entrypoint: ["/bin/sh", "-c"] + command: + - | + if [ ! -f /home/heighliner/.osmosisd/config/genesis.json ]; then + osmosisd init validator --chain-id localosmo-1 --home /home/heighliner/.osmosisd + sed -i 's/timeout_commit = "5s"/timeout_commit = "1s"/' /home/heighliner/.osmosisd/config/config.toml + sed -i 's/timeout_propose = "3s"/timeout_propose = "1s"/' /home/heighliner/.osmosisd/config/config.toml + sed -i 's/laddr = "tcp:\/\/127.0.0.1:26657"/laddr = "tcp:\/\/0.0.0.0:26657"/' /home/heighliner/.osmosisd/config/config.toml + sed -i 's/enable = false/enable = true/' /home/heighliner/.osmosisd/config/app.toml + sed -i 's/cors_allowed_origins = \[\]/cors_allowed_origins = ["*"]/' /home/heighliner/.osmosisd/config/config.toml + osmosisd keys add validator --keyring-backend test --home /home/heighliner/.osmosisd + VALADDR=$$(osmosisd keys show validator -a --keyring-backend test --home /home/heighliner/.osmosisd) + osmosisd genesis add-genesis-account $$VALADDR 1000000000000uosmo --home /home/heighliner/.osmosisd + echo "${RELAYER_MNEMONIC}" | osmosisd keys add relayer --recover --keyring-backend test --home /home/heighliner/.osmosisd + RELAYADDR=$$(osmosisd keys show relayer -a --keyring-backend test --home /home/heighliner/.osmosisd) + osmosisd genesis add-genesis-account $$RELAYADDR 10000000000uosmo --home /home/heighliner/.osmosisd + osmosisd genesis gentx validator 500000000000uosmo --chain-id localosmo-1 --keyring-backend test --home /home/heighliner/.osmosisd + osmosisd genesis collect-gentxs --home /home/heighliner/.osmosisd + fi + osmosisd start --home /home/heighliner/.osmosisd + volumes: + - osmosis-data:/home/heighliner/.osmosisd + healthcheck: + test: ["CMD-SHELL", "osmosisd status --home /home/heighliner/.osmosisd 2>&1 | grep -q 'latest_block_height'"] + interval: 10s + timeout: 5s + retries: 30 + networks: + - devnet + + noble: + image: ghcr.io/noble-assets/noble:v11.3.0 + profiles: ["ibc", "full"] + user: "1025:1025" + entrypoint: ["/bin/sh", "-c"] + command: + - | + if [ ! -f /home/heighliner/.noble/config/genesis.json ]; then + nobled init validator --chain-id noble-devnet-1 --home /home/heighliner/.noble + sed -i 's/timeout_commit = "5s"/timeout_commit = "1s"/' /home/heighliner/.noble/config/config.toml + sed -i 's/timeout_propose = "3s"/timeout_propose = "1s"/' /home/heighliner/.noble/config/config.toml + sed -i 's/laddr = "tcp:\/\/127.0.0.1:26657"/laddr = "tcp:\/\/0.0.0.0:26657"/' /home/heighliner/.noble/config/config.toml + sed -i 's/enable = false/enable = true/' /home/heighliner/.noble/config/app.toml + sed -i 's/cors_allowed_origins = \[\]/cors_allowed_origins = ["*"]/' /home/heighliner/.noble/config/config.toml + nobled keys add validator --keyring-backend test --home /home/heighliner/.noble + VALADDR=$$(nobled keys show validator -a --keyring-backend test --home /home/heighliner/.noble) + nobled keys add minter --keyring-backend test --home /home/heighliner/.noble + MINTER=$$(nobled keys show minter -a --keyring-backend test --home /home/heighliner/.noble) + echo "${RELAYER_MNEMONIC}" | nobled keys add relayer --recover --keyring-backend test --home /home/heighliner/.noble + RELAYADDR=$$(nobled keys show relayer -a --keyring-backend test --home /home/heighliner/.noble) + nobled genesis add-genesis-account $$VALADDR 1000000000000ustake --home /home/heighliner/.noble + nobled genesis add-genesis-account $$MINTER 1000000ustake --home /home/heighliner/.noble + nobled genesis add-genesis-account $$RELAYADDR 10000000000ustake --home /home/heighliner/.noble + nobled genesis gentx validator 500000000000ustake --chain-id noble-devnet-1 --keyring-backend test --home /home/heighliner/.noble + nobled genesis collect-gentxs --home /home/heighliner/.noble + GENESIS=/home/heighliner/.noble/config/genesis.json + TEMP=/tmp/genesis.json + jq --arg addr "$$VALADDR" '.app_state.authority.owner = $$addr' $$GENESIS > $$TEMP && mv $$TEMP $$GENESIS + jq '.app_state.staking.params.bond_denom = "ustake"' $$GENESIS > $$TEMP && mv $$TEMP $$GENESIS + jq '.app_state.bank.denom_metadata += [{"description":"Circle USD Coin","denom_units":[{"denom":"uusdc","exponent":0,"aliases":["microusdc"]},{"denom":"usdc","exponent":6}],"base":"uusdc","display":"usdc","name":"Circle USD Coin","symbol":"USDC"}]' $$GENESIS > $$TEMP && mv $$TEMP $$GENESIS + jq '.app_state."fiat-tokenfactory".mintingDenom = {"denom":"uusdc"}' $$GENESIS > $$TEMP && mv $$TEMP $$GENESIS + jq '.app_state."fiat-tokenfactory".paused.paused = false' $$GENESIS > $$TEMP && mv $$TEMP $$GENESIS + jq --arg addr "$$VALADDR" '.app_state."fiat-tokenfactory".owner = {"address":$$addr}' $$GENESIS > $$TEMP && mv $$TEMP $$GENESIS + jq --arg addr "$$VALADDR" '.app_state."fiat-tokenfactory".masterMinter = {"address":$$addr}' $$GENESIS > $$TEMP && mv $$TEMP $$GENESIS + jq --arg ctrl "$$VALADDR" --arg minter "$$MINTER" '.app_state."fiat-tokenfactory".minterControllerList = [{"controller":$$ctrl,"minter":$$minter}]' $$GENESIS > $$TEMP && mv $$TEMP $$GENESIS + jq --arg minter "$$MINTER" '.app_state."fiat-tokenfactory".mintersList = [{"address":$$minter,"allowance":{"denom":"uusdc","amount":"1000000000000000"}}]' $$GENESIS > $$TEMP && mv $$TEMP $$GENESIS + fi + nobled start --home /home/heighliner/.noble + volumes: + - noble-data:/home/heighliner/.noble + healthcheck: + test: ["CMD-SHELL", "nobled status --home /home/heighliner/.noble 2>&1 | grep -q 'latest_block_height'"] + interval: 10s + timeout: 5s + retries: 30 + networks: + - devnet + + hermes: + image: ghcr.io/informalsystems/hermes:v1.12.0 + profiles: ["ibc", "full"] + volumes: + - ./config/hermes/config.toml:/home/hermes/.hermes/config.toml:ro + - hermes-data:/home/hermes/.hermes/keys + entrypoint: ["/bin/sh", "-c"] + command: + - | + echo "Waiting for chains to be ready..." + until hermes health-check 2>/dev/null; do sleep 5; done + + echo "${RELAYER_MNEMONIC}" > /tmp/mnemonic.txt + hermes keys add --chain xion-devnet-1 --mnemonic-file /tmp/mnemonic.txt --overwrite || true + hermes keys add --chain localosmo-1 --mnemonic-file /tmp/mnemonic.txt --overwrite || true + hermes keys add --chain noble-devnet-1 --mnemonic-file /tmp/mnemonic.txt --overwrite || true + rm /tmp/mnemonic.txt + + hermes create client --host-chain xion-devnet-1 --reference-chain localosmo-1 + hermes create client --host-chain localosmo-1 --reference-chain xion-devnet-1 + hermes create client --host-chain xion-devnet-1 --reference-chain noble-devnet-1 + hermes create client --host-chain noble-devnet-1 --reference-chain xion-devnet-1 + + hermes create connection --a-chain xion-devnet-1 --b-chain localosmo-1 + hermes create connection --a-chain xion-devnet-1 --b-chain noble-devnet-1 + + hermes create channel --a-chain xion-devnet-1 --a-connection connection-0 --a-port transfer --b-port transfer + hermes create channel --a-chain xion-devnet-1 --a-connection connection-1 --a-port transfer --b-port transfer + + echo "IBC channels created. Starting relayer..." + hermes start + depends_on: + xion: + condition: service_healthy + osmosis: + condition: service_healthy + noble: + condition: service_healthy + healthcheck: + test: ["CMD-SHELL", "hermes health-check 2>&1 | grep -q 'healthy'"] + interval: 30s + timeout: 10s + retries: 10 + networks: + - devnet + +# ═════════════════════════════════════════════════════════════════════════════ +# NETWORKS & VOLUMES +# ═════════════════════════════════════════════════════════════════════════════ networks: - default: + devnet: volumes: shared: + init-scripts: + postgres-data: + osmosis-data: + noble-data: + hermes-data: diff --git a/oauth2-api-service b/oauth2-api-service new file mode 160000 index 0000000..ea1f2bb --- /dev/null +++ b/oauth2-api-service @@ -0,0 +1 @@ +Subproject commit ea1f2bb8f9ca1fd62adcda583415284812d695ca diff --git a/oauth2-clients-dashboard b/oauth2-clients-dashboard new file mode 160000 index 0000000..a18f38a --- /dev/null +++ b/oauth2-clients-dashboard @@ -0,0 +1 @@ +Subproject commit a18f38aff1055ff8dbcae8c080ff67cde3267f8b diff --git a/scripts/init/deploy-contracts.sh b/scripts/init/deploy-contracts.sh new file mode 100755 index 0000000..b4b56d8 --- /dev/null +++ b/scripts/init/deploy-contracts.sh @@ -0,0 +1,229 @@ +#!/usr/bin/env bash +set -euo pipefail + +# ═══════════════════════════════════════════════════════════════════════════ +# deploy-contracts.sh — Post-genesis contract deployment for devnet +# +# Instantiates abstract account + treasury (fee granter) contracts after +# the chain starts producing blocks. The entrypoint.sh stores WASM codes +# in genesis (code_id 1 = abstract account, code_id 2 = treasury) but +# does NOT instantiate them. This script does the instantiation step. +# +# Usage: Run as a one-shot init container after xion is healthy. +# docker compose run --rm deploy-contracts +# ═══════════════════════════════════════════════════════════════════════════ + +SCRIPTS_DIR=$(dirname "$0") + +# Load environment +if [ -f "${HOME}/.env" ]; then + source "${HOME}/.env" +fi + +# Defaults +CHAIN_ID="${CHAIN_ID:-xion-devnet-1}" +DAEMON_NAME="${DAEMON_NAME:-xiond}" +DEFAULT_DENOM="${DEFAULT_DENOM:-uxion}" +NODE="${XION_RPC:-http://xion:26657}" +ABSTRAXION_KEY="abstraxion" + +# The mnemonic is the same devnet mnemonic used in entrypoint.sh +MNEMONIC="${MNEMONIC:?MNEMONIC is required}" + +OUTPUT_FILE="${OUTPUT_FILE:-/home/${DAEMON_NAME}/deploy-contracts.env}" + +# ─── Helpers ────────────────────────────────────────────────────────────── + +log() { echo "[deploy-contracts] $*"; } + +wait_for_chain() { + log "Waiting for chain to produce blocks..." + local attempts=0 + while ! ${DAEMON_NAME} status --node "${NODE}" 2>/dev/null | jq -e '.sync_info.latest_block_height | tonumber > 1' > /dev/null 2>&1; do + attempts=$((attempts + 1)) + if [ $attempts -ge 120 ]; then + log "ERROR: Chain not ready after 120s" + exit 1 + fi + sleep 1 + done + log "Chain is producing blocks" +} + +recover_key() { + log "Recovering deployer key '${ABSTRAXION_KEY}'..." + echo "${MNEMONIC}" | ${DAEMON_NAME} keys add "${ABSTRAXION_KEY}" \ + --account 1 --index 0 \ + --keyring-backend test --recover --output json 2>/dev/null || true + DEPLOYER_ADDR=$(${DAEMON_NAME} keys show "${ABSTRAXION_KEY}" -a --keyring-backend test) + log "Deployer address: ${DEPLOYER_ADDR}" +} + +tx_flags() { + echo "--from ${ABSTRAXION_KEY} --keyring-backend test --chain-id ${CHAIN_ID} --node ${NODE} --gas auto --gas-adjustment 1.5 --gas-prices 0.001${DEFAULT_DENOM} -y --output json" +} + +wait_for_tx() { + local txhash="$1" + local attempts=0 + while ! ${DAEMON_NAME} query tx "${txhash}" --node "${NODE}" --output json 2>/dev/null | jq -e '.code == 0' > /dev/null 2>&1; do + attempts=$((attempts + 1)) + if [ $attempts -ge 30 ]; then + log "ERROR: tx ${txhash} not confirmed after 30s" + ${DAEMON_NAME} query tx "${txhash}" --node "${NODE}" --output json 2>/dev/null || true + exit 1 + fi + sleep 1 + done +} + +# ─── Contract Instantiation ────────────────────────────────────────────── + +instantiate_abstract_account() { + local code_id=1 + log "Instantiating abstract account contract (code_id=${code_id})..." + + local init_msg='{"account_owner":{"key":"Ag=="}}' + + local result + result=$(${DAEMON_NAME} tx wasm instantiate "${code_id}" "${init_msg}" \ + --label "abstract-account-devnet" \ + --admin "${DEPLOYER_ADDR}" \ + $(tx_flags) 2>&1) + + local txhash + txhash=$(echo "${result}" | jq -r '.txhash // empty') + if [ -z "${txhash}" ]; then + log "WARN: Abstract account instantiation may have failed: ${result}" + AA_CONTRACT_ADDR="" + return + fi + + wait_for_tx "${txhash}" + AA_CONTRACT_ADDR=$(${DAEMON_NAME} query tx "${txhash}" --node "${NODE}" --output json | \ + jq -r '.events[] | select(.type=="instantiate") | .attributes[] | select(.key=="_contract_address") | .value') + log "Abstract account contract: ${AA_CONTRACT_ADDR}" +} + +instantiate_treasury() { + local code_id=2 + log "Instantiating treasury/fee-granter contract (code_id=${code_id})..." + + # Treasury instantiate msg based on e2e test patterns + # This sets up a basic fee granter with common authz grants + local init_msg + init_msg=$(cat <<'EOF' +{ + "admin": null, + "type_urls": [ + "/cosmos.bank.v1beta1.MsgSend", + "/cosmwasm.wasm.v1.MsgExecuteContract" + ], + "grant_configs": [ + { + "description": "Bank send authorization", + "authorization": { + "type_url": "/cosmos.authz.v1beta1.GenericAuthorization", + "value": "CiEvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5k" + }, + "optional": true + }, + { + "description": "Wasm execute authorization", + "authorization": { + "type_url": "/cosmos.authz.v1beta1.GenericAuthorization", + "value": "CicvY29zbXdhc20ud2FzbS52MS5Nc2dFeGVjdXRlQ29udHJhY3Q=" + }, + "optional": true + } + ], + "fee_config": { + "description": "Devnet fee allowance", + "allowance": { + "type_url": "/cosmos.feegrant.v1beta1.BasicAllowance", + "value": "" + }, + "expiration": 31536000 + }, + "params": { + "redirect_url": "http://localhost:4173", + "icon_url": "https://xion.burnt.com/icon.png", + "metadata": "{}" + } +} +EOF + ) + + local result + result=$(${DAEMON_NAME} tx wasm instantiate "${code_id}" "${init_msg}" \ + --label "treasury-fee-granter-devnet" \ + --admin "${DEPLOYER_ADDR}" \ + $(tx_flags) 2>&1) + + local txhash + txhash=$(echo "${result}" | jq -r '.txhash // empty') + if [ -z "${txhash}" ]; then + log "WARN: Treasury instantiation may have failed: ${result}" + TREASURY_ADDR="" + return + fi + + wait_for_tx "${txhash}" + TREASURY_ADDR=$(${DAEMON_NAME} query tx "${txhash}" --node "${NODE}" --output json | \ + jq -r '.events[] | select(.type=="instantiate") | .attributes[] | select(.key=="_contract_address") | .value') + log "Treasury/fee-granter contract: ${TREASURY_ADDR}" +} + +fund_treasury() { + if [ -z "${TREASURY_ADDR}" ]; then + log "WARN: No treasury address, skipping funding" + return + fi + + local fund_amount="10000000000${DEFAULT_DENOM}" # 10,000 XION + log "Funding treasury with ${fund_amount}..." + + local result + result=$(${DAEMON_NAME} tx bank send "${DEPLOYER_ADDR}" "${TREASURY_ADDR}" "${fund_amount}" \ + $(tx_flags) 2>&1) + + local txhash + txhash=$(echo "${result}" | jq -r '.txhash // empty') + if [ -n "${txhash}" ]; then + wait_for_tx "${txhash}" + log "Treasury funded" + else + log "WARN: Treasury funding may have failed: ${result}" + fi +} + +write_output() { + log "Writing deployment output to ${OUTPUT_FILE}..." + cat > "${OUTPUT_FILE}" < "${TMP_DIR}/genesis.json" + diff -u "${DAEMON_HOME}/config/genesis.json" "${TMP_DIR}/genesis.json" || true + mv "${TMP_DIR}/genesis.json" "${DAEMON_HOME}/config/genesis.json" fi echo "Collecting gentxs..." diff --git a/scripts/init/hermes-entrypoint.sh b/scripts/init/hermes-entrypoint.sh new file mode 100755 index 0000000..1a91d72 --- /dev/null +++ b/scripts/init/hermes-entrypoint.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Hermes IBC relayer init script +# Waits for all chains, imports keys, creates clients/connections/channels, starts relaying + +# Shared relayer mnemonic (same as in osmosis/noble entrypoints) +RELAYER_MNEMONIC="opinion chunk knowledge hospital nature adjust candy struggle grain lemon virtual trigger fiber promise phone jelly name attitude arrow daring assist fossil liberty strong" + +HERMES_HOME="${HOME}/.hermes" +MNEMONIC_FILE="/tmp/relayer_mnemonic.txt" + +echo "${RELAYER_MNEMONIC}" > "${MNEMONIC_FILE}" + +# ── Wait for all chains to be healthy ── + +wait_for_chain() { + local name="$1" + local rpc="$2" + echo "Waiting for ${name} at ${rpc}..." + for i in $(seq 1 120); do + if curl -sf "${rpc}/status" > /dev/null 2>&1; then + local height=$(curl -sf "${rpc}/status" | jq -r '.result.sync_info.latest_block_height // "0"') + if [ "${height}" != "0" ] && [ "${height}" != "null" ] && [ "$(echo "${height}" | tr -d '[:space:]')" -gt 1 ] 2>/dev/null; then + echo "${name} is ready (block height: ${height})" + return 0 + fi + fi + sleep 5 + done + echo "ERROR: ${name} did not become ready in time" + exit 1 +} + +wait_for_chain "Xion" "http://xion:26657" +wait_for_chain "Osmosis" "http://osmosis:26657" +wait_for_chain "Noble" "http://noble:26657" + +echo "All chains are healthy!" + +# ── Import relayer keys ── + +echo "Importing relayer keys..." +hermes keys add --chain xion-devnet-1 --mnemonic-file "${MNEMONIC_FILE}" --overwrite 2>&1 || true +hermes keys add --chain localosmo-1 --mnemonic-file "${MNEMONIC_FILE}" --overwrite 2>&1 || true +hermes keys add --chain noble-devnet-1 --mnemonic-file "${MNEMONIC_FILE}" --overwrite 2>&1 || true + +rm -f "${MNEMONIC_FILE}" + +# ── Create clients, connections, and channels ── + +echo "Creating Xion ↔ Osmosis connection..." +hermes create client --host-chain xion-devnet-1 --reference-chain localosmo-1 +hermes create client --host-chain localosmo-1 --reference-chain xion-devnet-1 +hermes create connection --a-chain xion-devnet-1 --b-chain localosmo-1 +echo "Creating Xion ↔ Osmosis transfer channel (connection-0)..." +hermes create channel --a-chain xion-devnet-1 --a-connection connection-0 --a-port transfer --b-port transfer + +echo "Creating Xion ↔ Noble connection..." +hermes create client --host-chain xion-devnet-1 --reference-chain noble-devnet-1 +hermes create client --host-chain noble-devnet-1 --reference-chain xion-devnet-1 +hermes create connection --a-chain xion-devnet-1 --b-chain noble-devnet-1 +echo "Creating Xion ↔ Noble transfer channel (connection-1)..." +hermes create channel --a-chain xion-devnet-1 --a-connection connection-1 --a-port transfer --b-port transfer + +echo "IBC channels created successfully!" +echo "Starting Hermes relayer..." + +exec hermes start diff --git a/scripts/init/noble-entrypoint.sh b/scripts/init/noble-entrypoint.sh new file mode 100755 index 0000000..db1d45a --- /dev/null +++ b/scripts/init/noble-entrypoint.sh @@ -0,0 +1,153 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Noble single-validator init script for devnet +# Includes USDC (fiat-tokenfactory) genesis configuration + +CHAIN_ID="noble-devnet-1" +DAEMON_NAME="nobled" +DAEMON_HOME="${HOME}/.noble" +STAKING_DENOM="ustake" +GENESIS_AMOUNT="1000000000000" +GENTX_AMOUNT="500000000000" + +# Noble devnet mnemonic — different from xion and osmosis +MNEMONIC="camp creek youth spend option clinic entry ice front myth dress analyst merge work art gate challenge horror search gap fashion blanket ivory critic" + +# Relayer shared mnemonic (same across all chains for Hermes) +RELAYER_MNEMONIC="opinion chunk knowledge hospital nature adjust candy struggle grain lemon virtual trigger fiber promise phone jelly name attitude arrow daring assist fossil liberty strong" + +init_noble() { + if [ -f "${DAEMON_HOME}/config/genesis.json" ]; then + echo "Chain already initialized, starting..." + exec ${DAEMON_NAME} start --home "${DAEMON_HOME}" + fi + + echo "Initializing Noble chain ${CHAIN_ID}..." + ${DAEMON_NAME} init validator --chain-id "${CHAIN_ID}" --home "${DAEMON_HOME}" > /dev/null 2>&1 + + # Create validator key from mnemonic + echo "${MNEMONIC}" | ${DAEMON_NAME} keys add validator --keyring-backend test --recover --home "${DAEMON_HOME}" > /dev/null 2>&1 + VALADDR=$(${DAEMON_NAME} keys show validator -a --keyring-backend test --home "${DAEMON_HOME}") + echo "Validator address: ${VALADDR}" + + # Create minter key (for USDC minting) + ${DAEMON_NAME} keys add minter --keyring-backend test --home "${DAEMON_HOME}" > /dev/null 2>&1 + MINTER=$(${DAEMON_NAME} keys show minter -a --keyring-backend test --home "${DAEMON_HOME}") + echo "Minter address: ${MINTER}" + + # Create relayer key from shared mnemonic + echo "${RELAYER_MNEMONIC}" | ${DAEMON_NAME} keys add relayer --keyring-backend test --recover --home "${DAEMON_HOME}" > /dev/null 2>&1 + RELAYADDR=$(${DAEMON_NAME} keys show relayer -a --keyring-backend test --home "${DAEMON_HOME}") + echo "Relayer address: ${RELAYADDR}" + + # Fund accounts (staking denom) + ${DAEMON_NAME} genesis add-genesis-account "${VALADDR}" "${GENESIS_AMOUNT}${STAKING_DENOM}" --home "${DAEMON_HOME}" --keyring-backend test + ${DAEMON_NAME} genesis add-genesis-account "${MINTER}" "1000000${STAKING_DENOM}" --home "${DAEMON_HOME}" --keyring-backend test + ${DAEMON_NAME} genesis add-genesis-account "${RELAYADDR}" "10000000000${STAKING_DENOM}" --home "${DAEMON_HOME}" --keyring-backend test + + # Create gentx + ${DAEMON_NAME} genesis gentx validator "${GENTX_AMOUNT}${STAKING_DENOM}" \ + --chain-id "${CHAIN_ID}" \ + --keyring-backend test \ + --home "${DAEMON_HOME}" + + # Collect gentxs + ${DAEMON_NAME} genesis collect-gentxs --home "${DAEMON_HOME}" > /dev/null 2>&1 + + # ── Noble-specific genesis modifications (USDC / fiat-tokenfactory) ── + + GENESIS="${DAEMON_HOME}/config/genesis.json" + TMP="/tmp/genesis_tmp.json" + + # Set staking bond denom + jq '.app_state.staking.params.bond_denom = "ustake"' "${GENESIS}" > "${TMP}" && mv "${TMP}" "${GENESIS}" + + # Set authority owner + jq --arg addr "${VALADDR}" '.app_state.authority.owner = $addr' "${GENESIS}" > "${TMP}" && mv "${TMP}" "${GENESIS}" + + # USDC denom metadata + jq '.app_state.bank.denom_metadata += [{ + "description": "Circle USD Coin", + "denom_units": [ + {"denom": "uusdc", "exponent": 0, "aliases": ["microusdc"]}, + {"denom": "usdc", "exponent": 6} + ], + "base": "uusdc", + "display": "usdc", + "name": "Circle USD Coin", + "symbol": "USDC" + }]' "${GENESIS}" > "${TMP}" && mv "${TMP}" "${GENESIS}" + + # Fiat token factory — enable USDC minting + jq '.app_state["fiat-tokenfactory"].mintingDenom = {"denom": "uusdc"}' "${GENESIS}" > "${TMP}" && mv "${TMP}" "${GENESIS}" + jq '.app_state["fiat-tokenfactory"].paused.paused = false' "${GENESIS}" > "${TMP}" && mv "${TMP}" "${GENESIS}" + jq --arg addr "${VALADDR}" '.app_state["fiat-tokenfactory"].owner = {"address": $addr}' "${GENESIS}" > "${TMP}" && mv "${TMP}" "${GENESIS}" + jq --arg addr "${VALADDR}" '.app_state["fiat-tokenfactory"].masterMinter = {"address": $addr}' "${GENESIS}" > "${TMP}" && mv "${TMP}" "${GENESIS}" + jq --arg ctrl "${VALADDR}" --arg minter "${MINTER}" \ + '.app_state["fiat-tokenfactory"].minterControllerList = [{"controller": $ctrl, "minter": $minter}]' \ + "${GENESIS}" > "${TMP}" && mv "${TMP}" "${GENESIS}" + jq --arg minter "${MINTER}" \ + '.app_state["fiat-tokenfactory"].mintersList = [{"address": $minter, "allowance": {"denom": "uusdc", "amount": "1000000000000000"}}]' \ + "${GENESIS}" > "${TMP}" && mv "${TMP}" "${GENESIS}" + + # Replace "stake" with "ustake" in genesis (Noble default denom fix) + sed -i 's/"stake"/"ustake"/g' "${GENESIS}" + + # ── Config modifications ── + + CONFIG="${DAEMON_HOME}/config/config.toml" + APP_CONFIG="${DAEMON_HOME}/config/app.toml" + + # Fast block times + sed -i 's/^timeout_commit =.*$/timeout_commit = "1s"/' "${CONFIG}" + sed -i 's/^timeout_propose =.*$/timeout_propose = "1s"/' "${CONFIG}" + + # Allow external RPC connections + sed -i 's|laddr = "tcp://127.0.0.1:26657"|laddr = "tcp://0.0.0.0:26657"|' "${CONFIG}" + + # CORS + sed -i 's/cors_allowed_origins = \[\]/cors_allowed_origins = ["*"]/' "${CONFIG}" + + # Disable strict address book + sed -i 's/^addr_book_strict =.*$/addr_book_strict = false/' "${CONFIG}" + + # Enable API + sed -i '/^\[api\]$/,/^\[/ s/^enable = false/enable = true/' "${APP_CONFIG}" + sed -i 's|address = "tcp://localhost:1317"|address = "tcp://0.0.0.0:1317"|' "${APP_CONFIG}" + + # Enable gRPC + sed -i '/^\[grpc\]$/,/^\[/ s/^enable = false/enable = true/' "${APP_CONFIG}" + sed -i 's|address = "localhost:9090"|address = "0.0.0.0:9090"|' "${APP_CONFIG}" + + echo "Noble chain initialized successfully!" + + # Start chain, then mint USDC in background after chain is ready + mint_usdc_background & + exec ${DAEMON_NAME} start --home "${DAEMON_HOME}" +} + +mint_usdc_background() { + echo "Waiting for chain to produce blocks before minting USDC..." + sleep 15 + for i in $(seq 1 30); do + if ${DAEMON_NAME} status --home "${DAEMON_HOME}" 2>/dev/null | jq -e '.sync_info.latest_block_height | tonumber > 1' > /dev/null 2>&1; then + echo "Chain is producing blocks, minting USDC..." + ${DAEMON_NAME} tx fiat-tokenfactory mint "${MINTER}" 1000000000000uusdc \ + --from minter \ + --keyring-backend test \ + --home "${DAEMON_HOME}" \ + --chain-id "${CHAIN_ID}" \ + --gas auto \ + --gas-adjustment 1.5 \ + -y 2>&1 || echo "USDC mint failed, may need manual minting" + return + fi + sleep 5 + done + echo "WARNING: Chain did not produce blocks in time, USDC not minted" +} + +# Export MINTER for background function +export MINTER="" +init_noble diff --git a/scripts/init/osmosis-entrypoint.sh b/scripts/init/osmosis-entrypoint.sh new file mode 100755 index 0000000..5a729fd --- /dev/null +++ b/scripts/init/osmosis-entrypoint.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Osmosis single-validator init script for devnet +# Simplified from xion entrypoint.sh pattern + +CHAIN_ID="localosmo-1" +DAEMON_NAME="osmosisd" +DAEMON_HOME="${HOME}/.osmosisd" +DEFAULT_DENOM="uosmo" +GENESIS_AMOUNT="1000000000000" +GENTX_AMOUNT="500000000000" + +# Osmosis devnet mnemonic — different from xion +MNEMONIC="milk butter claim chair orient slow already effort champion feed meadow catalog worry kitchen risk flower surround cloud trip chapter vehicle economy voyage abstract" + +# Relayer shared mnemonic (same across all chains for Hermes) +RELAYER_MNEMONIC="opinion chunk knowledge hospital nature adjust candy struggle grain lemon virtual trigger fiber promise phone jelly name attitude arrow daring assist fossil liberty strong" + +init_osmosis() { + if [ -f "${DAEMON_HOME}/config/genesis.json" ]; then + echo "Chain already initialized, starting..." + exec ${DAEMON_NAME} start --home "${DAEMON_HOME}" + fi + + echo "Initializing Osmosis chain ${CHAIN_ID}..." + ${DAEMON_NAME} init validator --chain-id "${CHAIN_ID}" --home "${DAEMON_HOME}" --default-denom "${DEFAULT_DENOM}" > /dev/null 2>&1 + + # Create validator key from mnemonic + echo "${MNEMONIC}" | ${DAEMON_NAME} keys add validator --keyring-backend test --recover --home "${DAEMON_HOME}" > /dev/null 2>&1 + VALADDR=$(${DAEMON_NAME} keys show validator -a --keyring-backend test --home "${DAEMON_HOME}") + echo "Validator address: ${VALADDR}" + + # Create relayer key from shared mnemonic + echo "${RELAYER_MNEMONIC}" | ${DAEMON_NAME} keys add relayer --keyring-backend test --recover --home "${DAEMON_HOME}" > /dev/null 2>&1 + RELAYADDR=$(${DAEMON_NAME} keys show relayer -a --keyring-backend test --home "${DAEMON_HOME}") + echo "Relayer address: ${RELAYADDR}" + + # Create test account + ${DAEMON_NAME} keys add test-account --keyring-backend test --home "${DAEMON_HOME}" > /dev/null 2>&1 + TESTADDR=$(${DAEMON_NAME} keys show test-account -a --keyring-backend test --home "${DAEMON_HOME}") + + # Fund accounts in genesis + ${DAEMON_NAME} genesis add-genesis-account "${VALADDR}" "${GENESIS_AMOUNT}${DEFAULT_DENOM}" --home "${DAEMON_HOME}" --keyring-backend test + ${DAEMON_NAME} genesis add-genesis-account "${RELAYADDR}" "10000000000${DEFAULT_DENOM}" --home "${DAEMON_HOME}" --keyring-backend test + ${DAEMON_NAME} genesis add-genesis-account "${TESTADDR}" "10000000000${DEFAULT_DENOM}" --home "${DAEMON_HOME}" --keyring-backend test + + # Create gentx + ${DAEMON_NAME} genesis gentx validator "${GENTX_AMOUNT}${DEFAULT_DENOM}" \ + --chain-id "${CHAIN_ID}" \ + --keyring-backend test \ + --home "${DAEMON_HOME}" + + # Collect gentxs + ${DAEMON_NAME} genesis collect-gentxs --home "${DAEMON_HOME}" > /dev/null 2>&1 + + # ── Config modifications ── + + CONFIG="${DAEMON_HOME}/config/config.toml" + APP_CONFIG="${DAEMON_HOME}/config/app.toml" + + # Fast block times + sed -i 's/^timeout_commit =.*$/timeout_commit = "1s"/' "${CONFIG}" + sed -i 's/^timeout_propose =.*$/timeout_propose = "1s"/' "${CONFIG}" + + # Allow external RPC connections + sed -i 's|laddr = "tcp://127.0.0.1:26657"|laddr = "tcp://0.0.0.0:26657"|' "${CONFIG}" + + # CORS + sed -i 's/cors_allowed_origins = \[\]/cors_allowed_origins = ["*"]/' "${CONFIG}" + + # Disable strict address book + sed -i 's/^addr_book_strict =.*$/addr_book_strict = false/' "${CONFIG}" + + # Enable API + sed -i '/^\[api\]$/,/^\[/ s/^enable = false/enable = true/' "${APP_CONFIG}" + sed -i 's|address = "tcp://localhost:1317"|address = "tcp://0.0.0.0:1317"|' "${APP_CONFIG}" + + # Enable gRPC + sed -i '/^\[grpc\]$/,/^\[/ s/^enable = false/enable = true/' "${APP_CONFIG}" + sed -i 's|address = "localhost:9090"|address = "0.0.0.0:9090"|' "${APP_CONFIG}" + + echo "Osmosis chain initialized successfully!" + exec ${DAEMON_NAME} start --home "${DAEMON_HOME}" +} + +init_osmosis diff --git a/xion b/xion index aaa3800..0d22d35 160000 --- a/xion +++ b/xion @@ -1 +1 @@ -Subproject commit aaa380084f0453af96577f34095f456c80c6988f +Subproject commit 0d22d35af0b4d4bf2162ec5fb8506eb0aae9054b diff --git a/xion-assets b/xion-assets index 30c5dd2..e3ffed5 160000 --- a/xion-assets +++ b/xion-assets @@ -1 +1 @@ -Subproject commit 30c5dd21f25c60c83724aa548cf8d81d110fc568 +Subproject commit e3ffed56a478394c6ffc12a179383b08bb000191 diff --git a/xion-dashboard-app b/xion-dashboard-app index 153b5a2..929807d 160000 --- a/xion-dashboard-app +++ b/xion-dashboard-app @@ -1 +1 @@ -Subproject commit 153b5a20f835baba5d01dcb1992374bf070d8fec +Subproject commit 929807d75b887fbd2cde5a31f6776ba8d31eebf6 diff --git a/xion-developer-portal b/xion-developer-portal index 50c999b..2a4fed3 160000 --- a/xion-developer-portal +++ b/xion-developer-portal @@ -1 +1 @@ -Subproject commit 50c999b3e48b2a5b9e73bf502de9f01f97bd55d9 +Subproject commit 2a4fed340cbc43b8d39d39a714447ad3a76751ee diff --git a/xion-indexer-proxy b/xion-indexer-proxy new file mode 160000 index 0000000..894b549 --- /dev/null +++ b/xion-indexer-proxy @@ -0,0 +1 @@ +Subproject commit 894b549a922d54925ac4b2d466c07c6c9e3d9d3b diff --git a/xion-staking b/xion-staking index c45398c..e5ee8d5 160000 --- a/xion-staking +++ b/xion-staking @@ -1 +1 @@ -Subproject commit c45398c0877addcf4fa33255030b75c67121520f +Subproject commit e5ee8d55d35be7abcc14a7b4c2c01d6072273f8d diff --git a/zk-email-backend b/zk-email-backend new file mode 160000 index 0000000..e9f1a46 --- /dev/null +++ b/zk-email-backend @@ -0,0 +1 @@ +Subproject commit e9f1a46979f652451c434523263d7e176dddc139 diff --git a/zk-email-prover b/zk-email-prover new file mode 160000 index 0000000..825cb33 --- /dev/null +++ b/zk-email-prover @@ -0,0 +1 @@ +Subproject commit 825cb3376ad42e9e673e39f728c6a372e9220196 diff --git a/zk-email-worker b/zk-email-worker new file mode 160000 index 0000000..c8a038d --- /dev/null +++ b/zk-email-worker @@ -0,0 +1 @@ +Subproject commit c8a038df705e57c38e82143d7a737bcb00881bbd