@symbiome-forge/cow-sdk-wasm 0.1.0-alpha.1
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/LICENSE +674 -0
- package/README.md +278 -0
- package/dist/cloudflare/callbacks.cjs +2 -0
- package/dist/cloudflare/callbacks.d.ts +55 -0
- package/dist/cloudflare/callbacks.js +1 -0
- package/dist/cloudflare/envelope.cjs +2 -0
- package/dist/cloudflare/envelope.d.ts +5 -0
- package/dist/cloudflare/envelope.js +1 -0
- package/dist/cloudflare/errors.cjs +150 -0
- package/dist/cloudflare/errors.d.ts +82 -0
- package/dist/cloudflare/errors.js +145 -0
- package/dist/cloudflare/index.cjs +286 -0
- package/dist/cloudflare/index.d.ts +78 -0
- package/dist/cloudflare/index.js +1 -0
- package/dist/cloudflare/index.mjs +223 -0
- package/dist/cloudflare/internal.cjs +127 -0
- package/dist/cloudflare/internal.d.ts +40 -0
- package/dist/cloudflare/internal.js +115 -0
- package/dist/cloudflare/options.cjs +2 -0
- package/dist/cloudflare/options.d.ts +70 -0
- package/dist/cloudflare/options.js +1 -0
- package/dist/cloudflare/raw/cloudflare.cjs +65 -0
- package/dist/cloudflare/raw/cloudflare.d.ts +30 -0
- package/dist/cloudflare/raw/cloudflare.js +29 -0
- package/dist/default/callbacks.cjs +2 -0
- package/dist/default/callbacks.d.ts +55 -0
- package/dist/default/callbacks.js +1 -0
- package/dist/default/envelope.cjs +2 -0
- package/dist/default/envelope.d.ts +5 -0
- package/dist/default/envelope.js +1 -0
- package/dist/default/errors.cjs +150 -0
- package/dist/default/errors.d.ts +82 -0
- package/dist/default/errors.js +145 -0
- package/dist/default/index.cjs +359 -0
- package/dist/default/index.d.ts +94 -0
- package/dist/default/index.js +1 -0
- package/dist/default/index.mjs +295 -0
- package/dist/default/internal.cjs +127 -0
- package/dist/default/internal.d.ts +40 -0
- package/dist/default/internal.js +115 -0
- package/dist/default/options.cjs +2 -0
- package/dist/default/options.d.ts +70 -0
- package/dist/default/options.js +1 -0
- package/dist/default/raw/default.cjs +66 -0
- package/dist/default/raw/default.d.ts +31 -0
- package/dist/default/raw/default.js +30 -0
- package/dist/orderbook/callbacks.cjs +2 -0
- package/dist/orderbook/callbacks.d.ts +55 -0
- package/dist/orderbook/callbacks.js +1 -0
- package/dist/orderbook/envelope.cjs +2 -0
- package/dist/orderbook/envelope.d.ts +5 -0
- package/dist/orderbook/envelope.js +1 -0
- package/dist/orderbook/errors.cjs +150 -0
- package/dist/orderbook/errors.d.ts +82 -0
- package/dist/orderbook/errors.js +145 -0
- package/dist/orderbook/index.cjs +195 -0
- package/dist/orderbook/index.d.ts +57 -0
- package/dist/orderbook/index.js +1 -0
- package/dist/orderbook/index.mjs +139 -0
- package/dist/orderbook/internal.cjs +127 -0
- package/dist/orderbook/internal.d.ts +40 -0
- package/dist/orderbook/internal.js +115 -0
- package/dist/orderbook/options.cjs +2 -0
- package/dist/orderbook/options.d.ts +70 -0
- package/dist/orderbook/options.js +1 -0
- package/dist/orderbook/raw/orderbook.cjs +58 -0
- package/dist/orderbook/raw/orderbook.d.ts +23 -0
- package/dist/orderbook/raw/orderbook.js +22 -0
- package/dist/raw/cloudflare-web/cow_sdk_wasm.d.ts +2870 -0
- package/dist/raw/cloudflare-web/cow_sdk_wasm.js +2183 -0
- package/dist/raw/cloudflare-web/cow_sdk_wasm_bg.wasm +0 -0
- package/dist/raw/cloudflare-web/cow_sdk_wasm_bg.wasm.d.ts +65 -0
- package/dist/raw/default-bundler/cow_sdk_wasm.d.ts +2916 -0
- package/dist/raw/default-bundler/cow_sdk_wasm.js +9 -0
- package/dist/raw/default-bundler/cow_sdk_wasm_bg.js +2297 -0
- package/dist/raw/default-bundler/cow_sdk_wasm_bg.wasm +0 -0
- package/dist/raw/default-bundler/cow_sdk_wasm_bg.wasm.d.ts +75 -0
- package/dist/raw/default-nodejs/cow_sdk_wasm.cjs +2330 -0
- package/dist/raw/default-nodejs/cow_sdk_wasm.d.ts +2916 -0
- package/dist/raw/default-nodejs/cow_sdk_wasm_bg.wasm.d.ts +75 -0
- package/dist/raw/orderbook-bundler/cow_sdk_wasm.d.ts +1876 -0
- package/dist/raw/orderbook-bundler/cow_sdk_wasm.js +9 -0
- package/dist/raw/orderbook-bundler/cow_sdk_wasm_bg.js +1636 -0
- package/dist/raw/orderbook-bundler/cow_sdk_wasm_bg.wasm +0 -0
- package/dist/raw/orderbook-bundler/cow_sdk_wasm_bg.wasm.d.ts +50 -0
- package/dist/raw/orderbook-nodejs/cow_sdk_wasm.cjs +1661 -0
- package/dist/raw/orderbook-nodejs/cow_sdk_wasm.d.ts +1876 -0
- package/dist/raw/orderbook-nodejs/cow_sdk_wasm_bg.wasm.d.ts +50 -0
- package/dist/raw/signing-bundler/cow_sdk_wasm.d.ts +774 -0
- package/dist/raw/signing-bundler/cow_sdk_wasm.js +9 -0
- package/dist/raw/signing-bundler/cow_sdk_wasm_bg.js +1059 -0
- package/dist/raw/signing-bundler/cow_sdk_wasm_bg.wasm +0 -0
- package/dist/raw/signing-bundler/cow_sdk_wasm_bg.wasm.d.ts +27 -0
- package/dist/raw/signing-nodejs/cow_sdk_wasm.cjs +1078 -0
- package/dist/raw/signing-nodejs/cow_sdk_wasm.d.ts +774 -0
- package/dist/raw/signing-nodejs/cow_sdk_wasm_bg.wasm.d.ts +27 -0
- package/dist/signing/callbacks.cjs +2 -0
- package/dist/signing/callbacks.d.ts +55 -0
- package/dist/signing/callbacks.js +1 -0
- package/dist/signing/envelope.cjs +2 -0
- package/dist/signing/envelope.d.ts +5 -0
- package/dist/signing/envelope.js +1 -0
- package/dist/signing/errors.cjs +150 -0
- package/dist/signing/errors.d.ts +82 -0
- package/dist/signing/errors.js +145 -0
- package/dist/signing/index.cjs +93 -0
- package/dist/signing/index.d.ts +23 -0
- package/dist/signing/index.js +1 -0
- package/dist/signing/index.mjs +44 -0
- package/dist/signing/internal.cjs +127 -0
- package/dist/signing/internal.d.ts +40 -0
- package/dist/signing/internal.js +115 -0
- package/dist/signing/options.cjs +2 -0
- package/dist/signing/options.d.ts +70 -0
- package/dist/signing/options.js +1 -0
- package/dist/signing/raw/signing.cjs +52 -0
- package/dist/signing/raw/signing.d.ts +17 -0
- package/dist/signing/raw/signing.js +16 -0
- package/package.json +112 -0
package/README.md
ADDED
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
# @symbiome-forge/cow-sdk-wasm
|
|
2
|
+
|
|
3
|
+
TypeScript-callable WebAssembly bindings for the CoW Protocol Rust SDK.
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
npm install @symbiome-forge/cow-sdk-wasm@alpha
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
The package exposes a TypeScript facade over deterministic Rust protocol logic.
|
|
10
|
+
JavaScript and TypeScript consumers get typed DTOs, explicit wallet and HTTP
|
|
11
|
+
callbacks, per-call cancellation, per-call timeouts, and flavor-specific imports
|
|
12
|
+
without depending on a specific wallet library.
|
|
13
|
+
|
|
14
|
+
## When to use this SDK
|
|
15
|
+
|
|
16
|
+
| You are building... | Choose | Why |
|
|
17
|
+
| --- | --- | --- |
|
|
18
|
+
| Browser dapp with viem, ethers, wagmi, or an EIP-1193 wallet | `@symbiome-forge/cow-sdk-wasm` | Wallet stack stays outside the package behind typed callbacks |
|
|
19
|
+
| Browser dapp with a smaller orderbook bundle target | `@symbiome-forge/cow-sdk-wasm/orderbook` | Orderbook and signing subset with a smaller raw wasm budget |
|
|
20
|
+
| Node.js 22 or 24 LTS backend | `@symbiome-forge/cow-sdk-wasm` | Node target works without browser polyfills when transport is configured |
|
|
21
|
+
| Cloudflare Worker proxying CoW orderbook calls | `@symbiome-forge/cow-sdk-wasm/cloudflare` | Worker-compatible web target and explicit wasm module initialization |
|
|
22
|
+
| Signer service or HSM proxy | `@symbiome-forge/cow-sdk-wasm/signing` | Signing primitives without orderbook, trading, subgraph, or IPFS clients |
|
|
23
|
+
| Native Rust service, bot, solver, or treasury automation | `cow-sdk` | Avoids wasm-bindgen and npm packaging entirely |
|
|
24
|
+
| Rust app compiled to browser WASM | `cow-sdk-browser-wallet` plus `cow-sdk-core` (browser `FetchTransport`) | Rust-on-wasm path; this package is for JavaScript hosts |
|
|
25
|
+
|
|
26
|
+
## Not in this crate
|
|
27
|
+
|
|
28
|
+
Use the upstream TypeScript SDK packages until these capability families ship
|
|
29
|
+
in `cow-rs`:
|
|
30
|
+
|
|
31
|
+
- TWAP and composable orders.
|
|
32
|
+
- Cross-chain bridging.
|
|
33
|
+
- Cow Shed account abstraction.
|
|
34
|
+
- Flash-loan helpers.
|
|
35
|
+
- Weiroll command planning.
|
|
36
|
+
- Hardware wallet adapters.
|
|
37
|
+
- On-chain transaction submission; this package emits typed data or
|
|
38
|
+
transaction requests and lets the caller's wallet submit.
|
|
39
|
+
- WASI, WebAssembly components, TinyGo, Blazor, AssemblyScript guests, and
|
|
40
|
+
`no_std` embedded targets.
|
|
41
|
+
|
|
42
|
+
## Quickstart
|
|
43
|
+
|
|
44
|
+
### Node.js 22 or 24 with viem
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
import { TradingClient } from "@symbiome-forge/cow-sdk-wasm";
|
|
48
|
+
|
|
49
|
+
const trading = new TradingClient({
|
|
50
|
+
chainId: 1,
|
|
51
|
+
env: "prod",
|
|
52
|
+
appCode: "my-node-service",
|
|
53
|
+
transport: { kind: "fetch" },
|
|
54
|
+
transportPolicy: {
|
|
55
|
+
retryPolicy: { maxAttempts: 3, baseDelayMs: 200 },
|
|
56
|
+
userAgent: "my-node-service/1.0"
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// `getQuote` returns a fully resolved `QuoteResultsDto` envelope.
|
|
61
|
+
const quote = await trading.getQuote({
|
|
62
|
+
kind: "sell",
|
|
63
|
+
sellToken: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
|
|
64
|
+
buyToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
65
|
+
amount: "1000000000000000000"
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// Reuse the quote to sign and post in one call; `quote.value` is the
|
|
69
|
+
// `QuoteResultsDto` and the callback receives the EIP-712 envelope.
|
|
70
|
+
const result = await trading.postSwapOrderFromQuote(
|
|
71
|
+
quote.value,
|
|
72
|
+
"0x1111111111111111111111111111111111111111",
|
|
73
|
+
async (envelope) => walletClient.signTypedData(envelope),
|
|
74
|
+
{ walletConfig: { timeoutMs: 15_000 } }
|
|
75
|
+
);
|
|
76
|
+
// `result.value.orderId` is the posted order UID.
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Browser with `window.ethereum`
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
import { signOrderWithEip1193 } from "@symbiome-forge/cow-sdk-wasm";
|
|
83
|
+
|
|
84
|
+
const ethereum = window.ethereum;
|
|
85
|
+
const [owner] = await ethereum.request({ method: "eth_requestAccounts" });
|
|
86
|
+
const abortController = new AbortController();
|
|
87
|
+
|
|
88
|
+
// The order to sign: build it yourself or map it from a fetched quote.
|
|
89
|
+
const order = {
|
|
90
|
+
sellToken: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
|
|
91
|
+
buyToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
92
|
+
receiver: owner,
|
|
93
|
+
sellAmount: "1000000000000000000",
|
|
94
|
+
buyAmount: "3500000000",
|
|
95
|
+
validTo: Math.floor(Date.now() / 1000) + 3_600,
|
|
96
|
+
appData: "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
97
|
+
feeAmount: "0",
|
|
98
|
+
kind: "sell",
|
|
99
|
+
partiallyFillable: false,
|
|
100
|
+
sellTokenBalance: "erc20",
|
|
101
|
+
buyTokenBalance: "erc20"
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const signed = await signOrderWithEip1193(
|
|
105
|
+
order,
|
|
106
|
+
1,
|
|
107
|
+
owner,
|
|
108
|
+
(rpc) => ethereum.request(rpc),
|
|
109
|
+
{ signal: abortController.signal, walletConfig: { timeoutMs: 20_000 } }
|
|
110
|
+
);
|
|
111
|
+
// `signed.value` is the SignedOrderDto.
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Browser with MetaMask `eth_signTypedData_v4`
|
|
115
|
+
|
|
116
|
+
When the wallet exposes the typed-data JSON-RPC method directly, callers can
|
|
117
|
+
pass the envelope to `eth_signTypedData_v4` from inside the typed-data signer
|
|
118
|
+
callback. The helper hands the callback a typed-data envelope — plain `domain`,
|
|
119
|
+
`types`, `primaryType`, and `message` objects — that the callback serializes and
|
|
120
|
+
returns the signature string for.
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
import { signOrderWithTypedDataSigner } from "@symbiome-forge/cow-sdk-wasm";
|
|
124
|
+
|
|
125
|
+
const [owner] = await window.ethereum.request({ method: "eth_requestAccounts" });
|
|
126
|
+
|
|
127
|
+
const signed = await signOrderWithTypedDataSigner(order, 1, owner, async (envelope) => {
|
|
128
|
+
const signature = await window.ethereum.request({
|
|
129
|
+
method: "eth_signTypedData_v4",
|
|
130
|
+
params: [owner, JSON.stringify(envelope)]
|
|
131
|
+
});
|
|
132
|
+
if (typeof signature !== "string") {
|
|
133
|
+
throw new Error("wallet did not return a signature");
|
|
134
|
+
}
|
|
135
|
+
return signature;
|
|
136
|
+
});
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Cloudflare Worker
|
|
140
|
+
|
|
141
|
+
```ts
|
|
142
|
+
import initialize, {
|
|
143
|
+
OrderBookClient
|
|
144
|
+
} from "@symbiome-forge/cow-sdk-wasm/cloudflare";
|
|
145
|
+
import wasmModule from "@symbiome-forge/cow-sdk-wasm/cloudflare/wasm";
|
|
146
|
+
|
|
147
|
+
export default {
|
|
148
|
+
async fetch(request: Request, env: Env): Promise<Response> {
|
|
149
|
+
await initialize(wasmModule);
|
|
150
|
+
|
|
151
|
+
const client = new OrderBookClient({
|
|
152
|
+
chainId: 1,
|
|
153
|
+
env: "prod",
|
|
154
|
+
apiKey: env.COW_PARTNER_API_KEY ?? null,
|
|
155
|
+
transport: { kind: "fetch" },
|
|
156
|
+
transportPolicy: { userAgent: "my-worker/1.0" }
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
const quote = await client.getQuote(await request.json(), {
|
|
160
|
+
timeoutMs: 8_000
|
|
161
|
+
});
|
|
162
|
+
client.dispose();
|
|
163
|
+
|
|
164
|
+
return Response.json(quote);
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Choosing your import
|
|
170
|
+
|
|
171
|
+
| Import | Surface | Use when |
|
|
172
|
+
| --- | --- | --- |
|
|
173
|
+
| `@symbiome-forge/cow-sdk-wasm` | Default facade with orderbook, signing, app-data, IPFS, trading, and subgraph | General TypeScript or Node use |
|
|
174
|
+
| `@symbiome-forge/cow-sdk-wasm/orderbook` | Orderbook client, cancellation helpers, and signing helpers | Browser dapps that do not need trading or subgraph clients |
|
|
175
|
+
| `@symbiome-forge/cow-sdk-wasm/signing` | Signing, UID, EIP-1271, deployment, and version helpers | Signer services and HSM-facing adapters |
|
|
176
|
+
| `@symbiome-forge/cow-sdk-wasm/cloudflare` | Worker-compatible orderbook and trading facade | Cloudflare Workers |
|
|
177
|
+
| `@symbiome-forge/cow-sdk-wasm/cloudflare/wasm` | Raw Worker wasm module asset | Pass to the Cloudflare `initialize` helper |
|
|
178
|
+
|
|
179
|
+
Do not import from `dist/raw` or generated wasm-pack target directories. Raw
|
|
180
|
+
wasm-bindgen output is package-internal; public imports go through the facade
|
|
181
|
+
subpaths above.
|
|
182
|
+
|
|
183
|
+
## Performance and bundle size
|
|
184
|
+
|
|
185
|
+
The package is built with release-size settings and a `wasm-opt -Oz` post-pass.
|
|
186
|
+
Measured on the `0.1.0-alpha.1` build:
|
|
187
|
+
|
|
188
|
+
| Flavor | Raw wasm | Brotli | Gzip | Gate |
|
|
189
|
+
| --- | ---: | ---: | ---: | --- |
|
|
190
|
+
| default | 1.59 MiB | 501 KiB | 675 KiB | 3.3 MiB raw / 900 KiB brotli |
|
|
191
|
+
| orderbook | 0.99 MiB | 330 KiB | 432 KiB | 1.5 MiB raw / 500 KiB brotli |
|
|
192
|
+
| signing | 0.31 MiB | 119 KiB | 142 KiB | 0.9 MiB raw / 300 KiB brotli |
|
|
193
|
+
| cloudflare | 1.50 MiB | 478 KiB | 642 KiB | 3.2 MiB raw / 850 KiB brotli / 3,000,000 B gzip (warn at 2,700,000 B) |
|
|
194
|
+
|
|
195
|
+
The cloudflare flavor's gzip-compressed artifact is below the current
|
|
196
|
+
Cloudflare Workers Free compressed-size limit at the time of measurement.
|
|
197
|
+
Full Workers support still requires release-bundle verification and Worker
|
|
198
|
+
startup measurement; the release pipeline enforces the gzip byte budget on
|
|
199
|
+
every build, but Wrangler deployment and `startup_time_ms` telemetry are
|
|
200
|
+
separate operational gates.
|
|
201
|
+
|
|
202
|
+
Cloudflare Workers cold starts are runtime-sensitive. The package treats
|
|
203
|
+
300 ms as the warning threshold, 500 ms as the release gate, and 1 second as
|
|
204
|
+
the platform-limit budget that Worker consumers should stay well below.
|
|
205
|
+
|
|
206
|
+
## Transport configuration
|
|
207
|
+
|
|
208
|
+
Every client accepts one transport:
|
|
209
|
+
|
|
210
|
+
```ts
|
|
211
|
+
transport: { kind: "fetch" }
|
|
212
|
+
transport: { kind: "fetch", fetch: customFetch }
|
|
213
|
+
transport: { kind: "callback", callback: customHttpCallback }
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Use `fetch` for browser, Node, and Worker runtimes that expose a standards
|
|
217
|
+
compatible `fetch`. Use `callback` when the host must own request dispatch,
|
|
218
|
+
fixtures, proxying, custom authentication, or observability.
|
|
219
|
+
|
|
220
|
+
Every client also accepts optional `transportPolicy` settings for retry,
|
|
221
|
+
rate-limit, jitter, and user-agent behavior.
|
|
222
|
+
|
|
223
|
+
## Cancellation and timeouts
|
|
224
|
+
|
|
225
|
+
Every call accepts an optional `signal` (an `AbortSignal`) and a per-call
|
|
226
|
+
`timeoutMs`. Aborting the signal rejects the pending call promptly with a
|
|
227
|
+
`cancelled` `CowError`; `timeoutMs` rejects with a `timeout` error. Both resolve
|
|
228
|
+
the *awaited call* — an already-dispatched HTTP request may keep running in the
|
|
229
|
+
background until it completes or the timeout elapses, so treat cancellation as
|
|
230
|
+
"stop waiting," not a guarantee that the network request is halted.
|
|
231
|
+
|
|
232
|
+
## Architecture
|
|
233
|
+
|
|
234
|
+
The TypeScript facade is the public package contract. It:
|
|
235
|
+
|
|
236
|
+
- exposes camelCase TypeScript APIs;
|
|
237
|
+
- exposes `dispose()` and `[Symbol.dispose]` (so `using client = new …` works)
|
|
238
|
+
while hiding the raw wasm-bindgen `free()` handle;
|
|
239
|
+
- maps raw wasm errors into `CowError`;
|
|
240
|
+
- adapts `transport: { kind: "fetch" }` into the callback HTTP ABI;
|
|
241
|
+
- keeps wallet libraries outside the package behind named callback types.
|
|
242
|
+
|
|
243
|
+
## API reference
|
|
244
|
+
|
|
245
|
+
The declaration snapshots under `crates/wasm/snapshots/facade/` show the
|
|
246
|
+
public TypeScript surface for each flavor. Key exports include:
|
|
247
|
+
|
|
248
|
+
- clients: `OrderBookClient`, `TradingClient`, `SubgraphClient`, `IpfsClient`;
|
|
249
|
+
- signing helpers: `signOrderWithTypedDataSigner`, `signOrderWithEip1193`,
|
|
250
|
+
`signOrderEthSignDigest`, `signOrderWithEip1271`,
|
|
251
|
+
`signOrderWithCustomEip1271`;
|
|
252
|
+
- cancellation helpers: `signCancellationWithTypedDataSigner`,
|
|
253
|
+
`signCancellationWithEip1193`, `signCancellationEthSignDigest`,
|
|
254
|
+
`buildCancelOrderTx`, `buildPresignTx`;
|
|
255
|
+
- pure helpers: `domainSeparator`, `orderTypedData`, `computeOrderUid`,
|
|
256
|
+
`deploymentAddresses`, `supportedChainIds`, `appDataInfo`,
|
|
257
|
+
`validateAppDataDoc`, `appDataDoc`, `appDataHexToCid`,
|
|
258
|
+
`cidToAppDataHex`, `wasmVersion`.
|
|
259
|
+
|
|
260
|
+
## When to use this package vs the upstream TypeScript SDK
|
|
261
|
+
|
|
262
|
+
For most browser dapps, web apps, and CowSwap-style UIs, the upstream
|
|
263
|
+
[`@cowprotocol/cow-sdk`](https://www.npmjs.com/package/@cowprotocol/cow-sdk)
|
|
264
|
+
is the recommended choice; it is substantially smaller at equivalent feature
|
|
265
|
+
subsets. This package is appropriate for specialized cases:
|
|
266
|
+
|
|
267
|
+
- TypeScript services that need byte-for-byte parity with the Rust SDK's
|
|
268
|
+
EIP-712 + EIP-1271 signing path.
|
|
269
|
+
- Single-source-of-truth Rust + TypeScript embedding (one implementation
|
|
270
|
+
across both runtimes).
|
|
271
|
+
- Cloudflare Workers (size-compatible with the current Workers Free
|
|
272
|
+
compressed-size limit at the time of measurement; full Workers support
|
|
273
|
+
pending release-bundle and startup validation).
|
|
274
|
+
- Embeddable signing helpers (the `./signing` flavor is the smallest).
|
|
275
|
+
|
|
276
|
+
The "When to use this SDK" table at the top of this README routes consumers
|
|
277
|
+
by use case. The Quickstart sections above show the supported import shapes
|
|
278
|
+
for the most common runtimes.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export type SupportedChainId = 1 | 100 | 137 | 8453 | 42161 | 43114 | 56 | 11155111 | 9745 | 57073 | 59144;
|
|
2
|
+
export type CowEnv = "prod" | "staging";
|
|
3
|
+
export type CowFetchMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
|
|
4
|
+
export interface CowFetchRequest {
|
|
5
|
+
method: CowFetchMethod;
|
|
6
|
+
url: string;
|
|
7
|
+
headers: Record<string, string>;
|
|
8
|
+
body?: string;
|
|
9
|
+
timeoutMs?: number;
|
|
10
|
+
signal?: AbortSignal;
|
|
11
|
+
}
|
|
12
|
+
export interface CowFetchResponse {
|
|
13
|
+
status: number;
|
|
14
|
+
statusText?: string;
|
|
15
|
+
headers?: Record<string, string>;
|
|
16
|
+
body?: string;
|
|
17
|
+
}
|
|
18
|
+
export type CowFetchCallback = (request: CowFetchRequest) => Promise<CowFetchResponse> | CowFetchResponse;
|
|
19
|
+
export interface TypedDataDomainDto {
|
|
20
|
+
name: string;
|
|
21
|
+
version: string;
|
|
22
|
+
chainId: number;
|
|
23
|
+
verifyingContract: string;
|
|
24
|
+
}
|
|
25
|
+
export interface TypedDataFieldDto {
|
|
26
|
+
name: string;
|
|
27
|
+
type: string;
|
|
28
|
+
}
|
|
29
|
+
export interface TypedDataEnvelopeDto {
|
|
30
|
+
domain: TypedDataDomainDto;
|
|
31
|
+
types: Record<string, TypedDataFieldDto[]>;
|
|
32
|
+
primaryType: string;
|
|
33
|
+
message: unknown;
|
|
34
|
+
}
|
|
35
|
+
export interface CowEip1271SignRequest {
|
|
36
|
+
order: unknown;
|
|
37
|
+
typedData: TypedDataEnvelopeDto;
|
|
38
|
+
owner: string;
|
|
39
|
+
chainId: number;
|
|
40
|
+
}
|
|
41
|
+
export interface ContractCallDto {
|
|
42
|
+
address: string;
|
|
43
|
+
method: string;
|
|
44
|
+
abiJson: string;
|
|
45
|
+
argsJson: string;
|
|
46
|
+
}
|
|
47
|
+
export type TypedDataSignerCallback = (envelope: TypedDataEnvelopeDto) => Promise<string> | string;
|
|
48
|
+
export type Eip1193RequestCallback = (request: {
|
|
49
|
+
method: string;
|
|
50
|
+
params?: unknown[];
|
|
51
|
+
}) => Promise<unknown> | unknown;
|
|
52
|
+
export type DigestSignerCallback = (digest: string) => Promise<string> | string;
|
|
53
|
+
export type CowEip1271SignCallback = (request: CowEip1271SignRequest) => Promise<string> | string;
|
|
54
|
+
export type CustomEip1271Callback = CowEip1271SignCallback;
|
|
55
|
+
export type ContractReadCallback = (request: ContractCallDto) => Promise<string> | string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.normalizeError = normalizeError;
|
|
4
|
+
exports.cancelledError = cancelledError;
|
|
5
|
+
exports.invalidInput = invalidInput;
|
|
6
|
+
const knownKinds = new Set([
|
|
7
|
+
"invalidInput",
|
|
8
|
+
"unknownEnumValue",
|
|
9
|
+
"unsupportedChain",
|
|
10
|
+
"walletRequest",
|
|
11
|
+
"walletTimeout",
|
|
12
|
+
"transport",
|
|
13
|
+
"orderbook",
|
|
14
|
+
"subgraph",
|
|
15
|
+
"signing",
|
|
16
|
+
"appData",
|
|
17
|
+
"cancelled",
|
|
18
|
+
"internal",
|
|
19
|
+
"__unknown"
|
|
20
|
+
]);
|
|
21
|
+
function normalizeError(raw) {
|
|
22
|
+
if (isRecord(raw)) {
|
|
23
|
+
// The Rust `WasmError` serializes with serde `rename_all(_fields) = "camelCase"`
|
|
24
|
+
// through a json-compatible serializer, so it already crosses the boundary as a
|
|
25
|
+
// camelCase plain object — no field renaming is needed here.
|
|
26
|
+
const normalized = raw;
|
|
27
|
+
const kind = typeof normalized.kind === "string" ? normalized.kind : undefined;
|
|
28
|
+
if (kind && knownKinds.has(kind)) {
|
|
29
|
+
const schemaVersion = normalized.schemaVersion === "__unknown" ? "__unknown" : "v1";
|
|
30
|
+
if (kind === "__unknown") {
|
|
31
|
+
return {
|
|
32
|
+
schemaVersion,
|
|
33
|
+
kind: "__unknown",
|
|
34
|
+
message: unknownMessage(),
|
|
35
|
+
raw: normalized.raw ?? raw
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
return withActionableMessage({
|
|
39
|
+
...normalized,
|
|
40
|
+
schemaVersion,
|
|
41
|
+
kind
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
if (kind) {
|
|
45
|
+
return {
|
|
46
|
+
schemaVersion: normalized.schemaVersion === "__unknown" ? "__unknown" : "v1",
|
|
47
|
+
kind: "__unknown",
|
|
48
|
+
message: unknownMessage(),
|
|
49
|
+
raw
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (raw instanceof Error) {
|
|
54
|
+
return (classifyDeserializationFailure(raw.message) ?? {
|
|
55
|
+
schemaVersion: "v1",
|
|
56
|
+
kind: "internal",
|
|
57
|
+
message: internalMessage(raw.message)
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
return (classifyDeserializationFailure(String(raw)) ?? {
|
|
61
|
+
schemaVersion: "v1",
|
|
62
|
+
kind: "internal",
|
|
63
|
+
message: internalMessage(String(raw))
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
// Input-DTO deserialization failures cross the wasm boundary as a plain
|
|
67
|
+
// `Error`: the generated wasm-bindgen glue throws the serde message, so it
|
|
68
|
+
// never carries a structured `kind`. These are CALLER input errors — a value
|
|
69
|
+
// that does not match the documented input type (unknown enum variant,
|
|
70
|
+
// missing/unknown field, wrong type) — not SDK-internal faults, so they must
|
|
71
|
+
// normalize to `invalidInput` rather than `internal` (whose contract implies
|
|
72
|
+
// an SDK bug). The verbatim detail is preserved because it already names the
|
|
73
|
+
// offending field/variant and the expected set, e.g.
|
|
74
|
+
// "unknown variant `teleport`, expected `sell` or `buy`".
|
|
75
|
+
const DESERIALIZATION_FAILURE_PATTERNS = [
|
|
76
|
+
/unknown variant `/,
|
|
77
|
+
/missing field `/,
|
|
78
|
+
/unknown field `/,
|
|
79
|
+
/duplicate field `/,
|
|
80
|
+
/invalid type:/,
|
|
81
|
+
/invalid length\b/,
|
|
82
|
+
/invalid value:/,
|
|
83
|
+
/data did not match any variant/
|
|
84
|
+
];
|
|
85
|
+
function classifyDeserializationFailure(message) {
|
|
86
|
+
if (!DESERIALIZATION_FAILURE_PATTERNS.some((pattern) => pattern.test(message))) {
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
const detail = message.replace(/^Error:\s*/, "");
|
|
90
|
+
const field = detail.match(/(?:missing|unknown|duplicate) field `([^`]+)`/)?.[1];
|
|
91
|
+
const reason = `Invalid SDK input: ${detail}. Check the value against the documented input type and retry.`;
|
|
92
|
+
return field !== undefined
|
|
93
|
+
? { schemaVersion: "v1", kind: "invalidInput", field, message: reason }
|
|
94
|
+
: { schemaVersion: "v1", kind: "invalidInput", message: reason };
|
|
95
|
+
}
|
|
96
|
+
function cancelledError() {
|
|
97
|
+
return {
|
|
98
|
+
schemaVersion: "v1",
|
|
99
|
+
kind: "cancelled",
|
|
100
|
+
message: "Operation was cancelled. Create a fresh AbortController or retry without an already-aborted signal."
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
function invalidInput(field, reason) {
|
|
104
|
+
return {
|
|
105
|
+
schemaVersion: "v1",
|
|
106
|
+
kind: "invalidInput",
|
|
107
|
+
field,
|
|
108
|
+
message: `Invalid \`${field}\`: ${reason}. Check the value supplied for \`${field}\` and retry with a valid SDK input.`
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function isRecord(value) {
|
|
112
|
+
return typeof value === "object" && value !== null;
|
|
113
|
+
}
|
|
114
|
+
function withActionableMessage(error) {
|
|
115
|
+
if ("message" in error && typeof error.message === "string" && error.message.length > 0) {
|
|
116
|
+
return error;
|
|
117
|
+
}
|
|
118
|
+
switch (error.kind) {
|
|
119
|
+
case "unknownEnumValue":
|
|
120
|
+
return {
|
|
121
|
+
...error,
|
|
122
|
+
message: `Unsupported value \`${error.value}\` for \`${error.field}\`. Use one of the documented values for this field.`
|
|
123
|
+
};
|
|
124
|
+
case "unsupportedChain":
|
|
125
|
+
return {
|
|
126
|
+
...error,
|
|
127
|
+
message: `Unsupported chain ID ${error.chainId}. Call supportedChainIds() before constructing requests and route unsupported networks to another integration.`
|
|
128
|
+
};
|
|
129
|
+
case "walletTimeout":
|
|
130
|
+
return {
|
|
131
|
+
...error,
|
|
132
|
+
message: `Wallet request timed out after ${error.timeoutMs} ms. Increase walletConfig.timeoutMs or ask the user to approve the wallet request before the timeout.`
|
|
133
|
+
};
|
|
134
|
+
case "cancelled":
|
|
135
|
+
return cancelledError();
|
|
136
|
+
case "__unknown":
|
|
137
|
+
return {
|
|
138
|
+
...error,
|
|
139
|
+
message: unknownMessage()
|
|
140
|
+
};
|
|
141
|
+
default:
|
|
142
|
+
return error;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
function internalMessage(detail) {
|
|
146
|
+
return `SDK internal error: ${detail}. This indicates serialization or invariant failure; retry with the same inputs only after checking the reported input shape.`;
|
|
147
|
+
}
|
|
148
|
+
function unknownMessage() {
|
|
149
|
+
return "SDK received an unrecognized error variant. Inspect raw, preserve it in logs without credentials, and update the SDK if the variant is now documented.";
|
|
150
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { SchemaVersion } from "./envelope.js";
|
|
2
|
+
/**
|
|
3
|
+
* Coarse, switchable classification of an orderbook rejection. Lets a consumer
|
|
4
|
+
* branch on the action a rejection calls for — fix the request, fund the
|
|
5
|
+
* wallet, re-quote, wait, or escalate — without matching every wire tag. The
|
|
6
|
+
* `__unknown` member is the forward-compatible sentinel for a category a newer
|
|
7
|
+
* SDK may introduce.
|
|
8
|
+
*/
|
|
9
|
+
export type OrderBookRejectionCategory = "authorization" | "insufficientFunds" | "invalidOrder" | "notFound" | "conflict" | "unfulfillable" | "server" | "__unknown";
|
|
10
|
+
export type CowError = {
|
|
11
|
+
schemaVersion: "v1";
|
|
12
|
+
kind: "invalidInput";
|
|
13
|
+
message: string;
|
|
14
|
+
field?: string;
|
|
15
|
+
} | {
|
|
16
|
+
schemaVersion: "v1";
|
|
17
|
+
kind: "unknownEnumValue";
|
|
18
|
+
message: string;
|
|
19
|
+
field: string;
|
|
20
|
+
value: string;
|
|
21
|
+
} | {
|
|
22
|
+
schemaVersion: "v1";
|
|
23
|
+
kind: "unsupportedChain";
|
|
24
|
+
message: string;
|
|
25
|
+
chainId: number;
|
|
26
|
+
} | {
|
|
27
|
+
schemaVersion: "v1";
|
|
28
|
+
kind: "walletRequest";
|
|
29
|
+
method: string;
|
|
30
|
+
code?: number;
|
|
31
|
+
message: string;
|
|
32
|
+
} | {
|
|
33
|
+
schemaVersion: "v1";
|
|
34
|
+
kind: "walletTimeout";
|
|
35
|
+
message: string;
|
|
36
|
+
timeoutMs: number;
|
|
37
|
+
} | {
|
|
38
|
+
schemaVersion: "v1";
|
|
39
|
+
kind: "transport";
|
|
40
|
+
class: string;
|
|
41
|
+
message: string;
|
|
42
|
+
status?: number;
|
|
43
|
+
headers?: [string, string][];
|
|
44
|
+
body?: string;
|
|
45
|
+
} | {
|
|
46
|
+
schemaVersion: "v1";
|
|
47
|
+
kind: "orderbook";
|
|
48
|
+
code?: string;
|
|
49
|
+
category?: OrderBookRejectionCategory;
|
|
50
|
+
message: string;
|
|
51
|
+
retryable: boolean;
|
|
52
|
+
retryAfterMs?: number;
|
|
53
|
+
} | {
|
|
54
|
+
schemaVersion: "v1";
|
|
55
|
+
kind: "subgraph";
|
|
56
|
+
message: string;
|
|
57
|
+
} | {
|
|
58
|
+
schemaVersion: "v1";
|
|
59
|
+
kind: "signing";
|
|
60
|
+
message: string;
|
|
61
|
+
} | {
|
|
62
|
+
schemaVersion: "v1";
|
|
63
|
+
kind: "appData";
|
|
64
|
+
class?: string;
|
|
65
|
+
message: string;
|
|
66
|
+
} | {
|
|
67
|
+
schemaVersion: "v1";
|
|
68
|
+
kind: "cancelled";
|
|
69
|
+
message: string;
|
|
70
|
+
} | {
|
|
71
|
+
schemaVersion: "v1";
|
|
72
|
+
kind: "internal";
|
|
73
|
+
message: string;
|
|
74
|
+
} | {
|
|
75
|
+
schemaVersion: SchemaVersion;
|
|
76
|
+
kind: "__unknown";
|
|
77
|
+
message: string;
|
|
78
|
+
raw: unknown;
|
|
79
|
+
};
|
|
80
|
+
export declare function normalizeError(raw: unknown): CowError;
|
|
81
|
+
export declare function cancelledError(): CowError;
|
|
82
|
+
export declare function invalidInput(field: string, reason: string): CowError;
|