Skip to main content

Further building on the previous tutorial, we will now submit the order we signed in the sign order tutorial to CoW Protocol.

Submitting an order

Submitting orders to the API may very well result in an error. For this reason, we should ALWAYS handle errors. To do this, we will use the try/catch syntax.

run.ts
import type { Web3Provider } from '@ethersproject/providers';
import { OrderBookApi, SupportedChainId, OrderQuoteRequest, OrderQuoteSideKindSell, OrderSigningUtils, UnsignedOrder, SigningScheme } from '@cowprotocol/cow-sdk';

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

	try {
		const orderId = await orderBookApi.sendOrder({
			...quote,
			...orderSigningResult,
			sellAmount: order.sellAmount, // replace quote sellAmount with signed order sellAmount, which is equal to original sellAmount
			feeAmount: order.feeAmount, // replace quote feeAmount with signed order feeAmount, which is 0
			signingScheme: orderSigningResult.signingScheme as unknown as SigningScheme
		})
  
		return { orderId }    
	} catch (e) {
		return e
	}
}

Currently the OrderSigningResult returns an enum which is not compatible with the SigningScheme type. This is why we need to cast it to unknown and then to SigningScheme.

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

An example orderId should look like:

output.json
{
	"orderId": "0xae842840f65743bc84190a68da1e4adf1771b242fa903b6c2e87bc5050e07c1329104bb91ada737a89393c78335e48ff4708727e65952d5e"
}

The orderId is the unique identifier for the order we have just submitted. We can use this orderId (also known as orderUid) to check the status of the order on CoW Explorer. Keep this handy, as we will practice some more with this orderId in the next tutorial!

Errors

A couple of errors may easily result when running this code:

  • InsufficientBalance: The wallet you have signed with does not have enough balance for the sellToken. A reminder in this example, the sellToken is wxDai on Gnosis chain.
  • InsufficientAllowance: In this case, the wallet has enough balance, however you have missed out a step in the approve tutorial and have not approved the relayerAddress to spend the sellToken on your behalf.

Next: Viewing status

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import { OrderBookApi, OrderQuoteRequest, OrderQuoteSideKindSell, OrderSigningUtils, SupportedChainId, UnsignedOrder } from '@cowprotocol/cow-sdk';
import type { Web3Provider } from '@ethersproject/providers';
 
export async function run(provider: Web3Provider): Promise<unknown> {
    const chainId = +(await provider.send('eth_chainId', []));
    if (chainId !== SupportedChainId.GNOSIS_CHAIN) {
        throw new Error(`Please connect to the Gnosis chain. ChainId: ${chainId}`);
    }
 
    const orderBookApi = new OrderBookApi({ chainId: SupportedChainId.GNOSIS_CHAIN });
 
    const signer = provider.getSigner();
    const ownerAddress = await signer.getAddress();
 
    const sellToken = '0xe91d153e0b41518a2ce8dd3d7944fa863463a97d'; // wxDAI
    const buyToken = '0x177127622c4A00F3d409B75571e12cB3c8973d3c'; // COW
    const sellAmount = '1000000000000000000'; // 1 wxDAI
 
    const quoteRequest: OrderQuoteRequest = {
        sellToken,
        buyToken,
        from: ownerAddress,
        receiver: ownerAddress,
        sellAmountBeforeFee: sellAmount,
        kind: OrderQuoteSideKindSell.SELL,
    };
 
    const { quote } = await orderBookApi.getQuote(quoteRequest);
 
    // Use the original sellAmount, which is equal to quoted sellAmount added to quoted feeAmount
    // sellAmount === BigNumber.from(quote.sellAmount).add(BigNumber.from(quote.feeAmount)).toString()
 
    // And feeAmount must be set to 0
    const feeAmount = '0'
 
    const order: UnsignedOrder = {
      ...quote,
      sellAmount,
      feeAmount,
      receiver: ownerAddress,
    }
 
    return OrderSigningUtils.signOrder(order, chainId, signer)
}
 
initialising