Skip to content

Commit

Permalink
feat: basic orders (#18)
Browse files Browse the repository at this point in the history
This PR:

1. Rearranges the general tutorials layout.
2. Implements tutorials for creating / cancelling (off-chain & on-chain)
/ viewing basic orders.
  • Loading branch information
mfw78 authored Jan 5, 2024
1 parent 42899f3 commit 491e730
Show file tree
Hide file tree
Showing 64 changed files with 1,335 additions and 115 deletions.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

26 changes: 0 additions & 26 deletions content/tutorial/01-cow-protocol/tsconfig.json

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
title: Getting started
---

Tutorials are designed to be followed in order, as each tutorial builds on the previous one. The tutorial system is built with Web Containers, which means that you can run the code in your browser without having to install anything on your computer.

## Prerequisites

- [Rabby](https://rabby.io/) or [Metamask](https://metamask.io) installed in your browser
- A web browser with WASM support (Chrome, Firefox, Edge, Safari)

> If you are using Brave, you will need to disable shields for the webcontainers to work.
## Code snippets

All code snippets are in TypeScript, and are executed in a sandboxed environment. You can edit the code and run it again.

Let's look at the current code snippet:

```typescript
/// file: run.ts
import type { Web3Provider } from '@ethersproject/providers'

export async function run(provider: Web3Provider): Promise<unknown> {
// TODO: Implement
}
```

### Web3 Provider

The tutorials allows for the use of a browser's Web3 provider, such as Rabby or Metamask. The `provider` argument is a [Web3Provider](https://docs.ethers.io/v5/api/providers/types/#providers-Web3Provider) from the [ethers.js](https://docs.ethers.io/v5/) library.

This is automatically injected into the code snippet, and you can use it to interact with the blockchain via your browser's wallet.

### `run` function

Tutorials are very simple plain TypeScript, and the `run` function is the entry point for the code snippet. This function is called when you click the "Run" button.

## Running the code

Let's finish the code snippet by adding some debugging and returning a value:

```typescript
/// file: run.ts
import type { Web3Provider } from '@ethersproject/providers'

export async function run(provider: Web3Provider): Promise<unknown> {
console.log('Hello world!');
return {
message: "Hello world!"
};
}
```

Once you click the "Run" button, you should see the following output:

```json
/// file: output.json
{
"message": "Hello world!"
}
```

> You will see that the console output is not visible. To see this, you must open the browser's developer tools (F12) and select the "Console" tab.
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
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type { Web3Provider } from '@ethersproject/providers'

export async function run(provider: Web3Provider): Promise<unknown> {
console.log('Hello world!');
return {
message: "Hello world!"
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"title": "Getting started",
"scope": {
"prefix": "/src/lib/",
"name": "src"
},
"focus": "/src/lib/run.ts"
}
134 changes: 134 additions & 0 deletions content/tutorial/01-orders/01-basic-orders/01-approve/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
---
title: Approving sell token
---

For an order to be tradeable on CoW Protocol, the owner needs to approve the [GPv2VaultRelayer](https://beta.docs.cow.fi/cow-protocol/reference/contracts/core/vault-relayer) to spend the token they want to trade.

> A list of the core deployed contracts can be found [here](https://beta.docs.cow.fi/cow-protocol/reference/contracts/core).
## Contract (token) interaction

For interacting with contracts, the tutorials use [ethers.js](https://docs.ethers.io/v5/).

To interact with a contract, we need to know:

- the contract address
- the ABI

Additionally, if we want to **make a transaction**, we must have a _signer_ (e.g. a wallet).

### Contract address

The contract to be interacted with is the token we want to trade. In this tutorial, we use the [wxDAI](https://gnosisscan.io/token/0xe91d153e0b41518a2ce8dd3d7944fa863463a97d) token, and assign it's address `0xe91d153e0b41518a2ce8dd3d7944fa863463a97d` to a `const`.

At the same time, we assign the address of the [GPv2VaultRelayer](https://beta.docs.cow.fi/cow-protocol/reference/contracts/core/vault-relayer) to a `const`:

```typescript
/// file: run.ts
import type { Web3Provider } from '@ethersproject/providers';

export async function run(provider: Web3Provider): Promise<unknown> {
const relayerAddress = '0xC92E8bdf79f0507f65a392b0ab4667716BFE0110';
const tokenAddress = '0xe91d153e0b41518a2ce8dd3d7944fa863463a97d';

// ...
}
```

### `approve` ABI

You may either set a limited approval (at least the amount of tokens you want to trade) or an unlimited approval. To do this, we use the [`approve`](https://eips.ethereum.org/EIPS/eip-20#approve) function of the [ERC-20](https://eips.ethereum.org/EIPS/eip-20) token standard.

We can set this function's ABI as a `const`:

```typescript
/// file: run.ts
import type { Web3Provider } from '@ethersproject/providers';

export async function run(provider: Web3Provider): Promise<unknown> {
// ...

const approveAbi = [
{
inputs: [
{ name: '_spender', type: 'address' },
{ name: '_value', type: 'uint256' },
],
name: 'approve',
outputs: [{ type: 'bool' }],
stateMutability: 'nonpayable',
type: 'function',
},
];

// ...
}
```

### Signer

To make a transaction, we need a signer. In this tutorial, we use an injected Web3Provider, such as [Rabby](https://rabby.io). We can get the signer from the provider:

```typescript
/// file: run.ts
import type { Web3Provider } from '@ethersproject/providers';

export async function run(provider: Web3Provider): Promise<unknown> {
// ...

const signer = provider.getSigner();

// ...
}
```

### Connect to the contract

To interact with the contract, we need to connect to it. We can do this by using the `Contract` class from ethers.js:

```typescript
/// file: run.ts
import type { Web3Provider } from '@ethersproject/providers';
+++import { Contract } from '@ethersproject/contracts';+++

export async function run(provider: Web3Provider): Promise<unknown> {
// ...

const wxDai = new Contract(tokenAddress, approveAbi, signer);

// ...
}
```

### Execute the `approve`

Now we have everything we need to execute the `approve` function. We will now give the `relayerAddress` unlimited approval to spend the `tokenAddress` token.

```typescript
/// file: run.ts
import type { Web3Provider } from '@ethersproject/providers';
+++import { Contract, ethers } from '@ethersproject/contracts';+++

export async function run(provider: Web3Provider): Promise<unknown> {
// ...

const wxDai = new Contract(tokenAddress, approveAbi, signer);

const tx = await wxDai.approve(relayerAddress, ethers.constants.MaxUint256);
console.log('tx', tx);
const receipt = await tx.wait();

return receipt;
}
```

## Run the code

To run the snippet, we simply press the "Run" button in the bottom right panel (the web container).

When running the script, we will be asked to connect a wallet. We can use Rabby for this.

1. Accept the connection request in Rabby
2. Click "Run"
3. Observe the `tx` object in the browser's console
4. On successful confirmation of the transaction, the `receipt` object will be returned to the output panel
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
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import type { Web3Provider } from '@ethersproject/providers'
import { Contract, ethers } from "ethers";

export async function run(provider: Web3Provider): Promise<unknown> {
const relayerAddress = '0xC92E8bdf79f0507f65a392b0ab4667716BFE0110';
const tokenAddress = '0xe91d153e0b41518a2ce8dd3d7944fa863463a97d';

// Compacted ABI for the approve function
const approveAbi = [
{
inputs: [
{ name: '_spender', type: 'address' },
{ name: '_value', type: 'uint256' },
],
name: 'approve',
outputs: [{ type: 'bool' }],
stateMutability: 'nonpayable',
type: 'function',
},
];

const signer = provider.getSigner();
const wxDai = new Contract(tokenAddress, approveAbi, signer);

const tx = await wxDai.approve(relayerAddress, ethers.constants.MaxUint256);
console.log('tx', tx);
const receipt = await tx.wait();

return receipt;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"title": "Approve sell token",
"scope": {
"prefix": "/src/lib/",
"name": "src"
},
"focus": "/src/lib/run.ts"
}
Loading

0 comments on commit 491e730

Please sign in to comment.