@cowprotocol/cow-sdk 0.0.15 → 1.0.0-RC.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 +247 -103
- package/dist/CowSdk.d.ts +4 -0
- package/dist/api/0x/error/index.d.ts +21 -0
- package/dist/api/0x/index.d.ts +11 -0
- package/dist/api/0x/utils.d.ts +17 -0
- package/dist/api/base/index.d.ts +25 -0
- package/dist/api/cow/index.d.ts +4 -16
- package/dist/api/cow/types.d.ts +4 -1
- package/dist/api/cow-subgraph/graphql.d.ts +24 -2
- package/dist/api/metadata/index.d.ts +11 -5
- package/dist/api/metadata/types.d.ts +8 -21
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/index.modern.js +4 -4
- package/dist/index.modern.js.map +1 -1
- package/dist/index.module.js +4 -4
- package/dist/index.module.js.map +1 -1
- package/dist/utils/appData.d.ts +3 -3
- package/dist/utils/context.d.ts +5 -9
- package/dist/utils/ipfs.d.ts +2 -2
- package/dist/utils/market.d.ts +16 -0
- package/package.json +2 -1
- package/dist/appData.schema-42d10730.js +0 -2
- package/dist/appData.schema-42d10730.js.map +0 -1
- package/dist/appData.schema-b8f018d7.js +0 -2
- package/dist/appData.schema-b8f018d7.js.map +0 -1
package/README.md
CHANGED
|
@@ -2,16 +2,12 @@
|
|
|
2
2
|
<img width="400" src="https://raw.githubusercontent.com/cowprotocol/cow-sdk/main/docs/images/CoW.png">
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
|
-
# CoW
|
|
5
|
+
# CoW SDK
|
|
6
6
|
|
|
7
7
|
[](https://prettier.io/)
|
|
8
8
|
[](https://coveralls.io/github/cowprotocol/cow-sdk?branch=main)
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
> It is being currently develop and is a work in progress, also it's API is subjected to change.
|
|
12
|
-
> If you experience any problems, please open an issue in Github trying to describe your problem.
|
|
13
|
-
|
|
14
|
-
### Getting started
|
|
10
|
+
## Getting started
|
|
15
11
|
|
|
16
12
|
Install the SDK:
|
|
17
13
|
|
|
@@ -22,14 +18,29 @@ yarn add @cowprotocol/cow-sdk
|
|
|
22
18
|
Instantiate the SDK:
|
|
23
19
|
|
|
24
20
|
```js
|
|
25
|
-
import { CowSdk } from 'cow-sdk'
|
|
21
|
+
import { CowSdk } from '@cowprotocol/cow-sdk'
|
|
26
22
|
|
|
27
23
|
const chainId = 4 // Rinkeby
|
|
28
24
|
const cowSdk = new CowSdk(chainId)
|
|
29
25
|
```
|
|
30
26
|
|
|
31
|
-
The SDK will expose
|
|
27
|
+
The SDK will expose:
|
|
28
|
+
* The CoW API (`cowSdk.cowApi`)
|
|
29
|
+
* The CoW Subgraph (`cowSdk.cowSubgraphApi`)
|
|
30
|
+
* Convenient method to facilitate signing orders (i.e `cowSdk.signOrder`)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
> For a quick snippet with the full process on posting an order see the [Post an Order Example](./docs/post-order-example.ts)
|
|
34
|
+
|
|
32
35
|
|
|
36
|
+
## CoW API
|
|
37
|
+
The SDK provides access to the CoW API. The CoW API allows you:
|
|
38
|
+
- Post orders
|
|
39
|
+
- Get fee quotes
|
|
40
|
+
- Get order details
|
|
41
|
+
- Get history of orders: i.e. filtering by account, transaction hash, etc.
|
|
42
|
+
|
|
43
|
+
For example, you can easily get the last 5 order of a trader:
|
|
33
44
|
```js
|
|
34
45
|
// i.e. Get last 5 orders for a given trader
|
|
35
46
|
const trades = await cowSdk.cowApi.getOrders({
|
|
@@ -40,29 +51,62 @@ const trades = await cowSdk.cowApi.getOrders({
|
|
|
40
51
|
console.log(trades)
|
|
41
52
|
```
|
|
42
53
|
|
|
43
|
-
|
|
54
|
+
> For more information about the API methods, you can check [api.cow.fi/docs](https://api.cow.fi/docs).
|
|
44
55
|
|
|
45
|
-
|
|
46
|
-
|
|
56
|
+
## Sign and Post orders
|
|
57
|
+
In order to trade, you will need to create a valid order first.
|
|
58
|
+
|
|
59
|
+
On the contraty to other decentralised exchanges, creating orders is free in CoW Protocol. This is because, one of the
|
|
60
|
+
most common ways to do it is by created offchain signed messages (meta-transactions, uses `EIP-712` or `EIP-1271`).
|
|
47
61
|
|
|
48
|
-
|
|
62
|
+
Posting orders is a three steps process:
|
|
63
|
+
|
|
64
|
+
- 1. **Get Market Pricea**: Fee & Price
|
|
65
|
+
- 2. **Sign the order**: Using off-chain signing or Meta-transactions
|
|
66
|
+
- 3. **Post the signed order to the API**: So, the order becomes `OPEN`
|
|
67
|
+
|
|
68
|
+
The next sections will guide you through the process of creating a valid order.
|
|
69
|
+
|
|
70
|
+
> For a quick snippet with the full process on posting an order see the [Post an Order Example](./docs/post-order-example.ts).
|
|
71
|
+
|
|
72
|
+
### Enable tokens (token approval)
|
|
73
|
+
Because of the use of off-chain signing (meta-transactions), users will need to **Enable the sell token** before signed
|
|
74
|
+
orders can be considered as valid ones.
|
|
75
|
+
|
|
76
|
+
This enabling is technically an `ERC-20` approval, and is something that needs to be done only once. After this all
|
|
77
|
+
order creation can be done for free using offchain signing.
|
|
78
|
+
|
|
79
|
+
> For more details see https://docs.cow.fi/tutorials/how-to-submit-orders-via-the-api/1.-set-allowance-for-the-sell-token
|
|
49
80
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
- 3. **Sign the order using your wallet**: Only signed orders are considered by the protocol.
|
|
53
|
-
- 4. **Post the signed order to the API**: Post the order so it can be executed.
|
|
81
|
+
### Instantiate SDK with a signer
|
|
82
|
+
Before you can sign any transaction, you have to instantiate the SDK with a [Ethers.JS signer](https://docs.ethers.io/v5/api/signer/):
|
|
54
83
|
|
|
55
84
|
```js
|
|
56
85
|
import { Wallet } from 'ethers'
|
|
57
|
-
import { CowSdk, OrderKind } from 'cow-sdk'
|
|
86
|
+
import { CowSdk, OrderKind } from '@cowprotocol/cow-sdk'
|
|
58
87
|
|
|
59
|
-
// 1. Instantiate wallet and SDK
|
|
60
88
|
const mnemonic = 'fall dirt bread cactus...'
|
|
61
89
|
const wallet = Wallet.fromMnemonic(mnemonic)
|
|
62
|
-
const cowSdk = new CowSdk(
|
|
90
|
+
const cowSdk = new CowSdk(
|
|
91
|
+
4, { // Leaving chainId empty will default to MAINNET
|
|
92
|
+
signer: wallet // Provide a signer, so you can sign order
|
|
93
|
+
})
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### STEP 1: Get Market Price
|
|
97
|
+
To create an order, you need to get a price/fee quote first:
|
|
98
|
+
|
|
99
|
+
* The SDK will give you easy access to the API, which returns the `Market Price` and the `Fee` for any given trade you intent to do.
|
|
100
|
+
* The returned `Market Price` is not strictly needed, you can use your own pricing logic.
|
|
101
|
+
* You can choose a price that is below this Market price (**Market Order**), or above Market Price (**Limit Order**).
|
|
102
|
+
* The `Fee` however is very important.
|
|
103
|
+
* It is the required amount in sell token the trader agrees on paying for executing the order onchain.
|
|
104
|
+
* Normally, its value is proportional to the current Gas Price of the network.
|
|
105
|
+
* This fee is never charged if you don't trade.
|
|
106
|
+
|
|
107
|
+
To get the quote, you simply specify the trade you intent to do:
|
|
63
108
|
|
|
64
|
-
|
|
65
|
-
// It will return the price and fee to "Sell 1 ETH for USDC"
|
|
109
|
+
```js
|
|
66
110
|
const quoteResponse = await cowSdk.cowApi.getQuote({
|
|
67
111
|
kind: OrderKind.SELL, // Sell order (could also be BUY)
|
|
68
112
|
sellToken: '0xc778417e063141139fce010982780140aa0cd5ab', // WETH
|
|
@@ -73,122 +117,222 @@ const quoteResponse = await cowSdk.cowApi.getQuote({
|
|
|
73
117
|
})
|
|
74
118
|
|
|
75
119
|
const { sellToken, buyToken, validTo, buyAmount, sellAmount, receiver, feeAmount } = quoteResponse.quote
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### STEP 2: Sign the order
|
|
123
|
+
Once you know the price and fee, we can create the order and sign it:
|
|
124
|
+
|
|
125
|
+
* Technically the order is just a signed message with your intent to trade, and contains your `Limit Price` and `Fee`.
|
|
126
|
+
* As explained before, you can choose your `Limit Price`, but some general approach is to take the current Market Price
|
|
127
|
+
and apply some slippage tolerance to it. `Received Amount = Expected Amount * (1 - Slippage Tolerance)`
|
|
128
|
+
* The SDK will provide an easy way to sign orders given the raw data
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
```js
|
|
132
|
+
const { sellToken, buyToken, validTo, buyAmount, sellAmount, receiver, feeAmount } = quoteResponse.quote
|
|
133
|
+
|
|
134
|
+
// Prepare the RAW order
|
|
76
135
|
const order = {
|
|
77
|
-
kind: OrderKind.SELL,
|
|
78
|
-
|
|
136
|
+
kind: OrderKind.SELL, // SELL || BUY
|
|
137
|
+
receiver, // Your account or any other
|
|
79
138
|
sellToken,
|
|
80
139
|
buyToken,
|
|
140
|
+
|
|
141
|
+
partiallyFillable: false, // ("false" is for a "Fill or Kill" order, "true" for allowing "Partial execution" which is not supported yet)
|
|
142
|
+
|
|
143
|
+
// Deadline
|
|
81
144
|
validTo,
|
|
82
|
-
|
|
145
|
+
|
|
146
|
+
// Limit Price
|
|
147
|
+
// You can apply some slippage tolerance here to make sure the trade is executed.
|
|
148
|
+
// CoW protocol protects from MEV, so it can work with higher slippages
|
|
83
149
|
sellAmount,
|
|
84
|
-
|
|
150
|
+
buyAmount,
|
|
151
|
+
|
|
152
|
+
// Use the fee you received from the API
|
|
85
153
|
feeAmount,
|
|
154
|
+
|
|
155
|
+
// The appData allows you to attach arbitrary information (meta-data) to the order. Its explained in their own section. For now, you can use this 0x0 value
|
|
156
|
+
appData: '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
86
157
|
}
|
|
87
158
|
|
|
88
|
-
//
|
|
159
|
+
// Sign the order
|
|
89
160
|
const signedOrder = await cowSdk.signOrder(order)
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
At this point, you have a signed order. So next step will be to post it to the API so it's considered by the solvers and executed.
|
|
90
164
|
|
|
91
|
-
|
|
165
|
+
|
|
166
|
+
## STEP 3: **Post the signed order to the API**:
|
|
167
|
+
Once you have a signed order, last step is to send it to the API.
|
|
168
|
+
* The API will accept the order if its correctly signed, the deadline is correct, and the fee is enough to settle it
|
|
169
|
+
* Once accepted, the order will be `OPEN` until the specified `validTo` date (expiration)
|
|
170
|
+
* The possible outcomes once accepted is:
|
|
171
|
+
* The order is `EXECUTED`: you will pay the signed fee, and get at least the `buyAmount` tokens you specified, although you will probably get more! (you will probably get a so-called **Surplus**).
|
|
172
|
+
* The order `EXPIRES`: If your price is not good enough, and the order is out of the market price before
|
|
173
|
+
expiration, your order will expire. This doesn't have any cost to the user, which **only pays the fee if the trade is executed**.
|
|
174
|
+
* You cancel the order, so it becomes `CANCELLED`. Cancelling an order can be done both as a free meta-transaction
|
|
175
|
+
(**soft cancelations**) or as a regular on-chain transaction (**hard cancelations**).
|
|
176
|
+
* The API will return an `orderId` which identifies the order, and is created as a summary (hash) of it. In other words, the `orderId` is deterministic given all the order parameters.
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
Post an order using the SDK:
|
|
180
|
+
|
|
181
|
+
```js
|
|
92
182
|
const orderId = await cowSdk.cowApi.sendOrder({
|
|
93
183
|
order: { ...order, ...signedOrder },
|
|
94
184
|
owner: '0x1811be0994930fe9480eaede25165608b093ad7a',
|
|
95
185
|
})
|
|
186
|
+
```
|
|
187
|
+
|
|
96
188
|
|
|
97
|
-
|
|
189
|
+
### BONUS: Show link to Explorer
|
|
190
|
+
Once the order is posted, its good to allow to check the state of it.
|
|
191
|
+
|
|
192
|
+
One easy is to check in the CoW Explorer. You can create a CoW Explorer link if you have the `orderId`:
|
|
193
|
+
|
|
194
|
+
```js
|
|
195
|
+
// View order in explorer
|
|
98
196
|
console.log(`https://explorer.cow.fi/rinkeby/orders/${orderId}`)
|
|
197
|
+
```
|
|
99
198
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
199
|
+
|
|
200
|
+
## Create a meta-data document for attaching to an order
|
|
201
|
+
Orders in CoW Protocol can contain arbitrary data in a field called `AppData`.
|
|
202
|
+
|
|
203
|
+
The SDK facilitates the creation of these documents, and getting the `AppData` Hex number that summarizes it.
|
|
204
|
+
|
|
205
|
+
The most important thing to define in the meta-data is the name of your app, so the order-flow can be credited to it.
|
|
206
|
+
|
|
207
|
+
```js
|
|
208
|
+
const appDataDoc = cowSdk.metadataApi.generateAppDataDoc({
|
|
209
|
+
appDataParams: { appCode: "YourApp" }
|
|
210
|
+
})
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
This will create a document similar to:
|
|
214
|
+
```json
|
|
215
|
+
{
|
|
216
|
+
"version": "0.4.0",
|
|
217
|
+
"appCode": "YourApp",
|
|
218
|
+
"metadata": {}
|
|
219
|
+
}
|
|
108
220
|
```
|
|
109
221
|
|
|
110
|
-
|
|
222
|
+
After creating the most basic document, you can see how to attach additional meta-data items.
|
|
223
|
+
|
|
224
|
+
For example, you could give information about who referred the user creating the order.
|
|
111
225
|
|
|
112
226
|
```js
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
227
|
+
const appDataDoc = cowSdk.metadataApi.generateAppDataDoc({
|
|
228
|
+
appDataParams: { appCode: "YourApp" },
|
|
229
|
+
metadataParas: {
|
|
230
|
+
referrerParams: {
|
|
231
|
+
address: '0x1f5B740436Fc5935622e92aa3b46818906F416E9'
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
})
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
This will create a document similar to:
|
|
238
|
+
|
|
239
|
+
```json
|
|
240
|
+
{
|
|
241
|
+
"version": "0.4.0",
|
|
242
|
+
"appCode": "YourApp",
|
|
243
|
+
"metadata": {
|
|
244
|
+
"referrer": {
|
|
245
|
+
"address": "0x1f5B740436Fc5935622e92aa3b46818906F416E9",
|
|
128
246
|
"version": "0.1.0"
|
|
129
|
-
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
```
|
|
130
251
|
|
|
131
|
-
|
|
252
|
+
The method `cowSdk.metadataApi.generateAppDataDoc` will always create the latest schema version.
|
|
132
253
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
254
|
+
For a complete list of metadata that can be attached and for previous versions
|
|
255
|
+
check `@cowprotocol/app-data` [repository](https://github.com/cowprotocol/app-data)
|
|
256
|
+
and [NPM package](https://www.npmjs.com/package/@cowprotocol/app-data)
|
|
136
257
|
|
|
137
|
-
|
|
258
|
+
## Get the AppData Hex
|
|
259
|
+
The `AppData` Hex points to an IPFS document with the meta-data attached to the order.
|
|
138
260
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
/*Create an AppData Document with empty metadata and default appCode
|
|
144
|
-
generateAppDataDoc receives as parameters:
|
|
145
|
-
- metadata: MetadataDoc (Default: {})
|
|
146
|
-
- appCode: string (Default: 'Cowswap')
|
|
147
|
-
*/
|
|
148
|
-
const appDataDoc = cowSdk.metadataApi.generateAppDataDoc({})
|
|
149
|
-
/* {
|
|
150
|
-
version: '0.1.0',
|
|
151
|
-
appCode: 'CowSwap',
|
|
152
|
-
metadata: {},
|
|
153
|
-
}
|
|
154
|
-
*/
|
|
155
|
-
|
|
156
|
-
// Create an AppData Document with custom metadata and appCode
|
|
157
|
-
const appDataDoc = cowSdk.metadataApi.generateAppDataDoc(
|
|
158
|
-
{
|
|
159
|
-
referrer: {
|
|
160
|
-
address: '0x1f5B740436Fc5935622e92aa3b46818906F416E9',
|
|
161
|
-
version: '0.1.0',
|
|
162
|
-
},
|
|
163
|
-
},
|
|
164
|
-
'CowApp'
|
|
165
|
-
)
|
|
166
|
-
/* {
|
|
167
|
-
version: '0.1.0',
|
|
168
|
-
appCode: 'CowApp',
|
|
169
|
-
metadata: {
|
|
170
|
-
referrer: {
|
|
171
|
-
address: '0x1f5B740436Fc5935622e92aa3b46818906F416E9',
|
|
172
|
-
version: '0.1.0',
|
|
173
|
-
},
|
|
174
|
-
},
|
|
175
|
-
}
|
|
176
|
-
*/
|
|
177
|
-
|
|
178
|
-
// Calculate appDataHash (and cidV0) for given doc without uploading to IPFS
|
|
179
|
-
// This operation is deterministic and can be used to know before the upload the actual hash
|
|
261
|
+
You can calculate the `AppData` Hex, and its corresponding `cidV0` using the SDK:
|
|
262
|
+
|
|
263
|
+
```js
|
|
180
264
|
const { appDataHash, cidv0 } = await cowSdk.metadataApi.calculateAppDataHash(appDataDoc)
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Note how this operation is deterministic, so given the same document, it will always generate the same hash.
|
|
268
|
+
|
|
269
|
+
This method can be used to calculate the actual hash before uploading the document to IPFS.
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
## Get meta-data document uploaded to IPFS from AppData
|
|
273
|
+
Given the `AppData` of a document that has been uploaded to IPFS, you can easily retrieve the document.
|
|
274
|
+
|
|
275
|
+
```js
|
|
276
|
+
const appDataDoc = await cowSdk.metadataApi.decodeAppData('0x5ddb2c8207c10b96fac92cb934ef9ba004bc007a073c9e5b13edc422f209ed80')
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
This will return a document similar to:
|
|
181
280
|
|
|
182
|
-
|
|
281
|
+
```json
|
|
282
|
+
{
|
|
283
|
+
"version": "0.1.0",
|
|
284
|
+
"appCode": "YourApp",
|
|
285
|
+
"metadata": {
|
|
286
|
+
"referrer": {
|
|
287
|
+
"address": "0x1f5B740436Fc5935622e92aa3b46818906F416E9",
|
|
288
|
+
"version": "0.1.0"
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
## Upload document to IPFS
|
|
295
|
+
The SDK uses Pinata to upload it to IPFS, so you will need an API Key in order to upload it using the SDK.
|
|
296
|
+
|
|
297
|
+
Alternativelly, you can upload the document on your own using any other service.
|
|
298
|
+
|
|
299
|
+
```js
|
|
300
|
+
// Make sure you provide the IPFS params when instantiating the SDK
|
|
183
301
|
const cowSdk = new CowSdk(4, {
|
|
184
|
-
ipfs: {
|
|
302
|
+
ipfs: {
|
|
303
|
+
pinataApiKey: 'YOUR_PINATA_API_KEY',
|
|
304
|
+
pinataApiSecret: 'YOUR_PINATA_API_SECRET'
|
|
305
|
+
},
|
|
185
306
|
})
|
|
186
307
|
|
|
308
|
+
// Upload to IPFS
|
|
187
309
|
const uploadedAppDataHash = await cowSdk.metadataApi.uploadMetadataDocToIpfs(appDataDoc)
|
|
188
|
-
/* 0x5ddb2c8207c10b96fac92cb934ef9ba004bc007a073c9e5b13edc422f209ed80 */
|
|
189
310
|
```
|
|
190
311
|
|
|
191
|
-
|
|
312
|
+
## Convert IPFS CIDv0 to AppData (and back)
|
|
313
|
+
Given an IPFS CIDv0 you can convert it to an `AppData`
|
|
314
|
+
|
|
315
|
+
```js
|
|
316
|
+
const decodedAppDataHex = await cowSdk.metadataApi.cidToAppDataHex('QmUf2TrpSANVXdgcYfAAACe6kg551cY3rAemB7xfEMjYvs')
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
This will return an `AppData` hex: `0x5ddb2c8207c10b96fac92cb934ef9ba004bc007a073c9e5b13edc422f209ed80`
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
> This might be handy if you decide to upload the document to IPFS yourself and then you need the AppData to post your order
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
Similarly, you can do the opposite and convert an `AppData` into an IPFS document:
|
|
326
|
+
|
|
327
|
+
```js
|
|
328
|
+
const decodedAppDataHex = await cowSdk.metadataApi.appDataHexToCid(hash)
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
This will return an IPFS CIDv0: `QmUf2TrpSANVXdgcYfAAACe6kg551cY3rAemB7xfEMjYvs`
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
## Querying the Cow Subgraph
|
|
192
336
|
|
|
193
337
|
You can query the Cow Subgraph either by running some common queries exposed by the `CowSubgraphApi` or by building your own ones:
|
|
194
338
|
|
package/dist/CowSdk.d.ts
CHANGED
|
@@ -5,14 +5,18 @@ import { SupportedChainId as ChainId } from './constants/chains';
|
|
|
5
5
|
import { validateAppDataDocument } from './utils/appData';
|
|
6
6
|
import { Context, CowContext } from './utils/context';
|
|
7
7
|
import { UnsignedOrder } from './utils/sign';
|
|
8
|
+
import { ZeroXApi } from './api/0x';
|
|
9
|
+
import { MatchaOptions } from './api/0x/types';
|
|
8
10
|
declare type Options = {
|
|
9
11
|
loglevel?: LogLevelDesc;
|
|
12
|
+
matchaOptions?: MatchaOptions;
|
|
10
13
|
};
|
|
11
14
|
export declare class CowSdk<T extends ChainId> {
|
|
12
15
|
context: Context;
|
|
13
16
|
cowApi: CowApi;
|
|
14
17
|
metadataApi: MetadataApi;
|
|
15
18
|
cowSubgraphApi: CowSubgraphApi;
|
|
19
|
+
zeroXApi: ZeroXApi;
|
|
16
20
|
constructor(chainId?: T, cowContext?: CowContext, options?: Options);
|
|
17
21
|
updateChainId: (chainId: ChainId) => void;
|
|
18
22
|
updateContext: (cowContext: CowContext, chainId?: ChainId | undefined) => Promise<void>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { CowError } from '../../../utils/common';
|
|
2
|
+
interface ValidationError {
|
|
3
|
+
field: string;
|
|
4
|
+
code: number;
|
|
5
|
+
reason: string;
|
|
6
|
+
}
|
|
7
|
+
export interface ZeroXErrorResponse {
|
|
8
|
+
code: number;
|
|
9
|
+
reason: string;
|
|
10
|
+
validationErrors?: ValidationError[];
|
|
11
|
+
}
|
|
12
|
+
export declare const logPrefix = "0x-sdk:";
|
|
13
|
+
export default class ZeroXError extends CowError {
|
|
14
|
+
name: string;
|
|
15
|
+
description: string;
|
|
16
|
+
message: string;
|
|
17
|
+
static getErrorMessage(response: Response): Promise<string>;
|
|
18
|
+
static getErrorFromStatusCode(response: Response): Promise<string>;
|
|
19
|
+
constructor(apiError: ZeroXErrorResponse);
|
|
20
|
+
}
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { SupportedChainId } from '../../constants/chains';
|
|
2
|
+
import BaseApi from '../base';
|
|
3
|
+
import { Options, PriceQuoteParams } from '../cow/types';
|
|
4
|
+
import { MatchaOptions, MatchaPriceQuote } from './types';
|
|
5
|
+
export declare class ZeroXApi extends BaseApi {
|
|
6
|
+
MATCHA_OPTIONS: MatchaOptions;
|
|
7
|
+
MATCHA_OPTIONS_URL: string;
|
|
8
|
+
constructor(chainId: SupportedChainId, { affiliateAddressMap, excludedSources }?: MatchaOptions);
|
|
9
|
+
getQuote(params: PriceQuoteParams, options?: Options): Promise<MatchaPriceQuote | null>;
|
|
10
|
+
updateOptions({ affiliateAddressMap, excludedSources }: Partial<MatchaOptions>): Promise<void>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { OrderKind } from '@cowprotocol/contracts';
|
|
2
|
+
import { SupportedChainId } from '../../constants/chains';
|
|
3
|
+
import { PriceInformation, PriceQuoteParams } from '../cow/types';
|
|
4
|
+
import { MatchaOptions, MatchaPriceQuote } from './types';
|
|
5
|
+
export declare function get0xUrls(): Partial<Record<SupportedChainId, string>>;
|
|
6
|
+
export declare function normaliseQuoteResponse(priceRaw: MatchaPriceQuote | null, kind: OrderKind): PriceInformation | null;
|
|
7
|
+
export declare function getMatchaChainId(chainId: SupportedChainId): SupportedChainId | null;
|
|
8
|
+
export declare function optionsToMatchaParamsUrl({ excludedSources, affiliateAddress, }: {
|
|
9
|
+
excludedSources: MatchaOptions['excludedSources'];
|
|
10
|
+
affiliateAddress: string;
|
|
11
|
+
}): string;
|
|
12
|
+
export declare function handleQuoteResponse<T = unknown, P extends PriceQuoteParams = PriceQuoteParams>(response: Response, params?: P): Promise<T>;
|
|
13
|
+
export declare function throwOrReturnAffiliateAddress({ affiliateAddressMap, chainId, }: {
|
|
14
|
+
affiliateAddressMap: MatchaOptions['affiliateAddressMap'];
|
|
15
|
+
chainId: SupportedChainId;
|
|
16
|
+
}): string;
|
|
17
|
+
export declare function extractExcludedSources({ excludedSources }: Pick<MatchaOptions, 'excludedSources'>): string;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { SupportedChainId } from '../../constants/chains';
|
|
2
|
+
import { Context } from '../../utils/context';
|
|
3
|
+
import { Options } from '../cow/types';
|
|
4
|
+
interface ConstructorParams {
|
|
5
|
+
context: Context;
|
|
6
|
+
name: string;
|
|
7
|
+
apiVersion?: string;
|
|
8
|
+
getApiUrl: (...params: any[]) => Partial<Record<SupportedChainId, string>>;
|
|
9
|
+
defaultHeaders?: HeadersInit;
|
|
10
|
+
}
|
|
11
|
+
export default class BaseApi {
|
|
12
|
+
context: Context;
|
|
13
|
+
API_NAME: string;
|
|
14
|
+
API_VERSION: string;
|
|
15
|
+
API_URL_GETTER: (...params: any[]) => Partial<Record<SupportedChainId, string>>;
|
|
16
|
+
DEFAULT_HEADERS: HeadersInit;
|
|
17
|
+
constructor({ context, name, getApiUrl, defaultHeaders, apiVersion, }: ConstructorParams);
|
|
18
|
+
protected getApiBaseUrl(...params: unknown[]): Promise<string>;
|
|
19
|
+
protected post(url: string, data: unknown, options?: Options): Promise<Response>;
|
|
20
|
+
protected get(url: string, options?: Options): Promise<Response>;
|
|
21
|
+
protected delete(url: string, data: unknown, options?: Options): Promise<Response>;
|
|
22
|
+
protected handleMethod(url: string, method: 'GET' | 'POST' | 'DELETE', fetchFn: BaseApi['fetch'], getApiUrl: BaseApi['API_URL_GETTER'], options?: Options, data?: unknown): Promise<Response>;
|
|
23
|
+
protected fetch(url: string, method: 'GET' | 'POST' | 'DELETE', baseUrl: string, data?: unknown, requestOptions?: RequestInit): Promise<Response>;
|
|
24
|
+
}
|
|
25
|
+
export {};
|
package/dist/api/cow/index.d.ts
CHANGED
|
@@ -1,17 +1,10 @@
|
|
|
1
|
-
import { SupportedChainId as ChainId } from '../../constants/chains';
|
|
2
1
|
import { OrderCreation } from '../../utils/sign';
|
|
3
2
|
import { FeeQuoteParams, PriceInformation, PriceQuoteParams, SimpleGetQuoteResponse } from './types';
|
|
4
3
|
import { GetOrdersParams, GetTradesParams, OrderCancellationParams, OrderID, OrderMetaData, ProfileData, TradeMetaData, Options } from './types';
|
|
5
4
|
import { Context } from '../../utils/context';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
API_NAME: string;
|
|
5
|
+
import BaseApi from '../base';
|
|
6
|
+
export declare class CowApi extends BaseApi {
|
|
9
7
|
constructor(context: Context);
|
|
10
|
-
get DEFAULT_HEADERS(): {
|
|
11
|
-
'Content-Type': string;
|
|
12
|
-
'X-AppId': string;
|
|
13
|
-
};
|
|
14
|
-
get API_BASE_URL(): Partial<Record<ChainId, string>>;
|
|
15
8
|
getProfileData(address: string, options?: Options): Promise<ProfileData | null>;
|
|
16
9
|
getTrades(params: GetTradesParams, options?: Options): Promise<TradeMetaData[]>;
|
|
17
10
|
getOrders(params: GetOrdersParams, options?: Options): Promise<OrderMetaData[]>;
|
|
@@ -25,13 +18,8 @@ export declare class CowApi {
|
|
|
25
18
|
owner: string;
|
|
26
19
|
}, options?: Options): Promise<OrderID>;
|
|
27
20
|
getOrderLink(orderId: OrderID): Promise<string>;
|
|
21
|
+
private getProfile;
|
|
28
22
|
private mapNewToLegacyParams;
|
|
29
|
-
|
|
30
|
-
private fetch;
|
|
23
|
+
protected getApiBaseUrl(): Promise<string>;
|
|
31
24
|
private fetchProfile;
|
|
32
|
-
private post;
|
|
33
|
-
private get;
|
|
34
|
-
private getProfile;
|
|
35
|
-
private delete;
|
|
36
|
-
private handleMethod;
|
|
37
25
|
}
|
package/dist/api/cow/types.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { GetQuoteResponse, OrderKind } from '@cowprotocol/contracts';
|
|
2
2
|
import { StrictUnion } from 'utilities';
|
|
3
3
|
import { SupportedChainId as ChainId } from '../../constants/chains';
|
|
4
|
+
import { Env } from '../../utils/context';
|
|
4
5
|
import { OrderCancellation, SigningSchemeValue } from '../../utils/sign';
|
|
5
6
|
/**
|
|
6
7
|
* Unique identifier for the order, calculated by keccak256(orderDigest, ownerAddress, validTo),
|
|
@@ -113,6 +114,8 @@ export declare type PriceQuoteParams = Omit<FeeQuoteParams, 'sellToken' | 'buyTo
|
|
|
113
114
|
};
|
|
114
115
|
export declare type Options = {
|
|
115
116
|
chainId?: ChainId;
|
|
116
|
-
|
|
117
|
+
env?: Env;
|
|
118
|
+
requestOptions?: RequestInit;
|
|
119
|
+
apiUrlGetterParams?: unknown[];
|
|
117
120
|
};
|
|
118
121
|
export {};
|
|
@@ -1569,12 +1569,16 @@ export declare type Token = {
|
|
|
1569
1569
|
__typename?: 'Token';
|
|
1570
1570
|
/** Token address */
|
|
1571
1571
|
address: Scalars['Bytes'];
|
|
1572
|
+
/** Daily totals */
|
|
1573
|
+
dailyTotals: Array<TokenDailyTotal>;
|
|
1572
1574
|
/** Token decimals fetched by contract call */
|
|
1573
1575
|
decimals: Scalars['Int'];
|
|
1574
1576
|
/** First token trade block timestamp */
|
|
1575
|
-
firstTradeTimestamp
|
|
1577
|
+
firstTradeTimestamp: Scalars['Int'];
|
|
1576
1578
|
/** History of trading for this token */
|
|
1577
1579
|
history: Array<TokenTradingEvent>;
|
|
1580
|
+
/** Hourly totals */
|
|
1581
|
+
hourlyTotals: Array<TokenHourlyTotal>;
|
|
1578
1582
|
/** Token address to hexString */
|
|
1579
1583
|
id: Scalars['ID'];
|
|
1580
1584
|
/** Token name fetched by ERC20 contract call */
|
|
@@ -1594,6 +1598,13 @@ export declare type Token = {
|
|
|
1594
1598
|
/** Total volume in Usd */
|
|
1595
1599
|
totalVolumeUsd: Scalars['BigDecimal'];
|
|
1596
1600
|
};
|
|
1601
|
+
export declare type TokenDailyTotalsArgs = {
|
|
1602
|
+
first?: InputMaybe<Scalars['Int']>;
|
|
1603
|
+
orderBy?: InputMaybe<TokenDailyTotal_OrderBy>;
|
|
1604
|
+
orderDirection?: InputMaybe<OrderDirection>;
|
|
1605
|
+
skip?: InputMaybe<Scalars['Int']>;
|
|
1606
|
+
where?: InputMaybe<TokenDailyTotal_Filter>;
|
|
1607
|
+
};
|
|
1597
1608
|
export declare type TokenHistoryArgs = {
|
|
1598
1609
|
first?: InputMaybe<Scalars['Int']>;
|
|
1599
1610
|
orderBy?: InputMaybe<TokenTradingEvent_OrderBy>;
|
|
@@ -1601,6 +1612,13 @@ export declare type TokenHistoryArgs = {
|
|
|
1601
1612
|
skip?: InputMaybe<Scalars['Int']>;
|
|
1602
1613
|
where?: InputMaybe<TokenTradingEvent_Filter>;
|
|
1603
1614
|
};
|
|
1615
|
+
export declare type TokenHourlyTotalsArgs = {
|
|
1616
|
+
first?: InputMaybe<Scalars['Int']>;
|
|
1617
|
+
orderBy?: InputMaybe<TokenHourlyTotal_OrderBy>;
|
|
1618
|
+
orderDirection?: InputMaybe<OrderDirection>;
|
|
1619
|
+
skip?: InputMaybe<Scalars['Int']>;
|
|
1620
|
+
where?: InputMaybe<TokenHourlyTotal_Filter>;
|
|
1621
|
+
};
|
|
1604
1622
|
export declare type TokenDailyTotal = {
|
|
1605
1623
|
__typename?: 'TokenDailyTotal';
|
|
1606
1624
|
/** Average trade price */
|
|
@@ -2019,6 +2037,7 @@ export declare type Token_Filter = {
|
|
|
2019
2037
|
address_not?: InputMaybe<Scalars['Bytes']>;
|
|
2020
2038
|
address_not_contains?: InputMaybe<Scalars['Bytes']>;
|
|
2021
2039
|
address_not_in?: InputMaybe<Array<Scalars['Bytes']>>;
|
|
2040
|
+
dailyTotals_?: InputMaybe<TokenDailyTotal_Filter>;
|
|
2022
2041
|
decimals?: InputMaybe<Scalars['Int']>;
|
|
2023
2042
|
decimals_gt?: InputMaybe<Scalars['Int']>;
|
|
2024
2043
|
decimals_gte?: InputMaybe<Scalars['Int']>;
|
|
@@ -2036,6 +2055,7 @@ export declare type Token_Filter = {
|
|
|
2036
2055
|
firstTradeTimestamp_not?: InputMaybe<Scalars['Int']>;
|
|
2037
2056
|
firstTradeTimestamp_not_in?: InputMaybe<Array<Scalars['Int']>>;
|
|
2038
2057
|
history_?: InputMaybe<TokenTradingEvent_Filter>;
|
|
2058
|
+
hourlyTotals_?: InputMaybe<TokenHourlyTotal_Filter>;
|
|
2039
2059
|
id?: InputMaybe<Scalars['ID']>;
|
|
2040
2060
|
id_gt?: InputMaybe<Scalars['ID']>;
|
|
2041
2061
|
id_gte?: InputMaybe<Scalars['ID']>;
|
|
@@ -2135,9 +2155,11 @@ export declare type Token_Filter = {
|
|
|
2135
2155
|
};
|
|
2136
2156
|
export declare enum Token_OrderBy {
|
|
2137
2157
|
Address = "address",
|
|
2158
|
+
DailyTotals = "dailyTotals",
|
|
2138
2159
|
Decimals = "decimals",
|
|
2139
2160
|
FirstTradeTimestamp = "firstTradeTimestamp",
|
|
2140
2161
|
History = "history",
|
|
2162
|
+
HourlyTotals = "hourlyTotals",
|
|
2141
2163
|
Id = "id",
|
|
2142
2164
|
Name = "name",
|
|
2143
2165
|
NumberOfTrades = "numberOfTrades",
|
|
@@ -2755,7 +2777,7 @@ export declare type User = {
|
|
|
2755
2777
|
/** Owner's address */
|
|
2756
2778
|
address: Scalars['Bytes'];
|
|
2757
2779
|
/** First trade block timestamp */
|
|
2758
|
-
firstTradeTimestamp
|
|
2780
|
+
firstTradeTimestamp: Scalars['Int'];
|
|
2759
2781
|
/** Trade event order owner */
|
|
2760
2782
|
id: Scalars['ID'];
|
|
2761
2783
|
/** Determine if user has solved a settlement */
|