Skip to content

SDK Prompts: Go

Integrate the Ryze offline quote SDK (Go binding) into an existing codebase — a swap aggregator, market-making system, or any trading infrastructure that needs Ryze quotes without the latency of an HTTP round-trip. The SDK is a precompiled native engine plus a thin Go binding: it computes the exact on-chain quote math locally, synchronously, with zero network I/O.

There is one prompt per operation. Each is fully self-contained — it embeds the SDK's API surface, the wiring steps, a complete pool fixture, and golden outputs with a runnable verification script as the acceptance gate. Your agent needs zero prior knowledge of Ryze and no access to this site.

Wiring summary: go mod edit -replace github.com/ryze-protocol/ryze-sdk-go=$RYZE_SDK_DIST — cgo binding with the rpath baked in; CGO_ENABLED=1 required.

How to use

  1. Unpack the Ryze SDK tarball for your platform (ryze-sdk-go-<platform>-<arch>.tar.gz — ask the Ryze team) and export RYZE_SDK_DIST=/absolute/path/to/the/unpacked/folder.
  2. Open your AI coding agent inside the repository you want to integrate (or an empty directory for a standalone proof).
  3. Copy one prompt below and paste it as your message.
  4. Hold the result to the prompt's acceptance checklist — the verification script must run and print all-PASS.

Quotes only

The SDK computes quotes (read-path). Executing swaps/joins/exits on-chain stays exactly as documented in the intent-path prompts — pair an SDK quote prompt with the matching intent prompt when you need both.

Swap Quotes

View raw
Preview the full prompt text
md
You are integrating the **Ryze offline quote SDK** (Go binding) into this
repository so it can compute Ryze AMM **swap quotes** locally — no HTTP
call, no RPC, no network at all. Study the repo first and match its conventions
(module layout, config handling, error types, logging, test framework). If you are
instead running in an empty directory, create a minimal standalone module (run `go mod init verify-ryze` first — the wiring commands below edit an existing go.mod)
whose only purpose is the verification script defined at the end — the acceptance
gate is identical either way.

## What the SDK is

The Ryze quote SDK is a precompiled native library (`libryzesdk`) plus a thin
Go binding. It reproduces the exact quote math of the on-chain Ryze AMM (an
oracle-anchored weighted-pool DEX on Base): same integers, same rounding, same
errors. You hand it a snapshot of a pool's state; it returns the quote synchronously,
in microseconds, with zero I/O. This replaces quoting through Ryze's hosted Router
API on the hot path — same numbers, none of the latency.

It is distributed as a platform tarball: `ryze-sdk-go-<platform>-<arch>.tar.gz`
(darwin-arm64, linux-amd64, …). Obtain the tarball matching your deploy target from
the Ryze team. Throughout this prompt `$RYZE_SDK_DIST` means the absolute path of
the UNPACKED distribution folder — read it from the environment; never hardcode it
(single exception: the `replace` path in go.mod, as documented above).

## Distribution layout & wiring

```text
$RYZE_SDK_DIST/
  go.mod                  # module github.com/ryze-protocol/ryze-sdk-go (go 1.22)
  ryze.go                 # the binding: package ryzesdk (cgo)
  include/ryze_sdk.h      # C header consumed by the binding
  lib/libryzesdk.*        # the closed-source native quote engine (.dylib/.so/.dll)
  example/quote.go        # smoke example
```

**Wiring.** Point your module at the unpacked folder (substitute the actual value of
`$RYZE_SDK_DIST` — this is the one place an absolute path is acceptable):

```bash
go mod edit -require=github.com/ryze-protocol/ryze-sdk-go@v0.0.0
go mod edit -replace=github.com/ryze-protocol/ryze-sdk-go=$RYZE_SDK_DIST
go mod tidy
```

```go
import ryzesdk "github.com/ryze-protocol/ryze-sdk-go"
```

- **cgo is required**: build with `CGO_ENABLED=1` and a C toolchain installed.
- The binding bakes an rpath to its own `lib/` dir (via `${SRCDIR}`), so no runtime
  env vars are needed as long as the distribution folder stays intact. Do not move or
  rename files inside it.
- Calls are **synchronous**; failures return an ordinary `error` whose text is the
  engine's error message.
- The request structs' `WBRConfig` field is `any` — pass a `json.RawMessage` holding
  the verbatim config object.

## The API you are integrating

```go
import ryzesdk "github.com/ryze-protocol/ryze-sdk-go"

resp, err := ryzesdk.QuoteSwap(ryzesdk.SwapRequest{ ... })  // sync

type SwapRequest struct {
    Pool             WeightedPool // pool snapshot (see fixture)
    TokenIn          string       // token address; must be one of Pool.Assets
    TokenOut         string
    AmountIn         string       // REQUIRED when IsExactIn — tokenIn base units
    AmountOut        string       // REQUIRED when !IsExactIn — tokenOut base units
    IsExactIn        bool
    NumHops          uint32       // total hops of the route; 1 for a direct swap
    IsIntentSwap     bool         // price with discounted intent fee rates
    FeeMultiplierWad string       // per-account fee discount (wad); "" for full fees
    TokenPrices      []TokenPrice // REQUIRED for SmartShield pools
    WBRConfig        any          // REQUIRED for SmartShield pools; pass json.RawMessage
}

type SwapResponse struct {
    AmountIn    string     // exact-out mode: the answer
    AmountOut   string     // exact-in mode: the answer
    PoolAddress string     // lowercase
    Path        []string   // [tokenIn, tokenOut], lowercase
    FeeDetails  FeeDetails // SwapFee/TakerFee/WbfFee/SlippageFee in tokenIn;
}                          // WbrFee (weight-breaking REWARD) in tokenOut
// FeeDetails components are FeeAsset{ Token, Amount string }
```

`WeightedPool`, `WeightedPoolAsset`, `PoolParameters`, `TokenPrice` etc. are all
declared in the distribution's `ryze.go` with camelCase JSON tags — the fixture below
unmarshals directly into them.

## Non-negotiable semantics

- Every amount, balance, weight, fee, and price is a **base-10 integer string** in
  base units. Never let a float touch any of these values — not in parsing, not in
  display math inside the quote path.
- "Wad" fields are 18-decimal fixed point: 1e18 = 1.0 (= 100% for rates/weights).
- `pool` is a point-in-time snapshot. In production hydrate it from the Ryze API
  (`GET {RYZE_API_URL}/pools` — mainnet `https://mainnet.api.ryze.pro/api`, testnet
  `https://sepolia.api.ryze.pro/api`) or your own indexer, and re-quote when state
  changes. The SDK is deterministic: stale input means stale quote. The verification
  script below uses the embedded fixture INSTEAD of any network fetch.
