Creating the order
Let’s do an intermediate step and create a method to submit the order. The gist of the process is the following:
  • Get the quote of the trade to do
  • Create an order through the api and get an order id
  • Use the order id to set a flag on-chain, saying you are ok with that trade
I tried adding comments around the code
1
from time import time
2
import requests
3
import web3
4
def cowswap_sell(safe, sell_token, buy_token):
5
# Contract used to sign the order
6
gnosis_settlement = safe.contract("0x9008D19f58AAbD9eD0D60971565AA8510560ab41")
7
amount = sell_token.balanceOf(safe.address)
8
9
# get the fee + the buy amount after fee
10
fee_and_quote = "https://api.cow.fi/mainnet/api/v1/feeAndQuote/sell"
11
get_params = {
12
"sellToken": sell_token.address,
13
"buyToken": buy_token.address,
14
"sellAmountBeforeFee": amount
15
}
16
r = requests.get(fee_and_quote, params=get_params)
17
assert r.ok and r.status_code == 200
18
19
# These two values are needed to create an order
20
fee_amount = int(r.json()['fee']['amount'])
21
buy_amount_after_fee = int(r.json()['buyAmountAfterFee'])
22
assert fee_amount > 0
23
assert buy_amount_after_fee > 0
24
25
# Pretty random order deadline :shrug:
26
deadline = chain.time() + 60*60*24*100 # 100 days
27
28
# Submit order
29
order_payload = {
30
"sellToken": sell_token.address,
31
"buyToken": buy_token.address,
32
"sellAmount": str(amount-fee_amount), # amount that we have minus the fee we have to pay
33
"buyAmount": str(buy_amount_after_fee), # buy amount fetched from the previous call
34
"validTo": deadline,
35
"appData": web3.Web3.keccak(text="yearn goes moooooo").hex(), # required field, do not change :)
36
"feeAmount": str(fee_amount),
37
"kind": "sell",
38
"partiallyFillable": False,
39
"receiver": safe.address,
40
"signature": safe.address,
41
"from": safe.address,
42
"sellTokenBalance": "erc20",
43
"buyTokenBalance": "erc20",
44
"signingScheme": "presign" # Very important. this tells the api you are going to sign on chain
45
}
46
orders_url = f"https://protocol-mainnet.gnosis.io/api/v1/orders"
47
r = requests.post(orders_url, json=order_payload)
48
assert r.ok and r.status_code == 201
49
order_uid = r.json()
50
print(f"Payload: {order_payload}")
51
print(f"Order uid: {order_uid}")
52
53
# With the order id, we set the flag, basically signing as the gnosis safe.
54
gnosis_settlement.setPreSignature(order_uid, True)
Copied!
Copy link