diff --git a/.envrc b/.envrc index a3693d2d5a..a93d020e9a 100644 --- a/.envrc +++ b/.envrc @@ -1,3 +1,4 @@ +# shellcheck shell=bash if ! has nix_direnv_version || ! nix_direnv_version 3.0.6; then URL=https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.6/direnvrc HASH=sha256-RYcUJaRMf8oF5LznDrlCXbkOQrywm0HDv1VjYGaJGdM= diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 1c550f7822..2d20522810 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,10 +1,13 @@ -> NOTE: Before using this guide, read the repository root `AGENTS.md` for authoritative agent instructions. +> NOTE: Before using this guide, read the repository root `AGENTS.md` for +> authoritative agent instructions. # Raindex – Agent Guide (Concise) -Always run commands via Nix: `nix develop -c `. Never cancel long-running tasks (45–90 min builds, 30+ min tests). +Always run commands via Nix: `nix develop -c `. Never cancel +long-running tasks (45–90 min builds, 30+ min tests). ## 1. Dependency readiness (quick check) + ```bash nix develop -c cargo build nix develop -c cargo build --target wasm32-unknown-unknown --lib -r --workspace \ @@ -17,34 +20,44 @@ nix develop -c npm run build:ui If any step fails due to earlier lint/test issues, use the fallback below. ## 2. Development loop + - Edit code - Rebuild dependencies you touched: - - Rust used by `@rainlanguage/raindex` → `nix develop -c npm run build:raindex` - - `@rainlanguage/ui-components` → `nix develop -c npm run build -w @rainlanguage/ui-components` + - Rust used by `@rainlanguage/raindex` → + `nix develop -c npm run build:raindex` + - `@rainlanguage/ui-components` → + `nix develop -c npm run build -w @rainlanguage/ui-components` - Run targeted tests and lints for changed areas ## Reference: tests and lints by area -| Area | Build (if needed) | Lint/Check | Tests | -|------|--------------------|------------|-------| -| Rust crates (`crates/*`) | `nix develop -c cargo build` | `nix develop -c cargo clippy --workspace --all-targets --all-features -D warnings` | `nix develop -c cargo test --workspace` or `--package ` | -| Raindex TS (`packages/raindex`) | `nix develop -c npm run build:raindex` | `nix develop -c npm run check -w @rainlanguage/raindex` | `nix develop -c npm run test -w @rainlanguage/raindex` | -| UI components (`packages/ui-components`) | `nix develop -c npm run build -w @rainlanguage/ui-components` | `nix develop -c npm run svelte-lint-format-check -w @rainlanguage/ui-components` | `nix develop -c npm run test -w @rainlanguage/ui-components` | -| Webapp (`packages/webapp`) | `nix develop -c npm run build -w @rainlanguage/webapp` | `nix develop -c npm run svelte-lint-format-check -w @rainlanguage/webapp` | `nix develop -c npm run test -w @rainlanguage/webapp` | -| Solidity contracts | `nix develop -c forge build` | — | `nix develop -c forge test` | +| Area | Build (if needed) | Lint/Check | Tests | +| ---------------------------------------- | ------------------------------------------------------------- | ---------------------------------------------------------------------------------- | -------------------------------------------------------------- | +| Rust crates (`crates/*`) | `nix develop -c cargo build` | `nix develop -c cargo clippy --workspace --all-targets --all-features -D warnings` | `nix develop -c cargo test --workspace` or `--package ` | +| Raindex TS (`packages/raindex`) | `nix develop -c npm run build:raindex` | `nix develop -c npm run check -w @rainlanguage/raindex` | `nix develop -c npm run test -w @rainlanguage/raindex` | +| UI components (`packages/ui-components`) | `nix develop -c npm run build -w @rainlanguage/ui-components` | `nix develop -c npm run svelte-lint-format-check -w @rainlanguage/ui-components` | `nix develop -c npm run test -w @rainlanguage/ui-components` | +| Webapp (`packages/webapp`) | `nix develop -c npm run build -w @rainlanguage/webapp` | `nix develop -c npm run svelte-lint-format-check -w @rainlanguage/webapp` | `nix develop -c npm run test -w @rainlanguage/webapp` | +| Solidity contracts | `nix develop -c forge build` | — | `nix develop -c forge test` | ## Frontend verification (required when frontend changes) -- If you modify frontend code or functionality affecting the frontend, you MUST provide a screenshot of the built webapp reflecting your change. +- If you modify frontend code or functionality affecting the frontend, you MUST + provide a screenshot of the built webapp reflecting your change. - Build and preview: + ```bash nix develop -c npm run build -w @rainlanguage/webapp nix develop -c npm run preview -w @rainlanguage/webapp ``` -- If you are unable to build the webapp, you MUST provide the concrete reasons and errors. Workarounds are not acceptable. + +- If you are unable to build the webapp, you MUST provide the concrete reasons + and errors. Workarounds are not acceptable. ## 3. End-of-session gate (comprehensive) -Partial commits are OK during the session. Before your final commit of the session, fully mirror CI: + +Partial commits are OK during the session. Before your final commit of the +session, fully mirror CI: + ```bash ./prep-all.sh nix develop -c npm run lint-format-check:all @@ -56,7 +69,9 @@ nix develop -c forge test ``` ## 4. Push gate (quick recheck) + Do a short verification right before pushing: + ```bash nix develop -c npm run lint-format-check:all nix develop -c npm run test @@ -64,7 +79,10 @@ nix develop -c cargo test --workspace ``` ## Fallback if end-of-session `./prep-all.sh` fails early -If the end-of-session gate fails during `./prep-all.sh`, run these steps sequentially so dependencies still build: + +If the end-of-session gate fails during `./prep-all.sh`, run these steps +sequentially so dependencies still build: + ```bash nix develop -c forge install nix develop -c bash -c '(cd lib/rain.interpreter && rainix-sol-prelude && rainix-rs-prelude && rainlang-prelude)' @@ -77,6 +95,5 @@ nix develop -c npm run build -w @rainlanguage/ui-components nix develop -c npm run build -w @rainlanguage/webapp ``` -Goal: all CI checks in `.github/workflows` pass. Be patient with long builds/tests and never commit with failing lint/tests. - - +Goal: all CI checks in `.github/workflows` pass. Be patient with long +builds/tests and never commit with failing lint/tests. diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index 3fd5061db4..f8307c5098 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -1,18 +1,15 @@ name: Copilot Agent Setup on: workflow_dispatch: - push: - paths: - - .github/workflows/copilot-setup-steps.yml - pull_request: - paths: - - .github/workflows/copilot-setup-steps.yml jobs: copilot-setup-steps: permissions: id-token: write contents: read runs-on: ubuntu-latest + env: + PUBLIC_WALLETCONNECT_PROJECT_ID: ${{ secrets.WALLETCONNECT_PROJECT_ID || 'test' }} + COMMIT_SHA: ${{ github.sha }} steps: - uses: actions/checkout@v4 - uses: nixbuild/nix-quick-install-action@v30 @@ -20,23 +17,46 @@ jobs: nix_conf: | keep-env-derivations = true keep-outputs = true + - uses: cachix/cachix-action@v15 + continue-on-error: true + with: + name: rainlanguage + authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} + useDaemon: false - name: Restore and save Nix store - uses: nix-community/cache-nix-action@v6 + uses: nix-community/cache-nix-action@v7 with: primary-key: nix-${{ runner.os }}-${{ hashFiles('**/*.nix', '**/flake.lock') }} restore-prefixes-first-match: nix-${{ runner.os }}- gc-max-store-size-linux: 1G + - uses: Swatinem/rust-cache@v2 + with: + prefix-key: rust-${{ github.workflow }} + - name: Cache npm + uses: actions/cache@v4 + with: + path: ~/.npm + key: npm-${{ runner.os }}-${{ github.workflow }}-${{ hashFiles('**/package-lock.json') }} + restore-keys: npm-${{ runner.os }}- - name: Prepare environment files run: | set -euxo pipefail cp -f .env.example .env cp -f packages/webapp/.env.example packages/webapp/.env cp -f .env.example crates/common/.env - - name: Prepare repository dependencies - run: ./prep-all.sh - env: - PUBLIC_WALLETCONNECT_PROJECT_ID: ${{ secrets.WALLETCONNECT_PROJECT_ID || 'test' }} - COMMIT_SHA: ${{ github.sha }} + # Inlined bootstrap (formerly ./prep-all.sh). All committed ABIs + + # vendored IMulticall3.sol mean cargo doesn't need forge build / + # soldeer install — forge is still on PATH in .#sol-shell if copilot + # needs it later. + - run: | + nix develop .#wasm-shell -c bash -c ' + set -euxo pipefail + npm install --no-check + (cd packages/ui-components && npm i && npm run lint) + npm run build -w @rainlanguage/raindex + npm run build -w @rainlanguage/ui-components + npm run build -w @rainlanguage/webapp + ' # forwards status to telegram chat if this ci fails or gets canceled, only runs for default branch - name: Forward CI Status if: always() diff --git a/.github/workflows/deploy-subgraph.yaml b/.github/workflows/deploy-subgraph.yaml index c10c03d10f..71a8ac5a76 100644 --- a/.github/workflows/deploy-subgraph.yaml +++ b/.github/workflows/deploy-subgraph.yaml @@ -19,6 +19,12 @@ jobs: nix_conf: | keep-env-derivations = true keep-outputs = true + - uses: cachix/cachix-action@v15 + continue-on-error: true + with: + name: rainlanguage + authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} + useDaemon: false - name: Restore and save Nix store uses: nix-community/cache-nix-action@v6 with: diff --git a/.github/workflows/manual-rs-release.yml b/.github/workflows/manual-rs-release.yml index 99e0a586d8..8e40e121ec 100644 --- a/.github/workflows/manual-rs-release.yml +++ b/.github/workflows/manual-rs-release.yml @@ -13,6 +13,12 @@ jobs: nix_conf: | keep-env-derivations = true keep-outputs = true + - uses: cachix/cachix-action@v15 + continue-on-error: true + with: + name: rainlanguage + authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} + useDaemon: false - name: Restore and save Nix store uses: nix-community/cache-nix-action@v6 with: @@ -24,7 +30,7 @@ jobs: # before trying to save a new cache # 1G = 1073741824 gc-max-store-size-linux: 1G - - run: nix develop --command cargo release --workspace + - run: nix develop .#rust-shell --command cargo release --workspace # forwards status to telegram chat if this ci fails or gets canceled, only runs for default branch - name: Forward CI Status if: always() diff --git a/.github/workflows/npm-package-release.yml b/.github/workflows/npm-package-release.yml index 9cb7d62ab5..23324f0932 100644 --- a/.github/workflows/npm-package-release.yml +++ b/.github/workflows/npm-package-release.yml @@ -37,11 +37,35 @@ jobs: with: swap-storage: false # install nix for building WASM artifacts and running tests - - uses: DeterminateSystems/nix-installer-action@main + - uses: nixbuild/nix-quick-install-action@v30 with: - determinate: true - # cache nix store to speed up subsequent builds - - uses: DeterminateSystems/flakehub-cache-action@main + nix_conf: | + keep-env-derivations = true + keep-outputs = true + # pull rainix derivations from shared Cachix; push new ones if the + # token is set. continue-on-error so a token miss / Cachix outage + # degrades gracefully. + - uses: cachix/cachix-action@v15 + continue-on-error: true + with: + name: rainlanguage + authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} + useDaemon: false + - name: Restore and save Nix store + uses: nix-community/cache-nix-action@v7 + with: + primary-key: nix-${{ runner.os }}-${{ hashFiles('**/*.nix', '**/flake.lock') }} + restore-prefixes-first-match: nix-${{ runner.os }}- + gc-max-store-size-linux: 8G + - uses: Swatinem/rust-cache@v2 + with: + prefix-key: rust-${{ github.workflow }} + - name: Cache npm + uses: actions/cache@v4 + with: + path: ~/.npm + key: npm-${{ runner.os }}-${{ github.workflow }}-${{ hashFiles('**/package-lock.json') }} + restore-keys: npm-${{ runner.os }}- # setup node with npm registry for OIDC-based publishing (no NPM_TOKEN needed) - name: Setup Node.js uses: actions/setup-node@v4 @@ -86,11 +110,11 @@ jobs: exit 1 fi echo "Repositories match" - # install dependencies and build the workspace - - run: ./prep-base.sh - # remove debug artifacts to free disk space before WASM build - - name: Remove Unused Artifacts - run: rm -rf ./target/debug + # forge install + build is no longer needed here — all sol! macros + # read committed ABIs under crates/*/abis/, and the wasm + npm builds + # below don't shell out to forge. The prior "Remove Unused Artifacts" + # / debug-dir scrubs went with forge; rust-cache + free-disk-space@v1 + # handle disk budget for the remaining WASM builds. # WASM linker can run out of memory on GitHub runners; add swap to prevent OOM - name: Add swap space run: | @@ -104,20 +128,23 @@ jobs: sudo swapon /swapfile # build and test WASM bindings - name: Test JS/TS Binding 1/2 - run: nix develop -c rainix-wasm-test - # cleanup between test phases to prevent disk space exhaustion - - name: Remove Test Artifacts run: | - rm -rf ./target/debug - rm -rf ./target/wasm32-unknown-unknown/debug + nix develop .#wasm-shell -c bash -c "CARGO_TARGET_WASM32_UNKNOWN_UNKNOWN_RUNNER=wasm-bindgen-test-runner cargo test --target wasm32-unknown-unknown --lib -p raindex_quote -p raindex_bindings -p raindex_js_api -p raindex_common" # run JS/TS integration tests against WASM bindings - name: Test JS/TS Binding 2/2 - run: nix develop -c test-js-bindings + run: | + nix develop .#wasm-shell -c bash -c ' + set -euxo pipefail + npm install --no-check + cd packages/raindex + npm run build + npm test + ' # build and test UI components before publishing - name: Build UI Components - run: nix develop -c npm run build -w @rainlanguage/ui-components + run: nix develop .#wasm-shell -c npm run build -w @rainlanguage/ui-components - name: Test UI Components - run: nix develop -c npm run test -w @rainlanguage/ui-components + run: nix develop .#wasm-shell -c npm run test -w @rainlanguage/ui-components # check for npm package blacklists pkgs across all raindex related packages - uses: rainlanguage/github-chore/.github/actions/npm-blacklist@main - uses: rainlanguage/github-chore/.github/actions/npm-blacklist@main diff --git a/.github/workflows/pr-assessment.yaml b/.github/workflows/pr-assessment.yaml index cbb8f2fb95..18e484f449 100644 --- a/.github/workflows/pr-assessment.yaml +++ b/.github/workflows/pr-assessment.yaml @@ -3,12 +3,11 @@ on: pull_request: types: - closed - jobs: assess-pr-size-on-merge: - uses: rainlanguage/github-chore/.github/workflows/pr-assessment.yml@main - with: - pr_number: ${{ github.event.pull_request.number }} - repo: ${{ github.event.repository.name }} - owner: ${{ github.repository_owner }} - merged: ${{ github.event.pull_request.merged }} + uses: rainlanguage/github-chore/.github/workflows/pr-assessment.yml@main + with: + pr_number: ${{ github.event.pull_request.number }} + repo: ${{ github.event.repository.name }} + owner: ${{ github.repository_owner }} + merged: ${{ github.event.pull_request.merged }} diff --git a/.github/workflows/rainix.yaml b/.github/workflows/rainix.yaml deleted file mode 100644 index 3234670a1f..0000000000 --- a/.github/workflows/rainix.yaml +++ /dev/null @@ -1,78 +0,0 @@ -name: Rainix CI -on: - push: - branches: - - main - pull_request: -concurrency: - group: ${{ github.ref }}-rainix - cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} -jobs: - # Rust / wasm / JS bindings run on raindex's own devshell: they need sqlite3 - # (rusqlite) and the forge-build artifacts, which the slim rainix rs reusables - # don't provide. Solidity + artifact checks live in rainix-sol.yaml and - # copy-artifacts.yaml (rainix reusables). - standard-tests: - permissions: - id-token: write - contents: read - strategy: - matrix: - os: [ubuntu-latest, macos-latest] - task: [raindex-rs-test, "cargo build --release"] - is-not-main: - - ${{ github.ref != 'refs/heads/main' }} - include: - # We don't need to do rust static analysis on multiple platforms - - os: ubuntu-latest - task: rainix-rs-static - # Wasm target doesnt need to run on multiple platforms - - os: ubuntu-latest - task: rainix-wasm-artifacts - - os: ubuntu-latest - task: rainix-wasm-test - - os: ubuntu-latest - task: rainix-wasm-browser-test - # Testing JS/TS bindings doesnt need to run on multiple platforms - - os: ubuntu-latest - task: test-js-bindings - exclude: - - is-not-main: true - os: macos-latest - fail-fast: false - runs-on: ${{ matrix.os }} - env: - COMMIT_SHA: ${{ github.sha }} - steps: - - uses: actions/checkout@v4 - - name: Free disk space - if: matrix.os == 'ubuntu-latest' - uses: jlumbroso/free-disk-space@v1.3.1 - with: - large-packages: ${{ matrix.task != 'rainix-wasm-browser-test' }} - - uses: nixbuild/nix-quick-install-action@v30 - with: - nix_conf: | - keep-env-derivations = true - keep-outputs = true - - name: Restore and save Nix store - uses: nix-community/cache-nix-action@v6 - with: - # restore and save a cache using this key - primary-key: nix-${{ runner.os }}-${{ hashFiles('**/*.nix', '**/flake.lock') }} - # if there's no cache hit, restore a cache by this prefix - restore-prefixes-first-match: nix-${{ runner.os }}- - # collect garbage until the Nix store size is at most this number - # before trying to save a new cache - gc-max-store-size-linux: 10G - - run: ./pointers.sh - - name: Run ${{ matrix.task }} - run: nix develop -c ${{ matrix.task }} - # forwards status to telegram chat if this ci fails or gets canceled, only runs for default branch - - name: Forward CI Status - if: always() - uses: rainlanguage/github-chore/.github/actions/telegram-status-report@main - with: - status: ${{ job.status }} - telegram-bot-token: ${{ secrets.TELEGRAM_BOT_TOKEN }} - telegram-chat-id: ${{ secrets.TELEGRAM_CHAT_ID }} diff --git a/.github/workflows/rs-static.yaml b/.github/workflows/rs-static.yaml new file mode 100644 index 0000000000..41bd02156d --- /dev/null +++ b/.github/workflows/rs-static.yaml @@ -0,0 +1,6 @@ +name: rs-static +on: [push] +jobs: + rs-static: + uses: rainlanguage/rainix/.github/workflows/rainix-rs-static.yaml@main + secrets: inherit diff --git a/.github/workflows/rs-test.yaml b/.github/workflows/rs-test.yaml new file mode 100644 index 0000000000..b033a8b3dc --- /dev/null +++ b/.github/workflows/rs-test.yaml @@ -0,0 +1,6 @@ +name: rs-test +on: [push] +jobs: + rs-test: + uses: rainlanguage/rainix/.github/workflows/rainix-rs-test.yaml@main + secrets: inherit diff --git a/.github/workflows/test-js-bindings.yaml b/.github/workflows/test-js-bindings.yaml new file mode 100644 index 0000000000..21e254cefc --- /dev/null +++ b/.github/workflows/test-js-bindings.yaml @@ -0,0 +1,48 @@ +name: test-js-bindings +on: [push] +jobs: + test-js-bindings: + runs-on: ubuntu-latest + env: + COMMIT_SHA: ${{ github.sha }} + steps: + - uses: actions/checkout@v4 + - name: Free disk space + uses: jlumbroso/free-disk-space@v1.3.1 + - uses: nixbuild/nix-quick-install-action@v30 + with: + nix_conf: | + keep-env-derivations = true + keep-outputs = true + - uses: cachix/cachix-action@v15 + continue-on-error: true + with: + name: rainlanguage + authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} + useDaemon: false + - name: Restore and save Nix store + uses: nix-community/cache-nix-action@v7 + with: + primary-key: nix-${{ runner.os }}-${{ hashFiles('**/*.nix', '**/flake.lock') }} + restore-prefixes-first-match: nix-${{ runner.os }}- + gc-max-store-size-linux: 8G + - uses: Swatinem/rust-cache@v2 + with: + prefix-key: rust-${{ github.workflow }} + - name: Cache npm + uses: actions/cache@v4 + with: + path: ~/.npm + key: npm-${{ runner.os }}-${{ github.workflow }}-${{ hashFiles('**/package-lock.json') }} + restore-keys: npm-${{ runner.os }}- + # npm install MUST run from the workspace root (not packages/raindex) + # so npm picks up the workspaces resolution. Default devshell's shellHook + # does this on entry — slim #wasm-shell doesn't, so we do it explicitly. + - run: | + nix develop .#wasm-shell -c bash -c ' + set -euxo pipefail + npm install --no-check + cd packages/raindex + npm run build + npm test + ' diff --git a/.github/workflows/test-subgraph.yml b/.github/workflows/test-subgraph.yml index c832d090c4..2064b5fa99 100644 --- a/.github/workflows/test-subgraph.yml +++ b/.github/workflows/test-subgraph.yml @@ -1,50 +1,6 @@ name: Subgraph unit tests -on: - push: - branches: - - main - pull_request: -concurrency: - group: ${{ github.ref }}-subgraph - cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} +on: [push] jobs: - test: - permissions: - id-token: write - contents: read - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - name: Free disk space - uses: jlumbroso/free-disk-space@v1.3.1 - - uses: nixbuild/nix-quick-install-action@v30 - with: - nix_conf: | - keep-env-derivations = true - keep-outputs = true - - name: Restore and save Nix store - uses: nix-community/cache-nix-action@v6 - with: - # restore and save a cache using this key - primary-key: nix-${{ runner.os }}-${{ hashFiles('**/*.nix', '**/flake.lock') }} - # if there's no cache hit, restore a cache by this prefix - restore-prefixes-first-match: nix-${{ runner.os }}- - # collect garbage until the Nix store size (in bytes) is at most this number - # before trying to save a new cache - # 1G = 1073741824 - gc-max-store-size-linux: 1G - - name: Install Soldeer dependencies - run: nix develop -c forge soldeer install - - name: Build subgraph - run: nix develop -c subgraph-build - - name: Matchstick tests - run: nix develop -c subgraph-test - # forwards status to telegram chat if this ci fails or gets canceled, only runs for default branch - - name: Forward CI Status - if: always() - uses: rainlanguage/github-chore/.github/actions/telegram-status-report@main - with: - status: ${{ job.status }} - telegram-bot-token: ${{ secrets.TELEGRAM_BOT_TOKEN }} - telegram-chat-id: ${{ secrets.TELEGRAM_CHAT_ID }} + subgraph-test: + uses: rainlanguage/rainix/.github/workflows/rainix-subgraph-test.yaml@main + secrets: inherit diff --git a/.github/workflows/test-ui-components.yaml b/.github/workflows/test-ui-components.yaml index 296fa79695..10127203ea 100644 --- a/.github/workflows/test-ui-components.yaml +++ b/.github/workflows/test-ui-components.yaml @@ -24,6 +24,12 @@ jobs: nix_conf: | keep-env-derivations = true keep-outputs = true + - uses: cachix/cachix-action@v15 + continue-on-error: true + with: + name: rainlanguage + authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} + useDaemon: false - name: Restore and save Nix store uses: nix-community/cache-nix-action@v6 with: @@ -35,16 +41,19 @@ jobs: # before trying to save a new cache # 1G = 1073741824 gc-max-store-size-linux: 10G - - run: ./prep-webapp.sh + - run: | + nix develop .#wasm-shell -c bash -c ' + set -euxo pipefail + npm install --no-check + npm run build -w @rainlanguage/raindex + npm run build -w @rainlanguage/ui-components + npm run build -w @rainlanguage/webapp + ' env: PUBLIC_WALLETCONNECT_PROJECT_ID: ${{ secrets.WALLETCONNECT_PROJECT_ID || 'test' }} COMMIT_SHA: ${{ github.sha }} - CARGO_HOME: ${{ github.workspace }}/.cargo - CARGO_TARGET_DIR: ${{ github.workspace }}/.cargo/target - - name: Cleanup Rust artifacts after prep - run: rm -rf target || true - - run: nix develop -c npm run svelte-lint-format-check -w @rainlanguage/ui-components - - run: nix develop -c npm run test -w @rainlanguage/ui-components + - run: nix develop .#wasm-shell -c npm run svelte-lint-format-check -w @rainlanguage/ui-components + - run: nix develop .#wasm-shell -c npm run test -w @rainlanguage/ui-components # check for npm package blacklists pkgs across all packages - uses: rainlanguage/github-chore/.github/actions/npm-blacklist@main - uses: rainlanguage/github-chore/.github/actions/npm-blacklist@main diff --git a/.github/workflows/test-webapp.yaml b/.github/workflows/test-webapp.yaml index 35e4c8b3c1..5e6e088fdf 100644 --- a/.github/workflows/test-webapp.yaml +++ b/.github/workflows/test-webapp.yaml @@ -24,6 +24,12 @@ jobs: nix_conf: | keep-env-derivations = true keep-outputs = true + - uses: cachix/cachix-action@v15 + continue-on-error: true + with: + name: rainlanguage + authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} + useDaemon: false - name: Restore and save Nix store uses: nix-community/cache-nix-action@v6 with: @@ -35,18 +41,21 @@ jobs: # before trying to save a new cache # 1G = 1073741824 gc-max-store-size-linux: 10G - - run: ./prep-webapp.sh + - run: | + nix develop .#wasm-shell -c bash -c ' + set -euxo pipefail + npm install --no-check + npm run build -w @rainlanguage/raindex + npm run build -w @rainlanguage/ui-components + npm run build -w @rainlanguage/webapp + ' env: PUBLIC_WALLETCONNECT_PROJECT_ID: ${{ secrets.WALLETCONNECT_PROJECT_ID || 'test' }} COMMIT_SHA: ${{ github.sha }} - CARGO_HOME: ${{ github.workspace }}/.cargo - CARGO_TARGET_DIR: ${{ github.workspace }}/.cargo/target - - name: Cleanup Rust artifacts after prep - run: rm -rf target || true - - run: nix develop -c npm run svelte-lint-format-check -w @rainlanguage/webapp + - run: nix develop .#wasm-shell -c npm run svelte-lint-format-check -w @rainlanguage/webapp env: PUBLIC_WALLETCONNECT_PROJECT_ID: ${{ secrets.WALLETCONNECT_PROJECT_ID || 'test' }} - - run: nix develop -c npm run test -w @rainlanguage/webapp + - run: nix develop .#wasm-shell -c npm run test -w @rainlanguage/webapp env: PUBLIC_WALLETCONNECT_PROJECT_ID: ${{ secrets.WALLETCONNECT_PROJECT_ID || 'test' }} # check for npm package blacklists pkgs across all packages diff --git a/.github/workflows/vercel-docs-preview.yaml b/.github/workflows/vercel-docs-preview.yaml index ce53233d8c..2f957f0f08 100644 --- a/.github/workflows/vercel-docs-preview.yaml +++ b/.github/workflows/vercel-docs-preview.yaml @@ -21,15 +21,44 @@ jobs: - uses: actions/checkout@v4 - name: Free disk space uses: jlumbroso/free-disk-space@v1.3.1 - - uses: DeterminateSystems/nix-installer-action@main + - uses: nixbuild/nix-quick-install-action@v30 with: - determinate: true - - uses: DeterminateSystems/flakehub-cache-action@main - - run: ./prep-all.sh - env: - PUBLIC_WALLETCONNECT_PROJECT_ID: ${{ secrets.WALLETCONNECT_PROJECT_ID }} - - run: nix develop .#webapp-shell -c npm run docs - working-directory: packages/raindex + nix_conf: | + keep-env-derivations = true + keep-outputs = true + - uses: cachix/cachix-action@v15 + continue-on-error: true + with: + name: rainlanguage + authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} + useDaemon: false + - name: Restore and save Nix store + uses: nix-community/cache-nix-action@v7 + with: + primary-key: nix-${{ runner.os }}-${{ hashFiles('**/*.nix', '**/flake.lock') }} + restore-prefixes-first-match: nix-${{ runner.os }}- + gc-max-store-size-linux: 8G + - uses: Swatinem/rust-cache@v2 + with: + prefix-key: rust-${{ github.workflow }} + - name: Cache npm + uses: actions/cache@v4 + with: + path: ~/.npm + key: npm-${{ runner.os }}-${{ github.workflow }}-${{ hashFiles('**/package-lock.json') }} + restore-keys: npm-${{ runner.os }}- + # Slim docs build: workspace-root npm install (for npm workspaces + # resolution) then build the raindex wasm package and run typedoc. + # Replaces ./prep-all.sh which also did forge install + forge build + + # raindex-prelude + raindex-cli build (none of that is read by typedoc). + - run: | + nix develop .#wasm-shell -c bash -c ' + set -euxo pipefail + npm install --no-check + cd packages/raindex + npm run build + npm run docs + ' - name: Prepare Vercel build output run: | OUTPUT_DIR="packages/raindex/.vercel/output" @@ -37,7 +66,7 @@ jobs: cp -r packages/raindex/docs/* "${OUTPUT_DIR}/static/" echo '{ "version": 3 }' > "${OUTPUT_DIR}/config.json" - name: Install Vercel CLI - run: npm install --global vercel@canary + run: npm install --global vercel@latest - name: Pull Vercel Environment Information run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }} - name: Deploy Project Artifacts to Vercel diff --git a/.github/workflows/vercel-docs-prod.yaml b/.github/workflows/vercel-docs-prod.yaml index 6138c26b47..3130c08668 100644 --- a/.github/workflows/vercel-docs-prod.yaml +++ b/.github/workflows/vercel-docs-prod.yaml @@ -16,15 +16,42 @@ jobs: COMMIT_SHA: ${{ github.sha }} steps: - uses: actions/checkout@v4 - - uses: DeterminateSystems/nix-installer-action@main + - name: Free disk space + uses: jlumbroso/free-disk-space@v1.3.1 + - uses: nixbuild/nix-quick-install-action@v30 with: - determinate: true - - uses: DeterminateSystems/flakehub-cache-action@main - - run: ./prep-all.sh - env: - PUBLIC_WALLETCONNECT_PROJECT_ID: ${{ secrets.WALLETCONNECT_PROJECT_ID }} - - run: nix develop .#webapp-shell -c npm run docs - working-directory: packages/raindex + nix_conf: | + keep-env-derivations = true + keep-outputs = true + - uses: cachix/cachix-action@v15 + continue-on-error: true + with: + name: rainlanguage + authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} + useDaemon: false + - name: Restore and save Nix store + uses: nix-community/cache-nix-action@v7 + with: + primary-key: nix-${{ runner.os }}-${{ hashFiles('**/*.nix', '**/flake.lock') }} + restore-prefixes-first-match: nix-${{ runner.os }}- + gc-max-store-size-linux: 8G + - uses: Swatinem/rust-cache@v2 + with: + prefix-key: rust-${{ github.workflow }} + - name: Cache npm + uses: actions/cache@v4 + with: + path: ~/.npm + key: npm-${{ runner.os }}-${{ github.workflow }}-${{ hashFiles('**/package-lock.json') }} + restore-keys: npm-${{ runner.os }}- + - run: | + nix develop .#wasm-shell -c bash -c ' + set -euxo pipefail + npm install --no-check + cd packages/raindex + npm run build + npm run docs + ' - name: Prepare Vercel build output run: | OUTPUT_DIR="packages/raindex/.vercel/output" @@ -32,7 +59,7 @@ jobs: cp -r packages/raindex/docs/* "${OUTPUT_DIR}/static/" echo '{ "version": 3 }' > "${OUTPUT_DIR}/config.json" - name: Install Vercel CLI - run: npm install --global vercel@canary + run: npm install --global vercel@latest - name: Pull Vercel Environment Information run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }} - name: Deploy Project Artifacts to Vercel diff --git a/.github/workflows/vercel-preview.yaml b/.github/workflows/vercel-preview.yaml index 12f6c91ca1..0fba08605d 100644 --- a/.github/workflows/vercel-preview.yaml +++ b/.github/workflows/vercel-preview.yaml @@ -40,6 +40,12 @@ jobs: nix_conf: | keep-env-derivations = true keep-outputs = true + - uses: cachix/cachix-action@v15 + continue-on-error: true + with: + name: rainlanguage + authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} + useDaemon: false - name: Restore and save Nix store uses: nix-community/cache-nix-action@v6 with: @@ -51,7 +57,14 @@ jobs: # before trying to save a new cache # 1G = 1073741824 gc-max-store-size-linux: 1G - - run: ./prep-webapp.sh + - run: | + nix develop .#wasm-shell -c bash -c ' + set -euxo pipefail + npm install --no-check + npm run build -w @rainlanguage/raindex + npm run build -w @rainlanguage/ui-components + npm run build -w @rainlanguage/webapp + ' env: PUBLIC_WALLETCONNECT_PROJECT_ID: ${{ secrets.WALLETCONNECT_PROJECT_ID }} - run: nix develop .#webapp-shell -c npm run build diff --git a/.github/workflows/vercel-prod.yaml b/.github/workflows/vercel-prod.yaml index 06b20d921f..1b7a736056 100644 --- a/.github/workflows/vercel-prod.yaml +++ b/.github/workflows/vercel-prod.yaml @@ -23,6 +23,12 @@ jobs: nix_conf: | keep-env-derivations = true keep-outputs = true + - uses: cachix/cachix-action@v15 + continue-on-error: true + with: + name: rainlanguage + authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} + useDaemon: false - name: Restore and save Nix store uses: nix-community/cache-nix-action@v6 with: @@ -34,7 +40,14 @@ jobs: # before trying to save a new cache # 1G = 1073741824 gc-max-store-size-linux: 1G - - run: ./prep-webapp.sh + - run: | + nix develop .#wasm-shell -c bash -c ' + set -euxo pipefail + npm install --no-check + npm run build -w @rainlanguage/raindex + npm run build -w @rainlanguage/ui-components + npm run build -w @rainlanguage/webapp + ' env: PUBLIC_WALLETCONNECT_PROJECT_ID: ${{ secrets.WALLETCONNECT_PROJECT_ID }} - run: nix develop .#webapp-shell -c npm run build diff --git a/.github/workflows/wasm-artifacts.yaml b/.github/workflows/wasm-artifacts.yaml new file mode 100644 index 0000000000..b2a934fa01 --- /dev/null +++ b/.github/workflows/wasm-artifacts.yaml @@ -0,0 +1,32 @@ +name: wasm-artifacts +on: [push] +jobs: + wasm-artifacts: + runs-on: ubuntu-latest + env: + COMMIT_SHA: ${{ github.sha }} + steps: + - uses: actions/checkout@v4 + - name: Free disk space + uses: jlumbroso/free-disk-space@v1.3.1 + - uses: nixbuild/nix-quick-install-action@v30 + with: + nix_conf: | + keep-env-derivations = true + keep-outputs = true + - uses: cachix/cachix-action@v15 + continue-on-error: true + with: + name: rainlanguage + authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} + useDaemon: false + - name: Restore and save Nix store + uses: nix-community/cache-nix-action@v7 + with: + primary-key: nix-${{ runner.os }}-${{ hashFiles('**/*.nix', '**/flake.lock') }} + restore-prefixes-first-match: nix-${{ runner.os }}- + gc-max-store-size-linux: 8G + - uses: Swatinem/rust-cache@v2 + with: + prefix-key: rust-${{ github.workflow }} + - run: nix develop .#wasm-shell -c cargo build --profile release-wasm --target wasm32-unknown-unknown --lib -p raindex_js_api diff --git a/.github/workflows/wasm-browser-test.yaml b/.github/workflows/wasm-browser-test.yaml new file mode 100644 index 0000000000..e09bc8895c --- /dev/null +++ b/.github/workflows/wasm-browser-test.yaml @@ -0,0 +1,43 @@ +name: wasm-browser-test +on: [push] +jobs: + wasm-browser-test: + runs-on: ubuntu-latest + env: + COMMIT_SHA: ${{ github.sha }} + steps: + - uses: actions/checkout@v4 + - name: Free disk space + uses: jlumbroso/free-disk-space@v1.3.1 + with: + # Keep chromium — wasm-pack test --headless --chrome needs it. + large-packages: false + - uses: nixbuild/nix-quick-install-action@v30 + with: + nix_conf: | + keep-env-derivations = true + keep-outputs = true + - uses: cachix/cachix-action@v15 + continue-on-error: true + with: + name: rainlanguage + authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} + useDaemon: false + - name: Restore and save Nix store + uses: nix-community/cache-nix-action@v7 + with: + primary-key: nix-${{ runner.os }}-${{ hashFiles('**/*.nix', '**/flake.lock') }} + restore-prefixes-first-match: nix-${{ runner.os }}- + gc-max-store-size-linux: 8G + - uses: Swatinem/rust-cache@v2 + with: + prefix-key: rust-${{ github.workflow }} + - run: | + nix develop .#wasm-shell -c bash -c ' + cd crates/common + wasm-pack test --headless --chrome --features browser-tests -- leadership::wasm_tests + wasm-pack test --headless --chrome --features browser-tests -- scheduler::wasm::wasm_tests + wasm-pack test --headless --chrome --features browser-tests -- status::wasm::wasm_tests + wasm-pack test --headless --chrome --features browser-tests -- retry::wasm_tests + wasm-pack test --headless --chrome --features browser-tests -- raindex_client::local_db::wasm_tests + ' diff --git a/.github/workflows/wasm-test.yaml b/.github/workflows/wasm-test.yaml new file mode 100644 index 0000000000..1fd8526a31 --- /dev/null +++ b/.github/workflows/wasm-test.yaml @@ -0,0 +1,32 @@ +name: wasm-test +on: [push] +jobs: + wasm-test: + runs-on: ubuntu-latest + env: + COMMIT_SHA: ${{ github.sha }} + steps: + - uses: actions/checkout@v4 + - name: Free disk space + uses: jlumbroso/free-disk-space@v1.3.1 + - uses: nixbuild/nix-quick-install-action@v30 + with: + nix_conf: | + keep-env-derivations = true + keep-outputs = true + - uses: cachix/cachix-action@v15 + continue-on-error: true + with: + name: rainlanguage + authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} + useDaemon: false + - name: Restore and save Nix store + uses: nix-community/cache-nix-action@v7 + with: + primary-key: nix-${{ runner.os }}-${{ hashFiles('**/*.nix', '**/flake.lock') }} + restore-prefixes-first-match: nix-${{ runner.os }}- + gc-max-store-size-linux: 8G + - uses: Swatinem/rust-cache@v2 + with: + prefix-key: rust-${{ github.workflow }} + - run: nix develop .#wasm-shell -c bash -c "CARGO_TARGET_WASM32_UNKNOWN_UNKNOWN_RUNNER=wasm-bindgen-test-runner cargo test --target wasm32-unknown-unknown --lib -p raindex_quote -p raindex_bindings -p raindex_js_api -p raindex_common" diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000000..86367cc9da --- /dev/null +++ b/.prettierignore @@ -0,0 +1,4 @@ +# Forge-emitted ABIs are copied verbatim by script/build-subgraph.sh; keeping +# them raw means rainix-copy-artifacts' regen + `git diff --exit-code` gate +# matches what forge build produces. +subgraph/abis/ diff --git a/AGENTS.md b/AGENTS.md index 99c8dffad8..ba9a798d9c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,36 +1,122 @@ # Repository Guidelines ## Project Structure & Module Organization -- Solidity contracts: `src/`, tests in `test/` with fixtures in `test-resources/`. -- Rust workspace: `crates/*` (e.g., `cli`, `common`, `bindings`, `js_api`, `quote`, `subgraph`, `settings`, `math`, `integration_tests`). -- JavaScript/Svelte: `packages/*` — `webapp`, `ui-components`, `raindex` (wasm wrapper published to npm). -- Subgraph and tooling: `subgraph/`, `script/`, helper scripts like `prep-all.sh`. + +- Solidity contracts: `src/`, tests in `test/` with fixtures in + `test-resources/`. +- Rust workspace: `crates/*` (e.g., `cli`, `common`, `bindings`, `js_api`, + `quote`, `subgraph`, `settings`, `math`, `integration_tests`). +- JavaScript/Svelte: `packages/*` — `webapp`, `ui-components`, `raindex` (wasm + wrapper published to npm). +- Subgraph and tooling: `subgraph/`, `script/`. ## Build, Test, and Development Commands -- Bootstrap: `./prep-all.sh` (installs deps and builds workspaces). + +- Bootstrap: + `nix develop -c forge soldeer install && nix develop -c forge build && nix develop -c raindex-ui-components-prelude && nix develop -c npm run build -w @rainlanguage/raindex && nix develop -c npm run build -w @rainlanguage/ui-components && nix develop -c npm run build -w @rainlanguage/webapp` + (installs deps and builds workspaces; see README for the multi-line form). - Rust: `cargo build --workspace`; tests: `cargo test`. - Solidity (Foundry): `forge build`; tests: `forge test`. - Webapp: `cd packages/webapp && npm run dev`. -- JS workspaces (top-level): `npm run test`, `npm run build:ui`, `npm run build:raindex`. +- JS workspaces (top-level): `npm run test`, `npm run build:ui`, + `npm run build:raindex`. - WASM bundle: `rainix-wasm-artifacts`. ## Coding Style & Naming Conventions -- Rust: format with `cargo fmt --all`; lint with `rainix-rs-static` (preconfigured flags included). Crates/modules use `snake_case`; types `PascalCase`. -- TS/Svelte: `npm run format`, `npm run lint`, `npm run check` in each package. Components `PascalCase.svelte`; files otherwise kebab/snake as appropriate. + +- Rust: format with `cargo fmt --all`; lint with `rainix-rs-static` + (preconfigured flags included). Crates/modules use `snake_case`; types + `PascalCase`. +- TS/Svelte: `npm run format`, `npm run lint`, `npm run check` in each package. + Components `PascalCase.svelte`; files otherwise kebab/snake as appropriate. - Solidity: `forge fmt`; compiler `solc 0.8.25` (see `foundry.toml`). ## Testing Guidelines -- Rust: `cargo test`; integration tests live in `crates/integration_tests`. Prefer `insta` snapshots and `proptest` where helpful. + +- Rust: `cargo test`; integration tests live in `crates/integration_tests`. + Prefer `insta` snapshots and `proptest` where helpful. - TS/Svelte: `npm run test` (Vitest). Name files `*.test.ts`/`*.spec.ts`. - Solidity: `forge test` (add fuzz/property tests where relevant). ## Commit & Pull Request Guidelines -- PRs must: describe scope/approach, link issues, include screenshots/GIFs for UI changes, update/ add tests, and pass CI. + +- PRs must: describe scope/approach, link issues, include screenshots/GIFs for + UI changes, update/ add tests, and pass CI. - Quick preflight: `npm run lint-format-check:all && rainix-rs-static`. ## Security & Configuration Tips -- Never commit secrets. Copy `.env.example` files (root, `packages/webapp`) and populate `PUBLIC_WALLETCONNECT_PROJECT_ID` as required. + +- Never commit secrets. Copy `.env.example` files (root, `packages/webapp`) and + populate `PUBLIC_WALLETCONNECT_PROJECT_ID` as required. + +## CI & Workflow Conventions + +GitHub Actions workflows in `.github/workflows/` follow a consistent shape. New +work should match. + +### Slim shells over default devshell + +- Use `nix develop .#wasm-shell` for rust+node work (cargo wasm build, npm + workspace builds, vitest, typedoc), and `.#subgraph-shell` for graph CLI work. + Both are local re-exports of `rainix`'s slim shells via `flake.nix`, so they + pin to the `flake.lock` rainix rev rather than the live + `github:rainlanguage/rainix#...` reference (which tracks rainix `main` and + bypasses `flake.lock`). +- Default `nix develop -c` enters the heavy full devshell — only use when you + legitimately need the full toolchain (e.g., `copilot-setup-steps`). +- `npm install --no-check` MUST run from the **workspace root** (not + `packages/`) for npm workspaces resolution. Default devshell's shellHook + does this on shell entry; slim shells don't, so do it explicitly as the first + command inside the `bash -c '...'`. + +### Nix infrastructure + +- Install nix with `nixbuild/nix-quick-install-action@v30`. +- Pull/push the shared `rainlanguage` Cachix with `cachix/cachix-action@v15` + (set `continue-on-error: true` and `useDaemon: false` alongside + `cache-nix-action`, else the nix DB corrupts). +- Cache the nix store with `nix-community/cache-nix-action@v7` keyed by + `**/*.nix` + `**/flake.lock` hashes. +- Do NOT use `DeterminateSystems/nix-installer-action` or + `DeterminateSystems/flakehub-cache-action` — they don't share the + `rainlanguage` Cachix that every other workflow warms. + +### Build caches + +- `Swatinem/rust-cache@v2` after the nix-store cache step for any cargo work + (rust-cache caches `~/.cargo/{registry,git}` + `target/`). +- `actions/cache@v4` over `~/.npm` keyed by `**/package-lock.json` for any + `npm install` work. + +### Committed derived artifacts + +- ABIs that `sol!` macros read are committed under `crates/*/abis/` so cargo can + build in slim shells without `forge soldeer install` + `forge build` on the + test path. +- jq-strip forge JSON to deterministic fields only: `{abi}` if no `::deploy()` + is called; `{abi, bytecode: (.bytecode | {object, + linkReferences})}` if it + is. **Drop `sourceMap`** — it embeds a file-ID that depends on solc's input + ordering and differs across runners. +- Vendored solidity files (e.g., + `crates/test_fixtures/contracts/ + IMulticall3.sol`) keep `sol!` chains + working in slim shells without needing the soldeer dep tree on disk. +- `script/build.sh` regenerates ALL committed derived artifacts; + `rainix-copy-artifacts` runs it then `git diff --exit-code` to catch drift. + +### Shell quoting + +Pass multi-command pipelines as `nix develop ...#X -c bash -c '...'`, NOT as +`nix develop ...#X -c bash <'`; TS `sg --lang ts -p ''`. -- Architecture context: when working in any directory, check for an `ARCHITECTURE.md` file in the current working directory and read it first to understand local architecture before making changes. + +- Prefer syntax-aware search with ast-grep: Rust + `sg --lang rust -p ''`; TS `sg --lang ts -p ''`. +- Architecture context: when working in any directory, check for an + `ARCHITECTURE.md` file in the current working directory and read it first to + understand local architecture before making changes. diff --git a/CLAUDE.md b/CLAUDE.md index 3e6421fed3..a97d2c4e6e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1 +1,2 @@ -Before working on anything in this repository, read and follow the @AGENTS.md file. +Before working on anything in this repository, read and follow the @AGENTS.md +file. diff --git a/LICENSES/Apache-2.0.txt b/LICENSES/Apache-2.0.txt new file mode 100644 index 0000000000..137069b823 --- /dev/null +++ b/LICENSES/Apache-2.0.txt @@ -0,0 +1,73 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + + (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + + You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + +To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/LICENSES/MIT.txt b/LICENSES/MIT.txt new file mode 100644 index 0000000000..d817195dad --- /dev/null +++ b/LICENSES/MIT.txt @@ -0,0 +1,18 @@ +MIT License + +Copyright (c) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the +following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT +LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO +EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index a5ac62a35b..9fb82cb6ae 100644 --- a/README.md +++ b/README.md @@ -40,13 +40,12 @@ allowing developers to more easily create their own frontends for Raindex. Then run the following to install dependencies and build the project: ```bash -./prep-all.sh -``` - -You may need to make the shell script executable: - -```bash -chmod +x prep-all.sh +nix develop -c forge soldeer install +nix develop -c forge build +nix develop -c raindex-ui-components-prelude +nix develop -c npm run build -w @rainlanguage/raindex +nix develop -c npm run build -w @rainlanguage/ui-components +nix develop -c npm run build -w @rainlanguage/webapp ``` ### Run Webapp for local development diff --git a/REUSE.toml b/REUSE.toml index 4eea063e00..7b32ced7e6 100644 --- a/REUSE.toml +++ b/REUSE.toml @@ -6,6 +6,7 @@ path = [ ".gas-snapshot", ".github/**/", ".gitignore", + ".prettierignore", ".vscode/**/", ".cargo/**/", "README.md", @@ -20,22 +21,18 @@ path = [ "slither.config.json", "typeshare.toml", "REUSE.toml", - "pointers.sh", "package.json", "package-lock.json", "Cargo.lock", "Cargo.toml", ".devcontainer.json", ".env.example", - "prep-all.sh", "packages/**/", "ai_commands/**/", "subgraph/**/", "crates/**/", "meta/**/", "test-resources/**/", - "prep-base.sh", - "prep-webapp.sh", "audit/**/", ".coderabbit.yaml", ] diff --git a/ai_commands/feature-implementation-plan.md b/ai_commands/feature-implementation-plan.md index f1111dc218..8291c16629 100644 --- a/ai_commands/feature-implementation-plan.md +++ b/ai_commands/feature-implementation-plan.md @@ -1,158 +1,229 @@ Title: Generate Repository-Aware Feature Implementation Plan -You are an engineering assistant. Your task is to elicit clear requirements for a new feature and produce a comprehensive, repository-aware implementation plan tailored to this codebase. The plan must identify impacted areas, propose an end-to-end approach, outline concrete code changes (by directory/file where possible), define testing and rollout, and align with project conventions. It should be detailed enough for engineers to implement with minimal back-and-forth. +You are an engineering assistant. Your task is to elicit clear requirements for +a new feature and produce a comprehensive, repository-aware implementation plan +tailored to this codebase. The plan must identify impacted areas, propose an +end-to-end approach, outline concrete code changes (by directory/file where +possible), define testing and rollout, and align with project conventions. It +should be detailed enough for engineers to implement with minimal +back-and-forth. Interactive Start -- Ask the user to summarize the feature in one or two sentences and provide the primary user story or job-to-be-done. + +- Ask the user to summarize the feature in one or two sentences and provide the + primary user story or job-to-be-done. - Ask for acceptance criteria and explicit out-of-scope items. - Ask which areas are likely in scope (check all that apply): - Solidity contracts (`src/`, `test/`, `test-resources/`) - - Rust crates (`crates/*` — e.g., `cli`, `common`, `bindings`, `js_api`, `quote`, `subgraph`, `settings`, `math`) + - Rust crates (`crates/*` — e.g., `cli`, `common`, `bindings`, `js_api`, + `quote`, `subgraph`, `settings`, `math`) - JS/WASM package (`packages/raindex`) - Webapp UI (`packages/webapp`) or UI components (`packages/ui-components`) - Subgraph/indexing (`subgraph/*`) - Tooling/scripts (`script/*`, `.github/*`, `nix.flake`, repo root scripts) - Documentation (`README.md`, `ARCHITECTURE.md` in target dirs) - Ask for any known entry points, files, or APIs to extend vs. create new ones. -- Ask for constraints and NFRs (choose/apply as relevant): performance targets, latency budget, throughput, gas bounds, security/trust model, backwards-compat requirements, migration needs, feature flags/env vars, telemetry/observability, offline/edge concerns, platform targets (native/WASM/browser), network or provider assumptions. -- Ask for existing examples or patterns in the repo to mimic, and any explicit anti-patterns to avoid. +- Ask for constraints and NFRs (choose/apply as relevant): performance targets, + latency budget, throughput, gas bounds, security/trust model, backwards-compat + requirements, migration needs, feature flags/env vars, + telemetry/observability, offline/edge concerns, platform targets + (native/WASM/browser), network or provider assumptions. +- Ask for existing examples or patterns in the repo to mimic, and any explicit + anti-patterns to avoid. Pre‑Plan Summary (non‑blocking) -- Echo back a concise summary of the inputs captured and list intended analysis steps (what code areas you will inspect and which ast-grep scans you will run). -- Call out any missing information with 2–5 focused questions and proposed assumptions. -- Proceed immediately to generate the plan using these assumptions; no explicit approval is required. + +- Echo back a concise summary of the inputs captured and list intended analysis + steps (what code areas you will inspect and which ast-grep scans you will + run). +- Call out any missing information with 2–5 focused questions and proposed + assumptions. +- Proceed immediately to generate the plan using these assumptions; no explicit + approval is required. Inputs + - Short feature summary, acceptance criteria, and out-of-scope list. - Probable areas of the repo to touch (from checklist above). - Constraints/NFRs and any domain/legal/security requirements. - Pointers to related issues/PRs or specific files. Constraints & Repo Conventions -- Planning-only, non-destructive policy: do NOT implement code or change repository state. Your role is to gather context and produce a plan. + +- Planning-only, non-destructive policy: do NOT implement code or change + repository state. Your role is to gather context and produce a plan. - Do not modify source code, configs, tests, or assets. - - Do not scaffold/generate files except the final plan markdown under `ai_implementation_plans/` per Persistence. - - Do not run build/test/format/lint commands; include them in the plan as guidance only. - - Perform read-only analysis only (open files, ast-grep searches, summarize docs). + - Do not scaffold/generate files except the final plan markdown under + `ai_implementation_plans/` per Persistence. + - Do not run build/test/format/lint commands; include them in the plan as + guidance only. + - Perform read-only analysis only (open files, ast-grep searches, summarize + docs). - No network access. -- When listing commands in the plan, use Nix shells: prefix with `nix develop -c `. Do not execute these commands. +- When listing commands in the plan, use Nix shells: prefix with + `nix develop -c `. Do not execute these commands. - Prefer syntax-aware search with ast-grep for structured matching: - Rust: `sg --lang rust -p ''` - TypeScript: `sg --lang ts -p ''` - - Use simple reads for languages without ast-grep support when structural matching is unnecessary. + - Use simple reads for languages without ast-grep support when structural + matching is unnecessary. - Follow `AGENTS.md` for tone and repo norms: - - Rust: format `nix develop -c cargo fmt --all`, lint `nix develop -c rainix-rs-static`. - - TS/Svelte: `nix develop -c npm run format`, `nix develop -c npm run lint`, `nix develop -c npm run check`. + - Rust: format `nix develop -c cargo fmt --all`, lint + `nix develop -c rainix-rs-static`. + - TS/Svelte: `nix develop -c npm run format`, `nix develop -c npm run lint`, + `nix develop -c npm run check`. - Solidity: `forge fmt`; compiler `solc 0.8.25`. - Testing guidelines: - - Rust: unit + `crates/integration_tests` (prefer `insta` snapshots and `proptest` where helpful). + - Rust: unit + `crates/integration_tests` (prefer `insta` snapshots and + `proptest` where helpful). - TS/Svelte: Vitest (`*.test.ts`/`*.spec.ts`). - Solidity: Foundry fuzz/property tests where relevant. -- Commit/PR: Conventional Commits; PRs describe scope, link issues, include screenshots for UI, and pass CI. Preflight: `nix develop -c npm run lint-format-check:all && nix develop -c rainix-rs-static`. +- Commit/PR: Conventional Commits; PRs describe scope, link issues, include + screenshots for UI, and pass CI. Preflight: + `nix develop -c npm run lint-format-check:all && nix develop -c rainix-rs-static`. - Never commit secrets; respect `.env.example` guidance. High‑Level Goal -1) Clarify the problem, goal, and constraints of the new feature. -2) Identify impacted areas and relevant existing code to extend or reuse. -3) Propose an architecture and API shape consistent with repo patterns. -4) Produce a step‑by‑step implementation plan with code‑level waypoints, tests, and docs. -5) Outline risks, alternatives, and a rollout/validation strategy. - -Procedure -0) Pre‑plan summary & assumptions - - Summarize captured inputs (feature, acceptance criteria, in-scope areas, constraints, rollout preferences). - - Outline analysis scope: directories to inspect and exact searches to run (ast-grep patterns per area). - - List missing info and explicit assumptions; proceed to generate the plan without waiting. - -1) Requirements and scope + +1. Clarify the problem, goal, and constraints of the new feature. +2. Identify impacted areas and relevant existing code to extend or reuse. +3. Propose an architecture and API shape consistent with repo patterns. +4. Produce a step‑by‑step implementation plan with code‑level waypoints, tests, + and docs. +5. Outline risks, alternatives, and a rollout/validation strategy. + +Procedure 0) Pre‑plan summary & assumptions + +- Summarize captured inputs (feature, acceptance criteria, in-scope areas, + constraints, rollout preferences). +- Outline analysis scope: directories to inspect and exact searches to run + (ast-grep patterns per area). +- List missing info and explicit assumptions; proceed to generate the plan + without waiting. + +1. Requirements and scope - Capture the short summary, acceptance criteria, and out-of-scope. - - Record explicit constraints: perf/security/gas, compatibility, rollout strategy. + - Record explicit constraints: perf/security/gas, compatibility, rollout + strategy. - Note any required integrations (providers, networks, crates/packages). -2) Discover relevant code and patterns +2. Discover relevant code and patterns - Read `AGENTS.md` and any `ARCHITECTURE.md` within target directories. - Locate current entry points and similar features using ast-grep. - - Rust public surface: `sg --lang rust -p 'pub (fn|struct|enum|trait) $NAME' crates` + - Rust public surface: + `sg --lang rust -p 'pub (fn|struct|enum|trait) $NAME' crates` - Rust CLI: `sg --lang rust -p '#[derive(Parser)]' crates/cli` - Rust WASM bindings: `sg --lang rust -p '#[wasm_bindgen]' crates/js_api` - - TS exports: `sg --lang ts -p 'export (function|class|interface|type) $NAME' packages` + - TS exports: + `sg --lang ts -p 'export (function|class|interface|type) $NAME' packages` - Svelte components: scan `packages/webapp/src/**/*.svelte` - Solidity contracts/interfaces: scan `src/**/*.sol` - Subgraph mappings/schema: scan `subgraph/**/*` - - Identify patterns to reuse (module layout, naming, test styles, error handling, result types, wasm export metadata). - -3) Draft approach and boundaries - - Describe the end-to-end flow: inputs, transformations, outputs, and interfaces between components (contracts ↔ Rust ↔ JS/WASM ↔ UI ↔ subgraph as applicable). - - Specify new/changed APIs and data shapes (Rust types, TS types, solidity interfaces) and how they fit existing modules. - - Define compatibility and migration strategy (schema changes, feature flags, env vars, deprecations). - -4) Detailed implementation plan (by directory) - - For each impacted area, list concrete changes with file path anchors where possible. For example: - - Rust crates (e.g., `crates/`): modules to add/modify, new types/functions, error handling, feature flags; `Cargo.toml` updates if needed. - - JS/WASM (`packages/raindex`): new exports, TS types, wasm bindings, build scripts. - - Webapp (`packages/webapp`): routes/components, stores, API calls, state management, styles. - - Contracts (`src/`): new contracts/interfaces/libraries, events, storage layout notes, upgrade path; tests in `test/` with fixtures in `test-resources/`. - - Subgraph (`subgraph/`): schema changes, mappings, handlers, data flow and reindex considerations. - - Scripts/tooling (`script/`, root scripts): CLI tasks, generators, migrations. - - Include code‑level notes: naming conventions, module boundaries, error/result patterns, and how to thread config. - -5) Testing strategy + - Identify patterns to reuse (module layout, naming, test styles, error + handling, result types, wasm export metadata). + +3. Draft approach and boundaries + - Describe the end-to-end flow: inputs, transformations, outputs, and + interfaces between components (contracts ↔ Rust ↔ JS/WASM ↔ UI ↔ subgraph + as applicable). + - Specify new/changed APIs and data shapes (Rust types, TS types, solidity + interfaces) and how they fit existing modules. + - Define compatibility and migration strategy (schema changes, feature flags, + env vars, deprecations). + +4. Detailed implementation plan (by directory) + - For each impacted area, list concrete changes with file path anchors where + possible. For example: + - Rust crates (e.g., `crates/`): modules to add/modify, new + types/functions, error handling, feature flags; `Cargo.toml` updates if + needed. + - JS/WASM (`packages/raindex`): new exports, TS types, wasm bindings, build + scripts. + - Webapp (`packages/webapp`): routes/components, stores, API calls, state + management, styles. + - Contracts (`src/`): new contracts/interfaces/libraries, events, storage + layout notes, upgrade path; tests in `test/` with fixtures in + `test-resources/`. + - Subgraph (`subgraph/`): schema changes, mappings, handlers, data flow and + reindex considerations. + - Scripts/tooling (`script/`, root scripts): CLI tasks, generators, + migrations. + - Include code‑level notes: naming conventions, module boundaries, + error/result patterns, and how to thread config. + +5. Testing strategy - Enumerate unit/integration/e2e tests by area: - - Rust: unit tests per module; integration tests under `crates/integration_tests`; use `insta`/`proptest` where applicable. - - TS/Svelte: Vitest unit tests; component tests for UI changes; mock WASM where necessary. - - Solidity: Foundry unit/property tests; fuzz critical invariants; event emission checks. - - Subgraph: mapping tests if applicable; validate handlers against schema changes. + - Rust: unit tests per module; integration tests under + `crates/integration_tests`; use `insta`/`proptest` where applicable. + - TS/Svelte: Vitest unit tests; component tests for UI changes; mock WASM + where necessary. + - Solidity: Foundry unit/property tests; fuzz critical invariants; event + emission checks. + - Subgraph: mapping tests if applicable; validate handlers against schema + changes. - Define fixtures, snapshots, and test data sources. -6) Validation, build, and CI - - Include correct local commands to build, lint, and test each area using Nix shells (reference only; do not execute). +6. Validation, build, and CI + - Include correct local commands to build, lint, and test each area using Nix + shells (reference only; do not execute). - Add preflight and formatting/linting commands per language. - Note any CI considerations and artifacts. -7) Risks, alternatives, and open questions - - Enumerate key risks (complexity, perf, security, migration) and mitigations. +7. Risks, alternatives, and open questions + - Enumerate key risks (complexity, perf, security, migration) and + mitigations. - Propose plausible alternatives if applicable with pros/cons. - List any open questions to confirm with the user. -8) PR breakdown and sequencing +8. PR breakdown and sequencing - Suggest a logical PR stack or single PR with checkpoints. - Provide conventional-commit scoped titles for each PR. - Include rough estimates and dependencies between tasks. -Output Format -Return a structured plan with the following sections and persist it to disk: -1) Summary -2) Assumptions & Open Questions -3) Impacted Areas -4) Proposed Design & Data Shapes -5) Detailed Steps by Directory -6) Testing Strategy -7) Security, Performance & Observability -8) Migration & Rollout (flags/env/compat) -9) Documentation Updates -10) Risks & Alternatives -11) PR Breakdown & Estimates -12) Validation Commands +Output Format Return a structured plan with the following sections and persist +it to disk: + +1. Summary +2. Assumptions & Open Questions +3. Impacted Areas +4. Proposed Design & Data Shapes +5. Detailed Steps by Directory +6. Testing Strategy +7. Security, Performance & Observability +8. Migration & Rollout (flags/env/compat) +9. Documentation Updates +10. Risks & Alternatives +11. PR Breakdown & Estimates +12. Validation Commands Persistence -- After generating the plan, write the full plan to a markdown file under `ai_implementation_plans/` at the repo root. -- Filename convention: `-.md` (use lowercase, hyphens; max ~60 chars). If a conflict exists, append `-v2`, `-v3`, etc. + +- After generating the plan, write the full plan to a markdown file under + `ai_implementation_plans/` at the repo root. +- Filename convention: `-.md` (use lowercase, + hyphens; max ~60 chars). If a conflict exists, append `-v2`, `-v3`, etc. - File header (top of the file): - Title: ` — Implementation Plan` - Date: `YYYY-MM-DD` - Status: `Draft` - Areas: comma-separated list from “Impacted Areas” - Inputs: one-paragraph recap of key requirements/constraints -- Return the saved path in your response, e.g., `ai_implementation_plans/2025-09-14-new-matcher-api.md`. +- Return the saved path in your response, e.g., + `ai_implementation_plans/2025-09-14-new-matcher-api.md`. - Updates and revisions: - - When users request changes, update the same plan file in place when the feature slug matches; do not create duplicates. - - Track `Revision: vN` near the header and bump it on each update; append a “Last Updated: YYYY-MM-DD — Summary of changes” line. - - Only create a new `-v2`/`-v3` file when the user explicitly asks for a separate variant. + - When users request changes, update the same plan file in place when the + feature slug matches; do not create duplicates. + - Track `Revision: vN` near the header and bump it on each update; append a + “Last Updated: YYYY-MM-DD — Summary of changes” line. + - Only create a new `-v2`/`-v3` file when the user explicitly asks for a + separate variant. -Always include an “Assumptions & Open Questions” section when inputs are incomplete; proceed without gating on approval. +Always include an “Assumptions & Open Questions” section when inputs are +incomplete; proceed without gating on approval. Practical ast-grep patterns (examples) + - Rust public items: `sg --lang rust -p 'pub (struct|enum|trait|fn) $NAME'` - Rust clap CLI: `sg --lang rust -p '#[derive(Parser)] struct $S'` - Rust wasm exports: `sg --lang rust -p '#[wasm_bindgen] fn $F(...)'` @@ -160,7 +231,9 @@ Practical ast-grep patterns (examples) - Find existing error types: `sg --lang rust -p 'enum $E(Error|Err)' crates` - Find config handling: `sg --lang rust -p 'struct $S { .. }' crates/settings` -Build/Test Commands Reference (use where relevant; reference only — do not execute) +Build/Test Commands Reference (use where relevant; reference only — do not +execute) + - Bootstrap: `./prep-all.sh` - Rust: `nix develop -c cargo build --workspace` / `nix develop -c cargo test` - Solidity: `nix develop -c forge build` / `nix develop -c forge test` @@ -169,18 +242,31 @@ Build/Test Commands Reference (use where relevant; reference only — do not exe - Webapp: `cd packages/webapp && nix develop -c npm run dev` Acceptance Criteria -- Starts by asking concise, high-value clarifying questions and records assumptions. -- Proceeds without requiring explicit approval; records assumptions and generates the plan. -- Identifies impacted directories and proposes code-level changes consistent with local patterns and naming conventions. -- Specifies public API changes (Rust/TS/Solidity) with indicative signatures/types where relevant. -- Provides a concrete testing plan aligned with repo guidelines, including where tests live and what they validate. -- Includes migration/feature flag/env var considerations when behavior surfaces change. + +- Starts by asking concise, high-value clarifying questions and records + assumptions. +- Proceeds without requiring explicit approval; records assumptions and + generates the plan. +- Identifies impacted directories and proposes code-level changes consistent + with local patterns and naming conventions. +- Specifies public API changes (Rust/TS/Solidity) with indicative + signatures/types where relevant. +- Provides a concrete testing plan aligned with repo guidelines, including where + tests live and what they validate. +- Includes migration/feature flag/env var considerations when behavior surfaces + change. - Lists validation commands using Nix shells and preflight checks. -- Produces a plan that is implementable without guesswork and suitable for review/approval. -- Persists the final plan to `ai_implementation_plans/-.md` and returns its path. - - Performs read-only analysis only; makes no code changes or side effects beyond writing the plan file. +- Produces a plan that is implementable without guesswork and suitable for + review/approval. +- Persists the final plan to `ai_implementation_plans/-.md` and + returns its path. +- Performs read-only analysis only; makes no code changes or side effects beyond + writing the plan file. What to return + - The complete implementation plan in the structure above. -- If key inputs are missing, include a short “Missing Info” note and proceed with a reasonable draft based on explicit assumptions; highlight these in the plan’s “Assumptions & Open Questions”. +- If key inputs are missing, include a short “Missing Info” note and proceed + with a reasonable draft based on explicit assumptions; highlight these in the + plan’s “Assumptions & Open Questions”. - Optional: offer 1–2 design variants with trade-offs when appropriate. diff --git a/ai_commands/generate-pr-content.md b/ai_commands/generate-pr-content.md index fff51f6816..e03f1d22f8 100644 --- a/ai_commands/generate-pr-content.md +++ b/ai_commands/generate-pr-content.md @@ -1,31 +1,47 @@ Title: Generate PR Title and Description from Diff -You are an engineering assistant. Your task is to generate a high‑quality Pull Request title and description using the repository’s PR template, based on a git diff. Start by asking the user which base branch to diff against and whether they want to provide additional motivation/context. Use the diff and any provided context to infer scope, summarize changes, and produce a conventional‑commit style title and a filled template. +You are an engineering assistant. Your task is to generate a high‑quality Pull +Request title and description using the repository’s PR template, based on a git +diff. Start by asking the user which base branch to diff against and whether +they want to provide additional motivation/context. Use the diff and any +provided context to infer scope, summarize changes, and produce a +conventional‑commit style title and a filled template. Interactive Start -- Ask: “Which base branch should I compare against? Use `main` or specify another (e.g., `release/x.y` or a feature branch).” -- Ask: “Do you want to provide any specific motivation (issue links, goals, context) to include?” -- If motivation is unclear after the diff, ask a brief follow‑up before finalizing text. + +- Ask: “Which base branch should I compare against? Use `main` or specify + another (e.g., `release/x.y` or a feature branch).” +- Ask: “Do you want to provide any specific motivation (issue links, goals, + context) to include?” +- If motivation is unclear after the diff, ask a brief follow‑up before + finalizing text. Inputs + - Base branch to compare against (default: `main`). - Optional motivation/context and links (issues/PRs). Constraints & Repo Conventions -- Use Conventional Commits for the title: `feat:`, `fix:`, `chore:`, `docs:`, `test:`, `refactor:`, `perf:`, `ci:`, `build:`. + +- Use Conventional Commits for the title: `feat:`, `fix:`, `chore:`, `docs:`, + `test:`, `refactor:`, `perf:`, `ci:`, `build:`. - Prefer syntax‑aware search with ast-grep when inspecting code structure: - Rust: `sg --lang rust -p ''` - TypeScript: `sg --lang ts -p ''` -- When running builds/tests locally, use Nix shells (if needed for context): `nix develop -c `. +- When running builds/tests locally, use Nix shells (if needed for context): + `nix develop -c `. - Follow AGENTS.md tone: concise, accurate, minimal verbosity. High‑Level Goal -1) Determine the correct base for the diff (default `main`). -2) Summarize the changes and infer scope (crates/packages/areas touched). -3) Generate a clear, conventional‑commit PR title with a scoped summary. -4) Fill the PR description using the template below, incorporating user‑provided motivation and a crisp solution summary derived from the diff. + +1. Determine the correct base for the diff (default `main`). +2. Summarize the changes and infer scope (crates/packages/areas touched). +3. Generate a clear, conventional‑commit PR title with a scoped summary. +4. Fill the PR description using the template below, incorporating user‑provided + motivation and a crisp solution summary derived from the diff. Template (use exactly this in the PR body) + ``` @@ -54,7 +70,8 @@ By submitting this for review, I'm confirming I've done the following: ``` Procedure -1) Confirm base branch + +1. Confirm base branch - If the user provides none, use `main`. - Compute a local diff without network access. - Preferred commands: @@ -62,7 +79,7 @@ Procedure - Short stats: `git --no-pager diff --stat ...HEAD` - Commit context (optional): `git --no-pager log --oneline ..HEAD` -2) Infer scope and impact +2. Infer scope and impact - Group changes by top-level path to derive scope keywords, e.g.: - `crates/` → Rust crate scope - `packages/` → npm/TS package scope @@ -73,45 +90,59 @@ Procedure - `refactor:` if changes are structural without behavior; otherwise - `docs:` if docs only; `test:` if tests only; `chore:` for tooling/infra. - Optionally use ast‑grep to pull high-signal names to improve the title: - - Rust public items: `sg --lang rust -p 'pub (fn|struct|enum|trait) $NAME' ` - - TS exports: `sg --lang ts -p 'export (function|class|interface|type) $NAME' ` + - Rust public items: + `sg --lang rust -p 'pub (fn|struct|enum|trait) $NAME' ` + - TS exports: + `sg --lang ts -p 'export (function|class|interface|type) $NAME' ` -3) Draft the title +3. Draft the title - Format: `: : ` - - Scope: prefer a short identifier like `common`, `js_api`, `raindex`, `webapp`. + - Scope: prefer a short identifier like `common`, `js_api`, `raindex`, + `webapp`. - Summary: 6–12 words, describe outcome, not implementation details. -4) Fill the description template +4. Fill the description template - Motivation: - Use user-provided context verbatim when given. - - If missing, infer a brief rationale from the diff; if unsure, add a one‑line prompt asking the user to confirm/clarify. + - If missing, infer a brief rationale from the diff; if unsure, add a + one‑line prompt asking the user to confirm/clarify. - Solution: - - Summarize what changed: key files/areas, notable functions/types touched, new behaviors or fixed defects. + - Summarize what changed: key files/areas, notable functions/types touched, + new behaviors or fixed defects. - Mention tests updated/added and any important follow‑ups. - - If UI files changed under `packages/webapp`, include a note to attach screenshots. + - If UI files changed under `packages/webapp`, include a note to attach + screenshots. - Keep paragraphs short and skimmable. -5) Present results +5. Present results - Return both: - Title: a single line - Description: the filled template body - - Optionally include a compact diff summary in your answer for the user’s review. + - Optionally include a compact diff summary in your answer for the user’s + review. Edge Cases & Guidance + - If the diff is empty, say so and ask the user to confirm the base branch. -- If there are many unrelated changes, propose splitting into multiple PRs and draft multiple candidate titles if appropriate. -- Do not invent details. Prefer asking one concise follow‑up if motivation cannot be inferred reliably. +- If there are many unrelated changes, propose splitting into multiple PRs and + draft multiple candidate titles if appropriate. +- Do not invent details. Prefer asking one concise follow‑up if motivation + cannot be inferred reliably. - Keep style consistent with this repo’s PR expectations in AGENTS.md. Acceptance Criteria -- Asks the user for base branch (`main` by default) and optional motivation before generating output. + +- Asks the user for base branch (`main` by default) and optional motivation + before generating output. - Produces a conventional‑commit title reflecting scope and change intent. -- Returns the description filled with the exact template, customized with inferred/provided context. -- Summarizes solution grounded in the actual diff (files/areas touched), not speculation. +- Returns the description filled with the exact template, customized with + inferred/provided context. +- Summarizes solution grounded in the actual diff (files/areas touched), not + speculation. - Notes when screenshots are relevant for front‑end changes. What to return + - Title: `: : ` - Description: the filled template body text - Optional: a short “Diff summary” section to help reviewers sanity‑check scope - diff --git a/ai_commands/refresh-architecture.md b/ai_commands/refresh-architecture.md index d7f1571af9..998c5f279c 100644 --- a/ai_commands/refresh-architecture.md +++ b/ai_commands/refresh-architecture.md @@ -1,64 +1,105 @@ Title: Refresh ARCHITECTURE.md for a Given Directory -You are an engineering assistant. Your task is to refresh the ARCHITECTURE.md file for a directory specified by the user. The document must accurately describe the current code and behavior in that directory. If the code has changed since the doc was written, identify discrepancies and update the doc to reflect the current state. +You are an engineering assistant. Your task is to refresh the ARCHITECTURE.md +file for a directory specified by the user. The document must accurately +describe the current code and behavior in that directory. If the code has +changed since the doc was written, identify discrepancies and update the doc to +reflect the current state. Inputs -- A path to the target directory inside this repository, provided by the user (e.g., `crates/common`, `packages/raindex`). + +- A path to the target directory inside this repository, provided by the user + (e.g., `crates/common`, `packages/raindex`). Constraints and Repo Conventions -- Always work inside a Nix shell when running build/test commands (`nix develop -c `). Do not fetch network resources. + +- Always work inside a Nix shell when running build/test commands + (`nix develop -c `). Do not fetch network resources. - Prefer syntax-aware searches with ast-grep for structured matching: - Rust: `sg --lang rust -p ''` - TypeScript: `sg --lang ts -p ''` - - Use plain file reads or simple text scans for languages not supported by ast-grep (e.g., Solidity, Svelte markup) when structural matching is not needed. -- Follow AGENTS.md: if an `ARCHITECTURE.md` exists in the directory, read it first and preserve its voice, structure, and intent where still accurate. -- Do not modify code; only update documentation. Do not commit secrets or change configs. + - Use plain file reads or simple text scans for languages not supported by + ast-grep (e.g., Solidity, Svelte markup) when structural matching is not + needed. +- Follow AGENTS.md: if an `ARCHITECTURE.md` exists in the directory, read it + first and preserve its voice, structure, and intent where still accurate. +- Do not modify code; only update documentation. Do not commit secrets or change + configs. High-Level Goal -1) Read the existing `ARCHITECTURE.md` (or create a new one if missing) in the provided directory. -2) Build a “current state” snapshot by examining the directory’s code, configuration, and exported surfaces. -3) Compare the snapshot to the current document and list discrepancies. -4) Update `ARCHITECTURE.md` to accurately represent the current state, keeping the style consistent with nearby docs in this repo. + +1. Read the existing `ARCHITECTURE.md` (or create a new one if missing) in the + provided directory. +2. Build a “current state” snapshot by examining the directory’s code, + configuration, and exported surfaces. +3. Compare the snapshot to the current document and list discrepancies. +4. Update `ARCHITECTURE.md` to accurately represent the current state, keeping + the style consistent with nearby docs in this repo. Procedure -1) Verify input and locate doc + +1. Verify input and locate doc - Confirm the target path exists and is inside this repo. - - Look for `ARCHITECTURE.md` and also accept `architecture.md` (case-insensitive). If none exist, you will create `ARCHITECTURE.md`. + - Look for `ARCHITECTURE.md` and also accept `architecture.md` + (case-insensitive). If none exist, you will create `ARCHITECTURE.md`. -2) Read local context +2. Read local context - Open and read the current `ARCHITECTURE.md` fully (if present). - Skim `AGENTS.md` at repo root to align format and terminology. -3) Build a current-state snapshot of the directory - - File/Folder layout: list primary files and subfolders (1–2 levels deep), excluding obvious build outputs (`target`, `dist`, `node_modules`, `out`). +3. Build a current-state snapshot of the directory + - File/Folder layout: list primary files and subfolders (1–2 levels deep), + excluding obvious build outputs (`target`, `dist`, `node_modules`, `out`). - Language-specific cues: - - Rust: read `Cargo.toml`, list crate name, lib/bin targets, features. Use ast-grep to enumerate public surface and structure: - - Public items: `pub struct`, `pub enum`, `pub trait`, `pub fn` (top-level, module-level). + - Rust: read `Cargo.toml`, list crate name, lib/bin targets, features. Use + ast-grep to enumerate public surface and structure: + - Public items: `pub struct`, `pub enum`, `pub trait`, `pub fn` + (top-level, module-level). - CLI commands (if any): look for `clap::Parser` or `#[derive(Parser)]`. - WASM exposure: `#[wasm_bindgen]`, `tsify`, feature flags gating. - - TypeScript/Svelte: read `package.json` (name, scripts, exports, types). Use ast-grep to find exported API (`export function`, `export class`, `export interface`, `export type`). Note Svelte components under `*.svelte` and any public entry points. - - Solidity: scan `src/**/*.sol` for `contract`, `interface`, `event` names; note Foundry config in `foundry.toml` and ABIs under `out/` if relevant. - - Subgraph: if present, capture `subgraph.yaml`, `schema.graphql`, and mapping entry points. - - Behavior and flows: identify primary responsibilities, key data flows, important invariants, and external dependencies (internal crates, packages, providers) as reflected in code. - - Build/Test commands: derive correct commands from this repo's conventions (Nix + cargo/forge/npm) relevant to this directory. - -4) Detect discrepancies between doc and code - - Outdated or missing sections: modules/types that no longer exist, new modules not documented, renamed/moved files, changed public APIs, added/removed commands, changed feature flags or build targets. - - Behavior changes: different data flows, new invariants/constraints, updated error handling, WASM vs native surface changes. - - Integration points: new or removed dependencies, changed entry points, updated environment variables. - -5) Update the document - - Keep the existing voice and section ordering when they still make sense. Update only what’s necessary to make the document true and useful. - - If the doc is severely out of date, rewrite it using the Template below. Otherwise, surgically edit inaccurate parts. - - When introducing new sections, mirror styles used by other `ARCHITECTURE.md` files in this repo (short headings, bullets, concise prose, code fences where helpful). - - Prefer accuracy over exhaustiveness; link to code paths where appropriate rather than duplicating implementation details. - -6) Validate and summarize + - TypeScript/Svelte: read `package.json` (name, scripts, exports, types). + Use ast-grep to find exported API (`export function`, `export class`, + `export interface`, `export type`). Note Svelte components under + `*.svelte` and any public entry points. + - Solidity: scan `src/**/*.sol` for `contract`, `interface`, `event` names; + note Foundry config in `foundry.toml` and ABIs under `out/` if relevant. + - Subgraph: if present, capture `subgraph.yaml`, `schema.graphql`, and + mapping entry points. + - Behavior and flows: identify primary responsibilities, key data flows, + important invariants, and external dependencies (internal crates, packages, + providers) as reflected in code. + - Build/Test commands: derive correct commands from this repo's conventions + (Nix + cargo/forge/npm) relevant to this directory. + +4. Detect discrepancies between doc and code + - Outdated or missing sections: modules/types that no longer exist, new + modules not documented, renamed/moved files, changed public APIs, + added/removed commands, changed feature flags or build targets. + - Behavior changes: different data flows, new invariants/constraints, updated + error handling, WASM vs native surface changes. + - Integration points: new or removed dependencies, changed entry points, + updated environment variables. + +5. Update the document + - Keep the existing voice and section ordering when they still make sense. + Update only what’s necessary to make the document true and useful. + - If the doc is severely out of date, rewrite it using the Template below. + Otherwise, surgically edit inaccurate parts. + - When introducing new sections, mirror styles used by other + `ARCHITECTURE.md` files in this repo (short headings, bullets, concise + prose, code fences where helpful). + - Prefer accuracy over exhaustiveness; link to code paths where appropriate + rather than duplicating implementation details. + +6. Validate and summarize - Ensure headings, lists, and code fences render cleanly. - - At the end of the file, append a short “Last Updated: YYYY-MM-DD — Summary of changes” line. - - In your output back to the user, include a brief summary of changes and any notable gaps or TODOs discovered. + - At the end of the file, append a short “Last Updated: YYYY-MM-DD — Summary + of changes” line. + - In your output back to the user, include a brief summary of changes and any + notable gaps or TODOs discovered. Template (use when creating or fully rewriting the doc) + ``` # — Architecture @@ -95,16 +136,23 @@ Last Updated: YYYY-MM-DD — Summary of changes ``` Practical ast-grep patterns (examples) + - Rust public items: `sg --lang rust -p 'pub (struct|enum|trait|fn) $NAME'` - Rust clap CLI: `sg --lang rust -p '#[derive(Parser)] struct $S'` - Rust wasm exports: `sg --lang rust -p '#[wasm_bindgen] fn $F(...)'` - TS exports: `sg --lang ts -p 'export (function|class|interface|type) $NAME'` Acceptance Criteria -- The updated `ARCHITECTURE.md` exists in the target directory and describes the current code accurately. -- Discrepancies between the previous document and the code have been resolved or explicitly noted. -- The tone and structure match other architecture docs in this repo (concise headings, bullets, minimal verbosity). -- The doc includes a “Last Updated” line with today’s date and a one-line summary. + +- The updated `ARCHITECTURE.md` exists in the target directory and describes the + current code accurately. +- Discrepancies between the previous document and the code have been resolved or + explicitly noted. +- The tone and structure match other architecture docs in this repo (concise + headings, bullets, minimal verbosity). +- The doc includes a “Last Updated” line with today’s date and a one-line + summary. What to return + - A short summary of what changed and why, plus the path to the updated file. diff --git a/ai_commands/sdk-documentation-update.md b/ai_commands/sdk-documentation-update.md index 9dceaea040..be886b5f03 100644 --- a/ai_commands/sdk-documentation-update.md +++ b/ai_commands/sdk-documentation-update.md @@ -1,110 +1,173 @@ Title: Sync SDK Documentation with Current JS API and Package -You are an engineering assistant. Your task is to verify and update the SDK documentation so it matches the current codebase. The primary source of truth is the Rust JS API in `crates/js_api` (inline docs on items exported via the `wasm_export` macro). You must also validate and update the additional package-level docs in `packages/raindex` (e.g., README and any in‑package docs) to stay consistent with the built TypeScript surface. +You are an engineering assistant. Your task is to verify and update the SDK +documentation so it matches the current codebase. The primary source of truth is +the Rust JS API in `crates/js_api` (inline docs on items exported via the +`wasm_export` macro). You must also validate and update the additional +package-level docs in `packages/raindex` (e.g., README and any in‑package docs) +to stay consistent with the built TypeScript surface. Goal -- Ensure every JS-facing API exported from `crates/js_api` is documented accurately: names, parameters, parameter descriptions, return types, return descriptions, error semantics, and examples. -- Ensure package documentation in `packages/raindex` (e.g., README) reflects the current API surface and real usage patterns. -- Avoid changing behavior or public API; this task is documentation-only. If you find code/doc conflicts that cannot be resolved with doc edits alone, open/leave a clear TODO note in your summary. + +- Ensure every JS-facing API exported from `crates/js_api` is documented + accurately: names, parameters, parameter descriptions, return types, return + descriptions, error semantics, and examples. +- Ensure package documentation in `packages/raindex` (e.g., README) reflects the + current API surface and real usage patterns. +- Avoid changing behavior or public API; this task is documentation-only. If you + find code/doc conflicts that cannot be resolved with doc edits alone, + open/leave a clear TODO note in your summary. Scope -- Rust JS API: `crates/js_api/**` — functions, classes, and types reachable from JS via `#[wasm_export]`, `#[wasm_bindgen]`, and `Tsify`. -- Package docs: `packages/raindex/README.md` and any additional docs in that package. Validate against built declarations `packages/raindex/{cjs.d.ts,esm.d.ts}` when helpful. -- Cross-check TS usage in `packages/raindex/test/**/*` to keep examples canonical. + +- Rust JS API: `crates/js_api/**` — functions, classes, and types reachable from + JS via `#[wasm_export]`, `#[wasm_bindgen]`, and `Tsify`. +- Package docs: `packages/raindex/README.md` and any additional docs in that + package. Validate against built declarations + `packages/raindex/{cjs.d.ts,esm.d.ts}` when helpful. +- Cross-check TS usage in `packages/raindex/test/**/*` to keep examples + canonical. Constraints and Repo Conventions -- Always use a Nix shell for build/test commands: prefix commands with `nix develop -c` (or use appropriate shell attributes). + +- Always use a Nix shell for build/test commands: prefix commands with + `nix develop -c` (or use appropriate shell attributes). - Do not fetch network resources. Keep changes scoped to docs and docstrings. - Prefer syntax-aware search with ast-grep for structured matching: - Rust: `sg --lang rust -p ''` - TypeScript: `sg --lang ts -p ''` - - Use plain file reads only when structural matching is unnecessary (e.g., opening a README). -- Follow AGENTS.md for tone and style. Keep edits concise and consistent with existing documentation voice. + - Use plain file reads only when structural matching is unnecessary (e.g., + opening a README). +- Follow AGENTS.md for tone and style. Keep edits concise and consistent with + existing documentation voice. High-Level Process -1) Build and list the JS-facing API. -2) Compare inline Rust docs and export metadata to the built TypeScript surface. -3) Audit package README and examples against canonical usage from tests. -4) Apply focused documentation edits in Rust doc comments and package docs. -5) Validate with workspace builds and TS checks. Summarize changes and any gaps. + +1. Build and list the JS-facing API. +2. Compare inline Rust docs and export metadata to the built TypeScript surface. +3. Audit package README and examples against canonical usage from tests. +4. Apply focused documentation edits in Rust doc comments and package docs. +5. Validate with workspace builds and TS checks. Summarize changes and any gaps. Procedure -1) Prep and build + +1. Prep and build - Run the relevant builds and tests to ensure the code is in a good state: - `nix develop -c cargo build --workspace` - `nix develop -c cargo test` - `cd packages/raindex && nix develop -c npm run build && nix develop -c npm run test` -2) Enumerate exported JS API (Rust) +2. Enumerate exported JS API (Rust) - Find all wasm-exported items and their metadata: - `sg --lang rust -p '#[wasm_export]' crates/js_api` - - Also consider `#[wasm_bindgen]` classes/impls and `Tsify` types when relevant: + - Also consider `#[wasm_bindgen]` classes/impls and `Tsify` types when + relevant: - `sg --lang rust -p '#[wasm_bindgen]' crates/js_api` - `sg --lang rust -p 'derive(Tsify)' crates/js_api` - For each exported function/class/method, record: - - JS name (`js_name` in the attribute, or inferred from Rust name if not set) - - Parameter list and ordering; whether any `unchecked_param_type` is specified - - Return type (`unchecked_return_type` if present), and whether `preserve_js_class` is set - - Associated doc comments (`///`), `param_description`, and `return_description` - -3) Compare Rust docs to the effective TS surface - - Build the package and inspect generated declarations as a quick proxy for the public TS surface: + - JS name (`js_name` in the attribute, or inferred from Rust name if not + set) + - Parameter list and ordering; whether any `unchecked_param_type` is + specified + - Return type (`unchecked_return_type` if present), and whether + `preserve_js_class` is set + - Associated doc comments (`///`), `param_description`, and + `return_description` + +3. Compare Rust docs to the effective TS surface + - Build the package and inspect generated declarations as a quick proxy for + the public TS surface: - `cd packages/raindex && nix develop -c npm run build` - Open `packages/raindex/cjs.d.ts` and `packages/raindex/esm.d.ts`. - - Verify that each exported item’s JS name, parameter types/order, and return type match the Rust `wasm_export` metadata. - - If you find a mismatch between Rust doc comments/metadata and the generated `.d.ts`, prefer fixing the Rust docs/metadata (not changing code semantics) so docs match actual exports. + - Verify that each exported item’s JS name, parameter types/order, and return + type match the Rust `wasm_export` metadata. + - If you find a mismatch between Rust doc comments/metadata and the generated + `.d.ts`, prefer fixing the Rust docs/metadata (not changing code semantics) + so docs match actual exports. -4) Reconcile README and examples with canonical usage +4. Reconcile README and examples with canonical usage - Locate examples and usage references in the package README: - `packages/raindex/README.md` - - Cross-check against real usage in tests to keep documentation examples canonical: + - Cross-check against real usage in tests to keep documentation examples + canonical: - `sg --lang ts -p 'import { $X } from \"@rainlanguage/raindex\"' packages/raindex/test` - - Skim `packages/raindex/test/js_api/*.test.ts` for calls and parameter shapes. - - Ensure examples use correct names, parameter order and types, and demonstrate error handling with `WasmEncodedResult` where relevant. + - Skim `packages/raindex/test/js_api/*.test.ts` for calls and parameter + shapes. + - Ensure examples use correct names, parameter order and types, and + demonstrate error handling with `WasmEncodedResult` where relevant. -5) Apply focused edits +5. Apply focused edits - In Rust (`crates/js_api/**`): - Update `///` doc comments to describe current behavior precisely. - - Ensure each exported function has accurate `param_description` and `return_description` attributes. - - Make examples minimal and correct, using the JS-facing `js_name` and showing realistic inputs. + - Ensure each exported function has accurate `param_description` and + `return_description` attributes. + - Make examples minimal and correct, using the JS-facing `js_name` and + showing realistic inputs. - Keep tone consistent with existing docs in this crate. - In package docs (`packages/raindex/README.md` and peers): - Fix any outdated names, parameters, or return shapes. - Align examples with patterns used in tests (preferred canonical usage). - Keep imports correct: `import { ... } from '@rainlanguage/raindex'`. -6) Validate - - Rust checks: `nix develop -c cargo fmt --all && nix develop -c rainix-rs-static` - - Build artifacts needed for TS surface checks: `cd packages/raindex && nix develop -c npm run build` - - TS type-check the built output: `cd packages/raindex && nix develop -c npm run check` - - Run tests to confirm examples mirror real usage: `cd packages/raindex && nix develop -c npm run test` +6. Validate + - Rust checks: + `nix develop -c cargo fmt --all && nix develop -c rainix-rs-static` + - Build artifacts needed for TS surface checks: + `cd packages/raindex && nix develop -c npm run build` + - TS type-check the built output: + `cd packages/raindex && nix develop -c npm run check` + - Run tests to confirm examples mirror real usage: + `cd packages/raindex && nix develop -c npm run test` Practical ast-grep patterns + - List wasm exports: `sg --lang rust -p '#[wasm_export]' crates/js_api` - Find JS name assignments: `sg --lang rust -p 'js_name = $NAME' crates/js_api` -- Param descriptions: `sg --lang rust -p 'param_description = $DESC' crates/js_api` -- Return descriptions: `sg --lang rust -p 'return_description = $DESC' crates/js_api` +- Param descriptions: + `sg --lang rust -p 'param_description = $DESC' crates/js_api` +- Return descriptions: + `sg --lang rust -p 'return_description = $DESC' crates/js_api` - Tsify types: `sg --lang rust -p 'derive(Tsify)' crates/js_api` -- TS API imports in tests: `sg --lang ts -p 'import { $API } from "@rainlanguage/raindex"' packages/raindex/test` +- TS API imports in tests: + `sg --lang ts -p 'import { $API } from "@rainlanguage/raindex"' packages/raindex/test` Editing Guidelines + - Do not change any function signatures or runtime logic for this task. -- Prefer clarifying Rust doc comments and `wasm_export` attributes so the generated TypeScript aligns with docs. +- Prefer clarifying Rust doc comments and `wasm_export` attributes so the + generated TypeScript aligns with docs. - Use the `js_name` in all JS examples; avoid Rust identifiers in examples. -- Keep examples realistic but short; include basic error handling with `WasmEncodedResult` where applicable. -- If multiple names or behaviors are plausible, defer to the generated `.d.ts` and existing tests. +- Keep examples realistic but short; include basic error handling with + `WasmEncodedResult` where applicable. +- If multiple names or behaviors are plausible, defer to the generated `.d.ts` + and existing tests. - Preserve the existing voice and formatting used across current docs. Acceptance Criteria -- All `#[wasm_export]` items in `crates/js_api` have accurate, up-to-date docs: names, params (with descriptions), return types/descriptions, and examples. -- `packages/raindex/README.md` contains examples that compile conceptually against the current `.d.ts` and mirror test usage. -- TypeScript declarations (`cjs.d.ts`/`esm.d.ts`) match the documentation claims for names/types. -- Builds, tests, and type checks pass locally using Nix shell commands listed above. -- Your summary lists what changed and calls out any unresolved mismatches that require follow-up. + +- All `#[wasm_export]` items in `crates/js_api` have accurate, up-to-date docs: + names, params (with descriptions), return types/descriptions, and examples. +- `packages/raindex/README.md` contains examples that compile conceptually + against the current `.d.ts` and mirror test usage. +- TypeScript declarations (`cjs.d.ts`/`esm.d.ts`) match the documentation claims + for names/types. +- Builds, tests, and type checks pass locally using Nix shell commands listed + above. +- Your summary lists what changed and calls out any unresolved mismatches that + require follow-up. What to return -- A concise summary of updates made, the files touched, and any notable mismatches discovered that couldn’t be resolved via doc changes. + +- A concise summary of updates made, the files touched, and any notable + mismatches discovered that couldn’t be resolved via doc changes. Notes -- This repo uses a macro named `wasm_export` in `crates/js_api` to define JS-visible APIs and attach TypeScript-specific metadata (`js_name`, `unchecked_return_type`, `param_description`, `return_description`, `preserve_js_class`). Treat those attributes as the contract for the generated TypeScript surface. -- Some examples in README demonstrate end-to-end flows (e.g., builder setup via `RaindexOrderBuilder`, order hash/calldata helpers). Prefer aligning those with current tests under `packages/raindex/test/js_api` to avoid drift. + +- This repo uses a macro named `wasm_export` in `crates/js_api` to define + JS-visible APIs and attach TypeScript-specific metadata (`js_name`, + `unchecked_return_type`, `param_description`, `return_description`, + `preserve_js_class`). Treat those attributes as the contract for the generated + TypeScript surface. +- Some examples in README demonstrate end-to-end flows (e.g., builder setup via + `RaindexOrderBuilder`, order hash/calldata helpers). Prefer aligning those + with current tests under `packages/raindex/test/js_api` to avoid drift. diff --git a/crates/bindings/ARCHITECTURE.md b/crates/bindings/ARCHITECTURE.md index f774e0ead6..adc3772730 100644 --- a/crates/bindings/ARCHITECTURE.md +++ b/crates/bindings/ARCHITECTURE.md @@ -1,136 +1,233 @@ Rain Raindex Bindings — Architecture Summary -- Purpose: Provide strongly typed Rust bindings to the Rain Raindex Solidity contracts and small utilities for calling them from Rust (native and WASM). The crate centralizes ABI-derived types and call helpers so the rest of the workspace can construct calldata, perform reads, and expose safe JS-facing types. -- Scope: ABI-based type generation via Alloy, a read‑only provider builder with multi‑RPC fallback, and WASM interop shims (TypeScript typings + conversions). + +- Purpose: Provide strongly typed Rust bindings to the Rain Raindex Solidity + contracts and small utilities for calling them from Rust (native and WASM). + The crate centralizes ABI-derived types and call helpers so the rest of the + workspace can construct calldata, perform reads, and expose safe JS-facing + types. +- Scope: ABI-based type generation via Alloy, a read‑only provider builder with + multi‑RPC fallback, and WASM interop shims (TypeScript typings + conversions). File Layout -- Cargo.toml: Declares the crate `raindex_bindings`. Key deps: `alloy` (codegen + types + RPC), `serde` (Serialize/Deserialize), `tower` (layers), `url`, `thiserror`. For WASM builds it uses `wasm-bindgen-utils` and `wasm-bindgen-test` for tests. -- src/lib.rs: Declares contract bindings using Alloy’s `sol!` macro and re‑exports internal modules. Conditionally includes WASM modules. -- src/provider.rs: Builds a read‑only provider with multi‑RPC fallback and sensible default request fillers. -- src/js_api.rs (wasm only): JS/WASM interop. Implements wasm conversion traits and custom TypeScript interfaces for selected ABI types used in the order builder. -- src/wasm_traits.rs (wasm only): Utility trait to convert JS `BigInt` to `U256` with negative/overflow handling plus tests. + +- Cargo.toml: Declares the crate `raindex_bindings`. Key deps: `alloy` + (codegen + types + RPC), `serde` (Serialize/Deserialize), `tower` (layers), + `url`, `thiserror`. For WASM builds it uses `wasm-bindgen-utils` and + `wasm-bindgen-test` for tests. +- src/lib.rs: Declares contract bindings using Alloy’s `sol!` macro and + re‑exports internal modules. Conditionally includes WASM modules. +- src/provider.rs: Builds a read‑only provider with multi‑RPC fallback and + sensible default request fillers. +- src/js_api.rs (wasm only): JS/WASM interop. Implements wasm conversion traits + and custom TypeScript interfaces for selected ABI types used in the order + builder. +- src/wasm_traits.rs (wasm only): Utility trait to convert JS `BigInt` to `U256` + with negative/overflow handling plus tests. Generated Solidity Bindings (Alloy `sol!`) -- The crate uses `alloy::sol!` to generate Rust modules, types, and (optionally) RPC call helpers from contract ABIs produced by Foundry. ABIs are read from the repository’s `out/` directory. + +- The crate uses `alloy::sol!` to generate Rust modules, types, and (optionally) + RPC call helpers from contract ABIs produced by Foundry. ABIs are read from + the repository’s `out/` directory. - Bindings defined in `src/lib.rs`: - `IRaindexV5, "../../out/IRaindexV5.sol/IRaindexV5.json"` - - Attributes: `#![sol(all_derives = true, rpc)]`, `#![sol(extra_derives(serde::Serialize, serde::Deserialize))]`. - - Effect: Generates Rust types for all ABI structs/enums/events and RPC instance helpers for calling the contract. Adds `Serialize/Deserialize` derives for ergonomic (de)serialization. + - Attributes: `#![sol(all_derives = true, rpc)]`, + `#![sol(extra_derives(serde::Serialize, serde::Deserialize))]`. + - Effect: Generates Rust types for all ABI structs/enums/events and RPC + instance helpers for calling the contract. Adds `Serialize/Deserialize` + derives for ergonomic (de)serialization. - `Raindex, "../../out/Raindex.sol/Raindex.json"` - - Attributes: `#![sol(all_derives = true)]`, `#![sol(extra_derives(serde::Serialize, serde::Deserialize))]`. - - Effect: Same as above but without the `rpc` helpers. This is sufficient for constructing/calculating calldata (e.g., `multicallCall`) without needing a bound instance type. + - Attributes: `#![sol(all_derives = true)]`, + `#![sol(extra_derives(serde::Serialize, serde::Deserialize))]`. + - Effect: Same as above but without the `rpc` helpers. This is sufficient + for constructing/calculating calldata (e.g., `multicallCall`) without + needing a bound instance type. - `IERC20, "../../out/IERC20.sol/IERC20.json"` - Attributes: `#![sol(all_derives = true, rpc)]`. - - Effect: ERC‑20 call helpers and Rust types (e.g., `approveCall`, `allowanceCall`) with RPC instance support. + - Effect: ERC‑20 call helpers and Rust types (e.g., `approveCall`, + `allowanceCall`) with RPC instance support. - `ERC20, "../../out/ERC20.sol/ERC20.json"` - Attributes: `#![sol(all_derives = true)]`. - - Effect: Full types for concrete ERC‑20; used for calldata construction and decoding when instance helpers aren’t required. + - Effect: Full types for concrete ERC‑20; used for calldata construction and + decoding when instance helpers aren’t required. - Practical result of the `sol!(… rpc)` attribute: - - For `IRaindexV5` and `IERC20`, you can construct an instance bound to a provider and call methods with strong typing, for example: `let ob = IRaindexV5Instance::new(address, provider.clone()); ob.quote2(config).await?`. - - For all bindings, you can still directly use generated call structs, e.g., `IRaindexV5::removeOrder3Call { ... }.abi_encode()` or `Raindex::multicallCall { ... }`. + - For `IRaindexV5` and `IERC20`, you can construct an instance bound to a + provider and call methods with strong typing, for example: + `let ob = IRaindexV5Instance::new(address, provider.clone()); ob.quote2(config).await?`. + - For all bindings, you can still directly use generated call structs, e.g., + `IRaindexV5::removeOrder3Call { ... }.abi_encode()` or + `Raindex::multicallCall { ... }`. - Derives and defaults: - - `all_derives = true` enables useful traits on generated types, including `Clone`, `Debug`, `Default`, `Eq`, `PartialEq`, and more, which the codebase relies on (e.g., `OrderV4::default()`). - - `extra_derives(serde::Serialize, serde::Deserialize)` ensures all ABI types can be serialized to/from JSON, which is critical for CLI/builder I/O and WASM interop. + - `all_derives = true` enables useful traits on generated types, including + `Clone`, `Debug`, `Default`, `Eq`, `PartialEq`, and more, which the codebase + relies on (e.g., `OrderV4::default()`). + - `extra_derives(serde::Serialize, serde::Deserialize)` ensures all ABI types + can be serialized to/from JSON, which is critical for CLI/builder I/O and + WASM interop. ABI Source of Truth -- The referenced JSON files under `out/` are produced by Foundry (`forge build`). If ABIs change, re‑build the contracts so `out/.../*.json` stays in sync. The `sol!` macro reads these on compile. + +- The referenced JSON files under `out/` are produced by Foundry + (`forge build`). If ABIs change, re‑build the contracts so `out/.../*.json` + stays in sync. The `sol!` macro reads these on compile. Provider Utilities (`src/provider.rs`) + - Type alias - `pub type ReadProvider = FillProvider, AnyNetwork>;` - - Meaning: a provider stack consisting of an `RpcClient` → `RootProvider` for `AnyNetwork`, with the “recommended” fillers layered in (gas/nonce/chain-id/etc.) to auto‑complete missing call fields. + - Meaning: a provider stack consisting of an `RpcClient` → `RootProvider` for + `AnyNetwork`, with the “recommended” fillers layered in + (gas/nonce/chain-id/etc.) to auto‑complete missing call fields. - `mk_read_provider(rpcs: &[Url]) -> Result` - Accepts one or more RPC URLs for the same chain. - - Builds an HTTP transport stack wrapped with `FallbackLayer` so requests survive individual RPC outages by trying the next available transport. - - `with_active_transport_count(NonZeroUsize::new(size)?)` activates as many transports as provided URLs, enabling concurrent/fallback behavior. - - Connects an `RpcClient` to an `AnyNetwork` provider via `ProviderBuilder::new_with_network::().connect_client(client)`. + - Builds an HTTP transport stack wrapped with `FallbackLayer` so requests + survive individual RPC outages by trying the next available transport. + - `with_active_transport_count(NonZeroUsize::new(size)?)` activates as many + transports as provided URLs, enabling concurrent/fallback behavior. + - Connects an `RpcClient` to an `AnyNetwork` provider via + `ProviderBuilder::new_with_network::().connect_client(client)`. - Errors: - - `UrlParse`: invalid URL parsing failed (bubbled from `url` crate when constructing inputs elsewhere). + - `UrlParse`: invalid URL parsing failed (bubbled from `url` crate when + constructing inputs elsewhere). - `NoRpcs`: the input slice was empty (no transports to build). - When to use - - Use this provider for read‑only flows (e.g., quoting, allowances, balances) needing resilience across multiple public/provider endpoints. Signing/submitting transactions is performed elsewhere in the workspace; this crate doesn’t include wallet/signing. + - Use this provider for read‑only flows (e.g., quoting, allowances, balances) + needing resilience across multiple public/provider endpoints. + Signing/submitting transactions is performed elsewhere in the workspace; + this crate doesn’t include wallet/signing. WASM and JS Interop -- Conditional compilation: `src/js_api.rs` and `src/wasm_traits.rs` are compiled only for `target_family = "wasm"`. -- `src/js_api.rs` bridges key ABI types to predictable TypeScript shapes for the order builder, using the workspace’s `wasm-bindgen-utils` macros: - - `impl_wasm_traits!(T)` implements glue code to convert between Rust and JS values (e.g., Serde + wasm-bindgen interop) for the given type. - - `impl_custom_tsify!(T, "…TS interface…")` pins the exact TypeScript surface for WASM consumers. This avoids relying on auto‑generated typings that may drift with upstream changes. +- Conditional compilation: `src/js_api.rs` and `src/wasm_traits.rs` are compiled + only for `target_family = "wasm"`. + +- `src/js_api.rs` bridges key ABI types to predictable TypeScript shapes for the + order builder, using the workspace’s `wasm-bindgen-utils` macros: + - `impl_wasm_traits!(T)` implements glue code to convert between Rust and JS + values (e.g., Serde + wasm-bindgen interop) for the given type. + - `impl_custom_tsify!(T, "…TS interface…")` pins the exact TypeScript surface + for WASM consumers. This avoids relying on auto‑generated typings that may + drift with upstream changes. - Exposed interfaces (hand‑written TS definitions): - `IOV2`: `{ token: string; vaultId: string; }` - - `QuoteV2`: `{ order: OrderV4; inputIOIndex: string; outputIOIndex: string; signedContext: SignedContextV1[]; }` - - `OrderV4`: `{ owner: string; evaluable: EvaluableV4; validInputs: IOV2[]; validOutputs: IOV2[]; nonce: string; }` + - `QuoteV2`: + `{ order: OrderV4; inputIOIndex: string; outputIOIndex: string; signedContext: SignedContextV1[]; }` + - `OrderV4`: + `{ owner: string; evaluable: EvaluableV4; validInputs: IOV2[]; validOutputs: IOV2[]; nonce: string; }` - `EvaluableV4`: `{ interpreter: string; store: string; bytecode: string; }` - - `SignedContextV1`: `{ signer: string; context: string[]; signature: string; }` - - `TakeOrderConfigV4`: `{ order: OrderV4; inputIOIndex: string; outputIOIndex: string; signedContext: SignedContextV1[]; }` - - `TakeOrdersConfigV5`: `{ minimumIO: string; maximumIO: string; maximumIORatio: string; IOIsInput: string; orders: TakeOrderConfigV4[]; data: string; }` + - `SignedContextV1`: + `{ signer: string; context: string[]; signature: string; }` + - `TakeOrderConfigV4`: + `{ order: OrderV4; inputIOIndex: string; outputIOIndex: string; signedContext: SignedContextV1[]; }` + - `TakeOrdersConfigV5`: + `{ minimumIO: string; maximumIO: string; maximumIORatio: string; IOIsInput: string; orders: TakeOrderConfigV4[]; data: string; }` - Why many fields are `string` in TS - - Large numeric values (e.g., `U256`) are represented as strings to avoid precision issues and to keep interop predictable across JS runtimes. Hex strings are used for byte data. This matches how the rest of the workspace serializes on the boundary. + - Large numeric values (e.g., `U256`) are represented as strings to avoid + precision issues and to keep interop predictable across JS runtimes. Hex + strings are used for byte data. This matches how the rest of the workspace + serializes on the boundary. - WASM tests (in `src/js_api.rs`) - - Use `wasm-bindgen-test` to validate that the serialized JS values expose exactly the properties declared by the TS interfaces (e.g., `'owner' in obj`). The tests create default Rust values, convert with `to_js_value`, and assert property presence. + - Use `wasm-bindgen-test` to validate that the serialized JS values expose + exactly the properties declared by the TS interfaces (e.g., + `'owner' in obj`). The tests create default Rust values, convert with + `to_js_value`, and assert property presence. WASM Numeric Conversion (`src/wasm_traits.rs`) + - Trait: `TryIntoU256` for JS `BigInt` → `U256` conversion. - - Implementation parses the stringified `BigInt` into `U256` using Alloy’s `ruint` parser. + - Implementation parses the stringified `BigInt` into `U256` using Alloy’s + `ruint` parser. - Error handling covers: - Negative values → `ParseError::InvalidDigit('-')`. - Overflow beyond `U256::MAX` → `ParseError::BaseConvertError(Overflow)`. - - Tests cover `0`, a small positive, `U256::MAX`, overflow (`2^256`), and negatives. + - Tests cover `0`, a small positive, `U256::MAX`, overflow (`2^256`), and + negatives. How This Crate Is Used Elsewhere + - Quote engine (`crates/quote`): - Imports `IRaindexV5::IRaindexV5Instance` and `mk_read_provider`. - - Binds the instance to a provider and calls `quote2` for many orders via Alloy’s multicall helper. + - Binds the instance to a provider and calls `quote2` for many orders via + Alloy’s multicall helper. - Common utilities (`crates/common`): - - Uses ABI‑generated call structs (e.g., `deposit3Call`, `withdraw3Call`, `removeOrder3Call`, `IERC20::approveCall`) to build calldata for transactions. + - Uses ABI‑generated call structs (e.g., `deposit3Call`, `withdraw3Call`, + `removeOrder3Call`, `IERC20::approveCall`) to build calldata for + transactions. - JS API (`crates/js_api`): - - Builds order builder calldata for approvals/deposits/add‑order and uses call structs like `Raindex::multicallCall` without needing on‑chain RPC instance helpers. + - Builds order builder calldata for approvals/deposits/add‑order and uses call + structs like `Raindex::multicallCall` without needing on‑chain RPC instance + helpers. - CLI (`crates/cli`): - - Consumes ABI struct types such as `OrderV4` and `IOV2` to construct orders from user inputs. + - Consumes ABI struct types such as `OrderV4` and `IOV2` to construct orders + from user inputs. Design Choices and Rationale -- Keep bindings centralized: All ABI structs and call helpers live in one place so downstream crates share a single, consistent type system. + +- Keep bindings centralized: All ABI structs and call helpers live in one place + so downstream crates share a single, consistent type system. - Split `rpc` vs. non‑`rpc` bindings: - `IRaindexV5`/`IERC20` include RPC instance helpers for ergonomic reads. - - `Raindex`/`ERC20` are included without `rpc` when only calldata construction/decoding is required. -- Provider is read‑only by design: This crate does not handle signing or nonce management beyond auto‑fillers. Submission/signature flows live in other crates. -- WASM boundary is explicit: Hand‑authored TS interfaces lock the surface area for the webapp, preventing accidental breaking changes from codegen drift. + - `Raindex`/`ERC20` are included without `rpc` when only calldata + construction/decoding is required. +- Provider is read‑only by design: This crate does not handle signing or nonce + management beyond auto‑fillers. Submission/signature flows live in other + crates. +- WASM boundary is explicit: Hand‑authored TS interfaces lock the surface area + for the webapp, preventing accidental breaking changes from codegen drift. Error Handling + - `ReadProviderError` enumerates provider construction failures: - `UrlParse(url::ParseError)` and `NoRpcs`. -- ABI call errors, revert decoding, and multicall aggregation are handled in consumer crates (e.g., `quote`), leveraging these bindings for encoding/decoding. +- ABI call errors, revert decoding, and multicall aggregation are handled in + consumer crates (e.g., `quote`), leveraging these bindings for + encoding/decoding. Build and Test + - Build (workspace): `nix develop -c cargo build -p raindex_bindings`. - Tests (native and wasm; wasm executed via runner in the flake): - Native: `nix develop -c cargo test -p raindex_bindings`. - - WASM: the workspace’s Nix config sets `CARGO_TARGET_WASM32_UNKNOWN_UNKNOWN_RUNNER='wasm-bindgen-test-runner'` and runs `cargo test --target wasm32-unknown-unknown -p raindex_bindings`. + - WASM: the workspace’s Nix config sets + `CARGO_TARGET_WASM32_UNKNOWN_UNKNOWN_RUNNER='wasm-bindgen-test-runner'` and + runs `cargo test --target wasm32-unknown-unknown -p raindex_bindings`. Examples + - Constructing a read provider and querying via an instance (native): - - Parse URLs to `url::Url` and build: `let provider = mk_read_provider(&rpcs)?;` - - Bind to a raindex: `let ob = IRaindexV5Instance::new(raindex_addr, provider.clone());` + - Parse URLs to `url::Url` and build: + `let provider = mk_read_provider(&rpcs)?;` + - Bind to a raindex: + `let ob = IRaindexV5Instance::new(raindex_addr, provider.clone());` - Call a view: `let quote = ob.quote2(config).await?;` - Building calldata without an instance: - `use raindex_bindings::IRaindexV5::removeOrder3Call;` - - Construct the struct and encode: `let bytes = removeOrder3Call { order, tasks }.abi_encode();` + - Construct the struct and encode: + `let bytes = removeOrder3Call { order, tasks }.abi_encode();` Limitations and Notes -- Not a signer: The provider is for reads; transaction signing/broadcast is out of scope. -- Assumes ABIs are current: If Foundry output changes, re‑build before compiling Rust. -- `AnyNetwork` provider: Consumers are responsible for ensuring the supplied RPCs point to the intended chain. + +- Not a signer: The provider is for reads; transaction signing/broadcast is out + of scope. +- Assumes ABIs are current: If Foundry output changes, re‑build before compiling + Rust. +- `AnyNetwork` provider: Consumers are responsible for ensuring the supplied + RPCs point to the intended chain. Updating Bindings -- Modify the Solidity contracts as needed, run `nix develop -c forge build`, then rebuild Rust. If new structs/functions are added to the ABIs, they will appear under the corresponding Rust modules after recompilation. Add/update WASM TS interfaces in `src/js_api.rs` as needed for order builder usage. +- Modify the Solidity contracts as needed, run `nix develop -c forge build`, + then rebuild Rust. If new structs/functions are added to the ABIs, they will + appear under the corresponding Rust modules after recompilation. Add/update + WASM TS interfaces in `src/js_api.rs` as needed for order builder usage. diff --git a/crates/bindings/abis/ERC20.json b/crates/bindings/abis/ERC20.json new file mode 100644 index 0000000000..b65fe63720 --- /dev/null +++ b/crates/bindings/abis/ERC20.json @@ -0,0 +1,312 @@ +{ + "abi": [ + { + "type": "function", + "name": "allowance", + "inputs": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "spender", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "approve", + "inputs": [ + { + "name": "spender", + "type": "address", + "internalType": "address" + }, + { + "name": "value", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "balanceOf", + "inputs": [ + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "decimals", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint8", + "internalType": "uint8" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "name", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "string", + "internalType": "string" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "symbol", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "string", + "internalType": "string" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "totalSupply", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "transfer", + "inputs": [ + { + "name": "to", + "type": "address", + "internalType": "address" + }, + { + "name": "value", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "transferFrom", + "inputs": [ + { + "name": "from", + "type": "address", + "internalType": "address" + }, + { + "name": "to", + "type": "address", + "internalType": "address" + }, + { + "name": "value", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "event", + "name": "Approval", + "inputs": [ + { + "name": "owner", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "spender", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "value", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Transfer", + "inputs": [ + { + "name": "from", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "to", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "value", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "ERC20InsufficientAllowance", + "inputs": [ + { + "name": "spender", + "type": "address", + "internalType": "address" + }, + { + "name": "allowance", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "needed", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "ERC20InsufficientBalance", + "inputs": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + }, + { + "name": "balance", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "needed", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "ERC20InvalidApprover", + "inputs": [ + { + "name": "approver", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ERC20InvalidReceiver", + "inputs": [ + { + "name": "receiver", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ERC20InvalidSender", + "inputs": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ERC20InvalidSpender", + "inputs": [ + { + "name": "spender", + "type": "address", + "internalType": "address" + } + ] + } + ] +} diff --git a/crates/bindings/abis/IERC20Metadata.json b/crates/bindings/abis/IERC20Metadata.json new file mode 100644 index 0000000000..9cf0433269 --- /dev/null +++ b/crates/bindings/abis/IERC20Metadata.json @@ -0,0 +1,226 @@ +{ + "abi": [ + { + "type": "function", + "name": "allowance", + "inputs": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "spender", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "approve", + "inputs": [ + { + "name": "spender", + "type": "address", + "internalType": "address" + }, + { + "name": "value", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "balanceOf", + "inputs": [ + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "decimals", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint8", + "internalType": "uint8" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "name", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "string", + "internalType": "string" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "symbol", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "string", + "internalType": "string" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "totalSupply", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "transfer", + "inputs": [ + { + "name": "to", + "type": "address", + "internalType": "address" + }, + { + "name": "value", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "transferFrom", + "inputs": [ + { + "name": "from", + "type": "address", + "internalType": "address" + }, + { + "name": "to", + "type": "address", + "internalType": "address" + }, + { + "name": "value", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "event", + "name": "Approval", + "inputs": [ + { + "name": "owner", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "spender", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "value", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Transfer", + "inputs": [ + { + "name": "from", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "to", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "value", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + } + ] +} diff --git a/crates/bindings/abis/IInterpreterStoreV3.json b/crates/bindings/abis/IInterpreterStoreV3.json new file mode 100644 index 0000000000..e7ddc59f43 --- /dev/null +++ b/crates/bindings/abis/IInterpreterStoreV3.json @@ -0,0 +1,71 @@ +{ + "abi": [ + { + "type": "function", + "name": "get", + "inputs": [ + { + "name": "namespace", + "type": "uint256", + "internalType": "FullyQualifiedNamespace" + }, + { + "name": "key", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "set", + "inputs": [ + { + "name": "namespace", + "type": "uint256", + "internalType": "StateNamespace" + }, + { + "name": "kvs", + "type": "bytes32[]", + "internalType": "bytes32[]" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "event", + "name": "Set", + "inputs": [ + { + "name": "namespace", + "type": "uint256", + "indexed": false, + "internalType": "FullyQualifiedNamespace" + }, + { + "name": "key", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + }, + { + "name": "value", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + } + ], + "anonymous": false + } + ] +} diff --git a/crates/bindings/abis/IRaindexV6.json b/crates/bindings/abis/IRaindexV6.json new file mode 100644 index 0000000000..7cd8e47c5f --- /dev/null +++ b/crates/bindings/abis/IRaindexV6.json @@ -0,0 +1,1971 @@ +{ + "abi": [ + { + "type": "function", + "name": "addOrder4", + "inputs": [ + { + "name": "config", + "type": "tuple", + "internalType": "struct OrderConfigV4", + "components": [ + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "secret", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "meta", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "tasks", + "type": "tuple[]", + "internalType": "struct TaskV2[]", + "components": [ + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "signedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ] + } + ], + "outputs": [ + { + "name": "stateChanged", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "clear3", + "inputs": [ + { + "name": "alice", + "type": "tuple", + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "bob", + "type": "tuple", + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "clearConfig", + "type": "tuple", + "internalType": "struct ClearConfigV2", + "components": [ + { + "name": "aliceInputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "aliceOutputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "bobInputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "bobOutputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "aliceBountyVaultId", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "bobBountyVaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "aliceSignedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "bobSignedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "deposit4", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "depositAmount", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "tasks", + "type": "tuple[]", + "internalType": "struct TaskV2[]", + "components": [ + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "signedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "entask2", + "inputs": [ + { + "name": "tasks", + "type": "tuple[]", + "internalType": "struct TaskV2[]", + "components": [ + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "signedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "flashFee", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "flashLoan", + "inputs": [ + { + "name": "receiver", + "type": "address", + "internalType": "contract IERC3156FlashBorrower" + }, + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "data", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "maxFlashLoan", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "orderExists", + "inputs": [ + { + "name": "orderHash", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "exists", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "quote2", + "inputs": [ + { + "name": "quoteConfig", + "type": "tuple", + "internalType": "struct QuoteV2", + "components": [ + { + "name": "order", + "type": "tuple", + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "inputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "outputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "signedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ] + } + ], + "outputs": [ + { + "name": "exists", + "type": "bool", + "internalType": "bool" + }, + { + "name": "outputMax", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "ioRatio", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "removeOrder3", + "inputs": [ + { + "name": "order", + "type": "tuple", + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "tasks", + "type": "tuple[]", + "internalType": "struct TaskV2[]", + "components": [ + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "signedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ] + } + ], + "outputs": [ + { + "name": "stateChanged", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "takeOrders4", + "inputs": [ + { + "name": "config", + "type": "tuple", + "internalType": "struct TakeOrdersConfigV5", + "components": [ + { + "name": "minimumIO", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "maximumIO", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "maximumIORatio", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "IOIsInput", + "type": "bool", + "internalType": "bool" + }, + { + "name": "orders", + "type": "tuple[]", + "internalType": "struct TakeOrderConfigV4[]", + "components": [ + { + "name": "order", + "type": "tuple", + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "inputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "outputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "signedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ] + }, + { + "name": "data", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ], + "outputs": [ + { + "name": "totalTakerInput", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "totalTakerOutput", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "vaultBalance2", + "inputs": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "balance", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "withdraw4", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "targetAmount", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "tasks", + "type": "tuple[]", + "internalType": "struct TaskV2[]", + "components": [ + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "signedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "event", + "name": "AddOrderV3", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "orderHash", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + }, + { + "name": "order", + "type": "tuple", + "indexed": false, + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "AfterClearV2", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "clearStateChange", + "type": "tuple", + "indexed": false, + "internalType": "struct ClearStateChangeV2", + "components": [ + { + "name": "aliceOutput", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "bobOutput", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "aliceInput", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "bobInput", + "type": "bytes32", + "internalType": "Float" + } + ] + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ClearV3", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "alice", + "type": "tuple", + "indexed": false, + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "bob", + "type": "tuple", + "indexed": false, + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "clearConfig", + "type": "tuple", + "indexed": false, + "internalType": "struct ClearConfigV2", + "components": [ + { + "name": "aliceInputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "aliceOutputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "bobInputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "bobOutputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "aliceBountyVaultId", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "bobBountyVaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ContextV2", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[][]", + "indexed": false, + "internalType": "bytes32[][]" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "DepositV2", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + }, + { + "name": "depositAmountUint256", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OrderExceedsMaxRatio", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "owner", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "orderHash", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OrderNotFound", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "owner", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "orderHash", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OrderZeroAmount", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "owner", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "orderHash", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RemoveOrderV3", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "orderHash", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + }, + { + "name": "order", + "type": "tuple", + "indexed": false, + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "TakeOrderV3", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "config", + "type": "tuple", + "indexed": false, + "internalType": "struct TakeOrderConfigV4", + "components": [ + { + "name": "order", + "type": "tuple", + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "inputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "outputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "signedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ] + }, + { + "name": "input", + "type": "bytes32", + "indexed": false, + "internalType": "Float" + }, + { + "name": "output", + "type": "bytes32", + "indexed": false, + "internalType": "Float" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "WithdrawV2", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + }, + { + "name": "targetAmount", + "type": "bytes32", + "indexed": false, + "internalType": "Float" + }, + { + "name": "withdrawAmount", + "type": "bytes32", + "indexed": false, + "internalType": "Float" + }, + { + "name": "withdrawAmountUint256", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "NoOrders", + "inputs": [] + }, + { + "type": "error", + "name": "OrderNoHandleIO", + "inputs": [] + }, + { + "type": "error", + "name": "OrderNoInputs", + "inputs": [] + }, + { + "type": "error", + "name": "OrderNoOutputs", + "inputs": [] + }, + { + "type": "error", + "name": "OrderNoSources", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroDepositAmount", + "inputs": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "type": "error", + "name": "ZeroMaximumIO", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroVaultId", + "inputs": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ZeroWithdrawTargetAmount", + "inputs": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + } + ] +} diff --git a/crates/bindings/abis/RaindexV6.json b/crates/bindings/abis/RaindexV6.json new file mode 100644 index 0000000000..fa86240bc2 --- /dev/null +++ b/crates/bindings/abis/RaindexV6.json @@ -0,0 +1,2375 @@ +{ + "abi": [ + { + "type": "function", + "name": "addOrder4", + "inputs": [ + { + "name": "orderConfig", + "type": "tuple", + "internalType": "struct OrderConfigV4", + "components": [ + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "secret", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "meta", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "post", + "type": "tuple[]", + "internalType": "struct TaskV2[]", + "components": [ + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "signedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ] + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "clear3", + "inputs": [ + { + "name": "aliceOrder", + "type": "tuple", + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "bobOrder", + "type": "tuple", + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "clearConfig", + "type": "tuple", + "internalType": "struct ClearConfigV2", + "components": [ + { + "name": "aliceInputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "aliceOutputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "bobInputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "bobOutputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "aliceBountyVaultId", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "bobBountyVaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "aliceSignedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "bobSignedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "deposit4", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "depositAmount", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "post", + "type": "tuple[]", + "internalType": "struct TaskV2[]", + "components": [ + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "signedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "entask2", + "inputs": [ + { + "name": "post", + "type": "tuple[]", + "internalType": "struct TaskV2[]", + "components": [ + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "signedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "flashFee", + "inputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + }, + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "flashLoan", + "inputs": [ + { + "name": "receiver", + "type": "address", + "internalType": "contract IERC3156FlashBorrower" + }, + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "data", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "maxFlashLoan", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "multicall", + "inputs": [ + { + "name": "data", + "type": "bytes[]", + "internalType": "bytes[]" + } + ], + "outputs": [ + { + "name": "results", + "type": "bytes[]", + "internalType": "bytes[]" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "orderExists", + "inputs": [ + { + "name": "orderHash", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "quote2", + "inputs": [ + { + "name": "quoteConfig", + "type": "tuple", + "internalType": "struct QuoteV2", + "components": [ + { + "name": "order", + "type": "tuple", + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "inputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "outputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "signedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ] + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + }, + { + "name": "", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "removeOrder3", + "inputs": [ + { + "name": "order", + "type": "tuple", + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "post", + "type": "tuple[]", + "internalType": "struct TaskV2[]", + "components": [ + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "signedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ] + } + ], + "outputs": [ + { + "name": "stateChanged", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "supportsInterface", + "inputs": [ + { + "name": "interfaceId", + "type": "bytes4", + "internalType": "bytes4" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "takeOrders4", + "inputs": [ + { + "name": "config", + "type": "tuple", + "internalType": "struct TakeOrdersConfigV5", + "components": [ + { + "name": "minimumIO", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "maximumIO", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "maximumIORatio", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "IOIsInput", + "type": "bool", + "internalType": "bool" + }, + { + "name": "orders", + "type": "tuple[]", + "internalType": "struct TakeOrderConfigV4[]", + "components": [ + { + "name": "order", + "type": "tuple", + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "inputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "outputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "signedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ] + }, + { + "name": "data", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ], + "outputs": [ + { + "name": "totalTakerInput", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "totalTakerOutput", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "vaultBalance2", + "inputs": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "withdraw4", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "targetAmount", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "post", + "type": "tuple[]", + "internalType": "struct TaskV2[]", + "components": [ + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "signedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "event", + "name": "AddOrderV3", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "orderHash", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + }, + { + "name": "order", + "type": "tuple", + "indexed": false, + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "AfterClearV2", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "clearStateChange", + "type": "tuple", + "indexed": false, + "internalType": "struct ClearStateChangeV2", + "components": [ + { + "name": "aliceOutput", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "bobOutput", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "aliceInput", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "bobInput", + "type": "bytes32", + "internalType": "Float" + } + ] + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ClearV3", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "alice", + "type": "tuple", + "indexed": false, + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "bob", + "type": "tuple", + "indexed": false, + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "clearConfig", + "type": "tuple", + "indexed": false, + "internalType": "struct ClearConfigV2", + "components": [ + { + "name": "aliceInputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "aliceOutputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "bobInputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "bobOutputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "aliceBountyVaultId", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "bobBountyVaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ContextV2", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[][]", + "indexed": false, + "internalType": "bytes32[][]" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "DepositV2", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + }, + { + "name": "depositAmountUint256", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "MetaV1_2", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "subject", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + }, + { + "name": "meta", + "type": "bytes", + "indexed": false, + "internalType": "bytes" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OrderExceedsMaxRatio", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "owner", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "orderHash", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OrderNotFound", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "owner", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "orderHash", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OrderZeroAmount", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "owner", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "orderHash", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RemoveOrderV3", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "orderHash", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + }, + { + "name": "order", + "type": "tuple", + "indexed": false, + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "TakeOrderV3", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "config", + "type": "tuple", + "indexed": false, + "internalType": "struct TakeOrderConfigV4", + "components": [ + { + "name": "order", + "type": "tuple", + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "inputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "outputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "signedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ] + }, + { + "name": "input", + "type": "bytes32", + "indexed": false, + "internalType": "Float" + }, + { + "name": "output", + "type": "bytes32", + "indexed": false, + "internalType": "Float" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "WithdrawV2", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + }, + { + "name": "targetAmount", + "type": "bytes32", + "indexed": false, + "internalType": "Float" + }, + { + "name": "withdrawAmount", + "type": "bytes32", + "indexed": false, + "internalType": "Float" + }, + { + "name": "withdrawAmountUint256", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "AddressEmptyCode", + "inputs": [ + { + "name": "target", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ClearZeroAmount", + "inputs": [] + }, + { + "type": "error", + "name": "CoefficientOverflow", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "DivisionByZero", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "ExponentOverflow", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "ExponentUnderflow", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "FailedCall", + "inputs": [] + }, + { + "type": "error", + "name": "FixedDecimalOverflow", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + }, + { + "name": "decimals", + "type": "uint8", + "internalType": "uint8" + } + ] + }, + { + "type": "error", + "name": "FlashLenderCallbackFailed", + "inputs": [ + { + "name": "result", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "type": "error", + "name": "InvalidSignature", + "inputs": [ + { + "name": "i", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "LossyConversionToFloat", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "MaximizeOverflow", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "MinimumIO", + "inputs": [ + { + "name": "minimumIO", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "actualIO", + "type": "bytes32", + "internalType": "Float" + } + ] + }, + { + "type": "error", + "name": "MulDivOverflow", + "inputs": [ + { + "name": "x", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "y", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "denominator", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "NegativeBounty", + "inputs": [] + }, + { + "type": "error", + "name": "NegativeFixedDecimalConversion", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "NegativePull", + "inputs": [] + }, + { + "type": "error", + "name": "NegativePush", + "inputs": [] + }, + { + "type": "error", + "name": "NegativeVaultBalance", + "inputs": [ + { + "name": "vaultBalance", + "type": "bytes32", + "internalType": "Float" + } + ] + }, + { + "type": "error", + "name": "NegativeVaultBalanceChange", + "inputs": [ + { + "name": "amount", + "type": "bytes32", + "internalType": "Float" + } + ] + }, + { + "type": "error", + "name": "NoOrders", + "inputs": [] + }, + { + "type": "error", + "name": "NotOrderOwner", + "inputs": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "NotRainMetaV1", + "inputs": [ + { + "name": "unmeta", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "type": "error", + "name": "OrderNoHandleIO", + "inputs": [] + }, + { + "type": "error", + "name": "OrderNoInputs", + "inputs": [] + }, + { + "type": "error", + "name": "OrderNoOutputs", + "inputs": [] + }, + { + "type": "error", + "name": "OrderNoSources", + "inputs": [] + }, + { + "type": "error", + "name": "ReentrancyGuardReentrantCall", + "inputs": [] + }, + { + "type": "error", + "name": "SafeERC20FailedOperation", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "SameOwner", + "inputs": [] + }, + { + "type": "error", + "name": "TOFUTokenDecimalsNotDeployed", + "inputs": [ + { + "name": "expectedAddress", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "TokenDecimalsReadFailure", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "tofuOutcome", + "type": "uint8", + "internalType": "enum TOFUOutcome" + } + ] + }, + { + "type": "error", + "name": "TokenMismatch", + "inputs": [] + }, + { + "type": "error", + "name": "TokenSelfTrade", + "inputs": [] + }, + { + "type": "error", + "name": "UnsupportedCalculateOutputs", + "inputs": [ + { + "name": "outputs", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "ZeroDepositAmount", + "inputs": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "type": "error", + "name": "ZeroMaximumIO", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroVaultId", + "inputs": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ZeroWithdrawTargetAmount", + "inputs": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + } + ] +} diff --git a/crates/bindings/src/lib.rs b/crates/bindings/src/lib.rs index 3e3a6dfc22..40c701f748 100644 --- a/crates/bindings/src/lib.rs +++ b/crates/bindings/src/lib.rs @@ -3,13 +3,13 @@ use alloy::sol; sol!( #![sol(all_derives = true, rpc)] #![sol(extra_derives(serde::Serialize, serde::Deserialize))] - IRaindexV6, "../../out/IRaindexV6.sol/IRaindexV6.json" + IRaindexV6, "./abis/IRaindexV6.json" ); sol!( #![sol(all_derives = true)] #![sol(extra_derives(serde::Serialize, serde::Deserialize))] - Raindex, "../../out/RaindexV6.sol/RaindexV6.json" + Raindex, "./abis/RaindexV6.json" ); // Inline definition avoids non-deterministic artifact collision between @@ -32,18 +32,18 @@ sol!( sol!( #![sol(all_derives = true)] - ERC20, "../../out/ERC20.sol/ERC20.json" + ERC20, "./abis/ERC20.json" ); sol!( #![sol(all_derives = true, rpc)] - IERC20Metadata, "../../out/IERC20Metadata.sol/IERC20Metadata.json" + IERC20Metadata, "./abis/IERC20Metadata.json" ); sol!( #![sol(all_derives = true)] #![sol(extra_derives(serde::Serialize, serde::Deserialize))] - IInterpreterStoreV3, "../../out/IInterpreterStoreV3.sol/IInterpreterStoreV3.json" + IInterpreterStoreV3, "./abis/IInterpreterStoreV3.json" ); pub mod provider; diff --git a/crates/cli/src/commands/local_db/README.md b/crates/cli/src/commands/local_db/README.md index 80b01ca0a3..c86d5e916b 100644 --- a/crates/cli/src/commands/local_db/README.md +++ b/crates/cli/src/commands/local_db/README.md @@ -1,14 +1,25 @@ # Raindex CLI — LocalDB -The legacy subcommands in this directory have been replaced by a single orchestration entry point: `local-db sync`. It drives the entire SQLite pipeline—bootstrap, fetch, decode, apply, export, and manifest generation—using the same engine that powers the browser sync. +The legacy subcommands in this directory have been replaced by a single +orchestration entry point: `local-db sync`. It drives the entire SQLite +pipeline—bootstrap, fetch, decode, apply, export, and manifest generation—using +the same engine that powers the browser sync. ## Pipeline Overview -- Parse the Rain settings YAML to discover networks, RPCs, raindexes, and per-network sync parameters. -- Optionally download and import the most recent dump referenced by each raindex’s `local-db-remote` manifest. -- Run the local DB engine for every raindex concurrently, fetching logs via HyperRPC, decoding events, fetching token metadata, and applying the resulting SQL into a fresh SQLite database. -- Export a gzipped SQL dump for the synced state and write an aggregated `manifest.yaml` that maps release URLs to the produced dumps when all jobs succeed. + +- Parse the Rain settings YAML to discover networks, RPCs, raindexes, and + per-network sync parameters. +- Optionally download and import the most recent dump referenced by each + raindex’s `local-db-remote` manifest. +- Run the local DB engine for every raindex concurrently, fetching logs via + HyperRPC, decoding events, fetching token metadata, and applying the resulting + SQL into a fresh SQLite database. +- Export a gzipped SQL dump for the synced state and write an aggregated + `manifest.yaml` that maps release URLs to the produced dumps when all jobs + succeed. ## Usage + Run the command from the workspace root so the CLI crate is available: ```bash @@ -20,29 +31,50 @@ nix develop -c cargo run -p raindex_cli -- local-db sync \ ``` ### Arguments -- `--settings-yaml ` (required): inline contents of a valid Rain settings document. You can embed it with command substitution as shown above. + +- `--settings-yaml ` (required): inline contents of a valid Rain settings + document. You can embed it with command substitution as shown above. - `--api-token ` (required): HyperRPC API token used when fetching logs. -- `--release-base-url ` (required): base URL that will prefix the generated dump filenames inside the manifest (e.g. your CDN or GitHub release path). -- `--out-root ` (optional, default `./local-db`): directory where SQLite databases, dumps, and the manifest are written. +- `--release-base-url ` (required): base URL that will prefix the generated + dump filenames inside the manifest (e.g. your CDN or GitHub release path). +- `--out-root ` (optional, default `./local-db`): directory where SQLite + databases, dumps, and the manifest are written. ## Settings YAML Expectations + The runner consumes the same schema as `crates/cli/settings.yaml`: + - `networks`: chain metadata plus RPC endpoints used for metadata reads. -- `raindexes`: each entry must reference a `network`, declare a `deployment-block`, and point to a `local-db-remote` manifest URL. -- `local-db-remotes`: map of manifest aliases to URLs; manifests describe previously published dumps that can be used as a bootstrap baseline. -- `local-db-sync`: per-network fetch configuration (batch size, concurrency, retry policy, finality depth). +- `raindexes`: each entry must reference a `network`, declare a + `deployment-block`, and point to a `local-db-remote` manifest URL. +- `local-db-remotes`: map of manifest aliases to URLs; manifests describe + previously published dumps that can be used as a bootstrap baseline. +- `local-db-sync`: per-network fetch configuration (batch size, concurrency, + retry policy, finality depth). -Validation is handled by `raindex_app_settings`, and missing sections will surface as CLI errors before any network calls are made. +Validation is handled by `raindex_app_settings`, and missing sections will +surface as CLI errors before any network calls are made. ## Outputs + All artifacts live under `--out-root`: -- `/.db`: fresh SQLite database containing the synced state. -- `/-.sql.gz`: gzipped SQL transaction with the data delta at the synced head. -- `manifest.yaml`: generated only when every raindex finishes successfully; references each dump using the provided `--release-base-url`. -Each run starts from a clean SQLite file. When a remote manifest exposes a prior dump, it is downloaded and replayed before the new sync to avoid replaying the entire chain from genesis. +- `/.db`: fresh SQLite database containing the synced + state. +- `/-.sql.gz`: gzipped SQL transaction with + the data delta at the synced head. +- `manifest.yaml`: generated only when every raindex finishes successfully; + references each dump using the provided `--release-base-url`. + +Each run starts from a clean SQLite file. When a remote manifest exposes a prior +dump, it is downloaded and replayed before the new sync to avoid replaying the +entire chain from genesis. ## Operational Notes -- The command reports a per-raindex summary once all jobs finish; non-zero failures prevent manifest emission. -- Supported chains are limited to those exposed by HyperRPC. Providing an unsupported `chain-id` in the settings YAML will fail early. -- Upload the generated `.sql.gz` files to the location represented by `--release-base-url` before distributing `manifest.yaml`. + +- The command reports a per-raindex summary once all jobs finish; non-zero + failures prevent manifest emission. +- Supported chains are limited to those exposed by HyperRPC. Providing an + unsupported `chain-id` in the settings YAML will fail early. +- Upload the generated `.sql.gz` files to the location represented by + `--release-base-url` before distributing `manifest.yaml`. diff --git a/crates/common/ARCHITECTURE.md b/crates/common/ARCHITECTURE.md index abd7b7d5cc..054bd9f143 100644 --- a/crates/common/ARCHITECTURE.md +++ b/crates/common/ARCHITECTURE.md @@ -1,149 +1,261 @@ # raindex_common — Architecture & Reference -This crate provides the shared core for the Raindex toolchain across native (CLI, services) and WebAssembly (browser) targets. It bundles higher‑level orchestration around: +This crate provides the shared core for the Raindex toolchain across native +(CLI, services) and WebAssembly (browser) targets. It bundles higher‑level +orchestration around: - Parsing and composing Rain language (Rainlang) and DOTRAIN YAML frontmatter. -- Building and executing Raindex contract calls (add/remove orders, deposit, withdraw), including Ledger support on native. -- Querying raindex state via the subgraph and flattening results for display/CSV export. -- A WASM‑friendly API surface for UI apps (via `wasm_bindgen_utils` and `tsify`). -- Developer ergonomics: LSP helpers, fuzz/unit‑test runners, and EVM fork utilities to parse/evaluate Rainlang and replay transactions. - -The library is built as `rlib` and `cdylib`. A Git commit identifier is embedded as `GH_COMMIT_SHA` for traceability. - +- Building and executing Raindex contract calls (add/remove orders, deposit, + withdraw), including Ledger support on native. +- Querying raindex state via the subgraph and flattening results for display/CSV + export. +- A WASM‑friendly API surface for UI apps (via `wasm_bindgen_utils` and + `tsify`). +- Developer ergonomics: LSP helpers, fuzz/unit‑test runners, and EVM fork + utilities to parse/evaluate Rainlang and replay transactions. + +The library is built as `rlib` and `cdylib`. A Git commit identifier is embedded +as `GH_COMMIT_SHA` for traceability. ## Module Overview -- `add_order` — Compose Rainlang from DOTRAIN, parse to bytecode via on‑chain Parser, generate `addOrder3` call parameters, execute or simulate on a fork. -- `remove_order` — Convert subgraph `SgOrder` to `removeOrder3` call, execute or return calldata. -- `deposit` — ERC20 allowance check/approve and `deposit3` call builder/executor. +- `add_order` — Compose Rainlang from DOTRAIN, parse to bytecode via on‑chain + Parser, generate `addOrder3` call parameters, execute or simulate on a fork. +- `remove_order` — Convert subgraph `SgOrder` to `removeOrder3` call, execute or + return calldata. +- `deposit` — ERC20 allowance check/approve and `deposit3` call + builder/executor. - `withdraw` — `withdraw3` call builder/executor and calldata generator. -- `transaction` — Shared tx args (RPCs, chain ID, fees), Ledger provider creation (native), and `WriteContractParameters` helpers. -- `erc20` — Typed ERC20 reads (decimals/name/symbol/allowance/balance), multicall token info, and robust revert decoding. +- `transaction` — Shared tx args (RPCs, chain ID, fees), Ledger provider + creation (native), and `WriteContractParameters` helpers. +- `erc20` — Typed ERC20 reads (decimals/name/symbol/allowance/balance), + multicall token info, and robust revert decoding. - `subgraph` — Thin wrapper to instantiate a raindex subgraph client from a URL. -- `raindex_client/*` — High‑level client over raindex YAML config: find networks/raindexes, fetch orders, vaults, trades, transactions; quote orders; prepare batch withdraw calldata; expose WASM‑friendly structs. The `local_db/` subtree is split into `state.rs` (runtime state, query routing via `LocalDbState`/`QuerySource`/`SyncReadiness`) and `status.rs` (UI status‑reporting types). -- `dotrain_order` — Parse and validate a DOTRAIN config; compose scenarios/deployments to Rainlang; fetch authoring metadata and pragma words; merge additional settings. -- `rainlang` — Compose Rainlang from a DOTRAIN string + bindings; optional fork‑based parser that returns encoded bytecode. -- `dotrain_add_order_lsp` — Language‑services integration for Rainlang/DOTRAIN (hover, completion, diagnostics, and fork‑parse problems). -- `types/*` — Flattened view models for CSV/export: orders, order takes, vault balance changes, token vaults, plus shared errors and constants. +- `raindex_client/*` — High‑level client over raindex YAML config: find + networks/raindexes, fetch orders, vaults, trades, transactions; quote orders; + prepare batch withdraw calldata; expose WASM‑friendly structs. The `local_db/` + subtree is split into `state.rs` (runtime state, query routing via + `LocalDbState`/`QuerySource`/`SyncReadiness`) and `status.rs` (UI + status‑reporting types). +- `dotrain_order` — Parse and validate a DOTRAIN config; compose + scenarios/deployments to Rainlang; fetch authoring metadata and pragma words; + merge additional settings. +- `rainlang` — Compose Rainlang from a DOTRAIN string + bindings; optional + fork‑based parser that returns encoded bytecode. +- `dotrain_add_order_lsp` — Language‑services integration for Rainlang/DOTRAIN + (hover, completion, diagnostics, and fork‑parse problems). +- `types/*` — Flattened view models for CSV/export: orders, order takes, vault + balance changes, token vaults, plus shared errors and constants. - `csv` — Generic `TryIntoCsv` trait for serializing vectors of typed rows. -- `utils/*` — Formatting helpers for amounts (`U256` → string) and timestamps (seconds → UTC string). -- `fuzz` — Fuzzing/evaluation harness over Rainlang entrypoints and charts (native), with WASM‑serializable result shapes. -- `replays` — EVM fork utilities to replay an on‑chain transaction and convert raw traces to `RainEvalResult`. -- `unit_tests` — Programmatic runner that executes DOTRAIN pre/calculate‑io/handle‑io/post entrypoints on a fork for deterministic tests. +- `utils/*` — Formatting helpers for amounts (`U256` → string) and timestamps + (seconds → UTC string). +- `fuzz` — Fuzzing/evaluation harness over Rainlang entrypoints and charts + (native), with WASM‑serializable result shapes. +- `replays` — EVM fork utilities to replay an on‑chain transaction and convert + raw traces to `RainEvalResult`. +- `unit_tests` — Programmatic runner that executes DOTRAIN + pre/calculate‑io/handle‑io/post entrypoints on a fork for deterministic tests. - `test_helpers` — Sample DOTRAIN used in tests. - `lib` — Public module wiring, re‑exports, and `GH_COMMIT_SHA` env binding. Target gating is used extensively: -- Native only: Ledger, EVM forking/eval, transaction execution, some tests. -- WASM: `tsify` types and `wasm_export` bindings, alternate `tokio` features, and JS‑oriented getters. +- Native only: Ledger, EVM forking/eval, transaction execution, some tests. +- WASM: `tsify` types and `wasm_export` bindings, alternate `tokio` features, + and JS‑oriented getters. ## Key Data Flow & Responsibilities ### 1) DOTRAIN → Rainlang → Bytecode (add_order) -- Inputs: DOTRAIN (YAML frontmatter + Rainlang sections), selected scenario/deployment (from `raindex_app_settings`), and bindings. -- `AddOrderArgs::compose_to_rainlang` uses `rainlang::compose_to_rainlang` to produce the Rainlang snippet for order entrypoints (`calculate-io`, `handle-io`). -- Parser address is discovered via `DISPair::from_deployer`; the Rainlang text is parsed by `ParserV2::parse_text` over provided RPCs to produce bytecode. -- Metadata is generated as a Rain Meta V1 document containing `RainlangSourceV1` and CBOR‑encoded with `rain-metadata`. -- The `addOrder3` call is assembled with Evaluable (interpreter/store/bytecode), inputs/outputs vaults, random nonce/secret, and a post task (`handle-add-order`) compiled similarly. + +- Inputs: DOTRAIN (YAML frontmatter + Rainlang sections), selected + scenario/deployment (from `raindex_app_settings`), and bindings. +- `AddOrderArgs::compose_to_rainlang` uses `rainlang::compose_to_rainlang` to + produce the Rainlang snippet for order entrypoints (`calculate-io`, + `handle-io`). +- Parser address is discovered via `DISPair::from_deployer`; the Rainlang text + is parsed by `ParserV2::parse_text` over provided RPCs to produce bytecode. +- Metadata is generated as a Rain Meta V1 document containing `RainlangSourceV1` + and CBOR‑encoded with `rain-metadata`. +- The `addOrder3` call is assembled with Evaluable (interpreter/store/bytecode), + inputs/outputs vaults, random nonce/secret, and a post task + (`handle-add-order`) compiled similarly. - Execution paths: - - Native: Build `WriteContractParameters` and execute with `WriteTransaction` via a Ledger provider, or simulate on a fork (`Forker`) per RPC. + - Native: Build `WriteContractParameters` and execute with `WriteTransaction` + via a Ledger provider, or simulate on a fork (`Forker`) per RPC. - Any target: Return ABI‑encoded calldata for external submission. ### 2) Remove Order -- `RemoveOrderArgs` converts `SgOrder` to `removeOrder3Call` via subgraph traits. -- Native execution mirrors `add_order` (Ledger provider + `WriteTransaction`), or return calldata only. + +- `RemoveOrderArgs` converts `SgOrder` to `removeOrder3Call` via subgraph + traits. +- Native execution mirrors `add_order` (Ledger provider + `WriteTransaction`), + or return calldata only. ### 3) Deposit / Approve + - `DepositArgs` holds token, vaultId, `Float` amount, and decimals. - `read_allowance` uses a readable provider to query ERC20 allowance. -- If allowance differs from the desired amount, `execute_approve` submits an ERC20 `approve` that overwrites the allowance with the target value. -- `execute_deposit` builds and submits `deposit3` with the exact `Float` amount converted to fixed decimal units. +- If allowance differs from the desired amount, `execute_approve` submits an + ERC20 `approve` that overwrites the allowance with the target value. +- `execute_deposit` builds and submits `deposit3` with the exact `Float` amount + converted to fixed decimal units. - Both execution functions accept a status callback for progress. ### 4) Withdraw -- `WithdrawArgs` maps directly to `withdraw3` call. Provides execution and calldata helpers. + +- `WithdrawArgs` maps directly to `withdraw3` call. Provides execution and + calldata helpers. ### 5) Transaction Plumbing -- `TransactionArgs` encapsulates RPCs, chain ID, optional Ledger derivation index, and EIP‑1559 fee caps. + +- `TransactionArgs` encapsulates RPCs, chain ID, optional Ledger derivation + index, and EIP‑1559 fee caps. - `try_fill_chain_id` reads chain ID via the readable client when absent. -- Native: `try_into_ledger_client` picks the first working RPC, connects a Ledger signer/provider, and returns the signer address. -- `try_into_write_contract_parameters` packages any typed `SolCall` into the `WriteContractParameters` used by `WriteTransaction`. +- Native: `try_into_ledger_client` picks the first working RPC, connects a + Ledger signer/provider, and returns the signer address. +- `try_into_write_contract_parameters` packages any typed `SolCall` into the + `WriteContractParameters` used by `WriteTransaction`. ### 6) ERC20 Reads & Error Decoding -- `ERC20` wraps an `IERC20Instance` over a read provider (`mk_read_provider`). Methods: `decimals`, `name`, `symbol`, `allowance`, `balanceOf`, and `token_info` (multicall over all three metadata calls). -- Revert data is decoded via `rain_error_decoding` to produce human‑readable errors. For multicall `CallFailed`, the revert is decoded and mapped. + +- `ERC20` wraps an `IERC20Instance` over a read provider (`mk_read_provider`). + Methods: `decimals`, `name`, `symbol`, `allowance`, `balanceOf`, and + `token_info` (multicall over all three metadata calls). +- Revert data is decoded via `rain_error_decoding` to produce human‑readable + errors. For multicall `CallFailed`, the revert is decoded and mapped. ### 7) Subgraph Client Creation -- `SubgraphArgs::to_subgraph_client` parses the URL and returns a raindex subgraph client bound to that endpoint. + +- `SubgraphArgs::to_subgraph_client` parses the URL and returns a raindex + subgraph client bound to that endpoint. ### 8) Raindex Client (raindex YAML–driven API) -- `RaindexClient::create` (async on WASM, aliased to `new` in JS) parses one or more raindex YAML strings using `RaindexYaml`, optionally with full validation. When the YAML declares `local-db-sync` sections and DB callbacks are provided, the constructor automatically sets up the local DB and starts the sync scheduler. -- `LocalDbState` encapsulates the local DB handle, scheduler, `SyncReadiness` (tracks which chains have completed a sync cycle), and the set of configured chain IDs. Query routing uses `QuerySource::LocalDb` vs `QuerySource::Subgraph` — each chain is routed to exactly one source based on configuration and readiness. -- Derives a map of networks and raindexes to build `MultiSubgraphArgs` groupings for cross‑network queries. + +- `RaindexClient::create` (async on WASM, aliased to `new` in JS) parses one or + more raindex YAML strings using `RaindexYaml`, optionally with full + validation. When the YAML declares `local-db-sync` sections and DB callbacks + are provided, the constructor automatically sets up the local DB and starts + the sync scheduler. +- `LocalDbState` encapsulates the local DB handle, scheduler, `SyncReadiness` + (tracks which chains have completed a sync cycle), and the set of configured + chain IDs. Query routing uses `QuerySource::LocalDb` vs + `QuerySource::Subgraph` — each chain is routed to exactly one source based on + configuration and readiness. +- Derives a map of networks and raindexes to build `MultiSubgraphArgs` groupings + for cross‑network queries. - Exposed operations (with WASM bindings): - - YAML accessors: get unique chain IDs, networks, raindexes by address, accounts, and RPC URLs. - - Orders: list with filters/pagination across networks, fetch by hash, fetch orders created in a transaction. - - Quotes: compute per‑pair quotes for an order (`get_order_quotes` under the hood), with formatted ratios and inverses. - - Vaults: list/query vaults for an order or raindex, fetch balance changes, prepare withdraw multicall calldata, format balances. - - Trades and transactions: list trades (with optional time bounds), fetch trade detail, transaction detail. -- Conversion helpers map subgraph types (`Sg*`) to WASM/JS‑friendly shapes (`Raindex*`) and back when needed. -- Error surface `RaindexError` normalizes failures from YAML parsing, hex parsing, subgraph network errors, ERC20 reads, float/parse errors, etc., and provides user‑facing messages via `to_readable_msg`. + - YAML accessors: get unique chain IDs, networks, raindexes by address, + accounts, and RPC URLs. + - Orders: list with filters/pagination across networks, fetch by hash, fetch + orders created in a transaction. + - Quotes: compute per‑pair quotes for an order (`get_order_quotes` under the + hood), with formatted ratios and inverses. + - Vaults: list/query vaults for an order or raindex, fetch balance changes, + prepare withdraw multicall calldata, format balances. + - Trades and transactions: list trades (with optional time bounds), fetch + trade detail, transaction detail. +- Conversion helpers map subgraph types (`Sg*`) to WASM/JS‑friendly shapes + (`Raindex*`) and back when needed. +- Error surface `RaindexError` normalizes failures from YAML parsing, hex + parsing, subgraph network errors, ERC20 reads, float/parse errors, etc., and + provides user‑facing messages via `to_readable_msg`. ### 9) DOTRAIN Order Utilities -- `DotrainOrder::create` extracts frontmatter from a DOTRAIN text, validates spec version, hydrates remote networks/tokens if configured, and builds both `DotrainYaml` and `RaindexYaml` caches. + +- `DotrainOrder::create` extracts frontmatter from a DOTRAIN text, validates + spec version, hydrates remote networks/tokens if configured, and builds both + `DotrainYaml` and `RaindexYaml` caches. - Compose helpers: - - `compose_scenario_to_rainlang` and `compose_deployment_to_rainlang` create Rainlang with scenario/deployment bindings applied. - - `compose_scenario_to_post_task_rainlang` produces post‑task (`handle-add-order`) Rainlang. + - `compose_scenario_to_rainlang` and `compose_deployment_to_rainlang` create + Rainlang with scenario/deployment bindings applied. + - `compose_scenario_to_post_task_rainlang` produces post‑task + (`handle-add-order`) Rainlang. - Queries: - - `get_pragmas_for_scenario` and `get_contract_authoring_meta_v2_for_scenario` read pragma addresses and authoring metadata (supports metaboard subgraph). + - `get_pragmas_for_scenario` and `get_contract_authoring_meta_v2_for_scenario` + read pragma addresses and authoring metadata (supports metaboard subgraph). - Errors map to readable messages for UI consumption. ### 10) Rainlang Composition & Fork Parse -- `rainlang::compose_to_rainlang` uses language services’ meta store and `RainDocument::create` with optional rebinding to render specified entrypoints. -- Native: `fork_parse::parse_rainlang_on_fork` lazily initializes a global `FORKER`, selects/creates an EVM fork per RPC, and returns ABI‑encoded expression config. Reverts are decoded to typed errors. + +- `rainlang::compose_to_rainlang` uses language services’ meta store and + `RainDocument::create` with optional rebinding to render specified + entrypoints. +- Native: `fork_parse::parse_rainlang_on_fork` lazily initializes a global + `FORKER`, selects/creates an EVM fork per RPC, and returns ABI‑encoded + expression config. Reverts are decoded to typed errors. ### 11) LSP Integration for Add Order -- `DotrainAddOrderLsp` stores a `TextDocumentItem` plus optional bindings. Methods: + +- `DotrainAddOrderLsp` stores a `TextDocumentItem` plus optional bindings. + Methods: - `hover`, `completion` via `RainLanguageServices`. - - `problems` composes entrypoints; if composition fails, reports structured errors; else optionally fork‑parses Rainlang against a selected deployment to provide diagnostics. + - `problems` composes entrypoints; if composition fails, reports structured + errors; else optionally fork‑parses Rainlang against a selected deployment + to provide diagnostics. ### 12) Fuzzing, Unit Tests, and Replays -- `fuzz::FuzzRunner` composes entrypoints for scenarios (replacing elided bindings with random data), creates a fork at configured block(s), and runs multiple iterations. Results flatten to tables for charting. -- `unit_tests::TestRunner` orchestrates a four‑phase evaluation (pre → calculate‑io → handle‑io → post) with controlled context injection; designed for deterministic contract‑level testing of Rainlang logic. -- `replays::TradeReplayer` builds a fork and replays a given transaction hash, returning converted `RainEvalResult` traces. + +- `fuzz::FuzzRunner` composes entrypoints for scenarios (replacing elided + bindings with random data), creates a fork at configured block(s), and runs + multiple iterations. Results flatten to tables for charting. +- `unit_tests::TestRunner` orchestrates a four‑phase evaluation (pre → + calculate‑io → handle‑io → post) with controlled context injection; designed + for deterministic contract‑level testing of Rainlang logic. +- `replays::TradeReplayer` builds a fork and replays a given transaction hash, + returning converted `RainEvalResult` traces. ### 13) Flattened Types and CSV -- `types/order_detail_extended.rs` — Wraps `SgOrder` and optionally decoded Rainlang source from meta. -- `types/orders_list_flattened.rs` — `OrderFlattened` for list views: timestamps, owner, interpreters/stores, valid vault IDs and token symbols, and first add‑event transaction, with `TryFrom`. -- `types/order_takes_list_flattened.rs` — `OrderTakeFlattened` summarizing a trade (input/output amounts, tokens, and formatted values). -- `types/vault_balance_change_flattened.rs` — Normalized view of vault balance changes across deposits/withdrawals/trades with signed formatted amounts and type labels. -- `types/token_vault_flattened.rs` — Vault + token metadata and formatted balance. -- All implement `TryIntoCsv` on `Vec` to produce headers + rows via `serde::Serialize` and `csv::Writer`. + +- `types/order_detail_extended.rs` — Wraps `SgOrder` and optionally decoded + Rainlang source from meta. +- `types/orders_list_flattened.rs` — `OrderFlattened` for list views: + timestamps, owner, interpreters/stores, valid vault IDs and token symbols, and + first add‑event transaction, with `TryFrom`. +- `types/order_takes_list_flattened.rs` — `OrderTakeFlattened` summarizing a + trade (input/output amounts, tokens, and formatted values). +- `types/vault_balance_change_flattened.rs` — Normalized view of vault balance + changes across deposits/withdrawals/trades with signed formatted amounts and + type labels. +- `types/token_vault_flattened.rs` — Vault + token metadata and formatted + balance. +- All implement `TryIntoCsv` on `Vec` to produce headers + rows via + `serde::Serialize` and `csv::Writer`. ### 14) Utilities -- `utils/amount_formatter.rs` — `format_amount_u256` using `alloy::primitives::utils::format_units` and `remove_trailing_zeros` to clean fixed‑decimal strings. Error type wraps unit and parse errors. -- `utils/timestamp.rs` — Formatting helpers: `format_bigint_timestamp_display` (string seconds → UTC) and `format_timestamp_display_utc` with strict bounds and parse errors. +- `utils/amount_formatter.rs` — `format_amount_u256` using + `alloy::primitives::utils::format_units` and `remove_trailing_zeros` to clean + fixed‑decimal strings. Error type wraps unit and parse errors. +- `utils/timestamp.rs` — Formatting helpers: `format_bigint_timestamp_display` + (string seconds → UTC) and `format_timestamp_display_utc` with strict bounds + and parse errors. ## Public API Highlights - Call builders and calldata - `AddOrderArgs::{try_into_call, get_add_order_call_parameters, execute, get_add_order_calldata, simulate_execute}` - `RemoveOrderArgs::{execute, get_rm_order_calldata}` - - `DepositArgs::{read_allowance, execute_approve, execute_deposit}` and `WithdrawArgs::{execute, get_withdraw_calldata}` + - `DepositArgs::{read_allowance, execute_approve, execute_deposit}` and + `WithdrawArgs::{execute, get_withdraw_calldata}` - `RaindexVaultsList::get_withdraw_calldata` for multicall batch withdraws - DOTRAIN/Rainlang - - `DotrainOrder::create`, `compose_*_to_rainlang`, YAML accessors, pragma/meta queries - - `rainlang::compose_to_rainlang` and native `fork_parse::parse_rainlang_on_fork` + - `DotrainOrder::create`, `compose_*_to_rainlang`, YAML accessors, pragma/meta + queries + - `rainlang::compose_to_rainlang` and native + `fork_parse::parse_rainlang_on_fork` - Raindex client (selected) - - YAML: `get_unique_chain_ids`, `get_all_networks`, `get_network_by_chain_id`, `get_raindex_by_address`, `get_all_accounts` + - YAML: `get_unique_chain_ids`, `get_all_networks`, `get_network_by_chain_id`, + `get_raindex_by_address`, `get_all_accounts` - Orders: `get_orders`, `get_order_by_hash`, `get_add_orders_for_transaction` - Quotes: `RaindexOrder::get_quotes` - - Vaults: `get_vaults_list`, `get_raindex_vaults_list`, `RaindexVault::{get_balance_changes, get_deposit_calldata, get_withdraw_calldata}`, `RaindexVault::get_account_balance` - - Trades/Tx: `RaindexOrder::{get_trades_list, get_trades_count}`, `RaindexOrder::get_trade_detail`, `RaindexClient::get_transaction` + - Vaults: `get_vaults_list`, `get_raindex_vaults_list`, + `RaindexVault::{get_balance_changes, get_deposit_calldata, get_withdraw_calldata}`, + `RaindexVault::get_account_balance` + - Trades/Tx: `RaindexOrder::{get_trades_list, get_trades_count}`, + `RaindexOrder::get_trade_detail`, `RaindexClient::get_transaction` - CSV & types - `TryIntoCsv` implemented on vectors of flattened types for export. @@ -154,110 +266,144 @@ Target gating is used extensively: - `types::vault::NO_SYMBOL` — fallback when token symbol is absent - `GH_COMMIT_SHA` — compile‑time commit id - ## Error Handling Each domain defines focused error enums with `thiserror::Error`: -- `AddOrderArgsError`, `RemoveOrderArgsError`, `DepositError`, `WritableTransactionExecuteError`, `TransactionArgsError` — transactional and parsing failures. -- `erc20::Error` — revert decoding, provider/multicall errors, and typed ABI decode errors. -- `RaindexError` — umbrella for YAML/subgraph/hex/float/amount formatting/ERC20/tx errors; exposes `to_readable_msg` for UI. -- `types::FlattenError` — conversion/formatting failures when building flattened view models. -- `TryDecodeRainlangSourceError` — meta decoding and content validation of Rainlang source. -- Fuzz/unit‑test/replay errors normalize fork issues, abi‑decoded reverts, and YAML/spec mismatches. - -Errors typically bubble with `#[from]` to preserve sources and are turned into WASM‑friendly structures via `From<...> for WasmEncodedError` where applicable. +- `AddOrderArgsError`, `RemoveOrderArgsError`, `DepositError`, + `WritableTransactionExecuteError`, `TransactionArgsError` — transactional and + parsing failures. +- `erc20::Error` — revert decoding, provider/multicall errors, and typed ABI + decode errors. +- `RaindexError` — umbrella for YAML/subgraph/hex/float/amount + formatting/ERC20/tx errors; exposes `to_readable_msg` for UI. +- `types::FlattenError` — conversion/formatting failures when building flattened + view models. +- `TryDecodeRainlangSourceError` — meta decoding and content validation of + Rainlang source. +- Fuzz/unit‑test/replay errors normalize fork issues, abi‑decoded reverts, and + YAML/spec mismatches. + +Errors typically bubble with `#[from]` to preserve sources and are turned into +WASM‑friendly structures via `From<...> for WasmEncodedError` where applicable. ## WASM vs Native Surface -- WASM builds derive `Tsify` for public structs and expose getters with JS‑friendly types (`Hex`, `Address`, `number[]`, `Map<..>`) using `wasm_bindgen_utils` annotations. +- WASM builds derive `Tsify` for public structs and expose getters with + JS‑friendly types (`Hex`, `Address`, `number[]`, `Map<..>`) using + `wasm_bindgen_utils` annotations. - Native builds enable: - `tokio` full features. - Ledger transport and provider setup for transaction execution. - - EVM forking (`rain_interpreter_eval`) to parse/eval Rainlang, simulate calls, and replay txs. - -Where functionality cannot run in WASM, equivalent calldata generation methods are provided so frontends can submit via their own providers. + - EVM forking (`rain_interpreter_eval`) to parse/eval Rainlang, simulate + calls, and replay txs. +Where functionality cannot run in WASM, equivalent calldata generation methods +are provided so frontends can submit via their own providers. ## Subgraph, YAML, and Quoting -- Subgraph clients are constructed from raindex YAML to ensure per‑network routing and naming. -- The client supports multi‑network fan‑out via `MultiRaindexSubgraphClient` and paginated queries. -- Quotes use on‑chain multicall under the hood; results are converted to `Float` and pre‑formatted strings, including inverse ratios and empty/infinite cases. - +- Subgraph clients are constructed from raindex YAML to ensure per‑network + routing and naming. +- The client supports multi‑network fan‑out via `MultiRaindexSubgraphClient` and + paginated queries. +- Quotes use on‑chain multicall under the hood; results are converted to `Float` + and pre‑formatted strings, including inverse ratios and empty/infinite cases. ## Testing & Quality Notes -- The crate has extensive unit tests across modules (including mocked RPC/subgraph) validating: +- The crate has extensive unit tests across modules (including mocked + RPC/subgraph) validating: - Error surfaces and message mapping. - ABI encoding/decoding of calls and calldata consistency. - - CSV/flattening correctness and edge cases (missing symbols, invalid timestamps, invalid hex/ABI). + - CSV/flattening correctness and edge cases (missing symbols, invalid + timestamps, invalid hex/ABI). - DOTRAIN spec version gating and settings merging. - ERC20 revert handling and multicall decoding. - EVM‑fork‑based parsing/evaluation and replay correctness (native). -- Fuzz and unit‑test runners demonstrate example patterns for evaluating Rainlang over controlled contexts. - +- Fuzz and unit‑test runners demonstrate example patterns for evaluating + Rainlang over controlled contexts. ## Notable Dependencies (workspace crates) -- `raindex_bindings` — Strongly‑typed ABI for Raindex and ERC20 contracts (`addOrder3`, `removeOrder3`, `deposit3`, `withdraw3`, multicall). -- `raindex_subgraph_client` — GraphQL types and clients for raindex data; provides `Sg*` models and helpers. -- `raindex_app_settings` — DOTRAIN/raindex YAML structures, validation, and spec versioning. +- `raindex_bindings` — Strongly‑typed ABI for Raindex and ERC20 contracts + (`addOrder3`, `removeOrder3`, `deposit3`, `withdraw3`, multicall). +- `raindex_subgraph_client` — GraphQL types and clients for raindex data; + provides `Sg*` models and helpers. +- `raindex_app_settings` — DOTRAIN/raindex YAML structures, validation, and spec + versioning. - `raindex_quote` — Batch quote engine for orders. -- `rain_interpreter_*` — Parser, eval, DISP pair, bindings used to compile/evaluate Rainlang. -- `rain_metadata` — CBOR‑encoded metadata with magic prefixes; used to embed Rainlang source. +- `rain_interpreter_*` — Parser, eval, DISP pair, bindings used to + compile/evaluate Rainlang. +- `rain_metadata` — CBOR‑encoded metadata with magic prefixes; used to embed + Rainlang source. - `rain_error_decoding` — ABI error decoding to readable types/names. -- `rain_math_float` — Arbitrary‑precision floats with hex encoding for on‑chain compatibility and pretty formatting. -- `alloy` & `alloy_ethers_typecast` — EVM primitives, providers, signers (Ledger), and Read/Write contract helpers. +- `rain_math_float` — Arbitrary‑precision floats with hex encoding for on‑chain + compatibility and pretty formatting. +- `alloy` & `alloy_ethers_typecast` — EVM primitives, providers, signers + (Ledger), and Read/Write contract helpers. - `wasm_bindgen_utils`, `tsify` — WASM/JS interop helpers and type generation. - ## Typical End‑to‑End Flows - Add an order (native or UI): - 1) Build `DotrainOrder` from DOTRAIN text; pick a deployment; build `AddOrderArgs` via `new_from_deployment`. - 2) Compose Rainlang and parse to bytecode via parser address (from `DISPair`). - 3) Generate metadata bytes and `addOrder3Call` with post task. - 4) Execute with `WriteTransaction` (native) or obtain `abi_encode()` and submit via external provider (WASM). + 1. Build `DotrainOrder` from DOTRAIN text; pick a deployment; build + `AddOrderArgs` via `new_from_deployment`. + 2. Compose Rainlang and parse to bytecode via parser address (from `DISPair`). + 3. Generate metadata bytes and `addOrder3Call` with post task. + 4. Execute with `WriteTransaction` (native) or obtain `abi_encode()` and + submit via external provider (WASM). - Remove an order: - 1) Fetch `SgOrder` from subgraph; convert to `removeOrder3Call` and execute or export calldata. + 1. Fetch `SgOrder` from subgraph; convert to `removeOrder3Call` and execute or + export calldata. - Deposit/Withdraw: - 1) For deposit, check allowance and, when it differs from the intended amount, approve the exact target before calling `deposit3`. - 2) For withdraw, construct `withdraw3` calldata or execute; batch multiple via `RaindexVaultsList::get_withdraw_calldata`. + 1. For deposit, check allowance and, when it differs from the intended amount, + approve the exact target before calling `deposit3`. + 2. For withdraw, construct `withdraw3` calldata or execute; batch multiple via + `RaindexVaultsList::get_withdraw_calldata`. - Explore raindex data in a UI: - 1) Instantiate `RaindexClient` from YAML configs. - 2) List orders across networks; fetch vaults, trades, and quotes for selected orders. - 3) Render CSV exports using `TryIntoCsv` on flattened types. - + 1. Instantiate `RaindexClient` from YAML configs. + 2. List orders across networks; fetch vaults, trades, and quotes for selected + orders. + 3. Render CSV exports using `TryIntoCsv` on flattened types. ## Constants & Build Flags -- `GH_COMMIT_SHA` is set at compile time via the `COMMIT_SHA` env var and can be displayed for “About/Version” screens. -- `crate-type = ["rlib", "cdylib"]` enables consumption as a Rust lib and a WASM/FFI‑ready dynamic library. -- Conditional `tokio` features are selected for WASM vs native targets in Cargo.toml. - +- `GH_COMMIT_SHA` is set at compile time via the `COMMIT_SHA` env var and can be + displayed for “About/Version” screens. +- `crate-type = ["rlib", "cdylib"]` enables consumption as a Rust lib and a + WASM/FFI‑ready dynamic library. +- Conditional `tokio` features are selected for WASM vs native targets in + Cargo.toml. ## Notes & Caveats -- Many error types intentionally capture inner variants to preserve exact failure causes (RPC transport vs. ABI decode vs. parse errors). UIs should prefer `to_readable_msg` for end users. -- Fork‑based helpers rely on at least one working RPC; functions return descriptive errors if all providers fail. -- Non‑WASM execution paths interact with hardware Ledger devices and therefore are compiled out for browser targets. -- Some performance‑related queries are stubbed/disabled (see TODOs referencing issue 1989) and kept for future reinstatement. - +- Many error types intentionally capture inner variants to preserve exact + failure causes (RPC transport vs. ABI decode vs. parse errors). UIs should + prefer `to_readable_msg` for end users. +- Fork‑based helpers rely on at least one working RPC; functions return + descriptive errors if all providers fail. +- Non‑WASM execution paths interact with hardware Ledger devices and therefore + are compiled out for browser targets. +- Some performance‑related queries are stubbed/disabled (see TODOs referencing + issue 1989) and kept for future reinstatement. ## File Map (quick reference) - API layers - - `src/add_order.rs`, `src/remove_order.rs`, `src/deposit.rs`, `src/withdraw.rs`, `src/transaction.rs`, `src/erc20.rs` + - `src/add_order.rs`, `src/remove_order.rs`, `src/deposit.rs`, + `src/withdraw.rs`, `src/transaction.rs`, `src/erc20.rs` - DOTRAIN/Rainlang - `src/dotrain_order.rs`, `src/rainlang.rs`, `src/dotrain_add_order_lsp.rs` - Client & data access - `src/raindex_client/` (orders, quotes, vaults, trades, transactions, YAML) - - `src/raindex_client/local_db/state.rs` (runtime state: `LocalDbState`, `QuerySource`, `SyncReadiness`, `ClassifiedChains`) - - `src/raindex_client/local_db/status.rs` (UI status types: `LocalDbStatus`, `SchedulerState`, `NetworkSyncStatus`, etc.) + - `src/raindex_client/local_db/state.rs` (runtime state: `LocalDbState`, + `QuerySource`, `SyncReadiness`, `ClassifiedChains`) + - `src/raindex_client/local_db/status.rs` (UI status types: `LocalDbStatus`, + `SchedulerState`, `NetworkSyncStatus`, etc.) - `src/subgraph.rs` - Data views & export - `src/types/` (flattened rows + errors), `src/csv.rs`, `src/utils/*` @@ -266,7 +412,10 @@ Where functionality cannot run in WASM, equivalent calldata generation methods a - Surfacing - `src/lib.rs` (pub mod graph, wasm re‑exports), `GH_COMMIT_SHA` -This document covers all publicly exposed modules and their roles so new contributors and integrators can navigate the crate quickly and correctly wire native/WASM consumers. - +This document covers all publicly exposed modules and their roles so new +contributors and integrators can navigate the crate quickly and correctly wire +native/WASM consumers. -Last Updated: 2026-03-03 — Updated for RaindexClient local DB refactor (single-step async construction, deterministic query routing, state.rs/status.rs split). +Last Updated: 2026-03-03 — Updated for RaindexClient local DB refactor +(single-step async construction, deterministic query routing, state.rs/status.rs +split). diff --git a/crates/js_api/ARCHITECTURE.md b/crates/js_api/ARCHITECTURE.md index fa57e3d15b..719fc81554 100644 --- a/crates/js_api/ARCHITECTURE.md +++ b/crates/js_api/ARCHITECTURE.md @@ -1,194 +1,356 @@ **Overview** -- Purpose: `raindex_js_api` exposes a single, browser-friendly WebAssembly surface for the Raindex application. It bridges YAML-based “dotrain” order configuration, on-chain ERC‑20/token metadata, and contract call generation into a typed JavaScript/TypeScript API. -- Target: Compiles as a `cdylib` for wasm and is designed to be consumed from JS environments (webapps). All public APIs are exported via `wasm_bindgen_utils` macros and return ergonomic results with rich, user‑readable errors. -- Scope: Includes high-level order builder helpers for interactive order building, a fetchable registry of orders, and low-level helpers for hashing and ABI calldata generation. It re-exports certain sibling crates so their wasm bindings are reachable from a single import. + +- Purpose: `raindex_js_api` exposes a single, browser-friendly WebAssembly + surface for the Raindex application. It bridges YAML-based “dotrain” order + configuration, on-chain ERC‑20/token metadata, and contract call generation + into a typed JavaScript/TypeScript API. +- Target: Compiles as a `cdylib` for wasm and is designed to be consumed from JS + environments (webapps). All public APIs are exported via `wasm_bindgen_utils` + macros and return ergonomic results with rich, user‑readable errors. +- Scope: Includes high-level order builder helpers for interactive order + building, a fetchable registry of orders, and low-level helpers for hashing + and ABI calldata generation. It re-exports certain sibling crates so their + wasm bindings are reachable from a single import. **Build & Targets** -- Crate type: `cdylib` (WASM output). Most modules are `#[cfg(target_family = "wasm")]` as they are JS facing. -- Key dependencies: `wasm-bindgen-utils`, `alloy` (ABI/primitives), `raindex_*` crates for app models + on-chain helpers, `tokio` (async), `reqwest` (HTTP, registry), `flate2`/`base64`/`bincode`/`sha2` (state serialization), `strict-yaml-rust` (YAML AST). -- TypeScript support: Adds TS definitions for `Address` and `Hex` template literal types and uses `tsify` to describe return/param types of exported structs. + +- Crate type: `cdylib` (WASM output). Most modules are + `#[cfg(target_family = "wasm")]` as they are JS facing. +- Key dependencies: `wasm-bindgen-utils`, `alloy` (ABI/primitives), `raindex_*` + crates for app models + on-chain helpers, `tokio` (async), `reqwest` (HTTP, + registry), `flate2`/`base64`/`bincode`/`sha2` (state serialization), + `strict-yaml-rust` (YAML AST). +- TypeScript support: Adds TS definitions for `Address` and `Hex` template + literal types and uses `tsify` to describe return/param types of exported + structs. **Top-Level Layout** + - `src/lib.rs` - - Exposes modules only when targeting wasm: `bindings`, `raindex_order_builder`, `registry`, `yaml`. - - Re-exports crates so their wasm bindings are available from this single module: `raindex_app_settings`, `raindex_common`, `raindex_subgraph_client`. - - Appends a small TS section defining `Address` and `Hex` template literal types for better typing on the JS side. + - Exposes modules only when targeting wasm: `bindings`, + `raindex_order_builder`, `registry`, `yaml`. + - Re-exports crates so their wasm bindings are available from this single + module: `raindex_app_settings`, `raindex_common`, `raindex_subgraph_client`. + - Appends a small TS section defining `Address` and `Hex` template literal + types for better typing on the JS side. **FFI & Error Conventions** -- Functions and impl blocks use `#[wasm_export]` (from `wasm_bindgen_utils`), which: - - Exports JS-callable functions and classes with Promise-based async where needed. - - Bridges `Result` into JS objects with `.value` on success or an `.error` containing a serialized `WasmEncodedError` with both `msg` and `readable_msg`. - - Uses hints like `unchecked_return_type` and `preserve_js_class` to fine-tune TS output. -- Data structs use `#[derive(Tsify)]` to generate accurate TS types (e.g., `Hex`, `Map<…>`, arrays), and many address-like types are annotated as TS `string` for interop. + +- Functions and impl blocks use `#[wasm_export]` (from `wasm_bindgen_utils`), + which: + - Exports JS-callable functions and classes with Promise-based async where + needed. + - Bridges `Result` into JS objects with `.value` on success or an + `.error` containing a serialized `WasmEncodedError` with both `msg` and + `readable_msg`. + - Uses hints like `unchecked_return_type` and `preserve_js_class` to fine-tune + TS output. +- Data structs use `#[derive(Tsify)]` to generate accurate TS types (e.g., + `Hex`, `Map<…>`, arrays), and many address-like types are annotated as TS + `string` for interop. **Modules** - `bindings` (src/bindings/mod.rs) - - Purpose: Low-level helpers exposed to JS for hashing and ABI encoding independent of the order builder flow. + - Purpose: Low-level helpers exposed to JS for hashing and ABI encoding + independent of the order builder flow. - Key types and exports: - `TakeOrdersCalldata(Bytes)` as an opaque JS type for encoded calldata. - - `getOrderHash(order: OrderV4) -> string`: ABI-encodes `OrderV4` and returns `keccak256` with `0x` prefix. - - `getTakeOrders4Calldata(config: TakeOrdersConfigV5) -> TakeOrdersCalldata`: ABI-encodes a `takeOrders4` call for the on-chain Raindex. - - `keccak256(bytes: Uint8Array) -> string` and `keccak256HexString(hex: string) -> string`. + - `getOrderHash(order: OrderV4) -> string`: ABI-encodes `OrderV4` and + returns `keccak256` with `0x` prefix. + - `getTakeOrders4Calldata(config: TakeOrdersConfigV5) -> TakeOrdersCalldata`: + ABI-encodes a `takeOrders4` call for the on-chain Raindex. + - `keccak256(bytes: Uint8Array) -> string` and + `keccak256HexString(hex: string) -> string`. - Errors: `Error::FromHexError` mapped to JS with human-readable message. - `raindex_order_builder` (src/raindex_order_builder/…) - - Purpose: High-level, stateful orchestrator for interactive order creation from a dotrain (YAML + Rainlang) configuration. Encapsulates reading config, managing user inputs, querying token metadata, validating fields, and generating contract call data for deployment. + - Purpose: High-level, stateful orchestrator for interactive order creation + from a dotrain (YAML + Rainlang) configuration. Encapsulates reading config, + managing user inputs, querying token metadata, validating fields, and + generating contract call data for deployment. - Core type: `RaindexOrderBuilder` - - Fields: `dotrain_order` (parsed configuration), `selected_deployment`, `field_values` and `deposits` (with preset tracking), and an optional `state_update_callback` JS function. + - Fields: `dotrain_order` (parsed configuration), `selected_deployment`, + `field_values` and `deposits` (with preset tracking), and an optional + `state_update_callback` JS function. - Construction: - - `RaindexOrderBuilder.getDeploymentKeys(dotrain: string) -> string[]` parses `builder.deployments`. - - `RaindexOrderBuilder.newWithDeployment(dotrain, selectedDeployment, stateUpdateCallback?) -> RaindexOrderBuilder` validates the deployment and bootstraps an order builder instance. + - `RaindexOrderBuilder.getDeploymentKeys(dotrain: string) -> string[]` + parses `builder.deployments`. + - `RaindexOrderBuilder.newWithDeployment(dotrain, selectedDeployment, stateUpdateCallback?) -> RaindexOrderBuilder` + validates the deployment and bootstraps an order builder instance. - Config accessors: - - `getBuilderConfig() -> OrderBuilderCfg`, `getCurrentDeployment() -> OrderBuilderDeploymentCfg` (filtered for the active deployment). - - `getOrderDetails(dotrain) -> NameAndDescriptionCfg` (static), `getDeploymentDetails(dotrain) -> Map`, `getDeploymentDetail(dotrain, key) -> NameAndDescriptionCfg`. + - `getBuilderConfig() -> OrderBuilderCfg`, + `getCurrentDeployment() -> OrderBuilderDeploymentCfg` (filtered for the + active deployment). + - `getOrderDetails(dotrain) -> NameAndDescriptionCfg` (static), + `getDeploymentDetails(dotrain) -> Map`, + `getDeploymentDetail(dotrain, key) -> NameAndDescriptionCfg`. - `getCurrentDeploymentDetails() -> NameAndDescriptionCfg`. - Token metadata: - - `getTokenInfo(key) -> TokenInfo`: returns address/decimals/name/symbol. Falls back to on-chain queries if YAML is incomplete. - - `getAllTokenInfos() -> TokenInfo[]`: collects token keys from `select-tokens` or order IO, then fetches details as needed. + - `getTokenInfo(key) -> TokenInfo`: returns address/decimals/name/symbol. + Falls back to on-chain queries if YAML is incomplete. + - `getAllTokenInfos() -> TokenInfo[]`: collects token keys from + `select-tokens` or order IO, then fetches details as needed. - Dotrain/Rainlang exports: - - `generateDotrainText() -> string`: emits full dotrain text (YAML frontmatter + `---` + Rainlang body), preserving the current config. - - `getComposedRainlang() -> string`: updates scenario bindings from saved field values and composes Rainlang ready for preview. + - `generateDotrainText() -> string`: emits full dotrain text (YAML + frontmatter + `---` + Rainlang body), preserving the current config. + - `getComposedRainlang() -> string`: updates scenario bindings from saved + field values and composes Rainlang ready for preview. - Submodules - `field_values.rs` - User-controlled inputs declared under `builder.deployments[*].fields`. - Setters and getters: - - `setFieldValue(binding, value)`: validates (if rules exist), detects preset matches, stores as either preset index or custom value, and triggers the state callback. + - `setFieldValue(binding, value)`: validates (if rules exist), detects + preset matches, stores as either preset index or custom value, and + triggers the state callback. - `setFieldValues([{field, value}, …])`: batch equivalent. - `unsetFieldValue(binding)`. - - `getFieldValue(binding) -> { field, value, isPreset }` expands presets to actual values for display. + - `getFieldValue(binding) -> { field, value, isPreset }` expands presets + to actual values for display. - `getAllFieldValues() -> FieldValue[]`. - - `getFieldDefinition(binding) -> OrderBuilderFieldDefinitionCfg` and `getAllFieldDefinitions(filterDefaults?)` (filter by has default/no default), `getMissingFieldValues()`. - - Validation: delegated to `validation.rs` using YAML-provided rules (Number min/max/exclusive bounds, String min/max length, Boolean exact `"true"|"false"`). Uses `rain_math_float::Float` for precise numeric comparisons. + - `getFieldDefinition(binding) -> OrderBuilderFieldDefinitionCfg` and + `getAllFieldDefinitions(filterDefaults?)` (filter by has default/no + default), `getMissingFieldValues()`. + - Validation: delegated to `validation.rs` using YAML-provided rules + (Number min/max/exclusive bounds, String min/max length, Boolean exact + `"true"|"false"`). Uses `rain_math_float::Float` for precise numeric + comparisons. - `deposits.rs` - User deposit amounts declared under `builder.deployments[*].deposits`. - Helpers: - - `getDeposits() -> TokenDeposit[]` expanding presets to actual values and pairing with token addresses. - - `setDeposit(tokenKey, amount)` validates per-token rules (min/max/exclusive), detects presets, stores, and triggers state callback. - - `unsetDeposit(tokenKey)`, `getDepositPresets(tokenKey) -> string[]`, `getMissingDeposits() -> string[]`, `hasAnyDeposit() -> boolean`. - - `check_deposits()` (internal) enforces that all required deposits are set for the current deployment. + - `getDeposits() -> TokenDeposit[]` expanding presets to actual values + and pairing with token addresses. + - `setDeposit(tokenKey, amount)` validates per-token rules + (min/max/exclusive), detects presets, stores, and triggers state + callback. + - `unsetDeposit(tokenKey)`, `getDepositPresets(tokenKey) -> string[]`, + `getMissingDeposits() -> string[]`, `hasAnyDeposit() -> boolean`. + - `check_deposits()` (internal) enforces that all required deposits are + set for the current deployment. - `select_tokens.rs` - - For deployments that declare `select-tokens`, users supply token contracts at runtime. + - For deployments that declare `select-tokens`, users supply token + contracts at runtime. - Features: - - `getSelectTokens() -> OrderBuilderSelectTokensCfg[]` and `checkSelectTokens()`. + - `getSelectTokens() -> OrderBuilderSelectTokensCfg[]` and + `checkSelectTokens()`. - `isSelectTokenSet(key) -> boolean`. - - `setSelectToken(key, address)` fetches ERC‑20 metadata via RPC (derived from the deployment’s network) and writes token records back into the dotrain YAML; triggers state callback. + - `setSelectToken(key, address)` fetches ERC‑20 metadata via RPC + (derived from the deployment’s network) and writes token records back + into the dotrain YAML; triggers state callback. - `unsetSelectToken(key)` removes previously selected token records. - `areAllTokensSelected() -> boolean`. - - Token discovery: `getAllTokens(search?) -> TokenInfo[]` returns all tokens for the active network. If metadata is missing in YAML, it fetches on-chain, dedupes by address, and optionally filters by name/symbol/address substring. Concurrency is limited by `MAX_CONCURRENT_FETCHES`. - - `getAccountBalance(tokenAddress, owner) -> AccountBalance` reads ERC‑20 decimals and balance and returns both raw and formatted balance. + - Token discovery: `getAllTokens(search?) -> TokenInfo[]` returns all + tokens for the active network. If metadata is missing in YAML, it + fetches on-chain, dedupes by address, and optionally filters by + name/symbol/address substring. Concurrency is limited by + `MAX_CONCURRENT_FETCHES`. + - `getAccountBalance(tokenAddress, owner) -> AccountBalance` reads + ERC‑20 decimals and balance and returns both raw and formatted + balance. - `order_operations.rs` - Generates all calldata required to deploy orders and related flows. - Internal preparation: - - `prepare_calldata_generation` validates select-tokens, ensures field values exist as needed, populates vault IDs, and updates scenario bindings before generating any calldata. - - `get_raindex()` and `get_transaction_args()` collect the raindex address and RPCs for downstream calls. - - `get_deposits_as_map()` and `get_vaults_and_deposits()` resolve deposit amounts by token/address and match them to order outputs + vaults. + - `prepare_calldata_generation` validates select-tokens, ensures field + values exist as needed, populates vault IDs, and updates scenario + bindings before generating any calldata. + - `get_raindex()` and `get_transaction_args()` collect the raindex + address and RPCs for downstream calls. + - `get_deposits_as_map()` and `get_vaults_and_deposits()` resolve + deposit amounts by token/address and match them to order outputs + + vaults. - Allowance/approvals: - - `checkAllowances(owner) -> AllowancesResult`: queries current allowances for each deposit token against the raindex. - - `generateApprovalCalldatas(owner) -> ApprovalCalldataResult`: compares allowances to desired deposit amounts and, when they differ, emits ERC‑20 `approve` calldatas that set the allowance to the exact target value. + - `checkAllowances(owner) -> AllowancesResult`: queries current + allowances for each deposit token against the raindex. + - `generateApprovalCalldatas(owner) -> ApprovalCalldataResult`: compares + allowances to desired deposit amounts and, when they differ, emits + ERC‑20 `approve` calldatas that set the allowance to the exact target + value. - Deposits: - - `generateDepositCalldatas() -> DepositCalldataResult`: builds `deposit3` calldatas for non-zero deposits using vault IDs (fetches decimals on-chain if missing in YAML). + - `generateDepositCalldatas() -> DepositCalldataResult`: builds + `deposit3` calldatas for non-zero deposits using vault IDs (fetches + decimals on-chain if missing in YAML). - Add order: - - `generateAddOrderCalldata() -> AddOrderCalldataResult`: composes Rainlang, builds an `AddOrderArgs` from the deployment, and returns the ABI-encoded call. + - `generateAddOrderCalldata() -> AddOrderCalldataResult`: composes + Rainlang, builds an `AddOrderArgs` from the deployment, and returns + the ABI-encoded call. - Combined deployment: - - `generateDepositAndAddOrderCalldatas() -> DepositAndAddOrderCalldataResult`: constructs a `multicall` that first performs `addOrder`, then all deposits. - - `getDeploymentTransactionArgs(owner) -> DeploymentTransactionArgs`: packages approval calldatas (with token symbol for UX), multicall calldata, raindex address, and chain ID for a one-shot deployment flow. + - `generateDepositAndAddOrderCalldatas() -> DepositAndAddOrderCalldataResult`: + constructs a `multicall` that first performs `addOrder`, then all + deposits. + - `getDeploymentTransactionArgs(owner) -> DeploymentTransactionArgs`: + packages approval calldatas (with token symbol for UX), multicall + calldata, raindex address, and chain ID for a one-shot deployment + flow. - Vault IDs: - - `setVaultId(type: 'input'|'output', tokenKey, vaultId?: string)`, `getVaultIds() -> IOVaultIds`, and `hasAnyVaultId() -> boolean`. - - Types exposed for JS: `AllowancesResult`, `ApprovalCalldataResult|DepositCalldataResult|AddOrderCalldataResult|DepositAndAddOrderCalldataResult`, `ExtendedApprovalCalldata`, `DeploymentTransactionArgs`, `IOVaultIds`. A `WithdrawCalldataResult` type exists but no public generator yet. + - `setVaultId(type: 'input'|'output', tokenKey, vaultId?: string)`, + `getVaultIds() -> IOVaultIds`, and `hasAnyVaultId() -> boolean`. + - Types exposed for JS: `AllowancesResult`, + `ApprovalCalldataResult|DepositCalldataResult|AddOrderCalldataResult|DepositAndAddOrderCalldataResult`, + `ExtendedApprovalCalldata`, `DeploymentTransactionArgs`, `IOVaultIds`. A + `WithdrawCalldataResult` type exists but no public generator yet. - `state_management.rs` - End-to-end state persistence and restoration: - - `serializeState() -> string`: bincode-serializes a compact state (field values and deposit presets, selected tokens, vault IDs, selected deployment) then gzips and base64-encodes. Also embeds a SHA‑256 of the full dotrain to prevent mismatched restores. - - `RaindexOrderBuilder.newFromState(dotrain, serialized, callback?) -> RaindexOrderBuilder`: validates the hash against the provided dotrain, rebuilds internal maps, replays selected tokens and vault IDs back into the YAML/documents, and returns a fully restored instance. - - `executeStateUpdateCallback()`: manually triggers the callback by passing the latest `serializeState()` string. Most mutating methods call this automatically. - - `getAllBuilderConfig() -> AllBuilderConfig`: returns all front-end relevant config slices grouped for progressive UI building (fields by required/optional, deposits, order inputs/outputs). + - `serializeState() -> string`: bincode-serializes a compact state + (field values and deposit presets, selected tokens, vault IDs, + selected deployment) then gzips and base64-encodes. Also embeds a + SHA‑256 of the full dotrain to prevent mismatched restores. + - `RaindexOrderBuilder.newFromState(dotrain, serialized, callback?) -> RaindexOrderBuilder`: + validates the hash against the provided dotrain, rebuilds internal + maps, replays selected tokens and vault IDs back into the + YAML/documents, and returns a fully restored instance. + - `executeStateUpdateCallback()`: manually triggers the callback by + passing the latest `serializeState()` string. Most mutating methods + call this automatically. + - `getAllBuilderConfig() -> AllBuilderConfig`: returns all front-end + relevant config slices grouped for progressive UI building (fields by + required/optional, deposits, order inputs/outputs). - `validation.rs` - Uniform validation library used by `field_values` and `deposits`: - - Numbers: `minimum`, `exclusive-minimum`, `maximum`, `exclusive-maximum`; rejects negatives; precise decimal support via `Float`. - - Strings: `min-length`, `max-length` (length measured on trimmed strings). + - Numbers: `minimum`, `exclusive-minimum`, `maximum`, + `exclusive-maximum`; rejects negatives; precise decimal support via + `Float`. + - Strings: `min-length`, `max-length` (length measured on trimmed + strings). - Booleans: accepts only `"true"` or `"false"`. - - Errors (`BuilderValidationError`) carry contextual, user-readable messages; surfaced to JS via `BuilderError::ValidationError`. + - Errors (`BuilderValidationError`) carry contextual, user-readable + messages; surfaced to JS via `BuilderError::ValidationError`. - Error type for the builder: `BuilderError` - - Captures configuration, selection, validation, I/O, chain, and serialization errors. + - Captures configuration, selection, validation, I/O, chain, and + serialization errors. - Provides `to_readable_msg()` with end-user friendly explanations. - Implements conversions to `JsValue` and `WasmEncodedError` for FFI. - `registry` (src/registry.rs) - - Purpose: Fetches a remote registry file that lists one shared settings YAML followed by one or more `.rain` order files. Produces merged dotrain content per order and can directly construct an `RaindexOrderBuilder` instance. + - Purpose: Fetches a remote registry file that lists one shared settings YAML + followed by one or more `.rain` order files. Produces merged dotrain content + per order and can directly construct an `RaindexOrderBuilder` instance. - Registry format: - First non-empty line: settings YAML URL (no key) - Subsequent lines: `" "` - Flow: - - `DotrainRegistry.new(registryUrl)` → fetch registry text → parse → fetch settings → fetch all orders (concurrently) → store in-memory. - - `getAllOrderDetails()` → parse order-level metadata for every merged dotrain, returning both valid and invalid entries (with errors) keyed by order. + - `DotrainRegistry.new(registryUrl)` → fetch registry text → parse → fetch + settings → fetch all orders (concurrently) → store in-memory. + - `getAllOrderDetails()` → parse order-level metadata for every merged + dotrain, returning both valid and invalid entries (with errors) keyed by + order. - `getOrderKeys()` → keys from `order_urls`. - - `getDeploymentDetails(orderKey)` → deployment name/description map for a specific order. - - `getRaindexYaml() -> RaindexYaml` → returns a `RaindexYaml` instance from the registry's shared settings YAML for querying tokens, networks, raindexes, etc. - - `getOrderBuilder(orderKey, deploymentKey, serializedState?, stateCallback?)` → merge `settings + order`, optionally restore serialized state, and produce a `RaindexOrderBuilder` instance. - - Errors: `DotrainRegistryError` covers fetch/parse/HTTP/URL issues and wraps `BuilderError`. Also returns human-readable messages. + - `getDeploymentDetails(orderKey)` → deployment name/description map for a + specific order. + - `getRaindexYaml() -> RaindexYaml` → returns a `RaindexYaml` instance from + the registry's shared settings YAML for querying tokens, networks, + raindexes, etc. + - `getOrderBuilder(orderKey, deploymentKey, serializedState?, stateCallback?)` + → merge `settings + order`, optionally restore serialized state, and produce + a `RaindexOrderBuilder` instance. + - Errors: `DotrainRegistryError` covers fetch/parse/HTTP/URL issues and wraps + `BuilderError`. Also returns human-readable messages. - `yaml` (src/yaml/mod.rs) - - Purpose: Wasm-friendly wrapper around raindex YAML parsing to retrieve configuration objects by address or query token metadata. + - Purpose: Wasm-friendly wrapper around raindex YAML parsing to retrieve + configuration objects by address or query token metadata. - Exports: - - `RaindexYaml.new([yamlSources], validate?) -> RaindexYaml`: parse/merge/optionally validate sources. + - `RaindexYaml.new([yamlSources], validate?) -> RaindexYaml`: + parse/merge/optionally validate sources. - `RaindexYaml.getRaindexByAddress(address) -> RaindexCfg`. - - `RaindexYaml.getTokens() -> TokenInfo[]` (async): returns all tokens from YAML with `chain_id`, `address`, `decimals`, `symbol`, and `name`. Automatically fetches remote tokens from `using-tokens-from` URLs. + - `RaindexYaml.getTokens() -> TokenInfo[]` (async): returns all tokens from + YAML with `chain_id`, `address`, `decimals`, `symbol`, and `name`. + Automatically fetches remote tokens from `using-tokens-from` URLs. - Errors: `RaindexYamlError` with readable messaging, converted to JS. **External Crates & Interactions** -- `raindex_app_settings`: typed config model + YAML parsing helpers for order builder sections, deployments, networks, orders, select-tokens, and validation rules. -- `raindex_common`: higher-level order manipulation (compose Rainlang, add order args), ERC‑20 RPC client, transaction helpers, and formatting utilities. -- `raindex_bindings`: generated Solidity bindings for `IRaindexV5` (e.g., `deposit3`, `multicall`, `takeOrders3`). -- `alloy`: ABI encoding/decoding, primitives (`Address`, `Bytes`, `U256`, keccak256), and Solidity type utilities. + +- `raindex_app_settings`: typed config model + YAML parsing helpers for order + builder sections, deployments, networks, orders, select-tokens, and validation + rules. +- `raindex_common`: higher-level order manipulation (compose Rainlang, add order + args), ERC‑20 RPC client, transaction helpers, and formatting utilities. +- `raindex_bindings`: generated Solidity bindings for `IRaindexV5` (e.g., + `deposit3`, `multicall`, `takeOrders3`). +- `alloy`: ABI encoding/decoding, primitives (`Address`, `Bytes`, `U256`, + keccak256), and Solidity type utilities. - `wasm-bindgen-utils`: export macro, JS bridging, `WasmEncodedError` packaging. **Data Flow & Typical Lifecycle** + - From dotrain → order builder → calldata: - - Parse dotrain (frontmatter YAML + Rainlang body) with `DotrainOrder::create`. + - Parse dotrain (frontmatter YAML + Rainlang body) with + `DotrainOrder::create`. - Initialize order builder with a deployment key. - - Optional: select tokens via on-chain metadata, set field values (with validation), set deposit amounts (with validation), and set vault IDs. - - Generate approvals if needed, deposits, add order calldata, or a combined multicall. Transaction args include raindex address and chain ID. + - Optional: select tokens via on-chain metadata, set field values (with + validation), set deposit amounts (with validation), and set vault IDs. + - Generate approvals if needed, deposits, add order calldata, or a combined + multicall. Transaction args include raindex address and chain ID. - State persistence: - - Any setter triggers `executeStateUpdateCallback()` with a gzipped/base64 state snapshot that includes a dotrain content hash. `newFromState` restores and protects against mismatched content. + - Any setter triggers `executeStateUpdateCallback()` with a gzipped/base64 + state snapshot that includes a dotrain content hash. `newFromState` restores + and protects against mismatched content. - Token metadata: - - Prefer YAML cache when available; otherwise, query chain via current network’s RPC(s). Concurrency for token info lookups is capped. + - Prefer YAML cache when available; otherwise, query chain via current + network’s RPC(s). Concurrency for token info lookups is capped. **TypeScript Surface** -- Most exported structs are `Tsify`’d, and methods use `unchecked_return_type` for readable TS types: - - Example: `getVaultIds()` returns a `Map>` keyed by `"input"`/`"output"` and token keys. - - Calldata types are exposed as `Hex` or `Hex[]`, addresses as `string` with TS template literal types appended by `lib.rs`. + +- Most exported structs are `Tsify`’d, and methods use `unchecked_return_type` + for readable TS types: + - Example: `getVaultIds()` returns a + `Map>` keyed by `"input"`/`"output"` + and token keys. + - Calldata types are exposed as `Hex` or `Hex[]`, addresses as `string` with + TS template literal types appended by `lib.rs`. **Testing Notes** + - Uses `wasm-bindgen-test` to exercise behavior within wasm targets. - Many tests validate: - Validation errors and their readable messages. - Deposit/field setters, preset detection, and getters. - Select-token flows and token discovery, including search and dedupe. - Vault ID setting and query helpers. - - State serialization and restoration roundtrips (including hash mismatch protection). - - Registry parsing/fetching logic; non-wasm tests use `httpmock` to simulate HTTP servers. + - State serialization and restoration roundtrips (including hash mismatch + protection). + - Registry parsing/fetching logic; non-wasm tests use `httpmock` to simulate + HTTP servers. **Edge Cases & Notes** -- If YAML is missing token metadata, the crate queries the chain; callers should expect async RPC usage and potential network failures in those code paths. -- `WithdrawCalldataResult` exists as a type placeholder; no public generator currently uses it. -- Many order builder methods error if `select-tokens` is configured but tokens are not yet selected, or if required field values/deposits are missing. These error cases surface clear `readable_msg`s. -- When decimals are absent in YAML, they are fetched on demand before encoding deposits. + +- If YAML is missing token metadata, the crate queries the chain; callers should + expect async RPC usage and potential network failures in those code paths. +- `WithdrawCalldataResult` exists as a type placeholder; no public generator + currently uses it. +- Many order builder methods error if `select-tokens` is configured but tokens + are not yet selected, or if required field values/deposits are missing. These + error cases surface clear `readable_msg`s. +- When decimals are absent in YAML, they are fetched on demand before encoding + deposits. **How To Use (High-Level)** + - Single order flow: - `const builder = await RaindexOrderBuilder.newWithDeployment(dotrain, deploymentKey, onStateChanged?)` - - Fill inputs: `setFieldValue`, `setDeposit`, optionally `setSelectToken`, `setVaultId`. - - Generate data: `generateAddOrderCalldata` or `generateDepositAndAddOrderCalldatas`; or get the full package from `getDeploymentTransactionArgs(owner)`. - - Persist UI state: read `serializeState()`; restore later with `RaindexOrderBuilder.newFromState(dotrain, serialized, callback?)`. + - Fill inputs: `setFieldValue`, `setDeposit`, optionally `setSelectToken`, + `setVaultId`. + - Generate data: `generateAddOrderCalldata` or + `generateDepositAndAddOrderCalldatas`; or get the full package from + `getDeploymentTransactionArgs(owner)`. + - Persist UI state: read `serializeState()`; restore later with + `RaindexOrderBuilder.newFromState(dotrain, serialized, callback?)`. - Multiple orders via registry: - - `const registry = await DotrainRegistry.new(registryUrl)` → inspect orders/deployments → `await registry.getOrderBuilder(orderKey, deploymentKey, serializedState?, onStateChanged?)`. + - `const registry = await DotrainRegistry.new(registryUrl)` → inspect + orders/deployments → + `await registry.getOrderBuilder(orderKey, deploymentKey, serializedState?, onStateChanged?)`. **Summary** -- `raindex_js_api` is the JS/WASM gateway for building, validating, and deploying Raindex orders from YAML+Rainlang definitions. It centralizes: YAML parsing and validation, user input state, token selection and metadata, field and deposit validation, vault ID management, transaction calldata generation (approvals, deposits, add order, multicall), registry-driven content fetching, and robust error handling—exposed as a typed, ergonomic TypeScript surface. + +- `raindex_js_api` is the JS/WASM gateway for building, validating, and + deploying Raindex orders from YAML+Rainlang definitions. It centralizes: YAML + parsing and validation, user input state, token selection and metadata, field + and deposit validation, vault ID management, transaction calldata generation + (approvals, deposits, add order, multicall), registry-driven content fetching, + and robust error handling—exposed as a typed, ergonomic TypeScript surface. diff --git a/crates/math/ARCHITECTURE.md b/crates/math/ARCHITECTURE.md index f00a152d6a..8aef52fc41 100644 --- a/crates/math/ARCHITECTURE.md +++ b/crates/math/ARCHITECTURE.md @@ -1,11 +1,13 @@ # raindex_math — Architecture & Design Notes -This crate provides small, focused, and overflow‑safe helpers for 256‑bit integer math used across the Rain Raindex codebase. It standardizes two things: +This crate provides small, focused, and overflow‑safe helpers for 256‑bit +integer math used across the Rain Raindex codebase. It standardizes two things: - Fixed‑point arithmetic in 18‑decimals (a.k.a. “wad” math). - Safe scaling between token native decimals and 18‑decimals. -The implementation wraps `alloy::primitives` big‑ints and exposes a trait implemented for `U256` so call sites can remain expressive and chainable. +The implementation wraps `alloy::primitives` big‑ints and exposes a trait +implemented for `U256` so call sites can remain expressive and chainable. ## Crate Surface @@ -23,16 +25,21 @@ The implementation wraps `alloy::primitives` big‑ints and exposes a trait impl - `mul_18(self, other: U256) -> Result` - `div_18(self, other: U256) -> Result` -There are no module subtrees; everything is in `src/lib.rs` with unit tests under `#[cfg(test)]`. +There are no module subtrees; everything is in `src/lib.rs` with unit tests +under `#[cfg(test)]`. ## Dependencies and Types - `alloy::primitives::{U256, U512}` — 256/512‑bit unsigned integers. -- `alloy::primitives::ruint::{FromUintError, UintTryTo}` — fallible, width‑aware conversions and helpers. -- `alloy::primitives::utils::UnitsError` — error type for unit/decimal utilities (not currently emitted by this crate’s functions, but accounted for in `MathError`). +- `alloy::primitives::ruint::{FromUintError, UintTryTo}` — fallible, width‑aware + conversions and helpers. +- `alloy::primitives::utils::UnitsError` — error type for unit/decimal utilities + (not currently emitted by this crate’s functions, but accounted for in + `MathError`). - `thiserror::Error` — error derivation. -Note: `once_cell` is a workspace dependency but is not used inside this crate as of this revision. +Note: `once_cell` is a workspace dependency but is not used inside this crate as +of this revision. ## Constants @@ -44,25 +51,34 @@ Note: `once_cell` is a workspace dependency but is not used inside this crate as ## Error Model — `MathError` -- `Overflow` — returned when checked arithmetic fails (e.g., `checked_mul`/`checked_div` or intermediate width conversions cannot fit). -- `UnitsError(UnitsError)` — passthrough for unit/decimal parsing and conversion errors (present for ergonomic composition; not produced by functions in this file at the moment). -- `FromUintErrorU256(FromUintError)` — converting into `U256` failed (e.g., narrowing from a `U512` result that won’t fit). -- `FromUintErrorU512(FromUintError)` — converting into `U512` failed (kept for completeness when using `UintTryTo::` paths). +- `Overflow` — returned when checked arithmetic fails (e.g., + `checked_mul`/`checked_div` or intermediate width conversions cannot fit). +- `UnitsError(UnitsError)` — passthrough for unit/decimal parsing and conversion + errors (present for ergonomic composition; not produced by functions in this + file at the moment). +- `FromUintErrorU256(FromUintError)` — converting into `U256` failed + (e.g., narrowing from a `U512` result that won’t fit). +- `FromUintErrorU512(FromUintError)` — converting into `U512` failed (kept + for completeness when using `UintTryTo::` paths). -All public functions return `Result`. Division by zero surfaces as `Overflow` (via `checked_div` returning `None`). +All public functions return `Result`. Division by zero surfaces +as `Overflow` (via `checked_div` returning `None`). ## BigUintMath — Semantics and Rationale -All methods are implemented for `U256` and return a `U256` (or error). The guiding principles are: +All methods are implemented for `U256` and return a `U256` (or error). The +guiding principles are: -- Deterministic integer arithmetic (no floats), suitable for on‑chain semantics and reproducible off‑chain analytics. +- Deterministic integer arithmetic (no floats), suitable for on‑chain semantics + and reproducible off‑chain analytics. - Use 512‑bit intermediates when multiplying to avoid overflow before dividing. - Keep API composable and minimal; callers can build richer flows on top. ### `scale_up(self, by: u8)` - Computes `self * 10^by` with `checked_mul` to detect overflow. -- Intended to increase a value’s decimal precision. Example: USDC `6 → 18` uses `by = 12`. +- Intended to increase a value’s decimal precision. Example: USDC `6 → 18` uses + `by = 12`. - Errors - `Overflow` if `10^by` overflows `U256` or the product doesn’t fit in `U256`. @@ -71,7 +87,8 @@ All methods are implemented for `U256` and return a `U256` (or error). The guidi - Computes `self / 10^by` with `checked_div`. - Truncates toward zero (integer division). No rounding. - Errors - - `Overflow` if divisor is zero due to an invalid exponent (practically unreachable for reasonable `by` but captured for safety). + - `Overflow` if divisor is zero due to an invalid exponent (practically + unreachable for reasonable `by` but captured for safety). ### `scale_18(self, decimals: u8)` @@ -81,14 +98,17 @@ All methods are implemented for `U256` and return a `U256` (or error). The guidi - If `decimals < 18`: `scale_up(18 - decimals)`. - If `decimals == 18`: returns `self`. - Behavior - - Scaling down truncates fractional remainders; callers must account for this if rounding is required. + - Scaling down truncates fractional remainders; callers must account for this + if rounding is required. ### `mul_div(self, mul: U256, div: U256)` -- Computes floor((`self * mul`) / `div`) using a 512‑bit widening multiply to avoid overflow during the product. +- Computes floor((`self * mul`) / `div`) using a 512‑bit widening multiply to + avoid overflow during the product. - Steps 1. `self.widening_mul(mul)` → `U512` product. - 2. `checked_div(U512(div))` — detect divide‑by‑zero; keep the integer quotient. + 2. `checked_div(U512(div))` — detect divide‑by‑zero; keep the integer + quotient. 3. Attempt to `try_to::()` the result; fail if it doesn’t fit. - Errors - `Overflow` on divide‑by‑zero or if intermediate doesn’t fit when narrowing. @@ -107,27 +127,36 @@ All methods are implemented for `U256` and return a `U256` (or error). The guidi ## Rounding and Truncation - All divisions truncate toward zero (integer floor for non‑negative inputs). -- There is no built‑in rounding mode. If callers require “round half up”, they should bias the numerator before division, e.g. `mul_div(x + div/2, mul, div)` for appropriate domains. +- There is no built‑in rounding mode. If callers require “round half up”, they + should bias the numerator before division, e.g. `mul_div(x + div/2, mul, div)` + for appropriate domains. ## Limits and Edge Cases -- Exponent bounds: `10^by` must fit in `U256` to be meaningful. Practical ERC‑20 token decimals are typically ≤ 36; values well beyond ~77 will overflow `U256`. +- Exponent bounds: `10^by` must fit in `U256` to be meaningful. Practical ERC‑20 + token decimals are typically ≤ 36; values well beyond ~77 will overflow + `U256`. - Division by zero: guarded and returned as `Overflow`. -- Sign: all values are unsigned (`U256`). If negative semantics are needed, the sign must be tracked out‑of‑band by the caller (as seen in other crates that pair magnitudes with boolean flags). +- Sign: all values are unsigned (`U256`). If negative semantics are needed, the + sign must be tracked out‑of‑band by the caller (as seen in other crates that + pair magnitudes with boolean flags). ## Interactions in the Workspace Downstream crates treat these helpers as the canonical way to: -- Normalize per‑token magnitudes to 18 decimals with `scale_18` for comparability. -- Perform fixed‑point rates and APY math using `mul_18`/`div_18` without risking 256‑bit overflow (thanks to widening intermediates). +- Normalize per‑token magnitudes to 18 decimals with `scale_18` for + comparability. +- Perform fixed‑point rates and APY math using `mul_18`/`div_18` without risking + 256‑bit overflow (thanks to widening intermediates). Examples of usage (from `crates/subgraph`): - Compute per‑vault APY over time windows: - Convert vault balances to 18‑dec with `scale_18`. - Compute annualization and ratios with `mul_18`/`div_18`. -- Convert between token denominations by applying a pair ratio via `mul_18` to capitals and net volumes. +- Convert between token denominations by applying a pair ratio via `mul_18` to + capitals and net volumes. ## Tests — Intent and Coverage @@ -139,20 +168,27 @@ Examples of usage (from `crates/subgraph`): - Shows that scaling down truncates remainders. - `test_big_uint_math_mul_div` - Checks simple products and divisions. - - Includes a case where a 256‑bit product would overflow, verifying `widening_mul` correctness and final narrowing. + - Includes a case where a 256‑bit product would overflow, verifying + `widening_mul` correctness and final narrowing. - `test_big_uint_math_mul_18` - - Exercises fixed‑point multiply, including a large value where a 256‑bit product would overflow without widening. + - Exercises fixed‑point multiply, including a large value where a 256‑bit + product would overflow without widening. - `test_big_uint_math_div_18` - Exercises fixed‑point division under large inputs. -These tests collectively validate scaling correctness, overflow resistance, and fixed‑point semantics. +These tests collectively validate scaling correctness, overflow resistance, and +fixed‑point semantics. ## Design Notes & Rationale -- Chosen representation: integers avoid floating‑point rounding and platform variance, matching on‑chain arithmetic. -- Widening strategy: `U512` intermediates for multiply‑then‑divide patterns are the standard approach to preserve precision without overflow before division. -- API locality: A single trait on `U256` keeps call sites terse and testable without introducing new wrapper types. -- Error aggregation: `MathError` centralizes math‑related failures for ergonomic propagation into higher‑level error types. +- Chosen representation: integers avoid floating‑point rounding and platform + variance, matching on‑chain arithmetic. +- Widening strategy: `U512` intermediates for multiply‑then‑divide patterns are + the standard approach to preserve precision without overflow before division. +- API locality: A single trait on `U256` keeps call sites terse and testable + without introducing new wrapper types. +- Error aggregation: `MathError` centralizes math‑related failures for ergonomic + propagation into higher‑level error types. ## Usage Patterns (Examples) @@ -183,15 +219,23 @@ Assume `amount` is a token balance in its native decimals. ## Known Limitations / Considerations -- No rounding modes are provided; all divisions truncate. Callers must implement their own rounding if required. -- `UnitsError` is part of `MathError` for convenience but is not currently produced by functions in this file. -- Extremely large exponents in scaling (e.g., `by > ~77`) will overflow `U256` powers of ten. +- No rounding modes are provided; all divisions truncate. Callers must implement + their own rounding if required. +- `UnitsError` is part of `MathError` for convenience but is not currently + produced by functions in this file. +- Extremely large exponents in scaling (e.g., `by > ~77`) will overflow `U256` + powers of ten. ## File Map - `src/lib.rs` — All implementations and tests. -- `Cargo.toml` — Declares crate as `raindex_math`; depends on `alloy`, `thiserror` (and `once_cell` via workspace, unused here). +- `Cargo.toml` — Declares crate as `raindex_math`; depends on `alloy`, + `thiserror` (and `once_cell` via workspace, unused here). ## Summary -`raindex_math` supplies the minimal, safe building blocks needed for consistent 18‑dec fixed‑point math on `U256`, with careful overflow handling and 512‑bit intermediates for the common mul‑then‑div pattern. Other Rain Raindex crates rely on these helpers to normalize magnitudes and compute rates without duplicating math or risking undefined overflow behavior. +`raindex_math` supplies the minimal, safe building blocks needed for consistent +18‑dec fixed‑point math on `U256`, with careful overflow handling and 512‑bit +intermediates for the common mul‑then‑div pattern. Other Rain Raindex crates +rely on these helpers to normalize magnitudes and compute rates without +duplicating math or risking undefined overflow behavior. diff --git a/crates/settings/ARCHITECTURE.md b/crates/settings/ARCHITECTURE.md index 4a32336edb..435da2e91c 100644 --- a/crates/settings/ARCHITECTURE.md +++ b/crates/settings/ARCHITECTURE.md @@ -1,90 +1,136 @@ # Settings Crate – Architecture and Responsibilities -This crate defines the configuration model, parsing, validation and update utilities for the Raindex stack. It turns one or more YAML "settings" documents into strongly‑typed Rust structures that the rest of the system can consume (CLI, services, and WASM/JS bindings). It also supports fetching and merging remote configuration (networks, tokens), contextual variable interpolation, and in‑place updates back to the underlying YAML. +This crate defines the configuration model, parsing, validation and update +utilities for the Raindex stack. It turns one or more YAML "settings" documents +into strongly‑typed Rust structures that the rest of the system can consume +(CLI, services, and WASM/JS bindings). It also supports fetching and merging +remote configuration (networks, tokens), contextual variable interpolation, and +in‑place updates back to the underlying YAML. At a glance: -- Input format: one or more YAML documents (via `StrictYaml` from `strict_yaml_rust`). -- Output types: `NetworkCfg`, `TokenCfg`, `RaindexCfg`, `SubgraphCfg`, `DeployerCfg`, `OrderCfg`, `ScenarioCfg`, `DeploymentCfg`, `OrderBuilderCfg`, `ChartCfg`, `MetaboardCfg`, `AccountCfg`, plus helpers. -- Cross‑document merge: parse operations accept a vector of YAML documents and merge sections across them, rejecting duplicate keys deterministically. -- Remote sources: optional “using‑*” sections enable fetching networks/tokens from external endpoints and merging them into the local model. -- Context: a runtime context carries selected deployment/order, token selection for order builder flows, remote caches, and supports string interpolation from order paths. -- WASM/TypeScript: many types derive `Tsify` and implement WASM trait helpers for interop with the webapp. - +- Input format: one or more YAML documents (via `StrictYaml` from + `strict_yaml_rust`). +- Output types: `NetworkCfg`, `TokenCfg`, `RaindexCfg`, `SubgraphCfg`, + `DeployerCfg`, `OrderCfg`, `ScenarioCfg`, `DeploymentCfg`, `OrderBuilderCfg`, + `ChartCfg`, `MetaboardCfg`, `AccountCfg`, plus helpers. +- Cross‑document merge: parse operations accept a vector of YAML documents and + merge sections across them, rejecting duplicate keys deterministically. +- Remote sources: optional “using‑*” sections enable fetching networks/tokens + from external endpoints and merging them into the local model. +- Context: a runtime context carries selected deployment/order, token selection + for order builder flows, remote caches, and supports string interpolation from + order paths. +- WASM/TypeScript: many types derive `Tsify` and implement WASM trait helpers + for interop with the webapp. ## Parsing Framework (yaml/*) Core traits and helpers live under `src/yaml` and are used by all config types: - Traits - - `ValidationConfig`: strategy for which sections to validate (networks, tokens, orders, etc.). - - `YamlParsable`: for top‑level parsers that accept multiple YAML documents (e.g. `RaindexYaml`, `DotrainYaml`). Provides constructors from strings/documents and helper to stringify a document. - - `YamlParsableHash`: for map‑shaped sections (e.g. `networks`, `tokens`, `orders`). Provides `parse_all_from_yaml` and `parse_from_yaml(key)`. + - `ValidationConfig`: strategy for which sections to validate (networks, + tokens, orders, etc.). + - `YamlParsable`: for top‑level parsers that accept multiple YAML documents + (e.g. `RaindexYaml`, `DotrainYaml`). Provides constructors from + strings/documents and helper to stringify a document. + - `YamlParsableHash`: for map‑shaped sections (e.g. `networks`, `tokens`, + `orders`). Provides `parse_all_from_yaml` and `parse_from_yaml(key)`. - `YamlParsableVector`: for vector‑shaped items if needed. - - `YamlParsableString`: for single string fields with optionality (e.g. `SpecVersion`, `Sentry`). - - `YamlParseableValue`: for single logical objects that are not a map (e.g. `OrderBuilderCfg`, `RemoteTokensCfg`). + - `YamlParsableString`: for single string fields with optionality (e.g. + `SpecVersion`, `Sentry`). + - `YamlParseableValue`: for single logical objects that are not a map (e.g. + `OrderBuilderCfg`, `RemoteTokensCfg`). - Context and caching - `Context` holds: - `order: Option>` – the current order for interpolation. - - `select_tokens: Option>` – allow order builder to reference tokens by key without YAML definitions. + - `select_tokens: Option>` – allow order builder to reference + tokens by key without YAML definitions. - `builder_context`: current deployment/order selection. - `yaml_cache`: remote networks/tokens cache injected by providers. - - Interpolation: `Context::interpolate("... ${order.inputs.0.token.symbol} ...")` resolves values from the current order (inputs/outputs, token address/symbol/label/decimals, vault IDs). - - Path resolution helpers and errors: `ContextError::{NoOrder, InvalidPath, InvalidIndex, PropertyNotFound}` with human‑readable messages. + - Interpolation: + `Context::interpolate("... ${order.inputs.0.token.symbol} ...")` resolves + values from the current order (inputs/outputs, token + address/symbol/label/decimals, vault IDs). + - Path resolution helpers and errors: + `ContextError::{NoOrder, InvalidPath, InvalidIndex, PropertyNotFound}` with + human‑readable messages. - Cache - - `yaml/cache.rs::Cache` stores remote networks/tokens fetched previously. The providers (`RaindexYaml`, `DotrainYaml`) expose them to `Context` when parsing. - - Update/get helpers return clones to keep the cache immutable from the caller’s perspective. + - `yaml/cache.rs::Cache` stores remote networks/tokens fetched previously. The + providers (`RaindexYaml`, `DotrainYaml`) expose them to `Context` when + parsing. + - Update/get helpers return clones to keep the cache immutable from the + caller’s perspective. - YAML helpers and errors - - Required/optional accessors: `require_string`, `optional_string`, `require_hash`, `optional_hash`, `require_vec`, `optional_vec`, `get_hash_value`, `get_hash_value_as_option`. - - `YamlError` and `FieldErrorKind` model validation issues precisely and implement `to_readable_msg()` for end‑user feedback. Additional variants wrap module‑specific parse errors (e.g. network/token/order errors). - + - Required/optional accessors: `require_string`, `optional_string`, + `require_hash`, `optional_hash`, `require_vec`, `optional_vec`, + `get_hash_value`, `get_hash_value_as_option`. + - `YamlError` and `FieldErrorKind` model validation issues precisely and + implement `to_readable_msg()` for end‑user feedback. Additional variants + wrap module‑specific parse errors (e.g. network/token/order errors). ## Document Providers -Two top‑level providers wrap one or more YAML documents and expose a convenient API to parse sections, fetch remote data, and produce contexts. +Two top‑level providers wrap one or more YAML documents and expose a convenient +API to parse sections, fetch remote data, and produce contexts. - RaindexYaml (`yaml/raindex.rs`) - Holds `documents: Vec>>` and a `Cache`. - - `new(sources, validation)` loads YAML strings, applies validation gates via `ValidationConfig`, and returns a provider. - - Context initialization: `initialize_context_and_expand_remote_data()` injects remote networks/tokens from the cache into a fresh `Context`. - - Accessors (all parse across all documents, merging maps and checking duplicates): - - Networks: `get_network_keys`, `get_networks`, `get_network(key)`, `get_network_by_chain_id(u32)`. + - `new(sources, validation)` loads YAML strings, applies validation gates via + `ValidationConfig`, and returns a provider. + - Context initialization: `initialize_context_and_expand_remote_data()` + injects remote networks/tokens from the cache into a fresh `Context`. + - Accessors (all parse across all documents, merging maps and checking + duplicates): + - Networks: `get_network_keys`, `get_networks`, `get_network(key)`, + `get_network_by_chain_id(u32)`. - Remote networks: `get_remote_networks` (parse `using-networks-from`). - Tokens: `get_token_keys`, `get_tokens`, `get_token(key)`. - Remote tokens: `get_remote_tokens` (parse optional `using-tokens-from`). - Subgraphs: `get_subgraph_keys`, `get_subgraphs`, `get_subgraph(key)`. - - Raindexes: `get_raindex_keys`, `get_raindexes`, `get_raindex(key)`, `get_raindex_by_address(Address)`, `get_raindexes_by_network_key(&str)`. - - Metaboards: `get_metaboard_keys`, `get_metaboards`, `get_metaboard(key)`, `add_metaboard(key, url)`. + - Raindexes: `get_raindex_keys`, `get_raindexes`, `get_raindex(key)`, + `get_raindex_by_address(Address)`, `get_raindexes_by_network_key(&str)`. + - Metaboards: `get_metaboard_keys`, `get_metaboards`, `get_metaboard(key)`, + `add_metaboard(key, url)`. - Deployers: `get_deployer_keys`, `get_deployers`, `get_deployer(key)`. - Sentry: `get_sentry()` → Option from `sentry` scalar. - Spec version: `get_spec_version()` → string from `version` scalar. - Accounts: `get_account_keys`, `get_accounts`, `get_account(key)`. - - Serde: serializes/deserializes as a sequence of YAML documents represented as strings. + - Serde: serializes/deserializes as a sequence of YAML documents represented + as strings. - DotrainYaml (`yaml/dotrain.rs`) - Also wraps `documents` and a `Cache`. - - `new(sources, validation)` selectively validates orders, scenarios, deployments. + - `new(sources, validation)` selectively validates orders, scenarios, + deployments. - Accessors: - - Orders: `get_order_keys`, `get_orders`, `get_order(key)`, `get_order_for_builder_deployment(order_key, deployment_key)`. + - Orders: `get_order_keys`, `get_orders`, `get_order(key)`, + `get_order_for_builder_deployment(order_key, deployment_key)`. - Scenarios: `get_scenario_keys`, `get_scenarios`, `get_scenario(key)`. - - Deployments: `get_deployment_keys`, `get_deployments`, `get_deployment(key)`. - - Order Builder: `get_order_builder(current_deployment)` parses optional builder section with deployment‑scoped overrides and select‑tokens. + - Deployments: `get_deployment_keys`, `get_deployments`, + `get_deployment(key)`. + - Order Builder: `get_order_builder(current_deployment)` parses optional + builder section with deployment‑scoped overrides and select‑tokens. - Charts: `get_chart_keys`, `get_charts`, `get_chart(key)`. - Serde mirrors `RaindexYaml`. - ## Core Config Objects -All core configs implement `YamlParsableHash` unless noted, and each instance carries a reference to the originating YAML document via `document: Arc>`. This enables in‑place updates that preserve the source document. Equality (`PartialEq`) ignores the `document` field and compares logical data only. +All core configs implement `YamlParsableHash` unless noted, and each instance +carries a reference to the originating YAML document via +`document: Arc>`. This enables in‑place updates that preserve +the source document. Equality (`PartialEq`) ignores the `document` field and +compares logical data only. ### Networks (`network.rs`) - `NetworkCfg { key, rpcs: Vec, chain_id, label?, network_id?, currency? }` - `dummy()` and `Default` for tests. - - Validators: `validate_rpc(&str) -> Url`, `validate_chain_id(&str) -> u64`, `validate_network_id(&str) -> u32`. + - Validators: `validate_rpc(&str) -> Url`, `validate_chain_id(&str) -> u64`, + `validate_network_id(&str) -> u32`. - Parse all: looks for `networks` map with entries shaped like: ```yaml networks: @@ -95,22 +141,32 @@ All core configs implement `YamlParsableHash` unless noted, and each instance ca network-id: 1 currency: ETH ``` - - `parse_rpcs(documents, network_key)` reads just the `rpcs` vector for a named network. - - `update_rpcs(&mut self, Vec)` updates both the YAML document and the in‑memory struct. - - Integrates remote networks from context cache; duplicate keys cause `KeyShadowing`. + - `parse_rpcs(documents, network_key)` reads just the `rpcs` vector for a + named network. + - `update_rpcs(&mut self, Vec)` updates both the YAML document and the + in‑memory struct. + - Integrates remote networks from context cache; duplicate keys cause + `KeyShadowing`. - Specific error enum: `ParseNetworkConfigSourceError` with readable messages. ### Tokens (`token.rs`) - `TokenCfg { key, network: Arc, address, decimals?, label?, symbol? }` - - Validators: `validate_address(value) -> Address`, `validate_decimals(value) -> u8`. - - Parsing requires `tokens` map entries with `network` and `address`, optional `decimals`/`label`/`symbol`. + - Validators: `validate_address(value) -> Address`, + `validate_decimals(value) -> u8`. + - Parsing requires `tokens` map entries with `network` and `address`, optional + `decimals`/`label`/`symbol`. - Mutations: - `update_address(&mut self, &str)` updates YAML and struct. - - `add_record_to_yaml(docs, key, network_key, address, decimals?, label?, symbol?)` inserts a new token record into the first document, checking that the key doesn’t already exist and that the referenced network exists. - - `remove_record_from_yaml(docs, key)` removes a token from whichever document contains it. - - `parse_network_key(docs, token_key)` returns the network key for an existing token definition. - - Merges remote tokens from context cache; conflicts produce `RemoteTokenKeyShadowing`. + - `add_record_to_yaml(docs, key, network_key, address, decimals?, label?, symbol?)` + inserts a new token record into the first document, checking that the key + doesn’t already exist and that the referenced network exists. + - `remove_record_from_yaml(docs, key)` removes a token from whichever + document contains it. + - `parse_network_key(docs, token_key)` returns the network key for an + existing token definition. + - Merges remote tokens from context cache; conflicts produce + `RemoteTokenKeyShadowing`. - Specific error enum: `ParseTokenConfigSourceError` with readable messages. ### Subgraphs (`subgraph.rs`) @@ -121,26 +177,38 @@ All core configs implement `YamlParsableHash` unless noted, and each instance ca ### Raindexes (`raindex.rs`) - `RaindexCfg { key, address, network: Arc, subgraph: Arc, local_db_remote?: Arc, label?, deployment_block }`. -- Validators: `validate_address(&str) -> Address`, `validate_deployment_block(&str) -> u64`. -- Lookup helpers: `parse_network_key(docs, raindex_key)` returns the referenced network key or defaults to the raindex key. -- Parses with references to previously parsed networks and subgraphs; duplicates are rejected. -- Error enum: `ParseRaindexConfigSourceError` (invalid address, missing network/subgraph, block parse error) with readable messages. +- Validators: `validate_address(&str) -> Address`, + `validate_deployment_block(&str) -> u64`. +- Lookup helpers: `parse_network_key(docs, raindex_key)` returns the referenced + network key or defaults to the raindex key. +- Parses with references to previously parsed networks and subgraphs; duplicates + are rejected. +- Error enum: `ParseRaindexConfigSourceError` (invalid address, missing + network/subgraph, block parse error) with readable messages. ### Local DB Remotes (`local_db_remotes.rs`) -- `local-db-remotes:` is a optional top-level map. Each entry is parsed as `LocalDbRemoteCfg { key, url }`. -- The `raindexes[*].local-db-remote` field is optional. If omitted, it defaults to the raindex's key. When provided explicitly, it must reference a defined remote key under `local-db-remotes`. - - See `src/raindex.rs` for the implementation and tests, e.g. `test_raindex_local_db_remote_absent_defaults_to_raindex_key`, `test_raindex_local_db_remote_resolves`, and `test_raindex_local_db_remote_not_found`. +- `local-db-remotes:` is a optional top-level map. Each entry is parsed as + `LocalDbRemoteCfg { key, url }`. +- The `raindexes[*].local-db-remote` field is optional. If omitted, it defaults + to the raindex's key. When provided explicitly, it must reference a defined + remote key under `local-db-remotes`. + - See `src/raindex.rs` for the implementation and tests, e.g. + `test_raindex_local_db_remote_absent_defaults_to_raindex_key`, + `test_raindex_local_db_remote_resolves`, and + `test_raindex_local_db_remote_not_found`. ### Deployers (`deployer.rs`) - `DeployerCfg { key, address, network }`. -- Validators and `parse_network_key` similar to raindexes (defaults to key if `network` is omitted). +- Validators and `parse_network_key` similar to raindexes (defaults to key if + `network` is omitted). - Error enum: `ParseDeployerConfigSourceError`. ### Accounts (`accounts.rs`) -- `AccountCfg { key, address }` from a simple `accounts:` map where values are addresses. +- `AccountCfg { key, address }` from a simple `accounts:` map where values are + addresses. - Error enum: `ParseAccountCfgError`. ### Metaboards (`metaboard.rs`) @@ -150,63 +218,95 @@ All core configs implement `YamlParsableHash` unless noted, and each instance ca ### Spec Version and Sentry -- `SpecVersion` reads required root scalar `version`. Const `CURRENT_SPEC_VERSION = "3"` and helpers `current()` / `is_current()`. -- `Sentry` parses optional root scalar `sentry`. `RaindexYaml::get_sentry()` normalizes to `Option` accepting `true/false/1/0`. - +- `SpecVersion` reads required root scalar `version`. Const + `CURRENT_SPEC_VERSION = "3"` and helpers `current()` / `is_current()`. +- `Sentry` parses optional root scalar `sentry`. `RaindexYaml::get_sentry()` + normalizes to `Option` accepting `true/false/1/0`. ## Orders, Scenarios, Deployments -These three model how orders are defined, how they are executed (bindings, blocks, runs), and how a deployment pairs an order with a scenario under a specific deployer. +These three model how orders are defined, how they are executed (bindings, +blocks, runs), and how a deployment pairs an order with a scenario under a +specific deployer. ### Orders (`order.rs`) - `OrderCfg { key, inputs: Vec, outputs: Vec, network: Arc, deployer?: Arc, raindex?: Arc }`. -- `OrderIOCfg { token_key: String, token?: Arc, vault_id?: U256 }` – `token_key` preserves the declared token name even when the token is unresolved for select‑tokens; vault IDs are arbitrary U256 strings. +- `OrderIOCfg { token_key: String, token?: Arc, vault_id?: U256 }` – + `token_key` preserves the declared token name even when the token is + unresolved for select‑tokens; vault IDs are arbitrary U256 strings. - Validation and network unification - - Inputs/outputs must each contain `token` (unless permitted by builder select‑tokens through context) and optional `vault-id`. - - The order’s effective `network` is inferred from first matching component (deployer/raindex/token), and all references must match. Mismatch yields detailed errors (`DeployerNetworkDoesNotMatch`, `RaindexNetworkDoesNotMatch`, `InputTokenNetworkDoesNotMatch`, `OutputTokenNetworkDoesNotMatch`). If no network can be determined, `NetworkNotFoundError` is raised. + - Inputs/outputs must each contain `token` (unless permitted by builder + select‑tokens through context) and optional `vault-id`. + - The order’s effective `network` is inferred from first matching component + (deployer/raindex/token), and all references must match. Mismatch yields + detailed errors (`DeployerNetworkDoesNotMatch`, + `RaindexNetworkDoesNotMatch`, `InputTokenNetworkDoesNotMatch`, + `OutputTokenNetworkDoesNotMatch`). If no network can be determined, + `NetworkNotFoundError` is raised. - Vault IDs are validated via `U256::from_str`. - Mutations - - `update_vault_id(vault_type, token_key, vault_id_opt)` updates a vault ID for a specific input/output token inside the YAML. - - `populate_vault_ids()` fills missing input/output `vault-id`s in the YAML with a freshly generated random U256, and updates the in‑memory struct accordingly. + - `update_vault_id(vault_type, token_key, vault_id_opt)` updates a vault ID + for a specific input/output token inside the YAML. + - `populate_vault_ids()` fills missing input/output `vault-id`s in the YAML + with a freshly generated random U256, and updates the in‑memory struct + accordingly. - Helpers - - `parse_network_key(docs, order_key)` – resolves the expected network key by reconciling deployer/raindex and all IO token networks; errors if any disagree. -- Error enum: `ParseOrderConfigSourceError` implements `to_readable_msg()` for user‑oriented descriptions. + - `parse_network_key(docs, order_key)` – resolves the expected network key by + reconciling deployer/raindex and all IO token networks; errors if any + disagree. +- Error enum: `ParseOrderConfigSourceError` implements `to_readable_msg()` for + user‑oriented descriptions. ### Scenarios (`scenario.rs`) - `ScenarioCfg { key, bindings: HashMap, runs?: u64, blocks?: BlocksCfg, deployer: Arc }`. -- Nested structure: scenarios can contain sub‑scenarios under `scenarios:`; keys compose as `parent.child` in the parsed map. +- Nested structure: scenarios can contain sub‑scenarios under `scenarios:`; keys + compose as `parent.child` in the parsed map. - Bindings - - Parent bindings are inherited; children cannot change an existing binding’s value (shadowing causes `ParentBindingShadowedError`). + - Parent bindings are inherited; children cannot change an existing binding’s + value (shadowing causes `ParentBindingShadowedError`). - Values support interpolation through `Context`. - Blocks and runs - `runs` is optional `u64`. - - `blocks` can be the compact range form (`[a..b]`, `[..b]`, `[a..]`) or an object with `{ range: [...], interval: u32 }` (see Blocks below). Parser accepts either string or structured map formats. + - `blocks` can be the compact range form (`[a..b]`, `[..b]`, `[a..]`) or an + object with `{ range: [...], interval: u32 }` (see Blocks below). Parser + accepts either string or structured map formats. - Deployer - - A scenario can pick a deployer explicitly (`deployer: `) or implicitly by name (scenario key matches a deployer key). A child scenario must not change the deployer chosen by its parent (`ParentDeployerShadowedError`). + - A scenario can pick a deployer explicitly (`deployer: `) or implicitly + by name (scenario key matches a deployer key). A child scenario must not + change the deployer chosen by its parent (`ParentDeployerShadowedError`). - Mutations - - `update_bindings(Map)` updates only existing binding keys across the scenario path; new keys are appended at the lowest level of the current scenario path. Changes are persisted into YAML, then the scenario is re‑parsed and returned. + - `update_bindings(Map)` updates only existing binding keys + across the scenario path; new keys are appended at the lowest level of the + current scenario path. Changes are persisted into YAML, then the scenario is + re‑parsed and returned. ### Blocks (`blocks.rs`) -- `BlockCfg`: `Number(BlockNumber) | Genesis | Latest` with helper `to_block_number(latest)`. +- `BlockCfg`: `Number(BlockNumber) | Genesis | Latest` with helper + `to_block_number(latest)`. - `BlockRangeCfg { start: BlockCfg, end: BlockCfg }` with `validate(latest)`. -- `BlocksCfg`: `SimpleRange(BlockRangeCfg)` or `RangeWithInterval { range, interval }`. -- Expansion: `expand_to_block_numbers(latest)` produces a concrete vector of block numbers after validating the range. +- `BlocksCfg`: `SimpleRange(BlockRangeCfg)` or + `RangeWithInterval { range, interval }`. +- Expansion: `expand_to_block_numbers(latest)` produces a concrete vector of + block numbers after validating the range. ### Deployments (`deployment.rs`) - `DeploymentCfg { key, scenario: Arc, order: Arc }`. - Parsing - - Respects optional order builder context for “current deployment” to allow per‑deployment scoping when documents contain many deployments. - - Ensures the selected order and scenario share the same deployer; otherwise returns `ParseDeploymentConfigSourceError::NoMatch`. - - Helper `parse_order_key(docs, deployment_key)` extracts the order name for a deployment. - + - Respects optional order builder context for “current deployment” to allow + per‑deployment scoping when documents contain many deployments. + - Ensures the selected order and scenario share the same deployer; otherwise + returns `ParseDeploymentConfigSourceError::NoMatch`. + - Helper `parse_order_key(docs, deployment_key)` extracts the order name for a + deployment. ## Order Builder Configuration (`order_builder.rs`) -The order builder DSL configures per‑deployment user inputs (fields), deposit presets/validation, and “select tokens” behavior for orders rendered in the UI. +The order builder DSL configures per‑deployment user inputs (fields), deposit +presets/validation, and “select tokens” behavior for orders rendered in the UI. - Source types (pure data) to transform into runtime types: - `OrderBuilderConfigSourceCfg { name, description, deployments: Map }`. @@ -228,10 +328,15 @@ The order builder DSL configures per‑deployment user inputs (fields), deposit - `OrderBuilderPresetCfg { id, name?, value }`. - Parsing - - `OrderBuilderCfg::parse_from_yaml_optional(documents, context)` traverses a `builder:` map, applying deployment scoping from order builder context and order/deployment context, and builds an `OrderBuilderCfg` if present. - - Helper queries: `check_builder_key_exists`, `parse_deployment_keys`, `parse_order_details`, `parse_deployment_details`, `parse_field_presets`, `parse_select_tokens`. - - Integrates tokens (if present) to resolve deposit token references to `Arc`. With “select‑tokens”, the context is seeded with allowed token keys so orders may omit YAML token entries. - + - `OrderBuilderCfg::parse_from_yaml_optional(documents, context)` traverses a + `builder:` map, applying deployment scoping from order builder context and + order/deployment context, and builds an `OrderBuilderCfg` if present. + - Helper queries: `check_builder_key_exists`, `parse_deployment_keys`, + `parse_order_details`, `parse_deployment_details`, `parse_field_presets`, + `parse_select_tokens`. + - Integrates tokens (if present) to resolve deposit token references to + `Arc`. With “select‑tokens”, the context is seeded with allowed + token keys so orders may omit YAML token entries. ## Charts and Plot DSL @@ -239,21 +344,29 @@ Charts let scenarios expose visualizations for analysis. - `ChartCfg { key, scenario: Arc, plots?: [PlotCfg], metrics?: [MetricCfg] }`. - `MetricCfg { label, description?, unit_prefix?, unit_suffix?, value, precision? }`. - - Parses `charts:` map; each chart may reference a scenario by key (defaults to the chart key) and include `plots:` and `metrics:`. + - Parses `charts:` map; each chart may reference a scenario by key (defaults + to the chart key) and include `plots:` and `metrics:`. - Plot source DSL (`plot_source.rs`) - `PlotCfg { title?, subtitle?, marks: [MarkCfg], x?: AxisOptionsCfg, y?: AxisOptionsCfg, margin/…? }`. - - `MarkCfg` variants: `Dot(DotOptionsCfg)`, `Line(LineOptionsCfg)`, `RectY(RectYOptionsCfg)`. + - `MarkCfg` variants: `Dot(DotOptionsCfg)`, `Line(LineOptionsCfg)`, + `RectY(RectYOptionsCfg)`. - Mark options may carry an optional transform. - - Transforms: `TransformCfg::HexBin(HexBinTransformCfg)` and `TransformCfg::BinX(BinXTransformCfg)` each with `TransformOutputsCfg` and `options` specific to the transform (e.g. `bin-width` for hexbin, `thresholds` for binx). + - Transforms: `TransformCfg::HexBin(HexBinTransformCfg)` and + `TransformCfg::BinX(BinXTransformCfg)` each with `TransformOutputsCfg` and + `options` specific to the transform (e.g. `bin-width` for hexbin, + `thresholds` for binx). - `AxisOptionsCfg` configures labels/anchors for axes. -- The chart parser (`chart.rs`) wires the YAML layout into these types and performs validation (e.g., presence and types of transform `content`, numeric fields, required `marks` vectors). Numeric strings are validated via `ChartCfg::validate_u32` where appropriate. - +- The chart parser (`chart.rs`) wires the YAML layout into these types and + performs validation (e.g., presence and types of transform `content`, numeric + fields, required `marks` vectors). Numeric strings are validated via + `ChartCfg::validate_u32` where appropriate. ## Remote Data -Remote sections allow enriching local YAML with data fetched at runtime and merged into the model. +Remote sections allow enriching local YAML with data fetched at runtime and +merged into the model. - Remote Networks (`remote_networks.rs` + `remote/chains.rs`) - YAML shape: @@ -263,9 +376,13 @@ Remote sections allow enriching local YAML with data fetched at runtime and merg url: https://… format: chainid ``` - - `RemoteNetworksCfg` parses the above. `fetch_networks(map)` issues HTTP GET requests and parses JSON into `ChainId` structures. - - `ChainId::try_into_network_cfg` converts a chain into a `NetworkCfg` by selecting the first acceptable RPC URL (non‑WS and without `API_KEY` placeholders). Key is the chain’s `shortName`. - - Conflicts in produced network keys across sources yield `ConflictingNetworks`. + - `RemoteNetworksCfg` parses the above. `fetch_networks(map)` issues HTTP GET + requests and parses JSON into `ChainId` structures. + - `ChainId::try_into_network_cfg` converts a chain into a `NetworkCfg` by + selecting the first acceptable RPC URL (non‑WS and without `API_KEY` + placeholders). Key is the chain’s `shortName`. + - Conflicts in produced network keys across sources yield + `ConflictingNetworks`. - Remote Tokens (`remote_tokens.rs` + `remote/tokens.rs`) - YAML shape: @@ -274,56 +391,81 @@ Remote sections allow enriching local YAML with data fetched at runtime and merg - https://…/tokenlist.json - https://…/another-list.json ``` - - `RemoteTokensCfg::parse_from_yaml_optional` collects/validates URLs (deduplicating across documents). `fetch_tokens(networks, cfg)` GETs each URL, merges token lists while de‑duplicating by `(chainId, addressLowercase)`, and then converts known chain IDs into `TokenCfg` by matching against provided `networks`. + - `RemoteTokensCfg::parse_from_yaml_optional` collects/validates URLs + (deduplicating across documents). `fetch_tokens(networks, cfg)` GETs each + URL, merges token lists while de‑duplicating by + `(chainId, addressLowercase)`, and then converts known chain IDs into + `TokenCfg` by matching against provided `networks`. - Key format: `"--"`. - Conflicting keys across URLs produce `ConflictingTokens`. -Both remote features are surfaced to parsing via the `Context`/`Cache`. `RaindexYaml` and `DotrainYaml` expose helper methods to fetch/update cache and then merge these into subsequent parses. - +Both remote features are surfaced to parsing via the `Context`/`Cache`. +`RaindexYaml` and `DotrainYaml` expose helper methods to fetch/update cache and +then merge these into subsequent parses. ## Miscellaneous Modules -- `accounts.rs`: named EVM addresses in `accounts:`. Simple map with validation and duplicate checks. -- `sentry.rs`: optional root scalar `sentry` read as string and normalized to `Option` by `RaindexYaml`. -- `spec_version.rs`: required root scalar `version` and helpers to compare to the current spec version (constant "3"). +- `accounts.rs`: named EVM addresses in `accounts:`. Simple map with validation + and duplicate checks. +- `sentry.rs`: optional root scalar `sentry` read as string and normalized to + `Option` by `RaindexYaml`. +- `spec_version.rs`: required root scalar `version` and helpers to compare to + the current spec version (constant "3"). - `test.rs`: test helpers to construct mock networks/tokens/deployers/raindexes. -- `unit_test.rs`: auxiliary types (`UnitTestConfigSource`, `TestConfigSource`, `ScenarioConfigSource`) used by the test harness in other crates. `TestConfigSource::into_test_config()` converts the simplified source into a `TestConfig` with an embedded `ScenarioCfg`. - +- `unit_test.rs`: auxiliary types (`UnitTestConfigSource`, `TestConfigSource`, + `ScenarioConfigSource`) used by the test harness in other crates. + `TestConfigSource::into_test_config()` converts the simplified source into a + `TestConfig` with an embedded `ScenarioCfg`. ## Concurrency and Update Semantics -Every config item carries `document: Arc>` pointing to the YAML document where it originated. “Update” methods (`TokenCfg::update_address`, `NetworkCfg::update_rpcs`, `OrderCfg::update_vault_id`, `OrderCfg::populate_vault_ids`, `MetaboardCfg::add_record_to_yaml`, `SubgraphCfg::add_record_to_yaml`, `TokenCfg::add_record_to_yaml`/`remove_record_from_yaml`) acquire a write lock, mutate the tree in place, and update the in‑memory struct for consistency. All read operations acquire read locks. - +Every config item carries `document: Arc>` pointing to the +YAML document where it originated. “Update” methods (`TokenCfg::update_address`, +`NetworkCfg::update_rpcs`, `OrderCfg::update_vault_id`, +`OrderCfg::populate_vault_ids`, `MetaboardCfg::add_record_to_yaml`, +`SubgraphCfg::add_record_to_yaml`, +`TokenCfg::add_record_to_yaml`/`remove_record_from_yaml`) acquire a write lock, +mutate the tree in place, and update the in‑memory struct for consistency. All +read operations acquire read locks. ## Duplicate Keys and Merging -For map‑shaped sections parsed across multiple documents, the crate enforces unique keys within the merged result. If a key appears twice across any documents, parsing fails with `YamlError::KeyShadowing(key, section)`. This guarantees deterministic provenance and avoids silent overrides. - +For map‑shaped sections parsed across multiple documents, the crate enforces +unique keys within the merged result. If a key appears twice across any +documents, parsing fails with `YamlError::KeyShadowing(key, section)`. This +guarantees deterministic provenance and avoids silent overrides. ## Error Reporting Philosophy -All parser and validator errors convert to `YamlError` or module‑specific `*Parse*Error` enums with a `to_readable_msg()` that is safe to show to end users. `FieldErrorKind::{Missing, InvalidType, InvalidValue}` always include a precise human‑readable location (e.g., "order 'MyOrder'", "output index '0' in order 'MyOrder'", "order builder deployment 'MyDeployment'"). - +All parser and validator errors convert to `YamlError` or module‑specific +`*Parse*Error` enums with a `to_readable_msg()` that is safe to show to end +users. `FieldErrorKind::{Missing, InvalidType, InvalidValue}` always include a +precise human‑readable location (e.g., "order 'MyOrder'", "output index '0' in +order 'MyOrder'", "order builder deployment 'MyDeployment'"). ## WASM/TypeScript Interop -When building for `wasm32`, many types derive `Tsify` and implement WASM trait helpers via `wasm_bindgen_utils::impl_wasm_traits!`. This allows the web UI to import the same configuration model with strong typing (including union types and optional fields) and to consume results produced by this crate. - +When building for `wasm32`, many types derive `Tsify` and implement WASM trait +helpers via `wasm_bindgen_utils::impl_wasm_traits!`. This allows the web UI to +import the same configuration model with strong typing (including union types +and optional fields) and to consume results produced by this crate. ## Typical Workflows - Validate raindex YAML for networks/tokens/etc. and query objects: 1. Load strings into `RaindexYaml::new([...], RaindexYamlValidation::full())`. - 2. Optionally fetch remote networks/tokens, store in cache, and then call `get_*` methods to retrieve `NetworkCfg`, `TokenCfg`, `RaindexCfg`, etc. + 2. Optionally fetch remote networks/tokens, store in cache, and then call + `get_*` methods to retrieve `NetworkCfg`, `TokenCfg`, `RaindexCfg`, etc. 3. Use update helpers to persist changes back to YAML documents. - Validate dotrain YAML and build a deployment plan: 1. Load strings into `DotrainYaml::new([...], DotrainYamlValidation::full())`. - 2. Resolve `OrderCfg`, `ScenarioCfg`, and `DeploymentCfg`; ensure network/deployer invariants hold. - 3. Optional Order Builder: parse `OrderBuilderCfg` scoped to a specific deployment and seed context with `select-tokens`. + 2. Resolve `OrderCfg`, `ScenarioCfg`, and `DeploymentCfg`; ensure + network/deployer invariants hold. + 3. Optional Order Builder: parse `OrderBuilderCfg` scoped to a specific + deployment and seed context with `select-tokens`. 4. Optional Charts: parse `ChartCfg` for visualization. - ## YAML Shape Reference (informative) - Root keys seen across modules (some optional depending on usage): @@ -344,12 +486,19 @@ When building for `wasm32`, many types derive `Tsify` and implement WASM trait h - `charts: { key: { scenario?, plots?: {...}, metrics?: [...] } }` - `sentry: true|false|1|0` - ## Testing -The crate ships extensive unit tests for every parser and update path, including error paths with precise messages. Test helpers in `src/test.rs` construct mock networks/deployers/tokens/raindexes; parser modules provide happy‑path and negative test cases (duplicate keys, missing/invalid fields, range validation for blocks, builder validation, remote fetch flows with http mocks, etc.). - +The crate ships extensive unit tests for every parser and update path, including +error paths with precise messages. Test helpers in `src/test.rs` construct mock +networks/deployers/tokens/raindexes; parser modules provide happy‑path and +negative test cases (duplicate keys, missing/invalid fields, range validation +for blocks, builder validation, remote fetch flows with http mocks, etc.). ## Summary -The settings crate provides a single, well‑typed interface over YAML configuration for the Raindex ecosystem: robust parsing across multiple files, strict validation with user‑friendly errors, safe in‑place updates, optional remote augmentation, contextual interpolation, builder and chart DSLs, and WASM interop. Other crates consume these types to build CLIs, runtimes, and UIs without re‑implementing YAML logic. +The settings crate provides a single, well‑typed interface over YAML +configuration for the Raindex ecosystem: robust parsing across multiple files, +strict validation with user‑friendly errors, safe in‑place updates, optional +remote augmentation, contextual interpolation, builder and chart DSLs, and WASM +interop. Other crates consume these types to build CLIs, runtimes, and UIs +without re‑implementing YAML logic. diff --git a/crates/test_fixtures/abis/RaindexV6.json b/crates/test_fixtures/abis/RaindexV6.json new file mode 100644 index 0000000000..654c1f74e1 --- /dev/null +++ b/crates/test_fixtures/abis/RaindexV6.json @@ -0,0 +1,2379 @@ +{ + "abi": [ + { + "type": "function", + "name": "addOrder4", + "inputs": [ + { + "name": "orderConfig", + "type": "tuple", + "internalType": "struct OrderConfigV4", + "components": [ + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "secret", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "meta", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "post", + "type": "tuple[]", + "internalType": "struct TaskV2[]", + "components": [ + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "signedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ] + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "clear3", + "inputs": [ + { + "name": "aliceOrder", + "type": "tuple", + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "bobOrder", + "type": "tuple", + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "clearConfig", + "type": "tuple", + "internalType": "struct ClearConfigV2", + "components": [ + { + "name": "aliceInputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "aliceOutputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "bobInputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "bobOutputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "aliceBountyVaultId", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "bobBountyVaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "aliceSignedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "bobSignedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "deposit4", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "depositAmount", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "post", + "type": "tuple[]", + "internalType": "struct TaskV2[]", + "components": [ + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "signedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "entask2", + "inputs": [ + { + "name": "post", + "type": "tuple[]", + "internalType": "struct TaskV2[]", + "components": [ + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "signedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "flashFee", + "inputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + }, + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "flashLoan", + "inputs": [ + { + "name": "receiver", + "type": "address", + "internalType": "contract IERC3156FlashBorrower" + }, + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "data", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "maxFlashLoan", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "multicall", + "inputs": [ + { + "name": "data", + "type": "bytes[]", + "internalType": "bytes[]" + } + ], + "outputs": [ + { + "name": "results", + "type": "bytes[]", + "internalType": "bytes[]" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "orderExists", + "inputs": [ + { + "name": "orderHash", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "quote2", + "inputs": [ + { + "name": "quoteConfig", + "type": "tuple", + "internalType": "struct QuoteV2", + "components": [ + { + "name": "order", + "type": "tuple", + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "inputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "outputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "signedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ] + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + }, + { + "name": "", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "removeOrder3", + "inputs": [ + { + "name": "order", + "type": "tuple", + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "post", + "type": "tuple[]", + "internalType": "struct TaskV2[]", + "components": [ + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "signedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ] + } + ], + "outputs": [ + { + "name": "stateChanged", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "supportsInterface", + "inputs": [ + { + "name": "interfaceId", + "type": "bytes4", + "internalType": "bytes4" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "takeOrders4", + "inputs": [ + { + "name": "config", + "type": "tuple", + "internalType": "struct TakeOrdersConfigV5", + "components": [ + { + "name": "minimumIO", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "maximumIO", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "maximumIORatio", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "IOIsInput", + "type": "bool", + "internalType": "bool" + }, + { + "name": "orders", + "type": "tuple[]", + "internalType": "struct TakeOrderConfigV4[]", + "components": [ + { + "name": "order", + "type": "tuple", + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "inputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "outputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "signedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ] + }, + { + "name": "data", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ], + "outputs": [ + { + "name": "totalTakerInput", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "totalTakerOutput", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "vaultBalance2", + "inputs": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "withdraw4", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "targetAmount", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "post", + "type": "tuple[]", + "internalType": "struct TaskV2[]", + "components": [ + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "signedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "event", + "name": "AddOrderV3", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "orderHash", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + }, + { + "name": "order", + "type": "tuple", + "indexed": false, + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "AfterClearV2", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "clearStateChange", + "type": "tuple", + "indexed": false, + "internalType": "struct ClearStateChangeV2", + "components": [ + { + "name": "aliceOutput", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "bobOutput", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "aliceInput", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "bobInput", + "type": "bytes32", + "internalType": "Float" + } + ] + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ClearV3", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "alice", + "type": "tuple", + "indexed": false, + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "bob", + "type": "tuple", + "indexed": false, + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "clearConfig", + "type": "tuple", + "indexed": false, + "internalType": "struct ClearConfigV2", + "components": [ + { + "name": "aliceInputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "aliceOutputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "bobInputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "bobOutputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "aliceBountyVaultId", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "bobBountyVaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ContextV2", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[][]", + "indexed": false, + "internalType": "bytes32[][]" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "DepositV2", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + }, + { + "name": "depositAmountUint256", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "MetaV1_2", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "subject", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + }, + { + "name": "meta", + "type": "bytes", + "indexed": false, + "internalType": "bytes" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OrderExceedsMaxRatio", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "owner", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "orderHash", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OrderNotFound", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "owner", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "orderHash", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OrderZeroAmount", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "owner", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "orderHash", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RemoveOrderV3", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "orderHash", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + }, + { + "name": "order", + "type": "tuple", + "indexed": false, + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "TakeOrderV3", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "config", + "type": "tuple", + "indexed": false, + "internalType": "struct TakeOrderConfigV4", + "components": [ + { + "name": "order", + "type": "tuple", + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "inputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "outputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "signedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ] + }, + { + "name": "input", + "type": "bytes32", + "indexed": false, + "internalType": "Float" + }, + { + "name": "output", + "type": "bytes32", + "indexed": false, + "internalType": "Float" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "WithdrawV2", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + }, + { + "name": "targetAmount", + "type": "bytes32", + "indexed": false, + "internalType": "Float" + }, + { + "name": "withdrawAmount", + "type": "bytes32", + "indexed": false, + "internalType": "Float" + }, + { + "name": "withdrawAmountUint256", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "AddressEmptyCode", + "inputs": [ + { + "name": "target", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ClearZeroAmount", + "inputs": [] + }, + { + "type": "error", + "name": "CoefficientOverflow", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "DivisionByZero", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "ExponentOverflow", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "ExponentUnderflow", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "FailedCall", + "inputs": [] + }, + { + "type": "error", + "name": "FixedDecimalOverflow", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + }, + { + "name": "decimals", + "type": "uint8", + "internalType": "uint8" + } + ] + }, + { + "type": "error", + "name": "FlashLenderCallbackFailed", + "inputs": [ + { + "name": "result", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "type": "error", + "name": "InvalidSignature", + "inputs": [ + { + "name": "i", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "LossyConversionToFloat", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "MaximizeOverflow", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "MinimumIO", + "inputs": [ + { + "name": "minimumIO", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "actualIO", + "type": "bytes32", + "internalType": "Float" + } + ] + }, + { + "type": "error", + "name": "MulDivOverflow", + "inputs": [ + { + "name": "x", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "y", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "denominator", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "NegativeBounty", + "inputs": [] + }, + { + "type": "error", + "name": "NegativeFixedDecimalConversion", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "NegativePull", + "inputs": [] + }, + { + "type": "error", + "name": "NegativePush", + "inputs": [] + }, + { + "type": "error", + "name": "NegativeVaultBalance", + "inputs": [ + { + "name": "vaultBalance", + "type": "bytes32", + "internalType": "Float" + } + ] + }, + { + "type": "error", + "name": "NegativeVaultBalanceChange", + "inputs": [ + { + "name": "amount", + "type": "bytes32", + "internalType": "Float" + } + ] + }, + { + "type": "error", + "name": "NoOrders", + "inputs": [] + }, + { + "type": "error", + "name": "NotOrderOwner", + "inputs": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "NotRainMetaV1", + "inputs": [ + { + "name": "unmeta", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "type": "error", + "name": "OrderNoHandleIO", + "inputs": [] + }, + { + "type": "error", + "name": "OrderNoInputs", + "inputs": [] + }, + { + "type": "error", + "name": "OrderNoOutputs", + "inputs": [] + }, + { + "type": "error", + "name": "OrderNoSources", + "inputs": [] + }, + { + "type": "error", + "name": "ReentrancyGuardReentrantCall", + "inputs": [] + }, + { + "type": "error", + "name": "SafeERC20FailedOperation", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "SameOwner", + "inputs": [] + }, + { + "type": "error", + "name": "TOFUTokenDecimalsNotDeployed", + "inputs": [ + { + "name": "expectedAddress", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "TokenDecimalsReadFailure", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "tofuOutcome", + "type": "uint8", + "internalType": "enum TOFUOutcome" + } + ] + }, + { + "type": "error", + "name": "TokenMismatch", + "inputs": [] + }, + { + "type": "error", + "name": "TokenSelfTrade", + "inputs": [] + }, + { + "type": "error", + "name": "UnsupportedCalculateOutputs", + "inputs": [ + { + "name": "outputs", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "ZeroDepositAmount", + "inputs": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "type": "error", + "name": "ZeroMaximumIO", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroVaultId", + "inputs": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ZeroWithdrawTargetAmount", + "inputs": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + } + ], + "bytecode": { + "object": "0x6080604052348015600e575f80fd5b5060017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055615c24806100405f395ff3fe608060405234801561000f575f80fd5b50600436106100f0575f3560e01c8063613255ab11610093578063ac9650d811610063578063ac9650d81461022b578063d7e442ec1461024b578063d9d98ce41461025e578063fa50118214610273575f80fd5b8063613255ab146101ad57806369c72856146101c0578063709fb8a5146101e85780639235084d146101fb575f80fd5b80632fbc4ba0116100ce5780632fbc4ba01461015157806341d1514f146101665780635cffe9de14610187578063607461191461019a575f80fd5b806301ffc9a7146100f45780631f69cb751461011c5780632cb77e9f1461012f575b5f80fd5b61010761010236600461463b565b610286565b60405190151581526020015b60405180910390f35b61010761012a3660046146a3565b6102bc565b61010761013d36600461470e565b5f9081526020819052604090205460011490565b61016461015f366004614744565b610404565b005b6101796101743660046147a9565b61054a565b604051908152602001610113565b6101076101953660046147e7565b61055e565b6101646101a8366004614744565b61065e565b6101796101bb36600461487e565b6107f1565b6101d36101ce3660046148af565b610859565b60408051928352602083019190915201610113565b6101076101f63660046148e1565b610efc565b61020e61020936600461492b565b6111c5565b604080519315158452602084019290925290820152606001610113565b61023e610239366004614962565b611286565b60405161011391906149cf565b610164610259366004614962565b61136c565b61017961026c366004614a31565b5f92915050565b610164610281366004614ea3565b6113c6565b5f6001600160e01b0319821663e414309160e01b14806102b657506301ffc9a760e01b6001600160e01b03198316145b92915050565b5f6102c5611865565b6102d2602085018561487e565b6001600160a01b0316336001600160a01b031614610321576102f7602085018561487e565b6040516335252be360e01b81526001600160a01b0390911660048201526024015b60405180910390fd5b5f61033361032e86614f5d565b611880565b5f818152602081905260409020549091505f19016103e6575f818152602081905260408082209190915551600192507f09d18501db0080ca2d6cd7c17fa7255daff4b2d503ea93b76ff68b6752ea8e6390610393903390849089906150aa565b60405180910390a16040805160028152602081018390523381830152606081019091526103e6906103d7905b60408051600181526020810192909252818101905290565b6103e1858761516e565b6118af565b506103fd60015f80516020615c0483398151915255565b9392505050565b61040c611865565b33858561041a838383611a7d565b610424865f611ab3565b610459576040516306dde9c360e41b81523360048201526001600160a01b038916602482015260448101889052606401610318565b5f80610466338b8a611aed565b604080513381526001600160a01b038e1660208201529081018c90526060810183905291935091507f7f9dfa19cf1cc2f806f2f860fbc9c056b601fb1afc0e9b843dfe5c63616268e69060800160405180910390a15f806104c9338d8d8d611bc7565b909250905087156105265760408051600581526001600160a01b038e1660208201528082018d9052606081018490526080810183905260ff851660a082015260c081019091526105269061051c906103bf565b6103e18a8c61516e565b5050505050505061054360015f80516020615c0483398151915255565b5050505050565b5f610556848484611cb7565b949350505050565b5f6105736001600160a01b0386168786611e60565b6040516323e30c8b60e01b81525f906001600160a01b038816906323e30c8b906105ab9033908a908a9087908b908b9060040161522e565b6020604051808303815f875af11580156105c7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105eb9190615272565b90507f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd9811461063057604051630b6c58a960e31b815260048101829052602401610318565b610651873061063f5f8961529d565b6001600160a01b038a16929190611e95565b5060019695505050505050565b610666611865565b338585610674838383611a7d565b5f8080806106828a82611ab3565b6106b657604051623a3a4d60e21b81523360048201526001600160a01b038d166024820152604481018c9052606401610318565b5f6106c2338e8e611cb7565b90506106ce8b82611ed1565b94506106dc338e8e88611eed565b90935091505f6106ed338f88611f64565b80965081925050507f8045c25080b0868951141ed0a91720bcad09a8364a2b3109ee1fd49c1f0bc8b8338f8f8f8a8660405161075f969594939291906001600160a01b03968716815294909516602085015260408401929092526060830152608082015260a081019190915260c00190565b60405180910390a1505060408051600681526001600160a01b038e1660208201528082018d9052606081018490526080810183905260a081018c905260ff851660c0820152600160e08201908152610100820182905261012082019092529089156107d2576107d2816103e18c8e61516e565b50505050505050505061054360015f80516020615c0483398151915255565b6040516370a0823160e01b81523060048201525f906001600160a01b038316906370a0823190602401602060405180830381865afa158015610835573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102b69190615272565b5f80610863611865565b61087060808401846152b0565b90505f0361089157604051639c95219f60e01b815260040160405180910390fd5b610899614563565b6108a161458f565b5f6108af60808701876152b0565b5f8181106108bf576108bf6152f6565b90506020028101906108d1919061530a565b6108db9080615328565b6108e990604081019061533c565b6108f660808901896152b0565b5f818110610906576109066152f6565b9050602002810190610918919061530a565b6020013581811061092b5761092b6152f6565b610941926020604090920201908101915061487e565b90505f61095160808801886152b0565b5f818110610961576109616152f6565b9050602002810190610973919061530a565b61097d9080615328565b61098b90606081019061533c565b61099860808a018a6152b0565b5f8181106109a8576109a86152f6565b90506020028101906109ba919061530a565b604001358181106109cd576109cd6152f6565b6109e3926020604090920201908101915061487e565b905060605f6109f560808a018a6152b0565b6040805160206001939093018302810190915293508a01359150610a1b9050815f611ab3565b610a385760405163315f9e2360e21b815260040160405180910390fd5b5f5b610a4760808b018b6152b0565b905081108015610a5c5750610a5c825f611ab3565b15610db957610a6e60808b018b6152b0565b82818110610a7e57610a7e6152f6565b9050602002810190610a90919061530a565b610a9990615382565b9650865f01519550846001600160a01b03168660400151886020015181518110610ac557610ac56152f6565b60200260200101515f01516001600160a01b0316141580610b1c5750836001600160a01b03168660600151886040015181518110610b0557610b056152f6565b60200260200101515f01516001600160a01b031614155b15610b3a5760405163936bb5ad60e01b815260040160405180910390fd5b610b4d8688602001518960400151612027565b5f610b5787611880565b5f81815260208190526040902054909150610bbc578651604080513381526001600160a01b03909216602083015281018290527fb70c12fa453793fa6818ec07c91e74363a47aa6a6829dcd9533937fdf30314f39060600160405180910390a1610db0565b5f610bd6888a602001518b60400151338d60600151612099565b6060810151909150610bec9060408e0135611ab3565b15610c42578751604080513381526001600160a01b03909216602083015281018390527fe3151dc8cb7a54ffc4baabd28c1f241c94d510b5e5b502491ac3cad6c16316d5906060015b60405180910390a1610dae565b60408101516001600160e01b0316610c9c578751604080513381526001600160a01b03909216602083015281018390527f500b713857325f9e6dcb52ae832eca9109d107ed1aae9cb4928b4c1e13f051aa90606001610c35565b5f808d6060016020810190610cb19190615418565b15610cea576040830151610cc59087611ed1565b6060840151909250610cd79083612657565b9050610ce386836126a4565b9550610d3b565b5f610d068460400151856060015161265790919063ffffffff16565b9050610d128188611ed1565b9150610d2b8460600151836126d490919063ffffffff16565b9250610d3787836126a4565b9650505b610d458c82612704565b9b50610d518d83612704565b9c50610d5e818385612734565b7f194f1feb3b4d7076a2c272e774e792e0c48bb8c7aa1a9a3671c1cd6da9e6b4c1338c8484604051610d939493929190615540565b60405180910390a15050845160010180865260200285018190525b505b50600101610a3a565b505f9050610dcd60808a0160608b01615418565b610dd75786610dd9565b875b9050610de6818a356128fc565b15610e0e5760405163573b6f4160e01b81528935600482015260248101829052604401610318565b50610e1a338389611f64565b505f9050610e2b60a08a018a61562a565b90501115610e99573363691f9ed783858a8a610e4a60a08f018f61562a565b6040518763ffffffff1660e01b8152600401610e6b9695949392919061522e565b5f604051808303815f87803b158015610e82575f80fd5b505af1158015610e94573d5f803e3d5ffd5b505050505b610ea4338488611aed565b50505f5b8151811015610edb57610ed3828281518110610ec657610ec66152f6565b6020026020010151612936565b600101610ea8565b505050505050610ef760015f80516020615c0483398151915255565b915091565b5f610f05611865565b610f12602085018561533c565b90505f03610f3357604051636c44ef8f60e01b815260040160405180910390fd5b610f40604085018561533c565b90505f03610f615760405163540e5f0b60e01b815260040160405180910390fd5b6040805160a081019091523381525f9060208101610f7f878061566d565b610f8890615681565b8152602001868060200190610f9d919061533c565b808060200260200160405190810160405280939291908181526020015f905b82821015610fe857610fd96040830286013681900381019061568c565b81526020019060010190610fbc565b5050509183525050602001611000604088018861533c565b808060200260200160405190810160405280939291908181526020015f905b8282101561104b5761103c6040830286013681900381019061568c565b8152602001906001019061101f565b50505050508152602001866060013581525090505f61106982611880565b5f818152602081905260409020549091501580156111ab575f828152602081905260409081902060019055835190517f87491344dfbcf91f6cbbc610cbbeedc85313d37a02df0c93527f7ea5f8db717f916110c791859087906156a6565b60405180910390a15f6110dd60a089018961562a565b905011156111795761112e6110f560a089018961562a565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250612b7992505050565b82517fd46c2c56b35c8210e9e712ec3f02242d5fc90187c0ac8ed80cc33626846ec369908361116060a08b018b61562a565b60405161117094939291906156cd565b60405180910390a15b6040805160028152602081018490523381830152606081019091526111ab906111a1906103bf565b6103e1878961516e565b925050506103fd60015f80516020615c0483398151915255565b5f8080806111df6111d68680615328565b61032e90614f5d565b5f8181526020819052604090205490915060011461120657505f925082915081905061127f565b61122b6112138680615328565b61121c90614f5d565b86602001358760400135612027565b5f6112686112398780615328565b61124290614f5d565b602088013560408901353361125a60608c018c6152b0565b611263916156ff565b612099565b905060018160400151826060015194509450945050505b9193909250565b604080515f8152602081019091526060908267ffffffffffffffff8111156112b0576112b0614a5b565b6040519080825280602002602001820160405280156112e357816020015b60608152602001906001900390816112ce5790505b5091505f5b838110156113645761133f30868684818110611306576113066152f6565b9050602002810190611318919061562a565b8560405160200161132b9392919061570b565b604051602081830303815290604052612ba4565b838281518110611351576113516152f6565b60209081029190910101526001016112e8565b505092915050565b611374611865565b604080515f808252602082019092526113ac916113a1565b606081526020019060019003908161138c5790505b506103e1838561516e565b6113c260015f80516020615c0483398151915255565b5050565b6113ce611865565b835185516001600160a01b039182169116036113fd57604051630a98f1f360e21b815260040160405180910390fd5b8360400151836040013581518110611417576114176152f6565b60200260200101515f01516001600160a01b03168560600151846020013581518110611445576114456152f6565b60200260200101515f01516001600160a01b03161415806114be5750604085015180518435908110611479576114796152f6565b60200260200101515f01516001600160a01b031684606001518460600135815181106114a7576114a76152f6565b60200260200101515f01516001600160a01b031614155b156114dc5760405163936bb5ad60e01b815260040160405180910390fd5b84606001518360200135815181106114f6576114f66152f6565b60200260200101515f01516001600160a01b03168560400151845f013581518110611523576115236152f6565b60200260200101515f01516001600160a01b03160361155557604051631cd2f1c760e21b815260040160405180910390fd5b5f805f61156188611880565b81526020019081526020015f2054036115d1577fb70c12fa453793fa6818ec07c91e74363a47aa6a6829dcd9533937fdf30314f333865f01516115a388611880565b604080516001600160a01b0394851681529390921660208401529082015260600160405180910390a161184f565b5f805f6115dd87611880565b81526020019081526020015f20540361161f577fb70c12fa453793fa6818ec07c91e74363a47aa6a6829dcd9533937fdf30314f333855f01516115a387611880565b7f6fa7f4c28634b0a9d6831401c45ae468195fb63aed07308935c35374ff5d9e3933868686604051611654949392919061572e565b60405180910390a15f61167486855f01358660200135885f015186612099565b90505f61168f86866040013587606001358a5f015188612099565b90505f61169c8383612c44565b90506116b08160400151825f015185612734565b6116c38160600151826020015184612734565b606081015181515f916116d691906126a4565b90505f6116f4836040015184602001516126a490919063ffffffff16565b9050611700825f6128fc565b806117105750611710815f6128fc565b1561172e57604051630d86822160e01b815260040160405180910390fd5b611762338b606001518a602001358151811061174c5761174c6152f6565b60200260200101515f01518a6080013585611bc7565b5050611798338a606001518a6060013581518110611782576117826152f6565b60200260200101515f01518a60a0013584611bc7565b5050604080513381528451602080830191909152850151818301529084015160608083019190915284015160808201527fd9fa84dd790c969daa5c33d8050dc06b4a9b59d5b42e2be5f5e8ae20447f618d925060a001905060405180910390a161180183612936565b61180a82612936565b80516001600160e01b031615801561182d575060208101516001600160e01b0316155b1561184b576040516321badf1f60e01b815260040160405180910390fd5b5050505b61054360015f80516020615c0483398151915255565b61186d612c92565b60025f80516020615c0483398151915255565b5f8160405160200161189291906157aa565b604051602081830303815290604052805190602001209050919050565b335f8181523060209081526040808320815160a0810183528083018581526060808301879052608083018190529082528185015282518581529384018581528484019093529093909291905b8651811015611a7357868181518110611916576119166152f6565b602002602001015193505f845f015160400151511115611a6b575f845f01515f01516001600160a01b031663d04dfe236040518060e00160405280885f0151602001516001600160a01b03168152602001898152602001885f01516040015181526020015f815260200161198e8d8a60200151612cc3565b8152602001878152602001868152506040518263ffffffff1660e01b81526004016119b99190615814565b5f60405180830381865afa1580156119d3573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526119fa919081019061590c565b9150505f81511115611a695784516020015160405163012c676d60e21b81526001600160a01b03909116906304b19db490611a3b908a9085906004016159c2565b5f604051808303815f87803b158015611a52575f80fd5b505af1158015611a64573d5f803e3d5ffd5b505050505b505b6001016118fb565b5050505050505050565b80611aae576040516305dbdfd960e41b81526001600160a01b03808516600483015283166024820152604401610318565b505050565b5f6001600160e01b03838116601b90810b9160e086811d9291861690910b9085901d611ae184848484612fa5565b12979650505050505050565b5f805f80611afa86613079565b90925090506001826003811115611b1357611b136159da565b14158015611b3257505f826003811115611b2f57611b2f6159da565b14155b15611b5457858260405163ee07877f60e01b81526004016103189291906159ee565b611b5e855f6128fc565b15611b7c57604051632eaefac360e21b815260040160405180910390fd5b5f80611b888784613106565b9150915080611b9d57611b9a82615a27565b91505b8115611bb857611bb86001600160a01b0389168a3085611e95565b5093509150505b935093915050565b5f80611bd383826128fc565b15611bf45760405163793a8f5560e01b815260048101849052602401610318565b83611c1257611c04868685611f64565b505f9250829150611cae9050565b6001600160a01b038087165f908152600160209081526040808320938916835292815282822087835290529081205490611c4c8286612704565b9050611c58815f6128fc565b15611c795760405163c5e12af560e01b815260048101829052602401610318565b6001600160a01b038089165f908152600160209081526040808320938b16835292815282822089835290522081905590925090505b94509492505050565b5f8115611cf157506001600160a01b038084165f9081526001602090815260408083209386168352928152828220848352905220546103fd565b5f80611cfc85613133565b90925090506001826003811115611d1557611d156159da565b14158015611d3457505f826003811115611d3157611d316159da565b14155b15611d5657848260405163ee07877f60e01b81526004016103189291906159ee565b6040516370a0823160e01b81526001600160a01b0387811660048301525f91611dca918816906370a0823190602401602060405180830381865afa158015611da0573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611dc49190615272565b83613192565b604051636eb1769f60e11b81526001600160a01b0389811660048301523060248301529192505f91611e48919089169063dd62ed3e90604401602060405180830381865afa158015611e1e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e429190615272565b846131b6565b509050611e558282611ed1565b9450505050506103fd565b611e6d83838360016131f6565b611aae57604051635274afe760e01b81526001600160a01b0384166004820152602401610318565b611ea3848484846001613258565b611ecb57604051635274afe760e01b81526001600160a01b0385166004820152602401610318565b50505050565b5f611edc83836128fc565b611ee657816103fd565b5090919050565b5f80611ef983826128fc565b15611f1a5760405163793a8f5560e01b815260048101849052602401610318565b83611f2a57611c04868685611aed565b6001600160a01b038087165f908152600160209081526040808320938916835292815282822087835290529081205490611c4c82866126a4565b5f805f80611f7186613079565b90925090506001826003811115611f8a57611f8a6159da565b14158015611fa957505f826003811115611fa657611fa66159da565b14155b15611fcb57858260405163ee07877f60e01b81526004016103189291906159ee565b611fd5855f6128fc565b15611ff357604051632d1671a360e11b815260040160405180910390fd5b5f611ffe8683613106565b509050801561201b5761201b6001600160a01b0388168983611e60565b97909650945050505050565b8260600151818151811061203d5761203d6152f6565b60200260200101515f01516001600160a01b031683604001518381518110612067576120676152f6565b60200260200101515f01516001600160a01b031603611aae57604051631cd2f1c760e21b815260040160405180910390fd5b6120a16145f6565b5f6120ab87611880565b60408051600480825260a082019092529192506060915f91816020015b60608152602001906001900390816120c85790505089516040805160038152602081018790526001600160a01b03928316818301529189166060830152608082019052909150816001800381518110612123576121236152f6565b60200260200101819052505f806121598b604001518b81518110612149576121496152f6565b60200260200101515f0151613133565b90925090506001826003811115612172576121726159da565b1415801561219157505f82600381111561218e5761218e6159da565b14155b156121d3578a604001518a815181106121ac576121ac6152f6565b60200260200101515f01518260405163ee07877f60e01b81526004016103189291906159ee565b5f6122238c5f01518d604001518d815181106121f1576121f16152f6565b60200260200101515f01518e604001518e81518110612212576122126152f6565b602002602001015160200151611cb7565b90506122b28c604001518c8151811061223e5761223e6152f6565b60200260200101515f01516001600160a01b03165f1b8360ff165f1b8e604001518e81518110612270576122706152f6565b602002602001015160200151845f801b60408051600581526020810196909652858101949094526060850192909252608084015260a083015260c08201905290565b846001600303815181106122c8576122c86152f6565b60200260200101819052505050505f806122f18b606001518a81518110612149576121496152f6565b9092509050600182600381111561230a5761230a6159da565b1415801561232957505f826003811115612326576123266159da565b14155b15612344578a6060015189815181106121ac576121ac6152f6565b5f6123838c5f01518d606001518c81518110612362576123626152f6565b60200260200101515f01518e606001518d81518110612212576122126152f6565b90506123d08c606001518b8151811061239e5761239e6152f6565b60200260200101515f01516001600160a01b03165f1b8360ff165f1b8e606001518d81518110612270576122706152f6565b846001600403815181106123e6576123e66152f6565b60200260200101819052505050506123fe8186612cc3565b9150505f885f01516001600160a01b031690505f808a602001515f01516001600160a01b031663d04dfe236040518060e001604052808e60200151602001516001600160a01b0316815260200161245e87305f9182526020526040902090565b81526020018e602001516040015181526020015f81526020018781526020015f67ffffffffffffffff81111561249657612496614a5b565b6040519080825280602002602001820160405280156124bf578160200160208202803683370190505b5081526020015f6040519080825280602002602001820160405280156124ef578160200160208202803683370190505b508152506040518263ffffffff1660e01b815260040161250f9190615814565b5f60405180830381865afa158015612529573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052612550919081019061590c565b9150915060028251101561257c578151604051630fbb8e5560e21b815260040161031891815260200190565b6020820151604083015160608d015180515f91908d9081106125a0576125a06152f6565b602002602001015190505f6125c08f5f0151835f01518460200151611cb7565b90506125cc8382611ed1565b6040805160028152602081018390528082018790526060810190915290935091506125f49050565b86600281518110612607576126076152f6565b60200260200101819052506040518060e001604052808e81526020018c81526020018281526020018381526020018781526020018681526020018481525097505050505050505095945050505050565b5f6001600160e01b03838116601b90810b9160e086811d9291861690910b9085901d8480612687868686866132c5565b915091505f61269683836133e4565b9a9950505050505050505050565b5f6001600160e01b03838116601b90810b9160e086811d9291861690910b9085901d848061268786868686613431565b5f6001600160e01b03838116601b90810b9160e086811d9291861690910b9085901d84806126878686868661345b565b5f6001600160e01b03838116601b90810b9160e086811d9291861690910b9085901d848061268786868686613998565b82816080015160038151811061274c5761274c6152f6565b6020026020010151600481518110612766576127666152f6565b60200260200101818152505081816080015160048151811061278a5761278a6152f6565b60200260200101516004815181106127a4576127a46152f6565b602002602001018181525050612833815f01515f015182608001516003815181106127d1576127d16152f6565b60200260200101515f815181106127ea576127ea6152f6565b60200260200101515f1c836080015160038151811061280b5761280b6152f6565b6020026020010151600281518110612825576128256152f6565b602002602001015186611bc7565b50506128b8815f01515f01518260800151600481518110612856576128566152f6565b60200260200101515f8151811061286f5761286f6152f6565b60200260200101515f1c8360800151600481518110612890576128906152f6565b60200260200101516002815181106128aa576128aa6152f6565b602002602001015185611eed565b50507f4cb6e22a3e7e651d7cf0376cff48f20f5007a54147777865be7f5f6c38c50f4a3382608001516040516128ef929190615a3f565b60405180910390a1505050565b5f6001600160e01b03838116601b90810b9160e086811d9291861690910b9085901d61292a84848484612fa5565b13979650505050505050565b60c081015151156129b0578051602090810151015160a082015160c083015160405163012c676d60e21b81526001600160a01b03909316926304b19db4926129829290916004016159c2565b5f604051808303815f87803b158015612999575f80fd5b505af11580156129ab573d5f803e3d5ffd5b505050505b5f815f0151602001515f01516001600160a01b031663d04dfe236040518060e00160405280855f015160200151602001516001600160a01b03168152602001612a068660a00151305f9182526020526040902090565b8152602001855f01516020015160400151815260200160018152602001856080015181526020015f67ffffffffffffffff811115612a4657612a46614a5b565b604051908082528060200260200182016040528015612a6f578160200160208202803683370190505b5081526020015f604051908082528060200260200182016040528015612a9f578160200160208202803683370190505b508152506040518263ffffffff1660e01b8152600401612abf9190615814565b5f60405180830381865afa158015612ad9573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052612b00919081019061590c565b9150505f815111156113c2578151602090810151015160a083015160405163012c676d60e21b81526001600160a01b03909216916304b19db491612b489185906004016159c2565b5f604051808303815f87803b158015612b5f575f80fd5b505af1158015612b71573d5f803e3d5ffd5b505050505050565b612b8281613a96565b612ba15780604051630c89984b60e31b81526004016103189190615a60565b50565b60605f612bb18484613ac4565b9050808015612bd257505f3d1180612bd257505f846001600160a01b03163b115b15612be757612bdf613ad7565b9150506102b6565b8015612c1157604051639996b31560e01b81526001600160a01b0385166004820152602401610318565b3d15612c2457612c1f613af0565b612c3d565b60405163d6bda27560e01b815260040160405180910390fd5b5092915050565b604080516080810182525f808252602082018190529181018290526060810191909152612c718383613afb565b82526040820152612c828284613afb565b6020830152606082015292915050565b5f80516020615c0483398151915254600203612cc157604051633ee5aeb560e01b815260040160405180910390fd5b565b60605f825167ffffffffffffffff811115612ce057612ce0614a5b565b604051908082528060200260200182016040528015612d09578160200160208202803683370190505b5090505f80845111612d1b575f612d21565b83516001015b85516001010190505f8167ffffffffffffffff811115612d4357612d43614a5b565b604051908082528060200260200182016040528015612d7657816020015b6060815260200190600190039081612d615790505b5090505f612d9a604080516002815233602082015230818301526060810190915290565b828281518110612dac57612dac6152f6565b60200260200101819052505f5b8751811015612e09578180600101925050878181518110612ddc57612ddc6152f6565b6020026020010151838381518110612df657612df66152f6565b6020908102919091010152600101612db9565b50855115612f9b57808060010191505083828281518110612e2c57612e2c6152f6565b60200260200101819052505f5b8651811015612f9957612ee8878281518110612e5757612e576152f6565b60200260200101515f0151612ec5612e938a8581518110612e7a57612e7a6152f6565b6020026020010151602001518051602090810291012090565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000005f908152601c91909152603c902090565b898481518110612ed757612ed76152f6565b602002602001015160400151613b64565b612f0857604051630a57f30960e31b815260048101829052602401610318565b868181518110612f1a57612f1a6152f6565b60200260200101515f01516001600160a01b03165f1b858281518110612f4257612f426152f6565b6020026020010181815250508180600101925050868181518110612f6857612f686152f6565b602002602001015160200151838381518110612f8657612f866152f6565b6020908102919091010152600101612e39565b505b5095945050505050565b5f8085158415178187128286121817858414178015612fca5786859250925050611cae565b505f85841315612fde575092949193919260015b8386035f8112604c8213178015613011578215613003575f8994509450505050611cae565b885f94509450505050611cae565b600a82900a8981028a82828161302957613029615a72565b0514613055578415613045575f8b965096505050505050611cae565b8a5f965096505050505050611cae565b841561306a578896509450611cae9350505050565b9550879450611cae9350505050565b5f80613083613bd4565b60405163b7bad1b160e01b81526001600160a01b038416600482015273200e12d10bb0c5e4a17e7018f0f1161919bb93899063b7bad1b19060240160408051808303815f875af11580156130d9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130fd9190615a86565b91509150915091565b5f806001600160e01b038416601b0b60e085901d613125828287613c5f565b9350935050505b9250929050565b5f8061313d613bd4565b604051630782d7e160e01b81526001600160a01b038416600482015273200e12d10bb0c5e4a17e7018f0f1161919bb938990630782d7e1906024016040805180830381865afa1580156130d9573d5f803e3d5ffd5b5f805f61319f8585613dc5565b915091506131ad8282613e0e565b95945050505050565b5f805f805f6131c58787613e47565b9250925092505f806131d78585613e8a565b91509150818380156131e65750815b9650965050505050509250929050565b60405163a9059cbb60e01b5f8181526001600160a01b038616600452602485905291602083604481808b5af1925060015f5114831661324c578383151615613240573d5f823e3d81fd5b5f873b113d1516831692505b60405250949350505050565b6040516323b872dd60e01b5f8181526001600160a01b038781166004528616602452604485905291602083606481808c5af1925060015f511483166132b45783831516156132a8573d5f823e3d81fd5b5f883b113d1516831692505b604052505f60605295945050505050565b5f80851584151780156132dd575f92505f91506133da565b6132e78487615ac6565b91505f6132f388613f62565b90505f6132ff87613f62565b90505f61330c8383613f90565b5090505f6f0785ee10d5da46d900f436a000000000821115613341576f0785ee10d5da46d900f436a000000000820491506025015b670de0b6b3a764000082111561336257670de0b6b3a7640000820491506012015b633b9aca0082111561337b57633b9aca00820491506009015b61271082111561339057612710820491506004015b81156133a457600a82049150600101613390565b6133ae8187615ac6565b95506133d08b8a6133ca87876133c587600a615bc5565b613fac565b89614078565b9097509550505050505b5094509492505050565b5f805f6133f18585613e8a565b9150915080158015613401575081155b1561342957604051638eba4d0760e01b81526004810186905260248101859052604401610318565b509392505050565b5f8061343d8484614118565b909450925061344e86868686613998565b9150915094509492505050565b5f80835f0361348757604051637a97930f60e01b81526004810187905260248101869052604401610318565b855f0361349857505f905080611cae565b5f805f806134a68a8a61416d565b919b50995091506134b7888861416d565b919950975090505f6134c88b613f62565b90505f6134d48a613f62565b90507f161bcca7119915b50764b4abe86529797775a5f1719510000000000000000000604c8183101561389957841561352b57507546bf5bb0385045767e0f0ef2e7aa1e517e454637d1dd604b1b9050604b613871565b6f4b3b4ca85a86c47a098a22400000000083101561365757678ac7230489e800008310156135bb576402540be40083101561358957620186a08310156135795750620186a090506005613832565b506402540be4009050600a613832565b655af3107a40008310156135a85750655af3107a40009050600e613832565b50678ac7230489e8000090506013613832565b6b204fce5e3e2502611000000083101561360d5769152d02c7e14af68000008310156135f6575069152d02c7e14af680000090506017613832565b506b204fce5e3e250261100000009050601c613832565b6d314dc6448d9338c15b0a0000000083101561363c57506d314dc6448d9338c15b0a0000000090506021613832565b506f4b3b4ca85a86c47a098a22400000000090506026613832565b780197d4df19d605767337e9f14d3eec8920e40000000000000083101561374f5773af298d050e4395d69670b12b7f410000000000008310156136ea577172cb5bd86321e38cb6ce6682e800000000008310156136cb57507172cb5bd86321e38cb6ce6682e800000000009050602b613832565b5073af298d050e4395d69670b12b7f4100000000000090506030613832565b76010b46c6cdd6e3e0828f4db456ff0c8ea000000000000083101561372b575076010b46c6cdd6e3e0828f4db456ff0c8ea000000000000090506035613832565b50780197d4df19d605767337e9f14d3eec8920e4000000000000009050603a613832565b7c03b58e88c75313ec9d329eaaa18fb92f75215b171000000000000000008310156137e5577a026e4d30eccc3215dd8f3157d27e23acbdcfe680000000000000008310156137bd57507a026e4d30eccc3215dd8f3157d27e23acbdcfe680000000000000009050603f613832565b507c03b58e88c75313ec9d329eaaa18fb92f75215b1710000000000000000090506044613832565b7e05a8e89d75252446eb5d5d5b1cc5edf20a1a059e10ca00000000000000000083101561383257507e05a8e89d75252446eb5d5d5b1cc5edf20a1a059e10ca000000000000000000905060495b81831161384757600a820491505f1901613832565b815f03613871576040516305e51ecb60e01b8152600481018d9052602481018c9052604401610318565b85613899576040516305e51ecb60e01b8152600481018f9052602481018e9052604401610318565b80600160ff1b018d126138b057808d039c506138ee565b600160ff1b9c90038c015f8113156138ee57806001600160ff1b03038b136138db57998a01996138ee565b5f80995099505050505050505050611cae565b5f808e1280156138fd57505f8c135b1561391e57600160ff1b8e01808d13613916575f61391a565b808d035b9150505b8b818f0103975061393b8f8e613935888789613fac565b8b614078565b90995097505f81131561398557604c811315613965575f809a509a50505050505050505050611cae565b80600a0a898161397757613977615a72565b059850885f03613985575f97505b50969850949650611cae95505050505050565b5f80851584151780156139c457865f036139b85784849250925050611cae565b86869250925050611cae565b6139ce87876143c7565b90975095506139dd85856143c7565b9095509350858413156139f1579395929492935b838603604c811115613a0a578787935093505050611cae565b80600a0a8681613a1c57613a1c615a72565b0595505086850180881860ff90811c151589881890911c15168015613a8557876001600160ff1b0303613a6c5760405163d556b11160e01b8152600481018a905260248101899052604401610318565b600a968790059690980586019760019790970196613a89565b8198505b5096979596505050505050565b5f600882511015613aa857505f919050565b506008015167ffffffffffffffff1667ff0a89c674ee78741490565b5f805f835160208501865af49392505050565b6040513d81523d5f602083013e3d602001810160405290565b6040513d5f823e3d81fd5b5f80613b188460600151856040015161265790919063ffffffff16565b915083604001519050613b38836040015183611ab390919063ffffffff16565b1561312c5782604001519150613b5b8460600151836126d490919063ffffffff16565b90509250929050565b5f836001600160a01b03163b5f03613bc2575f80613b828585614404565b5090925090505f816003811115613b9b57613b9b6159da565b148015613bb95750856001600160a01b0316826001600160a01b0316145b925050506103fd565b613bcd84848461444a565b90506103fd565b73200e12d10bb0c5e4a17e7018f0f1161919bb93893b1580613c2b575073200e12d10bb0c5e4a17e7018f0f1161919bb93893f7f1de7d717526cba131d684e312dedbf0852adef9cced9e36798ae4937f7145d4114155b15612cc1576040516373e6d7b360e01b815273200e12d10bb0c5e4a17e7018f0f1161919bb93896004820152602401610318565b5f805f851215613c8c57604051634a7d166b60e01b81526004810186905260248101859052604401610318565b845f03613c9e57505f90506001611bbf565b8460ff8416850185811215613cd05760405163d556b11160e01b81526004810188905260248101879052604401610318565b5f805f831215613d1c57604c19831215613cf3575f809550955050505050611bbf565b825f03600a0a9150818481613d0a57613d0a615a72565b0495505084029091149150611bbf9050565b5f831315613db557604d831315613d595760405163c849483b60e01b8152600481018a90526024810189905260ff88166044820152606401610318565b82600a0a9150815f1981613d6f57613d6f615a72565b04841115613da35760405163c849483b60e01b8152600481018a90526024810189905260ff88166044820152606401610318565b5091909102925060019150611bbf9050565b8360019550955050505050611bbf565b5f805f805f613dd48787613e47565b92509250925080613e0257604051636238bcb360e11b81526004810184905260248101839052604401610318565b50909590945092505050565b5f805f613e1b8585613e8a565b9150915080613429576040516322c9f7bb60e01b81526004810186905260248101859052604401610318565b5f808060ff841681036001600160ff1b03861115613e7957600a860460018201600a88065f1493509350935050613e83565b8593509150600190505b9250925092565b5f601b83900b8314838382613eee577d90e40fbeea1d3a4abc8955e946fe31cdcf66f634e1000000000000000000860515613ece57620186a0860595506005850194505b8586601b0b14613ee957600a86059550846001019450613ece565b613f04565b855f03613f0457505f92506001915061312c9050565b848560030b14613f47575f851215613f2457505f925082915061312c9050565b60405163d556b11160e01b81526004810183905260248101829052604401610318565b50506001600160e01b03841660e084901b1791509250929050565b5f80821215613f8757600160ff1b8203613f815750600160ff1b919050565b505f0390565b5090565b919050565b5f805f1983850993909202808410938190039390930393915050565b5f805f613fb98686613f90565b91509150815f03613fdd57838181613fd357613fd3615a72565b04925050506103fd565b83821061400e5760405163362ced0960e11b8152600481018790526024810186905260448101859052606401610318565b5f84868809600186198101871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103025f82900382900490920185841190960395909502919093039390930492909217029150509392505050565b5f805f85871812156140f4576001600160ff1b038411156140e1576140a56001600160ff1b03600161529d565b84036140b95750600160ff1b905081611cae565b6140c4600a85615bd0565b6140cd90615bef565b6140d8846001615ac6565b91509150611cae565b6140ea84615bef565b8391509150611cae565b6001600160ff1b0384111561410e576140cd600a85615bd0565b5082905081611cae565b5f80600160ff1b8403614163576001600160ff1b0383036141565760405163d556b11160e01b81526004810185905260248101849052604401610318565b600a840593508260010192505b50505f9190910391565b5f805f845f0361418557505f91508190506001613e83565b7546bf5bb0385045767e0f0ef2e7aa1e517e454637d1dd604b1b85055f03614372576f4b3b4ca85a86c47a098a22400000000085051580156141e757507f80000000000000000000000000000000000000000000000000000000000000268412155b15614208576f4b3b4ca85a86c47a098a224000000000850294506026840393505b7728c87cb5c89a2571ebfdcb54864ada834a00000000000000850515801561425057507f80000000000000000000000000000000000000000000000000000000000000138412155b1561426957678ac7230489e80000850294506013840393505b7b097edd871cfda3a5697758bf0e3cbb5ac5741c64000000000000000085051580156142b557507f800000000000000000000000000000000000000000000000000000000000000a8412155b156142cb576402540be40085029450600a840393505b7e3899162693736ac531a5a58f1fbb4b746504382ca7e4000000000000000000850515801561431a57507f80000000000000000000000000000000000000000000000000000000000000028412155b15614330576064850294506002840393506142cb565b7546bf5bb0385045767e0f0ef2e7aa1e517e454637d1dd604b1b850515801561436057506001600160ff1b018412155b1561437257600a850294506001840393505b600a8086029081058614801561438f57506001600160ff1b018512155b1561439e578095506001850394505b50939492935050507546bf5bb0385045767e0f0ef2e7aa1e517e454637d1dd604b1b8305151590565b5f805f805f6143d6878761416d565b92509250925080613e02576040516305e51ecb60e01b81526004810188905260248101879052604401610318565b5f805f835160410361443b576020840151604085015160608601515f1a61442d8882858561449b565b955095509550505050613e83565b505081515f9150600290613e83565b805160408051630b135d3f60e11b8082526004820186905260248201929092525f92906020820185604483015e60205f60648401838a5afa9050825f5114601f3d1116811693505050509392505050565b5f80807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08411156144d457505f91506003905082614559565b604080515f808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015614525573d5f803e3d5ffd5b5050604051601f1901519150506001600160a01b03811661455057505f925060019150829050614559565b92505f91508190505b9450945094915050565b604051806080016040528061457661458f565b81526020015f81526020015f8152602001606081525090565b6040518060a001604052805f6001600160a01b031681526020016145dd60405180606001604052805f6001600160a01b031681526020015f6001600160a01b03168152602001606081525090565b8152606060208201819052604082018190525f91015290565b6040518060e0016040528061460961458f565b81526020015f81526020015f80191681526020015f8019168152602001606081526020015f8152602001606081525090565b5f6020828403121561464b575f80fd5b81356001600160e01b0319811681146103fd575f80fd5b5f8083601f840112614672575f80fd5b50813567ffffffffffffffff811115614689575f80fd5b6020830191508360208260051b850101111561312c575f80fd5b5f805f604084860312156146b5575f80fd5b833567ffffffffffffffff808211156146cc575f80fd5b9085019060a082880312156146df575f80fd5b909350602085013590808211156146f4575f80fd5b5061470186828701614662565b9497909650939450505050565b5f6020828403121561471e575f80fd5b5035919050565b6001600160a01b0381168114612ba1575f80fd5b8035613f8b81614725565b5f805f805f60808688031215614758575f80fd5b853561476381614725565b94506020860135935060408601359250606086013567ffffffffffffffff81111561478c575f80fd5b61479888828901614662565b969995985093965092949392505050565b5f805f606084860312156147bb575f80fd5b83356147c681614725565b925060208401356147d681614725565b929592945050506040919091013590565b5f805f805f608086880312156147fb575f80fd5b853561480681614725565b9450602086013561481681614725565b935060408601359250606086013567ffffffffffffffff80821115614839575f80fd5b818801915088601f83011261484c575f80fd5b81358181111561485a575f80fd5b89602082850101111561486b575f80fd5b9699959850939650602001949392505050565b5f6020828403121561488e575f80fd5b81356103fd81614725565b5f60c082840312156148a9575f80fd5b50919050565b5f602082840312156148bf575f80fd5b813567ffffffffffffffff8111156148d5575f80fd5b61055684828501614899565b5f805f604084860312156148f3575f80fd5b833567ffffffffffffffff8082111561490a575f80fd5b61491687838801614899565b945060208601359150808211156146f4575f80fd5b5f6020828403121561493b575f80fd5b813567ffffffffffffffff811115614951575f80fd5b8201608081850312156103fd575f80fd5b5f8060208385031215614973575f80fd5b823567ffffffffffffffff811115614989575f80fd5b61499585828601614662565b90969095509350505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f60208083016020845280855180835260408601915060408160051b8701019250602087015f5b82811015614a2457603f19888603018452614a128583516149a1565b945092850192908501906001016149f6565b5092979650505050505050565b5f8060408385031215614a42575f80fd5b8235614a4d81614725565b946020939093013593505050565b634e487b7160e01b5f52604160045260245ffd5b6040516060810167ffffffffffffffff81118282101715614a9257614a92614a5b565b60405290565b6040805190810167ffffffffffffffff81118282101715614a9257614a92614a5b565b60405160a0810167ffffffffffffffff81118282101715614a9257614a92614a5b565b604051601f8201601f1916810167ffffffffffffffff81118282101715614b0757614b07614a5b565b604052919050565b5f82601f830112614b1e575f80fd5b813567ffffffffffffffff811115614b3857614b38614a5b565b614b4b601f8201601f1916602001614ade565b818152846020838601011115614b5f575f80fd5b816020850160208301375f918101602001919091529392505050565b5f60608284031215614b8b575f80fd5b614b93614a6f565b90508135614ba081614725565b81526020820135614bb081614725565b6020820152604082013567ffffffffffffffff811115614bce575f80fd5b614bda84828501614b0f565b60408301525092915050565b5f67ffffffffffffffff821115614bff57614bff614a5b565b5060051b60200190565b5f60408284031215614c19575f80fd5b614c21614a98565b90508135614c2e81614725565b808252506020820135602082015292915050565b5f82601f830112614c51575f80fd5b81356020614c66614c6183614be6565b614ade565b8083825260208201915060208460061b870101935086841115614c87575f80fd5b602086015b84811015614cac57614c9e8882614c09565b835291830191604001614c8c565b509695505050505050565b5f60a08284031215614cc7575f80fd5b614ccf614abb565b9050614cda82614739565b8152602082013567ffffffffffffffff80821115614cf6575f80fd5b614d0285838601614b7b565b60208401526040840135915080821115614d1a575f80fd5b614d2685838601614c42565b60408401526060840135915080821115614d3e575f80fd5b50614d4b84828501614c42565b6060830152506080820135608082015292915050565b5f614d6e614c6184614be6565b8381529050602080820190600585811b850187811115614d8c575f80fd5b855b81811015614e7957803567ffffffffffffffff80821115614dad575f80fd5b908801906060828c031215614dc0575f80fd5b614dc8614a6f565b8235614dd381614725565b81528287013582811115614de5575f80fd5b8301601f81018d13614df5575f80fd5b8035614e03614c6182614be6565b81815290881b8201890190898101908f831115614e1e575f80fd5b928a01925b82841015614e3c5783358252928a0192908a0190614e23565b848b01525060409150508381013583811115614e56575f80fd5b614e628e828701614b0f565b918301919091525087525050938301938301614d8e565b50505050509392505050565b5f82601f830112614e94575f80fd5b6103fd83833560208501614d61565b5f805f805f6101408688031215614eb8575f80fd5b853567ffffffffffffffff80821115614ecf575f80fd5b614edb89838a01614cb7565b96506020880135915080821115614ef0575f80fd5b614efc89838a01614cb7565b9550614f0b8960408a01614899565b9450610100880135915080821115614f21575f80fd5b614f2d89838a01614e85565b9350610120880135915080821115614f43575f80fd5b50614f5088828901614e85565b9150509295509295909350565b5f6102b63683614cb7565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b5f8135614f9c81614725565b6001600160a01b039081168452602083013590614fb882614725565b166020840152604082013536839003601e19018112614fd5575f80fd5b820160208101903567ffffffffffffffff811115614ff1575f80fd5b803603821315614fff575f80fd5b606060408601526131ad606086018284614f68565b5f808335601e19843603018112615029575f80fd5b830160208101925035905067ffffffffffffffff811115615048575f80fd5b8060061b360382131561312c575f80fd5b8183525f60208085019450825f5b8581101561509f57813561507a81614725565b6001600160a01b03168752818301358388015260409687019690910190600101615067565b509495945050505050565b5f6001600160a01b0380861683528460208401526060604084015283356150d081614725565b166060830152602083013536849003605e190181126150ed575f80fd5b60a060808401526151046101008401858301614f90565b90506151136040850185615014565b605f19808685030160a087015261512b848385615059565b935061513a6060880188615014565b93509150808685030160c087015250615154838383615059565b92505050608084013560e084015280915050949350505050565b5f61517b614c6184614be6565b80848252602080830192508560051b850136811115615198575f80fd5b855b8181101561522257803567ffffffffffffffff808211156151b9575f80fd5b8189019150604082360312156151cd575f80fd5b6151d5614a98565b8235828111156151e3575f80fd5b6151ef36828601614b7b565b8252508583013582811115615202575f80fd5b61520e36828601614e85565b82880152508752505093820193820161519a565b50919695505050505050565b5f6001600160a01b03808916835280881660208401525085604083015284606083015260a0608083015261526660a083018486614f68565b98975050505050505050565b5f60208284031215615282575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b808201808211156102b6576102b6615289565b5f808335601e198436030181126152c5575f80fd5b83018035915067ffffffffffffffff8211156152df575f80fd5b6020019150600581901b360382131561312c575f80fd5b634e487b7160e01b5f52603260045260245ffd5b5f8235607e1983360301811261531e575f80fd5b9190910192915050565b5f8235609e1983360301811261531e575f80fd5b5f808335601e19843603018112615351575f80fd5b83018035915067ffffffffffffffff82111561536b575f80fd5b6020019150600681901b360382131561312c575f80fd5b5f60808236031215615392575f80fd5b6040516080810167ffffffffffffffff82821081831117156153b6576153b6614a5b565b8160405284359150808211156153ca575f80fd5b6153d636838701614cb7565b8352602085013560208401526040850135604084015260608501359150808211156153ff575f80fd5b5061540c36828601614e85565b60608301525092915050565b5f60208284031215615428575f80fd5b813580151581146103fd575f80fd5b5f815180845260208085019450602084015f5b8381101561509f57815180516001600160a01b03168852830151838801526040909601959082019060010161544a565b5f6001600160a01b03808351168452602083015160a060208601528181511660a08601528160208201511660c08601526040810151915050606060e08501526154c76101008501826149a1565b9050604083015184820360408601526154e08282615437565b915050606083015184820360608601526154fa8282615437565b915050608083015160808501528091505092915050565b5f815180845260208085019450602084015f5b8381101561509f57815187529582019590820190600101615524565b5f6001600160a01b0380871683526020608081850152865160808086015261556c61010086018261547a565b90508188015160a086015260408089015160c08701526060808a0151607f198885030160e08901528381518086528686019150868160051b87010187840193505f5b8281101561560857601f1988830301845284518a815116835289810151878b8501526155dc88850182615511565b91890151848303858b01529190506155f481836149a1565b968b0196958b0195935050506001016155ae565b5080995050505050505050505083604083015282606083015295945050505050565b5f808335601e1984360301811261563f575f80fd5b83018035915067ffffffffffffffff821115615659575f80fd5b60200191503681900382131561312c575f80fd5b5f8235605e1983360301811261531e575f80fd5b5f6102b63683614b7b565b5f6040828403121561569c575f80fd5b6103fd8383614c09565b6001600160a01b0384168152826020820152606060408201525f6131ad606083018461547a565b6001600160a01b0385168152836020820152606060408201525f6156f5606083018486614f68565b9695505050505050565b5f6103fd368484614d61565b828482375f8382015f815283518060208601835e5f910190815295945050505050565b5f6101206001600160a01b03871683528060208401526157508184018761547a565b90508281036040840152615764818661547a565b9150508235606083015260208301356080830152604083013560a0830152606083013560c0830152608083013560e083015260a083013561010083015295945050505050565b602081525f6103fd602083018461547a565b5f8282518085526020808601955060208260051b840101602086015f5b8481101561580757601f198684030189526157f5838351615511565b988401989250908301906001016157d9565b5090979650505050505050565b602081526001600160a01b038251166020820152602082015160408201525f604083015160e0606084015261584d6101008401826149a1565b9050606084015160808401526080840151601f19808584030160a086015261587583836157bc565b925060a08601519150808584030160c08601526158928383615511565b925060c08601519150808584030160e0860152506131ad8282615511565b5f82601f8301126158bf575f80fd5b815160206158cf614c6183614be6565b8083825260208201915060208460051b8701019350868411156158f0575f80fd5b602086015b84811015614cac57805183529183019183016158f5565b5f806040838503121561591d575f80fd5b825167ffffffffffffffff80821115615934575f80fd5b818501915085601f830112615947575f80fd5b81516020615957614c6183614be6565b82815260059290921b84018101918181019089841115615975575f80fd5b948201945b838610156159935785518252948201949082019061597a565b918801519196509093505050808211156159ab575f80fd5b506159b8858286016158b0565b9150509250929050565b828152604060208201525f6105566040830184615511565b634e487b7160e01b5f52602160045260245ffd5b6001600160a01b03831681526040810160048310615a1a57634e487b7160e01b5f52602160045260245ffd5b8260208301529392505050565b5f60018201615a3857615a38615289565b5060010190565b6001600160a01b0383168152604060208201525f61055660408301846157bc565b602081525f6103fd60208301846149a1565b634e487b7160e01b5f52601260045260245ffd5b5f8060408385031215615a97575f80fd5b825160048110615aa5575f80fd5b602084015190925060ff81168114615abb575f80fd5b809150509250929050565b8082018281125f83128015821682158216171561136457611364615289565b600181815b80851115615b1f57815f1904821115615b0557615b05615289565b80851615615b1257918102915b93841c9390800290615aea565b509250929050565b5f82615b35575060016102b6565b81615b4157505f6102b6565b8160018114615b575760028114615b6157615b7d565b60019150506102b6565b60ff841115615b7257615b72615289565b50506001821b6102b6565b5060208310610133831016604e8410600b8410161715615ba0575081810a6102b6565b615baa8383615ae5565b805f1904821115615bbd57615bbd615289565b029392505050565b5f6103fd8383615b27565b5f82615bea57634e487b7160e01b5f52601260045260245ffd5b500490565b5f600160ff1b8201613f8157613f8161528956fe9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00", + "linkReferences": {} + } +} diff --git a/crates/test_fixtures/abis/RaindexV6SubParser.json b/crates/test_fixtures/abis/RaindexV6SubParser.json new file mode 100644 index 0000000000..d72c27e0a1 --- /dev/null +++ b/crates/test_fixtures/abis/RaindexV6SubParser.json @@ -0,0 +1,264 @@ +{ + "abi": [ + { + "type": "function", + "name": "buildLiteralParserFunctionPointers", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes", + "internalType": "bytes" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "buildOperandHandlerFunctionPointers", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes", + "internalType": "bytes" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "buildSubParserWordParsers", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes", + "internalType": "bytes" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "describedByMetaV1", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "subParseLiteral2", + "inputs": [ + { + "name": "data", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + }, + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "subParseWord2", + "inputs": [ + { + "name": "data", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + }, + { + "name": "", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "", + "type": "bytes32[]", + "internalType": "bytes32[]" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "supportsInterface", + "inputs": [ + { + "name": "interfaceId", + "type": "bytes4", + "internalType": "bytes4" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "error", + "name": "ContextGridOverflow", + "inputs": [ + { + "name": "column", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "row", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "ExpectedOperand", + "inputs": [] + }, + { + "type": "error", + "name": "ExponentOverflow", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "FixedDecimalOverflow", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + }, + { + "name": "decimals", + "type": "uint8", + "internalType": "uint8" + } + ] + }, + { + "type": "error", + "name": "LossyConversionFromFloat", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "NegativeFixedDecimalConversion", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "OperandOverflow", + "inputs": [] + }, + { + "type": "error", + "name": "SubParserIndexOutOfBounds", + "inputs": [ + { + "name": "index", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "length", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "UnexpectedOperand", + "inputs": [] + }, + { + "type": "error", + "name": "UnexpectedOperandValue", + "inputs": [] + }, + { + "type": "error", + "name": "WordSize", + "inputs": [ + { + "name": "word", + "type": "string", + "internalType": "string" + } + ] + } + ], + "bytecode": { + "object": "0x6080604052348015600e575f80fd5b506124d98061001c5f395ff3fe608060405234801561000f575f80fd5b506004361061007a575f3560e01c80636f5aa28d116100585780636f5aa28d146100dd578063c6c0cbb61461010b578063ccf4477514610135578063d6d8c9a814610148575f80fd5b806301ffc9a71461007e578063336284d4146100a6578063570c7a63146100bb575b5f80fd5b61009161008c3660046121c3565b610150565b60405190151581526020015b60405180910390f35b6100ae6101d7565b60405161009d919061221f565b6100ce6100c9366004612245565b610b58565b60405161009d939291906122ef565b6040517fdc6156fd1b9fda1ce642d416969c2f632029b10b9e3864fbde264f391c51bdee815260200161009d565b61011e610119366004612245565b610c9c565b60408051921515835260208301919091520161009d565b60408051602081019091525f81526100ae565b6100ae610cd4565b5f6001600160e01b031982166391ccb1d560e01b148061018057506001600160e01b03198216636f5aa28d60e01b145b8061019b57506001600160e01b03198216631a2c8edd60e01b145b806101b657506001600160e01b03198216630cd8a13560e21b145b806101d157506301ffc9a760e01b6001600160e01b03198316145b92915050565b60605f6101e66004600161234c565b6101f190600261234c565b6101fc90600161234c565b61020790600161234c565b6001600160401b0381111561021e5761021e612231565b60405190808252806020026020018201604052801561025157816020015b606081526020019060019003908161023c5790505b50604080516002808252606082019092529192505f9190816020015b6121b981526020019060019003908161026d5790505090506115f2815f8151811061029a5761029a61236b565b60200260200101906001600160401b031690816001600160401b03168152505061160f816001815181106102d0576102d061236b565b6001600160401b039290921660209283029190910190910152604080516003808252608082019092525f91816020015b6121b981526020019060019003908161030057905050905061161e815f8151811061032d5761032d61236b565b60200260200101906001600160401b031690816001600160401b03168152505061162d816001815181106103635761036361236b565b60200260200101906001600160401b031690816001600160401b03168152505061163c816002815181106103995761039961236b565b6001600160401b039290921660209283029190910190910152604080516002808252606082019092525f91816020015b6121b98152602001906001900390816103c957905050905061164c815f815181106103f6576103f661236b565b60200260200101906001600160401b031690816001600160401b03168152505061165b8160018151811061042c5761042c61236b565b6001600160401b03929092166020928302919091019091015260408051600580825260c082019092525f91816020015b6121b981526020019060019003908161045c57905050905061166b815f815181106104895761048961236b565b60200260200101906001600160401b031690816001600160401b03168152505061167a816001815181106104bf576104bf61236b565b60200260200101906001600160401b031690816001600160401b03168152505061168a816002815181106104f5576104f561236b565b60200260200101906001600160401b031690816001600160401b03168152505061169a8160038151811061052b5761052b61236b565b60200260200101906001600160401b031690816001600160401b0316815250506116a9816004815181106105615761056161236b565b6001600160401b03929092166020928302919091019091015260408051600580825260c082019092525f91816020015b6121b98152602001906001900390816105915790505090506116b9815f815181106105be576105be61236b565b60200260200101906001600160401b031690816001600160401b0316815250506116c8816001815181106105f4576105f461236b565b60200260200101906001600160401b031690816001600160401b0316815250506116d88160028151811061062a5761062a61236b565b60200260200101906001600160401b031690816001600160401b0316815250506116e8816003815181106106605761066061236b565b60200260200101906001600160401b031690816001600160401b0316815250506116f8816004815181106106965761069661236b565b6001600160401b0392909216602092830291909101909101526040805160018082528183019092525f91816020015b6121b98152602001906001900390816106c5579050509050611707815f815181106106f2576106f261236b565b6001600160401b0392909216602092830291909101909101526040805160018082528183019092525f91816020015b6121b9815260200190600190039081610721579050509050611716815f8151811061074e5761074e61236b565b60200260200101906001600160401b031690816001600160401b03168152505086885f815181106107815761078161236b565b602002602001018190525085886001815181106107a0576107a061236b565b602002602001018190525084886002815181106107bf576107bf61236b565b602002602001018190525083886003815181106107de576107de61236b565b602002602001018190525082886004815181106107fd576107fd61236b565b6020026020010181905250818860058151811061081c5761081c61236b565b6020026020010181905250808860068151811061083b5761083b61236b565b602090810291909101015260408051600580825260c082019092525f91816020015b6121b981526020019060019003908161085d5790505090506115f2815f8151811061088a5761088a61236b565b60200260200101906001600160401b031690816001600160401b03168152505061161e816001815181106108c0576108c061236b565b60200260200101906001600160401b031690816001600160401b03168152505061162d816002815181106108f6576108f661236b565b60200260200101906001600160401b031690816001600160401b03168152505061163c8160038151811061092c5761092c61236b565b60200260200101906001600160401b031690816001600160401b03168152505061174b816004815181106109625761096261236b565b6001600160401b039092166020928302919091019091015280896109886006600161234c565b815181106109985761099861236b565b602090810291909101015260408051600680825260e082019092525f91816020015b6121b98152602001906001900390816109ba5790505090506115f2815f815181106109e7576109e761236b565b60200260200101906001600160401b031690816001600160401b03168152505061161e81600181518110610a1d57610a1d61236b565b60200260200101906001600160401b031690816001600160401b03168152505061162d81600281518110610a5357610a5361236b565b60200260200101906001600160401b031690816001600160401b03168152505061163c81600381518110610a8957610a8961236b565b60200260200101906001600160401b031690816001600160401b03168152505061174b81600481518110610abf57610abf61236b565b60200260200101906001600160401b031690816001600160401b03168152505061175b81600581518110610af557610af561236b565b6001600160401b0390921660209283029190910190910152808a610b1b6006600261234c565b81518110610b2b57610b2b61236b565b602090810291909101015289610b48610b438261176b565b6117cd565b9b50505050505050505050505090565b5f6060805f805f610b7887610b6b61185c565b610b7361187c565b61189c565b9250925092505f610b8e82610220015160200190565b90505f8261022001515182610ba3919061234c565b90505f610bc183836f07fffffe0000000003ff20000000000061198d565b80925081945050505f80610bda86610240015184611a29565b915091508115610c6f575f610bef8783611b00565b90506121b95f610bfd611b2f565b90505f60028251610c0e9190612393565b9050808510610c3f576040516303bdd1b160e51b815260048101869052602481018290526044015b60405180910390fd5b6001850160020282015161ffff169250610c588c8c8686565b9e509e509e50505050505050505050505050610c95565b5050604080515f80825281830190925260208101828152919a5090985096505050505050505b9193909250565b5f805f805f610cc4866002810151815160228084019461ffff93909316840101920160200190565b505f988998509650505050505050565b60605f610ce36004600161234c565b610cee90600261234c565b610cf990600161234c565b610d0490600161234c565b6001600160401b03811115610d1b57610d1b612231565b604051908082528060200260200182016040528015610d4e57816020015b6060815260200190600190039081610d395790505b50604080516002808252606082019092529192505f9190816020015b6121b9815260200190600190039081610d6a579050509050611b4f815f81518110610d9757610d9761236b565b60200260200101906001600160401b031690816001600160401b031681525050611b4f81600181518110610dcd57610dcd61236b565b6001600160401b039290921660209283029190910190910152604080516003808252608082019092525f91816020015b6121b9815260200190600190039081610dfd579050509050611b4f815f81518110610e2a57610e2a61236b565b60200260200101906001600160401b031690816001600160401b031681525050611b4f81600181518110610e6057610e6061236b565b60200260200101906001600160401b031690816001600160401b031681525050611b4f81600281518110610e9657610e9661236b565b6001600160401b039290921660209283029190910190910152604080516002808252606082019092525f91816020015b6121b9815260200190600190039081610ec6579050509050611b4f815f81518110610ef357610ef361236b565b60200260200101906001600160401b031690816001600160401b031681525050611b4f81600181518110610f2957610f2961236b565b6001600160401b03929092166020928302919091019091015260408051600580825260c082019092525f91816020015b6121b9815260200190600190039081610f59579050509050611b4f815f81518110610f8657610f8661236b565b60200260200101906001600160401b031690816001600160401b031681525050611b4f81600181518110610fbc57610fbc61236b565b60200260200101906001600160401b031690816001600160401b031681525050611b4f81600281518110610ff257610ff261236b565b60200260200101906001600160401b031690816001600160401b031681525050611b4f816003815181106110285761102861236b565b60200260200101906001600160401b031690816001600160401b031681525050611b4f8160048151811061105e5761105e61236b565b6001600160401b03929092166020928302919091019091015260408051600580825260c082019092525f91816020015b6121b981526020019060019003908161108e579050509050611b4f815f815181106110bb576110bb61236b565b60200260200101906001600160401b031690816001600160401b031681525050611b4f816001815181106110f1576110f161236b565b60200260200101906001600160401b031690816001600160401b031681525050611b4f816002815181106111275761112761236b565b60200260200101906001600160401b031690816001600160401b031681525050611b4f8160038151811061115d5761115d61236b565b60200260200101906001600160401b031690816001600160401b031681525050611b4f816004815181106111935761119361236b565b6001600160401b0392909216602092830291909101909101526040805160018082528183019092525f91816020015b6121b98152602001906001900390816111c2579050509050611b78815f815181106111ef576111ef61236b565b6001600160401b0392909216602092830291909101909101526040805160018082528183019092525f91816020015b6121b981526020019060019003908161121e579050509050611c14815f8151811061124b5761124b61236b565b60200260200101906001600160401b031690816001600160401b03168152505086885f8151811061127e5761127e61236b565b6020026020010181905250858860018151811061129d5761129d61236b565b602002602001018190525084886002815181106112bc576112bc61236b565b602002602001018190525083886003815181106112db576112db61236b565b602002602001018190525082886004815181106112fa576112fa61236b565b602002602001018190525081886005815181106113195761131961236b565b602002602001018190525080886006815181106113385761133861236b565b602090810291909101015260408051600580825260c082019092525f91816020015b6121b981526020019060019003908161135a579050509050611b4f815f815181106113875761138761236b565b60200260200101906001600160401b031690816001600160401b031681525050611b4f816001815181106113bd576113bd61236b565b60200260200101906001600160401b031690816001600160401b031681525050611b4f816002815181106113f3576113f361236b565b60200260200101906001600160401b031690816001600160401b031681525050611b4f816003815181106114295761142961236b565b60200260200101906001600160401b031690816001600160401b031681525050611b4f8160048151811061145f5761145f61236b565b6001600160401b039092166020928302919091019091015280896114856006600161234c565b815181106114955761149561236b565b602090810291909101015260408051600680825260e082019092525f91816020015b6121b98152602001906001900390816114b7579050509050611b4f815f815181106114e4576114e461236b565b60200260200101906001600160401b031690816001600160401b031681525050611b4f8160018151811061151a5761151a61236b565b60200260200101906001600160401b031690816001600160401b031681525050611b4f816002815181106115505761155061236b565b60200260200101906001600160401b031690816001600160401b031681525050611b4f816003815181106115865761158661236b565b60200260200101906001600160401b031690816001600160401b031681525050611b4f816004815181106115bc576115bc61236b565b60200260200101906001600160401b031690816001600160401b031681525050611b4f81600581518110610af557610af561236b565b5f6060806116005f80611ccc565b92509250925093509350939050565b5f6060806116005f6001611ccc565b5f60608061160060015f611ccc565b5f606080611600600180611ccc565b5f60608061160060016002611ccc565b5f60608061160060025f611ccc565b5f60608061160060026001611ccc565b5f60608061160060035f611ccc565b5f60608061160060036001611ccc565b5f60608061160060036002611ccc565b5f606080611600600380611ccc565b5f60608061160060036004611ccc565b5f60608061160060045f611ccc565b5f60608061160060046001611ccc565b5f60608061160060046002611ccc565b5f60608061160060046003611ccc565b5f606080611600600480611ccc565b5f606080611600600585611ccc565b5f60608060ff80851690600886901c1661173a61173483600661234c565b82611ccc565b945094509450505093509350939050565b5f60608061160060016003611ccc565b5f60608061160060016004611ccc565b60605f61177783611d4e565b9050606060405190506020820260200181016040528181526020840160208551028101602083015b818310156117c257602083515102806020855101835e602093909301920161179f565b509195945050505050565b60605f82516002026001600160401b038111156117ec576117ec612231565b6040519080825280601f01601f191660200182016040528015611816576020820181803683370190505b50905061ffff80196020850160208651028101600285015b818310156118505780518351861690851617815260209092019160020161182e565b50939695505050505050565b60606040518060c00160405280609a81526020016123c7609a9139905090565b60606040518060600160405280603c8152602001612461603c9139905090565b5f8061192b6040518061026001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f80191681526020015f81526020015f81526020015f81526020015f81526020015f81526020015f80191681526020016060815260200160608152602001606081526020015f815260200160608152602001606081525090565b606061ffff600288015116935060ff600388015116925061ffff60058801511660058801975080885260208101880191505061197787878760405180602001604052805f815250611d7c565b915080826101e001819052505093509350939050565b5f8080600181878703602081116119a457806119a7565b60205b915050875192505b8519600184841a1b161581831016156119cd576001820191506119af565b9681019660208290036008810293841c90931b92611a185760408051602081018590520160408051601f198184030181529082905263e47fe8b760e01b8252610c369160040161221f565b50869350909150505b935093915050565b600182810180515f928392600560ff93909316602102870192830192909101835b81831015611aee5760018301516021909301805190935f90819060ff168180611a73838e611f2d565b915091508186165f03611a95575f809b509b5050505050505050505050611af9565b5f87611aa5600185038916611f58565b016004028b015195505062ffffff9081169350841683039150611ad99050575060019750601c1a9550611af9945050505050565b611ae283611f58565b84019350505050611a4a565b5f8095509550505050505b9250929050565b6101c08201516002828102820101516101e08401515f9261ffff9092169190611b269083565b95945050505050565b60606040518060600160405280603c815260200161249d603c9139905090565b5f81515f14611b71576040516304f8b58160e51b815260040160405180910390fd5b505f919050565b5f8151600103611bd5575060208101516001600160e01b038116601b0b60e082901d5f611ba6838383612011565b905061ffff811115611bcb57604051631e4e01d760e21b815260040160405180910390fd5b9250611c0f915050565b81515f03611bf657604051630f16066b60e41b815260040160405180910390fd5b604051630358cd2160e31b815260040160405180910390fd5b919050565b5f8151600203611ca957602082015160408301516001600160e01b038216601b0b60e083901d5f611c46838383612011565b6001600160e01b038516601b0b935060e085901d925090505f611c6a848483612011565b905060ff821180611c7b575060ff81115b15611c9957604051631e4e01d760e21b815260040160405180910390fd5b60081b179450611c0f9350505050565b600282511015611bf657604051630f16066b60e41b815260040160405180910390fd5b5f60608060ff851180611cdf575060ff84115b15611d0757604051639b0f326160e01b81526004810186905260248101859052604401610c36565b6040805160248101909152600386602383015385602283015360106021830153806020830153506004815260408051602081019091525f8152600197919650945092505050565b5f60208201602083510281015b80821015611d755781515183019250602082019150611d5b565b5050919050565b611e096040518061026001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f80191681526020015f81526020015f81526020015f81526020015f81526020015f81526020015f80191681526020016060815260200160608152602001606081526020015f815260200160608152602001606081525090565b5f6040518061026001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f801b81526020015f8152602001600481526020015f81526020015f81526020015f81526020015f801b815260200184815260200185815260200160046001600160401b03811115611e8e57611e8e612231565b604051908082528060200260200182016040528015611eb7578160200160208202803683370190505b5081525f602080830182905260408084018b905260609384018a90528051601f01601f19168281528083018252835161ffff191681178452855290840182905283018190529082018190526080820181905260a08201819052610120820181905261014082018190526102008201529050611b26565b5f80825f528360205360215f2090506001815f1a1b915062ffffff8116611af9575060019250929050565b5f5f198203611f6a5750610100919050565b507f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f7f5555555555555555555555555555555555555555555555555555555555555555600183901c16909103600281901c7f3333333333333333333333333333333333333333333333333333333333333333908116911601600481901c01167f01010101010101010101010101010101010101010101010101010101010101010260f81c90565b5f805f61201f868686612053565b915091508061204a5760405162bc8ecf60e31b81526004810187905260248101869052604401610c36565b50949350505050565b5f805f85121561208057604051634a7d166b60e01b81526004810186905260248101859052604401610c36565b845f0361209257505f90506001611a21565b8460ff84168501858112156120c45760405163d556b11160e01b81526004810188905260248101879052604401610c36565b5f805f83121561211057604c198312156120e7575f809550955050505050611a21565b825f03600a0a91508184816120fe576120fe61237f565b0495505084029091149150611a219050565b5f8313156121a957604d83131561214d5760405163c849483b60e01b8152600481018a90526024810189905260ff88166044820152606401610c36565b82600a0a9150815f19816121635761216361237f565b048411156121975760405163c849483b60e01b8152600481018a90526024810189905260ff88166044820152606401610c36565b5091909102925060019150611a219050565b8360019550955050505050611a21565b6121c16123b2565b565b5f602082840312156121d3575f80fd5b81356001600160e01b0319811681146121ea575f80fd5b9392505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f6121ea60208301846121f1565b634e487b7160e01b5f52604160045260245ffd5b5f60208284031215612255575f80fd5b81356001600160401b038082111561226b575f80fd5b818401915084601f83011261227e575f80fd5b81358181111561229057612290612231565b604051601f8201601f19908116603f011681019083821181831017156122b8576122b8612231565b816040528281528760208487010111156122d0575f80fd5b826020860160208301375f928101602001929092525095945050505050565b83151581525f60206060602084015261230b60608401866121f1565b8381036040850152845180825260208087019201905f5b8181101561233e57835183529284019291840191600101612322565b509098975050505050505050565b808201808211156101d157634e487b7160e01b5f52601160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601260045260245ffd5b5f826123ad57634e487b7160e01b5f52601260045260245ffd5b500490565b634e487b7160e01b5f52605160045260245ffdfe0101080010800082000100010480300038412a001810000010020004200004002018038ff54900cc66c60616592209895f0b16fec9301a02e0920c5bfe561c21609201e959460b1974270f844db208bcd3bf1d989376111049db13b93430190ae9a00af82a7805c138f40d28083f0742ef2104d561fd1415a13317716a6118d260cc107b9bfc0eec7ade15cba2891b6b14a512792bdb02e0f1471b4f1b4f1b4f1b4f1b4f1b4f1b4f1b4f1b4f1b4f1b4f1b4f1b4f1b4f1b4f1b4f1b4f1b781c141b4f1b4f1b4f1b4f1b4f1b4f1b4f1b4f1b4f1b4f1b4f15f2160f161e162d163c164c165b166b167a168a169a16a916b916c816d816e816f81707171615f2161e162d163c174b15f2161e162d163c174b175b", + "linkReferences": {} + } +} diff --git a/crates/test_fixtures/contracts/IMulticall3.sol b/crates/test_fixtures/contracts/IMulticall3.sol new file mode 100644 index 0000000000..6a94133e06 --- /dev/null +++ b/crates/test_fixtures/contracts/IMulticall3.sol @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity >=0.8.13 <0.9.0; + +interface IMulticall3 { + struct Call { + address target; + bytes callData; + } + + struct Call3 { + address target; + bool allowFailure; + bytes callData; + } + + struct Call3Value { + address target; + bool allowFailure; + uint256 value; + bytes callData; + } + + struct Result { + bool success; + bytes returnData; + } + + function aggregate(Call[] calldata calls) external payable returns (uint256 blockNumber, bytes[] memory returnData); + + function aggregate3(Call3[] calldata calls) external payable returns (Result[] memory returnData); + + function aggregate3Value(Call3Value[] calldata calls) external payable returns (Result[] memory returnData); + + function blockAndAggregate(Call[] calldata calls) + external + payable + returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData); + + function getBasefee() external view returns (uint256 basefee); + + function getBlockHash(uint256 blockNumber) external view returns (bytes32 blockHash); + + function getBlockNumber() external view returns (uint256 blockNumber); + + function getChainId() external view returns (uint256 chainid); + + function getCurrentBlockCoinbase() external view returns (address coinbase); + + function getCurrentBlockDifficulty() external view returns (uint256 difficulty); + + function getCurrentBlockGasLimit() external view returns (uint256 gaslimit); + + function getCurrentBlockTimestamp() external view returns (uint256 timestamp); + + function getEthBalance(address addr) external view returns (uint256 balance); + + function getLastBlockHash() external view returns (bytes32 blockHash); + + function tryAggregate(bool requireSuccess, Call[] calldata calls) + external + payable + returns (Result[] memory returnData); + + function tryBlockAndAggregate(bool requireSuccess, Call[] calldata calls) + external + payable + returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData); +} diff --git a/crates/test_fixtures/src/lib.rs b/crates/test_fixtures/src/lib.rs index 3f0aa4da70..c43543b19f 100644 --- a/crates/test_fixtures/src/lib.rs +++ b/crates/test_fixtures/src/lib.rs @@ -23,22 +23,17 @@ use rain_math_float::Float; sol!( #![sol(all_derives = true, rpc = true)] - Raindex, "../../out/RaindexV6.sol/RaindexV6.json" + Raindex, "./abis/RaindexV6.json" ); sol!( #![sol(all_derives = true, rpc = true)] - RaindexSubParser, "../../out/RaindexV6SubParser.sol/RaindexV6SubParser.json" + RaindexSubParser, "./abis/RaindexV6SubParser.json" ); sol!( #![sol(all_derives = true, rpc = true)] - "../../dependencies/forge-std-1.16.1/src/interfaces/IMulticall3.sol" -); - -sol!( - #![sol(all_derives = true, rpc = true)] - TOFUTokenDecimals, "../../out/TOFUTokenDecimals.sol/TOFUTokenDecimals.json" + "./contracts/IMulticall3.sol" ); /// A local evm instance that wraps an Anvil instance and provider with diff --git a/flake.lock b/flake.lock index 83ff2fcda9..2c1d82451b 100644 --- a/flake.lock +++ b/flake.lock @@ -499,11 +499,11 @@ "solc": "solc_2" }, "locked": { - "lastModified": 1779906039, - "narHash": "sha256-NKMWv+iiirFgjOLPPlKsUA7chNzRrZd+6LFMei2M8HQ=", + "lastModified": 1780154135, + "narHash": "sha256-dzfWTnq+80nLKHkwvbBcEIIJylABaxQShsok8nU0GLM=", "owner": "rainlanguage", "repo": "rainix", - "rev": "660d0efe84a3ed1c8a7ef5b8493db53e4a12fe04", + "rev": "81c6e4e3556abcbad30f51ef46481d01a672adbf", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 2639198e24..7b4ff9f052 100644 --- a/flake.nix +++ b/flake.nix @@ -190,6 +190,15 @@ packages = with pkgs; [ nodejs_20 ]; inherit (rainix.devShells.${system}.default) buildInputs nativeBuildInputs; }; + + # Re-export rainix's slim devShells so workflows can reference them + # via `.#X-shell` and pick up the flake.lock-pinned rainix rev + # instead of live `github:rainlanguage/rainix#X-shell` (which + # bypasses flake.lock and tracks rainix main). + devShells.wasm-shell = rainix.devShells.${system}.wasm-shell; + devShells.subgraph-shell = rainix.devShells.${system}.subgraph-shell; + devShells.sol-shell = rainix.devShells.${system}.sol-shell; + devShells.rust-shell = rainix.devShells.${system}.rust-shell; } ); diff --git a/packages/raindex/ARCHITECTURE.md b/packages/raindex/ARCHITECTURE.md index 4c1f77f90e..f0888c90c7 100644 --- a/packages/raindex/ARCHITECTURE.md +++ b/packages/raindex/ARCHITECTURE.md @@ -1,49 +1,76 @@ # @rainlanguage/raindex — Architecture -This package is the JavaScript/TypeScript SDK that exposes Raindex functionality to web and Node.js consumers. It packages the Rust WASM crate surface (primarily `raindex_js_api`, plus re-exports from sibling crates) into a single, installable NPM module with CJS and ESM entry points. - -The SDK is designed to work in browsers, Node.js, and hybrid runtimes. It embeds the compiled `.wasm` bytes directly in the published bundle so consumers do not need network fetches or filesystem access at runtime. +This package is the JavaScript/TypeScript SDK that exposes Raindex functionality +to web and Node.js consumers. It packages the Rust WASM crate surface (primarily +`raindex_js_api`, plus re-exports from sibling crates) into a single, +installable NPM module with CJS and ESM entry points. +The SDK is designed to work in browsers, Node.js, and hybrid runtimes. It embeds +the compiled `.wasm` bytes directly in the published bundle so consumers do not +need network fetches or filesystem access at runtime. ## Overview - Purpose - - Provide a WASM-backed API for: YAML parsing/validation, raindex queries (subgraph), quoting, vault management, transaction calldata generation (add/remove, deposit/withdraw), builder helpers to deploy orders from dotrain, and low-level hashing/ABI helpers. + - Provide a WASM-backed API for: YAML parsing/validation, raindex queries + (subgraph), quoting, vault management, transaction calldata generation + (add/remove, deposit/withdraw), builder helpers to deploy orders from + dotrain, and low-level hashing/ABI helpers. - Targets - ESM (browser) and CJS (Node.js) builds are both published. - The WASM is base64-embedded to avoid runtime `fetch`/`fs` requirements. - Upstream crates - - Backed by `raindex_js_api` (WASM cdylib) which re-exports `raindex_app_settings`, `raindex_common`, and `raindex_subgraph_client` for a unified JS surface. + - Backed by `raindex_js_api` (WASM cdylib) which re-exports + `raindex_app_settings`, `raindex_common`, and `raindex_subgraph_client` for + a unified JS surface. Typical import ```ts -import { RaindexClient, RaindexOrderBuilder, parseYaml, getOrderHash } from "@rainlanguage/raindex"; +import { + getOrderHash, + parseYaml, + RaindexClient, + RaindexOrderBuilder, +} from "@rainlanguage/raindex"; ``` - ## Build & Packaging -All builds should be run inside a Nix shell to ensure toolchain parity (`nix develop -c `). +All builds should be run inside a Nix shell to ensure toolchain parity +(`nix develop -c `). - Entry generation (`scripts/build.js`) - - Writes thin top-level entry files: `cjs.js` (CommonJS re-export), `esm.js` (ESM re-export), plus `.d.ts` stubs. + - Writes thin top-level entry files: `cjs.js` (CommonJS re-export), `esm.js` + (ESM re-export), plus `.d.ts` stubs. - Creates `dist/cjs` and `dist/esm` directories. - - Invokes `npm run build-wasm` to compile the Rust workspace to `wasm32-unknown-unknown` in release mode (excludes CLI and integration tests). - - For each package (currently just `js_api`), calls `scripts/buildPackage.js` to produce JS bindings and package artifacts. + - Invokes `npm run build-wasm` to compile the Rust workspace to + `wasm32-unknown-unknown` in release mode (excludes CLI and integration + tests). + - For each package (currently just `js_api`), calls `scripts/buildPackage.js` + to produce JS bindings and package artifacts. - WASM binding & embedding (`scripts/buildPackage.js`) - - Runs `wasm-bindgen` twice to generate Node (CJS) and Web (ESM) wrappers from the compiled `.wasm`. The `wasm-bindgen` binary comes from the Nix environment. - - Reads the generated `.wasm` files and writes `dist/cjs/raindex_wbg.json` and `dist/esm/raindex_wbg.json` containing base64-encoded bytes. + - Runs `wasm-bindgen` twice to generate Node (CJS) and Web (ESM) wrappers from + the compiled `.wasm`. The `wasm-bindgen` binary comes from the Nix + environment. + - Reads the generated `.wasm` files and writes `dist/cjs/raindex_wbg.json` and + `dist/esm/raindex_wbg.json` containing base64-encoded bytes. - Rewrites the generated JS to: - - CJS: read bytes from the embedded JSON via `Buffer.from(base64)` and initialize the module without touching the filesystem. - - ESM: import the embedded JSON and use top-level `await __wbg_init(bytes)` to initialize the WASM before exporting symbols. - - Copies type declarations to `dist/*/index.d.ts` and prefixes generated files with a note that they are auto-generated. + - CJS: read bytes from the embedded JSON via `Buffer.from(base64)` and + initialize the module without touching the filesystem. + - ESM: import the embedded JSON and use top-level `await __wbg_init(bytes)` + to initialize the WASM before exporting symbols. + - Copies type declarations to `dist/*/index.d.ts` and prefixes generated files + with a note that they are auto-generated. - Prepublish bootstrap (`scripts/setup.js`) - - If `./dist` exists, exits early (supporting installs from already-built tarballs). - - Otherwise, cleans temp/outputs and runs the full build inside Nix: `nix develop -c node scripts/build`. + - If `./dist` exists, exits early (supporting installs from already-built + tarballs). + - Otherwise, cleans temp/outputs and runs the full build inside Nix: + `nix develop -c node scripts/build`. - Type checking & tests - `npm run check` runs `tsc` over the built JS to validate the emitted types. - - `npm run test` executes Vitest suites under `test/` against the built artifacts. + - `npm run test` executes Vitest suites under `test/` against the built + artifacts. Key commands @@ -51,14 +78,15 @@ Key commands - Test: `nix develop -c npm run test` - Docs: `nix develop -c npm run docs` - ## Directory Layout -- `cjs.js`, `esm.js` — Top-level re-exports pointing at `dist/` (published files). +- `cjs.js`, `esm.js` — Top-level re-exports pointing at `dist/` (published + files). - `cjs.d.ts`, `esm.d.ts` — Type re-export stubs for consumers. - `dist/` — Build output (published) - `cjs/` - - `index.js` — Auto-generated CommonJS glue that initializes WASM from `raindex_wbg.json`. + - `index.js` — Auto-generated CommonJS glue that initializes WASM from + `raindex_wbg.json`. - `index.d.ts` — Type declarations. - `raindex_wbg.json` — Base64-encoded WASM bytes. - `esm/` @@ -70,54 +98,83 @@ Key commands - `buildPackage.js` — Runs `wasm-bindgen`, embeds WASM, writes JS/TS outputs. - `setup.js` — Prepublish bootstrap inside Nix. - `test/` — Vitest suites exercising bindings (bindings/common/js_api). -- `typedoc.json`, `tsconfig.json` — Documentation and TS settings for the published surface. +- `typedoc.json`, `tsconfig.json` — Documentation and TS settings for the + published surface. - `README.md` — End-user SDK guide with examples. - ## Exports & API Surface -The package re-exports the WASM-bound API from the Rust crates. Representative items: +The package re-exports the WASM-bound API from the Rust crates. Representative +items: - Functions - - `parseYaml`, `getOrderHash`, `getTakeOrders3Calldata`, `keccak256`, `keccak256HexString`. + - `parseYaml`, `getOrderHash`, `getTakeOrders3Calldata`, `keccak256`, + `keccak256HexString`. - High-level classes (selected) - - `RaindexClient` — raindex queries (orders, trades, vaults, quotes, transactions) across configured networks/subgraphs. Constructor is async (`await RaindexClient.new(...)`) and accepts optional `queryCallback` (for applying fetched records to the local DB), `wipeCallback` (for cleaning up stale data during full re-sync), and `statusCallback` (for reporting sync progress/errors to the caller) args for local DB sync when the YAML has `local-db-sync` sections. The sync scheduler starts automatically when configured and shuts down via Drop. - - `RaindexOrder`, `RaindexVault`, `RaindexTrade`, `RaindexTransaction`, `RaindexVaultsList`, etc. - - `DotrainOrder`, `RaindexOrderBuilder`, `DotrainRegistry` — dotrain parsing, builder orchestration, registry fetching (including `getRaindexYaml()` for token queries), and deployment calldata. - - `RaindexYaml` — typed access to networks, tokens (via `getTokens()`), raindexes, subgraphs, deployers, accounts, metaboards. + - `RaindexClient` — raindex queries (orders, trades, vaults, quotes, + transactions) across configured networks/subgraphs. Constructor is async + (`await RaindexClient.new(...)`) and accepts optional `queryCallback` (for + applying fetched records to the local DB), `wipeCallback` (for cleaning up + stale data during full re-sync), and `statusCallback` (for reporting sync + progress/errors to the caller) args for local DB sync when the YAML has + `local-db-sync` sections. The sync scheduler starts automatically when + configured and shuts down via Drop. + - `RaindexOrder`, `RaindexVault`, `RaindexTrade`, `RaindexTransaction`, + `RaindexVaultsList`, etc. + - `DotrainOrder`, `RaindexOrderBuilder`, `DotrainRegistry` — dotrain parsing, + builder orchestration, registry fetching (including `getRaindexYaml()` for + token queries), and deployment calldata. + - `RaindexYaml` — typed access to networks, tokens (via `getTokens()`), + raindexes, subgraphs, deployers, accounts, metaboards. - `Float` — arbitrary-precision float utilities used across the API. - Errors & results - - Most methods return `WasmEncodedResult` with either `{ value }` or `{ error: { msg, readableMsg } }` for ergonomic, user-readable error handling in JS. + - Most methods return `WasmEncodedResult` with either `{ value }` or + `{ error: { msg, readableMsg } }` for ergonomic, user-readable error + handling in JS. Notes on runtime behavior -- ESM builds use top-level `await` to initialize the WASM module before exports are used. Ensure your bundler/runtime supports top-level await. -- No network fetches are performed to load the WASM bytes; they are embedded via JSON. - +- ESM builds use top-level `await` to initialize the WASM module before exports + are used. Ensure your bundler/runtime supports top-level await. +- No network fetches are performed to load the WASM bytes; they are embedded via + JSON. ## How It Fits The Workspace -- Rust crates under `crates/*` implement the core logic. `raindex_js_api` compiles to WASM and re-exports pieces of `common`, `settings`, `subgraph`, and others for a cohesive JS surface. -- This package is the NPM wrapper that compiles those crates for WASM, generates JS glue, and publishes the resulting SDK. -- Consumers use only `@rainlanguage/raindex`; no direct interaction with the Rust build is required. - +- Rust crates under `crates/*` implement the core logic. `raindex_js_api` + compiles to WASM and re-exports pieces of `common`, `settings`, `subgraph`, + and others for a cohesive JS surface. +- This package is the NPM wrapper that compiles those crates for WASM, generates + JS glue, and publishes the resulting SDK. +- Consumers use only `@rainlanguage/raindex`; no direct interaction with the + Rust build is required. ## Testing & Documentation -- Tests: Vitest suites under `test/` validate representative flows: orders/vaults/trades queries, quoting, calldata generation, builder flows, and error surfaces. -- Docs: `npm run docs` builds TypeDoc from the emitted `.d.ts` for hosted API documentation. - +- Tests: Vitest suites under `test/` validate representative flows: + orders/vaults/trades queries, quoting, calldata generation, builder flows, and + error surfaces. +- Docs: `npm run docs` builds TypeDoc from the emitted `.d.ts` for hosted API + documentation. ## Publishing & Versioning -- The `prepublish` script ensures the package is fully rebuilt within a Nix shell and includes the embedded WASM. Tarballs contain `dist/` and thin top-level entry points. -- Node.js >= 22 is required (see `package.json#engines`). A small `buffer` dependency is bundled for ESM environments that lack a native `Buffer`. - +- The `prepublish` script ensures the package is fully rebuilt within a Nix + shell and includes the embedded WASM. Tarballs contain `dist/` and thin + top-level entry points. +- Node.js >= 22 is required (see `package.json#engines`). A small `buffer` + dependency is bundled for ESM environments that lack a native `Buffer`. ## Caveats & Tips -- Always run build/test inside `nix develop` so `wasm-bindgen`, Rust toolchains, and targets are available. -- If you add new WASM crates/exports in the workspace, extend the `packages` array in `scripts/build.js` and mirror any binding tweaks in `scripts/buildPackage.js`. -- If you see initialization issues in the browser, confirm your bundler supports top-level await and that `raindex_wbg.json` is included in the bundle. - -This document explains what the `packages/raindex` directory is for, how the WASM artifacts are produced and embedded, what gets exported to consumers, and how it connects to the rest of the Raindex workspace. +- Always run build/test inside `nix develop` so `wasm-bindgen`, Rust toolchains, + and targets are available. +- If you add new WASM crates/exports in the workspace, extend the `packages` + array in `scripts/build.js` and mirror any binding tweaks in + `scripts/buildPackage.js`. +- If you see initialization issues in the browser, confirm your bundler supports + top-level await and that `raindex_wbg.json` is included in the bundle. + +This document explains what the `packages/raindex` directory is for, how the +WASM artifacts are produced and embedded, what gets exported to consumers, and +how it connects to the rest of the Raindex workspace. diff --git a/packages/raindex/README.md b/packages/raindex/README.md index 83d6e58bcc..052b51d6b6 100644 --- a/packages/raindex/README.md +++ b/packages/raindex/README.md @@ -1,30 +1,48 @@ # Raindex SDK -A TypeScript/JavaScript SDK for interacting with Raindex contracts, providing comprehensive functionality for order management, configuration parsing, and blockchain interactions. +A TypeScript/JavaScript SDK for interacting with Raindex contracts, providing +comprehensive functionality for order management, configuration parsing, and +blockchain interactions. ## What is Raindex? -Raindex is an **onchain contract** that enables users to deploy complex, perpetual trading algorithms using **Rainlang**, a domain-specific language interpreted onchain. Learn more about Rainlang in the [official documentation](https://docs.rainlang.xyz/intro). +Raindex is an **onchain contract** that enables users to deploy complex, +perpetual trading algorithms using **Rainlang**, a domain-specific language +interpreted onchain. Learn more about Rainlang in the +[official documentation](https://docs.rainlang.xyz/intro). ### How It Works -- **Dynamic Orders**: Unlike traditional order books, Raindex orders contain algorithms that determine token movements based on real-time conditions -- **Vault System**: Users deposit tokens into vaults (virtual accounts) instead of using token approvals -- **Multi-Token Strategies**: Orders can reference multiple input/output vaults for sophisticated trading scenarios -- **Perpetual Execution**: Strategies remain active until explicitly removed by the owner -- **Decentralized Execution**: Third-party fillers execute trades by capitalizing on arbitrage opportunities +- **Dynamic Orders**: Unlike traditional order books, Raindex orders contain + algorithms that determine token movements based on real-time conditions +- **Vault System**: Users deposit tokens into vaults (virtual accounts) instead + of using token approvals +- **Multi-Token Strategies**: Orders can reference multiple input/output vaults + for sophisticated trading scenarios +- **Perpetual Execution**: Strategies remain active until explicitly removed by + the owner +- **Decentralized Execution**: Third-party fillers execute trades by + capitalizing on arbitrage opportunities ## SDK Overview -This SDK provides Rust-powered WebAssembly bindings for Raindex functionality, enabling developers to: - -- **Query Orders & Trades**: Search orders across multiple networks, fetch order details, and track trade history -- **Execute Quotes**: Get real-time quotes for trading pairs with maximum output amounts and IO ratios -- **Take Orders**: Generate calldata for executing trades against orders, with auto-discovery by token pair or targeting specific orders -- **Manage Vaults**: Query vault balances, generate deposit/withdraw calldata, and track vault activity -- **Parse Configurations**: Validate YAML files defining networks, tokens, raindexes, and subgraph endpoints -- **Generate Transactions**: Create ABI-encoded calldata for adding/removing orders and vault operations -- **Track Performance**: Monitor order volume, vault balance changes, and trading metrics over time +This SDK provides Rust-powered WebAssembly bindings for Raindex functionality, +enabling developers to: + +- **Query Orders & Trades**: Search orders across multiple networks, fetch order + details, and track trade history +- **Execute Quotes**: Get real-time quotes for trading pairs with maximum output + amounts and IO ratios +- **Take Orders**: Generate calldata for executing trades against orders, with + auto-discovery by token pair or targeting specific orders +- **Manage Vaults**: Query vault balances, generate deposit/withdraw calldata, + and track vault activity +- **Parse Configurations**: Validate YAML files defining networks, tokens, + raindexes, and subgraph endpoints +- **Generate Transactions**: Create ABI-encoded calldata for adding/removing + orders and vault operations +- **Track Performance**: Monitor order volume, vault balance changes, and + trading metrics over time ## Prerequisites @@ -32,7 +50,8 @@ Before using this SDK, ensure you have: - Node.js >= 22 - A Web3 provider (e.g., ethers.js, viem) -- A YAML configuration file (see [example configuration](https://github.com/rainlanguage/rain.strategies/blob/main/settings.yaml)) +- A YAML configuration file (see + [example configuration](https://github.com/rainlanguage/rain.strategies/blob/main/settings.yaml)) ## Installation @@ -44,9 +63,14 @@ npm install @rainlanguage/raindex ### Example configuration used in this guide -All of the code snippets below reuse the same fixed-limit dotrain/settings source. The portion before `---` represents the shared raindex and dotrain YAML, and Rainlang lives after the separator. +All of the code snippets below reuse the same fixed-limit dotrain/settings +source. The portion before `---` represents the shared raindex and dotrain YAML, +and Rainlang lives after the separator. -> **Heads-up:** These values are purely illustrative. Before deploying anything, pull the canonical strategies and settings from [rainlanguage/rain.strategies](https://github.com/rainlanguage/rain.strategies) to mirror what our web apps run in production. +> **Heads-up:** These values are purely illustrative. Before deploying anything, +> pull the canonical strategies and settings from +> [rainlanguage/rain.strategies](https://github.com/rainlanguage/rain.strategies) +> to mirror what our web apps run in production. ```ts const FIXED_LIMIT_SOURCE = ` @@ -185,24 +209,31 @@ io: if( :; `; -const RAINDEX_SETTINGS = FIXED_LIMIT_SOURCE.split('---')[0]; +const RAINDEX_SETTINGS = FIXED_LIMIT_SOURCE.split("---")[0]; ``` ### 1. Create a raindex client -This first snippet does three things: (1) load one or more settings YAML strings (these describe networks, accounts, and subgraph URLs), (2) feed those sources into `RaindexClient.new` so the WASM layer can parse and validate them, and (3) unwrap the resulting `WasmEncodedResult` so downstream samples can call the client with standard JS error handling expectations. The constructor is **async** — use `await`. +This first snippet does three things: (1) load one or more settings YAML strings +(these describe networks, accounts, and subgraph URLs), (2) feed those sources +into `RaindexClient.new` so the WASM layer can parse and validate them, and (3) +unwrap the resulting `WasmEncodedResult` so downstream samples can call the +client with standard JS error handling expectations. The constructor is +**async** — use `await`. ```ts -import { RaindexClient } from '@rainlanguage/raindex'; +import { RaindexClient } from "@rainlanguage/raindex"; const clientResult = await RaindexClient.new([RAINDEX_SETTINGS]); if (clientResult.error) throw new Error(clientResult.error.readableMsg); const client = clientResult.value; ``` -Pass `true` as the second argument to `RaindexClient.new` when you want strict schema validation. +Pass `true` as the second argument to `RaindexClient.new` when you want strict +schema validation. -When the YAML includes `local-db-sync` sections, pass optional callbacks to wire up a local SQLite cache: +When the YAML includes `local-db-sync` sections, pass optional callbacks to wire +up a local SQLite cache: ```ts const clientResult = await RaindexClient.new( @@ -214,20 +245,24 @@ const clientResult = await RaindexClient.new( ); ``` -The client will automatically start the sync scheduler and route queries to the local DB for configured chains once the first sync cycle completes. +The client will automatically start the sync scheduler and route queries to the +local DB for configured chains once the first sync cycle completes. ### 2. Query orders with filters & pagination -Here we scope the query by chain IDs and typical filters (owner, token, activity flag), ask the client to hydrate matching orders, and then walk the richer helpers on a single `RaindexOrder`—vault listings, trades, quotes, and detail lookups—to show how pagination + follow-up queries hang together. +Here we scope the query by chain IDs and typical filters (owner, token, activity +flag), ask the client to hydrate matching orders, and then walk the richer +helpers on a single `RaindexOrder`—vault listings, trades, quotes, and detail +lookups—to show how pagination + follow-up queries hang together. ```ts -import type { ChainIds, GetOrdersFilters } from '@rainlanguage/raindex'; +import type { ChainIds, GetOrdersFilters } from "@rainlanguage/raindex"; const chainIds: ChainIds = [8453]; const filters: GetOrdersFilters = { - owners: ['0x1234...'], + owners: ["0x1234..."], active: true, - tokens: ['0xTokenAddress'] + tokens: ["0xTokenAddress"], }; const ordersResult = await client.getOrders(chainIds, filters, 1); @@ -241,8 +276,10 @@ const rawVaults = vaultList.items; // RaindexVault[] const tradesResult = await first.getTradesList(); if (tradesResult.error) throw new Error(tradesResult.error.readableMsg); -const tradeDetailResult = await first.getTradeDetail('0xTradeId'); -if (tradeDetailResult.error) throw new Error(tradeDetailResult.error.readableMsg); +const tradeDetailResult = await first.getTradeDetail("0xTradeId"); +if (tradeDetailResult.error) { + throw new Error(tradeDetailResult.error.readableMsg); +} const quotesResult = await first.getQuotes(); if (quotesResult.error) throw new Error(quotesResult.error.readableMsg); @@ -250,13 +287,21 @@ if (quotesResult.error) throw new Error(quotesResult.error.readableMsg); Additional helpers worth wiring up: -- `client.getOrderByHash(chainId, raindexAddress, orderHash)` – fetch a single order with full vault metadata. -- `client.getAddOrdersForTransaction(...)` / `client.getRemoveOrdersForTransaction(...)` – diff deployments and removals by transaction hash. -- `client.getTransaction(raindexAddress, txHash)` – inspect who sent a transaction, the block number, and timestamp. +- `client.getOrderByHash(chainId, raindexAddress, orderHash)` – fetch a single + order with full vault metadata. +- `client.getAddOrdersForTransaction(...)` / + `client.getRemoveOrdersForTransaction(...)` – diff deployments and removals by + transaction hash. +- `client.getTransaction(raindexAddress, txHash)` – inspect who sent a + transaction, the block number, and timestamp. #### Poll for newly deployed orders -After you submit an `execute`/`addOrders` transaction you immediately have the transaction hash, but the subgraph still needs a few blocks to index the resulting order. Rather than re-querying every order and diffing manually, poll `client.getAddOrdersForTransaction` with that hash until it returns at least one `RaindexOrder`. +After you submit an `execute`/`addOrders` transaction you immediately have the +transaction hash, but the subgraph still needs a few blocks to index the +resulting order. Rather than re-querying every order and diffing manually, poll +`client.getAddOrdersForTransaction` with that hash until it returns at least one +`RaindexOrder`. ```ts import type { RaindexClient } from '@rainlanguage/raindex'; @@ -301,27 +346,33 @@ const raindexOrder = await waitForOrderFromTx(client, { ```ts const orderResult = await client.getOrderByHash( 8453, // Base - '0x52CEB8eBEf648744fFDDE89F7Bc9C3aC35944775', - '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef12' + "0x52CEB8eBEf648744fFDDE89F7Bc9C3aC35944775", + "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef12", ); if (orderResult.error) throw new Error(orderResult.error.readableMsg); const order = orderResult.value; // RaindexOrder const vaultsList = order.vaultsList; const removeCalldataResult = await order.getRemoveCalldata(); -if (removeCalldataResult.error) throw new Error(removeCalldataResult.error.readableMsg); +if (removeCalldataResult.error) { + throw new Error(removeCalldataResult.error.readableMsg); +} ``` ### 3. Work with vaults & Floats -Vault workflows usually require combining filters, inspecting the returned `RaindexVaultsList`, and then producing calldata or math-heavy amounts. This example chains those steps: fetch vaults, narrow the list to withdrawable entries, pull history, parse human inputs with `Float`, and finally build deposit/withdraw/approval payloads while checking allowances. +Vault workflows usually require combining filters, inspecting the returned +`RaindexVaultsList`, and then producing calldata or math-heavy amounts. This +example chains those steps: fetch vaults, narrow the list to withdrawable +entries, pull history, parse human inputs with `Float`, and finally build +deposit/withdraw/approval payloads while checking allowances. ```ts -import { Float, type GetVaultsFilters } from '@rainlanguage/raindex'; +import { Float, type GetVaultsFilters } from "@rainlanguage/raindex"; const vaultFilters: GetVaultsFilters = { - owners: ['0x1234...'], - hideZeroBalance: true + owners: ["0x1234..."], + hideZeroBalance: true, }; const vaultsResult = await client.getVaults([8453], vaultFilters, 1); @@ -329,22 +380,32 @@ if (vaultsResult.error) throw new Error(vaultsResult.error.readableMsg); const vaultsList = vaultsResult.value; // RaindexVaultsList const withdrawableResult = vaultsList.getWithdrawableVaults(); -if (withdrawableResult.error) throw new Error(withdrawableResult.error.readableMsg); +if (withdrawableResult.error) { + throw new Error(withdrawableResult.error.readableMsg); +} const withdrawableVaults = withdrawableResult.value; const vault = withdrawableVaults[0]; const historyResult = await vault.getBalanceChanges(); if (historyResult.error) throw new Error(historyResult.error.readableMsg); -const depositAmount = Float.parse('10.5'); +const depositAmount = Float.parse("10.5"); if (depositAmount.error) throw new Error(depositAmount.error.readableMsg); -const depositCalldataResult = await vault.getDepositCalldata(depositAmount.value); -if (depositCalldataResult.error) throw new Error(depositCalldataResult.error.readableMsg); +const depositCalldataResult = await vault.getDepositCalldata( + depositAmount.value, +); +if (depositCalldataResult.error) { + throw new Error(depositCalldataResult.error.readableMsg); +} -const withdrawAmount = Float.parse('2'); +const withdrawAmount = Float.parse("2"); if (withdrawAmount.error) throw new Error(withdrawAmount.error.readableMsg); -const withdrawCalldataResult = await vault.getWithdrawCalldata(withdrawAmount.value); -if (withdrawCalldataResult.error) throw new Error(withdrawCalldataResult.error.readableMsg); +const withdrawCalldataResult = await vault.getWithdrawCalldata( + withdrawAmount.value, +); +if (withdrawCalldataResult.error) { + throw new Error(withdrawCalldataResult.error.readableMsg); +} const approvalResult = await vault.getApprovalCalldata(depositAmount.value); if (approvalResult.error) throw new Error(approvalResult.error.readableMsg); @@ -354,29 +415,36 @@ if (allowanceResult.error) throw new Error(allowanceResult.error.readableMsg); const allowance = allowanceResult.value; ``` -`RaindexVaultsList` also exposes `getWithdrawCalldata()` (builds a multicall to empty every vault with a balance), `pickByIds([...])`, and `concat(otherList)` if you need to restructure vault groups before submitting a transaction. +`RaindexVaultsList` also exposes `getWithdrawCalldata()` (builds a multicall to +empty every vault with a balance), `pickByIds([...])`, and `concat(otherList)` +if you need to restructure vault groups before submitting a transaction. #### Fetch a single vault ```ts const vaultResult = await client.getVault( 8453, - '0x52CEB8eBEf648744fFDDE89F7Bc9C3aC35944775', - '0x01' + "0x52CEB8eBEf648744fFDDE89F7Bc9C3aC35944775", + "0x01", ); if (vaultResult.error) throw new Error(vaultResult.error.readableMsg); const vault = vaultResult.value; // RaindexVault const balanceChangesResult = await vault.getBalanceChanges(); -if (balanceChangesResult.error) throw new Error(balanceChangesResult.error.readableMsg); +if (balanceChangesResult.error) { + throw new Error(balanceChangesResult.error.readableMsg); +} ``` ### 4. Generate quotes & calldata -Once you have hydrated orders, you typically need deterministic hashes plus calldata builders. The snippet below hashes an order struct, generates take-orders calldata, asks an order for its removal calldata, and fetches quotes—mirroring the usual "inspect -> prepare transaction -> submit" flow. +Once you have hydrated orders, you typically need deterministic hashes plus +calldata builders. The snippet below hashes an order struct, generates +take-orders calldata, asks an order for its removal calldata, and fetches +quotes—mirroring the usual "inspect -> prepare transaction -> submit" flow. ```ts -import { getOrderHash, getTakeOrders3Calldata } from '@rainlanguage/raindex'; +import { getOrderHash, getTakeOrders3Calldata } from "@rainlanguage/raindex"; const orderHashResult = getOrderHash(orderV4Struct); if (orderHashResult.error) throw new Error(orderHashResult.error.readableMsg); @@ -386,72 +454,83 @@ if (takeOrdersResult.error) throw new Error(takeOrdersResult.error.readableMsg); const takeOrdersCalldata = takeOrdersResult.value; // hex string ready for the contract const removeCalldataResult = await first.getRemoveCalldata(); -if (removeCalldataResult.error) throw new Error(removeCalldataResult.error.readableMsg); +if (removeCalldataResult.error) { + throw new Error(removeCalldataResult.error.readableMsg); +} const quotesResult = await first.getQuotes(); if (quotesResult.error) throw new Error(quotesResult.error.readableMsg); ``` -Every `RaindexOrder` exposes `vaultsList`, `inputsList`, `outputsList`, and `inputsOutputsList`, so you can quickly scope which vault IDs map to which IO leg before building calldata. +Every `RaindexOrder` exposes `vaultsList`, `inputsList`, `outputsList`, and +`inputsOutputsList`, so you can quickly scope which vault IDs map to which IO +leg before building calldata. ### 5. Take orders -The SDK provides two approaches for executing `takeOrders4` transactions: auto-discovery by token pair or targeting a specific known order. +The SDK provides two approaches for executing `takeOrders4` transactions: +auto-discovery by token pair or targeting a specific known order. #### Take orders by token pair (auto-discovery) -Use `client.getTakeOrdersCalldata()` to discover and aggregate liquidity across all active orders for a given token pair: +Use `client.getTakeOrdersCalldata()` to discover and aggregate liquidity across +all active orders for a given token pair: ```ts -import type { TakeOrdersRequest } from '@rainlanguage/raindex'; +import type { TakeOrdersRequest } from "@rainlanguage/raindex"; const request: TakeOrdersRequest = { chainId: 137, - taker: '0xYourAddress...', - sellToken: '0xUSDC...', // Token you will GIVE - buyToken: '0xWETH...', // Token you will RECEIVE - mode: 'BuyUpTo', // BuyExact | BuyUpTo | SpendExact | SpendUpTo - amount: '10', // Target amount (buy tokens for buy modes, sell tokens for spend modes) - priceCap: '1.2' // Maximum price (sell per 1 buy) + taker: "0xYourAddress...", + sellToken: "0xUSDC...", // Token you will GIVE + buyToken: "0xWETH...", // Token you will RECEIVE + mode: "BuyUpTo", // BuyExact | BuyUpTo | SpendExact | SpendUpTo + amount: "10", // Target amount (buy tokens for buy modes, sell tokens for spend modes) + priceCap: "1.2", // Maximum price (sell per 1 buy) }; const takeResult = await client.getTakeOrdersCalldata(request); if (takeResult.error) throw new Error(takeResult.error.readableMsg); const { - raindex, // Contract address to call - calldata, // ABI-encoded takeOrders4 calldata + raindex, // Contract address to call + calldata, // ABI-encoded takeOrders4 calldata effectivePrice, // Blended price from simulation - prices, // Per-leg ratios (best to worst) - expectedSell, // Simulated sell amount at current quotes - maxSellCap // Worst-case spend cap + prices, // Per-leg ratios (best to worst) + expectedSell, // Simulated sell amount at current quotes + maxSellCap, // Worst-case spend cap } = takeResult.value; ``` **Take order modes:** -- `BuyExact` – Buy exactly `amount` of buy token (reverts if insufficient liquidity) + +- `BuyExact` – Buy exactly `amount` of buy token (reverts if insufficient + liquidity) - `BuyUpTo` – Buy up to `amount` of buy token (partial fills allowed) -- `SpendExact` – Spend exactly `amount` of sell token (reverts if insufficient liquidity) +- `SpendExact` – Spend exactly `amount` of sell token (reverts if insufficient + liquidity) - `SpendUpTo` – Spend up to `amount` of sell token (partial fills allowed) #### Take a specific order -When you already have a `RaindexOrder` instance, use `order.getTakeCalldata()` to target that specific order: +When you already have a `RaindexOrder` instance, use `order.getTakeCalldata()` +to target that specific order: ```ts const order = orders[0]; const takeResult = await order.getTakeCalldata( - 0, // inputIndex - index in order's validInputs array - 0, // outputIndex - index in order's validOutputs array - '0xTaker...', // taker address - 'BuyUpTo', // mode - '10', // amount - '1.2' // priceCap + 0, // inputIndex - index in order's validInputs array + 0, // outputIndex - index in order's validOutputs array + "0xTaker...", // taker address + "BuyUpTo", // mode + "10", // amount + "1.2", // priceCap ); if (takeResult.error) throw new Error(takeResult.error.readableMsg); -const { calldata, raindex, effectivePrice, expectedSell, maxSellCap } = takeResult.value; +const { calldata, raindex, effectivePrice, expectedSell, maxSellCap } = + takeResult.value; ``` #### Estimate take order amounts @@ -465,15 +544,15 @@ const quote = quotesResult.value[0]; // Pick the quote for your desired pair const estimateResult = order.estimateTakeOrder( quote, - true, // isBuy - true for buying output token, false for selling input token - '10' // amount as decimal string + true, // isBuy - true for buying output token, false for selling input token + "10", // amount as decimal string ); if (estimateResult.error) throw new Error(estimateResult.error.readableMsg); const { - expectedSpend, // How much sell token you'll give + expectedSpend, // How much sell token you'll give expectedReceive, // How much buy token you'll get - isPartial // True if order can't fully fill your amount + isPartial, // True if order can't fully fill your amount } = estimateResult.value; ``` @@ -482,16 +561,19 @@ const { Use directional token filters to find orders matching specific trading pairs: ```ts -import type { GetOrdersFilters, GetOrdersTokenFilter } from '@rainlanguage/raindex'; +import type { + GetOrdersFilters, + GetOrdersTokenFilter, +} from "@rainlanguage/raindex"; const tokenFilter: GetOrdersTokenFilter = { - inputs: ['0xUSDC...'], // Orders that accept USDC as input - outputs: ['0xWETH...'] // Orders that output WETH + inputs: ["0xUSDC..."], // Orders that accept USDC as input + outputs: ["0xWETH..."], // Orders that output WETH }; const filters: GetOrdersFilters = { tokens: tokenFilter, - active: true + active: true, }; const ordersResult = await client.getOrders([137], filters, 1); @@ -501,12 +583,15 @@ const ordersResult = await client.getOrders([137], filters, 1); ### Load remote strategies with `DotrainRegistry` -If you maintain a hosted registry, instantiate the helper, inspect what it exposes, and pull down any dotrain/builder definitions you need: +If you maintain a hosted registry, instantiate the helper, inspect what it +exposes, and pull down any dotrain/builder definitions you need: ```ts -import { DotrainRegistry } from '@rainlanguage/raindex'; +import { DotrainRegistry } from "@rainlanguage/raindex"; -const registryResult = await DotrainRegistry.new('https://example.com/registry.txt'); +const registryResult = await DotrainRegistry.new( + "https://example.com/registry.txt", +); if (registryResult.error) throw new Error(registryResult.error.readableMsg); const registry = registryResult.value; @@ -515,8 +600,10 @@ if (orderMenuResult.error) throw new Error(orderMenuResult.error.readableMsg); const orderMenu = orderMenuResult.value.valid; // Map const invalidOrders = orderMenuResult.value.invalid; // Map -const deploymentsResult = registry.getDeploymentDetails('fixed-limit'); -if (deploymentsResult.error) throw new Error(deploymentsResult.error.readableMsg); +const deploymentsResult = registry.getDeploymentDetails("fixed-limit"); +if (deploymentsResult.error) { + throw new Error(deploymentsResult.error.readableMsg); +} const deployments = deploymentsResult.value; ``` @@ -528,15 +615,19 @@ fixed-limit https://example.com/orders/fixed-limit.rain dca https://example.com/orders/dca.rain ``` -The SDK merges the shared settings YAML with each order's `.rain` content before you ever build an order builder. +The SDK merges the shared settings YAML with each order's `.rain` content before +you ever build an order builder. #### Access tokens from registry settings -Use `getRaindexYaml()` to access the shared settings as an `RaindexYaml` instance, then query tokens, networks, or raindexes: +Use `getRaindexYaml()` to access the shared settings as an `RaindexYaml` +instance, then query tokens, networks, or raindexes: ```ts const raindexYamlResult = registry.getRaindexYaml(); -if (raindexYamlResult.error) throw new Error(raindexYamlResult.error.readableMsg); +if (raindexYamlResult.error) { + throw new Error(raindexYamlResult.error.readableMsg); +} const raindexYaml = raindexYamlResult.value; const tokensResult = await raindexYaml.getTokens(); @@ -546,7 +637,8 @@ const tokens = tokensResult.value; // TokenInfo[] with chain_id, address, decima #### Get a RaindexClient from registry settings -Use `getRaindexClient()` to create a `RaindexClient` directly from the registry's shared settings, without manually bridging through `RaindexYaml`: +Use `getRaindexClient()` to create a `RaindexClient` directly from the +registry's shared settings, without manually bridging through `RaindexYaml`: ```ts const clientResult = registry.getRaindexClient(); @@ -559,12 +651,20 @@ const ordersResult = await client.getOrders([8453]); ### Build a deployment order builder -Any dotrain file that includes a `builder:` block plus the usual settings YAML is enough to drive `RaindexOrderBuilder`. The `FIXED_LIMIT_SOURCE` constant declared earlier already includes the required networks/tokens/deployers plus a full `builder` definition, so you can reference it directly (or trim it to your own bindings) instead of copying pieces of `settings.yaml` inline in this guide. Always cross-check the source you feed in with the latest definitions in [rainlanguage/rain.strategies](https://github.com/rainlanguage/rain.strategies); that repository tracks the real configurations our UI ships with. +Any dotrain file that includes a `builder:` block plus the usual settings YAML +is enough to drive `RaindexOrderBuilder`. The `FIXED_LIMIT_SOURCE` constant +declared earlier already includes the required networks/tokens/deployers plus a +full `builder` definition, so you can reference it directly (or trim it to your +own bindings) instead of copying pieces of `settings.yaml` inline in this guide. +Always cross-check the source you feed in with the latest definitions in +[rainlanguage/rain.strategies](https://github.com/rainlanguage/rain.strategies); +that repository tracks the real configurations our UI ships with. -With that single source string (read from disk or built dynamically) you can drive the full order builder workflow: +With that single source string (read from disk or built dynamically) you can +drive the full order builder workflow: ```ts -import { RaindexOrderBuilder } from '@rainlanguage/raindex'; +import { RaindexOrderBuilder } from "@rainlanguage/raindex"; const dotrainWithBuilder = FIXED_LIMIT_SOURCE; const SAMPLE_YAML = ` @@ -578,20 +678,22 @@ raindexes: address: 0x... network: mainnet ... -` +`; const additionalSettings = [SAMPLE_YAML]; // optional extra YAML strings const deploymentsResult = await RaindexOrderBuilder.getDeploymentKeys( dotrainWithBuilder, - additionalSettings + additionalSettings, ); -if (deploymentsResult.error) throw new Error(deploymentsResult.error.readableMsg); +if (deploymentsResult.error) { + throw new Error(deploymentsResult.error.readableMsg); +} const [firstDeployment] = deploymentsResult.value; const builderResult = await RaindexOrderBuilder.newWithDeployment( dotrainWithBuilder, additionalSettings, - firstDeployment + firstDeployment, ); if (builderResult.error) throw new Error(builderResult.error.readableMsg); const builder = builderResult.value; @@ -601,36 +703,55 @@ if (configResult.error) throw new Error(configResult.error.readableMsg); const config = configResult.value; const selectTokensResult = builder.getSelectTokens(); -if (selectTokensResult.error) throw new Error(selectTokensResult.error.readableMsg); +if (selectTokensResult.error) { + throw new Error(selectTokensResult.error.readableMsg); +} const selectTokens = selectTokensResult.value; const depositsResult = builder.getDeposits(); if (depositsResult.error) throw new Error(depositsResult.error.readableMsg); const deposits = depositsResult.value; -await builder.setSelectToken('input-token', '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'); // USDC -await builder.setSelectToken('output-token', '0x4200000000000000000000000000000000000006'); // WETH -const fieldResult = builder.setFieldValue('fixed-io', '1850'); +await builder.setSelectToken( + "input-token", + "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", +); // USDC +await builder.setSelectToken( + "output-token", + "0x4200000000000000000000000000000000000006", +); // WETH +const fieldResult = builder.setFieldValue("fixed-io", "1850"); if (fieldResult.error) throw new Error(fieldResult.error.readableMsg); -const amountResult = builder.setFieldValue('amount-per-trade', '250'); +const amountResult = builder.setFieldValue("amount-per-trade", "250"); if (amountResult.error) throw new Error(amountResult.error.readableMsg); -await builder.setDeposit('usdc', '5000'); -const vaultIdResult = builder.setVaultId('input', 'usdc', '42'); +await builder.setDeposit("usdc", "5000"); +const vaultIdResult = builder.setVaultId("input", "usdc", "42"); if (vaultIdResult.error) throw new Error(vaultIdResult.error.readableMsg); -const allowancesResult = await builder.checkAllowances('0xOwner'); +const allowancesResult = await builder.checkAllowances("0xOwner"); if (allowancesResult.error) throw new Error(allowancesResult.error.readableMsg); const allowances = allowancesResult.value; -const approvalCalldatasResult = await builder.generateApprovalCalldatas('0xOwner'); -if (approvalCalldatasResult.error) throw new Error(approvalCalldatasResult.error.readableMsg); +const approvalCalldatasResult = await builder.generateApprovalCalldatas( + "0xOwner", +); +if (approvalCalldatasResult.error) { + throw new Error(approvalCalldatasResult.error.readableMsg); +} const depositCalldatasResult = await builder.generateDepositCalldatas(); -if (depositCalldatasResult.error) throw new Error(depositCalldatasResult.error.readableMsg); +if (depositCalldatasResult.error) { + throw new Error(depositCalldatasResult.error.readableMsg); +} -const deploymentArgsResult = await builder.getDeploymentTransactionArgs('0xOwner'); -if (deploymentArgsResult.error) throw new Error(deploymentArgsResult.error.readableMsg); -const { approvals, deploymentCalldata, raindexAddress, chainId } = deploymentArgsResult.value; +const deploymentArgsResult = await builder.getDeploymentTransactionArgs( + "0xOwner", +); +if (deploymentArgsResult.error) { + throw new Error(deploymentArgsResult.error.readableMsg); +} +const { approvals, deploymentCalldata, raindexAddress, chainId } = + deploymentArgsResult.value; const rainlangResult = await builder.getComposedRainlang(); if (rainlangResult.error) throw new Error(rainlangResult.error.readableMsg); @@ -638,18 +759,23 @@ const composedRainlang = rainlangResult.value; const serializedStateResult = builder.serializeState(); if (!serializedStateResult.error) { - localStorage.setItem('fixed-limit-state', serializedStateResult.value); + localStorage.setItem("fixed-limit-state", serializedStateResult.value); } ``` -Serialize the builder state and later revive it with `RaindexOrderBuilder.newFromState(dotrainText, additionalSettings, serializedState, callback)` if you want to skip re-entering form choices. +Serialize the builder state and later revive it with +`RaindexOrderBuilder.newFromState(dotrainText, additionalSettings, serializedState, callback)` +if you want to skip re-entering form choices. #### Deploy with wallet + fetch your order -`builder.getDeploymentTransactionArgs(owner)` returns a `DeploymentTransactionArgs` struct with: +`builder.getDeploymentTransactionArgs(owner)` returns a +`DeploymentTransactionArgs` struct with: -- `approvals: ExtendedApprovalCalldata[]` (each item contains `token`, `calldata`, and the token `symbol` for UX) -- `deploymentCalldata: Hex` – a multicall that performs deposits (if required) and adds the order in one transaction +- `approvals: ExtendedApprovalCalldata[]` (each item contains `token`, + `calldata`, and the token `symbol` for UX) +- `deploymentCalldata: Hex` – a multicall that performs deposits (if required) + and adds the order in one transaction - `raindexAddress: string` – destination for the multicall - `chainId: number` – network you must connect your wallet to @@ -658,41 +784,54 @@ A typical deployment flow is: 1. Run `getDeploymentTransactionArgs` 2. Submit every approval in series (skip when `approvals` is empty) 3. Submit the deployment calldata -4. Poll `client.getAddOrdersForTransaction` (the helper shown earlier) with the deployment hash until the subgraph surfaces your `RaindexOrder` +4. Poll `client.getAddOrdersForTransaction` (the helper shown earlier) with the + deployment hash until the subgraph surfaces your `RaindexOrder` ```ts -import type { RaindexClient } from '@rainlanguage/raindex'; +import type { RaindexClient } from "@rainlanguage/raindex"; const deploymentArgsResult = await builder.getDeploymentTransactionArgs(owner); -if (deploymentArgsResult.error) throw new Error(deploymentArgsResult.error.readableMsg); -const { approvals, deploymentCalldata, raindexAddress, chainId } = deploymentArgsResult.value; +if (deploymentArgsResult.error) { + throw new Error(deploymentArgsResult.error.readableMsg); +} +const { approvals, deploymentCalldata, raindexAddress, chainId } = + deploymentArgsResult.value; // Assume sendTransaction({ to, data }) and waitForReceipt(hash) come from your wallet stack. for (const approval of approvals) { - const approvalHash = await sendTransaction({ to: approval.token, data: approval.calldata }); + const approvalHash = await sendTransaction({ + to: approval.token, + data: approval.calldata, + }); await waitForReceipt(approvalHash); } -const deploymentHash = await sendTransaction({ to: raindexAddress, data: deploymentCalldata }); +const deploymentHash = await sendTransaction({ + to: raindexAddress, + data: deploymentCalldata, +}); await waitForReceipt(deploymentHash); const raindexOrder = await waitForOrderFromTx(client as RaindexClient, { chainId, raindexAddress, - txHash: deploymentHash + txHash: deploymentHash, }); ``` -After you have a local dotrain source, you can also fetch equivalent sources from a registry and run the same flow: +After you have a local dotrain source, you can also fetch equivalent sources +from a registry and run the same flow: ```ts -import { DotrainRegistry } from '@rainlanguage/raindex'; +import { DotrainRegistry } from "@rainlanguage/raindex"; -const registryResult = await DotrainRegistry.new('https://example.com/registry.txt'); +const registryResult = await DotrainRegistry.new( + "https://example.com/registry.txt", +); if (registryResult.error) throw new Error(registryResult.error.readableMsg); const registry = registryResult.value; -const builderResult = await registry.getOrderBuilder('fixed-limit', 'base'); +const builderResult = await registry.getOrderBuilder("fixed-limit", "base"); if (builderResult.error) throw new Error(builderResult.error.readableMsg); const builderFromRegistry = builderResult.value; @@ -702,36 +841,59 @@ const builderFromRegistry = builderResult.value; ### Work directly with dotrain files -If you just need Rainlang composition (no builder state), read the dotrain text plus shared settings yourself, instantiate a `DotrainOrder`, and then ask it to compose scenario/deployment/post-task Rainlang. The example below reuses `FIXED_LIMIT_SOURCE`, but you can replace it with the contents of any `.rain` file. +If you just need Rainlang composition (no builder state), read the dotrain text +plus shared settings yourself, instantiate a `DotrainOrder`, and then ask it to +compose scenario/deployment/post-task Rainlang. The example below reuses +`FIXED_LIMIT_SOURCE`, but you can replace it with the contents of any `.rain` +file. ```ts -import { DotrainOrder } from '@rainlanguage/raindex'; +import { DotrainOrder } from "@rainlanguage/raindex"; -const dotrainResult = await DotrainOrder.create(FIXED_LIMIT_SOURCE, [RAINDEX_SETTINGS]); +const dotrainResult = await DotrainOrder.create(FIXED_LIMIT_SOURCE, [ + RAINDEX_SETTINGS, +]); if (dotrainResult.error) throw new Error(dotrainResult.error.readableMsg); const dotrain = dotrainResult.value; -const scenarioResult = await dotrain.composeScenarioToRainlang('backtest'); +const scenarioResult = await dotrain.composeScenarioToRainlang("backtest"); if (!scenarioResult.error) console.log(scenarioResult.value); -const deploymentResult = await dotrain.composeDeploymentToRainlang('flare-prod'); +const deploymentResult = await dotrain.composeDeploymentToRainlang( + "flare-prod", +); if (!deploymentResult.error) console.log(deploymentResult.value); -const postTaskResult = await dotrain.composeScenarioToPostTaskRainlang('flare-prod'); +const postTaskResult = await dotrain.composeScenarioToPostTaskRainlang( + "flare-prod", +); if (!postTaskResult.error) console.log(postTaskResult.value); ``` ## Utility exports -- `getOrderHash`, `keccak256`, `keccak256HexString` – deterministic hashing helpers for Rain orders or arbitrary payloads. -- `Float` – arbitrary-precision arithmetic with parsing, formatting, comparisons, math ops, fixed-decimal conversions, and helpers like `Float.zero()` or `.formatWithRange(...)`. -- `RaindexYaml.getTokens()` – async method returning all tokens from YAML configuration with `chain_id`, `address`, `decimals`, `symbol`, and `name`. Automatically fetches remote tokens from `using-tokens-from` URLs. -- `RaindexClient.getAllAccounts()` / `getAllVaultTokens()` – introspect accounts and ERC20 metadata defined in your YAML or discovered via subgraphs. -- Local DB sync – pass `queryCallback`, `wipeCallback`, and `statusCallback` to `RaindexClient.new()` when YAML has `local-db-sync` sections to enable an offline-capable persistent cache. The scheduler starts automatically and queries route to the local DB once the first sync cycle completes. -- `RaindexVaultsList.getWithdrawCalldata()` – multicall builder that withdraws every vault with a balance. -- `RaindexOrder.convertToSgOrder()` – convert WASM order representations back into the raw subgraph schema when you need to interop with other tooling. -- `TakeOrdersRequest`, `TakeOrdersCalldataResult`, `TakeOrderEstimate` – types for the take orders API. -- `GetOrdersTokenFilter` – directional token filter with `inputs` and `outputs` arrays for precise order discovery. +- `getOrderHash`, `keccak256`, `keccak256HexString` – deterministic hashing + helpers for Rain orders or arbitrary payloads. +- `Float` – arbitrary-precision arithmetic with parsing, formatting, + comparisons, math ops, fixed-decimal conversions, and helpers like + `Float.zero()` or `.formatWithRange(...)`. +- `RaindexYaml.getTokens()` – async method returning all tokens from YAML + configuration with `chain_id`, `address`, `decimals`, `symbol`, and `name`. + Automatically fetches remote tokens from `using-tokens-from` URLs. +- `RaindexClient.getAllAccounts()` / `getAllVaultTokens()` – introspect accounts + and ERC20 metadata defined in your YAML or discovered via subgraphs. +- Local DB sync – pass `queryCallback`, `wipeCallback`, and `statusCallback` to + `RaindexClient.new()` when YAML has `local-db-sync` sections to enable an + offline-capable persistent cache. The scheduler starts automatically and + queries route to the local DB once the first sync cycle completes. +- `RaindexVaultsList.getWithdrawCalldata()` – multicall builder that withdraws + every vault with a balance. +- `RaindexOrder.convertToSgOrder()` – convert WASM order representations back + into the raw subgraph schema when you need to interop with other tooling. +- `TakeOrdersRequest`, `TakeOrdersCalldataResult`, `TakeOrderEstimate` – types + for the take orders API. +- `GetOrdersTokenFilter` – directional token filter with `inputs` and `outputs` + arrays for precise order discovery. ## Error handling pattern @@ -742,9 +904,9 @@ type WasmEncodedResult = | { value: T; error: undefined } | { value: undefined; error: { msg: string; readableMsg: string } }; -const result = await client.getVault(14, '0xRaindex', '0x01'); +const result = await client.getVault(14, "0xRaindex", "0x01"); if (result.error) { - console.error('Vault lookup failed:', result.error.readableMsg); + console.error("Vault lookup failed:", result.error.readableMsg); return; } console.log(result.value); @@ -752,4 +914,5 @@ console.log(result.value); ## Contributing -This SDK is part of the Rain Language ecosystem. For contributions and issues, please visit the [GitHub repository](https://github.com/rainlanguage/raindex). +This SDK is part of the Rain Language ecosystem. For contributions and issues, +please visit the [GitHub repository](https://github.com/rainlanguage/raindex). diff --git a/packages/ui-components/ARCHITECTURE.md b/packages/ui-components/ARCHITECTURE.md index c489f6dd5a..0b0351d036 100644 --- a/packages/ui-components/ARCHITECTURE.md +++ b/packages/ui-components/ARCHITECTURE.md @@ -1,21 +1,31 @@ # @rainlanguage/ui-components — Architecture -This package is the reusable Svelte component library for building Rain Raindex UIs. It composes the WASM‑backed SDK `@rainlanguage/raindex` with UI primitives, domain components, providers, hooks, and utilities to implement common flows: listing and inspecting orders and vaults, showing charts, handling wallet connection and transactions, and guiding users through deploying algorithmic orders from a dotrain registry. - +This package is the reusable Svelte component library for building Rain Raindex +UIs. It composes the WASM‑backed SDK `@rainlanguage/raindex` with UI primitives, +domain components, providers, hooks, and utilities to implement common flows: +listing and inspecting orders and vaults, showing charts, handling wallet +connection and transactions, and guiding users through deploying algorithmic +orders from a dotrain registry. ## Overview - Purpose - - Provide a cohesive, app‑ready set of Svelte components and helpers for Raindex features: tables, detail views, charts, deployment builder, toasts, and transaction UX. - - Ship provider and hook contexts so apps can wire wallet, client, registry, toasts, and transaction state consistently. + - Provide a cohesive, app‑ready set of Svelte components and helpers for + Raindex features: tables, detail views, charts, deployment builder, toasts, + and transaction UX. + - Ship provider and hook contexts so apps can wire wallet, client, registry, + toasts, and transaction state consistently. - Targets - - Svelte 4 components, packaged with `svelte-package` for consumption in SvelteKit/Vite apps. - - Single `dist/index.js` entry (ESM) with `svelte` and `types` fields; no SSR‑specific code required. + - Svelte 4 components, packaged with `svelte-package` for consumption in + SvelteKit/Vite apps. + - Single `dist/index.js` entry (ESM) with `svelte` and `types` fields; no + SSR‑specific code required. - Upstream libraries - SDK: `@rainlanguage/raindex` (WASM) - State/query: `@tanstack/svelte-query` - Wallet: `wagmi`, `viem`, `@reown/appkit` + `@reown/appkit-adapter-wagmi` - - UI: `flowbite-svelte` (+ icons), `tailwindcss`, `lightweight-charts`, `svelte-markdown`, `svelte-codemirror-editor`, `codemirror-rainlang` + - UI: `flowbite-svelte` (+ icons), `tailwindcss`, `lightweight-charts`, + `svelte-markdown`, `svelte-codemirror-editor`, `codemirror-rainlang` Typical development @@ -24,87 +34,117 @@ cd packages/ui-components nix develop -c npm run dev ``` - ## Providers & State -The library exposes lightweight provider components that set Svelte contexts, plus hooks to access them: +The library exposes lightweight provider components that set Svelte contexts, +plus hooks to access them: - Raindex client - - `RaindexClientProvider` — sets a `RaindexClient` from `@rainlanguage/raindex` in context. - - `useRaindexClient()` — retrieves the client and reports a user‑facing error if missing. + - `RaindexClientProvider` — sets a `RaindexClient` from + `@rainlanguage/raindex` in context. + - `useRaindexClient()` — retrieves the client and reports a user‑facing error + if missing. - Wallet - - `WalletProvider` — injects a Svelte `Readable` account store into context. + - `WalletProvider` — injects a Svelte `Readable` account store + into context. - `useAccount()` — returns the account store from context. - Transactions - - `TransactionProvider` — constructs a `TransactionManager` using TanStack Query’s `QueryClient` (via `useQueryClient()`), a `wagmi` `Config`, and an `addToast` function. - - `useTransactions()` — returns `{ manager, transactions }`, where `transactions` is a store of in‑flight `TransactionStore` instances. - - UI components: `TransactionList`, `FixedBottomTransaction` to surface status, errors, and explorer links. + - `TransactionProvider` — constructs a `TransactionManager` using TanStack + Query’s `QueryClient` (via `useQueryClient()`), a `wagmi` `Config`, and an + `addToast` function. + - `useTransactions()` — returns `{ manager, transactions }`, where + `transactions` is a store of in‑flight `TransactionStore` instances. + - UI components: `TransactionList`, `FixedBottomTransaction` to surface + status, errors, and explorer links. - Registry - - `RegistryProvider` + `RegistryManager` — manage dotrain registry URL (persisted in `localStorage` and an optional `?registry=` query param). `useRegistry()` returns the manager. + - `RegistryProvider` + `RegistryManager` — manage dotrain registry URL + (persisted in `localStorage` and an optional `?registry=` query param). + `useRegistry()` returns the manager. - Toasts - - `ToastProvider` — provides a toasts store and renders `ToastDetail` instances. + - `ToastProvider` — provides a toasts store and renders `ToastDetail` + instances. - `useToasts()` — returns `{ toasts, addToast, removeToast, errToast }`. - Builder (deploy flows) - - `RaindexOrderBuilderProvider` — provides a `RaindexOrderBuilder` instance for deployment flows. - - `useRaindexOrderBuilder()` — retrieves the builder instance; integrates with deployment components. + - `RaindexOrderBuilderProvider` — provides a `RaindexOrderBuilder` instance + for deployment flows. + - `useRaindexOrderBuilder()` — retrieves the builder instance; integrates with + deployment components. Notes -- Consumers should wrap their app in a TanStack Query `QueryClientProvider` (from `@tanstack/svelte-query`) so `TransactionProvider` can access the client. -- `TransactionProvider` requires an `addToast` callback. A small “wrapper” component that calls `useToasts()` is a convenient way to pass this down. - +- Consumers should wrap their app in a TanStack Query `QueryClientProvider` + (from `@tanstack/svelte-query`) so `TransactionProvider` can access the + client. +- `TransactionProvider` requires an `addToast` callback. A small “wrapper” + component that calls `useToasts()` is a convenient way to pass this down. ## Components & Features - Tables & lists - - `OrdersListTable`, `OrderTradesListTable`, `VaultsListTable`, `VaultBalanceChangesTable`, `OrderVaultsVolTable` driven by TanStack Query, with `TanstackAppTable` wrapper. + - `OrdersListTable`, `OrderTradesListTable`, `VaultsListTable`, + `VaultBalanceChangesTable`, `OrderVaultsVolTable` driven by TanStack Query, + with `TanstackAppTable` wrapper. - Detail views & quotes - - `OrderDetail`, `VaultDetail`, `TanstackOrderQuote`, `TanstackPageContentDetail`, `Hash`, `OrderOrVaultHash`. + - `OrderDetail`, `VaultDetail`, `TanstackOrderQuote`, + `TanstackPageContentDetail`, `Hash`, `OrderOrVaultHash`. - Charts - - `LightweightChart`, `TanstackLightweightChartLine`, `OrderTradesChart`, `VaultBalanceChart` with time helpers and themes. + - `LightweightChart`, `TanstackLightweightChartLine`, `OrderTradesChart`, + `VaultBalanceChart` with time helpers and themes. - Deployment Builder - - `OrderPage`, `DeploymentsSection`, `DeploymentSteps`, `TokenIOInput`, `FieldDefinitionInput`, `SelectToken`, `DisclaimerModal`, `ValidOrdersSection`, `InvalidOrdersSection`. - - Services: dotrain registry fetch/validate/share (`registry.ts`, `loadRegistryUrl.ts`, `handleShareChoices.ts`). + - `OrderPage`, `DeploymentsSection`, `DeploymentSteps`, `TokenIOInput`, + `FieldDefinitionInput`, `SelectToken`, `DisclaimerModal`, + `ValidOrdersSection`, `InvalidOrdersSection`. + - Services: dotrain registry fetch/validate/share (`registry.ts`, + `loadRegistryUrl.ts`, `handleShareChoices.ts`). - Wallet UX & general UI - - `WalletConnect`, `ButtonDarkMode`, dropdowns, inputs (`InputTokenAmount`, `InputHex`, `InputOrderHash`, `InputRegistryUrl`), tooltips, badges, icons. + - `WalletConnect`, `ButtonDarkMode`, dropdowns, inputs (`InputTokenAmount`, + `InputHex`, `InputOrderHash`, `InputRegistryUrl`), tooltips, badges, icons. - Editors - `CodeMirrorRainlang`, `CodeMirrorDotrain` with theme helpers. - ## Services, Utils, Queries - Time & indexing - - `awaitTransactionIndexing` — generic polling helper to await subgraph indexing with success predicate; used by `TransactionStore`. - - `formatTimestampSecondsAsLocal`, `timestampSecondsToUTCTimestamp`, `promiseTimeout`, `dateTimestamp`. + - `awaitTransactionIndexing` — generic polling helper to await subgraph + indexing with success predicate; used by `TransactionStore`. + - `formatTimestampSecondsAsLocal`, `timestampSecondsToUTCTimestamp`, + `promiseTimeout`, `dateTimestamp`. - Links & formatting - - `getExplorerLink` (via `viem/chains`), `bigintStringToHex`, numeric/string utilities. + - `getExplorerLink` (via `viem/chains`), `bigintStringToHex`, numeric/string + utilities. - Registry - - `fetchParseRegistry`, `fetchRegistryDotrains`, `validateOrders`, `loadRegistryUrl`. + - `fetchParseRegistry`, `fetchRegistryDotrains`, `validateOrders`, + `loadRegistryUrl`. - Charts - `historicalOrderCharts.ts` for transforming trades to chartable data. - Queries - - `queries/constants.ts`, `queries/keys.ts`, `queries/queryClient.ts` (includes `invalidateTanstackQueries`). - + - `queries/constants.ts`, `queries/keys.ts`, `queries/queryClient.ts` + (includes `invalidateTanstackQueries`). ## Exports & API Surface `src/lib/index.ts` re‑exports by category: -- Components: tables, detail views, charts, editors, inputs, icons, wallet/connectivity, UI primitives. -- Providers: `RaindexOrderBuilderProvider`, `RaindexClientProvider`, `WalletProvider`, `RegistryProvider`, `ToastProvider`, `TransactionProvider`. -- Hooks: `useRaindexOrderBuilder`, `useRaindexClient`, `useAccount`, `useRegistry`, `useToasts`, `useTransactions`. +- Components: tables, detail views, charts, editors, inputs, icons, + wallet/connectivity, UI primitives. +- Providers: `RaindexOrderBuilderProvider`, `RaindexClientProvider`, + `WalletProvider`, `RegistryProvider`, `ToastProvider`, `TransactionProvider`. +- Hooks: `useRaindexOrderBuilder`, `useRaindexClient`, `useAccount`, + `useRegistry`, `useToasts`, `useTransactions`. - Types: app stores, modal/transaction/toast/order typings. -- Functions: time helpers, explorer link, TanStack invalidation helpers, mocks for tests. +- Functions: time helpers, explorer link, TanStack invalidation helpers, mocks + for tests. - Constants: query keys, default page sizes/intervals, chart/code editor themes. - Stores: cached writable store helpers. - Assets: light/dark logos. - Classes: `RegistryManager`, `TransactionStore`, `TransactionManager`. - ## Directory Layout -- `src/lib/components/` — Svelte components grouped by domain (`tables`, `detail`, `charts`, `deployment`, `transactions`, `wallet`, `input`, etc.). -- `src/lib/providers/` — Context providers for builder, client, wallet, registry, toasts, transactions. +- `src/lib/components/` — Svelte components grouped by domain (`tables`, + `detail`, `charts`, `deployment`, `transactions`, `wallet`, `input`, etc.). +- `src/lib/providers/` — Context providers for builder, client, wallet, + registry, toasts, transactions. - `src/lib/hooks/` — Accessors for provider contexts. - `src/lib/models/` — State models such as `TransactionStore`. - `src/lib/types/` — Type helpers and enums. @@ -114,54 +154,64 @@ Notes - `src/lib/assets/` — SVGs, logos. - `src/lib/__mocks__/` — Test helpers and resolvable queries/stores. - ## Build, Test, and Dev Run inside a Nix shell for tool parity (`nix develop -c `): - Dev preview: `nix develop -c npm run dev` -- Build: `nix develop -c npm run build` (Vite) and `npm run package` (svelte‑package + publint) +- Build: `nix develop -c npm run build` (Vite) and `npm run package` + (svelte‑package + publint) - Package only: `nix develop -c npm run package` - Lint/format/check: `npm run format`, `npm run lint`, `npm run check` - Tests: `nix develop -c npm run test` (Vitest, jsdom) - ## Usage Notes - Provider wiring - - Wrap your app in `QueryClientProvider`, then add `ToastProvider`, `WalletProvider`, `RaindexClientProvider`, `RegistryProvider`, and a small wrapper for `TransactionProvider` that supplies `addToast` from `useToasts()` and a `wagmi` `Config`. - - See `packages/webapp` for a working composition with a fixed‑bottom transaction status bar. + - Wrap your app in `QueryClientProvider`, then add `ToastProvider`, + `WalletProvider`, `RaindexClientProvider`, `RegistryProvider`, and a small + wrapper for `TransactionProvider` that supplies `addToast` from + `useToasts()` and a `wagmi` `Config`. + - See `packages/webapp` for a working composition with a fixed‑bottom + transaction status bar. - Tailwind setup - - Ensure Tailwind’s `content` globs include this package and `flowbite-svelte` so styles tree‑shake correctly. Example (from the webapp): + - Ensure Tailwind’s `content` globs include this package and `flowbite-svelte` + so styles tree‑shake correctly. Example (from the webapp): ```ts // tailwind.config.ts (consumer app) export default { content: [ - './src/**/*.{html,js,svelte,ts}', - '../../node_modules/flowbite-svelte/**/*.{html,js,svelte,ts}', - '../../node_modules/@rainlanguage/ui-components/**/*.{html,js,svelte,ts}', - '../ui-components/**/*.{html,js,svelte,ts}', + "./src/**/*.{html,js,svelte,ts}", + "../../node_modules/flowbite-svelte/**/*.{html,js,svelte,ts}", + "../../node_modules/@rainlanguage/ui-components/**/*.{html,js,svelte,ts}", + "../ui-components/**/*.{html,js,svelte,ts}", ], // ... -} +}; ``` - ## How It Fits The Workspace -- Rust crates under `crates/*` implement core logic and compile to a WASM surface consumed by `@rainlanguage/raindex`. -- `@rainlanguage/ui-components` provides the reusable Svelte UI and provider layer that apps compose. -- The `packages/webapp` project consumes this library directly to implement the full Raindex UI. - +- Rust crates under `crates/*` implement core logic and compile to a WASM + surface consumed by `@rainlanguage/raindex`. +- `@rainlanguage/ui-components` provides the reusable Svelte UI and provider + layer that apps compose. +- The `packages/webapp` project consumes this library directly to implement the + full Raindex UI. ## Caveats & Tips - Always run inside `nix develop` for consistent Node/tooling. -- Ensure the Query Client is available in context before mounting `TransactionProvider`. -- Pass a valid `wagmi` `Config` to `TransactionProvider` and ensure wallet connectors are initialized at the app level. +- Ensure the Query Client is available in context before mounting + `TransactionProvider`. +- Pass a valid `wagmi` `Config` to `TransactionProvider` and ensure wallet + connectors are initialized at the app level. - Include this package in Tailwind `content` globs to avoid missing styles. -- For deployment flows, pass a `RaindexOrderBuilder` via `RaindexOrderBuilderProvider` and use the registry helpers to load/validate dotrain entries. - -This document explains what `packages/ui-components` is for, how providers and components are organized, how to build and test the package, and how it integrates with the rest of the Rain Raindex workspace. +- For deployment flows, pass a `RaindexOrderBuilder` via + `RaindexOrderBuilderProvider` and use the registry helpers to load/validate + dotrain entries. +This document explains what `packages/ui-components` is for, how providers and +components are organized, how to build and test the package, and how it +integrates with the rest of the Rain Raindex workspace. diff --git a/packages/ui-components/README.md b/packages/ui-components/README.md index 16c70df2c8..e43d8ecb8b 100644 --- a/packages/ui-components/README.md +++ b/packages/ui-components/README.md @@ -1,8 +1,10 @@ # create-svelte -Everything you need to build a Svelte library, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/main/packages/create-svelte). +Everything you need to build a Svelte library, powered by +[`create-svelte`](https://github.com/sveltejs/kit/tree/main/packages/create-svelte). -Read more about creating a library [in the docs](https://svelte.dev/docs/kit/packaging). +Read more about creating a library +[in the docs](https://svelte.dev/docs/kit/packaging). ## Creating a project @@ -18,7 +20,8 @@ npx sv create my-app ## Developing -Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: +Once you've created a project and installed dependencies with `npm install` (or +`pnpm install` or `yarn`), start a development server: ```bash npm run dev @@ -27,7 +30,8 @@ npm run dev npm run dev -- --open ``` -Everything inside `src/lib` is part of your library, everything inside `src/routes` can be used as a showcase or preview app. +Everything inside `src/lib` is part of your library, everything inside +`src/routes` can be used as a showcase or preview app. ## Building @@ -45,11 +49,15 @@ npm run build You can preview the production build with `npm run preview`. -> To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment. +> To deploy your app, you may need to install an +> [adapter](https://svelte.dev/docs/kit/adapters) for your target environment. ## Publishing -Go into the `package.json` and give your package the desired name through the `"name"` option. Also consider adding a `"license"` field and point it to a `LICENSE` file which you can create from a template (one popular option is the [MIT license](https://opensource.org/license/mit/)). +Go into the `package.json` and give your package the desired name through the +`"name"` option. Also consider adding a `"license"` field and point it to a +`LICENSE` file which you can create from a template (one popular option is the +[MIT license](https://opensource.org/license/mit/)). To publish your library to [npm](https://www.npmjs.com): diff --git a/packages/webapp/ARCHITECTURE.md b/packages/webapp/ARCHITECTURE.md index ef5195373d..bf444b0457 100644 --- a/packages/webapp/ARCHITECTURE.md +++ b/packages/webapp/ARCHITECTURE.md @@ -1,25 +1,30 @@ # @rainlanguage/webapp — Architecture -This package is the SvelteKit web application for exploring and interacting with Rain Raindex. It composes the `@rainlanguage/ui-components` library with the WASM‑backed SDK `@rainlanguage/raindex` to provide a browser UI for: +This package is the SvelteKit web application for exploring and interacting with +Rain Raindex. It composes the `@rainlanguage/ui-components` library with the +WASM‑backed SDK `@rainlanguage/raindex` to provide a browser UI for: - Browsing orders, trades and vaults across networks - Viewing order detail and performing actions (remove, deposit, withdraw) - Deploying “algorithmic orders” from a dotrain registry via a guided builder - Managing wallet connection and transaction flows - ## Overview - Purpose - - End‑user web UI showcasing Raindex features and the reusable `@rainlanguage/ui-components` surface. - - Loads workspace settings from YAML, initializes a `RaindexClient`, and wires providers for state, wallet and transactions. + - End‑user web UI showcasing Raindex features and the reusable + `@rainlanguage/ui-components` surface. + - Loads workspace settings from YAML, initializes a `RaindexClient`, and wires + providers for state, wallet and transactions. - Targets - Client‑side SvelteKit app (SSR disabled) built with Vite and Tailwind. - Deployed using the Vercel adapter (Node.js 20 runtime). - Upstream libraries - - UI: `@rainlanguage/ui-components`, `flowbite-svelte`, `@tanstack/svelte-query`. + - UI: `@rainlanguage/ui-components`, `flowbite-svelte`, + `@tanstack/svelte-query`. - SDK: `@rainlanguage/raindex` (WASM), `@rainlanguage/float`. - - Wallet: `viem`, `@wagmi/core`, `@reown/appkit` + `@reown/appkit-adapter-wagmi`. + - Wallet: `viem`, `@wagmi/core`, `@reown/appkit` + + `@reown/appkit-adapter-wagmi`. Typical development @@ -28,12 +33,17 @@ cd packages/webapp nix develop -c npm run dev ``` - ## Runtime & State - App bootstrap (`src/routes/+layout.ts`) - - Loads the dotrain registry (`REGISTRY_URL` or `?registry=` override) via the WASM `DotrainRegistry` and constructs a `RaindexClient` from the registry’s shared settings. Construction is a single async call that accepts optional local DB callbacks (`queryCallback`, `wipeCallback`, `statusCallback`); the scheduler starts automatically when `local-db-sync` is configured in the YAML. - - Exposes a set of Svelte stores (selected chains, active accounts, filters, etc.) to child routes. + - Loads the dotrain registry (`REGISTRY_URL` or `?registry=` override) via the + WASM `DotrainRegistry` and constructs a `RaindexClient` from the registry’s + shared settings. Construction is a single async call that accepts optional + local DB callbacks (`queryCallback`, `wipeCallback`, `statusCallback`); the + scheduler starts automatically when `local-db-sync` is configured in the + YAML. + - Exposes a set of Svelte stores (selected chains, active accounts, filters, + etc.) to child routes. - `export const ssr = false;` — the app renders client‑side only. - Layout shell (`src/routes/+layout.svelte`) - Wraps the app with providers: @@ -42,53 +52,68 @@ nix develop -c npm run dev - `QueryClientProvider` (TanStack Query) for data caching - `TransactionProviderWrapper` and `FixedBottomTransaction` for tx UX - `RaindexClientProvider` to pass the initialized client to UI components - - Initializes wallet on mount and surfaces any initialization error to the user. -- Wallet integration (`src/lib/stores/wagmi.ts`, `src/lib/services/handleWalletInitialization.ts`) + - Initializes wallet on mount and surfaces any initialization error to the + user. +- Wallet integration (`src/lib/stores/wagmi.ts`, + `src/lib/services/handleWalletInitialization.ts`) - Configures Wagmi + AppKit with injected and WalletConnect connectors. - Requires `PUBLIC_WALLETCONNECT_PROJECT_ID` (see Configuration below). - - Tracks connection, chain, and signer via Svelte stores and reacts to account changes. + - Tracks connection, chain, and signer via Svelte stores and reacts to account + changes. - Modal orchestration (`src/lib/services/modal.ts`) - - Creates Svelte modals for deposit/withdraw/confirmation and a custom “withdraw all” flow by instantiating components onto `document.body`. - + - Creates Svelte modals for deposit/withdraw/confirmation and a custom + “withdraw all” flow by instantiating components onto `document.body`. ## Routes & Features - `/` — Home. Static copy and getting‑started content via `Homepage.svelte`. - `/orders` - Lists orders via `OrdersListTable` from `@rainlanguage/ui-components`. - - Detail route: `/orders/[chainId]-[raindex]-[orderHash]` displays `OrderDetail` and wires actions: + - Detail route: `/orders/[chainId]-[raindex]-[orderHash]` displays + `OrderDetail` and wires actions: - Remove order - Deposit / Withdraw / Withdraw All to/from vaults - `/vaults` - - Lists vaults using `VaultsListTable`; supports filtering, active accounts, and bulk withdraw. - - Detail route: `/vaults/[chainId]-[raindex]-[id]` (components handle the heavy lifting inside `ui-components`). + - Lists vaults using `VaultsListTable`; supports filtering, active accounts, + and bulk withdraw. + - Detail route: `/vaults/[chainId]-[raindex]-[id]` (components handle the + heavy lifting inside `ui-components`). - `/deploy` - - Loads a dotrain registry (`?registry=` query param or default `REGISTRY_URL`), validates orders, and shows valid/invalid sections. + - Loads a dotrain registry (`?registry=` query param or default + `REGISTRY_URL`), validates orders, and shows valid/invalid sections. - Nested routes: - `/deploy/[orderName]` — loads the dotrain and order details - - `/deploy/[orderName]/[deploymentKey]` — fetches deployment detail with `RaindexOrderBuilder.getDeploymentDetail`, then renders a builder for composing calldata + - `/deploy/[orderName]/[deploymentKey]` — fetches deployment detail with + `RaindexOrderBuilder.getDeploymentDetail`, then renders a builder for + composing calldata - `/license` — Static license information. - ## Directory Layout - `src/routes/` - - `+layout.ts` — Fetch settings, build `RaindexClient`, define app‑wide stores, disable SSR. - - `+layout.svelte` — Provider composition and app shell (sidebar + content area). + - `+layout.ts` — Fetch settings, build `RaindexClient`, define app‑wide + stores, disable SSR. + - `+layout.svelte` — Provider composition and app shell (sidebar + content + area). - `orders/` — Orders list and dynamic order detail. - `vaults/` — Vaults list and dynamic vault detail. - - `deploy/` — Registry load/validation, order selection, and deployment builder routes. + - `deploy/` — Registry load/validation, order selection, and deployment + builder routes. - `src/lib/` - - `components/` — App‑specific wrappers (Sidebar, modals, loaders, error page, etc.). - - `services/` — Side‑effectful helpers (wallet init, transactions, modal helpers, deposit/withdraw flows). - - `stores/` — Svelte stores for settings, wagmi state, loading flags, and toasts. + - `components/` — App‑specific wrappers (Sidebar, modals, loaders, error page, + etc.). + - `services/` — Side‑effectful helpers (wallet init, transactions, modal + helpers, deposit/withdraw flows). + - `stores/` — Svelte stores for settings, wagmi state, loading flags, and + toasts. - `types/` — Small app‑local type helpers. - `src/app.*` — SvelteKit app template, global CSS, and global TS types. - `static/` — Static assets. -- `tailwind.config.ts` — Tailwind setup (includes `ui-components` and Flowbite paths). +- `tailwind.config.ts` — Tailwind setup (includes `ui-components` and Flowbite + paths). - `svelte.config.js` — Vercel adapter (Node.js 20 runtime) and preprocessing. -- `vite.config.ts` — Build and Vitest configuration (JS DOM, inline deps, env passthrough). - +- `vite.config.ts` — Build and Vitest configuration (JS DOM, inline deps, env + passthrough). ## Build, Test, and Dev @@ -100,7 +125,6 @@ Run inside a Nix shell for tool parity (`nix develop -c `): - Lint/format/check: `npm run format`, `npm run lint`, `npm run check` - Tests: `nix develop -c npm run test` (Vitest, jsdom) - ## Configuration - Copy `.env.example` to `.env` and set: @@ -110,25 +134,35 @@ PUBLIC_WALLETCONNECT_PROJECT_ID= ``` - Notes - - Use the `PUBLIC_` prefix (SvelteKit convention) for variables that must be available in the browser. + - Use the `PUBLIC_` prefix (SvelteKit convention) for variables that must be + available in the browser. - Never commit secrets. Use Vercel/hosted environment variables for deploys. - - Deploy registry: `REGISTRY_URL` in `src/lib/constants.ts` can be overridden via the `?registry=` query parameter (persisted by `RegistryManager`). - + - Deploy registry: `REGISTRY_URL` in `src/lib/constants.ts` can be overridden + via the `?registry=` query parameter (persisted by `RegistryManager`). ## How It Fits The Workspace -- Rust crates under `crates/*` implement the core logic; `@rainlanguage/raindex` packages a WASM surface to consume from JS. -- `@rainlanguage/ui-components` provides reusable Svelte components, transaction plumbing, and providers. -- This webapp stitches both together into a cohesive UI. It lives in the JS workspace and is not part of the Cargo workspace. - +- Rust crates under `crates/*` implement the core logic; `@rainlanguage/raindex` + packages a WASM surface to consume from JS. +- `@rainlanguage/ui-components` provides reusable Svelte components, transaction + plumbing, and providers. +- This webapp stitches both together into a cohesive UI. It lives in the JS + workspace and is not part of the Cargo workspace. ## Caveats & Tips -- SSR is disabled; avoid Node‑only APIs or server‑only assumptions in route/load code. -- Always run inside `nix develop` so the correct Node and build tools are available. -- If you modify or add routes, ensure Tailwind’s `content` globs include your files for proper styling. -- Wallet init issues usually stem from a missing/invalid `PUBLIC_WALLETCONNECT_PROJECT_ID` or blocked popups. -- When adding new flows that touch the blockchain, prefer composing `@rainlanguage/ui-components` helpers and passing the `RaindexClient` from the layout provider. - - -This document explains the purpose and structure of `packages/webapp`, how the app boots and wires providers, where key features live, and how it integrates with the rest of the Rain Raindex workspace. +- SSR is disabled; avoid Node‑only APIs or server‑only assumptions in route/load + code. +- Always run inside `nix develop` so the correct Node and build tools are + available. +- If you modify or add routes, ensure Tailwind’s `content` globs include your + files for proper styling. +- Wallet init issues usually stem from a missing/invalid + `PUBLIC_WALLETCONNECT_PROJECT_ID` or blocked popups. +- When adding new flows that touch the blockchain, prefer composing + `@rainlanguage/ui-components` helpers and passing the `RaindexClient` from the + layout provider. + +This document explains the purpose and structure of `packages/webapp`, how the +app boots and wires providers, where key features live, and how it integrates +with the rest of the Rain Raindex workspace. diff --git a/packages/webapp/README.md b/packages/webapp/README.md index b5b295070b..ff0d9bde6c 100644 --- a/packages/webapp/README.md +++ b/packages/webapp/README.md @@ -1,6 +1,7 @@ # sv -Everything you need to build a Svelte project, powered by [`sv`](https://github.com/sveltejs/cli). +Everything you need to build a Svelte project, powered by +[`sv`](https://github.com/sveltejs/cli). ## Creating a project @@ -16,7 +17,8 @@ npx sv create my-app ## Developing -Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: +Once you've created a project and installed dependencies with `npm install` (or +`pnpm install` or `yarn`), start a development server: ```bash npm run dev @@ -35,4 +37,5 @@ npm run build You can preview the production build with `npm run preview`. -> To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment. +> To deploy your app, you may need to install an +> [adapter](https://svelte.dev/docs/kit/adapters) for your target environment. diff --git a/pointers.sh b/pointers.sh deleted file mode 100755 index 2642f70a2c..0000000000 --- a/pointers.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -set -euxo pipefail - -nix develop -c forge soldeer install -nix develop -c forge build diff --git a/prep-all.sh b/prep-all.sh deleted file mode 100755 index a47a72a720..0000000000 --- a/prep-all.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/bash - -# Set strict error handling -set -euxo pipefail - -echo "Starting project setup..." - -# Environment variables that need to be set (commented out as reference) -# export CI_DEPLOY_SEPOLIA_RPC_URL="" -# export CI_FORK_SEPOLIA_DEPLOYER_ADDRESS="" -# export CI_FORK_SEPOLIA_BLOCK_NUMBER="" -# export CI_DEPLOY_POLYGON_RPC_URL="" -# export CI_SEPOLIA_METABOARD_URL="" -# export RPC_URL_ETHEREUM_FORK="" -# export COMMIT_SHA="" - -# Keep environment variables when using nix-develop -keep=( - -k CI_DEPLOY_SEPOLIA_RPC_URL - -k CI_FORK_SEPOLIA_DEPLOYER_ADDRESS - -k CI_FORK_SEPOLIA_BLOCK_NUMBER - -k CI_DEPLOY_POLYGON_RPC_URL - -k CI_SEPOLIA_METABOARD_URL - -k RPC_URL_ETHEREUM_FORK - -k COMMIT_SHA - -k PUBLIC_WALLETCONNECT_PROJECT_ID -) - -echo "Preparing base setup..." -./prep-base.sh - -echo "Setting up UI components..." -nix develop -i ${keep[@]} -c raindex-ui-components-prelude - -echo "Building packages..." -nix develop -i ${keep[@]} -c bash -c '(npm run build -w @rainlanguage/raindex)' -nix develop -i ${keep[@]} -c bash -c '(npm run build -w @rainlanguage/ui-components && npm run build -w @rainlanguage/webapp)' - -# Temporarily disable command echoing -set +x - -export LANG=en_US.UTF-8 -export LC_ALL=en_US.UTF-8 - -GREEN='\033[0;32m' -NC='\033[0m' # No Color - -# Print the completion message -printf "\033[0;32m" # Set text to green -printf "╔════════════════════════════════════════════════════════════════════════╗\n" -printf "║ Setup Complete! ║\n" -printf "╠════════════════════════════════════════════════════════════════════════╣\n" -printf "║ How to run the app: ║\n" -printf "║ ║\n" -printf "║ To run webapp: cd packages/webapp && nix develop -c npm run dev ║\n" -printf "╚════════════════════════════════════════════════════════════════════════╝\n" -printf "\033[0m" # Reset text color - -# Re-enable command echoing -set -x diff --git a/prep-base.sh b/prep-base.sh deleted file mode 100755 index 49030a517b..0000000000 --- a/prep-base.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/bash - -set -euxo pipefail - -echo "Starting project setup..." - -keep=( - -k CI_DEPLOY_SEPOLIA_RPC_URL - -k CI_FORK_SEPOLIA_DEPLOYER_ADDRESS - -k CI_FORK_SEPOLIA_BLOCK_NUMBER - -k CI_DEPLOY_ARBITRUM_RPC_URL - -k CI_DEPLOY_BASE_RPC_URL - -k CI_DEPLOY_BASE_SEPOLIA_RPC_URL - -k CI_DEPLOY_FLARE_RPC_URL - -k CI_DEPLOY_POLYGON_RPC_URL - -k CI_SEPOLIA_METABOARD_URL - -k RPC_URL_ETHEREUM_FORK - -k COMMIT_SHA - -k DEPLOYMENT_KEY - -k PUBLIC_WALLETCONNECT_PROJECT_ID -) - -nix develop -c forge soldeer install -nix develop -c forge build - -nix develop -i "${keep[@]}" -c raindex-prelude - -nix develop -i "${keep[@]}" -c forge build - -set +x - -export LANG=en_US.UTF-8 -export LC_ALL=en_US.UTF-8 - -printf "\033[0;32m" -printf "╔════════════════════════════════════════════════════════════════════════╗\n" -printf "║ Base Setup Complete! ║\n" -printf "╚════════════════════════════════════════════════════════════════════════╝\n" -printf "\033[0m" - -set -x diff --git a/prep-webapp.sh b/prep-webapp.sh deleted file mode 100755 index 2b212165a5..0000000000 --- a/prep-webapp.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/bash - -# Set strict error handling -set -euxo pipefail - -echo "Starting project setup..." - -# Environment variables that need to be set (commented out as reference) -# export CI_DEPLOY_SEPOLIA_RPC_URL="" -# export CI_FORK_SEPOLIA_DEPLOYER_ADDRESS="" -# export CI_FORK_SEPOLIA_BLOCK_NUMBER="" -# export CI_DEPLOY_POLYGON_RPC_URL="" -# export CI_SEPOLIA_METABOARD_URL="" -# export RPC_URL_ETHEREUM_FORK="" -# export COMMIT_SHA="" - -# Keep environment variables when using nix-develop -keep=( - -k CI_DEPLOY_SEPOLIA_RPC_URL - -k CI_FORK_SEPOLIA_DEPLOYER_ADDRESS - -k CI_FORK_SEPOLIA_BLOCK_NUMBER - -k CI_DEPLOY_POLYGON_RPC_URL - -k CI_SEPOLIA_METABOARD_URL - -k RPC_URL_ETHEREUM_FORK - -k COMMIT_SHA - -k PUBLIC_WALLETCONNECT_PROJECT_ID -) - -echo "Preparing base setup..." -./prep-base.sh - -rm -rf target || true - -echo "Building packages..." -nix develop -i ${keep[@]} -c bash -c '(npm run build -w @rainlanguage/raindex)' - -rm -rf target || true - -nix develop -i ${keep[@]} -c bash -c '(npm run build -w @rainlanguage/ui-components && npm run build -w @rainlanguage/webapp)' - -# Temporarily disable command echoing -set +x - -export LANG=en_US.UTF-8 -export LC_ALL=en_US.UTF-8 - -GREEN='\033[0;32m' -NC='\033[0m' # No Color - -# Print the completion message -printf "\033[0;32m" # Set text to green -printf "╔════════════════════════════════════════════════════════════════════════╗\n" -printf "║ Setup Complete! ║\n" -printf "╠════════════════════════════════════════════════════════════════════════╣\n" -printf "║ How to run the apps: ║\n" -printf "║ ║\n" -printf "║ To run webapp: cd packages/webapp && nix develop -c npm run dev ║\n" -printf "╚════════════════════════════════════════════════════════════════════════╝\n" -printf "\033[0m" # Reset text color - -# Re-enable command echoing -set -x diff --git a/script/build.sh b/script/build.sh new file mode 100755 index 0000000000..218bd229c4 --- /dev/null +++ b/script/build.sh @@ -0,0 +1,44 @@ +#!/bin/bash +# SPDX-License-Identifier: LicenseRef-DCL-1.0 +# SPDX-FileCopyrightText: Copyright (c) 2020 Rain Open Source Software Ltd + +# Post-CopyArtifacts hook for rainix-copy-artifacts. Regenerates all committed +# derived artifacts: subgraph ABIs + codegen, bindings ABIs (read by `sol!` in +# crates/bindings/src/lib.rs), test_fixtures ABIs + IMulticall3.sol. Strips +# forge JSON to just `.abi` (or `.abi + .bytecode` where alloy ::deploy() +# needs it) — bytecode/metadata/id embed build-host paths and aren't +# deterministic across runners, which would defeat the diff gate; consumers +# (alloy sol!, graph CLI, matchstick) only read those fields anyway. + +set -euxo pipefail + +# Pass the whole pipeline via `bash -c '...'` rather than `bash < subgraph/abis/Raindex.json +jq "{abi}" out/ERC20.sol/ERC20.json > subgraph/abis/ERC20.json +jq "{abi}" out/DecimalFloat.sol/DecimalFloat.json > subgraph/abis/DecimalFloat.json + +(cd subgraph && npm ci && graph codegen) + +mkdir -p crates/bindings/abis +jq "{abi}" out/IRaindexV6.sol/IRaindexV6.json > crates/bindings/abis/IRaindexV6.json +jq "{abi}" out/RaindexV6.sol/RaindexV6.json > crates/bindings/abis/RaindexV6.json +jq "{abi}" out/ERC20.sol/ERC20.json > crates/bindings/abis/ERC20.json +jq "{abi}" out/IERC20Metadata.sol/IERC20Metadata.json > crates/bindings/abis/IERC20Metadata.json +jq "{abi}" out/IInterpreterStoreV3.sol/IInterpreterStoreV3.json > crates/bindings/abis/IInterpreterStoreV3.json + +mkdir -p crates/test_fixtures/abis +# bytecode.sourceMap embeds a file-ID that depends on solc input ordering and +# differs across runners — drop it (debug-only; alloy ::deploy() only reads +# bytecode.object). +jq "{abi, bytecode: (.bytecode | {object, linkReferences})}" out/RaindexV6.sol/RaindexV6.json > crates/test_fixtures/abis/RaindexV6.json +jq "{abi, bytecode: (.bytecode | {object, linkReferences})}" out/RaindexV6SubParser.sol/RaindexV6SubParser.json > crates/test_fixtures/abis/RaindexV6SubParser.json + +mkdir -p crates/test_fixtures/contracts +cp dependencies/forge-std-1.16.1/src/interfaces/IMulticall3.sol crates/test_fixtures/contracts/IMulticall3.sol +' diff --git a/subgraph/.gitignore b/subgraph/.gitignore index 65117f3fca..e00bd45070 100644 --- a/subgraph/.gitignore +++ b/subgraph/.gitignore @@ -1,4 +1,3 @@ node_modules -generated build .bin \ No newline at end of file diff --git a/subgraph/abis/DecimalFloat.json b/subgraph/abis/DecimalFloat.json new file mode 100644 index 0000000000..ae07f50603 --- /dev/null +++ b/subgraph/abis/DecimalFloat.json @@ -0,0 +1,1104 @@ +{ + "abi": [ + { + "type": "constructor", + "inputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "FORMAT_DEFAULT_SCIENTIFIC_MAX", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "FORMAT_DEFAULT_SCIENTIFIC_MIN", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "abs", + "inputs": [ + { + "name": "a", + "type": "bytes32", + "internalType": "Float" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "add", + "inputs": [ + { + "name": "a", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "b", + "type": "bytes32", + "internalType": "Float" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "ceil", + "inputs": [ + { + "name": "a", + "type": "bytes32", + "internalType": "Float" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "div", + "inputs": [ + { + "name": "a", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "b", + "type": "bytes32", + "internalType": "Float" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "e", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "eq", + "inputs": [ + { + "name": "a", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "b", + "type": "bytes32", + "internalType": "Float" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "floor", + "inputs": [ + { + "name": "a", + "type": "bytes32", + "internalType": "Float" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "format", + "inputs": [ + { + "name": "a", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "scientific", + "type": "bool", + "internalType": "bool" + } + ], + "outputs": [ + { + "name": "", + "type": "string", + "internalType": "string" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "format", + "inputs": [ + { + "name": "a", + "type": "bytes32", + "internalType": "Float" + } + ], + "outputs": [ + { + "name": "", + "type": "string", + "internalType": "string" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "format", + "inputs": [ + { + "name": "a", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "scientificMin", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "scientificMax", + "type": "bytes32", + "internalType": "Float" + } + ], + "outputs": [ + { + "name": "", + "type": "string", + "internalType": "string" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "frac", + "inputs": [ + { + "name": "a", + "type": "bytes32", + "internalType": "Float" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "fromFixedDecimalLossless", + "inputs": [ + { + "name": "value", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "decimals", + "type": "uint8", + "internalType": "uint8" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "fromFixedDecimalLossy", + "inputs": [ + { + "name": "value", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "decimals", + "type": "uint8", + "internalType": "uint8" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "gt", + "inputs": [ + { + "name": "a", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "b", + "type": "bytes32", + "internalType": "Float" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "gte", + "inputs": [ + { + "name": "a", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "b", + "type": "bytes32", + "internalType": "Float" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "integer", + "inputs": [ + { + "name": "a", + "type": "bytes32", + "internalType": "Float" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "inv", + "inputs": [ + { + "name": "a", + "type": "bytes32", + "internalType": "Float" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "isZero", + "inputs": [ + { + "name": "a", + "type": "bytes32", + "internalType": "Float" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "log10", + "inputs": [ + { + "name": "a", + "type": "bytes32", + "internalType": "Float" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "lt", + "inputs": [ + { + "name": "a", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "b", + "type": "bytes32", + "internalType": "Float" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "lte", + "inputs": [ + { + "name": "a", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "b", + "type": "bytes32", + "internalType": "Float" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "max", + "inputs": [ + { + "name": "a", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "b", + "type": "bytes32", + "internalType": "Float" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "maxNegativeValue", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "maxPositiveValue", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "min", + "inputs": [ + { + "name": "a", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "b", + "type": "bytes32", + "internalType": "Float" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "minNegativeValue", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "minPositiveValue", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "minus", + "inputs": [ + { + "name": "a", + "type": "bytes32", + "internalType": "Float" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "mul", + "inputs": [ + { + "name": "a", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "b", + "type": "bytes32", + "internalType": "Float" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "parse", + "inputs": [ + { + "name": "str", + "type": "string", + "internalType": "string" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes4", + "internalType": "bytes4" + }, + { + "name": "", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "pow", + "inputs": [ + { + "name": "a", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "b", + "type": "bytes32", + "internalType": "Float" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "pow10", + "inputs": [ + { + "name": "a", + "type": "bytes32", + "internalType": "Float" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "sqrt", + "inputs": [ + { + "name": "a", + "type": "bytes32", + "internalType": "Float" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "sub", + "inputs": [ + { + "name": "a", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "b", + "type": "bytes32", + "internalType": "Float" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "toFixedDecimalLossless", + "inputs": [ + { + "name": "float", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "decimals", + "type": "uint8", + "internalType": "uint8" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "toFixedDecimalLossy", + "inputs": [ + { + "name": "float", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "decimals", + "type": "uint8", + "internalType": "uint8" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "zero", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "pure" + }, + { + "type": "error", + "name": "CoefficientOverflow", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "DivisionByZero", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "ExponentOverflow", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "ExponentUnderflow", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "FixedDecimalOverflow", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + }, + { + "name": "decimals", + "type": "uint8", + "internalType": "uint8" + } + ] + }, + { + "type": "error", + "name": "Log10Negative", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "Log10Zero", + "inputs": [] + }, + { + "type": "error", + "name": "LogTablesNotDeployed", + "inputs": [ + { + "name": "tablesAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "expectedCodehash", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "actualCodehash", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "type": "error", + "name": "LossyConversionFromFloat", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "LossyConversionToFloat", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "MaximizeOverflow", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "MulDivOverflow", + "inputs": [ + { + "name": "x", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "y", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "denominator", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "NegativeFixedDecimalConversion", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "PowNegativeBase", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "ScientificMinNotLessThanMax", + "inputs": [ + { + "name": "scientificMin", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "scientificMax", + "type": "bytes32", + "internalType": "Float" + } + ] + }, + { + "type": "error", + "name": "UnformatableExponent", + "inputs": [ + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "WithTargetExponentOverflow", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + }, + { + "name": "targetExponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "ZeroNegativePower", + "inputs": [ + { + "name": "b", + "type": "bytes32", + "internalType": "Float" + } + ] + }, + { + "type": "error", + "name": "ZeroStringStartPointer", + "inputs": [] + } + ] +} diff --git a/subgraph/abis/ERC20.json b/subgraph/abis/ERC20.json new file mode 100644 index 0000000000..b65fe63720 --- /dev/null +++ b/subgraph/abis/ERC20.json @@ -0,0 +1,312 @@ +{ + "abi": [ + { + "type": "function", + "name": "allowance", + "inputs": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "spender", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "approve", + "inputs": [ + { + "name": "spender", + "type": "address", + "internalType": "address" + }, + { + "name": "value", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "balanceOf", + "inputs": [ + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "decimals", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint8", + "internalType": "uint8" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "name", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "string", + "internalType": "string" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "symbol", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "string", + "internalType": "string" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "totalSupply", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "transfer", + "inputs": [ + { + "name": "to", + "type": "address", + "internalType": "address" + }, + { + "name": "value", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "transferFrom", + "inputs": [ + { + "name": "from", + "type": "address", + "internalType": "address" + }, + { + "name": "to", + "type": "address", + "internalType": "address" + }, + { + "name": "value", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "event", + "name": "Approval", + "inputs": [ + { + "name": "owner", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "spender", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "value", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Transfer", + "inputs": [ + { + "name": "from", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "to", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "value", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "ERC20InsufficientAllowance", + "inputs": [ + { + "name": "spender", + "type": "address", + "internalType": "address" + }, + { + "name": "allowance", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "needed", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "ERC20InsufficientBalance", + "inputs": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + }, + { + "name": "balance", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "needed", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "ERC20InvalidApprover", + "inputs": [ + { + "name": "approver", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ERC20InvalidReceiver", + "inputs": [ + { + "name": "receiver", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ERC20InvalidSender", + "inputs": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ERC20InvalidSpender", + "inputs": [ + { + "name": "spender", + "type": "address", + "internalType": "address" + } + ] + } + ] +} diff --git a/subgraph/abis/Raindex.json b/subgraph/abis/Raindex.json new file mode 100644 index 0000000000..fa86240bc2 --- /dev/null +++ b/subgraph/abis/Raindex.json @@ -0,0 +1,2375 @@ +{ + "abi": [ + { + "type": "function", + "name": "addOrder4", + "inputs": [ + { + "name": "orderConfig", + "type": "tuple", + "internalType": "struct OrderConfigV4", + "components": [ + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "secret", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "meta", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "post", + "type": "tuple[]", + "internalType": "struct TaskV2[]", + "components": [ + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "signedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ] + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "clear3", + "inputs": [ + { + "name": "aliceOrder", + "type": "tuple", + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "bobOrder", + "type": "tuple", + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "clearConfig", + "type": "tuple", + "internalType": "struct ClearConfigV2", + "components": [ + { + "name": "aliceInputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "aliceOutputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "bobInputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "bobOutputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "aliceBountyVaultId", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "bobBountyVaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "aliceSignedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "bobSignedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "deposit4", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "depositAmount", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "post", + "type": "tuple[]", + "internalType": "struct TaskV2[]", + "components": [ + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "signedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "entask2", + "inputs": [ + { + "name": "post", + "type": "tuple[]", + "internalType": "struct TaskV2[]", + "components": [ + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "signedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "flashFee", + "inputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + }, + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "flashLoan", + "inputs": [ + { + "name": "receiver", + "type": "address", + "internalType": "contract IERC3156FlashBorrower" + }, + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "data", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "maxFlashLoan", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "multicall", + "inputs": [ + { + "name": "data", + "type": "bytes[]", + "internalType": "bytes[]" + } + ], + "outputs": [ + { + "name": "results", + "type": "bytes[]", + "internalType": "bytes[]" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "orderExists", + "inputs": [ + { + "name": "orderHash", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "quote2", + "inputs": [ + { + "name": "quoteConfig", + "type": "tuple", + "internalType": "struct QuoteV2", + "components": [ + { + "name": "order", + "type": "tuple", + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "inputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "outputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "signedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ] + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + }, + { + "name": "", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "removeOrder3", + "inputs": [ + { + "name": "order", + "type": "tuple", + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "post", + "type": "tuple[]", + "internalType": "struct TaskV2[]", + "components": [ + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "signedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ] + } + ], + "outputs": [ + { + "name": "stateChanged", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "supportsInterface", + "inputs": [ + { + "name": "interfaceId", + "type": "bytes4", + "internalType": "bytes4" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "takeOrders4", + "inputs": [ + { + "name": "config", + "type": "tuple", + "internalType": "struct TakeOrdersConfigV5", + "components": [ + { + "name": "minimumIO", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "maximumIO", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "maximumIORatio", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "IOIsInput", + "type": "bool", + "internalType": "bool" + }, + { + "name": "orders", + "type": "tuple[]", + "internalType": "struct TakeOrderConfigV4[]", + "components": [ + { + "name": "order", + "type": "tuple", + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "inputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "outputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "signedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ] + }, + { + "name": "data", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ], + "outputs": [ + { + "name": "totalTakerInput", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "totalTakerOutput", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "vaultBalance2", + "inputs": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "Float" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "withdraw4", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "targetAmount", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "post", + "type": "tuple[]", + "internalType": "struct TaskV2[]", + "components": [ + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "signedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "event", + "name": "AddOrderV3", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "orderHash", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + }, + { + "name": "order", + "type": "tuple", + "indexed": false, + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "AfterClearV2", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "clearStateChange", + "type": "tuple", + "indexed": false, + "internalType": "struct ClearStateChangeV2", + "components": [ + { + "name": "aliceOutput", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "bobOutput", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "aliceInput", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "bobInput", + "type": "bytes32", + "internalType": "Float" + } + ] + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ClearV3", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "alice", + "type": "tuple", + "indexed": false, + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "bob", + "type": "tuple", + "indexed": false, + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "clearConfig", + "type": "tuple", + "indexed": false, + "internalType": "struct ClearConfigV2", + "components": [ + { + "name": "aliceInputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "aliceOutputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "bobInputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "bobOutputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "aliceBountyVaultId", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "bobBountyVaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ContextV2", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[][]", + "indexed": false, + "internalType": "bytes32[][]" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "DepositV2", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + }, + { + "name": "depositAmountUint256", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "MetaV1_2", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "subject", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + }, + { + "name": "meta", + "type": "bytes", + "indexed": false, + "internalType": "bytes" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OrderExceedsMaxRatio", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "owner", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "orderHash", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OrderNotFound", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "owner", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "orderHash", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OrderZeroAmount", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "owner", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "orderHash", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RemoveOrderV3", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "orderHash", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + }, + { + "name": "order", + "type": "tuple", + "indexed": false, + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "TakeOrderV3", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "config", + "type": "tuple", + "indexed": false, + "internalType": "struct TakeOrderConfigV4", + "components": [ + { + "name": "order", + "type": "tuple", + "internalType": "struct OrderV4", + "components": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "evaluable", + "type": "tuple", + "internalType": "struct EvaluableV4", + "components": [ + { + "name": "interpreter", + "type": "address", + "internalType": "contract IInterpreterV4" + }, + { + "name": "store", + "type": "address", + "internalType": "contract IInterpreterStoreV3" + }, + { + "name": "bytecode", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "validInputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "validOutputs", + "type": "tuple[]", + "internalType": "struct IOV2[]", + "components": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "nonce", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "inputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "outputIOIndex", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "signedContext", + "type": "tuple[]", + "internalType": "struct SignedContextV1[]", + "components": [ + { + "name": "signer", + "type": "address", + "internalType": "address" + }, + { + "name": "context", + "type": "bytes32[]", + "internalType": "bytes32[]" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ] + }, + { + "name": "input", + "type": "bytes32", + "indexed": false, + "internalType": "Float" + }, + { + "name": "output", + "type": "bytes32", + "indexed": false, + "internalType": "Float" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "WithdrawV2", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + }, + { + "name": "targetAmount", + "type": "bytes32", + "indexed": false, + "internalType": "Float" + }, + { + "name": "withdrawAmount", + "type": "bytes32", + "indexed": false, + "internalType": "Float" + }, + { + "name": "withdrawAmountUint256", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "AddressEmptyCode", + "inputs": [ + { + "name": "target", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ClearZeroAmount", + "inputs": [] + }, + { + "type": "error", + "name": "CoefficientOverflow", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "DivisionByZero", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "ExponentOverflow", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "ExponentUnderflow", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "FailedCall", + "inputs": [] + }, + { + "type": "error", + "name": "FixedDecimalOverflow", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + }, + { + "name": "decimals", + "type": "uint8", + "internalType": "uint8" + } + ] + }, + { + "type": "error", + "name": "FlashLenderCallbackFailed", + "inputs": [ + { + "name": "result", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "type": "error", + "name": "InvalidSignature", + "inputs": [ + { + "name": "i", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "LossyConversionToFloat", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "MaximizeOverflow", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "MinimumIO", + "inputs": [ + { + "name": "minimumIO", + "type": "bytes32", + "internalType": "Float" + }, + { + "name": "actualIO", + "type": "bytes32", + "internalType": "Float" + } + ] + }, + { + "type": "error", + "name": "MulDivOverflow", + "inputs": [ + { + "name": "x", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "y", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "denominator", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "NegativeBounty", + "inputs": [] + }, + { + "type": "error", + "name": "NegativeFixedDecimalConversion", + "inputs": [ + { + "name": "signedCoefficient", + "type": "int256", + "internalType": "int256" + }, + { + "name": "exponent", + "type": "int256", + "internalType": "int256" + } + ] + }, + { + "type": "error", + "name": "NegativePull", + "inputs": [] + }, + { + "type": "error", + "name": "NegativePush", + "inputs": [] + }, + { + "type": "error", + "name": "NegativeVaultBalance", + "inputs": [ + { + "name": "vaultBalance", + "type": "bytes32", + "internalType": "Float" + } + ] + }, + { + "type": "error", + "name": "NegativeVaultBalanceChange", + "inputs": [ + { + "name": "amount", + "type": "bytes32", + "internalType": "Float" + } + ] + }, + { + "type": "error", + "name": "NoOrders", + "inputs": [] + }, + { + "type": "error", + "name": "NotOrderOwner", + "inputs": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "NotRainMetaV1", + "inputs": [ + { + "name": "unmeta", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "type": "error", + "name": "OrderNoHandleIO", + "inputs": [] + }, + { + "type": "error", + "name": "OrderNoInputs", + "inputs": [] + }, + { + "type": "error", + "name": "OrderNoOutputs", + "inputs": [] + }, + { + "type": "error", + "name": "OrderNoSources", + "inputs": [] + }, + { + "type": "error", + "name": "ReentrancyGuardReentrantCall", + "inputs": [] + }, + { + "type": "error", + "name": "SafeERC20FailedOperation", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "SameOwner", + "inputs": [] + }, + { + "type": "error", + "name": "TOFUTokenDecimalsNotDeployed", + "inputs": [ + { + "name": "expectedAddress", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "TokenDecimalsReadFailure", + "inputs": [ + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "tofuOutcome", + "type": "uint8", + "internalType": "enum TOFUOutcome" + } + ] + }, + { + "type": "error", + "name": "TokenMismatch", + "inputs": [] + }, + { + "type": "error", + "name": "TokenSelfTrade", + "inputs": [] + }, + { + "type": "error", + "name": "UnsupportedCalculateOutputs", + "inputs": [ + { + "name": "outputs", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "ZeroDepositAmount", + "inputs": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "type": "error", + "name": "ZeroMaximumIO", + "inputs": [] + }, + { + "type": "error", + "name": "ZeroVaultId", + "inputs": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "internalType": "address" + } + ] + }, + { + "type": "error", + "name": "ZeroWithdrawTargetAmount", + "inputs": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + }, + { + "name": "token", + "type": "address", + "internalType": "address" + }, + { + "name": "vaultId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + } + ] +} diff --git a/subgraph/docker-compose.yml b/subgraph/docker-compose.yml index ea277a2e6a..81e369e5ff 100644 --- a/subgraph/docker-compose.yml +++ b/subgraph/docker-compose.yml @@ -2,4 +2,4 @@ services: matchstick: image: rainprotocol/matchstick:main volumes: - - ..:/matchstick \ No newline at end of file + - ..:/matchstick diff --git a/subgraph/generated/Raindex/DecimalFloat.ts b/subgraph/generated/Raindex/DecimalFloat.ts new file mode 100644 index 0000000000..fca6408a99 --- /dev/null +++ b/subgraph/generated/Raindex/DecimalFloat.ts @@ -0,0 +1,996 @@ +// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. + +import { + ethereum, + JSONValue, + TypedMap, + Entity, + Bytes, + Address, + BigInt, +} from "@graphprotocol/graph-ts"; + +export class DecimalFloat__fromFixedDecimalLossyResult { + value0: Bytes; + value1: boolean; + + constructor(value0: Bytes, value1: boolean) { + this.value0 = value0; + this.value1 = value1; + } + + toMap(): TypedMap { + let map = new TypedMap(); + map.set("value0", ethereum.Value.fromFixedBytes(this.value0)); + map.set("value1", ethereum.Value.fromBoolean(this.value1)); + return map; + } + + getValue0(): Bytes { + return this.value0; + } + + getValue1(): boolean { + return this.value1; + } +} + +export class DecimalFloat__parseResult { + value0: Bytes; + value1: Bytes; + + constructor(value0: Bytes, value1: Bytes) { + this.value0 = value0; + this.value1 = value1; + } + + toMap(): TypedMap { + let map = new TypedMap(); + map.set("value0", ethereum.Value.fromFixedBytes(this.value0)); + map.set("value1", ethereum.Value.fromFixedBytes(this.value1)); + return map; + } + + getValue0(): Bytes { + return this.value0; + } + + getValue1(): Bytes { + return this.value1; + } +} + +export class DecimalFloat__toFixedDecimalLossyResult { + value0: BigInt; + value1: boolean; + + constructor(value0: BigInt, value1: boolean) { + this.value0 = value0; + this.value1 = value1; + } + + toMap(): TypedMap { + let map = new TypedMap(); + map.set("value0", ethereum.Value.fromUnsignedBigInt(this.value0)); + map.set("value1", ethereum.Value.fromBoolean(this.value1)); + return map; + } + + getValue0(): BigInt { + return this.value0; + } + + getValue1(): boolean { + return this.value1; + } +} + +export class DecimalFloat extends ethereum.SmartContract { + static bind(address: Address): DecimalFloat { + return new DecimalFloat("DecimalFloat", address); + } + + FORMAT_DEFAULT_SCIENTIFIC_MAX(): Bytes { + let result = super.call( + "FORMAT_DEFAULT_SCIENTIFIC_MAX", + "FORMAT_DEFAULT_SCIENTIFIC_MAX():(bytes32)", + [], + ); + + return result[0].toBytes(); + } + + try_FORMAT_DEFAULT_SCIENTIFIC_MAX(): ethereum.CallResult { + let result = super.tryCall( + "FORMAT_DEFAULT_SCIENTIFIC_MAX", + "FORMAT_DEFAULT_SCIENTIFIC_MAX():(bytes32)", + [], + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBytes()); + } + + FORMAT_DEFAULT_SCIENTIFIC_MIN(): Bytes { + let result = super.call( + "FORMAT_DEFAULT_SCIENTIFIC_MIN", + "FORMAT_DEFAULT_SCIENTIFIC_MIN():(bytes32)", + [], + ); + + return result[0].toBytes(); + } + + try_FORMAT_DEFAULT_SCIENTIFIC_MIN(): ethereum.CallResult { + let result = super.tryCall( + "FORMAT_DEFAULT_SCIENTIFIC_MIN", + "FORMAT_DEFAULT_SCIENTIFIC_MIN():(bytes32)", + [], + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBytes()); + } + + abs(a: Bytes): Bytes { + let result = super.call("abs", "abs(bytes32):(bytes32)", [ + ethereum.Value.fromFixedBytes(a), + ]); + + return result[0].toBytes(); + } + + try_abs(a: Bytes): ethereum.CallResult { + let result = super.tryCall("abs", "abs(bytes32):(bytes32)", [ + ethereum.Value.fromFixedBytes(a), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBytes()); + } + + add(a: Bytes, b: Bytes): Bytes { + let result = super.call("add", "add(bytes32,bytes32):(bytes32)", [ + ethereum.Value.fromFixedBytes(a), + ethereum.Value.fromFixedBytes(b), + ]); + + return result[0].toBytes(); + } + + try_add(a: Bytes, b: Bytes): ethereum.CallResult { + let result = super.tryCall("add", "add(bytes32,bytes32):(bytes32)", [ + ethereum.Value.fromFixedBytes(a), + ethereum.Value.fromFixedBytes(b), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBytes()); + } + + ceil(a: Bytes): Bytes { + let result = super.call("ceil", "ceil(bytes32):(bytes32)", [ + ethereum.Value.fromFixedBytes(a), + ]); + + return result[0].toBytes(); + } + + try_ceil(a: Bytes): ethereum.CallResult { + let result = super.tryCall("ceil", "ceil(bytes32):(bytes32)", [ + ethereum.Value.fromFixedBytes(a), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBytes()); + } + + div(a: Bytes, b: Bytes): Bytes { + let result = super.call("div", "div(bytes32,bytes32):(bytes32)", [ + ethereum.Value.fromFixedBytes(a), + ethereum.Value.fromFixedBytes(b), + ]); + + return result[0].toBytes(); + } + + try_div(a: Bytes, b: Bytes): ethereum.CallResult { + let result = super.tryCall("div", "div(bytes32,bytes32):(bytes32)", [ + ethereum.Value.fromFixedBytes(a), + ethereum.Value.fromFixedBytes(b), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBytes()); + } + + e(): Bytes { + let result = super.call("e", "e():(bytes32)", []); + + return result[0].toBytes(); + } + + try_e(): ethereum.CallResult { + let result = super.tryCall("e", "e():(bytes32)", []); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBytes()); + } + + eq(a: Bytes, b: Bytes): boolean { + let result = super.call("eq", "eq(bytes32,bytes32):(bool)", [ + ethereum.Value.fromFixedBytes(a), + ethereum.Value.fromFixedBytes(b), + ]); + + return result[0].toBoolean(); + } + + try_eq(a: Bytes, b: Bytes): ethereum.CallResult { + let result = super.tryCall("eq", "eq(bytes32,bytes32):(bool)", [ + ethereum.Value.fromFixedBytes(a), + ethereum.Value.fromFixedBytes(b), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBoolean()); + } + + floor(a: Bytes): Bytes { + let result = super.call("floor", "floor(bytes32):(bytes32)", [ + ethereum.Value.fromFixedBytes(a), + ]); + + return result[0].toBytes(); + } + + try_floor(a: Bytes): ethereum.CallResult { + let result = super.tryCall("floor", "floor(bytes32):(bytes32)", [ + ethereum.Value.fromFixedBytes(a), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBytes()); + } + + format(a: Bytes, scientific: boolean): string { + let result = super.call("format", "format(bytes32,bool):(string)", [ + ethereum.Value.fromFixedBytes(a), + ethereum.Value.fromBoolean(scientific), + ]); + + return result[0].toString(); + } + + try_format(a: Bytes, scientific: boolean): ethereum.CallResult { + let result = super.tryCall("format", "format(bytes32,bool):(string)", [ + ethereum.Value.fromFixedBytes(a), + ethereum.Value.fromBoolean(scientific), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toString()); + } + + format1(a: Bytes): string { + let result = super.call("format", "format(bytes32):(string)", [ + ethereum.Value.fromFixedBytes(a), + ]); + + return result[0].toString(); + } + + try_format1(a: Bytes): ethereum.CallResult { + let result = super.tryCall("format", "format(bytes32):(string)", [ + ethereum.Value.fromFixedBytes(a), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toString()); + } + + format2(a: Bytes, scientificMin: Bytes, scientificMax: Bytes): string { + let result = super.call( + "format", + "format(bytes32,bytes32,bytes32):(string)", + [ + ethereum.Value.fromFixedBytes(a), + ethereum.Value.fromFixedBytes(scientificMin), + ethereum.Value.fromFixedBytes(scientificMax), + ], + ); + + return result[0].toString(); + } + + try_format2( + a: Bytes, + scientificMin: Bytes, + scientificMax: Bytes, + ): ethereum.CallResult { + let result = super.tryCall( + "format", + "format(bytes32,bytes32,bytes32):(string)", + [ + ethereum.Value.fromFixedBytes(a), + ethereum.Value.fromFixedBytes(scientificMin), + ethereum.Value.fromFixedBytes(scientificMax), + ], + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toString()); + } + + frac(a: Bytes): Bytes { + let result = super.call("frac", "frac(bytes32):(bytes32)", [ + ethereum.Value.fromFixedBytes(a), + ]); + + return result[0].toBytes(); + } + + try_frac(a: Bytes): ethereum.CallResult { + let result = super.tryCall("frac", "frac(bytes32):(bytes32)", [ + ethereum.Value.fromFixedBytes(a), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBytes()); + } + + fromFixedDecimalLossless(value: BigInt, decimals: i32): Bytes { + let result = super.call( + "fromFixedDecimalLossless", + "fromFixedDecimalLossless(uint256,uint8):(bytes32)", + [ + ethereum.Value.fromUnsignedBigInt(value), + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(decimals)), + ], + ); + + return result[0].toBytes(); + } + + try_fromFixedDecimalLossless( + value: BigInt, + decimals: i32, + ): ethereum.CallResult { + let result = super.tryCall( + "fromFixedDecimalLossless", + "fromFixedDecimalLossless(uint256,uint8):(bytes32)", + [ + ethereum.Value.fromUnsignedBigInt(value), + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(decimals)), + ], + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBytes()); + } + + fromFixedDecimalLossy( + value: BigInt, + decimals: i32, + ): DecimalFloat__fromFixedDecimalLossyResult { + let result = super.call( + "fromFixedDecimalLossy", + "fromFixedDecimalLossy(uint256,uint8):(bytes32,bool)", + [ + ethereum.Value.fromUnsignedBigInt(value), + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(decimals)), + ], + ); + + return new DecimalFloat__fromFixedDecimalLossyResult( + result[0].toBytes(), + result[1].toBoolean(), + ); + } + + try_fromFixedDecimalLossy( + value: BigInt, + decimals: i32, + ): ethereum.CallResult { + let result = super.tryCall( + "fromFixedDecimalLossy", + "fromFixedDecimalLossy(uint256,uint8):(bytes32,bool)", + [ + ethereum.Value.fromUnsignedBigInt(value), + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(decimals)), + ], + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue( + new DecimalFloat__fromFixedDecimalLossyResult( + value[0].toBytes(), + value[1].toBoolean(), + ), + ); + } + + gt(a: Bytes, b: Bytes): boolean { + let result = super.call("gt", "gt(bytes32,bytes32):(bool)", [ + ethereum.Value.fromFixedBytes(a), + ethereum.Value.fromFixedBytes(b), + ]); + + return result[0].toBoolean(); + } + + try_gt(a: Bytes, b: Bytes): ethereum.CallResult { + let result = super.tryCall("gt", "gt(bytes32,bytes32):(bool)", [ + ethereum.Value.fromFixedBytes(a), + ethereum.Value.fromFixedBytes(b), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBoolean()); + } + + gte(a: Bytes, b: Bytes): boolean { + let result = super.call("gte", "gte(bytes32,bytes32):(bool)", [ + ethereum.Value.fromFixedBytes(a), + ethereum.Value.fromFixedBytes(b), + ]); + + return result[0].toBoolean(); + } + + try_gte(a: Bytes, b: Bytes): ethereum.CallResult { + let result = super.tryCall("gte", "gte(bytes32,bytes32):(bool)", [ + ethereum.Value.fromFixedBytes(a), + ethereum.Value.fromFixedBytes(b), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBoolean()); + } + + integer(a: Bytes): Bytes { + let result = super.call("integer", "integer(bytes32):(bytes32)", [ + ethereum.Value.fromFixedBytes(a), + ]); + + return result[0].toBytes(); + } + + try_integer(a: Bytes): ethereum.CallResult { + let result = super.tryCall("integer", "integer(bytes32):(bytes32)", [ + ethereum.Value.fromFixedBytes(a), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBytes()); + } + + inv(a: Bytes): Bytes { + let result = super.call("inv", "inv(bytes32):(bytes32)", [ + ethereum.Value.fromFixedBytes(a), + ]); + + return result[0].toBytes(); + } + + try_inv(a: Bytes): ethereum.CallResult { + let result = super.tryCall("inv", "inv(bytes32):(bytes32)", [ + ethereum.Value.fromFixedBytes(a), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBytes()); + } + + isZero(a: Bytes): boolean { + let result = super.call("isZero", "isZero(bytes32):(bool)", [ + ethereum.Value.fromFixedBytes(a), + ]); + + return result[0].toBoolean(); + } + + try_isZero(a: Bytes): ethereum.CallResult { + let result = super.tryCall("isZero", "isZero(bytes32):(bool)", [ + ethereum.Value.fromFixedBytes(a), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBoolean()); + } + + log10(a: Bytes): Bytes { + let result = super.call("log10", "log10(bytes32):(bytes32)", [ + ethereum.Value.fromFixedBytes(a), + ]); + + return result[0].toBytes(); + } + + try_log10(a: Bytes): ethereum.CallResult { + let result = super.tryCall("log10", "log10(bytes32):(bytes32)", [ + ethereum.Value.fromFixedBytes(a), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBytes()); + } + + lt(a: Bytes, b: Bytes): boolean { + let result = super.call("lt", "lt(bytes32,bytes32):(bool)", [ + ethereum.Value.fromFixedBytes(a), + ethereum.Value.fromFixedBytes(b), + ]); + + return result[0].toBoolean(); + } + + try_lt(a: Bytes, b: Bytes): ethereum.CallResult { + let result = super.tryCall("lt", "lt(bytes32,bytes32):(bool)", [ + ethereum.Value.fromFixedBytes(a), + ethereum.Value.fromFixedBytes(b), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBoolean()); + } + + lte(a: Bytes, b: Bytes): boolean { + let result = super.call("lte", "lte(bytes32,bytes32):(bool)", [ + ethereum.Value.fromFixedBytes(a), + ethereum.Value.fromFixedBytes(b), + ]); + + return result[0].toBoolean(); + } + + try_lte(a: Bytes, b: Bytes): ethereum.CallResult { + let result = super.tryCall("lte", "lte(bytes32,bytes32):(bool)", [ + ethereum.Value.fromFixedBytes(a), + ethereum.Value.fromFixedBytes(b), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBoolean()); + } + + max(a: Bytes, b: Bytes): Bytes { + let result = super.call("max", "max(bytes32,bytes32):(bytes32)", [ + ethereum.Value.fromFixedBytes(a), + ethereum.Value.fromFixedBytes(b), + ]); + + return result[0].toBytes(); + } + + try_max(a: Bytes, b: Bytes): ethereum.CallResult { + let result = super.tryCall("max", "max(bytes32,bytes32):(bytes32)", [ + ethereum.Value.fromFixedBytes(a), + ethereum.Value.fromFixedBytes(b), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBytes()); + } + + maxNegativeValue(): Bytes { + let result = super.call( + "maxNegativeValue", + "maxNegativeValue():(bytes32)", + [], + ); + + return result[0].toBytes(); + } + + try_maxNegativeValue(): ethereum.CallResult { + let result = super.tryCall( + "maxNegativeValue", + "maxNegativeValue():(bytes32)", + [], + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBytes()); + } + + maxPositiveValue(): Bytes { + let result = super.call( + "maxPositiveValue", + "maxPositiveValue():(bytes32)", + [], + ); + + return result[0].toBytes(); + } + + try_maxPositiveValue(): ethereum.CallResult { + let result = super.tryCall( + "maxPositiveValue", + "maxPositiveValue():(bytes32)", + [], + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBytes()); + } + + min(a: Bytes, b: Bytes): Bytes { + let result = super.call("min", "min(bytes32,bytes32):(bytes32)", [ + ethereum.Value.fromFixedBytes(a), + ethereum.Value.fromFixedBytes(b), + ]); + + return result[0].toBytes(); + } + + try_min(a: Bytes, b: Bytes): ethereum.CallResult { + let result = super.tryCall("min", "min(bytes32,bytes32):(bytes32)", [ + ethereum.Value.fromFixedBytes(a), + ethereum.Value.fromFixedBytes(b), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBytes()); + } + + minNegativeValue(): Bytes { + let result = super.call( + "minNegativeValue", + "minNegativeValue():(bytes32)", + [], + ); + + return result[0].toBytes(); + } + + try_minNegativeValue(): ethereum.CallResult { + let result = super.tryCall( + "minNegativeValue", + "minNegativeValue():(bytes32)", + [], + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBytes()); + } + + minPositiveValue(): Bytes { + let result = super.call( + "minPositiveValue", + "minPositiveValue():(bytes32)", + [], + ); + + return result[0].toBytes(); + } + + try_minPositiveValue(): ethereum.CallResult { + let result = super.tryCall( + "minPositiveValue", + "minPositiveValue():(bytes32)", + [], + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBytes()); + } + + minus(a: Bytes): Bytes { + let result = super.call("minus", "minus(bytes32):(bytes32)", [ + ethereum.Value.fromFixedBytes(a), + ]); + + return result[0].toBytes(); + } + + try_minus(a: Bytes): ethereum.CallResult { + let result = super.tryCall("minus", "minus(bytes32):(bytes32)", [ + ethereum.Value.fromFixedBytes(a), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBytes()); + } + + mul(a: Bytes, b: Bytes): Bytes { + let result = super.call("mul", "mul(bytes32,bytes32):(bytes32)", [ + ethereum.Value.fromFixedBytes(a), + ethereum.Value.fromFixedBytes(b), + ]); + + return result[0].toBytes(); + } + + try_mul(a: Bytes, b: Bytes): ethereum.CallResult { + let result = super.tryCall("mul", "mul(bytes32,bytes32):(bytes32)", [ + ethereum.Value.fromFixedBytes(a), + ethereum.Value.fromFixedBytes(b), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBytes()); + } + + parse(str: string): DecimalFloat__parseResult { + let result = super.call("parse", "parse(string):(bytes4,bytes32)", [ + ethereum.Value.fromString(str), + ]); + + return new DecimalFloat__parseResult( + result[0].toBytes(), + result[1].toBytes(), + ); + } + + try_parse(str: string): ethereum.CallResult { + let result = super.tryCall("parse", "parse(string):(bytes4,bytes32)", [ + ethereum.Value.fromString(str), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue( + new DecimalFloat__parseResult(value[0].toBytes(), value[1].toBytes()), + ); + } + + pow(a: Bytes, b: Bytes): Bytes { + let result = super.call("pow", "pow(bytes32,bytes32):(bytes32)", [ + ethereum.Value.fromFixedBytes(a), + ethereum.Value.fromFixedBytes(b), + ]); + + return result[0].toBytes(); + } + + try_pow(a: Bytes, b: Bytes): ethereum.CallResult { + let result = super.tryCall("pow", "pow(bytes32,bytes32):(bytes32)", [ + ethereum.Value.fromFixedBytes(a), + ethereum.Value.fromFixedBytes(b), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBytes()); + } + + pow10(a: Bytes): Bytes { + let result = super.call("pow10", "pow10(bytes32):(bytes32)", [ + ethereum.Value.fromFixedBytes(a), + ]); + + return result[0].toBytes(); + } + + try_pow10(a: Bytes): ethereum.CallResult { + let result = super.tryCall("pow10", "pow10(bytes32):(bytes32)", [ + ethereum.Value.fromFixedBytes(a), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBytes()); + } + + sqrt(a: Bytes): Bytes { + let result = super.call("sqrt", "sqrt(bytes32):(bytes32)", [ + ethereum.Value.fromFixedBytes(a), + ]); + + return result[0].toBytes(); + } + + try_sqrt(a: Bytes): ethereum.CallResult { + let result = super.tryCall("sqrt", "sqrt(bytes32):(bytes32)", [ + ethereum.Value.fromFixedBytes(a), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBytes()); + } + + sub(a: Bytes, b: Bytes): Bytes { + let result = super.call("sub", "sub(bytes32,bytes32):(bytes32)", [ + ethereum.Value.fromFixedBytes(a), + ethereum.Value.fromFixedBytes(b), + ]); + + return result[0].toBytes(); + } + + try_sub(a: Bytes, b: Bytes): ethereum.CallResult { + let result = super.tryCall("sub", "sub(bytes32,bytes32):(bytes32)", [ + ethereum.Value.fromFixedBytes(a), + ethereum.Value.fromFixedBytes(b), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBytes()); + } + + toFixedDecimalLossless(float: Bytes, decimals: i32): BigInt { + let result = super.call( + "toFixedDecimalLossless", + "toFixedDecimalLossless(bytes32,uint8):(uint256)", + [ + ethereum.Value.fromFixedBytes(float), + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(decimals)), + ], + ); + + return result[0].toBigInt(); + } + + try_toFixedDecimalLossless( + float: Bytes, + decimals: i32, + ): ethereum.CallResult { + let result = super.tryCall( + "toFixedDecimalLossless", + "toFixedDecimalLossless(bytes32,uint8):(uint256)", + [ + ethereum.Value.fromFixedBytes(float), + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(decimals)), + ], + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBigInt()); + } + + toFixedDecimalLossy( + float: Bytes, + decimals: i32, + ): DecimalFloat__toFixedDecimalLossyResult { + let result = super.call( + "toFixedDecimalLossy", + "toFixedDecimalLossy(bytes32,uint8):(uint256,bool)", + [ + ethereum.Value.fromFixedBytes(float), + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(decimals)), + ], + ); + + return new DecimalFloat__toFixedDecimalLossyResult( + result[0].toBigInt(), + result[1].toBoolean(), + ); + } + + try_toFixedDecimalLossy( + float: Bytes, + decimals: i32, + ): ethereum.CallResult { + let result = super.tryCall( + "toFixedDecimalLossy", + "toFixedDecimalLossy(bytes32,uint8):(uint256,bool)", + [ + ethereum.Value.fromFixedBytes(float), + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(decimals)), + ], + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue( + new DecimalFloat__toFixedDecimalLossyResult( + value[0].toBigInt(), + value[1].toBoolean(), + ), + ); + } + + zero(): Bytes { + let result = super.call("zero", "zero():(bytes32)", []); + + return result[0].toBytes(); + } + + try_zero(): ethereum.CallResult { + let result = super.tryCall("zero", "zero():(bytes32)", []); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBytes()); + } +} + +export class ConstructorCall extends ethereum.Call { + get inputs(): ConstructorCall__Inputs { + return new ConstructorCall__Inputs(this); + } + + get outputs(): ConstructorCall__Outputs { + return new ConstructorCall__Outputs(this); + } +} + +export class ConstructorCall__Inputs { + _call: ConstructorCall; + + constructor(call: ConstructorCall) { + this._call = call; + } +} + +export class ConstructorCall__Outputs { + _call: ConstructorCall; + + constructor(call: ConstructorCall) { + this._call = call; + } +} diff --git a/subgraph/generated/Raindex/ERC20.ts b/subgraph/generated/Raindex/ERC20.ts new file mode 100644 index 0000000000..c7309f63b7 --- /dev/null +++ b/subgraph/generated/Raindex/ERC20.ts @@ -0,0 +1,366 @@ +// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. + +import { + ethereum, + JSONValue, + TypedMap, + Entity, + Bytes, + Address, + BigInt, +} from "@graphprotocol/graph-ts"; + +export class Approval extends ethereum.Event { + get params(): Approval__Params { + return new Approval__Params(this); + } +} + +export class Approval__Params { + _event: Approval; + + constructor(event: Approval) { + this._event = event; + } + + get owner(): Address { + return this._event.parameters[0].value.toAddress(); + } + + get spender(): Address { + return this._event.parameters[1].value.toAddress(); + } + + get value(): BigInt { + return this._event.parameters[2].value.toBigInt(); + } +} + +export class Transfer extends ethereum.Event { + get params(): Transfer__Params { + return new Transfer__Params(this); + } +} + +export class Transfer__Params { + _event: Transfer; + + constructor(event: Transfer) { + this._event = event; + } + + get from(): Address { + return this._event.parameters[0].value.toAddress(); + } + + get to(): Address { + return this._event.parameters[1].value.toAddress(); + } + + get value(): BigInt { + return this._event.parameters[2].value.toBigInt(); + } +} + +export class ERC20 extends ethereum.SmartContract { + static bind(address: Address): ERC20 { + return new ERC20("ERC20", address); + } + + allowance(owner: Address, spender: Address): BigInt { + let result = super.call( + "allowance", + "allowance(address,address):(uint256)", + [ethereum.Value.fromAddress(owner), ethereum.Value.fromAddress(spender)], + ); + + return result[0].toBigInt(); + } + + try_allowance(owner: Address, spender: Address): ethereum.CallResult { + let result = super.tryCall( + "allowance", + "allowance(address,address):(uint256)", + [ethereum.Value.fromAddress(owner), ethereum.Value.fromAddress(spender)], + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBigInt()); + } + + approve(spender: Address, value: BigInt): boolean { + let result = super.call("approve", "approve(address,uint256):(bool)", [ + ethereum.Value.fromAddress(spender), + ethereum.Value.fromUnsignedBigInt(value), + ]); + + return result[0].toBoolean(); + } + + try_approve(spender: Address, value: BigInt): ethereum.CallResult { + let result = super.tryCall("approve", "approve(address,uint256):(bool)", [ + ethereum.Value.fromAddress(spender), + ethereum.Value.fromUnsignedBigInt(value), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBoolean()); + } + + balanceOf(account: Address): BigInt { + let result = super.call("balanceOf", "balanceOf(address):(uint256)", [ + ethereum.Value.fromAddress(account), + ]); + + return result[0].toBigInt(); + } + + try_balanceOf(account: Address): ethereum.CallResult { + let result = super.tryCall("balanceOf", "balanceOf(address):(uint256)", [ + ethereum.Value.fromAddress(account), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBigInt()); + } + + decimals(): i32 { + let result = super.call("decimals", "decimals():(uint8)", []); + + return result[0].toI32(); + } + + try_decimals(): ethereum.CallResult { + let result = super.tryCall("decimals", "decimals():(uint8)", []); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toI32()); + } + + name(): string { + let result = super.call("name", "name():(string)", []); + + return result[0].toString(); + } + + try_name(): ethereum.CallResult { + let result = super.tryCall("name", "name():(string)", []); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toString()); + } + + symbol(): string { + let result = super.call("symbol", "symbol():(string)", []); + + return result[0].toString(); + } + + try_symbol(): ethereum.CallResult { + let result = super.tryCall("symbol", "symbol():(string)", []); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toString()); + } + + totalSupply(): BigInt { + let result = super.call("totalSupply", "totalSupply():(uint256)", []); + + return result[0].toBigInt(); + } + + try_totalSupply(): ethereum.CallResult { + let result = super.tryCall("totalSupply", "totalSupply():(uint256)", []); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBigInt()); + } + + transfer(to: Address, value: BigInt): boolean { + let result = super.call("transfer", "transfer(address,uint256):(bool)", [ + ethereum.Value.fromAddress(to), + ethereum.Value.fromUnsignedBigInt(value), + ]); + + return result[0].toBoolean(); + } + + try_transfer(to: Address, value: BigInt): ethereum.CallResult { + let result = super.tryCall("transfer", "transfer(address,uint256):(bool)", [ + ethereum.Value.fromAddress(to), + ethereum.Value.fromUnsignedBigInt(value), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBoolean()); + } + + transferFrom(from: Address, to: Address, value: BigInt): boolean { + let result = super.call( + "transferFrom", + "transferFrom(address,address,uint256):(bool)", + [ + ethereum.Value.fromAddress(from), + ethereum.Value.fromAddress(to), + ethereum.Value.fromUnsignedBigInt(value), + ], + ); + + return result[0].toBoolean(); + } + + try_transferFrom( + from: Address, + to: Address, + value: BigInt, + ): ethereum.CallResult { + let result = super.tryCall( + "transferFrom", + "transferFrom(address,address,uint256):(bool)", + [ + ethereum.Value.fromAddress(from), + ethereum.Value.fromAddress(to), + ethereum.Value.fromUnsignedBigInt(value), + ], + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBoolean()); + } +} + +export class ApproveCall extends ethereum.Call { + get inputs(): ApproveCall__Inputs { + return new ApproveCall__Inputs(this); + } + + get outputs(): ApproveCall__Outputs { + return new ApproveCall__Outputs(this); + } +} + +export class ApproveCall__Inputs { + _call: ApproveCall; + + constructor(call: ApproveCall) { + this._call = call; + } + + get spender(): Address { + return this._call.inputValues[0].value.toAddress(); + } + + get value(): BigInt { + return this._call.inputValues[1].value.toBigInt(); + } +} + +export class ApproveCall__Outputs { + _call: ApproveCall; + + constructor(call: ApproveCall) { + this._call = call; + } + + get value0(): boolean { + return this._call.outputValues[0].value.toBoolean(); + } +} + +export class TransferCall extends ethereum.Call { + get inputs(): TransferCall__Inputs { + return new TransferCall__Inputs(this); + } + + get outputs(): TransferCall__Outputs { + return new TransferCall__Outputs(this); + } +} + +export class TransferCall__Inputs { + _call: TransferCall; + + constructor(call: TransferCall) { + this._call = call; + } + + get to(): Address { + return this._call.inputValues[0].value.toAddress(); + } + + get value(): BigInt { + return this._call.inputValues[1].value.toBigInt(); + } +} + +export class TransferCall__Outputs { + _call: TransferCall; + + constructor(call: TransferCall) { + this._call = call; + } + + get value0(): boolean { + return this._call.outputValues[0].value.toBoolean(); + } +} + +export class TransferFromCall extends ethereum.Call { + get inputs(): TransferFromCall__Inputs { + return new TransferFromCall__Inputs(this); + } + + get outputs(): TransferFromCall__Outputs { + return new TransferFromCall__Outputs(this); + } +} + +export class TransferFromCall__Inputs { + _call: TransferFromCall; + + constructor(call: TransferFromCall) { + this._call = call; + } + + get from(): Address { + return this._call.inputValues[0].value.toAddress(); + } + + get to(): Address { + return this._call.inputValues[1].value.toAddress(); + } + + get value(): BigInt { + return this._call.inputValues[2].value.toBigInt(); + } +} + +export class TransferFromCall__Outputs { + _call: TransferFromCall; + + constructor(call: TransferFromCall) { + this._call = call; + } + + get value0(): boolean { + return this._call.outputValues[0].value.toBoolean(); + } +} diff --git a/subgraph/generated/Raindex/Raindex.ts b/subgraph/generated/Raindex/Raindex.ts new file mode 100644 index 0000000000..fee60701d4 --- /dev/null +++ b/subgraph/generated/Raindex/Raindex.ts @@ -0,0 +1,2458 @@ +// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. + +import { + ethereum, + JSONValue, + TypedMap, + Entity, + Bytes, + Address, + BigInt, +} from "@graphprotocol/graph-ts"; + +export class AddOrderV3 extends ethereum.Event { + get params(): AddOrderV3__Params { + return new AddOrderV3__Params(this); + } +} + +export class AddOrderV3__Params { + _event: AddOrderV3; + + constructor(event: AddOrderV3) { + this._event = event; + } + + get sender(): Address { + return this._event.parameters[0].value.toAddress(); + } + + get orderHash(): Bytes { + return this._event.parameters[1].value.toBytes(); + } + + get order(): AddOrderV3OrderStruct { + return changetype( + this._event.parameters[2].value.toTuple(), + ); + } +} + +export class AddOrderV3OrderStruct extends ethereum.Tuple { + get owner(): Address { + return this[0].toAddress(); + } + + get evaluable(): AddOrderV3OrderEvaluableStruct { + return changetype(this[1].toTuple()); + } + + get validInputs(): Array { + return this[2].toTupleArray(); + } + + get validOutputs(): Array { + return this[3].toTupleArray(); + } + + get nonce(): Bytes { + return this[4].toBytes(); + } +} + +export class AddOrderV3OrderEvaluableStruct extends ethereum.Tuple { + get interpreter(): Address { + return this[0].toAddress(); + } + + get store(): Address { + return this[1].toAddress(); + } + + get bytecode(): Bytes { + return this[2].toBytes(); + } +} + +export class AddOrderV3OrderValidInputsStruct extends ethereum.Tuple { + get token(): Address { + return this[0].toAddress(); + } + + get vaultId(): Bytes { + return this[1].toBytes(); + } +} + +export class AddOrderV3OrderValidOutputsStruct extends ethereum.Tuple { + get token(): Address { + return this[0].toAddress(); + } + + get vaultId(): Bytes { + return this[1].toBytes(); + } +} + +export class AfterClearV2 extends ethereum.Event { + get params(): AfterClearV2__Params { + return new AfterClearV2__Params(this); + } +} + +export class AfterClearV2__Params { + _event: AfterClearV2; + + constructor(event: AfterClearV2) { + this._event = event; + } + + get sender(): Address { + return this._event.parameters[0].value.toAddress(); + } + + get clearStateChange(): AfterClearV2ClearStateChangeStruct { + return changetype( + this._event.parameters[1].value.toTuple(), + ); + } +} + +export class AfterClearV2ClearStateChangeStruct extends ethereum.Tuple { + get aliceOutput(): Bytes { + return this[0].toBytes(); + } + + get bobOutput(): Bytes { + return this[1].toBytes(); + } + + get aliceInput(): Bytes { + return this[2].toBytes(); + } + + get bobInput(): Bytes { + return this[3].toBytes(); + } +} + +export class ClearV3 extends ethereum.Event { + get params(): ClearV3__Params { + return new ClearV3__Params(this); + } +} + +export class ClearV3__Params { + _event: ClearV3; + + constructor(event: ClearV3) { + this._event = event; + } + + get sender(): Address { + return this._event.parameters[0].value.toAddress(); + } + + get alice(): ClearV3AliceStruct { + return changetype( + this._event.parameters[1].value.toTuple(), + ); + } + + get bob(): ClearV3BobStruct { + return changetype( + this._event.parameters[2].value.toTuple(), + ); + } + + get clearConfig(): ClearV3ClearConfigStruct { + return changetype( + this._event.parameters[3].value.toTuple(), + ); + } +} + +export class ClearV3AliceStruct extends ethereum.Tuple { + get owner(): Address { + return this[0].toAddress(); + } + + get evaluable(): ClearV3AliceEvaluableStruct { + return changetype(this[1].toTuple()); + } + + get validInputs(): Array { + return this[2].toTupleArray(); + } + + get validOutputs(): Array { + return this[3].toTupleArray(); + } + + get nonce(): Bytes { + return this[4].toBytes(); + } +} + +export class ClearV3AliceEvaluableStruct extends ethereum.Tuple { + get interpreter(): Address { + return this[0].toAddress(); + } + + get store(): Address { + return this[1].toAddress(); + } + + get bytecode(): Bytes { + return this[2].toBytes(); + } +} + +export class ClearV3AliceValidInputsStruct extends ethereum.Tuple { + get token(): Address { + return this[0].toAddress(); + } + + get vaultId(): Bytes { + return this[1].toBytes(); + } +} + +export class ClearV3AliceValidOutputsStruct extends ethereum.Tuple { + get token(): Address { + return this[0].toAddress(); + } + + get vaultId(): Bytes { + return this[1].toBytes(); + } +} + +export class ClearV3BobStruct extends ethereum.Tuple { + get owner(): Address { + return this[0].toAddress(); + } + + get evaluable(): ClearV3BobEvaluableStruct { + return changetype(this[1].toTuple()); + } + + get validInputs(): Array { + return this[2].toTupleArray(); + } + + get validOutputs(): Array { + return this[3].toTupleArray(); + } + + get nonce(): Bytes { + return this[4].toBytes(); + } +} + +export class ClearV3BobEvaluableStruct extends ethereum.Tuple { + get interpreter(): Address { + return this[0].toAddress(); + } + + get store(): Address { + return this[1].toAddress(); + } + + get bytecode(): Bytes { + return this[2].toBytes(); + } +} + +export class ClearV3BobValidInputsStruct extends ethereum.Tuple { + get token(): Address { + return this[0].toAddress(); + } + + get vaultId(): Bytes { + return this[1].toBytes(); + } +} + +export class ClearV3BobValidOutputsStruct extends ethereum.Tuple { + get token(): Address { + return this[0].toAddress(); + } + + get vaultId(): Bytes { + return this[1].toBytes(); + } +} + +export class ClearV3ClearConfigStruct extends ethereum.Tuple { + get aliceInputIOIndex(): BigInt { + return this[0].toBigInt(); + } + + get aliceOutputIOIndex(): BigInt { + return this[1].toBigInt(); + } + + get bobInputIOIndex(): BigInt { + return this[2].toBigInt(); + } + + get bobOutputIOIndex(): BigInt { + return this[3].toBigInt(); + } + + get aliceBountyVaultId(): Bytes { + return this[4].toBytes(); + } + + get bobBountyVaultId(): Bytes { + return this[5].toBytes(); + } +} + +export class ContextV2 extends ethereum.Event { + get params(): ContextV2__Params { + return new ContextV2__Params(this); + } +} + +export class ContextV2__Params { + _event: ContextV2; + + constructor(event: ContextV2) { + this._event = event; + } + + get sender(): Address { + return this._event.parameters[0].value.toAddress(); + } + + get context(): Array> { + return this._event.parameters[1].value.toBytesMatrix(); + } +} + +export class DepositV2 extends ethereum.Event { + get params(): DepositV2__Params { + return new DepositV2__Params(this); + } +} + +export class DepositV2__Params { + _event: DepositV2; + + constructor(event: DepositV2) { + this._event = event; + } + + get sender(): Address { + return this._event.parameters[0].value.toAddress(); + } + + get token(): Address { + return this._event.parameters[1].value.toAddress(); + } + + get vaultId(): Bytes { + return this._event.parameters[2].value.toBytes(); + } + + get depositAmountUint256(): BigInt { + return this._event.parameters[3].value.toBigInt(); + } +} + +export class MetaV1_2 extends ethereum.Event { + get params(): MetaV1_2__Params { + return new MetaV1_2__Params(this); + } +} + +export class MetaV1_2__Params { + _event: MetaV1_2; + + constructor(event: MetaV1_2) { + this._event = event; + } + + get sender(): Address { + return this._event.parameters[0].value.toAddress(); + } + + get subject(): Bytes { + return this._event.parameters[1].value.toBytes(); + } + + get meta(): Bytes { + return this._event.parameters[2].value.toBytes(); + } +} + +export class OrderExceedsMaxRatio extends ethereum.Event { + get params(): OrderExceedsMaxRatio__Params { + return new OrderExceedsMaxRatio__Params(this); + } +} + +export class OrderExceedsMaxRatio__Params { + _event: OrderExceedsMaxRatio; + + constructor(event: OrderExceedsMaxRatio) { + this._event = event; + } + + get sender(): Address { + return this._event.parameters[0].value.toAddress(); + } + + get owner(): Address { + return this._event.parameters[1].value.toAddress(); + } + + get orderHash(): Bytes { + return this._event.parameters[2].value.toBytes(); + } +} + +export class OrderNotFound extends ethereum.Event { + get params(): OrderNotFound__Params { + return new OrderNotFound__Params(this); + } +} + +export class OrderNotFound__Params { + _event: OrderNotFound; + + constructor(event: OrderNotFound) { + this._event = event; + } + + get sender(): Address { + return this._event.parameters[0].value.toAddress(); + } + + get owner(): Address { + return this._event.parameters[1].value.toAddress(); + } + + get orderHash(): Bytes { + return this._event.parameters[2].value.toBytes(); + } +} + +export class OrderZeroAmount extends ethereum.Event { + get params(): OrderZeroAmount__Params { + return new OrderZeroAmount__Params(this); + } +} + +export class OrderZeroAmount__Params { + _event: OrderZeroAmount; + + constructor(event: OrderZeroAmount) { + this._event = event; + } + + get sender(): Address { + return this._event.parameters[0].value.toAddress(); + } + + get owner(): Address { + return this._event.parameters[1].value.toAddress(); + } + + get orderHash(): Bytes { + return this._event.parameters[2].value.toBytes(); + } +} + +export class RemoveOrderV3 extends ethereum.Event { + get params(): RemoveOrderV3__Params { + return new RemoveOrderV3__Params(this); + } +} + +export class RemoveOrderV3__Params { + _event: RemoveOrderV3; + + constructor(event: RemoveOrderV3) { + this._event = event; + } + + get sender(): Address { + return this._event.parameters[0].value.toAddress(); + } + + get orderHash(): Bytes { + return this._event.parameters[1].value.toBytes(); + } + + get order(): RemoveOrderV3OrderStruct { + return changetype( + this._event.parameters[2].value.toTuple(), + ); + } +} + +export class RemoveOrderV3OrderStruct extends ethereum.Tuple { + get owner(): Address { + return this[0].toAddress(); + } + + get evaluable(): RemoveOrderV3OrderEvaluableStruct { + return changetype(this[1].toTuple()); + } + + get validInputs(): Array { + return this[2].toTupleArray(); + } + + get validOutputs(): Array { + return this[3].toTupleArray(); + } + + get nonce(): Bytes { + return this[4].toBytes(); + } +} + +export class RemoveOrderV3OrderEvaluableStruct extends ethereum.Tuple { + get interpreter(): Address { + return this[0].toAddress(); + } + + get store(): Address { + return this[1].toAddress(); + } + + get bytecode(): Bytes { + return this[2].toBytes(); + } +} + +export class RemoveOrderV3OrderValidInputsStruct extends ethereum.Tuple { + get token(): Address { + return this[0].toAddress(); + } + + get vaultId(): Bytes { + return this[1].toBytes(); + } +} + +export class RemoveOrderV3OrderValidOutputsStruct extends ethereum.Tuple { + get token(): Address { + return this[0].toAddress(); + } + + get vaultId(): Bytes { + return this[1].toBytes(); + } +} + +export class TakeOrderV3 extends ethereum.Event { + get params(): TakeOrderV3__Params { + return new TakeOrderV3__Params(this); + } +} + +export class TakeOrderV3__Params { + _event: TakeOrderV3; + + constructor(event: TakeOrderV3) { + this._event = event; + } + + get sender(): Address { + return this._event.parameters[0].value.toAddress(); + } + + get config(): TakeOrderV3ConfigStruct { + return changetype( + this._event.parameters[1].value.toTuple(), + ); + } + + get input(): Bytes { + return this._event.parameters[2].value.toBytes(); + } + + get output(): Bytes { + return this._event.parameters[3].value.toBytes(); + } +} + +export class TakeOrderV3ConfigStruct extends ethereum.Tuple { + get order(): TakeOrderV3ConfigOrderStruct { + return changetype(this[0].toTuple()); + } + + get inputIOIndex(): BigInt { + return this[1].toBigInt(); + } + + get outputIOIndex(): BigInt { + return this[2].toBigInt(); + } + + get signedContext(): Array { + return this[3].toTupleArray(); + } +} + +export class TakeOrderV3ConfigOrderStruct extends ethereum.Tuple { + get owner(): Address { + return this[0].toAddress(); + } + + get evaluable(): TakeOrderV3ConfigOrderEvaluableStruct { + return changetype(this[1].toTuple()); + } + + get validInputs(): Array { + return this[2].toTupleArray(); + } + + get validOutputs(): Array { + return this[3].toTupleArray(); + } + + get nonce(): Bytes { + return this[4].toBytes(); + } +} + +export class TakeOrderV3ConfigOrderEvaluableStruct extends ethereum.Tuple { + get interpreter(): Address { + return this[0].toAddress(); + } + + get store(): Address { + return this[1].toAddress(); + } + + get bytecode(): Bytes { + return this[2].toBytes(); + } +} + +export class TakeOrderV3ConfigOrderValidInputsStruct extends ethereum.Tuple { + get token(): Address { + return this[0].toAddress(); + } + + get vaultId(): Bytes { + return this[1].toBytes(); + } +} + +export class TakeOrderV3ConfigOrderValidOutputsStruct extends ethereum.Tuple { + get token(): Address { + return this[0].toAddress(); + } + + get vaultId(): Bytes { + return this[1].toBytes(); + } +} + +export class TakeOrderV3ConfigSignedContextStruct extends ethereum.Tuple { + get signer(): Address { + return this[0].toAddress(); + } + + get context(): Array { + return this[1].toBytesArray(); + } + + get signature(): Bytes { + return this[2].toBytes(); + } +} + +export class WithdrawV2 extends ethereum.Event { + get params(): WithdrawV2__Params { + return new WithdrawV2__Params(this); + } +} + +export class WithdrawV2__Params { + _event: WithdrawV2; + + constructor(event: WithdrawV2) { + this._event = event; + } + + get sender(): Address { + return this._event.parameters[0].value.toAddress(); + } + + get token(): Address { + return this._event.parameters[1].value.toAddress(); + } + + get vaultId(): Bytes { + return this._event.parameters[2].value.toBytes(); + } + + get targetAmount(): Bytes { + return this._event.parameters[3].value.toBytes(); + } + + get withdrawAmount(): Bytes { + return this._event.parameters[4].value.toBytes(); + } + + get withdrawAmountUint256(): BigInt { + return this._event.parameters[5].value.toBigInt(); + } +} + +export class Raindex__addOrder4InputOrderConfigStruct extends ethereum.Tuple { + get evaluable(): Raindex__addOrder4InputOrderConfigEvaluableStruct { + return changetype( + this[0].toTuple(), + ); + } + + get validInputs(): Array { + return this[1].toTupleArray(); + } + + get validOutputs(): Array { + return this[2].toTupleArray(); + } + + get nonce(): Bytes { + return this[3].toBytes(); + } + + get secret(): Bytes { + return this[4].toBytes(); + } + + get meta(): Bytes { + return this[5].toBytes(); + } +} + +export class Raindex__addOrder4InputOrderConfigEvaluableStruct extends ethereum.Tuple { + get interpreter(): Address { + return this[0].toAddress(); + } + + get store(): Address { + return this[1].toAddress(); + } + + get bytecode(): Bytes { + return this[2].toBytes(); + } +} + +export class Raindex__addOrder4InputOrderConfigValidInputsStruct extends ethereum.Tuple { + get token(): Address { + return this[0].toAddress(); + } + + get vaultId(): Bytes { + return this[1].toBytes(); + } +} + +export class Raindex__addOrder4InputOrderConfigValidOutputsStruct extends ethereum.Tuple { + get token(): Address { + return this[0].toAddress(); + } + + get vaultId(): Bytes { + return this[1].toBytes(); + } +} + +export class Raindex__addOrder4InputPostStruct extends ethereum.Tuple { + get evaluable(): Raindex__addOrder4InputPostEvaluableStruct { + return changetype( + this[0].toTuple(), + ); + } + + get signedContext(): Array { + return this[1].toTupleArray(); + } +} + +export class Raindex__addOrder4InputPostEvaluableStruct extends ethereum.Tuple { + get interpreter(): Address { + return this[0].toAddress(); + } + + get store(): Address { + return this[1].toAddress(); + } + + get bytecode(): Bytes { + return this[2].toBytes(); + } +} + +export class Raindex__addOrder4InputPostSignedContextStruct extends ethereum.Tuple { + get signer(): Address { + return this[0].toAddress(); + } + + get context(): Array { + return this[1].toBytesArray(); + } + + get signature(): Bytes { + return this[2].toBytes(); + } +} + +export class Raindex__quote2Result { + value0: boolean; + value1: Bytes; + value2: Bytes; + + constructor(value0: boolean, value1: Bytes, value2: Bytes) { + this.value0 = value0; + this.value1 = value1; + this.value2 = value2; + } + + toMap(): TypedMap { + let map = new TypedMap(); + map.set("value0", ethereum.Value.fromBoolean(this.value0)); + map.set("value1", ethereum.Value.fromFixedBytes(this.value1)); + map.set("value2", ethereum.Value.fromFixedBytes(this.value2)); + return map; + } + + getValue0(): boolean { + return this.value0; + } + + getValue1(): Bytes { + return this.value1; + } + + getValue2(): Bytes { + return this.value2; + } +} + +export class Raindex__quote2InputQuoteConfigStruct extends ethereum.Tuple { + get order(): Raindex__quote2InputQuoteConfigOrderStruct { + return changetype( + this[0].toTuple(), + ); + } + + get inputIOIndex(): BigInt { + return this[1].toBigInt(); + } + + get outputIOIndex(): BigInt { + return this[2].toBigInt(); + } + + get signedContext(): Array { + return this[3].toTupleArray(); + } +} + +export class Raindex__quote2InputQuoteConfigOrderStruct extends ethereum.Tuple { + get owner(): Address { + return this[0].toAddress(); + } + + get evaluable(): Raindex__quote2InputQuoteConfigOrderEvaluableStruct { + return changetype( + this[1].toTuple(), + ); + } + + get validInputs(): Array { + return this[2].toTupleArray(); + } + + get validOutputs(): Array { + return this[3].toTupleArray(); + } + + get nonce(): Bytes { + return this[4].toBytes(); + } +} + +export class Raindex__quote2InputQuoteConfigOrderEvaluableStruct extends ethereum.Tuple { + get interpreter(): Address { + return this[0].toAddress(); + } + + get store(): Address { + return this[1].toAddress(); + } + + get bytecode(): Bytes { + return this[2].toBytes(); + } +} + +export class Raindex__quote2InputQuoteConfigOrderValidInputsStruct extends ethereum.Tuple { + get token(): Address { + return this[0].toAddress(); + } + + get vaultId(): Bytes { + return this[1].toBytes(); + } +} + +export class Raindex__quote2InputQuoteConfigOrderValidOutputsStruct extends ethereum.Tuple { + get token(): Address { + return this[0].toAddress(); + } + + get vaultId(): Bytes { + return this[1].toBytes(); + } +} + +export class Raindex__quote2InputQuoteConfigSignedContextStruct extends ethereum.Tuple { + get signer(): Address { + return this[0].toAddress(); + } + + get context(): Array { + return this[1].toBytesArray(); + } + + get signature(): Bytes { + return this[2].toBytes(); + } +} + +export class Raindex__removeOrder3InputOrderStruct extends ethereum.Tuple { + get owner(): Address { + return this[0].toAddress(); + } + + get evaluable(): Raindex__removeOrder3InputOrderEvaluableStruct { + return changetype( + this[1].toTuple(), + ); + } + + get validInputs(): Array { + return this[2].toTupleArray(); + } + + get validOutputs(): Array { + return this[3].toTupleArray(); + } + + get nonce(): Bytes { + return this[4].toBytes(); + } +} + +export class Raindex__removeOrder3InputOrderEvaluableStruct extends ethereum.Tuple { + get interpreter(): Address { + return this[0].toAddress(); + } + + get store(): Address { + return this[1].toAddress(); + } + + get bytecode(): Bytes { + return this[2].toBytes(); + } +} + +export class Raindex__removeOrder3InputOrderValidInputsStruct extends ethereum.Tuple { + get token(): Address { + return this[0].toAddress(); + } + + get vaultId(): Bytes { + return this[1].toBytes(); + } +} + +export class Raindex__removeOrder3InputOrderValidOutputsStruct extends ethereum.Tuple { + get token(): Address { + return this[0].toAddress(); + } + + get vaultId(): Bytes { + return this[1].toBytes(); + } +} + +export class Raindex__removeOrder3InputPostStruct extends ethereum.Tuple { + get evaluable(): Raindex__removeOrder3InputPostEvaluableStruct { + return changetype( + this[0].toTuple(), + ); + } + + get signedContext(): Array { + return this[1].toTupleArray(); + } +} + +export class Raindex__removeOrder3InputPostEvaluableStruct extends ethereum.Tuple { + get interpreter(): Address { + return this[0].toAddress(); + } + + get store(): Address { + return this[1].toAddress(); + } + + get bytecode(): Bytes { + return this[2].toBytes(); + } +} + +export class Raindex__removeOrder3InputPostSignedContextStruct extends ethereum.Tuple { + get signer(): Address { + return this[0].toAddress(); + } + + get context(): Array { + return this[1].toBytesArray(); + } + + get signature(): Bytes { + return this[2].toBytes(); + } +} + +export class Raindex__takeOrders4Result { + value0: Bytes; + value1: Bytes; + + constructor(value0: Bytes, value1: Bytes) { + this.value0 = value0; + this.value1 = value1; + } + + toMap(): TypedMap { + let map = new TypedMap(); + map.set("value0", ethereum.Value.fromFixedBytes(this.value0)); + map.set("value1", ethereum.Value.fromFixedBytes(this.value1)); + return map; + } + + getTotalTakerInput(): Bytes { + return this.value0; + } + + getTotalTakerOutput(): Bytes { + return this.value1; + } +} + +export class Raindex__takeOrders4InputConfigStruct extends ethereum.Tuple { + get minimumIO(): Bytes { + return this[0].toBytes(); + } + + get maximumIO(): Bytes { + return this[1].toBytes(); + } + + get maximumIORatio(): Bytes { + return this[2].toBytes(); + } + + get IOIsInput(): boolean { + return this[3].toBoolean(); + } + + get orders(): Array { + return this[4].toTupleArray(); + } + + get data(): Bytes { + return this[5].toBytes(); + } +} + +export class Raindex__takeOrders4InputConfigOrdersStruct extends ethereum.Tuple { + get order(): Raindex__takeOrders4InputConfigOrdersOrderStruct { + return changetype( + this[0].toTuple(), + ); + } + + get inputIOIndex(): BigInt { + return this[1].toBigInt(); + } + + get outputIOIndex(): BigInt { + return this[2].toBigInt(); + } + + get signedContext(): Array { + return this[3].toTupleArray(); + } +} + +export class Raindex__takeOrders4InputConfigOrdersOrderStruct extends ethereum.Tuple { + get owner(): Address { + return this[0].toAddress(); + } + + get evaluable(): Raindex__takeOrders4InputConfigOrdersOrderEvaluableStruct { + return changetype( + this[1].toTuple(), + ); + } + + get validInputs(): Array { + return this[2].toTupleArray(); + } + + get validOutputs(): Array { + return this[3].toTupleArray(); + } + + get nonce(): Bytes { + return this[4].toBytes(); + } +} + +export class Raindex__takeOrders4InputConfigOrdersOrderEvaluableStruct extends ethereum.Tuple { + get interpreter(): Address { + return this[0].toAddress(); + } + + get store(): Address { + return this[1].toAddress(); + } + + get bytecode(): Bytes { + return this[2].toBytes(); + } +} + +export class Raindex__takeOrders4InputConfigOrdersOrderValidInputsStruct extends ethereum.Tuple { + get token(): Address { + return this[0].toAddress(); + } + + get vaultId(): Bytes { + return this[1].toBytes(); + } +} + +export class Raindex__takeOrders4InputConfigOrdersOrderValidOutputsStruct extends ethereum.Tuple { + get token(): Address { + return this[0].toAddress(); + } + + get vaultId(): Bytes { + return this[1].toBytes(); + } +} + +export class Raindex__takeOrders4InputConfigOrdersSignedContextStruct extends ethereum.Tuple { + get signer(): Address { + return this[0].toAddress(); + } + + get context(): Array { + return this[1].toBytesArray(); + } + + get signature(): Bytes { + return this[2].toBytes(); + } +} + +export class Raindex extends ethereum.SmartContract { + static bind(address: Address): Raindex { + return new Raindex("Raindex", address); + } + + addOrder4( + orderConfig: Raindex__addOrder4InputOrderConfigStruct, + post: Array, + ): boolean { + let result = super.call( + "addOrder4", + "addOrder4(((address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32,bytes32,bytes),((address,address,bytes),(address,bytes32[],bytes)[])[]):(bool)", + [ + ethereum.Value.fromTuple(orderConfig), + ethereum.Value.fromTupleArray(post), + ], + ); + + return result[0].toBoolean(); + } + + try_addOrder4( + orderConfig: Raindex__addOrder4InputOrderConfigStruct, + post: Array, + ): ethereum.CallResult { + let result = super.tryCall( + "addOrder4", + "addOrder4(((address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32,bytes32,bytes),((address,address,bytes),(address,bytes32[],bytes)[])[]):(bool)", + [ + ethereum.Value.fromTuple(orderConfig), + ethereum.Value.fromTupleArray(post), + ], + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBoolean()); + } + + flashFee(param0: Address, param1: BigInt): BigInt { + let result = super.call("flashFee", "flashFee(address,uint256):(uint256)", [ + ethereum.Value.fromAddress(param0), + ethereum.Value.fromUnsignedBigInt(param1), + ]); + + return result[0].toBigInt(); + } + + try_flashFee(param0: Address, param1: BigInt): ethereum.CallResult { + let result = super.tryCall( + "flashFee", + "flashFee(address,uint256):(uint256)", + [ + ethereum.Value.fromAddress(param0), + ethereum.Value.fromUnsignedBigInt(param1), + ], + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBigInt()); + } + + flashLoan( + receiver: Address, + token: Address, + amount: BigInt, + data: Bytes, + ): boolean { + let result = super.call( + "flashLoan", + "flashLoan(address,address,uint256,bytes):(bool)", + [ + ethereum.Value.fromAddress(receiver), + ethereum.Value.fromAddress(token), + ethereum.Value.fromUnsignedBigInt(amount), + ethereum.Value.fromBytes(data), + ], + ); + + return result[0].toBoolean(); + } + + try_flashLoan( + receiver: Address, + token: Address, + amount: BigInt, + data: Bytes, + ): ethereum.CallResult { + let result = super.tryCall( + "flashLoan", + "flashLoan(address,address,uint256,bytes):(bool)", + [ + ethereum.Value.fromAddress(receiver), + ethereum.Value.fromAddress(token), + ethereum.Value.fromUnsignedBigInt(amount), + ethereum.Value.fromBytes(data), + ], + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBoolean()); + } + + maxFlashLoan(token: Address): BigInt { + let result = super.call("maxFlashLoan", "maxFlashLoan(address):(uint256)", [ + ethereum.Value.fromAddress(token), + ]); + + return result[0].toBigInt(); + } + + try_maxFlashLoan(token: Address): ethereum.CallResult { + let result = super.tryCall( + "maxFlashLoan", + "maxFlashLoan(address):(uint256)", + [ethereum.Value.fromAddress(token)], + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBigInt()); + } + + multicall(data: Array): Array { + let result = super.call("multicall", "multicall(bytes[]):(bytes[])", [ + ethereum.Value.fromBytesArray(data), + ]); + + return result[0].toBytesArray(); + } + + try_multicall(data: Array): ethereum.CallResult> { + let result = super.tryCall("multicall", "multicall(bytes[]):(bytes[])", [ + ethereum.Value.fromBytesArray(data), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBytesArray()); + } + + orderExists(orderHash: Bytes): boolean { + let result = super.call("orderExists", "orderExists(bytes32):(bool)", [ + ethereum.Value.fromFixedBytes(orderHash), + ]); + + return result[0].toBoolean(); + } + + try_orderExists(orderHash: Bytes): ethereum.CallResult { + let result = super.tryCall("orderExists", "orderExists(bytes32):(bool)", [ + ethereum.Value.fromFixedBytes(orderHash), + ]); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBoolean()); + } + + quote2( + quoteConfig: Raindex__quote2InputQuoteConfigStruct, + ): Raindex__quote2Result { + let result = super.call( + "quote2", + "quote2(((address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),uint256,uint256,(address,bytes32[],bytes)[])):(bool,bytes32,bytes32)", + [ethereum.Value.fromTuple(quoteConfig)], + ); + + return new Raindex__quote2Result( + result[0].toBoolean(), + result[1].toBytes(), + result[2].toBytes(), + ); + } + + try_quote2( + quoteConfig: Raindex__quote2InputQuoteConfigStruct, + ): ethereum.CallResult { + let result = super.tryCall( + "quote2", + "quote2(((address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),uint256,uint256,(address,bytes32[],bytes)[])):(bool,bytes32,bytes32)", + [ethereum.Value.fromTuple(quoteConfig)], + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue( + new Raindex__quote2Result( + value[0].toBoolean(), + value[1].toBytes(), + value[2].toBytes(), + ), + ); + } + + removeOrder3( + order: Raindex__removeOrder3InputOrderStruct, + post: Array, + ): boolean { + let result = super.call( + "removeOrder3", + "removeOrder3((address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),((address,address,bytes),(address,bytes32[],bytes)[])[]):(bool)", + [ethereum.Value.fromTuple(order), ethereum.Value.fromTupleArray(post)], + ); + + return result[0].toBoolean(); + } + + try_removeOrder3( + order: Raindex__removeOrder3InputOrderStruct, + post: Array, + ): ethereum.CallResult { + let result = super.tryCall( + "removeOrder3", + "removeOrder3((address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),((address,address,bytes),(address,bytes32[],bytes)[])[]):(bool)", + [ethereum.Value.fromTuple(order), ethereum.Value.fromTupleArray(post)], + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBoolean()); + } + + supportsInterface(interfaceId: Bytes): boolean { + let result = super.call( + "supportsInterface", + "supportsInterface(bytes4):(bool)", + [ethereum.Value.fromFixedBytes(interfaceId)], + ); + + return result[0].toBoolean(); + } + + try_supportsInterface(interfaceId: Bytes): ethereum.CallResult { + let result = super.tryCall( + "supportsInterface", + "supportsInterface(bytes4):(bool)", + [ethereum.Value.fromFixedBytes(interfaceId)], + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBoolean()); + } + + takeOrders4( + config: Raindex__takeOrders4InputConfigStruct, + ): Raindex__takeOrders4Result { + let result = super.call( + "takeOrders4", + "takeOrders4((bytes32,bytes32,bytes32,bool,((address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),uint256,uint256,(address,bytes32[],bytes)[])[],bytes)):(bytes32,bytes32)", + [ethereum.Value.fromTuple(config)], + ); + + return new Raindex__takeOrders4Result( + result[0].toBytes(), + result[1].toBytes(), + ); + } + + try_takeOrders4( + config: Raindex__takeOrders4InputConfigStruct, + ): ethereum.CallResult { + let result = super.tryCall( + "takeOrders4", + "takeOrders4((bytes32,bytes32,bytes32,bool,((address,(address,address,bytes),(address,bytes32)[],(address,bytes32)[],bytes32),uint256,uint256,(address,bytes32[],bytes)[])[],bytes)):(bytes32,bytes32)", + [ethereum.Value.fromTuple(config)], + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue( + new Raindex__takeOrders4Result(value[0].toBytes(), value[1].toBytes()), + ); + } + + vaultBalance2(owner: Address, token: Address, vaultId: Bytes): Bytes { + let result = super.call( + "vaultBalance2", + "vaultBalance2(address,address,bytes32):(bytes32)", + [ + ethereum.Value.fromAddress(owner), + ethereum.Value.fromAddress(token), + ethereum.Value.fromFixedBytes(vaultId), + ], + ); + + return result[0].toBytes(); + } + + try_vaultBalance2( + owner: Address, + token: Address, + vaultId: Bytes, + ): ethereum.CallResult { + let result = super.tryCall( + "vaultBalance2", + "vaultBalance2(address,address,bytes32):(bytes32)", + [ + ethereum.Value.fromAddress(owner), + ethereum.Value.fromAddress(token), + ethereum.Value.fromFixedBytes(vaultId), + ], + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBytes()); + } +} + +export class AddOrder4Call extends ethereum.Call { + get inputs(): AddOrder4Call__Inputs { + return new AddOrder4Call__Inputs(this); + } + + get outputs(): AddOrder4Call__Outputs { + return new AddOrder4Call__Outputs(this); + } +} + +export class AddOrder4Call__Inputs { + _call: AddOrder4Call; + + constructor(call: AddOrder4Call) { + this._call = call; + } + + get orderConfig(): AddOrder4CallOrderConfigStruct { + return changetype( + this._call.inputValues[0].value.toTuple(), + ); + } + + get post(): Array { + return this._call.inputValues[1].value.toTupleArray(); + } +} + +export class AddOrder4Call__Outputs { + _call: AddOrder4Call; + + constructor(call: AddOrder4Call) { + this._call = call; + } + + get value0(): boolean { + return this._call.outputValues[0].value.toBoolean(); + } +} + +export class AddOrder4CallOrderConfigStruct extends ethereum.Tuple { + get evaluable(): AddOrder4CallOrderConfigEvaluableStruct { + return changetype( + this[0].toTuple(), + ); + } + + get validInputs(): Array { + return this[1].toTupleArray(); + } + + get validOutputs(): Array { + return this[2].toTupleArray(); + } + + get nonce(): Bytes { + return this[3].toBytes(); + } + + get secret(): Bytes { + return this[4].toBytes(); + } + + get meta(): Bytes { + return this[5].toBytes(); + } +} + +export class AddOrder4CallOrderConfigEvaluableStruct extends ethereum.Tuple { + get interpreter(): Address { + return this[0].toAddress(); + } + + get store(): Address { + return this[1].toAddress(); + } + + get bytecode(): Bytes { + return this[2].toBytes(); + } +} + +export class AddOrder4CallOrderConfigValidInputsStruct extends ethereum.Tuple { + get token(): Address { + return this[0].toAddress(); + } + + get vaultId(): Bytes { + return this[1].toBytes(); + } +} + +export class AddOrder4CallOrderConfigValidOutputsStruct extends ethereum.Tuple { + get token(): Address { + return this[0].toAddress(); + } + + get vaultId(): Bytes { + return this[1].toBytes(); + } +} + +export class AddOrder4CallPostStruct extends ethereum.Tuple { + get evaluable(): AddOrder4CallPostEvaluableStruct { + return changetype(this[0].toTuple()); + } + + get signedContext(): Array { + return this[1].toTupleArray(); + } +} + +export class AddOrder4CallPostEvaluableStruct extends ethereum.Tuple { + get interpreter(): Address { + return this[0].toAddress(); + } + + get store(): Address { + return this[1].toAddress(); + } + + get bytecode(): Bytes { + return this[2].toBytes(); + } +} + +export class AddOrder4CallPostSignedContextStruct extends ethereum.Tuple { + get signer(): Address { + return this[0].toAddress(); + } + + get context(): Array { + return this[1].toBytesArray(); + } + + get signature(): Bytes { + return this[2].toBytes(); + } +} + +export class Clear3Call extends ethereum.Call { + get inputs(): Clear3Call__Inputs { + return new Clear3Call__Inputs(this); + } + + get outputs(): Clear3Call__Outputs { + return new Clear3Call__Outputs(this); + } +} + +export class Clear3Call__Inputs { + _call: Clear3Call; + + constructor(call: Clear3Call) { + this._call = call; + } + + get aliceOrder(): Clear3CallAliceOrderStruct { + return changetype( + this._call.inputValues[0].value.toTuple(), + ); + } + + get bobOrder(): Clear3CallBobOrderStruct { + return changetype( + this._call.inputValues[1].value.toTuple(), + ); + } + + get clearConfig(): Clear3CallClearConfigStruct { + return changetype( + this._call.inputValues[2].value.toTuple(), + ); + } + + get aliceSignedContext(): Array { + return this._call.inputValues[3].value.toTupleArray(); + } + + get bobSignedContext(): Array { + return this._call.inputValues[4].value.toTupleArray(); + } +} + +export class Clear3Call__Outputs { + _call: Clear3Call; + + constructor(call: Clear3Call) { + this._call = call; + } +} + +export class Clear3CallAliceOrderStruct extends ethereum.Tuple { + get owner(): Address { + return this[0].toAddress(); + } + + get evaluable(): Clear3CallAliceOrderEvaluableStruct { + return changetype(this[1].toTuple()); + } + + get validInputs(): Array { + return this[2].toTupleArray(); + } + + get validOutputs(): Array { + return this[3].toTupleArray(); + } + + get nonce(): Bytes { + return this[4].toBytes(); + } +} + +export class Clear3CallAliceOrderEvaluableStruct extends ethereum.Tuple { + get interpreter(): Address { + return this[0].toAddress(); + } + + get store(): Address { + return this[1].toAddress(); + } + + get bytecode(): Bytes { + return this[2].toBytes(); + } +} + +export class Clear3CallAliceOrderValidInputsStruct extends ethereum.Tuple { + get token(): Address { + return this[0].toAddress(); + } + + get vaultId(): Bytes { + return this[1].toBytes(); + } +} + +export class Clear3CallAliceOrderValidOutputsStruct extends ethereum.Tuple { + get token(): Address { + return this[0].toAddress(); + } + + get vaultId(): Bytes { + return this[1].toBytes(); + } +} + +export class Clear3CallBobOrderStruct extends ethereum.Tuple { + get owner(): Address { + return this[0].toAddress(); + } + + get evaluable(): Clear3CallBobOrderEvaluableStruct { + return changetype(this[1].toTuple()); + } + + get validInputs(): Array { + return this[2].toTupleArray(); + } + + get validOutputs(): Array { + return this[3].toTupleArray(); + } + + get nonce(): Bytes { + return this[4].toBytes(); + } +} + +export class Clear3CallBobOrderEvaluableStruct extends ethereum.Tuple { + get interpreter(): Address { + return this[0].toAddress(); + } + + get store(): Address { + return this[1].toAddress(); + } + + get bytecode(): Bytes { + return this[2].toBytes(); + } +} + +export class Clear3CallBobOrderValidInputsStruct extends ethereum.Tuple { + get token(): Address { + return this[0].toAddress(); + } + + get vaultId(): Bytes { + return this[1].toBytes(); + } +} + +export class Clear3CallBobOrderValidOutputsStruct extends ethereum.Tuple { + get token(): Address { + return this[0].toAddress(); + } + + get vaultId(): Bytes { + return this[1].toBytes(); + } +} + +export class Clear3CallClearConfigStruct extends ethereum.Tuple { + get aliceInputIOIndex(): BigInt { + return this[0].toBigInt(); + } + + get aliceOutputIOIndex(): BigInt { + return this[1].toBigInt(); + } + + get bobInputIOIndex(): BigInt { + return this[2].toBigInt(); + } + + get bobOutputIOIndex(): BigInt { + return this[3].toBigInt(); + } + + get aliceBountyVaultId(): Bytes { + return this[4].toBytes(); + } + + get bobBountyVaultId(): Bytes { + return this[5].toBytes(); + } +} + +export class Clear3CallAliceSignedContextStruct extends ethereum.Tuple { + get signer(): Address { + return this[0].toAddress(); + } + + get context(): Array { + return this[1].toBytesArray(); + } + + get signature(): Bytes { + return this[2].toBytes(); + } +} + +export class Clear3CallBobSignedContextStruct extends ethereum.Tuple { + get signer(): Address { + return this[0].toAddress(); + } + + get context(): Array { + return this[1].toBytesArray(); + } + + get signature(): Bytes { + return this[2].toBytes(); + } +} + +export class Deposit4Call extends ethereum.Call { + get inputs(): Deposit4Call__Inputs { + return new Deposit4Call__Inputs(this); + } + + get outputs(): Deposit4Call__Outputs { + return new Deposit4Call__Outputs(this); + } +} + +export class Deposit4Call__Inputs { + _call: Deposit4Call; + + constructor(call: Deposit4Call) { + this._call = call; + } + + get token(): Address { + return this._call.inputValues[0].value.toAddress(); + } + + get vaultId(): Bytes { + return this._call.inputValues[1].value.toBytes(); + } + + get depositAmount(): Bytes { + return this._call.inputValues[2].value.toBytes(); + } + + get post(): Array { + return this._call.inputValues[3].value.toTupleArray(); + } +} + +export class Deposit4Call__Outputs { + _call: Deposit4Call; + + constructor(call: Deposit4Call) { + this._call = call; + } +} + +export class Deposit4CallPostStruct extends ethereum.Tuple { + get evaluable(): Deposit4CallPostEvaluableStruct { + return changetype(this[0].toTuple()); + } + + get signedContext(): Array { + return this[1].toTupleArray(); + } +} + +export class Deposit4CallPostEvaluableStruct extends ethereum.Tuple { + get interpreter(): Address { + return this[0].toAddress(); + } + + get store(): Address { + return this[1].toAddress(); + } + + get bytecode(): Bytes { + return this[2].toBytes(); + } +} + +export class Deposit4CallPostSignedContextStruct extends ethereum.Tuple { + get signer(): Address { + return this[0].toAddress(); + } + + get context(): Array { + return this[1].toBytesArray(); + } + + get signature(): Bytes { + return this[2].toBytes(); + } +} + +export class Entask2Call extends ethereum.Call { + get inputs(): Entask2Call__Inputs { + return new Entask2Call__Inputs(this); + } + + get outputs(): Entask2Call__Outputs { + return new Entask2Call__Outputs(this); + } +} + +export class Entask2Call__Inputs { + _call: Entask2Call; + + constructor(call: Entask2Call) { + this._call = call; + } + + get post(): Array { + return this._call.inputValues[0].value.toTupleArray(); + } +} + +export class Entask2Call__Outputs { + _call: Entask2Call; + + constructor(call: Entask2Call) { + this._call = call; + } +} + +export class Entask2CallPostStruct extends ethereum.Tuple { + get evaluable(): Entask2CallPostEvaluableStruct { + return changetype(this[0].toTuple()); + } + + get signedContext(): Array { + return this[1].toTupleArray(); + } +} + +export class Entask2CallPostEvaluableStruct extends ethereum.Tuple { + get interpreter(): Address { + return this[0].toAddress(); + } + + get store(): Address { + return this[1].toAddress(); + } + + get bytecode(): Bytes { + return this[2].toBytes(); + } +} + +export class Entask2CallPostSignedContextStruct extends ethereum.Tuple { + get signer(): Address { + return this[0].toAddress(); + } + + get context(): Array { + return this[1].toBytesArray(); + } + + get signature(): Bytes { + return this[2].toBytes(); + } +} + +export class FlashLoanCall extends ethereum.Call { + get inputs(): FlashLoanCall__Inputs { + return new FlashLoanCall__Inputs(this); + } + + get outputs(): FlashLoanCall__Outputs { + return new FlashLoanCall__Outputs(this); + } +} + +export class FlashLoanCall__Inputs { + _call: FlashLoanCall; + + constructor(call: FlashLoanCall) { + this._call = call; + } + + get receiver(): Address { + return this._call.inputValues[0].value.toAddress(); + } + + get token(): Address { + return this._call.inputValues[1].value.toAddress(); + } + + get amount(): BigInt { + return this._call.inputValues[2].value.toBigInt(); + } + + get data(): Bytes { + return this._call.inputValues[3].value.toBytes(); + } +} + +export class FlashLoanCall__Outputs { + _call: FlashLoanCall; + + constructor(call: FlashLoanCall) { + this._call = call; + } + + get value0(): boolean { + return this._call.outputValues[0].value.toBoolean(); + } +} + +export class MulticallCall extends ethereum.Call { + get inputs(): MulticallCall__Inputs { + return new MulticallCall__Inputs(this); + } + + get outputs(): MulticallCall__Outputs { + return new MulticallCall__Outputs(this); + } +} + +export class MulticallCall__Inputs { + _call: MulticallCall; + + constructor(call: MulticallCall) { + this._call = call; + } + + get data(): Array { + return this._call.inputValues[0].value.toBytesArray(); + } +} + +export class MulticallCall__Outputs { + _call: MulticallCall; + + constructor(call: MulticallCall) { + this._call = call; + } + + get results(): Array { + return this._call.outputValues[0].value.toBytesArray(); + } +} + +export class RemoveOrder3Call extends ethereum.Call { + get inputs(): RemoveOrder3Call__Inputs { + return new RemoveOrder3Call__Inputs(this); + } + + get outputs(): RemoveOrder3Call__Outputs { + return new RemoveOrder3Call__Outputs(this); + } +} + +export class RemoveOrder3Call__Inputs { + _call: RemoveOrder3Call; + + constructor(call: RemoveOrder3Call) { + this._call = call; + } + + get order(): RemoveOrder3CallOrderStruct { + return changetype( + this._call.inputValues[0].value.toTuple(), + ); + } + + get post(): Array { + return this._call.inputValues[1].value.toTupleArray(); + } +} + +export class RemoveOrder3Call__Outputs { + _call: RemoveOrder3Call; + + constructor(call: RemoveOrder3Call) { + this._call = call; + } + + get stateChanged(): boolean { + return this._call.outputValues[0].value.toBoolean(); + } +} + +export class RemoveOrder3CallOrderStruct extends ethereum.Tuple { + get owner(): Address { + return this[0].toAddress(); + } + + get evaluable(): RemoveOrder3CallOrderEvaluableStruct { + return changetype(this[1].toTuple()); + } + + get validInputs(): Array { + return this[2].toTupleArray(); + } + + get validOutputs(): Array { + return this[3].toTupleArray(); + } + + get nonce(): Bytes { + return this[4].toBytes(); + } +} + +export class RemoveOrder3CallOrderEvaluableStruct extends ethereum.Tuple { + get interpreter(): Address { + return this[0].toAddress(); + } + + get store(): Address { + return this[1].toAddress(); + } + + get bytecode(): Bytes { + return this[2].toBytes(); + } +} + +export class RemoveOrder3CallOrderValidInputsStruct extends ethereum.Tuple { + get token(): Address { + return this[0].toAddress(); + } + + get vaultId(): Bytes { + return this[1].toBytes(); + } +} + +export class RemoveOrder3CallOrderValidOutputsStruct extends ethereum.Tuple { + get token(): Address { + return this[0].toAddress(); + } + + get vaultId(): Bytes { + return this[1].toBytes(); + } +} + +export class RemoveOrder3CallPostStruct extends ethereum.Tuple { + get evaluable(): RemoveOrder3CallPostEvaluableStruct { + return changetype(this[0].toTuple()); + } + + get signedContext(): Array { + return this[1].toTupleArray(); + } +} + +export class RemoveOrder3CallPostEvaluableStruct extends ethereum.Tuple { + get interpreter(): Address { + return this[0].toAddress(); + } + + get store(): Address { + return this[1].toAddress(); + } + + get bytecode(): Bytes { + return this[2].toBytes(); + } +} + +export class RemoveOrder3CallPostSignedContextStruct extends ethereum.Tuple { + get signer(): Address { + return this[0].toAddress(); + } + + get context(): Array { + return this[1].toBytesArray(); + } + + get signature(): Bytes { + return this[2].toBytes(); + } +} + +export class TakeOrders4Call extends ethereum.Call { + get inputs(): TakeOrders4Call__Inputs { + return new TakeOrders4Call__Inputs(this); + } + + get outputs(): TakeOrders4Call__Outputs { + return new TakeOrders4Call__Outputs(this); + } +} + +export class TakeOrders4Call__Inputs { + _call: TakeOrders4Call; + + constructor(call: TakeOrders4Call) { + this._call = call; + } + + get config(): TakeOrders4CallConfigStruct { + return changetype( + this._call.inputValues[0].value.toTuple(), + ); + } +} + +export class TakeOrders4Call__Outputs { + _call: TakeOrders4Call; + + constructor(call: TakeOrders4Call) { + this._call = call; + } + + get totalTakerInput(): Bytes { + return this._call.outputValues[0].value.toBytes(); + } + + get totalTakerOutput(): Bytes { + return this._call.outputValues[1].value.toBytes(); + } +} + +export class TakeOrders4CallConfigStruct extends ethereum.Tuple { + get minimumIO(): Bytes { + return this[0].toBytes(); + } + + get maximumIO(): Bytes { + return this[1].toBytes(); + } + + get maximumIORatio(): Bytes { + return this[2].toBytes(); + } + + get IOIsInput(): boolean { + return this[3].toBoolean(); + } + + get orders(): Array { + return this[4].toTupleArray(); + } + + get data(): Bytes { + return this[5].toBytes(); + } +} + +export class TakeOrders4CallConfigOrdersStruct extends ethereum.Tuple { + get order(): TakeOrders4CallConfigOrdersOrderStruct { + return changetype( + this[0].toTuple(), + ); + } + + get inputIOIndex(): BigInt { + return this[1].toBigInt(); + } + + get outputIOIndex(): BigInt { + return this[2].toBigInt(); + } + + get signedContext(): Array { + return this[3].toTupleArray(); + } +} + +export class TakeOrders4CallConfigOrdersOrderStruct extends ethereum.Tuple { + get owner(): Address { + return this[0].toAddress(); + } + + get evaluable(): TakeOrders4CallConfigOrdersOrderEvaluableStruct { + return changetype( + this[1].toTuple(), + ); + } + + get validInputs(): Array { + return this[2].toTupleArray(); + } + + get validOutputs(): Array { + return this[3].toTupleArray(); + } + + get nonce(): Bytes { + return this[4].toBytes(); + } +} + +export class TakeOrders4CallConfigOrdersOrderEvaluableStruct extends ethereum.Tuple { + get interpreter(): Address { + return this[0].toAddress(); + } + + get store(): Address { + return this[1].toAddress(); + } + + get bytecode(): Bytes { + return this[2].toBytes(); + } +} + +export class TakeOrders4CallConfigOrdersOrderValidInputsStruct extends ethereum.Tuple { + get token(): Address { + return this[0].toAddress(); + } + + get vaultId(): Bytes { + return this[1].toBytes(); + } +} + +export class TakeOrders4CallConfigOrdersOrderValidOutputsStruct extends ethereum.Tuple { + get token(): Address { + return this[0].toAddress(); + } + + get vaultId(): Bytes { + return this[1].toBytes(); + } +} + +export class TakeOrders4CallConfigOrdersSignedContextStruct extends ethereum.Tuple { + get signer(): Address { + return this[0].toAddress(); + } + + get context(): Array { + return this[1].toBytesArray(); + } + + get signature(): Bytes { + return this[2].toBytes(); + } +} + +export class Withdraw4Call extends ethereum.Call { + get inputs(): Withdraw4Call__Inputs { + return new Withdraw4Call__Inputs(this); + } + + get outputs(): Withdraw4Call__Outputs { + return new Withdraw4Call__Outputs(this); + } +} + +export class Withdraw4Call__Inputs { + _call: Withdraw4Call; + + constructor(call: Withdraw4Call) { + this._call = call; + } + + get token(): Address { + return this._call.inputValues[0].value.toAddress(); + } + + get vaultId(): Bytes { + return this._call.inputValues[1].value.toBytes(); + } + + get targetAmount(): Bytes { + return this._call.inputValues[2].value.toBytes(); + } + + get post(): Array { + return this._call.inputValues[3].value.toTupleArray(); + } +} + +export class Withdraw4Call__Outputs { + _call: Withdraw4Call; + + constructor(call: Withdraw4Call) { + this._call = call; + } +} + +export class Withdraw4CallPostStruct extends ethereum.Tuple { + get evaluable(): Withdraw4CallPostEvaluableStruct { + return changetype(this[0].toTuple()); + } + + get signedContext(): Array { + return this[1].toTupleArray(); + } +} + +export class Withdraw4CallPostEvaluableStruct extends ethereum.Tuple { + get interpreter(): Address { + return this[0].toAddress(); + } + + get store(): Address { + return this[1].toAddress(); + } + + get bytecode(): Bytes { + return this[2].toBytes(); + } +} + +export class Withdraw4CallPostSignedContextStruct extends ethereum.Tuple { + get signer(): Address { + return this[0].toAddress(); + } + + get context(): Array { + return this[1].toBytesArray(); + } + + get signature(): Bytes { + return this[2].toBytes(); + } +} diff --git a/subgraph/generated/schema.ts b/subgraph/generated/schema.ts new file mode 100644 index 0000000000..67eb08dce0 --- /dev/null +++ b/subgraph/generated/schema.ts @@ -0,0 +1,2247 @@ +// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. + +import { + TypedMap, + Entity, + Value, + ValueKind, + store, + Bytes, + BigInt, + BigDecimal, +} from "@graphprotocol/graph-ts"; + +export class Raindex extends Entity { + constructor(id: Bytes) { + super(); + this.set("id", Value.fromBytes(id)); + } + + save(): void { + let id = this.get("id"); + assert(id != null, "Cannot save Raindex entity without an ID"); + if (id) { + assert( + id.kind == ValueKind.BYTES, + `Entities of type Raindex must have an ID of type Bytes but the id '${id.displayData()}' is of type ${id.displayKind()}`, + ); + store.set("Raindex", id.toBytes().toHexString(), this); + } + } + + static loadInBlock(id: Bytes): Raindex | null { + return changetype( + store.get_in_block("Raindex", id.toHexString()), + ); + } + + static load(id: Bytes): Raindex | null { + return changetype(store.get("Raindex", id.toHexString())); + } + + get id(): Bytes { + let value = this.get("id"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set id(value: Bytes) { + this.set("id", Value.fromBytes(value)); + } + + get orders(): OrderLoader { + return new OrderLoader( + "Raindex", + this.get("id")!.toBytes().toHexString(), + "orders", + ); + } + + get trades(): TradeLoader { + return new TradeLoader( + "Raindex", + this.get("id")!.toBytes().toHexString(), + "trades", + ); + } + + get vaults(): VaultLoader { + return new VaultLoader( + "Raindex", + this.get("id")!.toBytes().toHexString(), + "vaults", + ); + } + + get deposits(): DepositLoader { + return new DepositLoader( + "Raindex", + this.get("id")!.toBytes().toHexString(), + "deposits", + ); + } + + get withdrawals(): WithdrawalLoader { + return new WithdrawalLoader( + "Raindex", + this.get("id")!.toBytes().toHexString(), + "withdrawals", + ); + } + + get addOrders(): AddOrderLoader { + return new AddOrderLoader( + "Raindex", + this.get("id")!.toBytes().toHexString(), + "addOrders", + ); + } + + get removeOrders(): RemoveOrderLoader { + return new RemoveOrderLoader( + "Raindex", + this.get("id")!.toBytes().toHexString(), + "removeOrders", + ); + } + + get takeOrders(): TakeOrderLoader { + return new TakeOrderLoader( + "Raindex", + this.get("id")!.toBytes().toHexString(), + "takeOrders", + ); + } +} + +export class Vault extends Entity { + constructor(id: Bytes) { + super(); + this.set("id", Value.fromBytes(id)); + } + + save(): void { + let id = this.get("id"); + assert(id != null, "Cannot save Vault entity without an ID"); + if (id) { + assert( + id.kind == ValueKind.BYTES, + `Entities of type Vault must have an ID of type Bytes but the id '${id.displayData()}' is of type ${id.displayKind()}`, + ); + store.set("Vault", id.toBytes().toHexString(), this); + } + } + + static loadInBlock(id: Bytes): Vault | null { + return changetype( + store.get_in_block("Vault", id.toHexString()), + ); + } + + static load(id: Bytes): Vault | null { + return changetype(store.get("Vault", id.toHexString())); + } + + get id(): Bytes { + let value = this.get("id"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set id(value: Bytes) { + this.set("id", Value.fromBytes(value)); + } + + get raindex(): Bytes { + let value = this.get("raindex"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set raindex(value: Bytes) { + this.set("raindex", Value.fromBytes(value)); + } + + get token(): Bytes { + let value = this.get("token"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set token(value: Bytes) { + this.set("token", Value.fromBytes(value)); + } + + get owner(): Bytes { + let value = this.get("owner"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set owner(value: Bytes) { + this.set("owner", Value.fromBytes(value)); + } + + get vaultId(): Bytes { + let value = this.get("vaultId"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set vaultId(value: Bytes) { + this.set("vaultId", Value.fromBytes(value)); + } + + get ordersAsInput(): OrderLoader { + return new OrderLoader( + "Vault", + this.get("id")!.toBytes().toHexString(), + "ordersAsInput", + ); + } + + get ordersAsOutput(): OrderLoader { + return new OrderLoader( + "Vault", + this.get("id")!.toBytes().toHexString(), + "ordersAsOutput", + ); + } + + get balance(): Bytes { + let value = this.get("balance"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set balance(value: Bytes) { + this.set("balance", Value.fromBytes(value)); + } +} + +export class Deposit extends Entity { + constructor(id: Bytes) { + super(); + this.set("id", Value.fromBytes(id)); + } + + save(): void { + let id = this.get("id"); + assert(id != null, "Cannot save Deposit entity without an ID"); + if (id) { + assert( + id.kind == ValueKind.BYTES, + `Entities of type Deposit must have an ID of type Bytes but the id '${id.displayData()}' is of type ${id.displayKind()}`, + ); + store.set("Deposit", id.toBytes().toHexString(), this); + } + } + + static loadInBlock(id: Bytes): Deposit | null { + return changetype( + store.get_in_block("Deposit", id.toHexString()), + ); + } + + static load(id: Bytes): Deposit | null { + return changetype(store.get("Deposit", id.toHexString())); + } + + get id(): Bytes { + let value = this.get("id"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set id(value: Bytes) { + this.set("id", Value.fromBytes(value)); + } + + get raindex(): Bytes { + let value = this.get("raindex"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set raindex(value: Bytes) { + this.set("raindex", Value.fromBytes(value)); + } + + get vault(): Bytes { + let value = this.get("vault"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set vault(value: Bytes) { + this.set("vault", Value.fromBytes(value)); + } + + get amount(): Bytes { + let value = this.get("amount"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set amount(value: Bytes) { + this.set("amount", Value.fromBytes(value)); + } + + get oldVaultBalance(): Bytes { + let value = this.get("oldVaultBalance"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set oldVaultBalance(value: Bytes) { + this.set("oldVaultBalance", Value.fromBytes(value)); + } + + get newVaultBalance(): Bytes { + let value = this.get("newVaultBalance"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set newVaultBalance(value: Bytes) { + this.set("newVaultBalance", Value.fromBytes(value)); + } + + get timestamp(): BigInt { + let value = this.get("timestamp"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBigInt(); + } + } + + set timestamp(value: BigInt) { + this.set("timestamp", Value.fromBigInt(value)); + } + + get transaction(): Bytes { + let value = this.get("transaction"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set transaction(value: Bytes) { + this.set("transaction", Value.fromBytes(value)); + } + + get sender(): Bytes { + let value = this.get("sender"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set sender(value: Bytes) { + this.set("sender", Value.fromBytes(value)); + } +} + +export class Withdrawal extends Entity { + constructor(id: Bytes) { + super(); + this.set("id", Value.fromBytes(id)); + } + + save(): void { + let id = this.get("id"); + assert(id != null, "Cannot save Withdrawal entity without an ID"); + if (id) { + assert( + id.kind == ValueKind.BYTES, + `Entities of type Withdrawal must have an ID of type Bytes but the id '${id.displayData()}' is of type ${id.displayKind()}`, + ); + store.set("Withdrawal", id.toBytes().toHexString(), this); + } + } + + static loadInBlock(id: Bytes): Withdrawal | null { + return changetype( + store.get_in_block("Withdrawal", id.toHexString()), + ); + } + + static load(id: Bytes): Withdrawal | null { + return changetype( + store.get("Withdrawal", id.toHexString()), + ); + } + + get id(): Bytes { + let value = this.get("id"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set id(value: Bytes) { + this.set("id", Value.fromBytes(value)); + } + + get targetAmount(): Bytes { + let value = this.get("targetAmount"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set targetAmount(value: Bytes) { + this.set("targetAmount", Value.fromBytes(value)); + } + + get raindex(): Bytes { + let value = this.get("raindex"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set raindex(value: Bytes) { + this.set("raindex", Value.fromBytes(value)); + } + + get vault(): Bytes { + let value = this.get("vault"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set vault(value: Bytes) { + this.set("vault", Value.fromBytes(value)); + } + + get amount(): Bytes { + let value = this.get("amount"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set amount(value: Bytes) { + this.set("amount", Value.fromBytes(value)); + } + + get oldVaultBalance(): Bytes { + let value = this.get("oldVaultBalance"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set oldVaultBalance(value: Bytes) { + this.set("oldVaultBalance", Value.fromBytes(value)); + } + + get newVaultBalance(): Bytes { + let value = this.get("newVaultBalance"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set newVaultBalance(value: Bytes) { + this.set("newVaultBalance", Value.fromBytes(value)); + } + + get timestamp(): BigInt { + let value = this.get("timestamp"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBigInt(); + } + } + + set timestamp(value: BigInt) { + this.set("timestamp", Value.fromBigInt(value)); + } + + get transaction(): Bytes { + let value = this.get("transaction"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set transaction(value: Bytes) { + this.set("transaction", Value.fromBytes(value)); + } + + get sender(): Bytes { + let value = this.get("sender"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set sender(value: Bytes) { + this.set("sender", Value.fromBytes(value)); + } +} + +export class TradeVaultBalanceChange extends Entity { + constructor(id: Bytes) { + super(); + this.set("id", Value.fromBytes(id)); + } + + save(): void { + let id = this.get("id"); + assert( + id != null, + "Cannot save TradeVaultBalanceChange entity without an ID", + ); + if (id) { + assert( + id.kind == ValueKind.BYTES, + `Entities of type TradeVaultBalanceChange must have an ID of type Bytes but the id '${id.displayData()}' is of type ${id.displayKind()}`, + ); + store.set("TradeVaultBalanceChange", id.toBytes().toHexString(), this); + } + } + + static loadInBlock(id: Bytes): TradeVaultBalanceChange | null { + return changetype( + store.get_in_block("TradeVaultBalanceChange", id.toHexString()), + ); + } + + static load(id: Bytes): TradeVaultBalanceChange | null { + return changetype( + store.get("TradeVaultBalanceChange", id.toHexString()), + ); + } + + get id(): Bytes { + let value = this.get("id"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set id(value: Bytes) { + this.set("id", Value.fromBytes(value)); + } + + get raindex(): Bytes { + let value = this.get("raindex"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set raindex(value: Bytes) { + this.set("raindex", Value.fromBytes(value)); + } + + get trade(): Bytes { + let value = this.get("trade"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set trade(value: Bytes) { + this.set("trade", Value.fromBytes(value)); + } + + get vault(): Bytes { + let value = this.get("vault"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set vault(value: Bytes) { + this.set("vault", Value.fromBytes(value)); + } + + get amount(): Bytes { + let value = this.get("amount"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set amount(value: Bytes) { + this.set("amount", Value.fromBytes(value)); + } + + get oldVaultBalance(): Bytes { + let value = this.get("oldVaultBalance"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set oldVaultBalance(value: Bytes) { + this.set("oldVaultBalance", Value.fromBytes(value)); + } + + get newVaultBalance(): Bytes { + let value = this.get("newVaultBalance"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set newVaultBalance(value: Bytes) { + this.set("newVaultBalance", Value.fromBytes(value)); + } + + get timestamp(): BigInt { + let value = this.get("timestamp"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBigInt(); + } + } + + set timestamp(value: BigInt) { + this.set("timestamp", Value.fromBigInt(value)); + } + + get transaction(): Bytes { + let value = this.get("transaction"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set transaction(value: Bytes) { + this.set("transaction", Value.fromBytes(value)); + } +} + +export class ClearBounty extends Entity { + constructor(id: Bytes) { + super(); + this.set("id", Value.fromBytes(id)); + } + + save(): void { + let id = this.get("id"); + assert(id != null, "Cannot save ClearBounty entity without an ID"); + if (id) { + assert( + id.kind == ValueKind.BYTES, + `Entities of type ClearBounty must have an ID of type Bytes but the id '${id.displayData()}' is of type ${id.displayKind()}`, + ); + store.set("ClearBounty", id.toBytes().toHexString(), this); + } + } + + static loadInBlock(id: Bytes): ClearBounty | null { + return changetype( + store.get_in_block("ClearBounty", id.toHexString()), + ); + } + + static load(id: Bytes): ClearBounty | null { + return changetype( + store.get("ClearBounty", id.toHexString()), + ); + } + + get id(): Bytes { + let value = this.get("id"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set id(value: Bytes) { + this.set("id", Value.fromBytes(value)); + } + + get raindex(): Bytes { + let value = this.get("raindex"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set raindex(value: Bytes) { + this.set("raindex", Value.fromBytes(value)); + } + + get sender(): Bytes { + let value = this.get("sender"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set sender(value: Bytes) { + this.set("sender", Value.fromBytes(value)); + } + + get vault(): Bytes { + let value = this.get("vault"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set vault(value: Bytes) { + this.set("vault", Value.fromBytes(value)); + } + + get amount(): Bytes { + let value = this.get("amount"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set amount(value: Bytes) { + this.set("amount", Value.fromBytes(value)); + } + + get oldVaultBalance(): Bytes { + let value = this.get("oldVaultBalance"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set oldVaultBalance(value: Bytes) { + this.set("oldVaultBalance", Value.fromBytes(value)); + } + + get newVaultBalance(): Bytes { + let value = this.get("newVaultBalance"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set newVaultBalance(value: Bytes) { + this.set("newVaultBalance", Value.fromBytes(value)); + } + + get timestamp(): BigInt { + let value = this.get("timestamp"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBigInt(); + } + } + + set timestamp(value: BigInt) { + this.set("timestamp", Value.fromBigInt(value)); + } + + get transaction(): Bytes { + let value = this.get("transaction"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set transaction(value: Bytes) { + this.set("transaction", Value.fromBytes(value)); + } +} + +export class Order extends Entity { + constructor(id: Bytes) { + super(); + this.set("id", Value.fromBytes(id)); + } + + save(): void { + let id = this.get("id"); + assert(id != null, "Cannot save Order entity without an ID"); + if (id) { + assert( + id.kind == ValueKind.BYTES, + `Entities of type Order must have an ID of type Bytes but the id '${id.displayData()}' is of type ${id.displayKind()}`, + ); + store.set("Order", id.toBytes().toHexString(), this); + } + } + + static loadInBlock(id: Bytes): Order | null { + return changetype( + store.get_in_block("Order", id.toHexString()), + ); + } + + static load(id: Bytes): Order | null { + return changetype(store.get("Order", id.toHexString())); + } + + get id(): Bytes { + let value = this.get("id"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set id(value: Bytes) { + this.set("id", Value.fromBytes(value)); + } + + get raindex(): Bytes { + let value = this.get("raindex"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set raindex(value: Bytes) { + this.set("raindex", Value.fromBytes(value)); + } + + get active(): boolean { + let value = this.get("active"); + if (!value || value.kind == ValueKind.NULL) { + return false; + } else { + return value.toBoolean(); + } + } + + set active(value: boolean) { + this.set("active", Value.fromBoolean(value)); + } + + get orderHash(): Bytes { + let value = this.get("orderHash"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set orderHash(value: Bytes) { + this.set("orderHash", Value.fromBytes(value)); + } + + get owner(): Bytes { + let value = this.get("owner"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set owner(value: Bytes) { + this.set("owner", Value.fromBytes(value)); + } + + get inputs(): Array { + let value = this.get("inputs"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytesArray(); + } + } + + set inputs(value: Array) { + this.set("inputs", Value.fromBytesArray(value)); + } + + get outputs(): Array { + let value = this.get("outputs"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytesArray(); + } + } + + set outputs(value: Array) { + this.set("outputs", Value.fromBytesArray(value)); + } + + get nonce(): Bytes { + let value = this.get("nonce"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set nonce(value: Bytes) { + this.set("nonce", Value.fromBytes(value)); + } + + get orderBytes(): Bytes { + let value = this.get("orderBytes"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set orderBytes(value: Bytes) { + this.set("orderBytes", Value.fromBytes(value)); + } + + get addEvents(): AddOrderLoader { + return new AddOrderLoader( + "Order", + this.get("id")!.toBytes().toHexString(), + "addEvents", + ); + } + + get removeEvents(): RemoveOrderLoader { + return new RemoveOrderLoader( + "Order", + this.get("id")!.toBytes().toHexString(), + "removeEvents", + ); + } + + get trades(): TradeLoader { + return new TradeLoader( + "Order", + this.get("id")!.toBytes().toHexString(), + "trades", + ); + } + + get meta(): Bytes | null { + let value = this.get("meta"); + if (!value || value.kind == ValueKind.NULL) { + return null; + } else { + return value.toBytes(); + } + } + + set meta(value: Bytes | null) { + if (!value) { + this.unset("meta"); + } else { + this.set("meta", Value.fromBytes(value)); + } + } + + get timestampAdded(): BigInt { + let value = this.get("timestampAdded"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBigInt(); + } + } + + set timestampAdded(value: BigInt) { + this.set("timestampAdded", Value.fromBigInt(value)); + } +} + +export class AddOrder extends Entity { + constructor(id: Bytes) { + super(); + this.set("id", Value.fromBytes(id)); + } + + save(): void { + let id = this.get("id"); + assert(id != null, "Cannot save AddOrder entity without an ID"); + if (id) { + assert( + id.kind == ValueKind.BYTES, + `Entities of type AddOrder must have an ID of type Bytes but the id '${id.displayData()}' is of type ${id.displayKind()}`, + ); + store.set("AddOrder", id.toBytes().toHexString(), this); + } + } + + static loadInBlock(id: Bytes): AddOrder | null { + return changetype( + store.get_in_block("AddOrder", id.toHexString()), + ); + } + + static load(id: Bytes): AddOrder | null { + return changetype(store.get("AddOrder", id.toHexString())); + } + + get id(): Bytes { + let value = this.get("id"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set id(value: Bytes) { + this.set("id", Value.fromBytes(value)); + } + + get order(): Bytes { + let value = this.get("order"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set order(value: Bytes) { + this.set("order", Value.fromBytes(value)); + } + + get raindex(): Bytes { + let value = this.get("raindex"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set raindex(value: Bytes) { + this.set("raindex", Value.fromBytes(value)); + } + + get transaction(): Bytes { + let value = this.get("transaction"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set transaction(value: Bytes) { + this.set("transaction", Value.fromBytes(value)); + } + + get sender(): Bytes { + let value = this.get("sender"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set sender(value: Bytes) { + this.set("sender", Value.fromBytes(value)); + } +} + +export class RemoveOrder extends Entity { + constructor(id: Bytes) { + super(); + this.set("id", Value.fromBytes(id)); + } + + save(): void { + let id = this.get("id"); + assert(id != null, "Cannot save RemoveOrder entity without an ID"); + if (id) { + assert( + id.kind == ValueKind.BYTES, + `Entities of type RemoveOrder must have an ID of type Bytes but the id '${id.displayData()}' is of type ${id.displayKind()}`, + ); + store.set("RemoveOrder", id.toBytes().toHexString(), this); + } + } + + static loadInBlock(id: Bytes): RemoveOrder | null { + return changetype( + store.get_in_block("RemoveOrder", id.toHexString()), + ); + } + + static load(id: Bytes): RemoveOrder | null { + return changetype( + store.get("RemoveOrder", id.toHexString()), + ); + } + + get id(): Bytes { + let value = this.get("id"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set id(value: Bytes) { + this.set("id", Value.fromBytes(value)); + } + + get order(): Bytes { + let value = this.get("order"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set order(value: Bytes) { + this.set("order", Value.fromBytes(value)); + } + + get raindex(): Bytes { + let value = this.get("raindex"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set raindex(value: Bytes) { + this.set("raindex", Value.fromBytes(value)); + } + + get transaction(): Bytes { + let value = this.get("transaction"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set transaction(value: Bytes) { + this.set("transaction", Value.fromBytes(value)); + } + + get sender(): Bytes { + let value = this.get("sender"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set sender(value: Bytes) { + this.set("sender", Value.fromBytes(value)); + } +} + +export class Trade extends Entity { + constructor(id: Bytes) { + super(); + this.set("id", Value.fromBytes(id)); + } + + save(): void { + let id = this.get("id"); + assert(id != null, "Cannot save Trade entity without an ID"); + if (id) { + assert( + id.kind == ValueKind.BYTES, + `Entities of type Trade must have an ID of type Bytes but the id '${id.displayData()}' is of type ${id.displayKind()}`, + ); + store.set("Trade", id.toBytes().toHexString(), this); + } + } + + static loadInBlock(id: Bytes): Trade | null { + return changetype( + store.get_in_block("Trade", id.toHexString()), + ); + } + + static load(id: Bytes): Trade | null { + return changetype(store.get("Trade", id.toHexString())); + } + + get id(): Bytes { + let value = this.get("id"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set id(value: Bytes) { + this.set("id", Value.fromBytes(value)); + } + + get raindex(): Bytes { + let value = this.get("raindex"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set raindex(value: Bytes) { + this.set("raindex", Value.fromBytes(value)); + } + + get order(): Bytes { + let value = this.get("order"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set order(value: Bytes) { + this.set("order", Value.fromBytes(value)); + } + + get inputVaultBalanceChange(): Bytes { + let value = this.get("inputVaultBalanceChange"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set inputVaultBalanceChange(value: Bytes) { + this.set("inputVaultBalanceChange", Value.fromBytes(value)); + } + + get outputVaultBalanceChange(): Bytes { + let value = this.get("outputVaultBalanceChange"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set outputVaultBalanceChange(value: Bytes) { + this.set("outputVaultBalanceChange", Value.fromBytes(value)); + } + + get tradeEvent(): Bytes { + let value = this.get("tradeEvent"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set tradeEvent(value: Bytes) { + this.set("tradeEvent", Value.fromBytes(value)); + } + + get timestamp(): BigInt { + let value = this.get("timestamp"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBigInt(); + } + } + + set timestamp(value: BigInt) { + this.set("timestamp", Value.fromBigInt(value)); + } +} + +export class TakeOrder extends Entity { + constructor(id: Bytes) { + super(); + this.set("id", Value.fromBytes(id)); + } + + save(): void { + let id = this.get("id"); + assert(id != null, "Cannot save TakeOrder entity without an ID"); + if (id) { + assert( + id.kind == ValueKind.BYTES, + `Entities of type TakeOrder must have an ID of type Bytes but the id '${id.displayData()}' is of type ${id.displayKind()}`, + ); + store.set("TakeOrder", id.toBytes().toHexString(), this); + } + } + + static loadInBlock(id: Bytes): TakeOrder | null { + return changetype( + store.get_in_block("TakeOrder", id.toHexString()), + ); + } + + static load(id: Bytes): TakeOrder | null { + return changetype( + store.get("TakeOrder", id.toHexString()), + ); + } + + get id(): Bytes { + let value = this.get("id"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set id(value: Bytes) { + this.set("id", Value.fromBytes(value)); + } + + get inputAmount(): Bytes { + let value = this.get("inputAmount"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set inputAmount(value: Bytes) { + this.set("inputAmount", Value.fromBytes(value)); + } + + get outputAmount(): Bytes { + let value = this.get("outputAmount"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set outputAmount(value: Bytes) { + this.set("outputAmount", Value.fromBytes(value)); + } + + get takeOrderConfigBytes(): Bytes { + let value = this.get("takeOrderConfigBytes"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set takeOrderConfigBytes(value: Bytes) { + this.set("takeOrderConfigBytes", Value.fromBytes(value)); + } + + get raindex(): Bytes { + let value = this.get("raindex"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set raindex(value: Bytes) { + this.set("raindex", Value.fromBytes(value)); + } + + get trades(): TradeLoader { + return new TradeLoader( + "TakeOrder", + this.get("id")!.toBytes().toHexString(), + "trades", + ); + } + + get transaction(): Bytes { + let value = this.get("transaction"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set transaction(value: Bytes) { + this.set("transaction", Value.fromBytes(value)); + } + + get sender(): Bytes { + let value = this.get("sender"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set sender(value: Bytes) { + this.set("sender", Value.fromBytes(value)); + } +} + +export class Clear extends Entity { + constructor(id: Bytes) { + super(); + this.set("id", Value.fromBytes(id)); + } + + save(): void { + let id = this.get("id"); + assert(id != null, "Cannot save Clear entity without an ID"); + if (id) { + assert( + id.kind == ValueKind.BYTES, + `Entities of type Clear must have an ID of type Bytes but the id '${id.displayData()}' is of type ${id.displayKind()}`, + ); + store.set("Clear", id.toBytes().toHexString(), this); + } + } + + static loadInBlock(id: Bytes): Clear | null { + return changetype( + store.get_in_block("Clear", id.toHexString()), + ); + } + + static load(id: Bytes): Clear | null { + return changetype(store.get("Clear", id.toHexString())); + } + + get id(): Bytes { + let value = this.get("id"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set id(value: Bytes) { + this.set("id", Value.fromBytes(value)); + } + + get aliceInputAmount(): Bytes { + let value = this.get("aliceInputAmount"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set aliceInputAmount(value: Bytes) { + this.set("aliceInputAmount", Value.fromBytes(value)); + } + + get aliceOutputAmount(): Bytes { + let value = this.get("aliceOutputAmount"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set aliceOutputAmount(value: Bytes) { + this.set("aliceOutputAmount", Value.fromBytes(value)); + } + + get bobInputAmount(): Bytes { + let value = this.get("bobInputAmount"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set bobInputAmount(value: Bytes) { + this.set("bobInputAmount", Value.fromBytes(value)); + } + + get bobOutputAmount(): Bytes { + let value = this.get("bobOutputAmount"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set bobOutputAmount(value: Bytes) { + this.set("bobOutputAmount", Value.fromBytes(value)); + } + + get aliceBountyAmount(): Bytes { + let value = this.get("aliceBountyAmount"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set aliceBountyAmount(value: Bytes) { + this.set("aliceBountyAmount", Value.fromBytes(value)); + } + + get bobBountyAmount(): Bytes { + let value = this.get("bobBountyAmount"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set bobBountyAmount(value: Bytes) { + this.set("bobBountyAmount", Value.fromBytes(value)); + } + + get aliceBountyVaultBalanceChange(): Bytes | null { + let value = this.get("aliceBountyVaultBalanceChange"); + if (!value || value.kind == ValueKind.NULL) { + return null; + } else { + return value.toBytes(); + } + } + + set aliceBountyVaultBalanceChange(value: Bytes | null) { + if (!value) { + this.unset("aliceBountyVaultBalanceChange"); + } else { + this.set("aliceBountyVaultBalanceChange", Value.fromBytes(value)); + } + } + + get bobBountyVaultBalanceChange(): Bytes | null { + let value = this.get("bobBountyVaultBalanceChange"); + if (!value || value.kind == ValueKind.NULL) { + return null; + } else { + return value.toBytes(); + } + } + + set bobBountyVaultBalanceChange(value: Bytes | null) { + if (!value) { + this.unset("bobBountyVaultBalanceChange"); + } else { + this.set("bobBountyVaultBalanceChange", Value.fromBytes(value)); + } + } + + get raindex(): Bytes { + let value = this.get("raindex"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set raindex(value: Bytes) { + this.set("raindex", Value.fromBytes(value)); + } + + get trades(): TradeLoader { + return new TradeLoader( + "Clear", + this.get("id")!.toBytes().toHexString(), + "trades", + ); + } + + get transaction(): Bytes { + let value = this.get("transaction"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set transaction(value: Bytes) { + this.set("transaction", Value.fromBytes(value)); + } + + get sender(): Bytes { + let value = this.get("sender"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set sender(value: Bytes) { + this.set("sender", Value.fromBytes(value)); + } +} + +export class Transaction extends Entity { + constructor(id: Bytes) { + super(); + this.set("id", Value.fromBytes(id)); + } + + save(): void { + let id = this.get("id"); + assert(id != null, "Cannot save Transaction entity without an ID"); + if (id) { + assert( + id.kind == ValueKind.BYTES, + `Entities of type Transaction must have an ID of type Bytes but the id '${id.displayData()}' is of type ${id.displayKind()}`, + ); + store.set("Transaction", id.toBytes().toHexString(), this); + } + } + + static loadInBlock(id: Bytes): Transaction | null { + return changetype( + store.get_in_block("Transaction", id.toHexString()), + ); + } + + static load(id: Bytes): Transaction | null { + return changetype( + store.get("Transaction", id.toHexString()), + ); + } + + get id(): Bytes { + let value = this.get("id"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set id(value: Bytes) { + this.set("id", Value.fromBytes(value)); + } + + get timestamp(): BigInt { + let value = this.get("timestamp"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBigInt(); + } + } + + set timestamp(value: BigInt) { + this.set("timestamp", Value.fromBigInt(value)); + } + + get blockNumber(): BigInt { + let value = this.get("blockNumber"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBigInt(); + } + } + + set blockNumber(value: BigInt) { + this.set("blockNumber", Value.fromBigInt(value)); + } + + get from(): Bytes { + let value = this.get("from"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set from(value: Bytes) { + this.set("from", Value.fromBytes(value)); + } +} + +export class ERC20 extends Entity { + constructor(id: Bytes) { + super(); + this.set("id", Value.fromBytes(id)); + } + + save(): void { + let id = this.get("id"); + assert(id != null, "Cannot save ERC20 entity without an ID"); + if (id) { + assert( + id.kind == ValueKind.BYTES, + `Entities of type ERC20 must have an ID of type Bytes but the id '${id.displayData()}' is of type ${id.displayKind()}`, + ); + store.set("ERC20", id.toBytes().toHexString(), this); + } + } + + static loadInBlock(id: Bytes): ERC20 | null { + return changetype( + store.get_in_block("ERC20", id.toHexString()), + ); + } + + static load(id: Bytes): ERC20 | null { + return changetype(store.get("ERC20", id.toHexString())); + } + + get id(): Bytes { + let value = this.get("id"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set id(value: Bytes) { + this.set("id", Value.fromBytes(value)); + } + + get address(): Bytes { + let value = this.get("address"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set address(value: Bytes) { + this.set("address", Value.fromBytes(value)); + } + + get name(): string | null { + let value = this.get("name"); + if (!value || value.kind == ValueKind.NULL) { + return null; + } else { + return value.toString(); + } + } + + set name(value: string | null) { + if (!value) { + this.unset("name"); + } else { + this.set("name", Value.fromString(value)); + } + } + + get symbol(): string | null { + let value = this.get("symbol"); + if (!value || value.kind == ValueKind.NULL) { + return null; + } else { + return value.toString(); + } + } + + set symbol(value: string | null) { + if (!value) { + this.unset("symbol"); + } else { + this.set("symbol", Value.fromString(value)); + } + } + + get decimals(): BigInt | null { + let value = this.get("decimals"); + if (!value || value.kind == ValueKind.NULL) { + return null; + } else { + return value.toBigInt(); + } + } + + set decimals(value: BigInt | null) { + if (!value) { + this.unset("decimals"); + } else { + this.set("decimals", Value.fromBigInt(value)); + } + } +} + +export class ClearTemporaryData extends Entity { + constructor(id: Bytes) { + super(); + this.set("id", Value.fromBytes(id)); + } + + save(): void { + let id = this.get("id"); + assert(id != null, "Cannot save ClearTemporaryData entity without an ID"); + if (id) { + assert( + id.kind == ValueKind.BYTES, + `Entities of type ClearTemporaryData must have an ID of type Bytes but the id '${id.displayData()}' is of type ${id.displayKind()}`, + ); + store.set("ClearTemporaryData", id.toBytes().toHexString(), this); + } + } + + static loadInBlock(id: Bytes): ClearTemporaryData | null { + return changetype( + store.get_in_block("ClearTemporaryData", id.toHexString()), + ); + } + + static load(id: Bytes): ClearTemporaryData | null { + return changetype( + store.get("ClearTemporaryData", id.toHexString()), + ); + } + + get id(): Bytes { + let value = this.get("id"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set id(value: Bytes) { + this.set("id", Value.fromBytes(value)); + } + + get aliceOrderHash(): Bytes { + let value = this.get("aliceOrderHash"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set aliceOrderHash(value: Bytes) { + this.set("aliceOrderHash", Value.fromBytes(value)); + } + + get aliceAddress(): Bytes { + let value = this.get("aliceAddress"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set aliceAddress(value: Bytes) { + this.set("aliceAddress", Value.fromBytes(value)); + } + + get aliceInputVaultId(): Bytes { + let value = this.get("aliceInputVaultId"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set aliceInputVaultId(value: Bytes) { + this.set("aliceInputVaultId", Value.fromBytes(value)); + } + + get aliceInputToken(): Bytes { + let value = this.get("aliceInputToken"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set aliceInputToken(value: Bytes) { + this.set("aliceInputToken", Value.fromBytes(value)); + } + + get aliceOutputVaultId(): Bytes { + let value = this.get("aliceOutputVaultId"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set aliceOutputVaultId(value: Bytes) { + this.set("aliceOutputVaultId", Value.fromBytes(value)); + } + + get aliceOutputToken(): Bytes { + let value = this.get("aliceOutputToken"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set aliceOutputToken(value: Bytes) { + this.set("aliceOutputToken", Value.fromBytes(value)); + } + + get aliceBounty(): Bytes { + let value = this.get("aliceBounty"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set aliceBounty(value: Bytes) { + this.set("aliceBounty", Value.fromBytes(value)); + } + + get bobOrderHash(): Bytes { + let value = this.get("bobOrderHash"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set bobOrderHash(value: Bytes) { + this.set("bobOrderHash", Value.fromBytes(value)); + } + + get bobAddress(): Bytes { + let value = this.get("bobAddress"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set bobAddress(value: Bytes) { + this.set("bobAddress", Value.fromBytes(value)); + } + + get bobInputVaultId(): Bytes { + let value = this.get("bobInputVaultId"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set bobInputVaultId(value: Bytes) { + this.set("bobInputVaultId", Value.fromBytes(value)); + } + + get bobInputToken(): Bytes { + let value = this.get("bobInputToken"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set bobInputToken(value: Bytes) { + this.set("bobInputToken", Value.fromBytes(value)); + } + + get bobOutputVaultId(): Bytes { + let value = this.get("bobOutputVaultId"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set bobOutputVaultId(value: Bytes) { + this.set("bobOutputVaultId", Value.fromBytes(value)); + } + + get bobOutputToken(): Bytes { + let value = this.get("bobOutputToken"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set bobOutputToken(value: Bytes) { + this.set("bobOutputToken", Value.fromBytes(value)); + } + + get bobBounty(): Bytes { + let value = this.get("bobBounty"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set bobBounty(value: Bytes) { + this.set("bobBounty", Value.fromBytes(value)); + } +} + +export class OrderLoader extends Entity { + _entity: string; + _field: string; + _id: string; + + constructor(entity: string, id: string, field: string) { + super(); + this._entity = entity; + this._id = id; + this._field = field; + } + + load(): Order[] { + let value = store.loadRelated(this._entity, this._id, this._field); + return changetype(value); + } +} + +export class TradeLoader extends Entity { + _entity: string; + _field: string; + _id: string; + + constructor(entity: string, id: string, field: string) { + super(); + this._entity = entity; + this._id = id; + this._field = field; + } + + load(): Trade[] { + let value = store.loadRelated(this._entity, this._id, this._field); + return changetype(value); + } +} + +export class VaultLoader extends Entity { + _entity: string; + _field: string; + _id: string; + + constructor(entity: string, id: string, field: string) { + super(); + this._entity = entity; + this._id = id; + this._field = field; + } + + load(): Vault[] { + let value = store.loadRelated(this._entity, this._id, this._field); + return changetype(value); + } +} + +export class DepositLoader extends Entity { + _entity: string; + _field: string; + _id: string; + + constructor(entity: string, id: string, field: string) { + super(); + this._entity = entity; + this._id = id; + this._field = field; + } + + load(): Deposit[] { + let value = store.loadRelated(this._entity, this._id, this._field); + return changetype(value); + } +} + +export class WithdrawalLoader extends Entity { + _entity: string; + _field: string; + _id: string; + + constructor(entity: string, id: string, field: string) { + super(); + this._entity = entity; + this._id = id; + this._field = field; + } + + load(): Withdrawal[] { + let value = store.loadRelated(this._entity, this._id, this._field); + return changetype(value); + } +} + +export class AddOrderLoader extends Entity { + _entity: string; + _field: string; + _id: string; + + constructor(entity: string, id: string, field: string) { + super(); + this._entity = entity; + this._id = id; + this._field = field; + } + + load(): AddOrder[] { + let value = store.loadRelated(this._entity, this._id, this._field); + return changetype(value); + } +} + +export class RemoveOrderLoader extends Entity { + _entity: string; + _field: string; + _id: string; + + constructor(entity: string, id: string, field: string) { + super(); + this._entity = entity; + this._id = id; + this._field = field; + } + + load(): RemoveOrder[] { + let value = store.loadRelated(this._entity, this._id, this._field); + return changetype(value); + } +} + +export class TakeOrderLoader extends Entity { + _entity: string; + _field: string; + _id: string; + + constructor(entity: string, id: string, field: string) { + super(); + this._entity = entity; + this._id = id; + this._field = field; + } + + load(): TakeOrder[] { + let value = store.loadRelated(this._entity, this._id, this._field); + return changetype(value); + } +} diff --git a/subgraph/subgraph.yaml b/subgraph/subgraph.yaml index ebcf930c56..f7e063b46e 100644 --- a/subgraph/subgraph.yaml +++ b/subgraph/subgraph.yaml @@ -19,11 +19,11 @@ dataSources: - Transaction abis: - name: Raindex - file: ../out/RaindexV6.sol/RaindexV6.json + file: ./abis/Raindex.json - name: ERC20 - file: ../out/ERC20.sol/ERC20.json + file: ./abis/ERC20.json - name: DecimalFloat - file: ../out/DecimalFloat.sol/DecimalFloat.json + file: ./abis/DecimalFloat.json eventHandlers: - event: DepositV2(address,address,bytes32,uint256) handler: handleDeposit