chore: migrate luxd HTTP routes /ext -> /v1

Drop the Avalanche-heritage /ext prefix; /v1 is the single canonical route
surface (one way, no backward compat). The node's baseURL is the source of
truth; clients, SDKs, CLI, indexer, maker, genesis, netrunner, and the
k8s/compose/gateway/explorer configs are updated to match.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
This commit is contained in:
zeekay
2026-07-01 11:40:13 -07:00
co-authored by Hanzo Dev
parent d254dccc8a
commit 51a304804c
64 changed files with 386 additions and 381 deletions
+2 -2
View File
@@ -367,7 +367,7 @@ RUN --mount=type=cache,target=/root/.cache/go-build \
# accelerator in pkg/lx is a separate concern gated by its own cuda/metal tags and # accelerator in pkg/lx is a separate concern gated by its own cuda/metal tags and
# is NOT linked here. v1.5.10 is the first tag whose cmd/dchain builds CGO=0 # is NOT linked here. v1.5.10 is the first tag whose cmd/dchain builds CGO=0
# (drops the phantom dchain+cgo gate); v1.5.11 wires CLOB order ingestion over the # (drops the phantom dchain+cgo gate); v1.5.11 wires CLOB order ingestion over the
# node HTTP router (VM.CreateHandlers -> /ext/bc/D/dex/<method>, pkg/dchain/ingest.go) # node HTTP router (VM.CreateHandlers -> /v1/bc/D/dex/<method>, pkg/dchain/ingest.go)
# so an order POSTed to the node flows submitTx -> mempool -> consensus -> Verify # so an order POSTed to the node flows submitTx -> mempool -> consensus -> Verify
# (match) -> Accept; v1.5.12 persists the head block so the VM survives a restart # (match) -> Accept; v1.5.12 persists the head block so the VM survives a restart
# once advanced past genesis (GetBlock(lastAccepted) no longer ErrNotFound); # once advanced past genesis (GetBlock(lastAccepted) no longer ErrNotFound);
@@ -379,7 +379,7 @@ RUN --mount=type=cache,target=/root/.cache/go-build \
# DB (every plugin VM via vm/rpc) — that stranded the native D-Chain order book # DB (every plugin VM via vm/rpc) — that stranded the native D-Chain order book
# (rebuildBookFromDB folded empty -> 0 fills despite committed asks). v1.5.15 adds # (rebuildBookFromDB folded empty -> 0 fills despite committed asks). v1.5.15 adds
# the committed-state READ surface (clob_get_trades/orders/markets/book over # the committed-state READ surface (clob_get_trades/orders/markets/book over
# /ext/bc/D/dex/<method>, pkg/dchain/read.go): read-only JSON of the durable trade # /v1/bc/D/dex/<method>, pkg/dchain/read.go): read-only JSON of the durable trade
# log / resting book / markets, served beside the writes with ZERO consensus # log / resting book / markets, served beside the writes with ZERO consensus
# impact. Needed to VERIFY a fill replicated identically across validators (query # impact. Needed to VERIFY a fill replicated identically across validators (query
# every node, diff the trade rows + head root) and to feed markets-display (native # every node, diff the trade rows + head root) and to feed markets-display (native
+1 -1
View File
@@ -52,7 +52,7 @@ Target: validate all consensus, EVM, and staking behavior with K=11 validators.
- [ ] Verify all precompile activation timestamps are after 2025-12-25 - [ ] Verify all precompile activation timestamps are after 2025-12-25
- [ ] Deploy via PaaS (platform.hanzo.ai), not manual kubectl - [ ] Deploy via PaaS (platform.hanzo.ai), not manual kubectl
- [ ] Verify all 11 pods reach Running state - [ ] Verify all 11 pods reach Running state
- [ ] Verify all 11 nodes report healthy via `/ext/health/liveness` - [ ] Verify all 11 nodes report healthy via `/v1/health/liveness`
### 1.2 Bootstrap and Connectivity ### 1.2 Bootstrap and Connectivity
+7 -7
View File
@@ -65,10 +65,10 @@ selection, and EVM contract auth.
### Where to look for X ### Where to look for X
- Profile resolve at boot: `node/node.go:initSecurityProfile` - Profile resolve at boot: `node/node.go:initSecurityProfile`
- Profile RPC + REST + metrics: `service/security/` - Profile RPC + REST + metrics: `service/security/`
- JSON-RPC namespace: `security` at `POST /ext/security` - JSON-RPC namespace: `security` at `POST /v1/security`
(methods `securityProfile`, `blockSecurity`) (methods `securityProfile`, `blockSecurity`)
- REST sidecars: `GET /ext/security/profile`, `GET /ext/security/block/{n}` - REST sidecars: `GET /v1/security/profile`, `GET /v1/security/block/{n}`
- Prometheus gauges: `/ext/metrics` under the `security_*` family - Prometheus gauges: `/v1/metrics` under the `security_*` family
- Peer scheme gate: `network/peer/scheme_gate.go` - Peer scheme gate: `network/peer/scheme_gate.go`
- Classical-compat registry: `vms/txs/auth/policy.go` - Classical-compat registry: `vms/txs/auth/policy.go`
- Mempool gate (P-Chain): `vms/platformvm/mempool/*.go` - Mempool gate (P-Chain): `vms/platformvm/mempool/*.go`
@@ -659,7 +659,7 @@ When CGO disabled, these use CPU fallbacks:
```bash ```bash
curl -s -X POST -H "Content-Type: application/json" \ curl -s -X POST -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}' \ -d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}' \
http://localhost:9640/ext/bc/C/rpc http://localhost:9640/v1/bc/C/rpc
# Returns: {"jsonrpc":"2.0","id":1,"result":"0x17870"} # Returns: {"jsonrpc":"2.0","id":1,"result":"0x17870"}
``` ```
@@ -668,7 +668,7 @@ curl -s -X POST -H "Content-Type: application/json" \
**Behavior**: **Behavior**:
- **GET /**: Returns JSON node information (nodeId, networkId, version, chains, endpoints) - **GET /**: Returns JSON node information (nodeId, networkId, version, chains, endpoints)
- **POST /**: Proxies JSON-RPC requests directly to C-chain `/ext/bc/C/rpc` - **POST /**: Proxies JSON-RPC requests directly to C-chain `/v1/bc/C/rpc`
- **OPTIONS /**: Returns CORS preflight headers - **OPTIONS /**: Returns CORS preflight headers
**Files Modified**: `server/http/router.go`, `server/http/server.go` **Files Modified**: `server/http/router.go`, `server/http/server.go`
@@ -735,7 +735,7 @@ if s.validators.NumNets() != 0 {
**Verification**: **Verification**:
```bash ```bash
curl -s http://localhost:9650/ext/health | jq '.checks.bls' curl -s http://localhost:9650/v1/health | jq '.checks.bls'
# Should show: "message": "node has the correct BLS key" # Should show: "message": "node has the correct BLS key"
``` ```
@@ -769,7 +769,7 @@ Testing conducted on a single Lux validator node (testnet mode, macOS):
**Benchmark Command:** **Benchmark Command:**
```bash ```bash
cd ~/work/lux/benchmarks cd ~/work/lux/benchmarks
NODE_ENDPOINT="http://localhost:9640/ext/bc/C/rpc" \ NODE_ENDPOINT="http://localhost:9640/v1/bc/C/rpc" \
PRIVATE_KEY="<funded_key>" \ PRIVATE_KEY="<funded_key>" \
./bin/bench tps --chains=lux --duration=60s --concurrency=5 ./bin/bench tps --chains=lux --duration=60s --concurrency=5
``` ```
+1 -1
View File
@@ -212,7 +212,7 @@ run-testnet: build-fips init-chains
node-status: node-status:
@echo "$(GREEN)Checking node status...$(NC)" @echo "$(GREEN)Checking node status...$(NC)"
@curl -s -X POST --data '{"jsonrpc":"2.0","id":1,"method":"info.isBootstrapped","params":{}}' \ @curl -s -X POST --data '{"jsonrpc":"2.0","id":1,"method":"info.isBootstrapped","params":{}}' \
-H 'content-type:application/json;' http://localhost:9630/ext/info | jq -H 'content-type:application/json;' http://localhost:9630/v1/info | jq
stop-node: stop-node:
@echo "$(YELLOW)Stopping Lux node...$(NC)" @echo "$(YELLOW)Stopping Lux node...$(NC)"
+1 -1
View File
@@ -3066,7 +3066,7 @@ This version is backwards compatible to [v1.9.0](https://github.com/luxfi/node/r
- Fixed `x/merkledb.ChangeProof#getLargestKey` to correctly handle no changes - Fixed `x/merkledb.ChangeProof#getLargestKey` to correctly handle no changes
- Added test for `xvm/txs/executor.SemanticVerifier#verifyFxUsage` with multiple valid fxs - Added test for `xvm/txs/executor.SemanticVerifier#verifyFxUsage` with multiple valid fxs
- Fixed CPU + bandwidth performance regression during vertex processing - Fixed CPU + bandwidth performance regression during vertex processing
- Added example usage of the `/ext/index/X/block` API - Added example usage of the `/v1/index/X/block` API
- Reduced the default value of `--consensus-optimal-processing` from `50` to `10` - Reduced the default value of `--consensus-optimal-processing` from `50` to `10`
- Updated the year in the license header - Updated the year in the license header
+3 -3
View File
@@ -816,7 +816,7 @@ func (b *blockHandler) BootstrapFailure() error {
// is correctly failing safe DOWN (VM in Bootstrapping, serving nothing as head) and waiting for the // is correctly failing safe DOWN (VM in Bootstrapping, serving nothing as head) and waiting for the
// quorum to return; the network cannot make progress without it. monitorBootstrap's no-progress // quorum to return; the network cannot make progress without it. monitorBootstrap's no-progress
// watchdog polls this so it does NOT force-STOP a node that is deliberately waiting — which, given // watchdog polls this so it does NOT force-STOP a node that is deliberately waiting — which, given
// the K8s probes only poll the always-green /ext/health/liveness, would be a permanent brick. It is // the K8s probes only poll the always-green /v1/health/liveness, would be a permanent brick. It is
// the discriminator between "stuck on a served gap" (a real stall → stop) and "waiting for the // the discriminator between "stuck on a served gap" (a real stall → stop) and "waiting for the
// quorum" (self-heal → keep waiting). Distinct from BootstrapFailed (a terminal/structural fail). // quorum" (self-heal → keep waiting). Distinct from BootstrapFailed (a terminal/structural fail).
func (b *blockHandler) BootstrapConnecting() bool { return b.bootstrapConnecting.Load() } func (b *blockHandler) BootstrapConnecting() bool { return b.bootstrapConnecting.Load() }
@@ -921,7 +921,7 @@ func (b *blockHandler) runBootstrapThenPoll(ctx context.Context) {
// no-progress watchdog treats it as a deliberate WAIT, not a stall: the node stays in Bootstrapping // no-progress watchdog treats it as a deliberate WAIT, not a stall: the node stays in Bootstrapping
// (serving nothing as head, NEVER live at the stale height) and CONVERGES the instant the quorum // (serving nothing as head, NEVER live at the stale height) and CONVERGES the instant the quorum
// returns — the in-process self-heal the K8s probes do NOT provide (they poll the always-green // returns — the in-process self-heal the K8s probes do NOT provide (they poll the always-green
// /ext/health/liveness, so a fail-safe-DOWN node is never restarted). A STRUCTURAL failure (deep gap // /v1/health/liveness, so a fail-safe-DOWN node is never restarted). A STRUCTURAL failure (deep gap
// → state-sync) or an exhausted attempt bound returns false WITHOUT going Ready, bootstrapFailed // → state-sync) or an exhausted attempt bound returns false WITHOUT going Ready, bootstrapFailed
// recording the reason so monitorBootstrap surfaces it. The node NEVER false-completes at its stale // recording the reason so monitorBootstrap surfaces it. The node NEVER false-completes at its stale
// height, and a transient outage NEVER becomes a permanent brick. // height, and a transient outage NEVER becomes a permanent brick.
@@ -963,7 +963,7 @@ func (b *blockHandler) runInitialSync(ctx context.Context) bool {
// (eclipse / partition / a majority co-restart still in flight) is RE-ATTEMPTED — the node stays // (eclipse / partition / a majority co-restart still in flight) is RE-ATTEMPTED — the node stays
// in Bootstrapping (engine alive, VM serving nothing as head, never live at the stale height) // in Bootstrapping (engine alive, VM serving nothing as head, never live at the stale height)
// and CONVERGES the instant the quorum returns. This is the recovery the K8s probes do NOT // and CONVERGES the instant the quorum returns. This is the recovery the K8s probes do NOT
// provide (they all poll the always-green /ext/health/liveness, so a fail-safe-DOWN node is // provide (they all poll the always-green /v1/health/liveness, so a fail-safe-DOWN node is
// never restarted). bootstrapMaxAttempts ≤ 0 ⇒ retry until the quorum returns or shutdown; a // never restarted). bootstrapMaxAttempts ≤ 0 ⇒ retry until the quorum returns or shutdown; a
// test pins it to 1 to assert the single-attempt terminal fail-safe. A STRUCTURAL failure (deep // test pins it to 1 to assert the single-attempt terminal fail-safe. A STRUCTURAL failure (deep
// gap → state-sync) is NOT retried — a retry cannot fix it; it is surfaced for the operator. // gap → state-sync) is NOT retried — a retry cannot fix it; it is surfaced for the operator.
+1 -1
View File
@@ -1528,7 +1528,7 @@ func TestRED_TipHolderCoRestartGoesReadyAtOwnTip(t *testing.T) {
// It must NOT go live at its stale height (safety) and must NOT permanently give up (liveness): it // It must NOT go live at its stale height (safety) and must NOT permanently give up (liveness): it
// stays in Bootstrapping, RE-ATTEMPTS (bootstrapMaxAttempts ≤ 0 ⇒ until the quorum returns), and // stays in Bootstrapping, RE-ATTEMPTS (bootstrapMaxAttempts ≤ 0 ⇒ until the quorum returns), and
// CONVERGES the instant the quorum comes back — all IN-PROCESS, with no pod restart (the K8s probes // CONVERGES the instant the quorum comes back — all IN-PROCESS, with no pod restart (the K8s probes
// poll the always-green /ext/health/liveness and would never restart it). This is the bounded // poll the always-green /v1/health/liveness and would never restart it). This is the bounded
// re-bootstrap retry that closes the "permanent brick" RED flagged. // re-bootstrap retry that closes the "permanent brick" RED flagged.
func TestRED_MajorityOutageSelfHealsWhenQuorumReturns(t *testing.T) { func TestRED_MajorityOutageSelfHealsWhenQuorumReturns(t *testing.T) {
const N, K = 30, 16 // stale at N; the live frontier (once the quorum returns) is N+K const N, K = 30, 16 // stale at N; the live frontier (once the quorum returns) is N+K
+8 -8
View File
@@ -219,7 +219,7 @@ type ChainParameters struct {
FxIDs []ids.ID FxIDs []ids.ID
// Invariant: Only used when [ID] is the P-chain ID. // Invariant: Only used when [ID] is the P-chain ID.
CustomBeacons validators.Manager CustomBeacons validators.Manager
// Name of the chain (used for HTTP routing alias, e.g., /ext/bc/zoo/rpc) // Name of the chain (used for HTTP routing alias, e.g., /v1/bc/zoo/rpc)
Name string Name string
} }
@@ -743,7 +743,7 @@ func (m *manager) createChain(chainParams ChainParameters) {
// plugin shows up later (e.g. via lpm install). // plugin shows up later (e.g. via lpm install).
// //
// The old behavior (always register a failing health check) made // The old behavior (always register a failing health check) made
// /ext/health return 503 for any opted-out chain, which made // /v1/health return 503 for any opted-out chain, which made
// kubelet liveness probes kill the validator pod. That made // kubelet liveness probes kill the validator pod. That made
// chain participation effectively all-or-nothing per validator. // chain participation effectively all-or-nothing per validator.
// Now: validators participate per-plugin, opt-in. // Now: validators participate per-plugin, opt-in.
@@ -855,7 +855,7 @@ func (m *manager) createChain(chainParams ChainParameters) {
m.Server.AddRoute(handler, chainIDBase, endpoint) m.Server.AddRoute(handler, chainIDBase, endpoint)
} }
// Also register with chain name alias for user-friendly routing (e.g., /ext/bc/zoo/rpc) // Also register with chain name alias for user-friendly routing (e.g., /v1/bc/zoo/rpc)
if chainParams.Name != "" { if chainParams.Name != "" {
nameLower := strings.ToLower(chainParams.Name) nameLower := strings.ToLower(chainParams.Name)
nameBase := fmt.Sprintf("bc/%s", nameLower) nameBase := fmt.Sprintf("bc/%s", nameLower)
@@ -928,9 +928,9 @@ func (m *manager) createChain(chainParams ChainParameters) {
m.Log.Info("║ VM ID:", log.Stringer("vmID", chainParams.VMID)) m.Log.Info("║ VM ID:", log.Stringer("vmID", chainParams.VMID))
m.Log.Info("║ Network ID:", log.Stringer("chainID", chainParams.ChainID)) m.Log.Info("║ Network ID:", log.Stringer("chainID", chainParams.ChainID))
m.Log.Info("║ Endpoints available at:") m.Log.Info("║ Endpoints available at:")
m.Log.Info("║ → /ext/bc/" + chainParams.ID.String()) m.Log.Info("║ → /v1/bc/" + chainParams.ID.String())
if chainAlias != chainParams.ID.String() { if chainAlias != chainParams.ID.String() {
m.Log.Info("║ → /ext/bc/" + chainAlias) m.Log.Info("║ → /v1/bc/" + chainAlias)
} }
m.Log.Info("╚══════════════════════════════════════════════════════════════════╝") m.Log.Info("╚══════════════════════════════════════════════════════════════════╝")
@@ -2080,7 +2080,7 @@ func (m *manager) monitorBootstrap(engine Engine, h handler.Handler, sb nets.Net
// this true. The no-progress watchdog treats it as a deliberate quorum WAIT, not a stall: it must // this true. The no-progress watchdog treats it as a deliberate quorum WAIT, not a stall: it must
// NOT force-STOP a node that is correctly failing safe DOWN and waiting for its quorum to return // NOT force-STOP a node that is correctly failing safe DOWN and waiting for its quorum to return
// (the network cannot progress without the quorum, and the K8s probes — all polling the // (the network cannot progress without the quorum, and the K8s probes — all polling the
// always-green /ext/health/liveness — would never restart it, so a stop here is a permanent // always-green /v1/health/liveness — would never restart it, so a stop here is a permanent
// brick). The node stays in Bootstrapping (serving nothing as head) and converges when the quorum // brick). The node stays in Bootstrapping (serving nothing as head) and converges when the quorum
// returns. nil for degenerate handlers (legacy behavior). // returns. nil for degenerate handlers (legacy behavior).
type bootstrapConnector interface{ BootstrapConnecting() bool } type bootstrapConnector interface{ BootstrapConnecting() bool }
@@ -2723,7 +2723,7 @@ type blockHandler struct {
// tells monitorBootstrap's no-progress watchdog this is a deliberate WAIT for the quorum to // tells monitorBootstrap's no-progress watchdog this is a deliberate WAIT for the quorum to
// return (the network cannot make progress without it), NOT a stall — so the watchdog does not // return (the network cannot make progress without it), NOT a stall — so the watchdog does not
// force-STOP a node that is correctly failing safe and waiting, which (given the K8s probes only // force-STOP a node that is correctly failing safe and waiting, which (given the K8s probes only
// poll the always-green /ext/health/liveness) would otherwise be a permanent brick. // poll the always-green /v1/health/liveness) would otherwise be a permanent brick.
bootstrapConnecting gatomic.Bool bootstrapConnecting gatomic.Bool
bsActive gatomic.Bool // true while the bootstrap loop is driving bsActive gatomic.Bool // true while the bootstrap loop is driving
bsMu sync.Mutex // guards bsFrontierCh + bsAncestorCh bsMu sync.Mutex // guards bsFrontierCh + bsAncestorCh
@@ -2826,7 +2826,7 @@ type blockHandler struct {
// DOWN — never live at a stale height) and CONVERGES the instant the quorum returns. ≤0 ⇒ // DOWN — never live at a stale height) and CONVERGES the instant the quorum returns. ≤0 ⇒
// UNLIMITED (retry until the quorum returns or shutdown) — the production default, because a // UNLIMITED (retry until the quorum returns or shutdown) — the production default, because a
// node without a quorum must keep trying to rejoin and the K8s liveness probe does NOT restart // node without a quorum must keep trying to rejoin and the K8s liveness probe does NOT restart
// it (all luxd probes poll the always-green /ext/health/liveness). A STRUCTURAL failure (deep // it (all luxd probes poll the always-green /v1/health/liveness). A STRUCTURAL failure (deep
// gap → state-sync) is never retried regardless. Tests pin it to 1 to assert the single-attempt // gap → state-sync) is never retried regardless. Tests pin it to 1 to assert the single-attempt
// terminal fail-safe in isolation. // terminal fail-safe in isolation.
bootstrapMaxAttempts int bootstrapMaxAttempts int
+7 -7
View File
@@ -68,20 +68,20 @@ func (d *DebugTool) DiagnoseEndpoint(chainID ids.ID, alias string) *DiagnosticRe
// getURLPatterns returns all possible URL patterns to test. // getURLPatterns returns all possible URL patterns to test.
func (d *DebugTool) getURLPatterns(chainID ids.ID, alias string) []string { func (d *DebugTool) getURLPatterns(chainID ids.ID, alias string) []string {
patterns := []string{ patterns := []string{
fmt.Sprintf("%s/ext/bc/%s/rpc", d.baseURL, chainID.String()), fmt.Sprintf("%s/v1/bc/%s/rpc", d.baseURL, chainID.String()),
fmt.Sprintf("%s/ext/bc/%s/ws", d.baseURL, chainID.String()), fmt.Sprintf("%s/v1/bc/%s/ws", d.baseURL, chainID.String()),
fmt.Sprintf("%s/ext/bc/%s", d.baseURL, chainID.String()), fmt.Sprintf("%s/v1/bc/%s", d.baseURL, chainID.String()),
} }
if alias != "" && alias != chainID.String() { if alias != "" && alias != chainID.String() {
patterns = append(patterns, patterns = append(patterns,
fmt.Sprintf("%s/ext/bc/%s/rpc", d.baseURL, alias), fmt.Sprintf("%s/v1/bc/%s/rpc", d.baseURL, alias),
fmt.Sprintf("%s/ext/bc/%s/ws", d.baseURL, alias), fmt.Sprintf("%s/v1/bc/%s/ws", d.baseURL, alias),
fmt.Sprintf("%s/ext/bc/%s", d.baseURL, alias), fmt.Sprintf("%s/v1/bc/%s", d.baseURL, alias),
) )
} }
// Also test without /ext prefix (some setups might differ) // Also test without /v1 prefix (some setups might differ)
patterns = append(patterns, patterns = append(patterns,
fmt.Sprintf("%s/bc/%s/rpc", d.baseURL, chainID.String()), fmt.Sprintf("%s/bc/%s/rpc", d.baseURL, chainID.String()),
) )
+2 -2
View File
@@ -80,9 +80,9 @@ func IntegrationExample(
fmt.Printf("\n✅ Chain %s RPC endpoints ready:\n", chainID) fmt.Printf("\n✅ Chain %s RPC endpoints ready:\n", chainID)
for _, endpoint := range info.Endpoints { for _, endpoint := range info.Endpoints {
if info.ChainAlias != "" { if info.ChainAlias != "" {
fmt.Printf(" %s/ext/bc/%s%s\n", baseURL, info.ChainAlias, endpoint) fmt.Printf(" %s/v1/bc/%s%s\n", baseURL, info.ChainAlias, endpoint)
} }
fmt.Printf(" %s/ext/bc/%s%s\n", baseURL, chainID, endpoint) fmt.Printf(" %s/v1/bc/%s%s\n", baseURL, chainID, endpoint)
} }
fmt.Println() fmt.Println()
} }
+1 -1
View File
@@ -19,7 +19,7 @@ services:
LUXD_CONSENSUS_QUORUM_SIZE: "1" LUXD_CONSENSUS_QUORUM_SIZE: "1"
LUXD_LOG_LEVEL: "info" LUXD_LOG_LEVEL: "info"
healthcheck: healthcheck:
test: ["CMD", "curl", "-sf", "http://localhost:9630/ext/health"] test: ["CMD", "curl", "-sf", "http://localhost:9630/v1/health"]
interval: 30s interval: 30s
timeout: 10s timeout: 10s
retries: 5 retries: 5
+5 -5
View File
@@ -133,12 +133,12 @@ deploy:
### Prometheus Metrics ### Prometheus Metrics
The node exposes metrics at `http://localhost:9630/ext/metrics` The node exposes metrics at `http://localhost:9630/v1/metrics`
### Health Checks ### Health Checks
- Liveness: `http://localhost:9630/ext/health` - Liveness: `http://localhost:9630/v1/health`
- Readiness: `http://localhost:9630/ext/info` - Readiness: `http://localhost:9630/v1/info`
### Grafana Dashboard ### Grafana Dashboard
@@ -178,12 +178,12 @@ docker exec -it luxd /bin/bash
# Check if bootstrapped # Check if bootstrapped
curl -X POST -H "Content-Type: application/json" \ curl -X POST -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"info.isBootstrapped","params":{"chain":"C"}}' \ -d '{"jsonrpc":"2.0","id":1,"method":"info.isBootstrapped","params":{"chain":"C"}}' \
http://localhost:9630/ext/info http://localhost:9630/v1/info
# Get block number # Get block number
curl -X POST -H "Content-Type: application/json" \ curl -X POST -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}' \ -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}' \
http://localhost:9630/ext/bc/C/rpc http://localhost:9630/v1/bc/C/rpc
``` ```
## CI/CD ## CI/CD
+4 -4
View File
@@ -287,10 +287,10 @@ echo "📝 Starting with command:"
echo " $CMD" echo " $CMD"
echo "" echo ""
echo "📡 API Endpoints:" echo "📡 API Endpoints:"
echo " - JSON-RPC: http://$HTTP_HOST:$HTTP_PORT/ext/bc/C/rpc" echo " - JSON-RPC: http://$HTTP_HOST:$HTTP_PORT/v1/bc/C/rpc"
echo " - WebSocket: ws://$HTTP_HOST:$HTTP_PORT/ext/bc/C/ws" echo " - WebSocket: ws://$HTTP_HOST:$HTTP_PORT/v1/bc/C/ws"
echo " - Health: http://$HTTP_HOST:$HTTP_PORT/ext/health" echo " - Health: http://$HTTP_HOST:$HTTP_PORT/v1/health"
echo " - Info: http://$HTTP_HOST:$HTTP_PORT/ext/info" echo " - Info: http://$HTTP_HOST:$HTTP_PORT/v1/info"
echo "" echo ""
# Execute # Execute
+1 -1
View File
@@ -346,7 +346,7 @@ export default function HomePage() {
</p> </p>
<pre className="mt-4 overflow-x-auto rounded-lg bg-black/50 p-4"> <pre className="mt-4 overflow-x-auto rounded-lg bg-black/50 p-4">
<code className="text-sm text-green-400"> <code className="text-sm text-green-400">
curl -X POST --data &#39;&#123;&quot;jsonrpc&quot;:&quot;2.0&quot;,&quot;method&quot;:&quot;health.health&quot;,&quot;id&quot;:1&#125;&#39; \{"\n"} -H &#39;content-type:application/json&#39; \{"\n"} 127.0.0.1:9650/ext/health curl -X POST --data &#39;&#123;&quot;jsonrpc&quot;:&quot;2.0&quot;,&quot;method&quot;:&quot;health.health&quot;,&quot;id&quot;:1&#125;&#39; \{"\n"} -H &#39;content-type:application/json&#39; \{"\n"} 127.0.0.1:9650/v1/health
</code> </code>
</pre> </pre>
</div> </div>
+20 -20
View File
@@ -31,7 +31,7 @@ Or in configuration:
## Endpoint ## Endpoint
``` ```
http://localhost:9630/ext/admin http://localhost:9630/v1/admin
``` ```
## Methods ## Methods
@@ -54,7 +54,7 @@ curl -X POST --data '{
"chain":"2S53R2ub94CV5vmSRAjqPYmRxvuiFunCb1gN2CAw3DQBfPWghX" "chain":"2S53R2ub94CV5vmSRAjqPYmRxvuiFunCb1gN2CAw3DQBfPWghX"
}, },
"id":1 "id":1
}' -H 'content-type:application/json;' http://localhost:9630/ext/admin }' -H 'content-type:application/json;' http://localhost:9630/v1/admin
``` ```
--- ---
@@ -85,7 +85,7 @@ curl -X POST --data '{
"chain":"2S53R2ub94CV5vmSRAjqPYmRxvuiFunCb1gN2CAw3DQBfPWghX" "chain":"2S53R2ub94CV5vmSRAjqPYmRxvuiFunCb1gN2CAw3DQBfPWghX"
}, },
"id":1 "id":1
}' -H 'content-type:application/json;' http://localhost:9630/ext/admin }' -H 'content-type:application/json;' http://localhost:9630/v1/admin
``` ```
**Response:** **Response:**
@@ -114,7 +114,7 @@ curl -X POST --data '{
"method":"admin.getLogLevel", "method":"admin.getLogLevel",
"params":{}, "params":{},
"id":1 "id":1
}' -H 'content-type:application/json;' http://localhost:9630/ext/admin }' -H 'content-type:application/json;' http://localhost:9630/v1/admin
``` ```
**Response:** **Response:**
@@ -146,7 +146,7 @@ curl -X POST --data '{
"logLevel":"debug" "logLevel":"debug"
}, },
"id":1 "id":1
}' -H 'content-type:application/json;' http://localhost:9630/ext/admin }' -H 'content-type:application/json;' http://localhost:9630/v1/admin
``` ```
--- ---
@@ -181,7 +181,7 @@ curl -X POST --data '{
"method":"admin.loadVMs", "method":"admin.loadVMs",
"params":{}, "params":{},
"id":1 "id":1
}' -H 'content-type:application/json;' http://localhost:9630/ext/admin }' -H 'content-type:application/json;' http://localhost:9630/v1/admin
``` ```
**Response:** **Response:**
@@ -214,7 +214,7 @@ curl -X POST --data '{
"method":"admin.startCPUProfiler", "method":"admin.startCPUProfiler",
"params":{}, "params":{},
"id":1 "id":1
}' -H 'content-type:application/json;' http://localhost:9630/ext/admin }' -H 'content-type:application/json;' http://localhost:9630/v1/admin
``` ```
--- ---
@@ -232,7 +232,7 @@ curl -X POST --data '{
"method":"admin.stopCPUProfiler", "method":"admin.stopCPUProfiler",
"params":{}, "params":{},
"id":1 "id":1
}' -H 'content-type:application/json;' http://localhost:9630/ext/admin }' -H 'content-type:application/json;' http://localhost:9630/v1/admin
``` ```
--- ---
@@ -250,7 +250,7 @@ curl -X POST --data '{
"method":"admin.memoryProfile", "method":"admin.memoryProfile",
"params":{}, "params":{},
"id":1 "id":1
}' -H 'content-type:application/json;' http://localhost:9630/ext/admin }' -H 'content-type:application/json;' http://localhost:9630/v1/admin
``` ```
--- ---
@@ -276,7 +276,7 @@ curl -X POST --data '{
"method":"admin.getConfig", "method":"admin.getConfig",
"params":{}, "params":{},
"id":1 "id":1
}' -H 'content-type:application/json;' http://localhost:9630/ext/admin }' -H 'content-type:application/json;' http://localhost:9630/v1/admin
``` ```
**Response:** **Response:**
@@ -311,7 +311,7 @@ curl -X POST --data '{
"method":"admin.shutdown", "method":"admin.shutdown",
"params":{}, "params":{},
"id":1 "id":1
}' -H 'content-type:application/json;' http://localhost:9630/ext/admin }' -H 'content-type:application/json;' http://localhost:9630/v1/admin
``` ```
--- ---
@@ -330,7 +330,7 @@ curl -X POST --data '{
"method":"admin.db.commit", "method":"admin.db.commit",
"params":{}, "params":{},
"id":1 "id":1
}' -H 'content-type:application/json;' http://localhost:9630/ext/admin }' -H 'content-type:application/json;' http://localhost:9630/v1/admin
``` ```
## Profiling and Debugging ## Profiling and Debugging
@@ -344,7 +344,7 @@ curl -X POST --data '{
"method":"admin.startCPUProfiler", "method":"admin.startCPUProfiler",
"params":{}, "params":{},
"id":1 "id":1
}' http://localhost:9630/ext/admin }' http://localhost:9630/v1/admin
# Let it run for 30 seconds # Let it run for 30 seconds
sleep 30 sleep 30
@@ -355,7 +355,7 @@ curl -X POST --data '{
"method":"admin.stopCPUProfiler", "method":"admin.stopCPUProfiler",
"params":{}, "params":{},
"id":2 "id":2
}' http://localhost:9630/ext/admin }' http://localhost:9630/v1/admin
# Analyze profile # Analyze profile
go tool pprof cpu.prof go tool pprof cpu.prof
@@ -370,7 +370,7 @@ curl -X POST --data '{
"method":"admin.memoryProfile", "method":"admin.memoryProfile",
"params":{}, "params":{},
"id":1 "id":1
}' http://localhost:9630/ext/admin }' http://localhost:9630/v1/admin
# Analyze # Analyze
go tool pprof mem.prof go tool pprof mem.prof
@@ -401,7 +401,7 @@ set_log_level() {
\"method\":\"admin.setLogLevel\", \"method\":\"admin.setLogLevel\",
\"params\":{\"logLevel\":\"$LEVEL\"}, \"params\":{\"logLevel\":\"$LEVEL\"},
\"id\":1 \"id\":1
}" http://localhost:9630/ext/admin }" http://localhost:9630/v1/admin
} }
# Increase verbosity for debugging # Increase verbosity for debugging
@@ -476,7 +476,7 @@ Enable audit logging for admin operations:
# auto_restart.sh # auto_restart.sh
check_health() { check_health() {
curl -s http://localhost:9630/ext/health | jq -r '.healthy' curl -s http://localhost:9630/v1/health | jq -r '.healthy'
} }
restart_node() { restart_node() {
@@ -488,7 +488,7 @@ restart_node() {
"method":"admin.shutdown", "method":"admin.shutdown",
"params":{}, "params":{},
"id":1 "id":1
}' http://localhost:9630/ext/admin }' http://localhost:9630/v1/admin
sleep 10 sleep 10
@@ -514,7 +514,7 @@ CURRENT=$(curl -s -X POST --data '{
"method":"admin.getConfig", "method":"admin.getConfig",
"params":{}, "params":{},
"id":1 "id":1
}' http://localhost:9630/ext/admin) }' http://localhost:9630/v1/admin)
echo "Current configuration:" echo "Current configuration:"
echo $CURRENT | jq . echo $CURRENT | jq .
@@ -525,7 +525,7 @@ curl -X POST --data '{
"method":"admin.setLogLevel", "method":"admin.setLogLevel",
"params":{"logLevel":"debug"}, "params":{"logLevel":"debug"},
"id":2 "id":2
}' http://localhost:9630/ext/admin }' http://localhost:9630/v1/admin
``` ```
## Troubleshooting ## Troubleshooting
+12 -12
View File
@@ -10,7 +10,7 @@ The Health API provides endpoints to monitor the health and readiness of your Lu
## Endpoint ## Endpoint
``` ```
http://localhost:9630/ext/health http://localhost:9630/v1/health
``` ```
## Health Check Types ## Health Check Types
@@ -20,7 +20,7 @@ http://localhost:9630/ext/health
Get the overall health status of the node: Get the overall health status of the node:
```bash ```bash
curl http://localhost:9630/ext/health curl http://localhost:9630/v1/health
``` ```
**Response:** **Response:**
@@ -61,7 +61,7 @@ curl http://localhost:9630/ext/health
Check if the node is ready to serve requests: Check if the node is ready to serve requests:
```bash ```bash
curl http://localhost:9630/ext/health/readiness curl http://localhost:9630/v1/health/readiness
``` ```
Returns: Returns:
@@ -73,7 +73,7 @@ Returns:
Check if the node is alive and running: Check if the node is alive and running:
```bash ```bash
curl http://localhost:9630/ext/health/liveness curl http://localhost:9630/v1/health/liveness
``` ```
Returns: Returns:
@@ -92,7 +92,7 @@ curl -X POST --data '{
"id": 1, "id": 1,
"method": "health.health", "method": "health.health",
"params": {} "params": {}
}' -H 'content-type:application/json;' http://localhost:9630/ext/health }' -H 'content-type:application/json;' http://localhost:9630/v1/health
``` ```
**Response:** **Response:**
@@ -175,7 +175,7 @@ Configure per-chain health parameters:
Export health metrics in Prometheus format: Export health metrics in Prometheus format:
```bash ```bash
curl http://localhost:9630/ext/metrics | grep health curl http://localhost:9630/v1/metrics | grep health
``` ```
Metrics: Metrics:
@@ -208,13 +208,13 @@ spec:
image: luxfi/node:latest image: luxfi/node:latest
livenessProbe: livenessProbe:
httpGet: httpGet:
path: /ext/health/liveness path: /v1/health/liveness
port: 9630 port: 9630
initialDelaySeconds: 30 initialDelaySeconds: 30
periodSeconds: 10 periodSeconds: 10
readinessProbe: readinessProbe:
httpGet: httpGet:
path: /ext/health/readiness path: /v1/health/readiness
port: 9630 port: 9630
initialDelaySeconds: 60 initialDelaySeconds: 60
periodSeconds: 5 periodSeconds: 5
@@ -229,7 +229,7 @@ spec:
# health_monitor.sh # health_monitor.sh
while true; do while true; do
HEALTH=$(curl -s http://localhost:9630/ext/health | jq -r '.healthy') HEALTH=$(curl -s http://localhost:9630/v1/health | jq -r '.healthy')
if [ "$HEALTH" != "true" ]; then if [ "$HEALTH" != "true" ]; then
echo "ALERT: Node unhealthy at $(date)" echo "ALERT: Node unhealthy at $(date)"
@@ -248,7 +248,7 @@ done
# health_analysis.sh # health_analysis.sh
# Get detailed health # Get detailed health
RESPONSE=$(curl -s http://localhost:9630/ext/health) RESPONSE=$(curl -s http://localhost:9630/v1/health)
# Parse each chain # Parse each chain
for CHAIN in P X C Q; do for CHAIN in P X C Q; do
@@ -271,7 +271,7 @@ done
``` ```
backend lux_nodes backend lux_nodes
option httpchk GET /ext/health option httpchk GET /v1/health
http-check expect status 200 http-check expect status 200
server node1 192.168.1.10:9630 check server node1 192.168.1.10:9630 check
@@ -289,7 +289,7 @@ upstream lux_nodes {
} }
location /health_check { location /health_check {
proxy_pass http://lux_nodes/ext/health; proxy_pass http://lux_nodes/v1/health;
proxy_connect_timeout 1s; proxy_connect_timeout 1s;
proxy_read_timeout 1s; proxy_read_timeout 1s;
} }
+23 -23
View File
@@ -10,7 +10,7 @@ The Info API provides general information about the node and network status. Thi
## Endpoint ## Endpoint
``` ```
http://localhost:9630/ext/info http://localhost:9630/v1/info
``` ```
## Format ## Format
@@ -23,7 +23,7 @@ curl -X POST --data '{
"method": "info.<method>", "method": "info.<method>",
"params": {...}, "params": {...},
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/info }' -H 'content-type:application/json;' http://localhost:9630/v1/info
``` ```
## Methods ## Methods
@@ -41,7 +41,7 @@ curl -X POST --data '{
"method": "info.getNodeVersion", "method": "info.getNodeVersion",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/info }' -H 'content-type:application/json;' http://localhost:9630/v1/info
``` ```
**Example Response:** **Example Response:**
@@ -78,7 +78,7 @@ curl -X POST --data '{
"method": "info.getNodeID", "method": "info.getNodeID",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/info }' -H 'content-type:application/json;' http://localhost:9630/v1/info
``` ```
**Example Response:** **Example Response:**
@@ -111,7 +111,7 @@ curl -X POST --data '{
"method": "info.getNodeIP", "method": "info.getNodeIP",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/info }' -H 'content-type:application/json;' http://localhost:9630/v1/info
``` ```
**Example Response:** **Example Response:**
@@ -140,7 +140,7 @@ curl -X POST --data '{
"method": "info.getNetworkID", "method": "info.getNetworkID",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/info }' -H 'content-type:application/json;' http://localhost:9630/v1/info
``` ```
**Example Response:** **Example Response:**
@@ -175,7 +175,7 @@ curl -X POST --data '{
"method": "info.getNetworkName", "method": "info.getNetworkName",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/info }' -H 'content-type:application/json;' http://localhost:9630/v1/info
``` ```
**Example Response:** **Example Response:**
@@ -207,7 +207,7 @@ curl -X POST --data '{
"alias": "P" "alias": "P"
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/info }' -H 'content-type:application/json;' http://localhost:9630/v1/info
``` ```
**Example Response:** **Example Response:**
@@ -239,7 +239,7 @@ curl -X POST --data '{
"chain": "P" "chain": "P"
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/info }' -H 'content-type:application/json;' http://localhost:9630/v1/info
``` ```
**Example Response:** **Example Response:**
@@ -269,7 +269,7 @@ curl -X POST --data '{
"method": "info.peers", "method": "info.peers",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/info }' -H 'content-type:application/json;' http://localhost:9630/v1/info
``` ```
**Example Response:** **Example Response:**
@@ -313,7 +313,7 @@ curl -X POST --data '{
"method": "info.getTxFee", "method": "info.getTxFee",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/info }' -H 'content-type:application/json;' http://localhost:9630/v1/info
``` ```
**Example Response:** **Example Response:**
@@ -348,7 +348,7 @@ curl -X POST --data '{
"method": "info.uptime", "method": "info.uptime",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/info }' -H 'content-type:application/json;' http://localhost:9630/v1/info
``` ```
**Example Response (Validator):** **Example Response (Validator):**
@@ -390,7 +390,7 @@ curl -X POST --data '{
"method": "info.getVMs", "method": "info.getVMs",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/info }' -H 'content-type:application/json;' http://localhost:9630/v1/info
``` ```
**Example Response:** **Example Response:**
@@ -424,7 +424,7 @@ curl -X POST --data '{
"method": "info.getUpgrades", "method": "info.getUpgrades",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/info }' -H 'content-type:application/json;' http://localhost:9630/v1/info
``` ```
**Example Response:** **Example Response:**
@@ -468,7 +468,7 @@ VERSION=$(curl -s -X POST --data '{
"method": "info.getNodeVersion", "method": "info.getNodeVersion",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' $NODE_URL/ext/info | jq -r '.result.version') }' -H 'content-type:application/json;' $NODE_URL/v1/info | jq -r '.result.version')
echo "Version: $VERSION" echo "Version: $VERSION"
@@ -478,7 +478,7 @@ NODE_ID=$(curl -s -X POST --data '{
"method": "info.getNodeID", "method": "info.getNodeID",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' $NODE_URL/ext/info | jq -r '.result.nodeID') }' -H 'content-type:application/json;' $NODE_URL/v1/info | jq -r '.result.nodeID')
echo "Node ID: $NODE_ID" echo "Node ID: $NODE_ID"
@@ -488,7 +488,7 @@ PEERS=$(curl -s -X POST --data '{
"method": "info.peers", "method": "info.peers",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' $NODE_URL/ext/info | jq -r '.result.numPeers') }' -H 'content-type:application/json;' $NODE_URL/v1/info | jq -r '.result.numPeers')
echo "Connected Peers: $PEERS" echo "Connected Peers: $PEERS"
@@ -499,7 +499,7 @@ for CHAIN in P X C Q; do
\"method\": \"info.isBootstrapped\", \"method\": \"info.isBootstrapped\",
\"params\": {\"chain\": \"$CHAIN\"}, \"params\": {\"chain\": \"$CHAIN\"},
\"id\": 1 \"id\": 1
}" -H 'content-type:application/json;' $NODE_URL/ext/info | jq -r '.result.isBootstrapped') }" -H 'content-type:application/json;' $NODE_URL/v1/info | jq -r '.result.isBootstrapped')
echo "$CHAIN-Chain Bootstrapped: $STATUS" echo "$CHAIN-Chain Bootstrapped: $STATUS"
done done
@@ -510,7 +510,7 @@ UPTIME=$(curl -s -X POST --data '{
"method": "info.uptime", "method": "info.uptime",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' $NODE_URL/ext/info 2>/dev/null | jq -r '.result.rewardingStakePercentage' 2>/dev/null) }' -H 'content-type:application/json;' $NODE_URL/v1/info 2>/dev/null | jq -r '.result.rewardingStakePercentage' 2>/dev/null)
if [ "$UPTIME" != "null" ] && [ -n "$UPTIME" ]; then if [ "$UPTIME" != "null" ] && [ -n "$UPTIME" ]; then
echo "Validator Uptime: $UPTIME%" echo "Validator Uptime: $UPTIME%"
@@ -531,7 +531,7 @@ PEERS=$(curl -s -X POST --data '{
"method": "info.peers", "method": "info.peers",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' $NODE_URL/ext/info | jq -r '.result.peers[]') }' -H 'content-type:application/json;' $NODE_URL/v1/info | jq -r '.result.peers[]')
echo "=== Peer Connection Quality ===" echo "=== Peer Connection Quality ==="
echo "Node ID | Latency (ms) | Uptime % | Version" echo "Node ID | Latency (ms) | Uptime % | Version"
@@ -560,7 +560,7 @@ while true; do
\"method\": \"info.isBootstrapped\", \"method\": \"info.isBootstrapped\",
\"params\": {\"chain\": \"$CHAIN\"}, \"params\": {\"chain\": \"$CHAIN\"},
\"id\": 1 \"id\": 1
}" -H 'content-type:application/json;' $NODE_URL/ext/info | jq -r '.result.isBootstrapped') }" -H 'content-type:application/json;' $NODE_URL/v1/info | jq -r '.result.isBootstrapped')
if [ "$STATUS" == "true" ]; then if [ "$STATUS" == "true" ]; then
echo "✅ $CHAIN-Chain: Bootstrapped" echo "✅ $CHAIN-Chain: Bootstrapped"
@@ -575,7 +575,7 @@ while true; do
"method": "info.peers", "method": "info.peers",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' $NODE_URL/ext/info | jq -r '.result.numPeers') }' -H 'content-type:application/json;' $NODE_URL/v1/info | jq -r '.result.numPeers')
echo "" echo ""
echo "Connected Peers: $PEERS" echo "Connected Peers: $PEERS"
@@ -588,7 +588,7 @@ while true; do
\"method\": \"info.isBootstrapped\", \"method\": \"info.isBootstrapped\",
\"params\": {\"chain\": \"$CHAIN\"}, \"params\": {\"chain\": \"$CHAIN\"},
\"id\": 1 \"id\": 1
}" -H 'content-type:application/json;' $NODE_URL/ext/info | jq -r '.result.isBootstrapped') }" -H 'content-type:application/json;' $NODE_URL/v1/info | jq -r '.result.isBootstrapped')
if [ "$STATUS" != "true" ]; then if [ "$STATUS" != "true" ]; then
ALL_BOOTSTRAPPED=false ALL_BOOTSTRAPPED=false
+23 -23
View File
@@ -10,7 +10,7 @@ The Platform Chain (P-Chain) is responsible for staking, validators, and chain m
## Endpoint ## Endpoint
``` ```
http://localhost:9630/ext/bc/P http://localhost:9630/v1/bc/P
``` ```
## Format ## Format
@@ -23,7 +23,7 @@ curl -X POST --data '{
"method": "platform.<method>", "method": "platform.<method>",
"params": {...}, "params": {...},
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/P }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/P
``` ```
## Methods ## Methods
@@ -41,7 +41,7 @@ curl -X POST --data '{
"method": "platform.getHeight", "method": "platform.getHeight",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/P }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -73,7 +73,7 @@ curl -X POST --data '{
"addresses": ["P-lux1q8tgunsf7sxpl2qp9fz0xjs36kstm7vdjvpzcc"] "addresses": ["P-lux1q8tgunsf7sxpl2qp9fz0xjs36kstm7vdjvpzcc"]
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/P }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -114,7 +114,7 @@ curl -X POST --data '{
"limit": 100 "limit": 100
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/P }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/P
``` ```
--- ---
@@ -134,7 +134,7 @@ curl -X POST --data '{
"method": "platform.getCurrentValidators", "method": "platform.getCurrentValidators",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/P }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -190,7 +190,7 @@ curl -X POST --data '{
"method": "platform.getPendingValidators", "method": "platform.getPendingValidators",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/P }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/P
``` ```
--- ---
@@ -212,7 +212,7 @@ curl -X POST --data '{
"height": 365000 "height": 365000
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/P }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/P
``` ```
--- ---
@@ -233,7 +233,7 @@ curl -X POST --data '{
"height": 365000 "height": 365000
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/P }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/P
``` ```
--- ---
@@ -255,7 +255,7 @@ curl -X POST --data '{
"addresses": ["P-lux1q8tgunsf7sxpl2qp9fz0xjs36kstm7vdjvpzcc"] "addresses": ["P-lux1q8tgunsf7sxpl2qp9fz0xjs36kstm7vdjvpzcc"]
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/P }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/P
``` ```
--- ---
@@ -274,7 +274,7 @@ curl -X POST --data '{
"method": "platform.getMinStake", "method": "platform.getMinStake",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/P }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -305,7 +305,7 @@ curl -X POST --data '{
"method": "platform.getTotalStake", "method": "platform.getTotalStake",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/P }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/P
``` ```
--- ---
@@ -327,7 +327,7 @@ curl -X POST --data '{
"txID": "2nmH8LithVbdjaXsxVQCQfXtzN9hBbmebrsaEYnLM9T32Uy3Y5" "txID": "2nmH8LithVbdjaXsxVQCQfXtzN9hBbmebrsaEYnLM9T32Uy3Y5"
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/P }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/P
``` ```
--- ---
@@ -345,7 +345,7 @@ curl -X POST --data '{
"method": "platform.getTimestamp", "method": "platform.getTimestamp",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/P }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/P
``` ```
--- ---
@@ -363,7 +363,7 @@ curl -X POST --data '{
"method": "platform.getBlockchains", "method": "platform.getBlockchains",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/P }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -409,7 +409,7 @@ curl -X POST --data '{
"blockID": "vXSY7FK7NR65Y8BrJDKQH4a6vBdJuqAMvVzWj3Zxcap5J4ZE3" "blockID": "vXSY7FK7NR65Y8BrJDKQH4a6vBdJuqAMvVzWj3Zxcap5J4ZE3"
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/P }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/P
``` ```
--- ---
@@ -431,7 +431,7 @@ curl -X POST --data '{
"txID": "2nmH8LithVbdjaXsxVQCQfXtzN9hBbmebrsaEYnLM9T32Uy3Y5" "txID": "2nmH8LithVbdjaXsxVQCQfXtzN9hBbmebrsaEYnLM9T32Uy3Y5"
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/P }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/P
``` ```
--- ---
@@ -452,7 +452,7 @@ curl -X POST --data '{
"txID": "2nmH8LithVbdjaXsxVQCQfXtzN9hBbmebrsaEYnLM9T32Uy3Y5" "txID": "2nmH8LithVbdjaXsxVQCQfXtzN9hBbmebrsaEYnLM9T32Uy3Y5"
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/P }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -488,7 +488,7 @@ curl -X POST --data '{
"method": "platform.getCurrentSupply", "method": "platform.getCurrentSupply",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/P }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/P
``` ```
--- ---
@@ -507,7 +507,7 @@ curl -X POST --data '{
"method": "platform.getChains", "method": "platform.getChains",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/P }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/P
``` ```
--- ---
@@ -544,7 +544,7 @@ curl -X POST --data '{
"password": "mypassword" "password": "mypassword"
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/P }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/P
``` ```
--- ---
@@ -694,7 +694,7 @@ curl -s -X POST --data "{
\"nodeIDs\": [\"$NODE_ID\"] \"nodeIDs\": [\"$NODE_ID\"]
}, },
\"id\": 1 \"id\": 1
}" -H 'content-type:application/json;' http://localhost:9630/ext/bc/P | jq '.result.validators[0]' }" -H 'content-type:application/json;' http://localhost:9630/v1/bc/P | jq '.result.validators[0]'
``` ```
### Monitor Staking Rewards ### Monitor Staking Rewards
@@ -711,7 +711,7 @@ STAKE=$(curl -s -X POST --data "{
\"addresses\": [\"$ADDRESS\"] \"addresses\": [\"$ADDRESS\"]
}, },
\"id\": 1 \"id\": 1
}" -H 'content-type:application/json;' http://localhost:9630/ext/bc/P) }" -H 'content-type:application/json;' http://localhost:9630/v1/bc/P)
echo "Current stake: $(echo $STAKE | jq -r '.result.staked')" echo "Current stake: $(echo $STAKE | jq -r '.result.staked')"
echo "Stakeable: $(echo $STAKE | jq -r '.result.stakeable')" echo "Stakeable: $(echo $STAKE | jq -r '.result.stakeable')"
@@ -210,14 +210,14 @@ curl -X POST --data '{
"jsonrpc":"2.0", "jsonrpc":"2.0",
"id": 1, "id": 1,
"method": "health.health" "method": "health.health"
}' -H 'content-type:application/json;' http://localhost:9630/ext/health }' -H 'content-type:application/json;' http://localhost:9630/v1/health
# Get node info # Get node info
curl -X POST --data '{ curl -X POST --data '{
"jsonrpc":"2.0", "jsonrpc":"2.0",
"id": 1, "id": 1,
"method": "info.getNodeVersion" "method": "info.getNodeVersion"
}' -H 'content-type:application/json;' http://localhost:9630/ext/info }' -H 'content-type:application/json;' http://localhost:9630/v1/info
# Check bootstrap status # Check bootstrap status
curl -X POST --data '{ curl -X POST --data '{
@@ -227,7 +227,7 @@ curl -X POST --data '{
"params": { "params": {
"chain": "P" "chain": "P"
} }
}' -H 'content-type:application/json;' http://localhost:9630/ext/info }' -H 'content-type:application/json;' http://localhost:9630/v1/info
``` ```
## Troubleshooting ## Troubleshooting
@@ -308,7 +308,7 @@ curl -X POST --data '{
"jsonrpc":"2.0", "jsonrpc":"2.0",
"id": 1, "id": 1,
"method": "health.health" "method": "health.health"
}' -H 'content-type:application/json;' http://localhost:9630/ext/health }' -H 'content-type:application/json;' http://localhost:9630/v1/health
``` ```
### Bootstrap Status ### Bootstrap Status
@@ -320,7 +320,7 @@ curl -X POST --data '{
"id": 1, "id": 1,
"method": "info.isBootstrapped", "method": "info.isBootstrapped",
"params": {"chain": "P"} "params": {"chain": "P"}
}' -H 'content-type:application/json;' http://localhost:9630/ext/info }' -H 'content-type:application/json;' http://localhost:9630/v1/info
``` ```
### Metrics ### Metrics
@@ -328,7 +328,7 @@ curl -X POST --data '{
Access Prometheus metrics: Access Prometheus metrics:
```bash ```bash
curl http://localhost:9630/ext/metrics curl http://localhost:9630/v1/metrics
``` ```
Key metrics to monitor: Key metrics to monitor:
+17 -17
View File
@@ -58,7 +58,7 @@ curl -X POST --data '{
"jsonrpc":"2.0", "jsonrpc":"2.0",
"id": 1, "id": 1,
"method": "platform.getHeight" "method": "platform.getHeight"
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/P }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/P
# Check bootstrap status for all chains # Check bootstrap status for all chains
curl -X POST --data '{ curl -X POST --data '{
@@ -66,7 +66,7 @@ curl -X POST --data '{
"id": 1, "id": 1,
"method": "info.isBootstrapped", "method": "info.isBootstrapped",
"params": {"chain": "P"} "params": {"chain": "P"}
}' -H 'content-type:application/json;' http://localhost:9630/ext/info }' -H 'content-type:application/json;' http://localhost:9630/v1/info
``` ```
### Configure Public IP ### Configure Public IP
@@ -90,7 +90,7 @@ curl -X POST --data '{
"jsonrpc":"2.0", "jsonrpc":"2.0",
"id": 1, "id": 1,
"method": "info.getNodeID" "method": "info.getNodeID"
}' -H 'content-type:application/json;' http://localhost:9630/ext/info }' -H 'content-type:application/json;' http://localhost:9630/v1/info
``` ```
Response: Response:
@@ -155,7 +155,7 @@ curl -X POST --data '{
"password": "mypassword" "password": "mypassword"
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/keystore }' -H 'content-type:application/json;' http://localhost:9630/v1/keystore
# Create P-Chain address # Create P-Chain address
curl -X POST --data '{ curl -X POST --data '{
@@ -166,7 +166,7 @@ curl -X POST --data '{
"password": "mypassword" "password": "mypassword"
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/P }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/P
``` ```
### Transfer LUX to P-Chain ### Transfer LUX to P-Chain
@@ -185,7 +185,7 @@ curl -X POST --data '{
"amount": 2000000000000 "amount": 2000000000000
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/X }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/X
# Import to P-Chain # Import to P-Chain
curl -X POST --data '{ curl -X POST --data '{
@@ -197,7 +197,7 @@ curl -X POST --data '{
"sourceChain": "X" "sourceChain": "X"
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/P }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/P
``` ```
## Step 4: Add as Validator ## Step 4: Add as Validator
@@ -221,7 +221,7 @@ curl -X POST --data '{
"delegationFeeRate": 10 "delegationFeeRate": 10
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/P }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/P
``` ```
Parameters: Parameters:
@@ -243,7 +243,7 @@ curl -X POST --data '{
"method": "platform.getPendingValidators", "method": "platform.getPendingValidators",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/P }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/P
# Get current validators # Get current validators
curl -X POST --data '{ curl -X POST --data '{
@@ -251,7 +251,7 @@ curl -X POST --data '{
"method": "platform.getCurrentValidators", "method": "platform.getCurrentValidators",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/P }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/P
``` ```
## Step 5: Monitor Your Validator ## Step 5: Monitor Your Validator
@@ -268,7 +268,7 @@ curl -X POST --data '{
"nodeID": "NodeID-5KqnQfaFQxY9rsFBAa68377qWSherYLQ7" "nodeID": "NodeID-5KqnQfaFQxY9rsFBAa68377qWSherYLQ7"
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/P }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/P
``` ```
### Monitor Performance Metrics ### Monitor Performance Metrics
@@ -277,10 +277,10 @@ Key metrics to track:
```bash ```bash
# Node health # Node health
curl http://localhost:9630/ext/health curl http://localhost:9630/v1/health
# Prometheus metrics # Prometheus metrics
curl http://localhost:9630/ext/metrics | grep -E "uptime|stake|validator" curl http://localhost:9630/v1/metrics | grep -E "uptime|stake|validator"
``` ```
Important metrics: Important metrics:
@@ -308,7 +308,7 @@ NODE_URL="http://localhost:9630"
WEBHOOK_URL="your-webhook-url" WEBHOOK_URL="your-webhook-url"
# Check if node is responsive # Check if node is responsive
if ! curl -s "$NODE_URL/ext/health" > /dev/null; then if ! curl -s "$NODE_URL/v1/health" > /dev/null; then
curl -X POST "$WEBHOOK_URL" -d '{"text":"ALERT: Node is not responding!"}' curl -X POST "$WEBHOOK_URL" -d '{"text":"ALERT: Node is not responding!"}'
fi fi
@@ -318,7 +318,7 @@ UPTIME=$(curl -s -X POST --data '{
"method":"platform.getValidator", "method":"platform.getValidator",
"params":{"nodeID":"NodeID-xxx"}, "params":{"nodeID":"NodeID-xxx"},
"id":1 "id":1
}' "$NODE_URL/ext/bc/P" | jq -r '.result.uptime') }' "$NODE_URL/v1/bc/P" | jq -r '.result.uptime')
if [ "$UPTIME" -lt "80" ]; then if [ "$UPTIME" -lt "80" ]; then
curl -X POST "$WEBHOOK_URL" -d "{\"text\":\"WARNING: Uptime is $UPTIME%\"}" curl -X POST "$WEBHOOK_URL" -d "{\"text\":\"WARNING: Uptime is $UPTIME%\"}"
@@ -349,7 +349,7 @@ curl -X POST --data '{
"nodeID": "NodeID-5KqnQfaFQxY9rsFBAa68377qWSherYLQ7" "nodeID": "NodeID-5KqnQfaFQxY9rsFBAa68377qWSherYLQ7"
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/P }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/P
``` ```
## Chain Validation ## Chain Validation
@@ -373,7 +373,7 @@ curl -X POST --data '{
"weight": 1000 "weight": 1000
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/P }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/P
``` ```
### Chain Requirements ### Chain Requirements
+7 -7
View File
@@ -104,14 +104,14 @@ curl -X POST --data '{
"jsonrpc":"2.0", "jsonrpc":"2.0",
"id": 1, "id": 1,
"method": "info.getNetworkInfo" "method": "info.getNetworkInfo"
}' -H 'content-type:application/json;' http://localhost:9650/ext/info }' -H 'content-type:application/json;' http://localhost:9650/v1/info
# Get node ID # Get node ID
curl -X POST --data '{ curl -X POST --data '{
"jsonrpc":"2.0", "jsonrpc":"2.0",
"id": 1, "id": 1,
"method": "info.getNodeID" "method": "info.getNodeID"
}' -H 'content-type:application/json;' http://localhost:9650/ext/info }' -H 'content-type:application/json;' http://localhost:9650/v1/info
``` ```
## Chain Management ## Chain Management
@@ -130,7 +130,7 @@ curl -X POST --data '{
"genesisData": "...", "genesisData": "...",
"netID": "network-id" "netID": "network-id"
} }
}' -H 'content-type:application/json;' http://localhost:9650/ext/P }' -H 'content-type:application/json;' http://localhost:9650/v1/P
``` ```
### Validator Management ### Validator Management
@@ -147,7 +147,7 @@ curl -X POST --data '{
"endTime": ..., "endTime": ...,
"stakeAmount": ... "stakeAmount": ...
} }
}' -H 'content-type:application/json;' http://localhost:9650/ext/P }' -H 'content-type:application/json;' http://localhost:9650/v1/P
``` ```
## Configuration Reference ## Configuration Reference
@@ -175,10 +175,10 @@ curl -X POST --data '{
```bash ```bash
# Prometheus metrics endpoint # Prometheus metrics endpoint
curl http://localhost:9650/ext/metrics curl http://localhost:9650/v1/metrics
# Health check # Health check
curl http://localhost:9650/ext/health curl http://localhost:9650/v1/health
``` ```
### Logs ### Logs
@@ -193,7 +193,7 @@ curl -X POST --data '{
"id": 1, "id": 1,
"method": "admin.setLogLevel", "method": "admin.setLogLevel",
"params": {"logLevel": "debug"} "params": {"logLevel": "debug"}
}' http://localhost:9650/ext/admin }' http://localhost:9650/v1/admin
``` ```
## Testing ## Testing
@@ -595,10 +595,10 @@ curl -X POST --data '{
"jsonrpc":"2.0", "jsonrpc":"2.0",
"method":"info.peers", "method":"info.peers",
"id":1 "id":1
}' http://localhost:9630/ext/info }' http://localhost:9630/v1/info
# Check network metrics # Check network metrics
curl http://localhost:9630/ext/metrics | grep network curl http://localhost:9630/v1/metrics | grep network
# Monitor connections # Monitor connections
netstat -an | grep 9631 netstat -an | grep 9631
+9 -9
View File
@@ -39,7 +39,7 @@ scrape_configs:
- job_name: 'lux-node' - job_name: 'lux-node'
static_configs: static_configs:
- targets: ['localhost:9630'] - targets: ['localhost:9630']
metrics_path: '/ext/metrics' metrics_path: '/v1/metrics'
- job_name: 'node-exporter' - job_name: 'node-exporter'
static_configs: static_configs:
@@ -56,7 +56,7 @@ alerting:
### Available Metrics ### Available Metrics
The Lux node exposes 400+ Prometheus metrics at `http://localhost:9630/ext/metrics`. The Lux node exposes 400+ Prometheus metrics at `http://localhost:9630/v1/metrics`.
#### Key Metric Categories #### Key Metric Categories
@@ -419,11 +419,11 @@ groups:
```bash ```bash
# Basic health check # Basic health check
curl http://localhost:9630/ext/health curl http://localhost:9630/v1/health
# Detailed health with readiness/liveness # Detailed health with readiness/liveness
curl http://localhost:9630/ext/health/readiness curl http://localhost:9630/v1/health/readiness
curl http://localhost:9630/ext/health/liveness curl http://localhost:9630/v1/health/liveness
``` ```
### Custom Health Script ### Custom Health Script
@@ -443,7 +443,7 @@ send_alert() {
} }
# Check if node is responsive # Check if node is responsive
if ! curl -s "$NODE_URL/ext/health" > /dev/null; then if ! curl -s "$NODE_URL/v1/health" > /dev/null; then
send_alert "Node is not responding!" send_alert "Node is not responding!"
exit 1 exit 1
fi fi
@@ -455,7 +455,7 @@ for CHAIN in P X C Q; do
\"method\": \"info.isBootstrapped\", \"method\": \"info.isBootstrapped\",
\"params\": {\"chain\": \"$CHAIN\"}, \"params\": {\"chain\": \"$CHAIN\"},
\"id\": 1 \"id\": 1
}" -H 'content-type:application/json;' $NODE_URL/ext/info | jq -r '.result.isBootstrapped') }" -H 'content-type:application/json;' $NODE_URL/v1/info | jq -r '.result.isBootstrapped')
if [ "$STATUS" != "true" ]; then if [ "$STATUS" != "true" ]; then
send_alert "$CHAIN-Chain is not bootstrapped!" send_alert "$CHAIN-Chain is not bootstrapped!"
@@ -468,7 +468,7 @@ PEERS=$(curl -s -X POST --data '{
"method": "info.peers", "method": "info.peers",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' $NODE_URL/ext/info | jq -r '.result.numPeers') }' -H 'content-type:application/json;' $NODE_URL/v1/info | jq -r '.result.numPeers')
if [ "$PEERS" -lt 4 ]; then if [ "$PEERS" -lt 4 ]; then
send_alert "Low peer count: $PEERS" send_alert "Low peer count: $PEERS"
@@ -619,7 +619,7 @@ Create runbooks for common issues:
```bash ```bash
# Real-time metrics # Real-time metrics
watch -n 1 'curl -s http://localhost:9630/ext/metrics | grep -E "chain_height|network_peers"' watch -n 1 'curl -s http://localhost:9630/v1/metrics | grep -E "chain_height|network_peers"'
# Log streaming # Log streaming
tail -f ~/.luxd/logs/*.log | grep --line-buffered ERROR tail -f ~/.luxd/logs/*.log | grep --line-buffered ERROR
@@ -26,7 +26,7 @@ else
fi fi
# Check API responsiveness # Check API responsiveness
if curl -s http://localhost:9630/ext/health > /dev/null 2>&1; then if curl -s http://localhost:9630/v1/health > /dev/null 2>&1; then
echo "✅ API is responsive" echo "✅ API is responsive"
else else
echo "❌ API is NOT responsive" echo "❌ API is NOT responsive"
@@ -53,7 +53,7 @@ PEERS=$(curl -s -X POST --data '{
"jsonrpc":"2.0", "jsonrpc":"2.0",
"method":"info.peers", "method":"info.peers",
"id":1 "id":1
}' -H 'content-type:application/json;' http://localhost:9630/ext/info 2>/dev/null | jq -r '.result.numPeers') }' -H 'content-type:application/json;' http://localhost:9630/v1/info 2>/dev/null | jq -r '.result.numPeers')
if [ -n "$PEERS" ] && [ "$PEERS" -gt 0 ]; then if [ -n "$PEERS" ] && [ "$PEERS" -gt 0 ]; then
echo "✅ Connected peers: $PEERS" echo "✅ Connected peers: $PEERS"
@@ -225,7 +225,7 @@ curl -X POST --data '{
"method":"platform.getCurrentValidators", "method":"platform.getCurrentValidators",
"params":{"nodeIDs":["<your-node-id>"]}, "params":{"nodeIDs":["<your-node-id>"]},
"id":1 "id":1
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/P }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/P
# Verify staking transaction # Verify staking transaction
curl -X POST --data '{ curl -X POST --data '{
@@ -233,7 +233,7 @@ curl -X POST --data '{
"method":"platform.getTx", "method":"platform.getTx",
"params":{"txID":"<staking-tx-id>"}, "params":{"txID":"<staking-tx-id>"},
"id":1 "id":1
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/P }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/P
``` ```
#### Issue: Low uptime percentage #### Issue: Low uptime percentage
@@ -275,7 +275,7 @@ curl -X POST --data '{
"jsonrpc":"2.0", "jsonrpc":"2.0",
"method":"platform.getHeight", "method":"platform.getHeight",
"id":1 "id":1
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/P }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/P
# Reduce consensus participation # Reduce consensus participation
./build/node --consensus-gossip-concurrent=2 ./build/node --consensus-gossip-concurrent=2
@@ -334,7 +334,7 @@ grep "api" ~/.luxd/configs/node-config.json
./build/node --http-host=0.0.0.0 ./build/node --http-host=0.0.0.0
# Check for rate limiting # Check for rate limiting
curl -I http://localhost:9630/ext/info curl -I http://localhost:9630/v1/info
``` ```
### Staking Issues ### Staking Issues
@@ -369,7 +369,7 @@ curl -X POST --data '{
"method":"platform.getBalance", "method":"platform.getBalance",
"params":{"addresses":["P-lux1..."]}, "params":{"addresses":["P-lux1..."]},
"id":1 "id":1
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/P }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/P
# Import funds from X-Chain # Import funds from X-Chain
curl -X POST --data '{ curl -X POST --data '{
@@ -381,7 +381,7 @@ curl -X POST --data '{
"sourceChain":"X" "sourceChain":"X"
}, },
"id":1 "id":1
}' -H 'content-type:application/json;' http://localhost:9630/ext/bc/P }' -H 'content-type:application/json;' http://localhost:9630/v1/bc/P
``` ```
## Log Analysis ## Log Analysis
@@ -518,7 +518,7 @@ curl -X POST --data '{
"jsonrpc":"2.0", "jsonrpc":"2.0",
"method":"info.getNodeID", "method":"info.getNodeID",
"id":1 "id":1
}' http://localhost:9630/ext/info }' http://localhost:9630/v1/info
``` ```
### Support Channels ### Support Channels
+1 -1
View File
@@ -70,4 +70,4 @@ esac
echo "" echo ""
echo "Import complete! Verify with:" echo "Import complete! Verify with:"
echo " curl -s -X POST --data '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_blockNumber\",\"params\":[]}' -H 'content-type:application/json' \$RPC_URL/ext/bc/<blockchain-id>/rpc" echo " curl -s -X POST --data '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_blockNumber\",\"params\":[]}' -H 'content-type:application/json' \$RPC_URL/v1/bc/<blockchain-id>/rpc"
+2 -2
View File
@@ -21,8 +21,8 @@ type Client struct {
// calls. // calls.
// [uri] is the path to make API calls to. // [uri] is the path to make API calls to.
// For example: // For example:
// - http://1.2.3.4:9650/ext/index/C/block // - http://1.2.3.4:9650/v1/index/C/block
// - http://1.2.3.4:9650/ext/index/X/tx // - http://1.2.3.4:9650/v1/index/X/tx
func NewClient(uri string) *Client { func NewClient(uri string) *Client {
return &Client{ return &Client{
Requester: rpc.NewEndpointRequester(uri), Requester: rpc.NewEndpointRequester(uri),
+1 -1
View File
@@ -20,7 +20,7 @@ import (
// and prints the ID of the block and its transactions. // and prints the ID of the block and its transactions.
func main() { func main() {
var ( var (
uri = primary.LocalAPIURI + "/ext/index/P/block" uri = primary.LocalAPIURI + "/v1/index/P/block"
client = indexer.NewClient(uri) client = indexer.NewClient(uri)
ctx = context.Background() ctx = context.Background()
nextIndex uint64 nextIndex uint64
+1 -1
View File
@@ -19,7 +19,7 @@ import (
// and prints the ID of the block and its transactions. // and prints the ID of the block and its transactions.
func main() { func main() {
var ( var (
uri = primary.LocalAPIURI + "/ext/index/X/block" uri = primary.LocalAPIURI + "/v1/index/X/block"
xChainID = ids.FromStringOrPanic("2eNy1mUFdmaxXNj1eQHUe7Np4gju9sJsEtWQ4MX3ToiNKuADed") xChainID = ids.FromStringOrPanic("2eNy1mUFdmaxXNj1eQHUe7Np4gju9sJsEtWQ4MX3ToiNKuADed")
client = indexer.NewClient(uri) client = indexer.NewClient(uri)
ctx = context.Background() ctx = context.Background()
+13 -13
View File
@@ -25,29 +25,29 @@ Each chain has one or more index. To see if a C-Chain block is accepted, for exa
### C-Chain Blocks ### C-Chain Blocks
``` ```
/ext/index/C/block /v1/index/C/block
``` ```
### P-Chain Blocks ### P-Chain Blocks
``` ```
/ext/index/P/block /v1/index/P/block
``` ```
### X-Chain Transactions ### X-Chain Transactions
``` ```
/ext/index/X/tx /v1/index/X/tx
``` ```
### X-Chain Blocks ### X-Chain Blocks
``` ```
/ext/index/X/block /v1/index/X/block
``` ```
<Callout type="warn"> <Callout type="warn">
To ensure historical data can be accessed, the `/ext/index/X/vtx` is still accessible, even though it is no longer populated with chain data since the X-Chain block linearization landed. If you are using `V1.10.0` or higher, you need to migrate to using the `/ext/index/X/block` endpoint. To ensure historical data can be accessed, the `/v1/index/X/vtx` is still accessible, even though it is no longer populated with chain data since the X-Chain block linearization landed. If you are using `V1.10.0` or higher, you need to migrate to using the `/v1/index/X/block` endpoint.
</Callout> </Callout>
## Methods ## Methods
@@ -87,7 +87,7 @@ index.getContainerByID({
**Example Call**: **Example Call**:
```sh ```sh
curl --location --request POST 'localhost:9630/ext/index/X/tx' \ curl --location --request POST 'localhost:9630/v1/index/X/tx' \
--header 'Content-Type: application/json' \ --header 'Content-Type: application/json' \
--data-raw '{ --data-raw '{
"jsonrpc": "2.0", "jsonrpc": "2.0",
@@ -151,7 +151,7 @@ index.getContainerByIndex({
**Example Call**: **Example Call**:
```sh ```sh
curl --location --request POST 'localhost:9630/ext/index/X/tx' \ curl --location --request POST 'localhost:9630/v1/index/X/tx' \
--header 'Content-Type: application/json' \ --header 'Content-Type: application/json' \
--data-raw '{ --data-raw '{
"jsonrpc": "2.0", "jsonrpc": "2.0",
@@ -223,7 +223,7 @@ index.getContainerRange({
**Example Call**: **Example Call**:
```sh ```sh
curl --location --request POST 'localhost:9630/ext/index/X/tx' \ curl --location --request POST 'localhost:9630/v1/index/X/tx' \
--header 'Content-Type: application/json' \ --header 'Content-Type: application/json' \
--data-raw '{ --data-raw '{
"jsonrpc": "2.0", "jsonrpc": "2.0",
@@ -282,7 +282,7 @@ index.getIndex({
**Example Call**: **Example Call**:
```sh ```sh
curl --location --request POST 'localhost:9630/ext/index/X/tx' \ curl --location --request POST 'localhost:9630/v1/index/X/tx' \
--header 'Content-Type: application/json' \ --header 'Content-Type: application/json' \
--data-raw '{ --data-raw '{
"jsonrpc": "2.0", "jsonrpc": "2.0",
@@ -339,7 +339,7 @@ index.getLastAccepted({
**Example Call**: **Example Call**:
```sh ```sh
curl --location --request POST 'localhost:9630/ext/index/X/tx' \ curl --location --request POST 'localhost:9630/v1/index/X/tx' \
--header 'Content-Type: application/json' \ --header 'Content-Type: application/json' \
--data-raw '{ --data-raw '{
"jsonrpc": "2.0", "jsonrpc": "2.0",
@@ -394,7 +394,7 @@ index.isAccepted({
**Example Call**: **Example Call**:
```sh ```sh
curl --location --request POST 'localhost:9630/ext/index/X/tx' \ curl --location --request POST 'localhost:9630/v1/index/X/tx' \
--header 'Content-Type: application/json' \ --header 'Content-Type: application/json' \
--data-raw '{ --data-raw '{
"jsonrpc": "2.0", "jsonrpc": "2.0",
@@ -430,7 +430,7 @@ To get an X-Chain transaction by its index (the order it was accepted in), use I
For example, to get the second transaction (note that `"index":1`) accepted on the X-Chain, do: For example, to get the second transaction (note that `"index":1`) accepted on the X-Chain, do:
```sh ```sh
curl --location --request POST 'https://indexer-demo.lux.network/ext/index/X/tx' \ curl --location --request POST 'https://indexer-demo.lux.network/v1/index/X/tx' \
--header 'Content-Type: application/json' \ --header 'Content-Type: application/json' \
--data-raw '{ --data-raw '{
"jsonrpc": "2.0", "jsonrpc": "2.0",
@@ -474,7 +474,7 @@ curl -X POST --data '{
"txID":"ZGYTSU8w3zUP6VFseGC798vA2Vnxnfj6fz1QPfA9N93bhjJvo", "txID":"ZGYTSU8w3zUP6VFseGC798vA2Vnxnfj6fz1QPfA9N93bhjJvo",
"encoding": "json" "encoding": "json"
} }
}' -H 'content-type:application/json;' https://api.lux.network/ext/bc/X }' -H 'content-type:application/json;' https://api.lux.network/v1/bc/X
``` ```
**Response**: **Response**:
+3 -3
View File
@@ -79,7 +79,7 @@ spec:
cpu: "4" cpu: "4"
livenessProbe: livenessProbe:
httpGet: httpGet:
path: /ext/health path: /v1/health
port: 9630 port: 9630
initialDelaySeconds: 120 initialDelaySeconds: 120
periodSeconds: 30 periodSeconds: 30
@@ -87,7 +87,7 @@ spec:
timeoutSeconds: 10 timeoutSeconds: 10
readinessProbe: readinessProbe:
httpGet: httpGet:
path: /ext/health path: /v1/health
port: 9630 port: 9630
initialDelaySeconds: 30 initialDelaySeconds: 30
periodSeconds: 10 periodSeconds: 10
@@ -95,7 +95,7 @@ spec:
timeoutSeconds: 5 timeoutSeconds: 5
startupProbe: startupProbe:
httpGet: httpGet:
path: /ext/health path: /v1/health
port: 9630 port: 9630
initialDelaySeconds: 10 initialDelaySeconds: 10
periodSeconds: 10 periodSeconds: 10
+5 -5
View File
@@ -1825,18 +1825,18 @@ func (n *Node) initInfoAPI() error {
// initSecurityAPI exposes the chain-wide ChainSecurityProfile as a // initSecurityAPI exposes the chain-wide ChainSecurityProfile as a
// read-only API surface. Three endpoints share one handler: // read-only API surface. Three endpoints share one handler:
// //
// - JSON-RPC: POST /ext/security with methods securityProfile and // - JSON-RPC: POST /v1/security with methods securityProfile and
// blockSecurity (dispatched on the wire as security_securityProfile // blockSecurity (dispatched on the wire as security_securityProfile
// / security_blockSecurity per gorilla/rpc namespace convention) // / security_blockSecurity per gorilla/rpc namespace convention)
// - REST: GET /ext/security/profile // - REST: GET /v1/security/profile
// - REST: GET /ext/security/block/{n} // - REST: GET /v1/security/block/{n}
// //
// All three share the same Service receiver; the shape returned is // All three share the same Service receiver; the shape returned is
// the SCREAMING_SNAKE canonical profile JSON consumed by audit tooling, // the SCREAMING_SNAKE canonical profile JSON consumed by audit tooling,
// wallet posture banners, and block explorers. // wallet posture banners, and block explorers.
// //
// Prometheus gauges for the active profile are stamped onto the // Prometheus gauges for the active profile are stamped onto the
// node-wide metrics gatherer here so /ext/metrics carries the profile // node-wide metrics gatherer here so /v1/metrics carries the profile
// posture immediately after boot. // posture immediately after boot.
// //
// Closes F102 follow-ups (securityProfile RPC + profile metrics). // Closes F102 follow-ups (securityProfile RPC + profile metrics).
@@ -1844,7 +1844,7 @@ func (n *Node) initSecurityAPI() error {
n.Log.Info("initializing security API") n.Log.Info("initializing security API")
// Register profile metrics under the "security" namespace on the // Register profile metrics under the "security" namespace on the
// node-wide gatherer so /ext/metrics carries them alongside the // node-wide gatherer so /v1/metrics carries them alongside the
// existing process / api / chain metric families. // existing process / api / chain metric families.
securityMetricsReg, err := metric.MakeAndRegister( securityMetricsReg, err := metric.MakeAndRegister(
n.MetricsGatherer, n.MetricsGatherer,
+5 -5
View File
@@ -72,7 +72,7 @@ echo ""
# Wait for RPC to be ready # Wait for RPC to be ready
echo -n "Waiting for RPC..." echo -n "Waiting for RPC..."
for _ in {1..30}; do for _ in {1..30}; do
if curl -s "http://127.0.0.1:$HTTP_PORT/ext/info" >/dev/null 2>&1; then if curl -s "http://127.0.0.1:$HTTP_PORT/v1/info" >/dev/null 2>&1; then
echo " ready!" echo " ready!"
break break
fi fi
@@ -83,10 +83,10 @@ done
# Show status # Show status
echo "" echo ""
echo "=== Instance Ready ===" echo "=== Instance Ready ==="
echo " C-Chain RPC: http://127.0.0.1:$HTTP_PORT/ext/bc/C/rpc" echo " C-Chain RPC: http://127.0.0.1:$HTTP_PORT/v1/bc/C/rpc"
echo " X-Chain RPC: http://127.0.0.1:$HTTP_PORT/ext/bc/X" echo " X-Chain RPC: http://127.0.0.1:$HTTP_PORT/v1/bc/X"
echo " P-Chain RPC: http://127.0.0.1:$HTTP_PORT/ext/bc/P" echo " P-Chain RPC: http://127.0.0.1:$HTTP_PORT/v1/bc/P"
echo " Info API: http://127.0.0.1:$HTTP_PORT/ext/info" echo " Info API: http://127.0.0.1:$HTTP_PORT/v1/info"
echo "" echo ""
echo " Logs: tail -f $LOG_FILE" echo " Logs: tail -f $LOG_FILE"
echo " Stop: kill $(cat "$PID_FILE")" echo " Stop: kill $(cat "$PID_FILE")"
+1 -1
View File
@@ -101,7 +101,7 @@ global:
scrape_configs: scrape_configs:
- job_name: "node" - job_name: "node"
metrics_path: "/ext/metrics" metrics_path: "/v1/metrics"
file_sd_configs: file_sd_configs:
- files: - files:
- '${FILE_SD_PATH}/*.json' - '${FILE_SD_PATH}/*.json'
+11 -11
View File
@@ -147,9 +147,9 @@ func (r *router) handleRootGET(w http.ResponseWriter, _ *http.Request) {
P string `json:"p"` P string `json:"p"`
X string `json:"x"` X string `json:"x"`
}{ }{
C: "/ext/bc/C/rpc", C: baseURL + "/bc/C/rpc",
P: "/ext/bc/P", P: baseURL + "/bc/P",
X: "/ext/bc/X", X: baseURL + "/bc/X",
}, },
Endpoints: struct { Endpoints: struct {
RPC string `json:"rpc"` RPC string `json:"rpc"`
@@ -157,10 +157,10 @@ func (r *router) handleRootGET(w http.ResponseWriter, _ *http.Request) {
Info string `json:"info"` Info string `json:"info"`
Health string `json:"health"` Health string `json:"health"`
}{ }{
RPC: "/ext/bc/C/rpc", RPC: baseURL + "/bc/C/rpc",
Websocket: "/ext/bc/C/ws", Websocket: baseURL + "/bc/C/ws",
Info: "/ext/info", Info: baseURL + "/info",
Health: "/ext/health", Health: baseURL + "/health",
}, },
} }
} }
@@ -173,10 +173,10 @@ func (r *router) handleRootGET(w http.ResponseWriter, _ *http.Request) {
// handleRootPOST proxies JSON-RPC requests to the C-chain // handleRootPOST proxies JSON-RPC requests to the C-chain
func (r *router) handleRootPOST(w http.ResponseWriter, req *http.Request) { func (r *router) handleRootPOST(w http.ResponseWriter, req *http.Request) {
// Look up the C-chain RPC handler // Look up the C-chain RPC handler
handler, err := r.GetHandler("/ext/bc/C", "/rpc") handler, err := r.GetHandler(baseURL+"/bc/C", "/rpc")
if err != nil { if err != nil {
// Try alternate path formats // Try alternate path formats
handler, err = r.GetHandler("/ext/bc/C/rpc", "") handler, err = r.GetHandler(baseURL+"/bc/C/rpc", "")
if err != nil { if err != nil {
// Return proper JSON-RPC error // Return proper JSON-RPC error
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
@@ -198,10 +198,10 @@ func (r *router) SetRootInfoProvider(provider RootInfoProvider) {
} }
// handleHealthz returns a minimal health response for K8s probes. // handleHealthz returns a minimal health response for K8s probes.
// This delegates to the full /ext/health handler when available, // This delegates to the full /v1/health handler when available,
// falling back to a static 200 response during early startup. // falling back to a static 200 response during early startup.
func (r *router) handleHealthz(w http.ResponseWriter, req *http.Request) { func (r *router) handleHealthz(w http.ResponseWriter, req *http.Request) {
if handler, err := r.GetHandler("/ext/health", "/health"); err == nil { if handler, err := r.GetHandler(baseURL+"/health", "/health"); err == nil {
handler.ServeHTTP(w, req) handler.ServeHTTP(w, req)
return return
} }
+7 -2
View File
@@ -25,7 +25,12 @@ import (
) )
const ( const (
baseURL = "/ext" // baseURL is the canonical — and only — prefix for every luxd HTTP route
// (/v1/bc/C/rpc, /v1/info, /v1/health, ...). Single source of truth:
// AddRoute/AddAliases and the root/health helpers in router.go all derive
// their paths from it. The legacy Avalanche-heritage /ext prefix is gone;
// one way, no backward compatibility (activation Dec 25 2025).
baseURL = "/v1"
maxConcurrentStreams = 64 maxConcurrentStreams = 64
) )
@@ -95,7 +100,7 @@ type server struct {
listener net.Listener listener net.Listener
// handler is the fully-wrapped API handler chain (CORS + host-filter + // handler is the fully-wrapped API handler chain (CORS + host-filter +
// /ext/* router). Held here so the optional ZAP-RPC listener serves the // /v1/* router). Held here so the optional ZAP-RPC listener serves the
// exact same handler as the HTTP listener. // exact same handler as the HTTP listener.
handler http.Handler handler http.Handler
+1 -1
View File
@@ -2,7 +2,7 @@
// See the file LICENSE for licensing terms. // See the file LICENSE for licensing terms.
// ZAP-RPC listener — serves the EXACT same fully-wrapped API handler chain // ZAP-RPC listener — serves the EXACT same fully-wrapped API handler chain
// (CORS + host-filter + /ext/* router) as the HTTP listener, but over the // (CORS + host-filter + /v1/* router) as the HTTP listener, but over the
// github.com/zap-proto/http binary protocol. This is what makes luxd a // github.com/zap-proto/http binary protocol. This is what makes luxd a
// first-class citizen of the ZAP service mesh: the api.<brand> gateway can // first-class citizen of the ZAP service mesh: the api.<brand> gateway can
// proxy to luxd over native ZAP instead of HTTP/1.1. // proxy to luxd over native ZAP instead of HTTP/1.1.
+2 -2
View File
@@ -60,7 +60,7 @@ func TestStartZapRPCListener_RoundTrip(t *testing.T) {
const body = `{"jsonrpc":"2.0","result":"0x2a","id":1}` const body = `{"jsonrpc":"2.0","result":"0x2a","id":1}`
mux := http.NewServeMux() mux := http.NewServeMux()
mux.HandleFunc("/ext/bc/C/rpc", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/v1/bc/C/rpc", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
_, _ = io.WriteString(w, body) _, _ = io.WriteString(w, body)
}) })
@@ -75,7 +75,7 @@ func TestStartZapRPCListener_RoundTrip(t *testing.T) {
time.Sleep(150 * time.Millisecond) time.Sleep(150 * time.Millisecond)
client := &http.Client{Transport: zaphttp.NewTransport(addr)} client := &http.Client{Transport: zaphttp.NewTransport(addr)}
resp, err := client.Post("http://"+addr+"/ext/bc/C/rpc", "application/json", nil) resp, err := client.Post("http://"+addr+"/v1/bc/C/rpc", "application/json", nil)
if err != nil { if err != nil {
t.Fatalf("ZAP round-trip POST failed: %v", err) t.Fatalf("ZAP round-trip POST failed: %v", err)
} }
+12 -12
View File
@@ -143,7 +143,7 @@ func TestRevokeToken(t *testing.T) {
auth := NewFromHash(log.NewNoOpLogger(), "auth", hashedPassword).(*auth) auth := NewFromHash(log.NewNoOpLogger(), "auth", hashedPassword).(*auth)
// Make a token // Make a token
endpoints := []string{"/ext/info", "/ext/bc/X", "/ext/metrics"} endpoints := []string{"/v1/info", "/v1/bc/X", "/v1/metrics"}
tokenStr, err := auth.NewToken(testPassword, defaultTokenLifespan, endpoints) tokenStr, err := auth.NewToken(testPassword, defaultTokenLifespan, endpoints)
require.NoError(err) require.NoError(err)
@@ -157,7 +157,7 @@ func TestWrapHandlerHappyPath(t *testing.T) {
auth := NewFromHash(log.NewNoOpLogger(), "auth", hashedPassword) auth := NewFromHash(log.NewNoOpLogger(), "auth", hashedPassword)
// Make a token // Make a token
endpoints := []string{"/ext/info", "/ext/bc/X", "/ext/metrics"} endpoints := []string{"/v1/info", "/v1/bc/X", "/v1/metrics"}
tokenStr, err := auth.NewToken(testPassword, defaultTokenLifespan, endpoints) tokenStr, err := auth.NewToken(testPassword, defaultTokenLifespan, endpoints)
require.NoError(err) require.NoError(err)
@@ -178,7 +178,7 @@ func TestWrapHandlerRevokedToken(t *testing.T) {
auth := NewFromHash(log.NewNoOpLogger(), "auth", hashedPassword) auth := NewFromHash(log.NewNoOpLogger(), "auth", hashedPassword)
// Make a token // Make a token
endpoints := []string{"/ext/info", "/ext/bc/X", "/ext/metrics"} endpoints := []string{"/v1/info", "/v1/bc/X", "/v1/metrics"}
tokenStr, err := auth.NewToken(testPassword, defaultTokenLifespan, endpoints) tokenStr, err := auth.NewToken(testPassword, defaultTokenLifespan, endpoints)
require.NoError(err) require.NoError(err)
@@ -205,7 +205,7 @@ func TestWrapHandlerExpiredToken(t *testing.T) {
auth.clock.Set(time.Now().Add(-2 * defaultTokenLifespan)) auth.clock.Set(time.Now().Add(-2 * defaultTokenLifespan))
// Make a token that expired well in the past // Make a token that expired well in the past
endpoints := []string{"/ext/info", "/ext/bc/X", "/ext/metrics"} endpoints := []string{"/v1/info", "/v1/bc/X", "/v1/metrics"}
tokenStr, err := auth.NewToken(testPassword, defaultTokenLifespan, endpoints) tokenStr, err := auth.NewToken(testPassword, defaultTokenLifespan, endpoints)
require.NoError(err) require.NoError(err)
@@ -227,7 +227,7 @@ func TestWrapHandlerNoAuthToken(t *testing.T) {
auth := NewFromHash(log.NewNoOpLogger(), "auth", hashedPassword) auth := NewFromHash(log.NewNoOpLogger(), "auth", hashedPassword)
endpoints := []string{"/ext/info", "/ext/bc/X", "/ext/metrics"} endpoints := []string{"/v1/info", "/v1/bc/X", "/v1/metrics"}
wrappedHandler := auth.WrapHandler(dummyHandler) wrappedHandler := auth.WrapHandler(dummyHandler)
for _, endpoint := range endpoints { for _, endpoint := range endpoints {
req := httptest.NewRequest(http.MethodPost, fmt.Sprintf("http://127.0.0.1:9630%s", endpoint), strings.NewReader("")) req := httptest.NewRequest(http.MethodPost, fmt.Sprintf("http://127.0.0.1:9630%s", endpoint), strings.NewReader(""))
@@ -245,11 +245,11 @@ func TestWrapHandlerUnauthorizedEndpoint(t *testing.T) {
auth := NewFromHash(log.NewNoOpLogger(), "auth", hashedPassword) auth := NewFromHash(log.NewNoOpLogger(), "auth", hashedPassword)
// Make a token // Make a token
endpoints := []string{"/ext/info"} endpoints := []string{"/v1/info"}
tokenStr, err := auth.NewToken(testPassword, defaultTokenLifespan, endpoints) tokenStr, err := auth.NewToken(testPassword, defaultTokenLifespan, endpoints)
require.NoError(err) require.NoError(err)
unauthorizedEndpoints := []string{"/ext/bc/X", "/ext/metrics", "", "/foo", "/ext/info/foo"} unauthorizedEndpoints := []string{"/v1/bc/X", "/v1/metrics", "", "/foo", "/v1/info/foo"}
wrappedHandler := auth.WrapHandler(dummyHandler) wrappedHandler := auth.WrapHandler(dummyHandler)
for _, endpoint := range unauthorizedEndpoints { for _, endpoint := range unauthorizedEndpoints {
@@ -269,12 +269,12 @@ func TestWrapHandlerAuthEndpoint(t *testing.T) {
auth := NewFromHash(log.NewNoOpLogger(), "auth", hashedPassword) auth := NewFromHash(log.NewNoOpLogger(), "auth", hashedPassword)
// Make a token // Make a token
endpoints := []string{"/ext/info", "/ext/bc/X", "/ext/metrics", "", "/foo", "/ext/info/foo"} endpoints := []string{"/v1/info", "/v1/bc/X", "/v1/metrics", "", "/foo", "/v1/info/foo"}
tokenStr, err := auth.NewToken(testPassword, defaultTokenLifespan, endpoints) tokenStr, err := auth.NewToken(testPassword, defaultTokenLifespan, endpoints)
require.NoError(err) require.NoError(err)
wrappedHandler := auth.WrapHandler(dummyHandler) wrappedHandler := auth.WrapHandler(dummyHandler)
req := httptest.NewRequest(http.MethodPost, "http://127.0.0.1:9630/ext/auth", strings.NewReader("")) req := httptest.NewRequest(http.MethodPost, "http://127.0.0.1:9630/v1/auth", strings.NewReader(""))
req.Header.Add("Authorization", headerValStart+tokenStr) req.Header.Add("Authorization", headerValStart+tokenStr)
rr := httptest.NewRecorder() rr := httptest.NewRecorder()
wrappedHandler.ServeHTTP(rr, req) wrappedHandler.ServeHTTP(rr, req)
@@ -287,7 +287,7 @@ func TestWrapHandlerAccessAll(t *testing.T) {
auth := NewFromHash(log.NewNoOpLogger(), "auth", hashedPassword) auth := NewFromHash(log.NewNoOpLogger(), "auth", hashedPassword)
// Make a token that allows access to all endpoints // Make a token that allows access to all endpoints
endpoints := []string{"/ext/info", "/ext/bc/X", "/ext/metrics", "", "/foo", "/ext/foo/info"} endpoints := []string{"/v1/info", "/v1/bc/X", "/v1/metrics", "", "/foo", "/v1/foo/info"}
tokenStr, err := auth.NewToken(testPassword, defaultTokenLifespan, []string{"*"}) tokenStr, err := auth.NewToken(testPassword, defaultTokenLifespan, []string{"*"})
require.NoError(err) require.NoError(err)
@@ -316,7 +316,7 @@ func TestWrapHandlerMutatedRevokedToken(t *testing.T) {
auth := NewFromHash(log.NewNoOpLogger(), "auth", hashedPassword) auth := NewFromHash(log.NewNoOpLogger(), "auth", hashedPassword)
// Make a token // Make a token
endpoints := []string{"/ext/info", "/ext/bc/X", "/ext/metrics"} endpoints := []string{"/v1/info", "/v1/bc/X", "/v1/metrics"}
tokenStr, err := auth.NewToken(testPassword, defaultTokenLifespan, endpoints) tokenStr, err := auth.NewToken(testPassword, defaultTokenLifespan, endpoints)
require.NoError(err) require.NoError(err)
@@ -339,7 +339,7 @@ func TestWrapHandlerInvalidSigningMethod(t *testing.T) {
auth := NewFromHash(log.NewNoOpLogger(), "auth", hashedPassword).(*auth) auth := NewFromHash(log.NewNoOpLogger(), "auth", hashedPassword).(*auth)
// Make a token // Make a token
endpoints := []string{"/ext/info", "/ext/bc/X", "/ext/metrics"} endpoints := []string{"/v1/info", "/v1/bc/X", "/v1/metrics"}
idBytes := [tokenIDByteLen]byte{} idBytes := [tokenIDByteLen]byte{}
_, err := rand.Read(idBytes[:]) _, err := rand.Read(idBytes[:])
require.NoError(err) require.NoError(err)
+1 -1
View File
@@ -22,7 +22,7 @@ type Password struct {
type NewTokenArgs struct { type NewTokenArgs struct {
Password Password
// Endpoints that may be accessed with this token e.g. if endpoints is // Endpoints that may be accessed with this token e.g. if endpoints is
// ["/ext/bc/X", "/ext/admin"] then the token holder can hit the X-Chain API // ["/v1/bc/X", "/v1/admin"] then the token holder can hit the X-Chain API
// and the admin API. If [Endpoints] contains an element "*" then the token // and the admin API. If [Endpoints] contains an element "*" then the token
// allows access to all API endpoints. [Endpoints] must have between 1 and // allows access to all API endpoints. [Endpoints] must have between 1 and
// [maxEndpoints] elements // [maxEndpoints] elements
+9 -9
View File
@@ -23,7 +23,7 @@ To get an HTTP status code response that indicates the node's health, make a `GE
To filter GET health checks, add a `tag` query parameter to the request. The `tag` parameter is a string. For example, to filter health results by netID `29uVeLPJB1eQJkzRemU8g8wZDw5uJRqpab5U2mX9euieVwiEbL`, use the following query: To filter GET health checks, add a `tag` query parameter to the request. The `tag` parameter is a string. For example, to filter health results by netID `29uVeLPJB1eQJkzRemU8g8wZDw5uJRqpab5U2mX9euieVwiEbL`, use the following query:
```sh ```sh
curl 'http://localhost:9630/ext/health?tag=29uVeLPJB1eQJkzRemU8g8wZDw5uJRqpab5U2mX9euieVwiEbL' curl 'http://localhost:9630/v1/health?tag=29uVeLPJB1eQJkzRemU8g8wZDw5uJRqpab5U2mX9euieVwiEbL'
``` ```
In this example returned results will contain global health checks and health checks that are related to netID `29uVeLPJB1eQJkzRemU8g8wZDw5uJRqpab5U2mX9euieVwiEbL`. In this example returned results will contain global health checks and health checks that are related to netID `29uVeLPJB1eQJkzRemU8g8wZDw5uJRqpab5U2mX9euieVwiEbL`.
@@ -33,7 +33,7 @@ In this example returned results will contain global health checks and health ch
In order to filter results by multiple tags, use multiple `tag` query parameters. For example, to filter health results by netID `29uVeLPJB1eQJkzRemU8g8wZDw5uJRqpab5U2mX9euieVwiEbL` and `28nrH5T2BMvNrWecFcV3mfccjs6axM1TVyqe79MCv2Mhs8kxiY` use the following query: In order to filter results by multiple tags, use multiple `tag` query parameters. For example, to filter health results by netID `29uVeLPJB1eQJkzRemU8g8wZDw5uJRqpab5U2mX9euieVwiEbL` and `28nrH5T2BMvNrWecFcV3mfccjs6axM1TVyqe79MCv2Mhs8kxiY` use the following query:
```sh ```sh
curl 'http://localhost:9630/ext/health?tag=29uVeLPJB1eQJkzRemU8g8wZDw5uJRqpab5U2mX9euieVwiEbL&tag=28nrH5T2BMvNrWecFcV3mfccjs6axM1TVyqe79MCv2Mhs8kxiY' curl 'http://localhost:9630/v1/health?tag=29uVeLPJB1eQJkzRemU8g8wZDw5uJRqpab5U2mX9euieVwiEbL&tag=28nrH5T2BMvNrWecFcV3mfccjs6axM1TVyqe79MCv2Mhs8kxiY'
``` ```
The returned results will include health checks for both netIDs as well as global health checks. The returned results will include health checks for both netIDs as well as global health checks.
@@ -42,10 +42,10 @@ The returned results will include health checks for both netIDs as well as globa
The available endpoints for GET requests are: The available endpoints for GET requests are:
- `/ext/health` returns a holistic report of the status of the node. **Most operators should monitor this status.** - `/v1/health` returns a holistic report of the status of the node. **Most operators should monitor this status.**
- `/ext/health/health` is the same as `/ext/health`. - `/v1/health/health` is the same as `/v1/health`.
- `/ext/health/readiness` returns healthy once the node has finished initializing. - `/v1/health/readiness` returns healthy once the node has finished initializing.
- `/ext/health/liveness` returns healthy once the endpoint is available. - `/v1/health/liveness` returns healthy once the endpoint is available.
## JSON RPC Request ## JSON RPC Request
@@ -71,7 +71,7 @@ curl -H 'Content-Type: application/json' --data '{
"params": { "params": {
"tags": ["11111111111111111111111111111111LpoYY", "29uVeLPJB1eQJkzRemU8g8wZDw5uJRqpab5U2mX9euieVwiEbL"] "tags": ["11111111111111111111111111111111LpoYY", "29uVeLPJB1eQJkzRemU8g8wZDw5uJRqpab5U2mX9euieVwiEbL"]
} }
}' 'http://localhost:9630/ext/health' }' 'http://localhost:9630/v1/health'
``` ```
**Example Response**: **Example Response**:
@@ -203,7 +203,7 @@ curl -H 'Content-Type: application/json' --data '{
"params": { "params": {
"tags": ["11111111111111111111111111111111LpoYY", "29uVeLPJB1eQJkzRemU8g8wZDw5uJRqpab5U2mX9euieVwiEbL"] "tags": ["11111111111111111111111111111111LpoYY", "29uVeLPJB1eQJkzRemU8g8wZDw5uJRqpab5U2mX9euieVwiEbL"]
} }
}' 'http://localhost:9630/ext/health' }' 'http://localhost:9630/v1/health'
``` ```
**Example Response**: **Example Response**:
@@ -249,7 +249,7 @@ curl -H 'Content-Type: application/json' --data '{
"jsonrpc":"2.0", "jsonrpc":"2.0",
"id" :1, "id" :1,
"method" :"health.liveness" "method" :"health.liveness"
}' 'http://localhost:9630/ext/health' }' 'http://localhost:9630/v1/health'
``` ```
**Example Response**: **Example Response**:
+15 -15
View File
@@ -7,7 +7,7 @@ This API uses the `json 2.0` RPC format. For more information on making JSON RPC
## Endpoint ## Endpoint
``` ```
/ext/info /v1/info
``` ```
## Methods ## Methods
@@ -38,7 +38,7 @@ curl -sX POST --data '{
"id" :1, "id" :1,
"method" :"info.lps", "method" :"info.lps",
"params" :{} "params" :{}
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/info }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/info
``` ```
**Example Response**: **Example Response**:
@@ -125,7 +125,7 @@ curl -X POST --data '{
"params": { "params": {
"chain":"X" "chain":"X"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/info }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/info
``` ```
**Example Response**: **Example Response**:
@@ -160,7 +160,7 @@ curl -X POST --data '{
"params": { "params": {
"alias":"X" "alias":"X"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/info }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/info
``` ```
**Example Response**: **Example Response**:
@@ -192,7 +192,7 @@ curl -X POST --data '{
"jsonrpc":"2.0", "jsonrpc":"2.0",
"id" :1, "id" :1,
"method" :"info.getNetworkID" "method" :"info.getNetworkID"
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/info }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/info
``` ```
**Example Response**: **Example Response**:
@@ -226,7 +226,7 @@ curl -X POST --data '{
"jsonrpc":"2.0", "jsonrpc":"2.0",
"id" :1, "id" :1,
"method" :"info.getNetworkName" "method" :"info.getNetworkName"
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/info }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/info
``` ```
**Example Response**: **Example Response**:
@@ -273,7 +273,7 @@ curl -X POST --data '{
"jsonrpc":"2.0", "jsonrpc":"2.0",
"id" :1, "id" :1,
"method" :"info.getNodeID" "method" :"info.getNodeID"
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/info }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/info
``` ```
**Example Response**: **Example Response**:
@@ -313,7 +313,7 @@ curl -X POST --data '{
"jsonrpc":"2.0", "jsonrpc":"2.0",
"id" :1, "id" :1,
"method" :"info.getNodeIP" "method" :"info.getNodeIP"
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/info }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/info
``` ```
**Example Response**: **Example Response**:
@@ -359,7 +359,7 @@ curl -X POST --data '{
"jsonrpc":"2.0", "jsonrpc":"2.0",
"id" :1, "id" :1,
"method" :"info.getNodeVersion" "method" :"info.getNodeVersion"
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/info }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/info
``` ```
**Example Response**: **Example Response**:
@@ -426,7 +426,7 @@ curl -X POST --data '{
"jsonrpc":"2.0", "jsonrpc":"2.0",
"id" :1, "id" :1,
"method" :"info.getTxFee" "method" :"info.getTxFee"
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/info }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/info
``` ```
**Example Response**: **Example Response**:
@@ -473,7 +473,7 @@ curl -X POST --data '{
"id" :1, "id" :1,
"method" :"info.getVMs", "method" :"info.getVMs",
"params" :{} "params" :{}
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/info }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/info
``` ```
**Example Response**: **Example Response**:
@@ -540,7 +540,7 @@ curl -X POST --data '{
"params": { "params": {
"nodeIDs": [] "nodeIDs": []
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/info }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/info
``` ```
**Example Response**: **Example Response**:
@@ -619,7 +619,7 @@ curl -X POST --data '{
"jsonrpc":"2.0", "jsonrpc":"2.0",
"id" :1, "id" :1,
"method" :"info.uptime" "method" :"info.uptime"
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/info }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/info
``` ```
**Example Response**: **Example Response**:
@@ -645,7 +645,7 @@ curl -X POST --data '{
"params" :{ "params" :{
"netID":"29uVeLPJB1eQJkzRemU8g8wZDw5uJRqpab5U2mX9euieVwiEbL" "netID":"29uVeLPJB1eQJkzRemU8g8wZDw5uJRqpab5U2mX9euieVwiEbL"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/info }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/info
``` ```
#### Example Lux L1 Response #### Example Lux L1 Response
@@ -672,7 +672,7 @@ curl -X POST --data '{
"jsonrpc":"2.0", "jsonrpc":"2.0",
"id" :1, "id" :1,
"method" :"info.upgrades" "method" :"info.upgrades"
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/info }' -H 'content-type:application/json;' 127.0.0.1:9650/v1/info
``` ```
**Example Response**: **Example Response**:
+4 -4
View File
@@ -64,7 +64,7 @@ func TestGetNodeVersionConsensusRoundtrip(t *testing.T) {
log: log.NewNoOpLogger(), log: log.NewNoOpLogger(),
} }
req := httptest.NewRequest("POST", "/ext/info", nil) req := httptest.NewRequest("POST", "/v1/info", nil)
reply := apiinfo.GetNodeVersionReply{} reply := apiinfo.GetNodeVersionReply{}
require.NoError(info.GetNodeVersion(req, nil, &reply)) require.NoError(info.GetNodeVersion(req, nil, &reply))
require.NotNil(reply.Consensus) require.NotNil(reply.Consensus)
@@ -114,7 +114,7 @@ func TestGetVMsSuccess(t *testing.T) {
id2: []string{alias2}, id2: []string{alias2},
} }
req := httptest.NewRequest("POST", "/ext/info", nil) req := httptest.NewRequest("POST", "/v1/info", nil)
resources.mockVMManager.EXPECT().ListFactories(req.Context()).Times(1).Return(vmIDs, nil) resources.mockVMManager.EXPECT().ListFactories(req.Context()).Times(1).Return(vmIDs, nil)
resources.mockVMManager.EXPECT().PrimaryAlias(req.Context(), id1).Times(1).Return(alias1, nil) resources.mockVMManager.EXPECT().PrimaryAlias(req.Context(), id1).Times(1).Return(alias1, nil)
resources.mockVMManager.EXPECT().PrimaryAlias(req.Context(), id2).Times(1).Return(alias2, nil) resources.mockVMManager.EXPECT().PrimaryAlias(req.Context(), id2).Times(1).Return(alias2, nil)
@@ -128,7 +128,7 @@ func TestGetVMsSuccess(t *testing.T) {
func TestGetVMsVMsListFactoriesFails(t *testing.T) { func TestGetVMsVMsListFactoriesFails(t *testing.T) {
resources := initGetVMsTest(t) resources := initGetVMsTest(t)
req := httptest.NewRequest("POST", "/ext/info", nil) req := httptest.NewRequest("POST", "/v1/info", nil)
resources.mockVMManager.EXPECT().ListFactories(req.Context()).Times(1).Return(nil, errTest) resources.mockVMManager.EXPECT().ListFactories(req.Context()).Times(1).Return(nil, errTest)
reply := apiinfo.GetVMsReply{} reply := apiinfo.GetVMsReply{}
@@ -146,7 +146,7 @@ func TestGetVMsGetAliasesFails(t *testing.T) {
vmIDs := []ids.ID{id1, id2} vmIDs := []ids.ID{id1, id2}
alias1 := "vm1-alias-1" alias1 := "vm1-alias-1"
req := httptest.NewRequest("POST", "/ext/info", nil) req := httptest.NewRequest("POST", "/v1/info", nil)
resources.mockVMManager.EXPECT().ListFactories(req.Context()).Times(1).Return(vmIDs, nil) resources.mockVMManager.EXPECT().ListFactories(req.Context()).Times(1).Return(vmIDs, nil)
resources.mockVMManager.EXPECT().PrimaryAlias(req.Context(), id1).Times(1).Return(alias1, nil) resources.mockVMManager.EXPECT().PrimaryAlias(req.Context(), id1).Times(1).Return(alias1, nil)
resources.mockVMManager.EXPECT().PrimaryAlias(req.Context(), id2).Times(1).Return("", errTest) resources.mockVMManager.EXPECT().PrimaryAlias(req.Context(), id2).Times(1).Return("", errTest)
+1 -1
View File
@@ -38,7 +38,7 @@ type client struct {
// instead. // instead.
func NewClient(uri string) Client { func NewClient(uri string) Client {
return &client{requester: rpc.NewEndpointRequester( return &client{requester: rpc.NewEndpointRequester(
uri + "/ext/keystore", uri + "/v1/keystore",
)} )}
} }
+6 -6
View File
@@ -48,7 +48,7 @@ This API uses the `json 2.0` API format. For more information on making JSON RPC
## Endpoint ## Endpoint
```text ```text
/ext/keystore /v1/keystore
``` ```
## Methods ## Methods
@@ -89,7 +89,7 @@ curl -X POST --data '{
"username":"myUsername", "username":"myUsername",
"password":"myPassword" "password":"myPassword"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/keystore }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/keystore
``` ```
**Example Response:** **Example Response:**
@@ -129,7 +129,7 @@ curl -X POST --data '{
"username":"myUsername", "username":"myUsername",
"password":"myPassword" "password":"myPassword"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/keystore }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/keystore
``` ```
**Example Response:** **Example Response:**
@@ -183,7 +183,7 @@ curl -X POST --data '{
"username":"myUsername", "username":"myUsername",
"password":"myPassword" "password":"myPassword"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/keystore }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/keystore
``` ```
**Example Response:** **Example Response:**
@@ -238,7 +238,7 @@ curl -X POST --data '{
"password":"myPassword", "password":"myPassword",
"user" :"0x7655a29df6fc2747b0874e1148b423b954a25fcdb1f170d0ec8eb196430f7001942ce55b02a83b1faf50a674b1e55bfc000000008cf2d869" "user" :"0x7655a29df6fc2747b0874e1148b423b954a25fcdb1f170d0ec8eb196430f7001942ce55b02a83b1faf50a674b1e55bfc000000008cf2d869"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/keystore }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/keystore
``` ```
**Example Response:** **Example Response:**
@@ -274,7 +274,7 @@ curl -X POST --data '{
"jsonrpc":"2.0", "jsonrpc":"2.0",
"id" :1, "id" :1,
"method" :"keystore.listUsers" "method" :"keystore.listUsers"
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/keystore }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/keystore
``` ```
**Example Response:** **Example Response:**
+1 -1
View File
@@ -32,7 +32,7 @@ type Client struct {
// NewClient returns a new Metrics API Client // NewClient returns a new Metrics API Client
func NewClient(uri string) *Client { func NewClient(uri string) *Client {
return &Client{ return &Client{
uri: uri + "/ext/metrics", uri: uri + "/v1/metrics",
} }
} }
+2 -2
View File
@@ -7,7 +7,7 @@ This API set is for a specific node, it is unavailable on the [public server](ht
## Endpoint ## Endpoint
``` ```
/ext/metrics /v1/metrics
``` ```
## Usage ## Usage
@@ -15,7 +15,7 @@ This API set is for a specific node, it is unavailable on the [public server](ht
To get the node metrics: To get the node metrics:
```sh ```sh
curl -X POST 127.0.0.1:9630/ext/metrics curl -X POST 127.0.0.1:9630/v1/metrics
``` ```
## Format ## Format
+9 -9
View File
@@ -27,7 +27,7 @@ var ErrNoProfile = errors.New(
"(genesis carries no SecurityProfile{} block); RPC unavailable") "(genesis carries no SecurityProfile{} block); RPC unavailable")
// Service is the JSON-RPC handler set registered under the security // Service is the JSON-RPC handler set registered under the security
// namespace at /ext/security. Methods are read-only; the underlying // namespace at /v1/security. Methods are read-only; the underlying
// profile pointer is set once at construction and never mutated. // profile pointer is set once at construction and never mutated.
// //
// Exposed methods: // Exposed methods:
@@ -37,7 +37,7 @@ var ErrNoProfile = errors.New(
// //
// On the wire, gorilla/rpc dispatches these as security_securityProfile // On the wire, gorilla/rpc dispatches these as security_securityProfile
// and security_blockSecurity (namespace_method). Callers using the REST // and security_blockSecurity (namespace_method). Callers using the REST
// sidecars hit /ext/security/profile and /ext/security/block/{n} // sidecars hit /v1/security/profile and /v1/security/block/{n}
// directly. One namespace, two transports, one shape. // directly. One namespace, two transports, one shape.
// //
// The "block" method returns the chain-wide envelope; per-block // The "block" method returns the chain-wide envelope; per-block
@@ -53,13 +53,13 @@ type Service struct {
// namespace. Profile may be nil — see ErrNoProfile. // namespace. Profile may be nil — see ErrNoProfile.
// //
// The returned handler is suitable for APIServer.AddRoute(handler, // The returned handler is suitable for APIServer.AddRoute(handler,
// "security", "") so it lands at /ext/security on the node's HTTP // "security", "") so it lands at /v1/security on the node's HTTP
// listener. REST sidecars are mounted at /profile and /block/{n} on // listener. REST sidecars are mounted at /profile and /block/{n} on
// the same handler so the full external surface is: // the same handler so the full external surface is:
// //
// POST /ext/security (JSON-RPC, methods above) // POST /v1/security (JSON-RPC, methods above)
// GET /ext/security/profile (REST sidecar) // GET /v1/security/profile (REST sidecar)
// GET /ext/security/block/{n} (REST sidecar) // GET /v1/security/block/{n} (REST sidecar)
func NewHandler(logger log.Logger, profile *consensusconfig.ChainSecurityProfile) (http.Handler, error) { func NewHandler(logger log.Logger, profile *consensusconfig.ChainSecurityProfile) (http.Handler, error) {
server := rpc.NewServer() server := rpc.NewServer()
codec := avajson.NewCodec() codec := avajson.NewCodec()
@@ -71,7 +71,7 @@ func NewHandler(logger log.Logger, profile *consensusconfig.ChainSecurityProfile
} }
// REST sidecars share the Service receiver so the two transports // REST sidecars share the Service receiver so the two transports
// stay byte-identical in semantics (one and only one way to // stay byte-identical in semantics (one and only one way to
// compute the shape). Paths relative to /ext/security: // compute the shape). Paths relative to /v1/security:
// /profile → restProfile // /profile → restProfile
// /block/{n} → restBlockSecurity // /block/{n} → restBlockSecurity
mux := http.NewServeMux() mux := http.NewServeMux()
@@ -133,7 +133,7 @@ func (s *Service) BlockSecurity(_ *http.Request, _ *BlockSecurityArgs, reply *Bl
return nil return nil
} }
// restProfile is the GET /profile sidecar (full path /ext/security/profile). // restProfile is the GET /profile sidecar (full path /v1/security/profile).
// Same body as the securityProfile JSON-RPC method; useful for // Same body as the securityProfile JSON-RPC method; useful for
// explorers that don't speak JSON-RPC. Refuses every non-GET method so // explorers that don't speak JSON-RPC. Refuses every non-GET method so
// callers can't smuggle state through the read-only endpoint. // callers can't smuggle state through the read-only endpoint.
@@ -151,7 +151,7 @@ func (s *Service) restProfile(w http.ResponseWriter, r *http.Request) {
} }
// restBlockSecurity is the GET /block/{n} sidecar (full path // restBlockSecurity is the GET /block/{n} sidecar (full path
// /ext/security/block/{n}). The path suffix is taken as the block // /v1/security/block/{n}). The path suffix is taken as the block
// number; chain alias defaults to the platform chain (callers can // number; chain alias defaults to the platform chain (callers can
// re-route per-chain at the chain-manager layer if needed). // re-route per-chain at the chain-manager layer if needed).
func (s *Service) restBlockSecurity(w http.ResponseWriter, r *http.Request) { func (s *Service) restBlockSecurity(w http.ResponseWriter, r *http.Request) {
+2 -2
View File
@@ -203,7 +203,7 @@ func TestRPC_blockSecurity_StrictPQ(t *testing.T) {
} }
// TestREST_securityProfile_GET proves the /profile sidecar (full path // TestREST_securityProfile_GET proves the /profile sidecar (full path
// /ext/security/profile when mounted on APIServer) returns the same // /v1/security/profile when mounted on APIServer) returns the same
// JSON shape as the JSON-RPC handler. One shape, two transports — no // JSON shape as the JSON-RPC handler. One shape, two transports — no
// per-transport drift. // per-transport drift.
func TestREST_securityProfile_GET(t *testing.T) { func TestREST_securityProfile_GET(t *testing.T) {
@@ -262,7 +262,7 @@ func TestREST_securityProfile_MethodNotAllowed(t *testing.T) {
} }
// TestREST_blockSecurity_GET proves the /block/{n} sidecar (full path // TestREST_blockSecurity_GET proves the /block/{n} sidecar (full path
// /ext/security/block/{n} when mounted on APIServer) returns the same // /v1/security/block/{n} when mounted on APIServer) returns the same
// JSON shape as the JSON-RPC handler. One shape, two transports — no // JSON shape as the JSON-RPC handler. One shape, two transports — no
// per-transport drift. // per-transport drift.
func TestREST_blockSecurity_GET(t *testing.T) { func TestREST_blockSecurity_GET(t *testing.T) {
+5 -5
View File
@@ -3,8 +3,8 @@
// Package security exposes the chain-wide ChainSecurityProfile to operators, // Package security exposes the chain-wide ChainSecurityProfile to operators,
// dApps, and auditors through the security JSON-RPC namespace at // dApps, and auditors through the security JSON-RPC namespace at
// /ext/security and two REST sidecars at /ext/security/profile and // /v1/security and two REST sidecars at /v1/security/profile and
// /ext/security/block/{n}. // /v1/security/block/{n}.
// //
// The handlers in this package are read-only: every shape is derived from // The handlers in this package are read-only: every shape is derived from
// the immutable *consensusconfig.ChainSecurityProfile resolved at node // the immutable *consensusconfig.ChainSecurityProfile resolved at node
@@ -22,7 +22,7 @@ import (
) )
// ProfileReply is the JSON body returned by the securityProfile RPC // ProfileReply is the JSON body returned by the securityProfile RPC
// (POST /ext/security) and the REST sidecar (GET /ext/security/profile). // (POST /v1/security) and the REST sidecar (GET /v1/security/profile).
// //
// Stable shape: every field has a fixed JSON tag, no embedded structs. // Stable shape: every field has a fixed JSON tag, no embedded structs.
// Adding a new field requires bumping the major version of the security // Adding a new field requires bumping the major version of the security
@@ -99,8 +99,8 @@ type ProfileReply struct {
} }
// BlockSecurityReply is the JSON body returned by the blockSecurity // BlockSecurityReply is the JSON body returned by the blockSecurity
// RPC (POST /ext/security) and the REST endpoint // RPC (POST /v1/security) and the REST endpoint
// /ext/security/block/{n}. It enriches a block lookup with the // /v1/security/block/{n}. It enriches a block lookup with the
// chain-wide security envelope so explorers can show "this block was // chain-wide security envelope so explorers can show "this block was
// finalised under profile X with backend Y" without reimplementing // finalised under profile X with backend Y" without reimplementing
// profile lookup. // profile lookup.
+1 -1
View File
@@ -31,7 +31,7 @@ type SimpleNodesMetrics map[string]SimpleNodeMetrics
// GetSimpleNodeMetrics retrieves the specified metrics the provided node URI. // GetSimpleNodeMetrics retrieves the specified metrics the provided node URI.
func GetSimpleNodeMetrics(nodeURI string, metricNames ...string) (SimpleNodeMetrics, error) { func GetSimpleNodeMetrics(nodeURI string, metricNames ...string) (SimpleNodeMetrics, error) {
uri := nodeURI + "/ext/metrics" uri := nodeURI + "/v1/metrics"
return GetMetricsValue(uri, metricNames...) return GetMetricsValue(uri, metricNames...)
} }
+1 -1
View File
@@ -149,7 +149,7 @@ type Client interface {
For example: For example:
```bash ```bash
curl --location --request POST 'http://34.235.54.228:9630/ext/bc/28iioW2fYMBnKv24VG5nw9ifY2PsFuwuhxhyzxZB5MmxDd3rnT' \ curl --location --request POST 'http://34.235.54.228:9630/v1/bc/28iioW2fYMBnKv24VG5nw9ifY2PsFuwuhxhyzxZB5MmxDd3rnT' \
--header 'Content-Type: application/json' \ --header 'Content-Type: application/json' \
--data-raw '{ --data-raw '{
"jsonrpc": "2.0", "jsonrpc": "2.0",
@@ -5,7 +5,7 @@ The `GetAllValidatorsAt` endpoint returns the validator sets of all networks (in
## Endpoint ## Endpoint
``` ```
POST /ext/bc/P POST /v1/bc/P
``` ```
## Request Format ## Request Format
@@ -71,7 +71,7 @@ curl -X POST --data '{
"params": { "params": {
"height": 1000 "height": 1000
} }
}' -H 'content-type:application/json;' http://127.0.0.1:9650/ext/bc/P }' -H 'content-type:application/json;' http://127.0.0.1:9650/v1/bc/P
``` ```
### Get validators at proposed height ### Get validators at proposed height
@@ -83,7 +83,7 @@ curl -X POST --data '{
"params": { "params": {
"height": "proposed" "height": "proposed"
} }
}' -H 'content-type:application/json;' http://127.0.0.1:9650/ext/bc/P }' -H 'content-type:application/json;' http://127.0.0.1:9650/v1/bc/P
``` ```
## Use Cases ## Use Cases
+1 -1
View File
@@ -29,7 +29,7 @@ type staticClient struct {
// NewClient returns a platformvm client for interacting with the platformvm static api // NewClient returns a platformvm client for interacting with the platformvm static api
func NewStaticClient(uri string) StaticClient { func NewStaticClient(uri string) StaticClient {
return &staticClient{requester: rpc.NewEndpointRequester( return &staticClient{requester: rpc.NewEndpointRequester(
uri + "/ext/vm/platform", uri + "/v1/vm/platform",
)} )}
} }
+2 -2
View File
@@ -32,7 +32,7 @@ type Client struct {
func NewClient(uri string) *Client { func NewClient(uri string) *Client {
return &Client{Requester: rpc.NewEndpointRequester( return &Client{Requester: rpc.NewEndpointRequester(
uri + "/ext/bc/P", uri + "/v1/bc/P",
)} )}
} }
@@ -40,7 +40,7 @@ func NewClient(uri string) *Client {
// for proper bech32 address formatting // for proper bech32 address formatting
func NewClientWithNetworkID(uri string, networkID uint32) *Client { func NewClientWithNetworkID(uri string, networkID uint32) *Client {
return &Client{ return &Client{
Requester: rpc.NewEndpointRequester(uri + "/ext/bc/P"), Requester: rpc.NewEndpointRequester(uri + "/v1/bc/P"),
networkID: networkID, networkID: networkID,
} }
} }
+36 -36
View File
@@ -3,7 +3,7 @@ The P-Chain API allows clients to interact with the [P-Chain](https://build.lux.
## Endpoint ## Endpoint
``` ```
/ext/bc/P /v1/bc/P
``` ```
## Format ## Format
@@ -56,7 +56,7 @@ curl -X POST --data '{
"params" :{ "params" :{
"addresses":["P-custom18jma8ppw3nhx5r4ap8clazz0dps7rv5u9xde7p"] "addresses":["P-custom18jma8ppw3nhx5r4ap8clazz0dps7rv5u9xde7p"]
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/P }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -133,7 +133,7 @@ curl -X POST --data '{
"encoding": "hex" "encoding": "hex"
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/P }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -162,7 +162,7 @@ curl -X POST --data '{
"encoding": "json" "encoding": "json"
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/P }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -266,7 +266,7 @@ curl -X POST --data '{
"encoding": "hex" "encoding": "hex"
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/P }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -295,7 +295,7 @@ curl -X POST --data '{
"encoding": "json" "encoding": "json"
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/P }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -398,7 +398,7 @@ curl -X POST --data '{
"method": "platform.getBlockchains", "method": "platform.getBlockchains",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/P }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -490,7 +490,7 @@ curl -X POST --data '{
"blockchainID":"2NbS4dwGaf2p1MaXb65PrkZdXRwmSX4ZzGnUu7jm3aykgThuZE" "blockchainID":"2NbS4dwGaf2p1MaXb65PrkZdXRwmSX4ZzGnUu7jm3aykgThuZE"
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/P }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -530,7 +530,7 @@ curl -X POST --data '{
"netID": "11111111111111111111111111111111LpoYY" "netID": "11111111111111111111111111111111LpoYY"
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/P }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -671,7 +671,7 @@ curl -X POST --data '{
"nodeIDs": ["NodeID-5mb46qkSBj81k9g9e4VFjGGSbaaSLFRzD"] "nodeIDs": ["NodeID-5mb46qkSBj81k9g9e4VFjGGSbaaSLFRzD"]
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/P }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/P
``` ```
**Example Response (Primary Network):** **Example Response (Primary Network):**
@@ -793,7 +793,7 @@ curl -X POST --data '{
"method": "platform.getFeeConfig", "method": "platform.getFeeConfig",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/P }' -H 'content-type:application/json;' 127.0.0.1:9650/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -836,7 +836,7 @@ curl -X POST --data '{
"method": "platform.getFeeState", "method": "platform.getFeeState",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/P }' -H 'content-type:application/json;' 127.0.0.1:9650/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -875,7 +875,7 @@ curl -X POST --data '{
"method": "platform.getHeight", "method": "platform.getHeight",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/P }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -944,7 +944,7 @@ curl -X POST --data '{
"validationID": ["9FAftNgNBrzHUMMApsSyV6RcFiL9UmCbvsCu28xdLV2mQ7CMo"] "validationID": ["9FAftNgNBrzHUMMApsSyV6RcFiL9UmCbvsCu28xdLV2mQ7CMo"]
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/P }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -998,7 +998,7 @@ curl -X POST --data '{
"method": "platform.getProposedHeight", "method": "platform.getProposedHeight",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/P }' -H 'content-type:application/json;' 127.0.0.1:9650/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -1040,7 +1040,7 @@ curl -X POST --data '{
"params": { "params": {
"netID":"11111111111111111111111111111111LpoYY" "netID":"11111111111111111111111111111111LpoYY"
}, },
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/P }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -1096,7 +1096,7 @@ curl -X POST --data '{
"txID": "2nmH8LithVbdjaXsxVQCQfXtzN9hBbmebrsaEYnLM9T32Uy2Y5" "txID": "2nmH8LithVbdjaXsxVQCQfXtzN9hBbmebrsaEYnLM9T32Uy2Y5"
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/P }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -1161,7 +1161,7 @@ curl -X POST --data '{
}, },
"id": 1 "id": 1
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/P }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -1210,7 +1210,7 @@ curl -X POST --data '{
"netID": "11111111111111111111111111111111LpoYY" "netID": "11111111111111111111111111111111LpoYY"
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/P }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -1275,7 +1275,7 @@ curl -X POST --data '{
"method": "platform.getNet", "method": "platform.getNet",
"params": {"netID":"Vz2ArUpigHt7fyE79uF3gAXvTPLJi2LGgZoMpgNPHowUZJxBb"}, "params": {"netID":"Vz2ArUpigHt7fyE79uF3gAXvTPLJi2LGgZoMpgNPHowUZJxBb"},
"id": 1 "id": 1
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/P }' -H 'content-type:application/json;' 127.0.0.1:9650/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -1340,7 +1340,7 @@ curl -X POST --data '{
"method": "platform.getNets", "method": "platform.getNets",
"params": {"ids":["hW8Ma7dLMA7o4xmJf3AXBbo17bXzE7xnThUd3ypM4VAWo1sNJ"]}, "params": {"ids":["hW8Ma7dLMA7o4xmJf3AXBbo17bXzE7xnThUd3ypM4VAWo1sNJ"]},
"id": 1 "id": 1
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/P }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -1383,7 +1383,7 @@ curl -X POST --data '{
"params": {}, "params": {},
"id": 1 "id": 1
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/P }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -1426,7 +1426,7 @@ curl -X POST --data '{
}, },
"id": 1 "id": 1
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/P }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -1455,7 +1455,7 @@ curl -X POST --data '{
}, },
"id": 1 "id": 1
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/P }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/P
``` ```
**Example Response:** **Example Response:**
@@ -1500,7 +1500,7 @@ curl -X POST --data '{
"encoding": "json" "encoding": "json"
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/P }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -1612,7 +1612,7 @@ curl -X POST --data '{
"txID":"TAG9Ns1sa723mZy1GSoGqWipK6Mvpaj7CAswVJGM6MkVJDF9Q" "txID":"TAG9Ns1sa723mZy1GSoGqWipK6Mvpaj7CAswVJGM6MkVJDF9Q"
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/P }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -1685,7 +1685,7 @@ curl -X POST --data '{
"limit":5, "limit":5,
"encoding": "hex" "encoding": "hex"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/P }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/P
``` ```
This gives response: This gives response:
@@ -1729,7 +1729,7 @@ curl -X POST --data '{
}, },
"encoding": "hex" "encoding": "hex"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/P }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/P
``` ```
This gives response: This gives response:
@@ -1772,7 +1772,7 @@ curl -X POST --data '{
"sourceChain": "X", "sourceChain": "X",
"encoding": "hex" "encoding": "hex"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/P }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/P
``` ```
This gives response: This gives response:
@@ -1825,7 +1825,7 @@ curl -X POST --data '{
"height":1 "height":1
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/P }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -1874,7 +1874,7 @@ curl -X POST --data '{
"method": "platform.getValidatorFeeConfig", "method": "platform.getValidatorFeeConfig",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/P }' -H 'content-type:application/json;' 127.0.0.1:9650/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -1915,7 +1915,7 @@ curl -X POST --data '{
"method": "platform.getValidatorFeeState", "method": "platform.getValidatorFeeState",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/P }' -H 'content-type:application/json;' 127.0.0.1:9650/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -1961,7 +1961,7 @@ curl -X POST --data '{
"encoding": "hex" "encoding": "hex"
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/P }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -2008,7 +2008,7 @@ curl -X POST --data '{
"params" :{ "params" :{
"size":2 "size":2
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/P }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -2053,7 +2053,7 @@ curl -X POST --data '{
"blockchainID": "KDYHHKjM4yTJTT8H8qPs5KXzE6gQH5TZrmP1qVr1P6qECj3XN" "blockchainID": "KDYHHKjM4yTJTT8H8qPs5KXzE6gQH5TZrmP1qVr1P6qECj3XN"
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/P }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/P
``` ```
**Example Response:** **Example Response:**
@@ -2095,7 +2095,7 @@ curl -X POST --data '{
"netID":"2bRCr6B4MiEfSjidDwxDpdCyviwnfUVqB2HGwhm947w9YYqb7r" "netID":"2bRCr6B4MiEfSjidDwxDpdCyviwnfUVqB2HGwhm947w9YYqb7r"
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/P }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/P
``` ```
**Example Response:** **Example Response:**
+1 -1
View File
@@ -74,7 +74,7 @@ ground-truth numbers, drop captured bytes into `testdata/`:
```bash ```bash
POD=$(kubectl -n lux get pods -l app=luxd -o jsonpath='{.items[0].metadata.name}') POD=$(kubectl -n lux get pods -l app=luxd -o jsonpath='{.items[0].metadata.name}')
kubectl -n lux exec "$POD" -- curl -s http://localhost:9650/ext/bc/P \ kubectl -n lux exec "$POD" -- curl -s http://localhost:9650/v1/bc/P \
-H 'Content-Type: application/json' \ -H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"platform.getMempool"}' \ -d '{"jsonrpc":"2.0","id":1,"method":"platform.getMempool"}' \
> /tmp/mempool.json > /tmp/mempool.json
+2 -2
View File
@@ -7,7 +7,7 @@ The `GetProposedHeight` API endpoint returns the P-Chain height that would be pr
## Endpoint ## Endpoint
``` ```
/ext/bc/<CHAIN_ID>/proposervm /v1/bc/<CHAIN_ID>/proposervm
``` ```
## Method ## Method
@@ -45,7 +45,7 @@ curl -X POST --data '{
"id" :1, "id" :1,
"method" :"proposervm.getProposedHeight", "method" :"proposervm.getProposedHeight",
"params" :{} "params" :{}
}' -H 'content-type:application/json;' http://127.0.0.1:9650/ext/bc/C/proposervm }' -H 'content-type:application/json;' http://127.0.0.1:9650/v1/bc/C/proposervm
``` ```
### Response ### Response
+1 -1
View File
@@ -36,7 +36,7 @@ type GetProposedHeightReply struct {
// "id" :1, // "id" :1,
// "method" :"proposervm.getProposedHeight", // "method" :"proposervm.getProposedHeight",
// "params" :{} // "params" :{}
// }' -H 'content-type:application/json;' http://127.0.0.1:9650/ext/bc/C/rpc // }' -H 'content-type:application/json;' http://127.0.0.1:9650/v1/bc/C/rpc
func (s *Service) GetProposedHeight(r *http.Request, _ *GetProposedHeightArgs, reply *GetProposedHeightReply) error { func (s *Service) GetProposedHeight(r *http.Request, _ *GetProposedHeightArgs, reply *GetProposedHeightReply) error {
ctx := r.Context() ctx := r.Context()
+3 -3
View File
@@ -5,7 +5,7 @@ The ProposerVM API allows clients to fetch information about a chain's Consensus
## Endpoint ## Endpoint
```text ```text
/ext/bc/{blockchainID}/proposervm /v1/bc/{blockchainID}/proposervm
``` ```
## Format ## Format
@@ -35,7 +35,7 @@ curl -X POST --data '{
"method": "proposervm.getProposedHeight", "method": "proposervm.getProposedHeight",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/P/proposervm }' -H 'content-type:application/json;' 127.0.0.1:9650/v1/bc/P/proposervm
``` ```
**Example Response:** **Example Response:**
@@ -73,7 +73,7 @@ curl -X POST --data '{
"method": "proposervm.getCurrentEpoch", "method": "proposervm.getCurrentEpoch",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/P/proposervm }' -H 'content-type:application/json;' 127.0.0.1:9650/v1/bc/P/proposervm
``` ```
**Example Response:** **Example Response:**
+39 -39
View File
@@ -20,9 +20,9 @@ This API uses the `json 2.0` RPC format. For more information on making JSON RPC
## Endpoints ## Endpoints
`/ext/bc/X` to interact with the X-Chain. `/v1/bc/X` to interact with the X-Chain.
`/ext/bc/blockchainID` to interact with other XVM instances, where `blockchainID` is the ID of a `/v1/bc/blockchainID` to interact with other XVM instances, where `blockchainID` is the ID of a
blockchain running the XVM. blockchain running the XVM.
## Methods ## Methods
@@ -36,7 +36,7 @@ of that state.
This call is made to the XVMs static API endpoint: This call is made to the XVMs static API endpoint:
`/ext/vm/xvm` `/v1/vm/xvm`
Note: addresses should not include a chain prefix (that is `X-`) in calls to the static API endpoint Note: addresses should not include a chain prefix (that is `X-`) in calls to the static API endpoint
because these prefixes refer to a specific chain. because these prefixes refer to a specific chain.
@@ -169,7 +169,7 @@ curl -X POST --data '{
}, },
"encoding": "hex" "encoding": "hex"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/vm/xvm }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/vm/xvm
``` ```
**Example Response:** **Example Response:**
@@ -219,7 +219,7 @@ curl -X POST --data '{
"password": "myPassword" "password": "myPassword"
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/X }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/X
``` ```
**Example Response:** **Example Response:**
@@ -316,7 +316,7 @@ curl -X POST --data '{
"username":"myUsername", "username":"myUsername",
"password":"myPassword" "password":"myPassword"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/X }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/X
``` ```
**Example Response:** **Example Response:**
@@ -404,7 +404,7 @@ curl -X POST --data '{
"username":"myUsername", "username":"myUsername",
"password":"myPassword" "password":"myPassword"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/X }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/X
``` ```
**Example Response:** **Example Response:**
@@ -505,7 +505,7 @@ curl -X POST --data '{
"username":"myUsername", "username":"myUsername",
"password":"myPassword" "password":"myPassword"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/X }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/X
``` ```
**Example Response:** **Example Response:**
@@ -582,7 +582,7 @@ curl -X POST --data '{
"username":"myUsername", "username":"myUsername",
"password":"myPassword" "password":"myPassword"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/X }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/X
``` ```
**Example Response:** **Example Response:**
@@ -642,7 +642,7 @@ curl -X POST --data '{
"password":"myPassword", "password":"myPassword",
"address":"X-lux18jma8ppw3nhx5r4ap8clazz0dps7rv5ukulre5" "address":"X-lux18jma8ppw3nhx5r4ap8clazz0dps7rv5ukulre5"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/X }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/X
``` ```
**Example Response:** **Example Response:**
@@ -713,7 +713,7 @@ curl -X POST --data '{
"assetID":"LUX", "assetID":"LUX",
"pageSize":20 "pageSize":20
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/X }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/X
``` ```
**Example Response:** **Example Response:**
@@ -759,7 +759,7 @@ curl -X POST --data '{
"params" :{ "params" :{
"address":"X-lux1c79e0dd0susp7dc8udq34jgk2yvve7hapvdyht" "address":"X-lux1c79e0dd0susp7dc8udq34jgk2yvve7hapvdyht"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/X }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/X
``` ```
**Example Response:** **Example Response:**
@@ -829,7 +829,7 @@ curl -X POST --data '{
"params" :{ "params" :{
"assetID" :"FvwEAhmxKfeiG8SnEvq42hc6whRyY3EFYAvebMqDNDGCgxN5Z" "assetID" :"FvwEAhmxKfeiG8SnEvq42hc6whRyY3EFYAvebMqDNDGCgxN5Z"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/X }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/X
``` ```
**Example Response:** **Example Response:**
@@ -878,7 +878,7 @@ curl -X POST --data '{
"address":"X-lux18jma8ppw3nhx5r4ap8clazz0dps7rv5ukulre5", "address":"X-lux18jma8ppw3nhx5r4ap8clazz0dps7rv5ukulre5",
"assetID": "2pYGetDWyKdHxpFxh2LHeoLNCH6H5vxxCxHQtFnnFaYxLsqtHC" "assetID": "2pYGetDWyKdHxpFxh2LHeoLNCH6H5vxxCxHQtFnnFaYxLsqtHC"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/X }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/X
``` ```
**Example Response:** **Example Response:**
@@ -938,7 +938,7 @@ curl -X POST --data '{
"encoding": "hex" "encoding": "hex"
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/X }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/X
``` ```
**Example Response:** **Example Response:**
@@ -994,7 +994,7 @@ curl -X POST --data '{
"encoding": "hex" "encoding": "hex"
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/X }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/X
``` ```
**Example Response:** **Example Response:**
@@ -1031,7 +1031,7 @@ curl -X POST --data '{
"method": "xvm.getHeight", "method": "xvm.getHeight",
"params": {}, "params": {},
"id": 1 "id": 1
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/X }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/X
``` ```
**Example Response:** **Example Response:**
@@ -1074,7 +1074,7 @@ curl -X POST --data '{
"txID":"2oJCbb8pfdxEHAf9A8CdN4Afj9VSR3xzyzNkf8tDv7aM1sfNFL", "txID":"2oJCbb8pfdxEHAf9A8CdN4Afj9VSR3xzyzNkf8tDv7aM1sfNFL",
"encoding": "json" "encoding": "json"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/X }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/X
``` ```
**Example Response:** **Example Response:**
@@ -1208,7 +1208,7 @@ curl -X POST --data '{
"params" :{ "params" :{
"txID":"2QouvFWUbjuySRxeX5xMbNCuAaKWfbk5FeEa2JmoF85RKLk2dD" "txID":"2QouvFWUbjuySRxeX5xMbNCuAaKWfbk5FeEa2JmoF85RKLk2dD"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/X }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/X
``` ```
**Example Response:** **Example Response:**
@@ -1279,7 +1279,7 @@ curl -X POST --data '{
"limit":5, "limit":5,
"encoding": "hex" "encoding": "hex"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/X }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/X
``` ```
This gives response: This gives response:
@@ -1323,7 +1323,7 @@ curl -X POST --data '{
}, },
"encoding": "hex" "encoding": "hex"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/X }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/X
``` ```
This gives response: This gives response:
@@ -1367,7 +1367,7 @@ curl -X POST --data '{
"sourceChain": "P", "sourceChain": "P",
"encoding": "hex" "encoding": "hex"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/X }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/X
``` ```
This gives response: This gives response:
@@ -1435,7 +1435,7 @@ curl -X POST --data '{
"username":"myUsername", "username":"myUsername",
"password":"myPassword" "password":"myPassword"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/X }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/X
``` ```
**Example Response:** **Example Response:**
@@ -1493,7 +1493,7 @@ curl -X POST --data '{
"password":"myPassword", "password":"myPassword",
"privateKey":"PrivateKey-2w4XiXxPfQK4TypYqnohRL8DRNTz9cGiGmwQ1zmgEqD9c9KWLq" "privateKey":"PrivateKey-2w4XiXxPfQK4TypYqnohRL8DRNTz9cGiGmwQ1zmgEqD9c9KWLq"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/X }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/X
``` ```
**Example Response:** **Example Response:**
@@ -1536,7 +1536,7 @@ curl -X POST --data '{
"tx":"0x00000009de31b4d8b22991d51aa6aa1fc733f23a851a8c9400000000000186a0000000005f041280000000005f9ca900000030390000000000000001fceda8f90fcb5d30614b99d79fc4baa29307762668f16eb0259a57c2d3b78c875c86ec2045792d4df2d926c40f829196e0bb97ee697af71f5b0a966dabff749634c8b729855e937715b0e44303fd1014daedc752006011b730", "tx":"0x00000009de31b4d8b22991d51aa6aa1fc733f23a851a8c9400000000000186a0000000005f041280000000005f9ca900000030390000000000000001fceda8f90fcb5d30614b99d79fc4baa29307762668f16eb0259a57c2d3b78c875c86ec2045792d4df2d926c40f829196e0bb97ee697af71f5b0a966dabff749634c8b729855e937715b0e44303fd1014daedc752006011b730",
"encoding": "hex" "encoding": "hex"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/X }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/X
``` ```
**Example Response:** **Example Response:**
@@ -1585,7 +1585,7 @@ curl -X POST --data '{
"password":"myPassword" "password":"myPassword"
}, },
"id": 1 "id": 1
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/X }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/X
``` ```
**Example Response:** **Example Response:**
@@ -1660,7 +1660,7 @@ curl -X POST --data '{
"username":"myUsername", "username":"myUsername",
"password":"myPassword" "password":"myPassword"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/X }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/X
``` ```
**Example Response:** **Example Response:**
@@ -1741,7 +1741,7 @@ curl -X POST --data '{
"username":"myUsername", "username":"myUsername",
"password":"myPassword" "password":"myPassword"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/X }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/X
``` ```
**Example Response:** **Example Response:**
@@ -1814,7 +1814,7 @@ curl -X POST --data '{
"username" : "userThatControlsAtLeast10000OfThisAsset", "username" : "userThatControlsAtLeast10000OfThisAsset",
"password" : "myPassword" "password" : "myPassword"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/X }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/X
``` ```
**Example Response:** **Example Response:**
@@ -1897,7 +1897,7 @@ curl -X POST --data '{
"username" : "username", "username" : "username",
"password" : "myPassword" "password" : "myPassword"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/X }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/X
``` ```
**Example Response:** **Example Response:**
@@ -1967,7 +1967,7 @@ curl -X POST --data '{
"username" : "myUsername", "username" : "myUsername",
"password" : "myPassword" "password" : "myPassword"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/X }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/X
``` ```
**Example Response:** **Example Response:**
@@ -1991,7 +1991,7 @@ the format of the signed transaction. Can only be `hex` when a value is provided
This call is made to the wallet API endpoint: This call is made to the wallet API endpoint:
`/ext/bc/X/wallet` `/v1/bc/X/wallet`
:::caution :::caution
@@ -2021,7 +2021,7 @@ curl -X POST --data '{
"tx":"0x00000009de31b4d8b22991d51aa6aa1fc733f23a851a8c9400000000000186a0000000005f041280000000005f9ca900000030390000000000000001fceda8f90fcb5d30614b99d79fc4baa29307762668f16eb0259a57c2d3b78c875c86ec2045792d4df2d926c40f829196e0bb97ee697af71f5b0a966dabff749634c8b729855e937715b0e44303fd1014daedc752006011b730", "tx":"0x00000009de31b4d8b22991d51aa6aa1fc733f23a851a8c9400000000000186a0000000005f041280000000005f9ca900000030390000000000000001fceda8f90fcb5d30614b99d79fc4baa29307762668f16eb0259a57c2d3b78c875c86ec2045792d4df2d926c40f829196e0bb97ee697af71f5b0a966dabff749634c8b729855e937715b0e44303fd1014daedc752006011b730",
"encoding": "hex" "encoding": "hex"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/X/wallet }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/X/wallet
``` ```
**Example Response:** **Example Response:**
@@ -2047,7 +2047,7 @@ can use the modified UTXO set.
This call is made to the wallet API endpoint: This call is made to the wallet API endpoint:
`/ext/bc/X/wallet` `/v1/bc/X/wallet`
:::caution :::caution
@@ -2098,7 +2098,7 @@ curl -X POST --data '{
"username" : "userThatControlsAtLeast10000OfThisAsset", "username" : "userThatControlsAtLeast10000OfThisAsset",
"password" : "myPassword" "password" : "myPassword"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/X/wallet }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/X/wallet
``` ```
**Example Response:** **Example Response:**
@@ -2125,7 +2125,7 @@ addresses and assume the TX will be accepted so that future calls can use the mo
This call is made to the wallet API endpoint: This call is made to the wallet API endpoint:
`/ext/bc/X/wallet` `/v1/bc/X/wallet`
:::caution :::caution
@@ -2185,7 +2185,7 @@ curl -X POST --data '{
"username" : "username", "username" : "username",
"password" : "myPassword" "password" : "myPassword"
} }
}' -H 'content-type:application/json;' 127.0.0.1:9630/ext/bc/X/wallet }' -H 'content-type:application/json;' 127.0.0.1:9630/v1/bc/X/wallet
``` ```
**Example Response:** **Example Response:**
@@ -2207,7 +2207,7 @@ Listen for transactions on a specified address.
This call is made to the events API endpoint: This call is made to the events API endpoint:
`/ext/bc/X/events` `/v1/bc/X/events`
:::caution :::caution
@@ -2240,7 +2240,7 @@ func main() {
} }
httpHeader := http.Header{} httpHeader := http.Header{}
conn, _, err := dialer.Dial("ws://localhost:9630/ext/bc/X/events", httpHeader) conn, _, err := dialer.Dial("ws://localhost:9630/v1/bc/X/events", httpHeader)
if err != nil { if err != nil {
panic(err) panic(err)
} }
+1 -1
View File
@@ -25,7 +25,7 @@ type staticClient struct {
// NewClient returns an XVM client for interacting with the xvm static api // NewClient returns an XVM client for interacting with the xvm static api
func NewStaticClient(uri string) StaticClient { func NewStaticClient(uri string) StaticClient {
return &staticClient{requester: rpc.NewEndpointRequester( return &staticClient{requester: rpc.NewEndpointRequester(
uri + "/ext/vm/xvm", uri + "/v1/vm/xvm",
)} )}
} }
+1 -1
View File
@@ -70,7 +70,7 @@ type XClient struct {
func NewXClient(uri, chainAlias string) *XClient { func NewXClient(uri, chainAlias string) *XClient {
return &XClient{ return &XClient{
requester: rpc.NewEndpointRequester( requester: rpc.NewEndpointRequester(
fmt.Sprintf("%s/ext/bc/%s", uri, chainAlias), fmt.Sprintf("%s/v1/bc/%s", uri, chainAlias),
), ),
} }
} }
@@ -126,7 +126,7 @@ func sendSignedTx(ctx context.Context, client *ethclient.Client, chainID *big.In
// it first sends `seedAmount` from seedKey to the heartbeat key and waits // it first sends `seedAmount` from seedKey to the heartbeat key and waits
// for that to confirm before issuing the heartbeat tx. // for that to confirm before issuing the heartbeat tx.
func heartbeatChain(ctx context.Context, chain, rpcBase string, key, seedKey *ecdsa.PrivateKey, seedAmount, seedFloor *big.Int, waitFor time.Duration) (prev, next uint64, txHash common.Hash, gasUsed uint64, err error) { func heartbeatChain(ctx context.Context, chain, rpcBase string, key, seedKey *ecdsa.PrivateKey, seedAmount, seedFloor *big.Int, waitFor time.Duration) (prev, next uint64, txHash common.Hash, gasUsed uint64, err error) {
url := fmt.Sprintf("%s/ext/bc/%s/rpc", strings.TrimRight(rpcBase, "/"), chain) url := fmt.Sprintf("%s/v1/bc/%s/rpc", strings.TrimRight(rpcBase, "/"), chain)
client, err := ethclient.DialContext(ctx, url) client, err := ethclient.DialContext(ctx, url)
if err != nil { if err != nil {
return 0, 0, common.Hash{}, 0, fmt.Errorf("dial %s: %w", url, err) return 0, 0, common.Hash{}, 0, fmt.Errorf("dial %s: %w", url, err)
@@ -190,7 +190,7 @@ func main() {
seedAmountWei string seedAmountWei string
seedFloorWei string seedFloorWei string
) )
flag.StringVar(&chains, "chains", "C,hanzo,zoo,pars,spc", "comma-separated chain aliases under /ext/bc/<chain>/rpc") flag.StringVar(&chains, "chains", "C,hanzo,zoo,pars,spc", "comma-separated chain aliases under /v1/bc/<chain>/rpc")
flag.StringVar(&rpcBase, "rpc-base", "", "RPC base URL, e.g. https://api.lux-test.network") flag.StringVar(&rpcBase, "rpc-base", "", "RPC base URL, e.g. https://api.lux-test.network")
flag.StringVar(&mnemonicEnv, "mnemonic-env", "LUX_MNEMONIC", "env var holding the BIP39 mnemonic") flag.StringVar(&mnemonicEnv, "mnemonic-env", "LUX_MNEMONIC", "env var holding the BIP39 mnemonic")
flag.UintVar(&bipIdx, "bip44-idx", 10, "BIP44 child index at m/44'/60'/0'/0/<idx>") flag.UintVar(&bipIdx, "bip44-idx", 10, "BIP44 child index at m/44'/60'/0'/0/<idx>")