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.
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 theSigningScheme
type. This is why we need to cast it tounknown
and then toSigningScheme
.
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.
- Accept the connection request in Rabby
- Press the "Run" button again
- Observe the
orderId
returned to the output panel
An example orderId
should look like:
{
"orderId": "0xae842840f65743bc84190a68da1e4adf1771b242fa903b6c2e87bc5050e07c1329104bb91ada737a89393c78335e48ff4708727e65952d5e"
}
The
orderId
is the unique identifier for the order we have just submitted. We can use thisorderId
(also known asorderUid
) to check the status of the order on CoW Explorer. Keep this handy, as we will practice some more with thisorderId
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 thesellToken
. A reminder in this example, thesellToken
iswxDai
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 therelayerAddress
to spend thesellToken
on your behalf.
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)
}