@symbiome-forge/cow-sdk-wasm 0.1.0-alpha.3 → 0.1.0-alpha.5
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 +177 -216
- package/dist/default/callbacks.d.ts +18 -0
- package/dist/default/index.cjs +3 -0
- package/dist/default/index.d.ts +1 -0
- package/dist/default/index.mjs +3 -0
- package/dist/default/internal.cjs +3 -2
- package/dist/default/internal.js +3 -2
- package/dist/{cloudflare/raw/cloudflare.cjs → default/raw/trading-web.cjs} +1 -1
- package/dist/{cloudflare/raw/cloudflare.d.ts → default/raw/trading-web.d.ts} +2 -2
- package/dist/{cloudflare/raw/cloudflare.js → default/raw/trading-web.js} +1 -1
- package/dist/orderbook/callbacks.d.ts +18 -0
- package/dist/orderbook/internal.cjs +3 -2
- package/dist/orderbook/internal.js +3 -2
- package/dist/orderbook/raw/trading-web.cjs +65 -0
- package/dist/orderbook/raw/trading-web.d.ts +30 -0
- package/dist/orderbook/raw/trading-web.js +29 -0
- package/dist/raw/default-bundler/cow_sdk_wasm.d.ts +63 -15
- package/dist/raw/default-bundler/cow_sdk_wasm_bg.js +87 -36
- package/dist/raw/default-bundler/cow_sdk_wasm_bg.wasm +0 -0
- package/dist/raw/default-bundler/cow_sdk_wasm_bg.wasm.d.ts +4 -3
- package/dist/raw/default-nodejs/cow_sdk_wasm.cjs +87 -36
- package/dist/raw/default-nodejs/cow_sdk_wasm.d.ts +63 -15
- package/dist/raw/default-nodejs/cow_sdk_wasm_bg.wasm.d.ts +4 -3
- package/dist/raw/orderbook-bundler/cow_sdk_wasm.d.ts +18 -6
- package/dist/raw/orderbook-bundler/cow_sdk_wasm_bg.js +37 -25
- package/dist/raw/orderbook-bundler/cow_sdk_wasm_bg.wasm +0 -0
- package/dist/raw/orderbook-bundler/cow_sdk_wasm_bg.wasm.d.ts +3 -3
- package/dist/raw/orderbook-nodejs/cow_sdk_wasm.cjs +37 -25
- package/dist/raw/orderbook-nodejs/cow_sdk_wasm.d.ts +18 -6
- package/dist/raw/orderbook-nodejs/cow_sdk_wasm_bg.wasm.d.ts +3 -3
- package/dist/raw/signing-bundler/cow_sdk_wasm_bg.js +10 -10
- package/dist/raw/signing-bundler/cow_sdk_wasm_bg.wasm +0 -0
- package/dist/raw/signing-bundler/cow_sdk_wasm_bg.wasm.d.ts +3 -3
- package/dist/raw/signing-nodejs/cow_sdk_wasm.cjs +10 -10
- package/dist/raw/signing-nodejs/cow_sdk_wasm_bg.wasm.d.ts +3 -3
- package/dist/raw/trading-bundler/cow_sdk_wasm.d.ts +2977 -0
- package/dist/raw/trading-bundler/cow_sdk_wasm.js +9 -0
- package/dist/raw/trading-bundler/cow_sdk_wasm_bg.js +2175 -0
- package/dist/raw/{cloudflare-web → trading-bundler}/cow_sdk_wasm_bg.wasm +0 -0
- package/dist/raw/{cloudflare-web → trading-bundler}/cow_sdk_wasm_bg.wasm.d.ts +4 -3
- package/dist/raw/trading-nodejs/cow_sdk_wasm.cjs +2206 -0
- package/dist/raw/trading-nodejs/cow_sdk_wasm.d.ts +2977 -0
- package/dist/raw/trading-nodejs/cow_sdk_wasm_bg.wasm.d.ts +68 -0
- package/dist/raw/{cloudflare-web → trading-web}/cow_sdk_wasm.d.ts +67 -18
- package/dist/raw/{cloudflare-web → trading-web}/cow_sdk_wasm.js +87 -36
- package/dist/raw/trading-web/cow_sdk_wasm_bg.wasm.d.ts +68 -0
- package/dist/signing/callbacks.d.ts +18 -0
- package/dist/signing/internal.cjs +3 -2
- package/dist/signing/internal.js +3 -2
- package/dist/signing/raw/trading-web.cjs +65 -0
- package/dist/signing/raw/trading-web.d.ts +30 -0
- package/dist/signing/raw/trading-web.js +29 -0
- package/dist/{cloudflare → trading}/callbacks.d.ts +18 -0
- package/dist/trading/edge.d.ts +92 -0
- package/dist/trading/edge.mjs +243 -0
- package/dist/{cloudflare → trading}/index.cjs +15 -1
- package/dist/{cloudflare → trading}/index.d.ts +15 -3
- package/dist/{cloudflare → trading}/index.mjs +15 -1
- package/dist/{cloudflare → trading}/internal.cjs +3 -2
- package/dist/{cloudflare → trading}/internal.js +3 -2
- package/dist/trading/raw/trading-web.d.ts +30 -0
- package/dist/trading/raw/trading-web.js +29 -0
- package/dist/trading/raw/trading.cjs +72 -0
- package/dist/trading/raw/trading.d.ts +33 -0
- package/dist/trading/raw/trading.js +35 -0
- package/package.json +38 -8
- /package/dist/{cloudflare → trading}/callbacks.cjs +0 -0
- /package/dist/{cloudflare → trading}/callbacks.js +0 -0
- /package/dist/{cloudflare → trading}/envelope.cjs +0 -0
- /package/dist/{cloudflare → trading}/envelope.d.ts +0 -0
- /package/dist/{cloudflare → trading}/envelope.js +0 -0
- /package/dist/{cloudflare → trading}/errors.cjs +0 -0
- /package/dist/{cloudflare → trading}/errors.d.ts +0 -0
- /package/dist/{cloudflare → trading}/errors.js +0 -0
- /package/dist/{cloudflare → trading}/index.js +0 -0
- /package/dist/{cloudflare → trading}/internal.d.ts +0 -0
- /package/dist/{cloudflare → trading}/options.cjs +0 -0
- /package/dist/{cloudflare → trading}/options.d.ts +0 -0
- /package/dist/{cloudflare → trading}/options.js +0 -0
package/README.md
CHANGED
|
@@ -1,279 +1,240 @@
|
|
|
1
1
|
# @symbiome-forge/cow-sdk-wasm
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[CoW Protocol](https://cow.fi)'s Rust SDK, compiled to WebAssembly for JavaScript
|
|
4
|
+
and TypeScript. One protocol implementation runs in both runtimes, so the EIP-712
|
|
5
|
+
and EIP-1271 signatures a browser produces are byte-identical to the Rust
|
|
6
|
+
service's — checked against the upstream `cowprotocol/services` and
|
|
7
|
+
`cowprotocol/contracts` fixtures in CI, not asserted in prose.
|
|
4
8
|
|
|
5
9
|
```sh
|
|
6
10
|
npm install @symbiome-forge/cow-sdk-wasm@alpha
|
|
7
11
|
```
|
|
8
12
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
A TypeScript facade over deterministic Rust protocol logic: typed DTOs, explicit
|
|
14
|
+
wallet and HTTP callbacks, per-call cancellation and timeouts, and
|
|
15
|
+
flavor-specific imports — with no bundled wallet library.
|
|
16
|
+
|
|
17
|
+
## Why this package
|
|
18
|
+
|
|
19
|
+
- **One source of truth.** Quote echoing, order-UID packing, app-data hashing,
|
|
20
|
+
and the EIP-712 / EIP-1271 signing path are the same Rust code a native
|
|
21
|
+
`cow-sdk` service runs, compiled to wasm — so protocol drift between a Rust
|
|
22
|
+
backend and a TypeScript frontend cannot happen. Every transform is proven
|
|
23
|
+
byte-for-byte against pinned upstream fixtures on each CI run.
|
|
24
|
+
- **No private key ever enters the SDK.** Signing is a callback you supply (viem,
|
|
25
|
+
ethers, an EIP-1193 wallet, or a Safe). There is no code path — not even a
|
|
26
|
+
feature-gated one — that accepts a private key or holds a wallet inside wasm
|
|
27
|
+
memory. The package produces typed data and transaction requests; your wallet
|
|
28
|
+
signs and submits.
|
|
29
|
+
- **The TypeScript surface is locked.** The public `.d.ts` for every flavor is a
|
|
30
|
+
committed snapshot that CI diffs on every build, so a contract change is a
|
|
31
|
+
reviewed diff, never a silent drift — the wasm analog of `cargo-public-api`.
|
|
32
|
+
- **Honest about fit.** For a standard browser dapp where minimal bundle size
|
|
33
|
+
dominates, upstream
|
|
34
|
+
[`@cowprotocol/cow-sdk`](https://www.npmjs.com/package/@cowprotocol/cow-sdk) is
|
|
35
|
+
smaller — use it. This package is for Rust ↔ TypeScript parity, single-source
|
|
36
|
+
embedding, edge runtimes, and embeddable signing.
|
|
37
|
+
|
|
38
|
+
## Pick your import
|
|
13
39
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
| You are building... | Choose | Why |
|
|
40
|
+
| Import | Surface | Use when |
|
|
17
41
|
| --- | --- | --- |
|
|
18
|
-
|
|
|
19
|
-
|
|
|
20
|
-
|
|
|
21
|
-
|
|
|
22
|
-
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
`no_std` embedded targets.
|
|
41
|
-
|
|
42
|
-
## Quickstart
|
|
43
|
-
|
|
44
|
-
### Node.js 22 or 24 with viem
|
|
42
|
+
| `@symbiome-forge/cow-sdk-wasm/trading` | Full order lifecycle: quote, sign, post, cancel, app-data | A browser dapp, a Node backend, or an edge runtime running order flow — one feature set serves all three; pick the runtime by import |
|
|
43
|
+
| `@symbiome-forge/cow-sdk-wasm/trading/edge` | The `trading` flavor's web-target build, with explicit wasm init | Cloudflare Workers, Deno, or Vercel Edge; pair with `…/trading/edge/wasm` for the module asset |
|
|
44
|
+
| `@symbiome-forge/cow-sdk-wasm/orderbook` | Orderbook reads, cancellation, and signing — no trading or app-data | A read-focused dapp that does not post orders |
|
|
45
|
+
| `@symbiome-forge/cow-sdk-wasm/signing` | Signing, UID, EIP-1271, deployment, and version helpers — the smallest flavor | A signer service or HSM-facing adapter |
|
|
46
|
+
| `@symbiome-forge/cow-sdk-wasm` | Everything above plus subgraph analytics and IPFS app-data | General use that needs subgraph or IPFS |
|
|
47
|
+
|
|
48
|
+
The `trading` flavor resolves the right target automatically through standard
|
|
49
|
+
conditional exports — `node` and `browser` for bundlers and Node, and `workerd` /
|
|
50
|
+
`deno` / `edge-light` / `bun` for edge — with `./trading/edge` as the explicit
|
|
51
|
+
Workers entry. Public imports go through these subpaths; do not import from
|
|
52
|
+
`dist/raw` or generated wasm-pack directories.
|
|
53
|
+
|
|
54
|
+
Building a **native Rust** service, or a Rust app you compile to wasm yourself?
|
|
55
|
+
Use [`cow-sdk`](https://crates.io/crates/cow-sdk) — this package is for
|
|
56
|
+
JavaScript hosts.
|
|
57
|
+
|
|
58
|
+
## Quickstart — a browser swap, end to end
|
|
59
|
+
|
|
60
|
+
Quote, then reuse that quote to sign and post in one call, so the amounts the user
|
|
61
|
+
confirms are the amounts that get posted — no second quote, no drift between
|
|
62
|
+
preview and signature. The wallet signs a typed-data envelope the SDK hands it;
|
|
63
|
+
no key reaches the package.
|
|
45
64
|
|
|
46
65
|
```ts
|
|
47
|
-
import { TradingClient } from "@symbiome-forge/cow-sdk-wasm";
|
|
66
|
+
import { TradingClient } from "@symbiome-forge/cow-sdk-wasm/trading";
|
|
67
|
+
import { createWalletClient, custom } from "viem";
|
|
68
|
+
import { mainnet } from "viem/chains";
|
|
69
|
+
|
|
70
|
+
const [owner] = await window.ethereum.request({ method: "eth_requestAccounts" });
|
|
71
|
+
const wallet = createWalletClient({ chain: mainnet, transport: custom(window.ethereum) });
|
|
48
72
|
|
|
49
73
|
const trading = new TradingClient({
|
|
50
74
|
chainId: 1,
|
|
51
75
|
env: "prod",
|
|
52
|
-
appCode: "my-
|
|
53
|
-
transport: { kind: "fetch" }
|
|
54
|
-
transportPolicy: {
|
|
55
|
-
retryPolicy: { maxAttempts: 3, baseDelayMs: 200 },
|
|
56
|
-
userAgent: "my-node-service/1.0"
|
|
57
|
-
}
|
|
76
|
+
appCode: "my-dapp",
|
|
77
|
+
transport: { kind: "fetch" }
|
|
58
78
|
});
|
|
59
79
|
|
|
60
|
-
// `getQuote` returns a fully resolved
|
|
80
|
+
// 1. Quote. `getQuote` returns a fully resolved QuoteResultsDto envelope.
|
|
81
|
+
// `owner` is required for a quote-only call.
|
|
61
82
|
const quote = await trading.getQuote({
|
|
62
83
|
kind: "sell",
|
|
63
|
-
|
|
64
|
-
|
|
84
|
+
owner,
|
|
85
|
+
sellToken: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", // WETH
|
|
86
|
+
buyToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
|
|
65
87
|
amount: "1000000000000000000"
|
|
66
88
|
});
|
|
67
89
|
|
|
68
|
-
// Reuse the quote to sign and post
|
|
69
|
-
//
|
|
90
|
+
// 2. Reuse the quote to sign and post. The callback receives the EIP-712
|
|
91
|
+
// envelope and returns the signature — the key stays in the wallet.
|
|
70
92
|
const result = await trading.postSwapOrderFromQuote(
|
|
71
93
|
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
94
|
owner,
|
|
108
|
-
(
|
|
109
|
-
|
|
95
|
+
(envelope) => {
|
|
96
|
+
// viem derives EIP712Domain from `domain`; drop it from `types`.
|
|
97
|
+
const types = Object.fromEntries(
|
|
98
|
+
Object.entries(envelope.types).filter(([name]) => name !== "EIP712Domain")
|
|
99
|
+
);
|
|
100
|
+
return wallet.signTypedData({
|
|
101
|
+
account: owner,
|
|
102
|
+
domain: envelope.domain,
|
|
103
|
+
types,
|
|
104
|
+
primaryType: envelope.primaryType,
|
|
105
|
+
message: envelope.message
|
|
106
|
+
});
|
|
107
|
+
},
|
|
108
|
+
{ walletConfig: { timeoutMs: 20_000 } }
|
|
110
109
|
);
|
|
111
|
-
// `signed.value` is the SignedOrderDto.
|
|
112
|
-
```
|
|
113
110
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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";
|
|
111
|
+
console.log(`https://explorer.cow.fi/mainnet/orders/${result.value.orderId}`);
|
|
112
|
+
trading.dispose();
|
|
113
|
+
```
|
|
124
114
|
|
|
125
|
-
|
|
115
|
+
Selling the native asset is the same shape: `getQuote`, then
|
|
116
|
+
`buildSellNativeCurrencyTxFromQuote(quote.value, owner)`, which returns the EthFlow
|
|
117
|
+
transaction request for the wallet to submit.
|
|
126
118
|
|
|
127
|
-
|
|
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
|
-
```
|
|
119
|
+
### Cloudflare Worker (edge)
|
|
138
120
|
|
|
139
|
-
|
|
121
|
+
Workers cannot compile wasm from bytes at runtime, so the edge build takes the
|
|
122
|
+
statically imported module through an explicit `initialize`.
|
|
140
123
|
|
|
141
124
|
```ts
|
|
142
|
-
import initialize, {
|
|
143
|
-
|
|
144
|
-
} from "@symbiome-forge/cow-sdk-wasm/cloudflare";
|
|
145
|
-
import wasmModule from "@symbiome-forge/cow-sdk-wasm/cloudflare/wasm";
|
|
125
|
+
import initialize, { OrderBookClient } from "@symbiome-forge/cow-sdk-wasm/trading/edge";
|
|
126
|
+
import wasmModule from "@symbiome-forge/cow-sdk-wasm/trading/edge/wasm";
|
|
146
127
|
|
|
147
128
|
export default {
|
|
148
129
|
async fetch(request: Request, env: Env): Promise<Response> {
|
|
149
130
|
await initialize(wasmModule);
|
|
150
|
-
|
|
151
131
|
const client = new OrderBookClient({
|
|
152
132
|
chainId: 1,
|
|
153
133
|
env: "prod",
|
|
154
134
|
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
|
|
135
|
+
transport: { kind: "fetch" }
|
|
161
136
|
});
|
|
137
|
+
const quote = await client.getQuote(await request.json(), { timeoutMs: 8_000 });
|
|
162
138
|
client.dispose();
|
|
163
|
-
|
|
164
139
|
return Response.json(quote);
|
|
165
140
|
}
|
|
166
141
|
};
|
|
167
142
|
```
|
|
168
143
|
|
|
169
|
-
|
|
144
|
+
### Lower-level signing
|
|
170
145
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
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 |
|
|
146
|
+
For control over an order you build yourself, sign through an EIP-1193 wallet with
|
|
147
|
+
`signOrderWithEip1193(order, chainId, owner, (rpc) => ethereum.request(rpc))`, or
|
|
148
|
+
hand a typed-data method directly to `signOrderWithTypedDataSigner`. Both return a
|
|
149
|
+
`SignedOrderDto` you submit with `OrderBookClient.sendOrder`.
|
|
178
150
|
|
|
179
|
-
|
|
180
|
-
wasm-bindgen output is package-internal; public imports go through the facade
|
|
181
|
-
subpaths above.
|
|
151
|
+
## The callback boundary
|
|
182
152
|
|
|
183
|
-
|
|
153
|
+
The package names host responsibilities as typed callbacks and never reaches past
|
|
154
|
+
them for a key or a provider:
|
|
184
155
|
|
|
185
|
-
|
|
186
|
-
|
|
156
|
+
- `TypedDataSignerCallback` — signs an EIP-712 typed-data envelope.
|
|
157
|
+
- `Eip1193RequestCallback` — answers EIP-1193 requests from an injected or hosted
|
|
158
|
+
provider.
|
|
159
|
+
- `DigestSignerCallback` — signs a raw digest for explicit EthSign flows.
|
|
160
|
+
- `CustomEip1271Callback` — returns a smart-account's final EIP-1271 signature.
|
|
161
|
+
- `ContractReadCallback` — performs a read-only `eth_call` and returns the
|
|
162
|
+
ABI-decoded value as a decimal string or number (e.g. viem's `readContract`
|
|
163
|
+
result via `String(value)`).
|
|
164
|
+
- `CowFetchCallback` — dispatches HTTP for Node, Workers, Deno, and custom hosts.
|
|
187
165
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
| orderbook | 1.03 MiB | 341 KiB | 447 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.54 MiB | 489 KiB | 657 KiB | 3.2 MiB raw / 850 KiB brotli / 3,000,000 B gzip (warn at 2,700,000 B) |
|
|
166
|
+
A callback may return a plain value, a Promise, or a thenable. Clients expose
|
|
167
|
+
`dispose()` and `[Symbol.dispose]` (so `using client = new …` works) and release
|
|
168
|
+
the callbacks they hold on disposal.
|
|
194
169
|
|
|
195
|
-
|
|
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.
|
|
170
|
+
## Cancellation and timeouts
|
|
201
171
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
172
|
+
Every call accepts an optional `signal` (an `AbortSignal`) and `timeoutMs`.
|
|
173
|
+
Aborting the signal rejects the pending call with a `cancelled` `CowError`;
|
|
174
|
+
`timeoutMs` rejects with a `timeout` error. Both resolve the *awaited call* — an
|
|
175
|
+
already-dispatched HTTP request may keep running in the background until it
|
|
176
|
+
completes or the timeout elapses, so treat cancellation as "stop waiting," not a
|
|
177
|
+
guarantee that the network request is halted.
|
|
205
178
|
|
|
206
|
-
## Transport
|
|
179
|
+
## Transport
|
|
207
180
|
|
|
208
|
-
Every client
|
|
181
|
+
Every client takes one transport:
|
|
209
182
|
|
|
210
183
|
```ts
|
|
211
|
-
transport: { kind: "fetch" }
|
|
212
|
-
transport: { kind: "fetch", fetch: customFetch }
|
|
213
|
-
transport: { kind: "callback", callback
|
|
184
|
+
transport: { kind: "fetch" } // standards `fetch` (browser, Node, Workers)
|
|
185
|
+
transport: { kind: "fetch", fetch: customFetch } // a fetch you supply
|
|
186
|
+
transport: { kind: "callback", callback } // you own request dispatch
|
|
214
187
|
```
|
|
215
188
|
|
|
216
|
-
Use `
|
|
217
|
-
|
|
218
|
-
|
|
189
|
+
Use `callback` when the host must own dispatch for fixtures, proxying, custom
|
|
190
|
+
authentication, or observability. Each client also takes optional
|
|
191
|
+
`transportPolicy` settings for retry, rate-limit, jitter, and user-agent behavior.
|
|
219
192
|
|
|
220
|
-
|
|
221
|
-
rate-limit, jitter, and user-agent behavior.
|
|
193
|
+
## Errors
|
|
222
194
|
|
|
223
|
-
|
|
195
|
+
JavaScript-visible failures are a typed `CowError` discriminated union — transport,
|
|
196
|
+
app-data, signing, orderbook, subgraph, trading, wallet, cancellation, and
|
|
197
|
+
internal variants — with low-cardinality fields visible and URLs, headers, bodies,
|
|
198
|
+
and secret-shaped values redacted. The `orderbook` variant carries `retryable` and
|
|
199
|
+
an optional `retryAfterMs` parsed from the response `Retry-After`, mirroring the
|
|
200
|
+
native `OrderbookError::is_retryable` / `backoff_hint`, so a JavaScript retry loop
|
|
201
|
+
reaches the same verdict as the Rust one.
|
|
202
|
+
|
|
203
|
+
## Bundle size
|
|
224
204
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
-
|
|
237
|
-
-
|
|
238
|
-
|
|
239
|
-
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
`
|
|
259
|
-
|
|
260
|
-
|
|
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; the `cloudflare` flavor
|
|
273
|
-
is built and tested end-to-end in CI (Workers Vitest), within the Workers
|
|
274
|
-
compressed-size budget).
|
|
275
|
-
- Embeddable signing helpers (the `./signing` flavor is the smallest).
|
|
276
|
-
|
|
277
|
-
The "When to use this SDK" table at the top of this README routes consumers
|
|
278
|
-
by use case. The Quickstart sections above show the supported import shapes
|
|
279
|
-
for the most common runtimes.
|
|
205
|
+
Built with release-size settings and a `wasm-opt -Oz` pass; measured on the
|
|
206
|
+
current alpha build (gzip is the compressed-transfer figure):
|
|
207
|
+
|
|
208
|
+
| Flavor | Raw wasm | Brotli | Gzip | Release gate |
|
|
209
|
+
| --- | ---: | ---: | ---: | --- |
|
|
210
|
+
| signing | 0.31 MiB | 120 KiB | 142 KiB | 0.9 MiB raw / 300 KiB brotli |
|
|
211
|
+
| orderbook | 1.02 MiB | 341 KiB | 447 KiB | 1.5 MiB raw / 500 KiB brotli |
|
|
212
|
+
| trading | 1.54 MiB | 490 KiB | 659 KiB | 3.2 MiB raw / 850 KiB brotli |
|
|
213
|
+
| default | 1.63 MiB | 513 KiB | 692 KiB | 3.3 MiB raw / 900 KiB brotli |
|
|
214
|
+
|
|
215
|
+
The `trading` flavor emits one wasm binary across its bundler, Node, and web
|
|
216
|
+
targets; its web-target gzip size is within the current Cloudflare Workers Free
|
|
217
|
+
compressed-size limit, enforced as a byte budget on every build. End-to-end
|
|
218
|
+
Workers support also depends on `wrangler deploy --dry-run` verification and a
|
|
219
|
+
Worker startup-time gate, tracked separately.
|
|
220
|
+
|
|
221
|
+
## Not in this package
|
|
222
|
+
|
|
223
|
+
Use the upstream TypeScript SDK for these until they ship in `cow-rs`: TWAP and
|
|
224
|
+
composable orders, cross-chain bridging, CoW Shed account abstraction, flash-loan
|
|
225
|
+
helpers, and hardware-wallet adapters. This package emits typed data or
|
|
226
|
+
transaction requests and lets the caller's wallet submit on-chain; it ships no
|
|
227
|
+
WASI, WebAssembly-component, or `no_std` guest target.
|
|
228
|
+
|
|
229
|
+
## More
|
|
230
|
+
|
|
231
|
+
- The public TypeScript surface for each flavor is the committed declaration
|
|
232
|
+
snapshot under `crates/wasm/snapshots/facade/`.
|
|
233
|
+
- [Architecture](https://github.com/0xSymbiome/cow-rs/blob/main/docs/architecture.md),
|
|
234
|
+
[Observability](https://github.com/0xSymbiome/cow-rs/blob/main/docs/observability.md),
|
|
235
|
+
and the
|
|
236
|
+
[WASM Surface Audit](https://github.com/0xSymbiome/cow-rs/blob/main/docs/audit/wasm-surface-audit.md).
|
|
237
|
+
- Runnable browser, Node, and Worker examples live in the
|
|
238
|
+
[`cow-sdk-examples`](https://github.com/0xSymbiome/cow-sdk-examples) repository.
|
|
239
|
+
|
|
240
|
+
Licensed under GPL-3.0-or-later.
|
|
@@ -52,4 +52,22 @@ export type Eip1193RequestCallback = (request: {
|
|
|
52
52
|
export type DigestSignerCallback = (digest: string) => Promise<string> | string;
|
|
53
53
|
export type CowEip1271SignCallback = (request: CowEip1271SignRequest) => Promise<string> | string;
|
|
54
54
|
export type CustomEip1271Callback = CowEip1271SignCallback;
|
|
55
|
+
/**
|
|
56
|
+
* Performs a read-only contract call on behalf of the SDK and returns the
|
|
57
|
+
* ABI-decoded result.
|
|
58
|
+
*
|
|
59
|
+
* The callback must return the decoded value as a decimal string or number, not
|
|
60
|
+
* the raw `0x`-hex `eth_call` payload. With viem, pass the `readContract`
|
|
61
|
+
* result through `String(value)`:
|
|
62
|
+
*
|
|
63
|
+
* ```ts
|
|
64
|
+
* const readContract: ContractReadCallback = async ({ address, method, abiJson, argsJson }) =>
|
|
65
|
+
* String(await publicClient.readContract({
|
|
66
|
+
* address: address as `0x${string}`,
|
|
67
|
+
* abi: JSON.parse(abiJson),
|
|
68
|
+
* functionName: method,
|
|
69
|
+
* args: JSON.parse(argsJson)
|
|
70
|
+
* }));
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
55
73
|
export type ContractReadCallback = (request: ContractCallDto) => Promise<string> | string;
|
package/dist/default/index.cjs
CHANGED
|
@@ -247,6 +247,9 @@ class TradingClient {
|
|
|
247
247
|
async buildSellNativeCurrencyTx(order, quoteId, from, options) {
|
|
248
248
|
return this.#call((client, merged) => client.buildSellNativeCurrencyTx(order, quoteId, from, merged), options);
|
|
249
249
|
}
|
|
250
|
+
async buildSellNativeCurrencyTxFromQuote(quoteResults, from, options) {
|
|
251
|
+
return this.#call((client, merged) => client.buildSellNativeCurrencyTxFromQuote(quoteResults, from, merged), options);
|
|
252
|
+
}
|
|
250
253
|
async getCowProtocolAllowance(params, readContractCallback, options) {
|
|
251
254
|
return this.#call((client, merged) => client.getCowProtocolAllowance(params, readContractCallback, merged), options);
|
|
252
255
|
}
|
package/dist/default/index.d.ts
CHANGED
|
@@ -55,6 +55,7 @@ export declare class TradingClient {
|
|
|
55
55
|
#private;
|
|
56
56
|
constructor(config: TradingClientConfig);
|
|
57
57
|
buildSellNativeCurrencyTx(order: raw.OrderInput, quoteId: number, from: string, options?: SdkClientOptions | null): Promise<WasmEnvelope<raw.BuiltSellNativeCurrencyTxDto>>;
|
|
58
|
+
buildSellNativeCurrencyTxFromQuote(quoteResults: raw.QuoteResultsDto, from: string, options?: SdkClientOptions | null): Promise<WasmEnvelope<raw.BuiltSellNativeCurrencyTxDto>>;
|
|
58
59
|
getCowProtocolAllowance(params: raw.AllowanceParametersInput, readContractCallback: ContractReadCallback, options?: SdkClientOptions | null): Promise<WasmEnvelope<string>>;
|
|
59
60
|
buildApprovalTx(params: raw.ApprovalParametersInput, options?: SdkClientOptions | null): Promise<WasmEnvelope<raw.TransactionRequestDto>>;
|
|
60
61
|
getQuote(params: raw.SwapParametersInput, options?: SdkClientOptions | null): Promise<WasmEnvelope<raw.QuoteResultsDto>>;
|
package/dist/default/index.mjs
CHANGED
|
@@ -184,6 +184,9 @@ export class TradingClient {
|
|
|
184
184
|
async buildSellNativeCurrencyTx(order, quoteId, from, options) {
|
|
185
185
|
return this.#call((client, merged) => client.buildSellNativeCurrencyTx(order, quoteId, from, merged), options);
|
|
186
186
|
}
|
|
187
|
+
async buildSellNativeCurrencyTxFromQuote(quoteResults, from, options) {
|
|
188
|
+
return this.#call((client, merged) => client.buildSellNativeCurrencyTxFromQuote(quoteResults, from, merged), options);
|
|
189
|
+
}
|
|
187
190
|
async getCowProtocolAllowance(params, readContractCallback, options) {
|
|
188
191
|
return this.#call((client, merged) => client.getCowProtocolAllowance(params, readContractCallback, merged), options);
|
|
189
192
|
}
|
|
@@ -16,8 +16,9 @@ function translateHttpTransport(transport) {
|
|
|
16
16
|
return transport;
|
|
17
17
|
}
|
|
18
18
|
// An omitted transport (or `{ kind: "fetch" }` without an explicit fetch)
|
|
19
|
-
// defaults to the runtime's global `fetch
|
|
20
|
-
//
|
|
19
|
+
// defaults to the runtime's global `fetch`. This default is a facade
|
|
20
|
+
// affordance: the raw wasm layer has no transport default and requires an
|
|
21
|
+
// explicit callback transport, so the facade injects `globalThis.fetch` here.
|
|
21
22
|
const fetchFn = transport?.fetch ?? globalThis.fetch;
|
|
22
23
|
if (typeof fetchFn !== "function") {
|
|
23
24
|
throw (0, errors_js_1.invalidInput)("transport.fetch", "globalThis.fetch is unavailable; pass an explicit fetch function");
|
package/dist/default/internal.js
CHANGED
|
@@ -4,8 +4,9 @@ export function translateHttpTransport(transport) {
|
|
|
4
4
|
return transport;
|
|
5
5
|
}
|
|
6
6
|
// An omitted transport (or `{ kind: "fetch" }` without an explicit fetch)
|
|
7
|
-
// defaults to the runtime's global `fetch
|
|
8
|
-
//
|
|
7
|
+
// defaults to the runtime's global `fetch`. This default is a facade
|
|
8
|
+
// affordance: the raw wasm layer has no transport default and requires an
|
|
9
|
+
// explicit callback transport, so the facade injects `globalThis.fetch` here.
|
|
9
10
|
const fetchFn = transport?.fetch ?? globalThis.fetch;
|
|
10
11
|
if (typeof fetchFn !== "function") {
|
|
11
12
|
throw invalidInput("transport.fetch", "globalThis.fetch is unavailable; pass an explicit fetch function");
|
|
@@ -34,7 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.wasmVersion = exports.validateAppDataDoc = exports.supportedChainIds = exports.signOrderWithTypedDataSigner = exports.signOrderWithEip1271 = exports.signOrderWithEip1193 = exports.signOrderWithCustomEip1271 = exports.signOrderEthSignDigest = exports.signCancellationWithTypedDataSigner = exports.signCancellationWithEip1193 = exports.signCancellationEthSignDigest = exports.orderTypedData = exports.eip1271SignaturePayload = exports.domainSeparator = exports.deploymentAddresses = exports.decodeSettlementLog = exports.decodeEthFlowLog = exports.computeOrderUid = exports.cidToAppDataHex = exports.buildPresignTx = exports.buildCancelOrderTx = exports.appDataInfo = exports.appDataHexToCid = exports.appDataDoc = exports.__cow_sdk_wasm_init = exports.RawTradingClient = exports.RawOrderBookClient = exports.initializeRaw = void 0;
|
|
37
|
-
const cow_sdk_wasm_js_1 = __importStar(require("../../raw/
|
|
37
|
+
const cow_sdk_wasm_js_1 = __importStar(require("../../raw/trading-web/cow_sdk_wasm.cjs")), wasm = cow_sdk_wasm_js_1;
|
|
38
38
|
exports.initializeRaw = cow_sdk_wasm_js_1.default;
|
|
39
39
|
exports.RawOrderBookClient = wasm.OrderBookClient;
|
|
40
40
|
exports.RawTradingClient = wasm.TradingClient;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import init, * as wasm from "../../raw/
|
|
2
|
-
export type * from "../../raw/
|
|
1
|
+
import init, * as wasm from "../../raw/trading-web/cow_sdk_wasm.js";
|
|
2
|
+
export type * from "../../raw/trading-web/cow_sdk_wasm.js";
|
|
3
3
|
export declare const initializeRaw: typeof init;
|
|
4
4
|
export declare const RawOrderBookClient: typeof wasm.OrderBookClient;
|
|
5
5
|
export declare const RawTradingClient: typeof wasm.TradingClient;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import init, * as wasm from "../../raw/
|
|
1
|
+
import init, * as wasm from "../../raw/trading-web/cow_sdk_wasm.js";
|
|
2
2
|
export const initializeRaw = init;
|
|
3
3
|
export const RawOrderBookClient = wasm.OrderBookClient;
|
|
4
4
|
export const RawTradingClient = wasm.TradingClient;
|
|
@@ -52,4 +52,22 @@ export type Eip1193RequestCallback = (request: {
|
|
|
52
52
|
export type DigestSignerCallback = (digest: string) => Promise<string> | string;
|
|
53
53
|
export type CowEip1271SignCallback = (request: CowEip1271SignRequest) => Promise<string> | string;
|
|
54
54
|
export type CustomEip1271Callback = CowEip1271SignCallback;
|
|
55
|
+
/**
|
|
56
|
+
* Performs a read-only contract call on behalf of the SDK and returns the
|
|
57
|
+
* ABI-decoded result.
|
|
58
|
+
*
|
|
59
|
+
* The callback must return the decoded value as a decimal string or number, not
|
|
60
|
+
* the raw `0x`-hex `eth_call` payload. With viem, pass the `readContract`
|
|
61
|
+
* result through `String(value)`:
|
|
62
|
+
*
|
|
63
|
+
* ```ts
|
|
64
|
+
* const readContract: ContractReadCallback = async ({ address, method, abiJson, argsJson }) =>
|
|
65
|
+
* String(await publicClient.readContract({
|
|
66
|
+
* address: address as `0x${string}`,
|
|
67
|
+
* abi: JSON.parse(abiJson),
|
|
68
|
+
* functionName: method,
|
|
69
|
+
* args: JSON.parse(argsJson)
|
|
70
|
+
* }));
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
55
73
|
export type ContractReadCallback = (request: ContractCallDto) => Promise<string> | string;
|
|
@@ -16,8 +16,9 @@ function translateHttpTransport(transport) {
|
|
|
16
16
|
return transport;
|
|
17
17
|
}
|
|
18
18
|
// An omitted transport (or `{ kind: "fetch" }` without an explicit fetch)
|
|
19
|
-
// defaults to the runtime's global `fetch
|
|
20
|
-
//
|
|
19
|
+
// defaults to the runtime's global `fetch`. This default is a facade
|
|
20
|
+
// affordance: the raw wasm layer has no transport default and requires an
|
|
21
|
+
// explicit callback transport, so the facade injects `globalThis.fetch` here.
|
|
21
22
|
const fetchFn = transport?.fetch ?? globalThis.fetch;
|
|
22
23
|
if (typeof fetchFn !== "function") {
|
|
23
24
|
throw (0, errors_js_1.invalidInput)("transport.fetch", "globalThis.fetch is unavailable; pass an explicit fetch function");
|
|
@@ -4,8 +4,9 @@ export function translateHttpTransport(transport) {
|
|
|
4
4
|
return transport;
|
|
5
5
|
}
|
|
6
6
|
// An omitted transport (or `{ kind: "fetch" }` without an explicit fetch)
|
|
7
|
-
// defaults to the runtime's global `fetch
|
|
8
|
-
//
|
|
7
|
+
// defaults to the runtime's global `fetch`. This default is a facade
|
|
8
|
+
// affordance: the raw wasm layer has no transport default and requires an
|
|
9
|
+
// explicit callback transport, so the facade injects `globalThis.fetch` here.
|
|
9
10
|
const fetchFn = transport?.fetch ?? globalThis.fetch;
|
|
10
11
|
if (typeof fetchFn !== "function") {
|
|
11
12
|
throw invalidInput("transport.fetch", "globalThis.fetch is unavailable; pass an explicit fetch function");
|