Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .bindings-metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"expectedCommitSha": "PLACEHOLDER",
"requiredClientMethods": [
"balance",
"get_admin",
"place_bet",
"get_oracle",
"initialize",
"set_windows",
"create_round",
"mint_initial",
"predict_price",
"resolve_round",
"claim_winnings",
"get_user_stats",
"get_active_round",
"get_last_round_id",
"get_user_position",
"get_pending_winnings",
"get_updown_positions",
"get_precision_predictions",
"place_precision_prediction",
"get_user_precision_prediction"
],
"requiredExports": [
"Client",
"RoundMode",
"ContractError"
]
}
26 changes: 23 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,32 @@ jobs:
- name: Check OpenAPI contract drift
run: npm run docs:verify

bindings-drift:
name: bindings version skew check
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22
cache: npm

- name: Install dependencies
run: npm ci

- name: Validate vendored bindings
run: node scripts/validate-bindings.js

test-unit:
name: test (unit)
runs-on: ubuntu-latest
env:
NODE_ENV: test
JWT_SECRET: ci-test-secret
JWT_SECRET: ci-test-secret-at-least-16-chars
TEST_TYPE: unit

steps:
Expand Down Expand Up @@ -138,7 +158,7 @@ jobs:
env:
NODE_ENV: test
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/xelma_ci
JWT_SECRET: ci-test-secret
JWT_SECRET: ci-test-secret-at-least-16-chars

services:
postgres:
Expand Down Expand Up @@ -180,7 +200,7 @@ jobs:
env:
NODE_ENV: test
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/xelma_ci
JWT_SECRET: ci-test-secret
JWT_SECRET: ci-test-secret-at-least-16-chars

services:
postgres:
Expand Down
99 changes: 99 additions & 0 deletions BINDINGS_UPGRADE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Bindings Upgrade Procedure

This document describes how to upgrade the vendored `@tevalabs/xelma-bindings` package when the contract ABI changes.

## Overview

The backend vendors `@tevalabs/xelma-bindings` from the [Xelma-Blockchain](https://github.com/TevaLabs/Xelma-Blockchain) repository. The vendored copy must match the contract ABI used by the deployed Soroban contract. Version skew causes runtime failures that are expensive to debug.

## Detection

The following mechanisms detect bindings version skew:

1. **CI pipeline** — The `bindings-drift` job in `.github/workflows/ci.yml` runs `scripts/validate-bindings.js` on every push and PR. It fails if:
- Structural files are missing (dist, package.json)
- Commit SHA does not match `.bindings-metadata.json`
- Required Client methods or module exports are missing

2. **Startup validation** — The backend logs warnings/errors at startup via `src/utils/bindings-validator.ts`:
- Structural checks run synchronously (warnings)
- API surface checks run asynchronously before server start (errors)
- Set `FAIL_ON_BINDINGS_MISMATCH=true` to abort startup on skew

## Upgrade Steps

### 1. Update the vendored bindings

```bash
npm run install-bindings
```

This script:
- Sparse-clones the `bindings/` directory from `Xelma-Blockchain` main branch
- Builds both ESM and CJS outputs
- Writes `.commit-sha` with the upstream commit hash
- Copies the result to `vendor/xelma-bindings/`

### 2. Verify the new bindings

```bash
node scripts/validate-bindings.js
```

This runs the same checks as CI. Confirm it passes before committing.

### 3. Update metadata (if ABI changed)

If the new bindings add/remove methods or exports, update `.bindings-metadata.json`:

```json
{
"expectedCommitSha": "<new-sha-from-.commit-sha>",
"requiredClientMethods": [
"balance",
"get_admin",
"place_bet",
"... add/remove as needed ..."
],
"requiredExports": [
"Client",
"BetSide",
"RoundMode",
"... add/remove as needed ..."
]
}
```

**How to find the required methods:** Check `src/services/soroban.service.ts` for all `this.client.*` calls. Each method used there must be in `requiredClientMethods`.

**How to find the required exports:** Check all files that import from `@tevalabs/xelma-bindings` (including type imports). Each imported name must be in `requiredExports`.

### 4. Run tests

```bash
npm run test:unit -- --testPathPattern=bindings-validator
```

### 5. Commit

```bash
git add vendor/xelma-bindings/ .bindings-metadata.json
git commit -m "chore: upgrade xelma-bindings to <short-sha>"
```

## CI Failure Remediation

If the `bindings-drift` CI job fails:

1. Check the error message — it will say which methods/exports are missing or which SHA doesn't match
2. Run `npm run install-bindings` to fetch the latest bindings
3. If the ABI changed, update `.bindings-metadata.json` with the new SHA and surface
4. Run `node scripts/validate-bindings.js` locally to verify
5. Commit and push

## Environment Variables

| Variable | Purpose |
|---|---|
| `FAIL_ON_BINDINGS_MISMATCH` | Set to `true` to abort startup on version skew (recommended for production) |
| `NODE_ENV` | When `test`, node version check is skipped |
Loading
Loading