- `pool.assets` order is canonical — preserve it in every array you build.
- SmartShield pools (`smartShieldEnabled: true` — the fixture pool is one) price
  against the oracle. For them BOTH `tokenPrices` AND `wbrConfig` are REQUIRED and
  travel together: omitting `tokenPrices` fails with `WeightedPoolMathError("Token price not found")`;
  supplying prices but omitting `wbrConfig` fails with
  `WeightBreakingRewardError("Config not loaded")`. Pass `wbrConfig` through
  VERBATIM as one opaque JSON object, exactly as the Ryze API returns it — never
  interpret, rename, filter, or re-derive its fields.
- `tokenPrices` are USD per WHOLE token in wad (1e18 = $1.00) — e.g. the fixture
  prices USDC at $0.9997 and WETH at $1662.50.
- Responses echo all addresses in **lowercase**. Compare addresses
  case-insensitively everywhere.
- Engine errors are terse Solidity-style strings (`InvalidSlippage()`,
  `WeightedPoolMathError("...")`). Treat them as opaque: assert on them in tests,
  never branch on them in production logic.
- **Exact-in vs exact-out** is one flag: `isExactIn` decides which of
  `amountIn`/`amountOut` you provide; the engine returns the other.
- **numHops** is the total hop count of the enclosing route (fees derate for
  multi-hop routes). A direct pool swap is `1`. For an N-hop route your router quotes
  each hop separately with `numHops: N`, feeding each hop's output into the next.
- The weight-breaking reward (`wbrFee`) is denominated in the OUTPUT token and is
  paid on top of `amountOut` on-chain — an aggregator comparing venues should rank by
  `amountOut + wbrFee.amount` when the reward token equals tokenOut.

## Deliverable 1 — the integration module

Expose one narrow, typed function shaped for a router/aggregator integration —
for example `quoteRyzeSwap(pool, tokenIn, tokenOut, amountIn, opts)` returning the
output amount plus the fee breakdown, and its exact-out twin — where `opts` carries
the pass-through inputs (`numHops`, `isIntentSwap`, `feeMultiplierWad`,
`tokenPrices`, `wbrConfig`; the last two are required for SmartShield pools). Internally it must do nothing
but validate inputs, assemble the SDK request, call the SDK, and map the response into
your codebase's own types. Do NOT post-process the numbers: no rounding, no fee
re-derivation, no float conversion — the SDK's integers are the on-chain truth.

Example names above are illustrative — adapt them to this language's and this repo's
conventions (snake_case in Rust, exported PascalCase in Go, camelCase in TypeScript).

## Deliverable 2 — standalone verification script (the acceptance gate)

Create `cmd/verify-ryze-swap/main.go` (repo mode) or `main.go` of a fresh module (standalone mode); run with `go run`.

The script must be fully self-contained: it embeds the fixture below verbatim, calls
the SDK through YOUR integration module (not around it), checks every assertion in
the table, prints one `PASS <name>` / `FAIL <name> expected=<e> got=<g>` line per
assertion (a table row that bundles several fields may emit one line per field), and
exits 0 only if every assertion passed. For the negative case: check the returned `error`'s text.

Golden values below were produced by this exact SDK build from this exact fixture —
they are deterministic. An off-by-one is a real failure; investigate your request
construction before suspecting the goldens.

### Fixture (embed verbatim — tokens are USDC, 6 decimals, and WETH, 18 decimals)

```json
{
  "pool": {
    "address": "0x0000000000000000000000000000000000001001",
    "totalSupplyLP": "1000000000000000000000",
    "parameters": {
      "swapFeeWad": "1000000000000000",
      "takerFeeWad": "500000000000000",
      "smartShieldEnabled": true,
      "smartShieldParams": {
        "thresholdWeightDiffWad": "10000000000000000",
        "minOracleWeightWad": "150000000000000000"
      },
      "intentSwapFeeWad": "400000000000000",
      "intentTakerFeeWad": "200000000000000"
    },
    "assets": [
      {
        "tokenAddress": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
        "balance": "1000000000000",
        "weight": "500000000000000000",
        "decimals": 6,
        "liability": "0",
        "custody": "0",
        "externalLiquidityRatio": "2000000000000000000",
        "liquidityBands": [
          {
            "thresholdWad": "1000000000000000000000",
            "ratioWad": "2000000000000000000",
            "minSlippageWad": "100000000000000"
          },
          {
            "thresholdWad": "100000000000000000000000",
            "ratioWad": "1500000000000000000",
            "minSlippageWad": "200000000000000"
          },
          {
            "thresholdWad": "1000000000000000000000000",
            "ratioWad": "1200000000000000000",
            "minSlippageWad": "400000000000000"
          }
        ]
      },
      {
        "tokenAddress": "0x4200000000000000000000000000000000000006",
        "balance": "500000000000000000000",
        "weight": "500000000000000000",
        "decimals": 18,
        "liability": "0",
        "custody": "0",
        "externalLiquidityRatio": "2000000000000000000",
        "liquidityBands": [
          {
            "thresholdWad": "1000000000000000000000",
            "ratioWad": "2000000000000000000",
            "minSlippageWad": "100000000000000"
          },
          {
            "thresholdWad": "100000000000000000000000",
            "ratioWad": "1500000000000000000",
            "minSlippageWad": "200000000000000"
          },
          {
            "thresholdWad": "1000000000000000000000000",
            "ratioWad": "1200000000000000000",
            "minSlippageWad": "400000000000000"
          }
        ]
      }
    ]
  },
  "tokenPrices": [
    {
      "token": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "priceWad": "999700000000000000"
    },
    {
      "token": "0x4200000000000000000000000000000000000006",
      "priceWad": "1662500000000000000000"
    }
  ],
  "wbrConfig": {
    "wad": "1000000000000000000",
    "maxWbfWad": "990000000000000000",
    "maxExpArgWad": "20000000000000000000",
    "maxFeeBps": "10000",
    "maxSkewPenaltyWad": "40000000000000000",
    "maxWbfRateBps": "400",
    "maxWeightWad": "1000000000000000000",
    "weightThresholdWad": "550000000000000000",
    "weightThresholdLambdaWad": "600000000000000000",
    "weightThresholdLogWad": "800000000000000000",
    "weightThresholdSigmaWad": "550000000000000000",
    "weightMultiplierLogWad": "10000000000000000000",
    "weightHalfWad": "500000000000000000",
    "bQuoteAdjustmentWad": "0",
    "bOverflowCap": "1000000000000000000000000000000",
    "bSAnchorS": [
      "250000000000000000000",
      "1000000000000000000000",
      "10000000000000000000000",
      "100000000000000000000000",
      "500000000000000000000000",
      "1000000000000000000000000",
      "2500000000000000000000000",
      "5000000000000000000000000"
    ],
    "bSAnchorBpsWad": [
      "0",
      "2000000000000000000",
      "3000000000000000000",
      "6000000000000000000",
      "11000000000000000000",
      "15000000000000000000",
      "25000000000000000000",
      "45000000000000000000"
    ],
    "bSNumAnchors": "8",
    "fPowMultiplier": "5",
    "fPowExponentWad": "2500000000000000000",
    "fLogExponentMultiplier": "10",
    "fLogOverflowDivisor": "10",
    "smoothstepCoeff1": "3000000000000000000",
    "smoothstepCoeff2": "2000000000000000000",
    "wrrDivisor": "2",
    "wrrMaxBps": "200",
    "wrrWeightMaxWad": "850000000000000000",
    "basisPointsDivisor": "10000",
    "bpsToWadMultiplier": "100000000000000"
  }
}
```

