@blazephoenix/sdk 0.5.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +133 -153
- package/dist/index.cjs +6288 -441
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3955 -470
- package/dist/index.d.ts +3955 -470
- package/dist/index.js +6239 -436
- package/dist/index.js.map +1 -1
- package/package.json +10 -11
package/README.md
CHANGED
|
@@ -3,203 +3,183 @@
|
|
|
3
3
|
Official TypeScript SDK for **[BlazePhoenix](https://blazephoenix.xyz)** — the on-chain
|
|
4
4
|
DEX aggregator on **Base · Ethereum · Optimism · Arbitrum · Robinhood Chain**.
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
> Live docs & playground: **https://blazephoenix.xyz/?tab=api**
|
|
6
|
+
**1.x runs 100% on YOUR RPC.** Every quote is an `eth_call` from your process to your
|
|
7
|
+
node, against the Quoter contract that settles the swap. There is no BlazePhoenix API
|
|
8
|
+
in the read path, no key, and the package ships no RPC endpoints (a test enforces it).
|
|
9
|
+
We don't pay for your reads, and you don't depend on our servers being up.
|
|
11
10
|
|
|
12
11
|
```bash
|
|
13
|
-
npm i
|
|
14
|
-
#
|
|
15
|
-
# optional (only for the on-chain module: quoteOnChain / watchFills / getFills):
|
|
16
|
-
npm i viem
|
|
12
|
+
npm i @blazephoenix/sdk viem
|
|
13
|
+
# or straight from GitHub (builds on install): npm i github:blazephoenixxyz-crypto/SDK viem
|
|
17
14
|
```
|
|
18
15
|
|
|
19
|
-
## Quote →
|
|
16
|
+
## Quote → build → execute
|
|
20
17
|
|
|
21
18
|
```ts
|
|
22
|
-
import { BlazePhoenix
|
|
23
|
-
|
|
24
|
-
const blaze = new BlazePhoenix(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const q = await blaze.quote({
|
|
28
|
-
chain: 'base', // 8453 | 'base' | 1 | 'eth' | 10 | 42161 …
|
|
29
|
-
tokenIn: 'WETH', // 0x-address, ETH/WETH/USDC/BZPX — or ANY traded
|
|
30
|
-
// symbol ('TOSHI', 'DEGEN'…): resolved to the
|
|
31
|
-
// deepest-liquidity token, echoed in q.resolved
|
|
32
|
-
tokenOut: 'USDC',
|
|
33
|
-
amountIn,
|
|
34
|
-
recipient: '0xYOU', // ← makes the API return ready-to-send calldata
|
|
35
|
-
slippageBps: 50,
|
|
19
|
+
import { BlazePhoenix } from '@blazephoenix/sdk';
|
|
20
|
+
|
|
21
|
+
const blaze = new BlazePhoenix({
|
|
22
|
+
rpc: { base: process.env.BASE_RPC_URL }, // YOUR node — any provider's free tier is enough
|
|
36
23
|
});
|
|
37
24
|
|
|
38
|
-
//
|
|
39
|
-
await
|
|
40
|
-
//
|
|
41
|
-
|
|
25
|
+
// 1) the Quoter's preview, read on your node ("amount" is human units)
|
|
26
|
+
const q = await blaze.quote({ chain: 'base', tokenIn: 'WETH', tokenOut: 'USDC', amount: '1.5' });
|
|
27
|
+
q.amountOut; // net output after the 0.28% fee (bigint, base units)
|
|
28
|
+
q.checks.verdict; // Phoenix Check: ok | caution | danger | blocked (fails closed)
|
|
29
|
+
q.version; // protocol version that answered ('1.0.0' today, '2.0.0' once deployed)
|
|
30
|
+
|
|
31
|
+
// 2) the swap transaction(s): verified calldata + the approval step if needed
|
|
32
|
+
const plan = await blaze.buildSwap({
|
|
33
|
+
chain: 'base', tokenIn: 'WETH', tokenOut: 'USDC', amount: '1.5',
|
|
34
|
+
recipient: me, from: me, // `from` enables the allowance check
|
|
35
|
+
slippageBps: 50, // default 50; never below the on-chain floor
|
|
36
|
+
});
|
|
37
|
+
plan.steps; // [approve?, swap] — { chainId, to, data, value }
|
|
38
|
+
plan.minOut; // the minimum the Router will enforce for you
|
|
39
|
+
plan.encodedBy; // 'quoter' on 2.x (the Quoter's own bytes, verified) · 'sdk' on 1.x
|
|
40
|
+
|
|
41
|
+
// 3) optional: dry-run on your node, then execute with YOUR wallet
|
|
42
|
+
await blaze.simulate(plan, me); // { ok, amountOut } or the decoded revert
|
|
43
|
+
const res = await blaze.execute({ wallet, plan }); // approve → simulate → swap → receipt
|
|
44
|
+
res.amountOut; // realised, from the Router's Swap event
|
|
42
45
|
```
|
|
43
46
|
|
|
44
|
-
|
|
47
|
+
`execute` takes a viem `WalletClient`. The SDK never asks for, stores or touches a key.
|
|
45
48
|
|
|
46
|
-
|
|
47
|
-
const { results } = await blaze.quoteBatch([
|
|
48
|
-
{ chain: 'base', tokenIn: 'WETH', tokenOut: 'USDC', amountIn: 10n ** 18n },
|
|
49
|
-
{ chain: 'base', tokenIn: 'WETH', tokenOut: 'BZPX', amountIn: 10n ** 18n },
|
|
50
|
-
{ chain: 'arbitrum', tokenIn: 'WETH', tokenOut: 'USDC', amountIn: 10n ** 18n },
|
|
51
|
-
]); // one round-trip (max 10), per-item errors inline
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
## Deep links (bot buttons / referral posts)
|
|
49
|
+
## Your RPC, your way
|
|
55
50
|
|
|
56
51
|
```ts
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
//
|
|
52
|
+
new BlazePhoenix({ rpc: 'https://your-base-node.example/KEY' }); // one node — its own chain
|
|
53
|
+
new BlazePhoenix({ rpc: ['https://node-a.example', 'https://node-b.example'] }); // your fallback order
|
|
54
|
+
new BlazePhoenix({ rpc: window.ethereum }); // the user's wallet (EIP-1193)
|
|
55
|
+
new BlazePhoenix({ rpc: http('https://…', { batch: true }) }); // any viem Transport
|
|
56
|
+
new BlazePhoenix({ rpc: { base: '…', eth: ['…', '…'], arbitrum: provider } }); // per chain
|
|
57
|
+
new BlazePhoenix(); // reads BLAZEPHOENIX_RPC_BASE / _ETHEREUM / _OPTIMISM / _ARBITRUM / _ROBINHOOD
|
|
58
|
+
// (comma-separated for fallback) or BLAZEPHOENIX_RPC_URL
|
|
61
59
|
```
|
|
62
60
|
|
|
63
|
-
|
|
61
|
+
- Each node is asked for `eth_chainId` once. Quoting Base contracts on an Ethereum node
|
|
62
|
+
throws `rpc_chain_mismatch` instead of returning garbage.
|
|
63
|
+
- With a single node, `chain` may be omitted: the node's own chain is used.
|
|
64
|
+
- A chain without a configured node throws `rpc_required` — nothing silently falls back
|
|
65
|
+
to someone else's infrastructure.
|
|
66
|
+
- `https://` and `wss://` only (`http://` allowed for `localhost` — your anvil/geth).
|
|
67
|
+
URLs are redacted in every error message, because keys live in them.
|
|
64
68
|
|
|
65
|
-
|
|
66
|
-
v0.4.0**: omit `rpcUrl` and the SDK falls back across public keyless endpoints
|
|
67
|
-
(bring your own node for production throughput). Still zero providers and zero
|
|
68
|
-
keys shipped — enforced by tests.
|
|
69
|
+
## Versions — pick yours
|
|
69
70
|
|
|
70
|
-
|
|
71
|
-
import { quoteOnChain, watchFills, getFills } from '@blazephoenix/sdk';
|
|
71
|
+
Protocol versions are deployments, not SDK versions:
|
|
72
72
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
amountIn: 10n ** 18n,
|
|
78
|
-
});
|
|
73
|
+
| version | status | what it is |
|
|
74
|
+
|---|---|---|
|
|
75
|
+
| `1.0.0` | **live** on all five chains | the generation deployed at launch |
|
|
76
|
+
| `2.0.0` | pending | the final Core / Hub / Solver / Quoter / Router from [BlazePhoenix-Dex](https://github.com/blazephoenixxyz-crypto/Blaze-Phoenix-Dex) (`VERSION()` = `"2.0.0"`) |
|
|
79
77
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
});
|
|
78
|
+
```ts
|
|
79
|
+
new BlazePhoenix({ rpc, version: 'latest' }); // default: newest version deployed on each chain
|
|
80
|
+
new BlazePhoenix({ rpc, version: '1' }); // stay on 1.x
|
|
81
|
+
await blaze.quote({ ...req, version: '2.0.0' }); // per call
|
|
84
82
|
```
|
|
85
83
|
|
|
86
|
-
|
|
87
|
-
the input for the **quoted-vs-executed verification pattern** documented on the
|
|
88
|
-
API page: re-run each fill's quote at its block and compare with the executed
|
|
89
|
-
amount the event recorded. Verify us, don't trust us.
|
|
90
|
-
|
|
91
|
-
## Resilient by default (v0.3.0)
|
|
84
|
+
The SDK adapts to what each version can do (`featuresOf(version)`):
|
|
92
85
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
-
|
|
99
|
-
|
|
86
|
+
| capability | 1.x | 2.x |
|
|
87
|
+
|---|---|---|
|
|
88
|
+
| preview + Router calldata in ONE call (`previewAndEncode`) | — (encoded by the SDK) | ✅ verified field by field |
|
|
89
|
+
| native ETH in, no pre-wrap (`swapExactInNative`) | wrap first: `buildWrapTx` | ✅ |
|
|
90
|
+
| solve + execute in the same tx (`mode: 'best'` → `swapBestExactIn`) | — | ✅ |
|
|
91
|
+
| on-chain `batchQuote` | parallel previews | ✅ chunked |
|
|
92
|
+
| `ExecutionProof` on every fill (quoted vs realised vs floor) | — | ✅ |
|
|
93
|
+
|
|
94
|
+
### New deployments reach you without a new SDK release
|
|
95
|
+
|
|
96
|
+
The registry has three layers:
|
|
97
|
+
|
|
98
|
+
1. **Embedded** — shipped in the package. Non-zero addresses are **pins**: nothing fetched
|
|
99
|
+
at runtime can move them.
|
|
100
|
+
2. **Remote** — `GET https://blazephoenix.xyz/api/deployments` (static JSON, refreshed every
|
|
101
|
+
10 min in the background; the first lookup waits at most 3 s). It can only fill what the
|
|
102
|
+
snapshot doesn't know — e.g. the 2.0.0 addresses the day they are deployed — and only for
|
|
103
|
+
versions that can be verified on-chain (2.x+). Every remote-sourced set is **verified on
|
|
104
|
+
your RPC before first use**:
|
|
105
|
+
code at every address, `VERSION()` matches, and the Quoter, Router and Solver all point at
|
|
106
|
+
the same Hub and Solver. Anything else fails closed (`deployment_unverified`).
|
|
107
|
+
3. **Your overrides** — always win:
|
|
100
108
|
|
|
101
109
|
```ts
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
{
|
|
106
|
-
|
|
107
|
-
|
|
110
|
+
new BlazePhoenix({
|
|
111
|
+
rpc,
|
|
112
|
+
contracts: { base: { router: '0x…', quoter: '0x…', version: '2.0.0' } }, // your fork / audit target
|
|
113
|
+
registry: { mode: 'embedded' }, // never touch the network for addresses
|
|
114
|
+
});
|
|
115
|
+
await blaze.deployments(); // the chains × versions table this client sees
|
|
116
|
+
await blaze.verifyDeployment({ chain: 'base' }); // run the on-chain checks yourself
|
|
108
117
|
```
|
|
109
118
|
|
|
110
|
-
##
|
|
111
|
-
|
|
112
|
-
[`examples/phoenix-bot.ts`](examples/phoenix-bot.ts) is a complete Telegram bot
|
|
113
|
-
with a difference: **it never holds a key**. It quotes on-chain truth, streams
|
|
114
|
-
real fills (`/watch`), and executes by deep-linking users into their OWN wallet.
|
|
115
|
-
The famous trading bots custody your funds; this one can't lose what it never
|
|
116
|
-
touches.
|
|
117
|
-
|
|
118
|
-
```bash
|
|
119
|
-
npm i grammy viem
|
|
120
|
-
BOT_TOKEN=... RPC_URL=https://your-base-rpc npx tsx examples/phoenix-bot.ts
|
|
121
|
-
```
|
|
119
|
+
## Why the calldata can be trusted
|
|
122
120
|
|
|
123
|
-
|
|
121
|
+
On 2.x, `Quoter.previewAndEncode` returns the preview **and** the exact `swapExactIn` bytes that
|
|
122
|
+
execute it. The Quoter's own source says what that is worth — *"a compromised Quoter fools the
|
|
123
|
+
interface"* — so the SDK never forwards those bytes blind. It decodes them with the Router ABI
|
|
124
|
+
and refuses (`calldata_mismatch`) unless the amount, recipient, deadline, the route
|
|
125
|
+
(identical to the previewed one, connecting tokenIn → tokenOut) and a minimum at least the
|
|
126
|
+
on-chain floor all match what you asked. Your slippage then only ever **tightens** that minimum.
|
|
124
127
|
|
|
125
|
-
|
|
126
|
-
of the shared pool:
|
|
128
|
+
## More
|
|
127
129
|
|
|
128
130
|
```ts
|
|
129
|
-
|
|
130
|
-
//
|
|
131
|
-
await blaze.
|
|
131
|
+
await blaze.quoteExact(req); // previewPlanExact: every concentrated leg dry-run on the pool
|
|
132
|
+
await blaze.quoteBatch([req1, req2]); // per-item { ok, quote } | { ok:false, error }
|
|
133
|
+
await blaze.getFills({ chain: 'base', lookbackBlocks: 5_000n }); // Swap (+ ExecutionProof on 2.x)
|
|
134
|
+
const stop = await blaze.watchFills({ chain: 'base', onFill: console.log });
|
|
135
|
+
await blaze.tokenInfo('base', '0x…'); // symbol / name / decimals
|
|
136
|
+
await blaze.solvency(); // the staking engine's proof-of-solvency (Base)
|
|
137
|
+
toJSON(quote); // bigint → string, for HTTP / queues / LLMs
|
|
132
138
|
```
|
|
133
139
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
public pool remains the fallback, so supplying one can only make calls more
|
|
138
|
-
reliable, never less. `meta.rpc` in the response reads `byo` or `shared`.
|
|
140
|
+
Pure helpers (no RPC): `buildApproveTx`, `buildWrapTx`, `buildUnwrapTx`, `permit2TypedData`,
|
|
141
|
+
`encodeSwapExactInWithPermit2`, `encodeSwapExactIn`, `verifySwapExactIn`, `minOutFor`,
|
|
142
|
+
`decodeBlazeError`, `toBaseUnits`, `fromBaseUnits`, `deepLink`.
|
|
139
143
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
144
|
+
Tokens: `0x` addresses, or the universal symbols `ETH` (native), `WETH`, `USDC` (the chain's
|
|
145
|
+
dollar asset — USDG on Robinhood), `BZPX`. Anything else: pass the address. The SDK never
|
|
146
|
+
guesses a token from a ticker.
|
|
143
147
|
|
|
144
148
|
## Errors
|
|
145
149
|
|
|
146
|
-
|
|
150
|
+
Every failure is a `BlazeError` with a stable `code`; protocol reverts carry `revert`
|
|
151
|
+
(`RouterE` / `QuoterE` / `SolverE` / `HubE` + the reason from the contract's own source):
|
|
147
152
|
|
|
148
153
|
| code | meaning |
|
|
149
154
|
|---|---|
|
|
150
|
-
| `
|
|
151
|
-
| `
|
|
152
|
-
| `
|
|
155
|
+
| `rpc_required` | no node configured for that chain |
|
|
156
|
+
| `rpc_chain_mismatch` | the node serves a different chain |
|
|
157
|
+
| `rpc_error` | your node failed (network, rate limit) |
|
|
158
|
+
| `no_route` | the Solver found no executable path (`SolverE(5)`) or the quote reverted |
|
|
159
|
+
| `not_executable` | the Quoter says the route cannot settle now (`canExecute = false`) |
|
|
160
|
+
| `calldata_mismatch` | Quoter bytes did not match your request — refused |
|
|
161
|
+
| `deployment_unverified` | a registry deployment failed on-chain verification |
|
|
162
|
+
| `unsupported_by_version` | e.g. native ETH input on a 1.x Router |
|
|
163
|
+
| `not_deployed` / `bad_request` / `wallet_chain_mismatch` / `reverted` | as named |
|
|
153
164
|
|
|
154
|
-
##
|
|
165
|
+
## MCP (AI agents)
|
|
155
166
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
- Manifest (contracts / token / event topics): `GET https://blazephoenix.xyz/api/manifest`
|
|
159
|
-
- Examples: [`examples/`](examples) — plain quote, Telegram bot, fill watcher
|
|
160
|
-
- Protocol fee: 0.28% on quoted output; **execution surplus is fee-exempt → user**
|
|
167
|
+
[`@blazephoenix/mcp`](https://github.com/blazephoenixxyz-crypto/blazephoenix-mcp) wraps this SDK as
|
|
168
|
+
a local MCP server — the agent's tools run on your machine, on your RPC.
|
|
161
169
|
|
|
162
|
-
##
|
|
170
|
+
## Examples
|
|
163
171
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
[full proof-of-solvency report](https://blazephoenix.xyz/solvency)
|
|
172
|
+
[`examples/`](examples): `quote.ts`, `watch-fills.ts`, `telegram-bot.ts`, and
|
|
173
|
+
[`phoenix-bot.ts`](examples/phoenix-bot.ts) — a complete zero-custody Telegram bot on your own nodes.
|
|
167
174
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
| Ethereum (1) | Quoter | [`0x4a20AA0912388ff7A9221Ab6BFC224cc20Baa0c3`](https://etherscan.io/address/0x4a20AA0912388ff7A9221Ab6BFC224cc20Baa0c3) |
|
|
176
|
-
| Optimism (10) | Router | [`0x7262e7483ab6f0db7b8f90eC3a9de3B02Ab36F6A`](https://optimistic.etherscan.io/address/0x7262e7483ab6f0db7b8f90eC3a9de3B02Ab36F6A) |
|
|
177
|
-
| Optimism (10) | Quoter | [`0xfB18EF6f62A0278A273Af4b7A46b454F9E482dc2`](https://optimistic.etherscan.io/address/0xfB18EF6f62A0278A273Af4b7A46b454F9E482dc2) |
|
|
178
|
-
| Arbitrum (42161) | Router | [`0x7262e7483ab6f0db7b8f90eC3a9de3B02Ab36F6A`](https://arbiscan.io/address/0x7262e7483ab6f0db7b8f90eC3a9de3B02Ab36F6A) |
|
|
179
|
-
| Arbitrum (42161) | Quoter | [`0xfB18EF6f62A0278A273Af4b7A46b454F9E482dc2`](https://arbiscan.io/address/0xfB18EF6f62A0278A273Af4b7A46b454F9E482dc2) |
|
|
180
|
-
|
|
181
|
-
Always cross-check against the live manifest: `https://blazephoenix.xyz/api/manifest`.
|
|
182
|
-
|
|
183
|
-
## Learn the engineering
|
|
184
|
-
|
|
185
|
-
The protocol is documented from the deployed bytecode — every article ends with
|
|
186
|
-
a command to reproduce its claims:
|
|
187
|
-
|
|
188
|
-
- **The mathematics** (every formula; the originals are ours): https://blazephoenix.xyz/learn/the-mathematics
|
|
189
|
-
- **Integrate any bot** (keyless / keyed / ethers / viem / Python / AI-agent): https://blazephoenix.xyz/learn/integrate-any-bot
|
|
190
|
-
- **Web 2.5 vs Web 3.0** (the decision on-chain, not just settlement): https://blazephoenix.xyz/learn/web25-vs-web30
|
|
191
|
-
- **Machine-readable measured cases**: https://blazephoenix.xyz/measured-cases.json
|
|
192
|
-
- **Agent guide**: https://blazephoenix.xyz/llms.txt
|
|
193
|
-
|
|
194
|
-
## Citing BlazePhoenix
|
|
195
|
-
|
|
196
|
-
This repository ships a `CITATION.cff`, so GitHub shows a **“Cite this
|
|
197
|
-
repository”** button. Please cite with attribution and a link — the protocol's
|
|
198
|
-
original constructions (the Iron Law Φ, the Vitality Field Ψ, the
|
|
199
|
-
Capital-Anchored Filter, the Master Conservation Identity) are © 2026
|
|
200
|
-
BlazePhoenix.
|
|
175
|
+
## Regenerating the ABIs
|
|
176
|
+
|
|
177
|
+
The protocol ABIs are compiled from the Solidity sources, never written by hand:
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
npm i --no-save solc@0.8.36 && npm run gen:abis # expects ../Blaze-Phoenix-Dex
|
|
181
|
+
```
|
|
201
182
|
|
|
202
183
|
## License
|
|
203
184
|
|
|
204
|
-
MIT —
|
|
205
|
-
(The BlazePhoenix protocol and site carry their own licenses.)
|
|
185
|
+
MIT — deliberately permissive so anyone can integrate. The protocol contracts are BUSL-1.1.
|