@blazephoenix/sdk 1.0.1 → 1.1.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 +32 -4
- package/dist/index.cjs +21 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +21 -4
- package/dist/index.js.map +1 -1
- package/llms.txt +8 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,6 +13,31 @@ npm i @blazephoenix/sdk viem
|
|
|
13
13
|
# or straight from GitHub (builds on install): npm i github:blazephoenixxyz-crypto/SDK viem
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
+
## BlazePhoenix in one sentence
|
|
17
|
+
|
|
18
|
+
BlazePhoenix is the fully on-chain DEX aggregator — the route is computed inside the transaction that executes it — paired with an oracle-free staking engine that proves its own solvency on every transaction. It runs on Base, Ethereum, Optimism, Arbitrum and Robinhood Chain.
|
|
19
|
+
|
|
20
|
+
**Swap** in the [app](https://blazephoenix.xyz/?tab=swap) · **integrate** with the [SDK](https://github.com/blazephoenixxyz-crypto/SDK) (`npm i @blazephoenix/sdk`) · **connect an agent** to the [MCP server](https://github.com/blazephoenixxyz-crypto/blazephoenix-mcp) (`https://blazephoenix.xyz/mcp`, no key)
|
|
21
|
+
|
|
22
|
+
## Reading guide by level
|
|
23
|
+
|
|
24
|
+
- **New to DeFi:** [BlazePhoenix in five minutes](https://blazephoenix.xyz/learn/blazephoenix-in-five-minutes), then [What is a DEX aggregator](https://blazephoenix.xyz/learn/what-is-a-dex-aggregator) and [How to swap tokens safely](https://blazephoenix.xyz/learn/how-to-swap-safely).
|
|
25
|
+
- **Comfortable with swaps:** [Anatomy of a DEX aggregator](https://blazephoenix.xyz/learn/anatomy-of-an-aggregator) and [BlazePhoenix vs the established aggregators](https://blazephoenix.xyz/learn/how-we-compare).
|
|
26
|
+
- **Engineers and researchers:** the [Technical Whitepaper v2.3](https://blazephoenix.xyz/whitepaper.md) (DOI [10.5281/zenodo.23084091](https://doi.org/10.5281/zenodo.23084091)), the contract source in [Blaze-Phoenix-Dex](https://github.com/blazephoenixxyz-crypto/Blaze-Phoenix-Dex) and [Blaze-Phoenix-Staking](https://github.com/blazephoenixxyz-crypto/Blaze-Phoenix-Staking), and [On-chain quoting](https://blazephoenix.xyz/learn/on-chain-quoting).
|
|
27
|
+
- **Models and agents:** [https://blazephoenix.xyz/llms.txt](https://blazephoenix.xyz/llms.txt) and the [reading guide](https://blazephoenix.xyz/reading-guide.md).
|
|
28
|
+
|
|
29
|
+
## Trust and verification
|
|
30
|
+
|
|
31
|
+
Each item links to the place where it can be checked. The full list is at [https://blazephoenix.xyz/trust](https://blazephoenix.xyz/trust).
|
|
32
|
+
|
|
33
|
+
- **Verified contracts:** source-verified on Sourcify and the chain explorers; every address per chain at [/api/deployments](https://blazephoenix.xyz/api/deployments).
|
|
34
|
+
- **Source available:** the contract source is public under the [Business Source License 1.1](https://github.com/blazephoenixxyz-crypto/Blaze-Phoenix-Dex/blob/main/LICENSE), converting to GPL-2.0-or-later on 2030-06-01.
|
|
35
|
+
- **Public CI:** [GitHub Actions](https://github.com/blazephoenixxyz-crypto/Blaze-Phoenix-Dex/actions) on every push, including the Certora Prover and Halmos.
|
|
36
|
+
- **Bug bounty:** a [public programme](https://blazephoenix.xyz/bounty) with [credited researchers](https://blazephoenix.xyz/security/researchers) and [published advisories](https://blazephoenix.xyz/security/advisories).
|
|
37
|
+
- **Whitepaper DOI:** [10.5281/zenodo.23084091](https://doi.org/10.5281/zenodo.23084091); papers timestamped with [OpenTimestamps](https://blazephoenix.xyz/provenance/provenance.json).
|
|
38
|
+
- **Contact:** contact@blazephoenix.xyz ([security.txt](https://blazephoenix.xyz/.well-known/security.txt)); official channels at [/official](https://blazephoenix.xyz/official).
|
|
39
|
+
- **Audit status:** an independent external audit is scheduled before launch.
|
|
40
|
+
|
|
16
41
|
## Quote → build → execute
|
|
17
42
|
|
|
18
43
|
```ts
|
|
@@ -91,17 +116,20 @@ The SDK adapts to what each version can do (`featuresOf(version)`):
|
|
|
91
116
|
| on-chain `batchQuote` | parallel previews | ✅ chunked |
|
|
92
117
|
| `ExecutionProof` on every fill (quoted vs realised vs floor) | — | ✅ |
|
|
93
118
|
|
|
94
|
-
###
|
|
119
|
+
### Only pinned addresses are routed to by default
|
|
95
120
|
|
|
96
121
|
The registry has three layers:
|
|
97
122
|
|
|
98
123
|
1. **Embedded** — shipped in the package. Non-zero addresses are **pins**: nothing fetched
|
|
99
|
-
at runtime can move them
|
|
124
|
+
at runtime can move them, and by default they are the only Router and Quoter addresses
|
|
125
|
+
a quote or a swap uses. A new deployment reaches you with a new SDK release.
|
|
100
126
|
2. **Remote** — `GET https://blazephoenix.xyz/api/deployments` (static JSON, refreshed every
|
|
101
127
|
10 min in the background; the first lookup waits at most 3 s). It can only fill what the
|
|
102
128
|
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+).
|
|
104
|
-
|
|
129
|
+
versions that can be verified on-chain (2.x+). Those versions are listed, but routed to
|
|
130
|
+
only with `registry: { remoteVersions: true }`: the on-chain check reads the entry's own
|
|
131
|
+
contracts, so it cannot tell a real deployment from a look-alike. With the opt-in, every
|
|
132
|
+
remote-sourced set is still **verified on your RPC before first use**:
|
|
105
133
|
code at every address, `VERSION()` matches, and the Quoter, Router and Solver all point at
|
|
106
134
|
the same Hub and Solver. Anything else fails closed (`deployment_unverified`).
|
|
107
135
|
3. **Your overrides** — always win:
|
package/dist/index.cjs
CHANGED
|
@@ -5356,6 +5356,7 @@ var Registry = class {
|
|
|
5356
5356
|
fetchedAt = 0;
|
|
5357
5357
|
lastError;
|
|
5358
5358
|
mode;
|
|
5359
|
+
remoteVersions;
|
|
5359
5360
|
url;
|
|
5360
5361
|
ttlMs;
|
|
5361
5362
|
fetchFn;
|
|
@@ -5364,6 +5365,7 @@ var Registry = class {
|
|
|
5364
5365
|
overrides = /* @__PURE__ */ new Map();
|
|
5365
5366
|
constructor(opts = {}, overrides) {
|
|
5366
5367
|
this.mode = opts.mode ?? "auto";
|
|
5368
|
+
this.remoteVersions = opts.remoteVersions ?? false;
|
|
5367
5369
|
this.url = opts.url ?? DEPLOYMENTS_URL;
|
|
5368
5370
|
this.ttlMs = opts.ttlMs ?? 10 * 6e4;
|
|
5369
5371
|
this.fetchFn = opts.fetchFn ?? globalThis.fetch;
|
|
@@ -5495,7 +5497,7 @@ var Registry = class {
|
|
|
5495
5497
|
if (!isValidSelector(selector)) throw new BlazeError("bad_request", `bad version selector "${selector}"`);
|
|
5496
5498
|
const ov = this.overrides.get(chainId);
|
|
5497
5499
|
const sel = ov?.version && selector === "latest" ? ov.version : selector;
|
|
5498
|
-
const candidates = this.doc.versions.filter((v) => matchesSelector(v.version, sel) && isDeployed(v.chains[chainId])).sort((a, b) => compareVersions(b.version, a.version));
|
|
5500
|
+
const candidates = this.doc.versions.filter((v) => matchesSelector(v.version, sel) && isDeployed(v.chains[chainId])).filter((v) => this.remoteVersions || this.isPinned(v.version, chainId)).sort((a, b) => compareVersions(b.version, a.version));
|
|
5499
5501
|
const pick = candidates[0];
|
|
5500
5502
|
if (ov && (ov.router || ov.quoter)) {
|
|
5501
5503
|
const base = pick ? { ...pick.chains[chainId] } : {
|
|
@@ -5515,9 +5517,10 @@ var Registry = class {
|
|
|
5515
5517
|
}
|
|
5516
5518
|
if (!pick) {
|
|
5517
5519
|
const deployed = this.versionsOn(chainId);
|
|
5520
|
+
const remoteOnly = this.remoteVersions ? [] : deployed.filter((v) => matchesSelector(v, sel) && !this.isPinned(v, chainId));
|
|
5518
5521
|
throw new BlazeError(
|
|
5519
5522
|
"not_deployed",
|
|
5520
|
-
`no BlazePhoenix deployment matching version "${selector}" on chain ${chainId}` + (deployed.length ? ` (deployed: ${deployed.join(", ")})` : ""),
|
|
5523
|
+
`no BlazePhoenix deployment matching version "${selector}" on chain ${chainId}` + (deployed.length ? ` (deployed: ${deployed.join(", ")})` : "") + (remoteOnly.length ? ` \u2014 ${remoteOnly.join(", ")} is known only from the fetched registry; update the SDK, or set registry.remoteVersions after checking the addresses yourself` : ""),
|
|
5521
5524
|
{ details: { chainId, selector, deployed } }
|
|
5522
5525
|
);
|
|
5523
5526
|
}
|
|
@@ -5526,6 +5529,11 @@ var Registry = class {
|
|
|
5526
5529
|
const source = src("router") === "remote" || src("quoter") === "remote" ? "remote" : "embedded";
|
|
5527
5530
|
return { chainId, version: pick.version, status: pick.status, contracts: { ...set }, source };
|
|
5528
5531
|
}
|
|
5532
|
+
/** Router and Quoter both pinned in this package (not filled by a fetched document). */
|
|
5533
|
+
isPinned(version, chainId) {
|
|
5534
|
+
const src = (k) => this.fieldSource[`${version}|${chainId}|${k}`];
|
|
5535
|
+
return src("router") === "embedded" && src("quoter") === "embedded";
|
|
5536
|
+
}
|
|
5529
5537
|
latestKnownVersion(selector) {
|
|
5530
5538
|
const all = this.doc.versions.map((v) => v.version).sort((a, b) => compareVersions(b, a));
|
|
5531
5539
|
const m = selector ? all.find((v) => matchesSelector(v, selector)) : void 0;
|
|
@@ -5773,16 +5781,19 @@ var BlazePhoenix = class {
|
|
|
5773
5781
|
return { address: c.weth, native: true };
|
|
5774
5782
|
case "WETH":
|
|
5775
5783
|
return { address: c.weth, native: false };
|
|
5784
|
+
// `usdc` holds each chain's one dollar asset: USDG on Robinhood Chain, USDC
|
|
5785
|
+
// elsewhere. The other symbol names a different token there, so it is refused.
|
|
5776
5786
|
case "USDC":
|
|
5777
5787
|
case "USDG":
|
|
5778
|
-
return { address: c.usdc, native: false };
|
|
5788
|
+
if (s.toUpperCase() === (chainId === 4663 ? "USDG" : "USDC")) return { address: c.usdc, native: false };
|
|
5789
|
+
break;
|
|
5779
5790
|
case "BZPX":
|
|
5780
5791
|
if (c.bzpx) return { address: c.bzpx, native: false };
|
|
5781
5792
|
break;
|
|
5782
5793
|
}
|
|
5783
5794
|
throw new BlazeError(
|
|
5784
5795
|
"bad_request",
|
|
5785
|
-
`${side}: "${ref}" is not a 0x address or a built-in symbol (ETH, WETH, USDC, BZPX) on ${c.name} \u2014 pass the token address`
|
|
5796
|
+
`${side}: "${ref}" is not a 0x address or a built-in symbol (ETH, WETH, ${chainId === 4663 ? "USDG" : "USDC"}, BZPX) on ${c.name} \u2014 pass the token address`
|
|
5786
5797
|
);
|
|
5787
5798
|
}
|
|
5788
5799
|
async decimalsOf(client, chainId, t) {
|
|
@@ -6172,6 +6183,12 @@ var BlazePhoenix = class {
|
|
|
6172
6183
|
if (r.status !== "success") throw new BlazeError("reverted", `approval transaction reverted (${approvalHash})`);
|
|
6173
6184
|
}
|
|
6174
6185
|
plan = { ...plan, approval: { ...plan.approval, current: plan.approval.amount } };
|
|
6186
|
+
if (Date.now() - plan.quote.quotedAt > maxAge) {
|
|
6187
|
+
if (!req) {
|
|
6188
|
+
throw new BlazeError("bad_request", `plan went older than ${maxAge}ms while the approval confirmed${approvalHash ? ` (${approvalHash})` : ""} \u2014 the swap was NOT sent; rebuild the plan, or pass \`request\` so it can be rebuilt`);
|
|
6189
|
+
}
|
|
6190
|
+
plan = await this.buildSwap({ ...req, from: req.from ?? account.address });
|
|
6191
|
+
}
|
|
6175
6192
|
}
|
|
6176
6193
|
if (opts.simulate ?? true) {
|
|
6177
6194
|
const sim = await this.simulate(plan, account.address);
|