### Assertions

| # | Call | Expected (assert EXACTLY) |
|---|---|---|
| 1 | exact-in: `tokenIn`=USDC, `tokenOut`=WETH, `amountIn`="1000000000", `isExactIn`=true, `numHops`=1, with fixture `tokenPrices`+`wbrConfig` | `amountOut` = "599970135642316143" |
| 2 | same response | `feeDetails`: swapFee.amount="1000000", takerFee.amount="500000", wbfFee.amount="199956", slippageFee.amount="550367" (all in USDC); wbrFee.amount="0" with wbrFee.token = WETH (lowercase) |
| 3 | same response | `path` = [USDC, WETH] both lowercase |
| 4 | exact-out: same pair, `amountOut`="599970135642316143", `isExactIn`=false, `numHops`=1, prices+wbrConfig | `amountIn` = "999999042" (round-trips to ~the 1000 USDC of #1) |
| 5 | NEGATIVE — repeat #1 but omit `tokenPrices` entirely | the call FAILS and the error text contains `Token price not found` |

## Hard rules

- No network calls anywhere in the quote path or the verification script.
- No floats in amount handling; no silent re-rounding of SDK outputs.
- Do not modify, move, or rename anything inside `$RYZE_SDK_DIST`.
- Do not reimplement or "simplify" the quote math from observed outputs — the SDK is
  the only source of Ryze numbers in this codebase.
- Keep the wbrConfig object opaque wherever it appears.

## Acceptance checklist (verify each before declaring done)

- [ ] SDK wired via `$RYZE_SDK_DIST` (only go.mod may contain the literal SDK path)
- [ ] Integration module exposes the typed function(s) described above, in this
      repo's own conventions
- [ ] Verification script exists, runs offline, prints one PASS/FAIL line per
      assertion, and exits 0 with every assertion passing
- [ ] All amounts handled as integer strings end-to-end
- [ ] Exact-in and exact-out both work through the public function(s) you exposed
- [ ] The negative test asserts the failure, i.e. a successful quote there is a FAIL
- [ ] You actually RAN the verification script and pasted its output in your summary

Single-Asset Join Quotes

View raw
Preview the full prompt text
md
You are integrating the **Ryze offline quote SDK** (Go binding) into this
repository so it can compute Ryze AMM **single-asset join quotes** locally — no HTTP
call, no RPC, no network at all. Study the repo first and match its conventions
(module layout, config handling, error types, logging, test framework). If you are
instead running in an empty directory, create a minimal standalone module (run `go mod init verify-ryze` first — the wiring commands below edit an existing go.mod)
whose only purpose is the verification script defined at the end — the acceptance
gate is identical either way.

## What the SDK is

The Ryze quote SDK is a precompiled native library (`libryzesdk`) plus a thin
Go binding. It reproduces the exact quote math of the on-chain Ryze AMM (an
oracle-anchored weighted-pool DEX on Base): same integers, same rounding, same
errors. You hand it a snapshot of a pool's state; it returns the quote synchronously,
in microseconds, with zero I/O. This replaces quoting through Ryze's hosted Router
API on the hot path — same numbers, none of the latency.

It is distributed as a platform tarball: `ryze-sdk-go-<platform>-<arch>.tar.gz`
(darwin-arm64, linux-amd64, …). Obtain the tarball matching your deploy target from
the Ryze team. Throughout this prompt `$RYZE_SDK_DIST` means the absolute path of
the UNPACKED distribution folder — read it from the environment; never hardcode it
(single exception: the `replace` path in go.mod, as documented above).

## Distribution layout & wiring

```text
$RYZE_SDK_DIST/
  go.mod                  # module github.com/ryze-protocol/ryze-sdk-go (go 1.22)
  ryze.go                 # the binding: package ryzesdk (cgo)
  include/ryze_sdk.h      # C header consumed by the binding
  lib/libryzesdk.*        # the closed-source native quote engine (.dylib/.so/.dll)
  example/quote.go        # smoke example
```

**Wiring.** Point your module at the unpacked folder (substitute the actual value of
`$RYZE_SDK_DIST` — this is the one place an absolute path is acceptable):

```bash
go mod edit -require=github.com/ryze-protocol/ryze-sdk-go@v0.0.0
go mod edit -replace=github.com/ryze-protocol/ryze-sdk-go=$RYZE_SDK_DIST
go mod tidy
```

```go
import ryzesdk "github.com/ryze-protocol/ryze-sdk-go"
```

- **cgo is required**: build with `CGO_ENABLED=1` and a C toolchain installed.
- The binding bakes an rpath to its own `lib/` dir (via `${SRCDIR}`), so no runtime
  env vars are needed as long as the distribution folder stays intact. Do not move or
  rename files inside it.
- Calls are **synchronous**; failures return an ordinary `error` whose text is the
  engine's error message.
- The request structs' `WBRConfig` field is `any` — pass a `json.RawMessage` holding
  the verbatim config object.

## The API you are integrating

```go
import ryzesdk "github.com/ryze-protocol/ryze-sdk-go"

resp, err := ryzesdk.QuoteSingleAssetJoin(ryzesdk.SingleJoinRequest{ ... })  // sync

type SingleJoinRequest struct {
    Pool             WeightedPool
    TokenIn          string       // the single token being deposited
    AmountIn         string       // base units of TokenIn
    IsIntentSwap     bool         // price with discounted intent fee rates
    FeeMultiplierWad string       // per-account fee discount (wad); "" for full fees
    TokenPrices      []TokenPrice // REQUIRED for SmartShield pools
    WBRConfig        any          // REQUIRED for SmartShield pools; pass json.RawMessage
}

type SingleJoinResponse struct {
    AmountIn      string     // echo of the deposit
    PoolSharesOut string     // LP tokens minted (18 decimals)
    PoolAddress   string     // lowercase
    TVL           string     // pool TVL in USD, wad (1e18 = $1)
    FeeDetails    FeeDetails // fees charged in TokenIn; WbrFee in the other pool token
}
```

All binding types are declared in the distribution's `ryze.go` with camelCase JSON
tags — the fixture below unmarshals directly into them.

## Non-negotiable semantics

- Every amount, balance, weight, fee, and price is a **base-10 integer string** in
  base units. Never let a float touch any of these values — not in parsing, not in
  display math inside the quote path.
- "Wad" fields are 18-decimal fixed point: 1e18 = 1.0 (= 100% for rates/weights).
- `pool` is a point-in-time snapshot. In production hydrate it from the Ryze API
  (`GET {RYZE_API_URL}/pools` — mainnet `https://mainnet.api.ryze.pro/api`, testnet
  `https://sepolia.api.ryze.pro/api`) or your own indexer, and re-quote when state
  changes. The SDK is deterministic: stale input means stale quote. The verification
  script below uses the embedded fixture INSTEAD of any network fetch.
- `pool.assets` order is canonical — preserve it in every array you build.
- SmartShield pools (`smartShieldEnabled: true` — the fixture pool is one) price
  against the oracle. For them BOTH `tokenPrices` AND `wbrConfig` are REQUIRED and
  travel together: omitting `tokenPrices` fails with `InvalidPriceData()`;
  supplying prices but omitting `wbrConfig` fails with
  `WeightBreakingRewardError("Config not loaded")`. Pass `wbrConfig` through
  VERBATIM as one opaque JSON object, exactly as the Ryze API returns it — never
  interpret, rename, filter, or re-derive its fields.
- `tokenPrices` are USD per WHOLE token in wad (1e18 = $1.00) — e.g. the fixture
  prices USDC at $0.9997 and WETH at $1662.50.
- Responses echo all addresses in **lowercase**. Compare addresses
  case-insensitively everywhere.
- Engine errors are terse Solidity-style strings (`InvalidSlippage()`,
  `WeightedPoolMathError("...")`). Treat them as opaque: assert on them in tests,
  never branch on them in production logic.
- A single-asset join is priced like a partial swap into the pool's other side, so it
  pays swap-type fees (that is why the response carries `feeDetails` and a
  proportional join does not).
- `tvl` is the pool's total value locked in USD wad (1e18 = $1) under the supplied
  oracle prices — useful for share-price sanity checks upstream.

## Deliverable 1 — the integration module

Expose one narrow, typed function — for example
`quoteRyzeSingleJoin(pool, tokenIn, amountIn, opts)` — returning the LP shares
minted, the pool TVL, and the fee breakdown — where `opts` carries the pass-through
inputs (`isIntentSwap`, `feeMultiplierWad`, `tokenPrices`, `wbrConfig`; the
last two are required for SmartShield pools). Internally it must do nothing but validate inputs,
assemble the SDK request, call the SDK, and map the response into your codebase's own
types. Do NOT post-process the numbers: no rounding, no fee re-derivation, no float
conversion — the SDK's integers are the on-chain truth.

Example names above are illustrative — adapt them to this language's and this repo's
conventions (snake_case in Rust, exported PascalCase in Go, camelCase in TypeScript).

## Deliverable 2 — standalone verification script (the acceptance gate)

Create `cmd/verify-ryze-join-single/main.go` (repo mode) or `main.go` of a fresh module (standalone mode); run with `go run`.

The script must be fully self-contained: it embeds the fixture below verbatim, calls
the SDK through YOUR integration module (not around it), checks every assertion in
the table, prints one `PASS <name>` / `FAIL <name> expected=<e> got=<g>` line per
assertion (a table row that bundles several fields may emit one line per field), and
exits 0 only if every assertion passed. For the negative case: check the returned `error`'s text.

Golden values below were produced by this exact SDK build from this exact fixture —
they are deterministic. An off-by-one is a real failure; investigate your request
construction before suspecting the goldens.

### Fixture (embed verbatim — tokens are USDC, 6 decimals, and WETH, 18 decimals)

```json
{
  "pool": {
    "address": "0x0000000000000000000000000000000000001001",
    "totalSupplyLP": "1000000000000000000000",
    "parameters": {
      "swapFeeWad": "1000000000000000",
      "takerFeeWad": "500000000000000",
      "smartShieldEnabled": true,
      "smartShieldParams": {
        "thresholdWeightDiffWad": "10000000000000000",
        "minOracleWeightWad": "150000000000000000"
      },
      "intentSwapFeeWad": "400000000000000",
      "intentTakerFeeWad": "200000000000000"
    },
    "assets": [
      {
        "tokenAddress": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
        "balance": "1000000000000",
        "weight": "500000000000000000",
        "decimals": 6,
        "liability": "0",
        "custody": "0",
        "externalLiquidityRatio": "2000000000000000000",
        "liquidityBands": [
          {
            "thresholdWad": "1000000000000000000000",
            "ratioWad": "2000000000000000000",
            "minSlippageWad": "100000000000000"
          },
          {
            "thresholdWad": "100000000000000000000000",
            "ratioWad": "1500000000000000000",
            "minSlippageWad": "200000000000000"
          },
          {
            "thresholdWad": "1000000000000000000000000",
            "ratioWad": "1200000000000000000",
            "minSlippageWad": "400000000000000"
          }
        ]
      },
      {
        "tokenAddress": "0x4200000000000000000000000000000000000006",
        "balance": "500000000000000000000",
        "weight": "500000000000000000",
        "decimals": 18,
        "liability": "0",
        "custody": "0",
        "externalLiquidityRatio": "2000000000000000000",
        "liquidityBands": [
          {
            "thresholdWad": "1000000000000000000000",
            "ratioWad": "2000000000000000000",
            "minSlippageWad": "100000000000000"
          },
          {
            "thresholdWad": "100000000000000000000000",
            "ratioWad": "1500000000000000000",
            "minSlippageWad": "200000000000000"
          },
          {
            "thresholdWad": "1000000000000000000000000",
            "ratioWad": "1200000000000000000",
            "minSlippageWad": "400000000000000"
          }
        ]
      }
    ]
  },
  "tokenPrices": [
    {
      "token": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "priceWad": "999700000000000000"
    },
    {
      "token": "0x4200000000000000000000000000000000000006",
      "priceWad": "1662500000000000000000"
    }
  ],
  "wbrConfig": {
    "wad": "1000000000000000000",
    "maxWbfWad": "990000000000000000",
    "maxExpArgWad": "20000000000000000000",
    "maxFeeBps": "10000",
    "maxSkewPenaltyWad": "40000000000000000",
    "maxWbfRateBps": "400",
    "maxWeightWad": "1000000000000000000",
    "weightThresholdWad": "550000000000000000",
    "weightThresholdLambdaWad": "600000000000000000",
    "weightThresholdLogWad": "800000000000000000",
    "weightThresholdSigmaWad": "550000000000000000",
    "weightMultiplierLogWad": "10000000000000000000",
    "weightHalfWad": "500000000000000000",
    "bQuoteAdjustmentWad": "0",
    "bOverflowCap": "1000000000000000000000000000000",
    "bSAnchorS": [
      "250000000000000000000",
      "1000000000000000000000",
      "10000000000000000000000",
      "100000000000000000000000",
      "500000000000000000000000",
      "1000000000000000000000000",
      "2500000000000000000000000",
      "5000000000000000000000000"
    ],
    "bSAnchorBpsWad": [
      "0",
      "2000000000000000000",
      "3000000000000000000",
      "6000000000000000000",
      "11000000000000000000",
      "15000000000000000000",
      "25000000000000000000",
      "45000000000000000000"
    ],
    "bSNumAnchors": "8",
    "fPowMultiplier": "5",
    "fPowExponentWad": "2500000000000000000",
    "fLogExponentMultiplier": "10",
    "fLogOverflowDivisor": "10",
    "smoothstepCoeff1": "3000000000000000000",
    "smoothstepCoeff2": "2000000000000000000",
    "wrrDivisor": "2",
    "wrrMaxBps": "200",
    "wrrWeightMaxWad": "850000000000000000",
    "basisPointsDivisor": "10000",
    "bpsToWadMultiplier": "100000000000000"
  }
}
```

### Assertions

| # | Call | Expected (assert EXACTLY) |
|---|---|---|
| 1 | `tokenIn`=USDC, `amountIn`="1000000000", with fixture `tokenPrices`+`wbrConfig` | `poolSharesOut` = "545545661580042036" |
| 2 | same response | `tvl` = "1830950000000000000000000" |
| 3 | same response | `feeDetails`: swapFee.amount="453999", takerFee.amount="226999", wbfFee.amount="39058", slippageFee.amount="113472" (all in USDC) |
| 4 | same response | `amountIn` echoed = "1000000000"; `poolAddress` = the fixture pool address (lowercase) |
| 5 | NEGATIVE — repeat #1 but omit `tokenPrices` entirely (keep `wbrConfig`) | the call FAILS and the error text contains `InvalidPriceData` |

## Hard rules

- No network calls anywhere in the quote path or the verification script.
- No floats in amount handling; no silent re-rounding of SDK outputs.
- Do not modify, move, or rename anything inside `$RYZE_SDK_DIST`.
- Do not reimplement or "simplify" the quote math from observed outputs — the SDK is
  the only source of Ryze numbers in this codebase.
- Keep the wbrConfig object opaque wherever it appears.

## Acceptance checklist (verify each before declaring done)

- [ ] SDK wired via `$RYZE_SDK_DIST` (only go.mod may contain the literal SDK path)
- [ ] Integration module exposes the typed function(s) described above, in this
      repo's own conventions
- [ ] Verification script exists, runs offline, prints one PASS/FAIL line per
      assertion, and exits 0 with every assertion passing
- [ ] All amounts handled as integer strings end-to-end
- [ ] The negative test asserts the failure, i.e. a successful quote there is a FAIL
- [ ] You actually RAN the verification script and pasted its output in your summary

Proportional Join Quotes

View raw
Preview the full prompt text
md
You are integrating the **Ryze offline quote SDK** (Go binding) into this
repository so it can compute Ryze AMM **proportional join quotes** locally — no HTTP
call, no RPC, no network at all. Study the repo first and match its conventions
(module layout, config handling, error types, logging, test framework). If you are
instead running in an empty directory, create a minimal standalone module (run `go mod init verify-ryze` first — the wiring commands below edit an existing go.mod)
whose only purpose is the verification script defined at the end — the acceptance
gate is identical either way.

## What the SDK is

The Ryze quote SDK is a precompiled native library (`libryzesdk`) plus a thin
Go binding. It reproduces the exact quote math of the on-chain Ryze AMM (an
oracle-anchored weighted-pool DEX on Base): same integers, same rounding, same
errors. You hand it a snapshot of a pool's state; it returns the quote synchronously,
in microseconds, with zero I/O. This replaces quoting through Ryze's hosted Router
API on the hot path — same numbers, none of the latency.

It is distributed as a platform tarball: `ryze-sdk-go-<platform>-<arch>.tar.gz`
(darwin-arm64, linux-amd64, …). Obtain the tarball matching your deploy target from
the Ryze team. Throughout this prompt `$RYZE_SDK_DIST` means the absolute path of
the UNPACKED distribution folder — read it from the environment; never hardcode it
(single exception: the `replace` path in go.mod, as documented above).

## Distribution layout & wiring

```text
$RYZE_SDK_DIST/
  go.mod                  # module github.com/ryze-protocol/ryze-sdk-go (go 1.22)
  ryze.go                 # the binding: package ryzesdk (cgo)
  include/ryze_sdk.h      # C header consumed by the binding
  lib/libryzesdk.*        # the closed-source native quote engine (.dylib/.so/.dll)
  example/quote.go        # smoke example
```

**Wiring.** Point your module at the unpacked folder (substitute the actual value of
`$RYZE_SDK_DIST` — this is the one place an absolute path is acceptable):

```bash
go mod edit -require=github.com/ryze-protocol/ryze-sdk-go@v0.0.0
go mod edit -replace=github.com/ryze-protocol/ryze-sdk-go=$RYZE_SDK_DIST
go mod tidy
```

```go
import ryzesdk "github.com/ryze-protocol/ryze-sdk-go"
```

- **cgo is required**: build with `CGO_ENABLED=1` and a C toolchain installed.
- The binding bakes an rpath to its own `lib/` dir (via `${SRCDIR}`), so no runtime
  env vars are needed as long as the distribution folder stays intact. Do not move or
  rename files inside it.
- Calls are **synchronous**; failures return an ordinary `error` whose text is the
  engine's error message.
- The request structs' `WBRConfig` field is `any` — pass a `json.RawMessage` holding
  the verbatim config object.

## The API you are integrating

```go
import ryzesdk "github.com/ryze-protocol/ryze-sdk-go"

resp, err := ryzesdk.QuoteProportionalJoin(ryzesdk.ProportionalJoinRequest{ ... })  // sync

type ProportionalJoinRequest struct {
    Pool      WeightedPool
    AmountsIn []string   // one entry per pool asset, IN POOL ASSET ORDER, base units
}

type ProportionalJoinResponse struct {
    PoolSharesOut string   // LP tokens minted (18 decimals)
    AmountsUsed   []string // amounts actually consumed, pool asset order
    PoolAddress   string   // lowercase
}
```

Proportional joins are fee-free and oracle-free: no TokenPrices, no WBRConfig, no fee
details in the response. The engine deposits at the pool's current balance ratio; the
LIMITING asset decides, and surplus on the other side is left unused
(`AmountsUsed[i] <= AmountsIn[i]`).

## Non-negotiable semantics

- Every amount, balance, weight, fee, and price is a **base-10 integer string** in
  base units. Never let a float touch any of these values — not in parsing, not in
  display math inside the quote path.
- "Wad" fields are 18-decimal fixed point: 1e18 = 1.0 (= 100% for rates/weights).
- `pool` is a point-in-time snapshot. In production hydrate it from the Ryze API
  (`GET {RYZE_API_URL}/pools` — mainnet `https://mainnet.api.ryze.pro/api`, testnet
  `https://sepolia.api.ryze.pro/api`) or your own indexer, and re-quote when state
  changes. The SDK is deterministic: stale input means stale quote. The verification
  script below uses the embedded fixture INSTEAD of any network fetch.
- `pool.assets` order is canonical — preserve it in every array you build.
- This operation uses only `pool` from the fixture. `tokenPrices`/`wbrConfig` are
  included in the fixture so that all four Ryze SDK prompts share one identical
  fixture — this operation simply ignores them.
- Responses echo all addresses in **lowercase**. Compare addresses
  case-insensitively everywhere.
- Engine errors are terse Solidity-style strings (`InvalidSlippage()`,
  `WeightedPoolMathError("...")`). Treat them as opaque: assert on them in tests,
  never branch on them in production logic.
- `amountsIn` MUST follow the pool's asset order (the order of `pool.assets`).
- The engine joins at the pool's CURRENT balance ratio. The limiting asset determines
  the shares; any surplus of the other asset is simply not consumed — always surface
  `amountsUsed` to the caller so the UI/executor can refund or withhold the surplus.
- Proportional joins charge no fees and need no oracle prices.

## Deliverable 1 — the integration module

Expose one narrow, typed function — for example
`quoteRyzeProportionalJoin(pool, amountsIn)` — returning the LP shares minted and the
amounts actually consumed. Internally it must do nothing but validate inputs, assemble
the SDK request, call the SDK, and map the response into your codebase's own types.
Do NOT post-process the numbers: no rounding, no float conversion — the SDK's integers
are the on-chain truth.

Example names above are illustrative — adapt them to this language's and this repo's
conventions (snake_case in Rust, exported PascalCase in Go, camelCase in TypeScript).

## Deliverable 2 — standalone verification script (the acceptance gate)

Create `cmd/verify-ryze-join-proportional/main.go` (repo mode) or `main.go` of a fresh module (standalone mode); run with `go run`.

The script must be fully self-contained: it embeds the fixture below verbatim, calls
the SDK through YOUR integration module (not around it), checks every assertion in
the table, prints one `PASS <name>` / `FAIL <name> expected=<e> got=<g>` line per
assertion (a table row that bundles several fields may emit one line per field), and
exits 0 only if every assertion passed.

Golden values below were produced by this exact SDK build from this exact fixture —
they are deterministic. An off-by-one is a real failure; investigate your request
construction before suspecting the goldens.

### Fixture (embed verbatim — tokens are USDC, 6 decimals, and WETH, 18 decimals)

```json
{
  "pool": {
    "address": "0x0000000000000000000000000000000000001001",
    "totalSupplyLP": "1000000000000000000000",
    "parameters": {
      "swapFeeWad": "1000000000000000",
      "takerFeeWad": "500000000000000",
      "smartShieldEnabled": true,
      "smartShieldParams": {
        "thresholdWeightDiffWad": "10000000000000000",
        "minOracleWeightWad": "150000000000000000"
      },
      "intentSwapFeeWad": "400000000000000",
      "intentTakerFeeWad": "200000000000000"
    },
    "assets": [
      {
        "tokenAddress": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
        "balance": "1000000000000",
        "weight": "500000000000000000",
        "decimals": 6,
        "liability": "0",
        "custody": "0",
        "externalLiquidityRatio": "2000000000000000000",
        "liquidityBands": [
          {
            "thresholdWad": "1000000000000000000000",
            "ratioWad": "2000000000000000000",
            "minSlippageWad": "100000000000000"
          },
          {
            "thresholdWad": "100000000000000000000000",
            "ratioWad": "1500000000000000000",
            "minSlippageWad": "200000000000000"
          },
          {
            "thresholdWad": "1000000000000000000000000",
            "ratioWad": "1200000000000000000",
            "minSlippageWad": "400000000000000"
          }
        ]
      },
      {
        "tokenAddress": "0x4200000000000000000000000000000000000006",
        "balance": "500000000000000000000",
        "weight": "500000000000000000",
        "decimals": 18,
        "liability": "0",
        "custody": "0",
        "externalLiquidityRatio": "2000000000000000000",
        "liquidityBands": [
          {
            "thresholdWad": "1000000000000000000000",
            "ratioWad": "2000000000000000000",
            "minSlippageWad": "100000000000000"
          },
          {
            "thresholdWad": "100000000000000000000000",
            "ratioWad": "1500000000000000000",
            "minSlippageWad": "200000000000000"
          },
          {
            "thresholdWad": "1000000000000000000000000",
            "ratioWad": "1200000000000000000",
            "minSlippageWad": "400000000000000"
          }
        ]
      }
    ]
  },
  "tokenPrices": [
    {
      "token": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "priceWad": "999700000000000000"
    },
    {
      "token": "0x4200000000000000000000000000000000000006",
      "priceWad": "1662500000000000000000"
    }
  ],
  "wbrConfig": {
    "wad": "1000000000000000000",
    "maxWbfWad": "990000000000000000",
    "maxExpArgWad": "20000000000000000000",
    "maxFeeBps": "10000",
    "maxSkewPenaltyWad": "40000000000000000",
    "maxWbfRateBps": "400",
    "maxWeightWad": "1000000000000000000",
    "weightThresholdWad": "550000000000000000",
    "weightThresholdLambdaWad": "600000000000000000",
    "weightThresholdLogWad": "800000000000000000",
    "weightThresholdSigmaWad": "550000000000000000",
    "weightMultiplierLogWad": "10000000000000000000",
    "weightHalfWad": "500000000000000000",
    "bQuoteAdjustmentWad": "0",
    "bOverflowCap": "1000000000000000000000000000000",
    "bSAnchorS": [
      "250000000000000000000",
      "1000000000000000000000",
      "10000000000000000000000",
      "100000000000000000000000",
      "500000000000000000000000",
      "1000000000000000000000000",
      "2500000000000000000000000",
      "5000000000000000000000000"
    ],
    "bSAnchorBpsWad": [
      "0",
      "2000000000000000000",
      "3000000000000000000",
      "6000000000000000000",
      "11000000000000000000",
      "15000000000000000000",
      "25000000000000000000",
      "45000000000000000000"
    ],
    "bSNumAnchors": "8",
    "fPowMultiplier": "5",
    "fPowExponentWad": "2500000000000000000",
    "fLogExponentMultiplier": "10",
    "fLogOverflowDivisor": "10",
    "smoothstepCoeff1": "3000000000000000000",
    "smoothstepCoeff2": "2000000000000000000",
    "wrrDivisor": "2",
    "wrrMaxBps": "200",
    "wrrWeightMaxWad": "850000000000000000",
    "basisPointsDivisor": "10000",
    "bpsToWadMultiplier": "100000000000000"
  }
}
```

### Assertions

| # | Call | Expected (assert EXACTLY) |
|---|---|---|
| 1 | balanced: `amountsIn` = ["1000000000", "500000000000000000"] (1,000 USDC + 0.5 WETH — the pool ratio) | `poolSharesOut` = "1000000000000000000" (exactly 1 LP = 0.1% of the 1000-LP supply) |
| 2 | same response | `amountsUsed` = ["1000000000", "500000000000000000"] (everything consumed) |
| 3 | imbalanced: `amountsIn` = ["2000000000", "500000000000000000"] (2,000 USDC but still 0.5 WETH) | `poolSharesOut` = "1000000000000000000" AND `amountsUsed` = ["1000000000", "500000000000000000"] — WETH limits, the extra 1,000 USDC is NOT consumed |
| 4 | both responses above | `poolAddress` = the fixture pool address (lowercase) |

## Hard rules

- No network calls anywhere in the quote path or the verification script.
- No floats in amount handling; no silent re-rounding of SDK outputs.
- Do not modify, move, or rename anything inside `$RYZE_SDK_DIST`.
- Do not reimplement or "simplify" the quote math from observed outputs — the SDK is
  the only source of Ryze numbers in this codebase.
- Keep the wbrConfig object opaque wherever it appears.

## Acceptance checklist (verify each before declaring done)

- [ ] SDK wired via `$RYZE_SDK_DIST` (only go.mod may contain the literal SDK path)
- [ ] Integration module exposes the typed function(s) described above, in this
      repo's own conventions
- [ ] Verification script exists, runs offline, prints one PASS/FAIL line per
      assertion, and exits 0 with every assertion passing
- [ ] All amounts handled as integer strings end-to-end
- [ ] The imbalanced case (#3) is asserted — it proves limiting-ratio semantics survive your mapping layer
- [ ] You actually RAN the verification script and pasted its output in your summary

Proportional Exit Quotes

View raw
Preview the full prompt text
md
You are integrating the **Ryze offline quote SDK** (Go binding) into this
repository so it can compute Ryze AMM **proportional exit quotes** locally — no HTTP
call, no RPC, no network at all. Study the repo first and match its conventions
(module layout, config handling, error types, logging, test framework). If you are
instead running in an empty directory, create a minimal standalone module (run `go mod init verify-ryze` first — the wiring commands below edit an existing go.mod)
whose only purpose is the verification script defined at the end — the acceptance
gate is identical either way.

## What the SDK is

The Ryze quote SDK is a precompiled native library (`libryzesdk`) plus a thin
Go binding. It reproduces the exact quote math of the on-chain Ryze AMM (an
oracle-anchored weighted-pool DEX on Base): same integers, same rounding, same
errors. You hand it a snapshot of a pool's state; it returns the quote synchronously,
in microseconds, with zero I/O. This replaces quoting through Ryze's hosted Router
API on the hot path — same numbers, none of the latency.

It is distributed as a platform tarball: `ryze-sdk-go-<platform>-<arch>.tar.gz`
(darwin-arm64, linux-amd64, …). Obtain the tarball matching your deploy target from
the Ryze team. Throughout this prompt `$RYZE_SDK_DIST` means the absolute path of
the UNPACKED distribution folder — read it from the environment; never hardcode it
(single exception: the `replace` path in go.mod, as documented above).

## Distribution layout & wiring

```text
$RYZE_SDK_DIST/
  go.mod                  # module github.com/ryze-protocol/ryze-sdk-go (go 1.22)
  ryze.go                 # the binding: package ryzesdk (cgo)
  include/ryze_sdk.h      # C header consumed by the binding
  lib/libryzesdk.*        # the closed-source native quote engine (.dylib/.so/.dll)
  example/quote.go        # smoke example
```

**Wiring.** Point your module at the unpacked folder (substitute the actual value of
`$RYZE_SDK_DIST` — this is the one place an absolute path is acceptable):

```bash
go mod edit -require=github.com/ryze-protocol/ryze-sdk-go@v0.0.0
go mod edit -replace=github.com/ryze-protocol/ryze-sdk-go=$RYZE_SDK_DIST
go mod tidy
```

```go
import ryzesdk "github.com/ryze-protocol/ryze-sdk-go"
```

- **cgo is required**: build with `CGO_ENABLED=1` and a C toolchain installed.
- The binding bakes an rpath to its own `lib/` dir (via `${SRCDIR}`), so no runtime
  env vars are needed as long as the distribution folder stays intact. Do not move or
  rename files inside it.
- Calls are **synchronous**; failures return an ordinary `error` whose text is the
  engine's error message.
- The request structs' `WBRConfig` field is `any` — pass a `json.RawMessage` holding
  the verbatim config object.

## The API you are integrating

```go
import ryzesdk "github.com/ryze-protocol/ryze-sdk-go"

resp, err := ryzesdk.QuoteProportionalExit(ryzesdk.ProportionalExitRequest{ ... })  // sync

type ProportionalExitRequest struct {
    Pool          WeightedPool
    PoolSharesIn  string   // LP tokens burned (18 decimals)
    MinAmountsOut []string // optional floors, pool asset order;
}                          // engine errors "InvalidSlippage()" if any is unmet

type ProportionalExitResponse struct {
    AmountsOut  []string // withdrawal per asset, pool asset order, base units
    PoolAddress string   // lowercase
}
```

Proportional exits are fee-free and oracle-free: no TokenPrices, no WBRConfig, no fee
details in the response.

## Non-negotiable semantics

- Every amount, balance, weight, fee, and price is a **base-10 integer string** in
  base units. Never let a float touch any of these values — not in parsing, not in
  display math inside the quote path.
- "Wad" fields are 18-decimal fixed point: 1e18 = 1.0 (= 100% for rates/weights).
- `pool` is a point-in-time snapshot. In production hydrate it from the Ryze API
  (`GET {RYZE_API_URL}/pools` — mainnet `https://mainnet.api.ryze.pro/api`, testnet
  `https://sepolia.api.ryze.pro/api`) or your own indexer, and re-quote when state
  changes. The SDK is deterministic: stale input means stale quote. The verification
  script below uses the embedded fixture INSTEAD of any network fetch.
- `pool.assets` order is canonical — preserve it in every array you build.
- This operation uses only `pool` from the fixture. `tokenPrices`/`wbrConfig` are
  included in the fixture so that all four Ryze SDK prompts share one identical
  fixture — this operation simply ignores them.
- Responses echo all addresses in **lowercase**. Compare addresses
  case-insensitively everywhere.
- Engine errors are terse Solidity-style strings (`InvalidSlippage()`,
  `WeightedPoolMathError("...")`). Treat them as opaque: assert on them in tests,
  never branch on them in production logic.
- `amountsOut` follows the pool's asset order (the order of `pool.assets`).
- `minAmountsOut` is the slippage guard: pass the floors your executor will enforce
  on-chain and the SDK fails the quote early — with the engine error
  `InvalidSlippage()` — instead of letting a doomed transaction through.
- Proportional exits charge no fees and need no oracle prices.

## Deliverable 1 — the integration module

Expose one narrow, typed function — for example
`quoteRyzeExit(pool, poolSharesIn, minAmountsOut?)` — returning the per-asset
withdrawal amounts. Internally it must do nothing but validate inputs, assemble the
SDK request, call the SDK, and map the response into your codebase's own types.
Do NOT post-process the numbers: no rounding, no float conversion — the SDK's integers
are the on-chain truth.

Example names above are illustrative — adapt them to this language's and this repo's
conventions (snake_case in Rust, exported PascalCase in Go, camelCase in TypeScript).

## Deliverable 2 — standalone verification script (the acceptance gate)

Create `cmd/verify-ryze-exit/main.go` (repo mode) or `main.go` of a fresh module (standalone mode); run with `go run`.

The script must be fully self-contained: it embeds the fixture below verbatim, calls
the SDK through YOUR integration module (not around it), checks every assertion in
the table, prints one `PASS <name>` / `FAIL <name> expected=<e> got=<g>` line per
assertion (a table row that bundles several fields may emit one line per field), and
exits 0 only if every assertion passed. For the negative case: check the returned `error`'s text.

Golden values below were produced by this exact SDK build from this exact fixture —
they are deterministic. An off-by-one is a real failure; investigate your request
construction before suspecting the goldens.

### Fixture (embed verbatim — tokens are USDC, 6 decimals, and WETH, 18 decimals)

```json
{
  "pool": {
    "address": "0x0000000000000000000000000000000000001001",
    "totalSupplyLP": "1000000000000000000000",
    "parameters": {
      "swapFeeWad": "1000000000000000",
      "takerFeeWad": "500000000000000",
      "smartShieldEnabled": true,
      "smartShieldParams": {
        "thresholdWeightDiffWad": "10000000000000000",
        "minOracleWeightWad": "150000000000000000"
      },
      "intentSwapFeeWad": "400000000000000",
      "intentTakerFeeWad": "200000000000000"
    },
    "assets": [
      {
        "tokenAddress": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
        "balance": "1000000000000",
        "weight": "500000000000000000",
        "decimals": 6,
        "liability": "0",
        "custody": "0",
        "externalLiquidityRatio": "2000000000000000000",
        "liquidityBands": [
          {
            "thresholdWad": "1000000000000000000000",
            "ratioWad": "2000000000000000000",
            "minSlippageWad": "100000000000000"
          },
          {
            "thresholdWad": "100000000000000000000000",
            "ratioWad": "1500000000000000000",
            "minSlippageWad": "200000000000000"
          },
          {
            "thresholdWad": "1000000000000000000000000",
            "ratioWad": "1200000000000000000",
            "minSlippageWad": "400000000000000"
          }
        ]
      },
      {
        "tokenAddress": "0x4200000000000000000000000000000000000006",
        "balance": "500000000000000000000",
        "weight": "500000000000000000",
        "decimals": 18,
        "liability": "0",
        "custody": "0",
        "externalLiquidityRatio": "2000000000000000000",
        "liquidityBands": [
          {
            "thresholdWad": "1000000000000000000000",
            "ratioWad": "2000000000000000000",
            "minSlippageWad": "100000000000000"
          },
          {
            "thresholdWad": "100000000000000000000000",
            "ratioWad": "1500000000000000000",
            "minSlippageWad": "200000000000000"
          },
          {
            "thresholdWad": "1000000000000000000000000",
            "ratioWad": "1200000000000000000",
            "minSlippageWad": "400000000000000"
          }
        ]
      }
    ]
  },
  "tokenPrices": [
    {
      "token": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "priceWad": "999700000000000000"
    },
    {
      "token": "0x4200000000000000000000000000000000000006",
      "priceWad": "1662500000000000000000"
    }
  ],
  "wbrConfig": {
    "wad": "1000000000000000000",
    "maxWbfWad": "990000000000000000",
    "maxExpArgWad": "20000000000000000000",
    "maxFeeBps": "10000",
    "maxSkewPenaltyWad": "40000000000000000",
    "maxWbfRateBps": "400",
    "maxWeightWad": "1000000000000000000",
    "weightThresholdWad": "550000000000000000",
    "weightThresholdLambdaWad": "600000000000000000",
    "weightThresholdLogWad": "800000000000000000",
    "weightThresholdSigmaWad": "550000000000000000",
    "weightMultiplierLogWad": "10000000000000000000",
    "weightHalfWad": "500000000000000000",
    "bQuoteAdjustmentWad": "0",
    "bOverflowCap": "1000000000000000000000000000000",
    "bSAnchorS": [
      "250000000000000000000",
      "1000000000000000000000",
      "10000000000000000000000",
      "100000000000000000000000",
      "500000000000000000000000",
      "1000000000000000000000000",
      "2500000000000000000000000",
      "5000000000000000000000000"
    ],
    "bSAnchorBpsWad": [
      "0",
      "2000000000000000000",
      "3000000000000000000",
      "6000000000000000000",
      "11000000000000000000",
      "15000000000000000000",
      "25000000000000000000",
      "45000000000000000000"
    ],
    "bSNumAnchors": "8",
    "fPowMultiplier": "5",
    "fPowExponentWad": "2500000000000000000",
    "fLogExponentMultiplier": "10",
    "fLogOverflowDivisor": "10",
    "smoothstepCoeff1": "3000000000000000000",
    "smoothstepCoeff2": "2000000000000000000",
    "wrrDivisor": "2",
    "wrrMaxBps": "200",
    "wrrWeightMaxWad": "850000000000000000",
    "basisPointsDivisor": "10000",
    "bpsToWadMultiplier": "100000000000000"
  }
}
```

### Assertions

| # | Call | Expected (assert EXACTLY) |
|---|---|---|
| 1 | `poolSharesIn` = "25000000000000000000" (25 LP = 2.5% of the 1000-LP supply) | `amountsOut` = ["25000000000", "12500000000000000000"] (25,000 USDC + 12.5 WETH) |
| 2 | same response | `poolAddress` = the fixture pool address (lowercase) |
| 3 | NEGATIVE — same `poolSharesIn` with `minAmountsOut` = ["25000000001", "0"] (floor one base unit above the real output) | the call FAILS and the error text contains `InvalidSlippage` |

## Hard rules

- No network calls anywhere in the quote path or the verification script.
- No floats in amount handling; no silent re-rounding of SDK outputs.
- Do not modify, move, or rename anything inside `$RYZE_SDK_DIST`.
- Do not reimplement or "simplify" the quote math from observed outputs — the SDK is
  the only source of Ryze numbers in this codebase.
- Keep the wbrConfig object opaque wherever it appears.

## Acceptance checklist (verify each before declaring done)

- [ ] SDK wired via `$RYZE_SDK_DIST` (only go.mod may contain the literal SDK path)
- [ ] Integration module exposes the typed function(s) described above, in this
      repo's own conventions
- [ ] Verification script exists, runs offline, prints one PASS/FAIL line per
      assertion, and exits 0 with every assertion passing
- [ ] All amounts handled as integer strings end-to-end
- [ ] The negative test asserts the failure, i.e. a successful quote there is a FAIL
- [ ] You actually RAN the verification script and pasted its output in your summary