-
Notifications
You must be signed in to change notification settings - Fork 10
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
21 changed files
with
726 additions
and
558 deletions.
There are no files selected for viewing
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
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,50 @@ | ||
import { OrderKind, SupportedChainId, SwapParameters } from '../../../src' | ||
import { TOKENS } from './tokens' | ||
|
||
const appCode = 'trade-sdk-example' | ||
|
||
interface FormState { | ||
privateKey: string | ||
chainId: string | ||
sellToken: string | ||
buyToken: string | ||
amount: string | ||
slippageBps: string | ||
kind: 'sell' | 'buy' | ||
} | ||
|
||
export const getFormState = (): FormState => { | ||
return Object.fromEntries(new FormData(document.getElementById('form') as HTMLFormElement)) as unknown as FormState | ||
} | ||
|
||
export const getSwapParameters = (): SwapParameters => { | ||
const { | ||
privateKey, | ||
slippageBps: _slippageBps, | ||
chainId: _chainId, | ||
sellToken: _sellToken, | ||
buyToken: _buyToken, | ||
amount: _amount, | ||
kind, | ||
} = getFormState() | ||
|
||
const chainId: SupportedChainId = +_chainId | ||
const isSell = kind === 'sell' | ||
const sellToken = TOKENS[chainId].find((t) => t.address === _sellToken) | ||
const buyToken = TOKENS[chainId].find((t) => t.address === _buyToken) | ||
const amount = BigInt(_amount) * BigInt(10 ** (isSell ? sellToken.decimals : buyToken.decimals)) | ||
const slippageBps = _slippageBps ? +_slippageBps : undefined | ||
|
||
return { | ||
appCode, | ||
signer: privateKey, | ||
chainId, | ||
sellToken: sellToken.address, | ||
sellTokenDecimals: sellToken.decimals, | ||
buyToken: buyToken.address, | ||
buyTokenDecimals: buyToken.decimals, | ||
amount: amount.toString(), | ||
slippageBps, | ||
kind: isSell ? OrderKind.SELL : OrderKind.BUY, | ||
} | ||
} |
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 |
---|---|---|
@@ -1,18 +1,84 @@ | ||
import { OrderBookApi, SubgraphApi, SupportedChainId } from '@cowprotocol/cow-sdk' | ||
import { SupportedChainId, getQuote, UnsignedOrder } from '../../../src' | ||
|
||
// See more examples in /examples/cra | ||
import { getOrderToSignFromQuoteResult, swapParamsToLimitOrderParams, postCoWProtocolTrade } from '../../../src/trading' | ||
|
||
import { TOKENS } from './tokens' | ||
import { atomsToAmount } from './utils' | ||
import { pageHtml } from './pageHtml' | ||
import { pageActions, printResult } from './pageActions' | ||
import { GetQuoteResult } from '../../../src/trading/getQuote' | ||
import { getFormState, getSwapParameters } from './formState' | ||
import './styles.css' | ||
|
||
// Run the example | ||
;(async function () { | ||
const orderBookApi = new OrderBookApi({ chainId: SupportedChainId.MAINNET }) | ||
let getQuoteResult: GetQuoteResult | null = null | ||
|
||
// Render page | ||
const page = pageHtml() | ||
document.body.appendChild(page) | ||
|
||
// Bind actions to the page | ||
pageActions({ | ||
onFormReset() { | ||
getQuoteResult = null | ||
}, | ||
async onGetQuote() { | ||
const { | ||
slippageBps: _slippageBps, | ||
chainId: _chainId, | ||
sellToken: _sellToken, | ||
buyToken: _buyToken, | ||
amount: _amount, | ||
kind, | ||
} = getFormState() | ||
|
||
const chainId: SupportedChainId = +_chainId | ||
const isSell = kind === 'sell' | ||
const sellToken = TOKENS[chainId].find((t) => t.address === _sellToken) | ||
const buyToken = TOKENS[chainId].find((t) => t.address === _buyToken) | ||
|
||
getQuoteResult = await getQuote(getSwapParameters()) | ||
|
||
const { | ||
amountsAndCosts: { beforeNetworkCosts, afterSlippage }, | ||
} = getQuoteResult | ||
|
||
console.log('Quote results:', getQuoteResult) | ||
|
||
const outputToken = isSell ? buyToken : sellToken | ||
|
||
const order = await orderBookApi.getOrder( | ||
'0xff2e2e54d178997f173266817c1e9ed6fee1a1aae4b43971c53b543cffcc2969845c6f5599fbb25dbdd1b9b013daf85c03f3c63763e4bc4a' | ||
) | ||
printResult(` | ||
Quote amount: ${atomsToAmount( | ||
beforeNetworkCosts[isSell ? 'buyAmount' : 'sellAmount'], | ||
outputToken.decimals | ||
)} ${outputToken.symbol} | ||
Amount to sign: ${atomsToAmount( | ||
afterSlippage[isSell ? 'buyAmount' : 'sellAmount'], | ||
outputToken.decimals | ||
)} ${outputToken.symbol} | ||
See more info in the console (Quote results) | ||
`) | ||
}, | ||
async onConfirmOrder() { | ||
const orderToSign = await getOrderToSignFromQuoteResult(getQuoteResult, getSwapParameters()) | ||
|
||
const orderElement = document.createElement('textarea') | ||
printResult(` | ||
You are going to sign: | ||
${JSON.stringify(orderToSign, null, 4)} | ||
`) | ||
}, | ||
async onSignAndSendOrder() { | ||
const { orderBookApi, signer, appDataInfo, quoteResponse } = getQuoteResult | ||
|
||
orderElement.value = JSON.stringify({ order }, null, 4) | ||
orderElement.style.minWidth = '950px' | ||
orderElement.style.minHeight = '800px' | ||
const orderId = await postCoWProtocolTrade( | ||
orderBookApi, | ||
signer, | ||
appDataInfo, | ||
swapParamsToLimitOrderParams(getSwapParameters(), quoteResponse) | ||
) | ||
|
||
document.body.appendChild(orderElement) | ||
printResult(`Order created, id: ${orderId}`) | ||
}, | ||
}) | ||
})() |
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,96 @@ | ||
import { tokensSelect } from './pageHtml' | ||
|
||
const sendOrderText = 'Send order' | ||
|
||
interface Actions { | ||
onFormReset(): void | ||
onGetQuote(): Promise<void> | ||
onConfirmOrder(): Promise<void> | ||
onSignAndSendOrder(): Promise<void> | ||
} | ||
|
||
export function pageActions(actions: Actions) { | ||
onFormReset(actions.onFormReset) | ||
onNetworkChange() | ||
onGetQuote(actions) | ||
} | ||
|
||
export function printResult(text: string) { | ||
const resultsEl = document.getElementById('results')! as HTMLTextAreaElement | ||
|
||
resultsEl.value = text | ||
.split('\n') | ||
.map((t) => t.trim()) | ||
.join('\n') | ||
} | ||
|
||
function onFormReset(callback: () => void) { | ||
document.getElementById('form')?.addEventListener('change', () => { | ||
printResult('') | ||
|
||
document.getElementById('sendOrder').innerText = sendOrderText | ||
callback() | ||
}) | ||
} | ||
|
||
function onNetworkChange() { | ||
document.getElementById('chainId').addEventListener('change', (event) => { | ||
const chainId = +(event.target as unknown as { value: string }).value | ||
|
||
document.getElementById('sellToken')!.parentElement.innerHTML = tokensSelect(chainId, 'sellToken') | ||
document.getElementById('buyToken')!.parentElement.innerHTML = tokensSelect(chainId, 'buyToken') | ||
}) | ||
} | ||
|
||
function onGetQuote(actions: Actions) { | ||
document.getElementById('getQuote').addEventListener('click', (event) => { | ||
event.preventDefault() | ||
|
||
printResult('Loading...') | ||
|
||
const sendOrderEl = document.getElementById('sendOrder') | ||
|
||
sendOrderEl.innerText = sendOrderText | ||
|
||
actions.onFormReset() | ||
|
||
actions | ||
.onGetQuote() | ||
.then(() => { | ||
const sendOrderEl = document.getElementById('sendOrder') as HTMLButtonElement | ||
|
||
sendOrderEl.style.display = 'inline-block' | ||
|
||
sendOrderEl.addEventListener('click', async (event) => { | ||
event.preventDefault() | ||
|
||
sendOrderEl.disabled = true | ||
sendOrderEl.innerText = 'Loading...' | ||
|
||
try { | ||
if (sendOrderEl.innerText === sendOrderText) { | ||
await actions.onConfirmOrder() | ||
|
||
sendOrderEl.innerText = 'Sign and send' | ||
} else { | ||
await actions.onSignAndSendOrder() | ||
|
||
sendOrderEl.innerText = sendOrderText | ||
sendOrderEl.style.display = 'none' | ||
} | ||
} catch (error) { | ||
printError(error) | ||
} finally { | ||
sendOrderEl.disabled = false | ||
} | ||
}) | ||
}) | ||
.catch((error) => { | ||
printError(error) | ||
}) | ||
}) | ||
} | ||
|
||
function printError(error: any) { | ||
printResult(JSON.stringify(error.body || error.message || error.toString(), null, 4)) | ||
} |
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 @@ | ||
import { ALL_SUPPORTED_CHAIN_IDS, SupportedChainId } from '../../../src' | ||
import { TOKENS } from './tokens' | ||
|
||
const chainId = SupportedChainId.MAINNET | ||
|
||
export const tokensSelect = (chainId: SupportedChainId, name: string) => | ||
`<select name="${name}" id="${name}"> | ||
${TOKENS[chainId].map((token) => `<option value="${token.address}">${token.symbol}</option>`)} | ||
</select>` | ||
|
||
export function pageHtml() { | ||
const page = document.createElement('div') | ||
|
||
const networksSelect = () => | ||
`<select name="chainId" id="chainId"> | ||
${ALL_SUPPORTED_CHAIN_IDS.map((chainId) => `<option value="${chainId}">${chainId}</option>`)} | ||
</select>` | ||
|
||
page.innerHTML = ` | ||
<table id="layout"> | ||
<tr> | ||
<td> | ||
<form id="form"> | ||
<h3>Swap</h3> | ||
<div> | ||
<label for="privateKey">Private key</label> | ||
<div><input name="privateKey"/></div> | ||
</div> | ||
<div> | ||
<label for="chainId">Network</label> | ||
<div>${networksSelect()}</div> | ||
</div> | ||
<div> | ||
<label for="sellToken">Sell token</label> | ||
<div>${tokensSelect(chainId, 'sellToken')}</div> | ||
</div> | ||
<div> | ||
<label for="sellToken">Buy token</label> | ||
<div>${tokensSelect(chainId, 'buyToken')}</div> | ||
</div> | ||
<div> | ||
<label for="amount">Amount</label> | ||
<div><input name="amount" value="20"/></div> | ||
</div> | ||
<div> | ||
<label for="slippageBps">Slippage (BPS)</label> | ||
<div><input name="slippageBps" type="number"/></div> | ||
</div> | ||
<div> | ||
<label for="kind">Type</label> | ||
<div> | ||
<select name="kind"> | ||
<option value="sell">Sell</option> | ||
<option value="buy">Buy</option> | ||
</select> | ||
</div> | ||
</div> | ||
<div> | ||
<button id="getQuote">Get quote</button> | ||
<button id="sendOrder">Send order</button> | ||
</div> | ||
</form> | ||
</td> | ||
<td> | ||
<h4>Result:</h4> | ||
<textarea id="results" disabled></textarea> | ||
</td> | ||
</tr> | ||
</table> | ||
` | ||
|
||
return page | ||
} |
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,41 @@ | ||
#layout { | ||
margin: 0 auto; | ||
} | ||
|
||
#layout td { | ||
vertical-align: top; | ||
} | ||
|
||
#form { | ||
min-width: 400px; | ||
} | ||
|
||
#form > div { | ||
border: 1px solid #d4d9de; | ||
margin: 10px; | ||
padding: 10px; | ||
} | ||
|
||
#form input, #form select { | ||
width: 100%; | ||
box-sizing: border-box; | ||
} | ||
|
||
#form button { | ||
background: #282c34; | ||
color: #fff; | ||
font-size: 18px; | ||
padding: 5px 10px; | ||
cursor: pointer; | ||
border: 0; | ||
border-radius: 4px; | ||
} | ||
|
||
#results { | ||
min-height: 400px; | ||
min-width: 600px; | ||
} | ||
|
||
#sendOrder { | ||
display: none; | ||
} |
Oops, something went wrong.