-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
91 changed files
with
1,137 additions
and
61 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
27 changes: 0 additions & 27 deletions
27
content/tutorial/01-orders/02-app-data/02-app-data/app-a/src/lib/run.ts
This file was deleted.
Oops, something went wrong.
15 changes: 0 additions & 15 deletions
15
content/tutorial/01-orders/02-app-data/02-app-data/app-a/tsconfig.json
This file was deleted.
Oops, something went wrong.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
146 changes: 146 additions & 0 deletions
146
content/tutorial/01-simple-orders/02-app-data/01-simple-app-data/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
--- | ||
title: Simple app data | ||
--- | ||
|
||
So, we have created a simple order in the previous section, but what if you're a wallet provider, and you want to add some extra data to the order? For example, you may want to associate the order with your app in order to brag about how many orders on CoW Protocol are created by your app. | ||
|
||
## `app-data` SDK | ||
|
||
The `app-data` is documented in [JSON Schema](https://beta.docs.cow.fi/cow-protocol/reference/core/intents/app-data#schema). Writing to a schema is not very convenient, so we have a special SDK for that. It's called the `app-data` SDK. | ||
|
||
To install it, run: `npm install @cowprotocol/app-data` | ||
|
||
> It is highly suggested to use the `app-data` SDK to generate the `app-data` document. There are many subtle nuances to the `app-data` document, making it easy to get wrong. | ||
### Instantiate the SDK | ||
|
||
To instantiate the SDK, we simply call it's constructor: | ||
|
||
```typescript | ||
/// file: run.ts | ||
import type { Web3Provider } from '@ethersproject/providers'; | ||
+++import { MetadataApi } from '@cowprotocol/app-data';+++ | ||
|
||
export async function run(provider: Web3Provider): Promise<unknown> { | ||
// ... | ||
const metadataApi = new MetadataApi(); | ||
// ... | ||
} | ||
``` | ||
|
||
### App data parameters | ||
|
||
As an example, if we were developing a wallet, we may want to add some metadata to the order. In doing so, we will provide: | ||
|
||
- `appCode` - the name of our app | ||
- `environment` - the environment we're running on (e.g. `prod`, `staging`) | ||
- `referrer` - the ethereum address for the referrer of the order | ||
- `quote` - the quote parameters, nominally the slippage applied to the order | ||
- `orderClass` - the order class, eg. `market`, `limit`, `twap` etc. | ||
|
||
```typescript | ||
/// file: run.ts | ||
import type { Web3Provider } from '@ethersproject/providers'; | ||
+++import { MetadataApi, latest } from '@cowprotocol/app-data';+++ | ||
|
||
export async function run(provider: Web3Provider): Promise<unknown> { | ||
// ... | ||
|
||
const appCode = 'Decentralized CoW'; | ||
const environment = 'prod'; | ||
const referrer = { address: '0xcA771eda0c70aA7d053aB1B25004559B918FE662' }; | ||
|
||
const quoteAppDoc: latest.Quote = { slippageBips: '50' }; | ||
const orderClass: latest.OrderClass = { orderClass: 'market' }; | ||
|
||
// ... | ||
} | ||
``` | ||
|
||
> We use the `latest` namespace to get the latest types. The schema is versioned, so you may alternatively use the version namespace. | ||
### App data document | ||
|
||
Now that we have the parameters, we can create the app data document: | ||
|
||
```typescript | ||
/// file: run.ts | ||
import type { Web3Provider } from '@ethersproject/providers'; | ||
import { MetadataApi, latest } from '@cowprotocol/app-data'; | ||
|
||
export async function run(provider: Web3Provider): Promise<unknown> { | ||
// ... | ||
|
||
const appDataDoc = await metadataApi.generateAppDataDoc({ | ||
appCode, | ||
environment, | ||
metadata: { | ||
referrer, | ||
quote: quoteAppDoc, | ||
orderClass, | ||
}, | ||
}); | ||
|
||
// ... | ||
} | ||
``` | ||
|
||
### Processing the document | ||
|
||
Now that we have the document, we can process it. In doing this, we will: | ||
|
||
- determine the CID of the document | ||
- determine the appDataContent, which is passed in the order's `appData` field when sent to the API | ||
- determine the appDataHex, which is passed in the order's `appDataHash` field when sent to the API | ||
|
||
```typescript | ||
/// file: run.ts | ||
import type { Web3Provider } from '@ethersproject/providers'; | ||
import { MetadataApi, latest } from '@cowprotocol/app-data'; | ||
|
||
export async function run(provider: Web3Provider): Promise<unknown> { | ||
// ... | ||
|
||
const { appDataHex, appDataContent } = await metadataApi.appDataToCid(appDataDoc); | ||
|
||
return { | ||
appDataDoc, | ||
appDataHex, | ||
appDataContent, | ||
}; | ||
} | ||
``` | ||
|
||
## Run the code | ||
|
||
To run the code, we can press the "Run" button in the bottom right panel (the web container). | ||
|
||
1. Press the "Run" button | ||
2. Observe the respective data returned to the output panel | ||
|
||
An example output should look like: | ||
|
||
```json | ||
/// file: output.json | ||
{ | ||
"appDataDoc": { | ||
"appCode": "Decentralized CoW", | ||
"metadata": { | ||
"referrer": { | ||
"address": "0xcA771eda0c70aA7d053aB1B25004559B918FE662" | ||
}, | ||
"quote": { | ||
"slippageBips": "50" | ||
}, | ||
"orderClass": { | ||
"orderClass": "market" | ||
} | ||
}, | ||
"version": "0.11.0", | ||
"environment": "prod" | ||
}, | ||
"cid": "f01551b20b4b4561d26cfe084594ddbb4cf6af5397c1bf1cb31997ae4d2a82325eeda8f6d", | ||
"appDataHex": "0xb4b4561d26cfe084594ddbb4cf6af5397c1bf1cb31997ae4d2a82325eeda8f6d", | ||
"appDataContent": "{\"appCode\":\"Decentralized CoW\",\"environment\":\"prod\",\"metadata\":{\"orderClass\":{\"orderClass\":\"market\"},\"quote\":{\"slippageBips\":\"50\"},\"referrer\":{\"address\":\"0xcA771eda0c70aA7d053aB1B25004559B918FE662\"}},\"version\":\"0.11.0\"}" | ||
} | ||
``` |
5 changes: 5 additions & 0 deletions
5
content/tutorial/01-simple-orders/02-app-data/01-simple-app-data/app-a/src/lib/run.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import type { Web3Provider } from '@ethersproject/providers' | ||
|
||
export async function run(provider: Web3Provider): Promise<unknown> { | ||
// TODO: Implement | ||
} |
31 changes: 31 additions & 0 deletions
31
content/tutorial/01-simple-orders/02-app-data/01-simple-app-data/app-b/src/lib/run.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import type { Web3Provider } from '@ethersproject/providers' | ||
import { MetadataApi, latest } from '@cowprotocol/app-data' | ||
|
||
export async function run(provider: Web3Provider): Promise<unknown> { | ||
const metadataApi = new MetadataApi() | ||
|
||
const appCode = 'Decentralized CoW' | ||
const environment = 'production' | ||
const referrer = { address: `0xcA771eda0c70aA7d053aB1B25004559B918FE662` } | ||
|
||
const quoteAppDoc: latest.Quote = { slippageBips: '50' } | ||
const orderClass: latest.OrderClass = { orderClass: 'market' } | ||
|
||
const appDataDoc = await metadataApi.generateAppDataDoc({ | ||
appCode, | ||
environment, | ||
metadata: { | ||
referrer, | ||
quote: quoteAppDoc, | ||
orderClass | ||
}, | ||
}) | ||
|
||
const { appDataHex, appDataContent } = await metadataApi.appDataToCid(appDataDoc) | ||
|
||
return { | ||
appDataDoc, | ||
appDataHex, | ||
appDataContent | ||
} | ||
} |
81 changes: 81 additions & 0 deletions
81
content/tutorial/01-simple-orders/02-app-data/02-create-order-app-data/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
--- | ||
title: Create order with appData | ||
--- | ||
|
||
Now, from the previous tutorial we have created a simple app data document. We will now use this document to create an order. | ||
|
||
In doing so, we will be making use of: | ||
|
||
- [Submit order](/tutorial/submit-order) | ||
- [Simple app data](/tutorial/simple-app-data) | ||
|
||
## Instantiate the SDK | ||
|
||
We will start from the basic setup from the [submit order](/tutorial/submit-order) tutorial and the [simple app data](/tutorial/simple-app-data) tutorial. This has been populated in the code editor for you. | ||
|
||
|
||
### Quoting with app data | ||
|
||
The keen eye-ed among you will notice that `appDataHex` and `appDataContent` are not used. Let's fix that. When we request a quote, we will pass `appDataHex` and `appDataContent` to the API. This allows the API to: | ||
|
||
- validate the app data document and it's has (`appDataHex`) | ||
- wrap the app data into the response object | ||
- determine any additional fees that may be required (if the app data document contains hooks) | ||
|
||
```typescript | ||
/// file: run.ts | ||
// ... | ||
export async function run(provider: Web3Provider): Promise<unknown> { | ||
// ... | ||
|
||
const quoteRequest: OrderQuoteRequest = { | ||
sellToken, | ||
buyToken, | ||
from: ownerAddress, | ||
receiver: ownerAddress, | ||
sellAmountBeforeFee: sellAmount, | ||
kind: OrderQuoteSideKindSell.SELL, | ||
+++appData: appDataContent,+++ | ||
+++appDataHash: appDataHex,+++ | ||
}; | ||
|
||
// ... | ||
} | ||
``` | ||
|
||
### Signing with app data | ||
|
||
When signing an order, we need to make sure that we have set the `appData` correctly. In this case, the `UnsignedOrder` used by the `OrderSigningUtils` class has an `appData` field which should be set to the `appDataHex` value. | ||
|
||
```typescript | ||
/// file: run.ts | ||
// ... | ||
export async function run(provider: Web3Provider): Promise<unknown> { | ||
// ... | ||
const order: UnsignedOrder = { | ||
...quote, | ||
receiver: ownerAddress, | ||
+++appData: appDataHex,+++ | ||
} | ||
// ... | ||
} | ||
``` | ||
|
||
## Run the code | ||
|
||
To run the code, we can press the "Run" button in the bottom right panel (the web container). | ||
|
||
When running the script, we may be asked to connect a wallet. We can use Rabby for this. | ||
|
||
1. Accept the connection request in Rabby | ||
2. Press the "Run" button again | ||
3. Observe the `orderId` returned to the output panel | ||
|
||
You can now use the `orderId` to check the status of the order on [CoW Explorer](https://explorer.cow.fi/). Within the order details page, you can also see the app data document that was used to create the order. | ||
|
||
### Errors | ||
|
||
The usual API errors from the [submit order](/tutorial/submit-order) tutorial may occur. In addition, the following errors may occur: | ||
|
||
- **`InvalidAppData`**: The app data passed to the API is not either `bytes32` or a stringified JSON object. | ||
- **`AppDataHashMismatch`**: The hash of the app data document doesn't match the `appDataHash` field provided in the order. This may be due to the app data document being modified after the order was signed. |
Oops, something went wrong.