-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: trading API #98
Open
shoom3301
wants to merge
33
commits into
main
Choose a base branch
from
feat/trading-sdk
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
33 commits
Select commit
Hold shift + click to select a range
e227665
feat: trade api getQuote
shoom3301 ef4b64b
refactor: copy trading schemas from sdk
shoom3301 1822ead
refactor: move route path
shoom3301 fdbc4b0
chore: remove generateSchemas call
shoom3301 53868f1
chore: bump cow-sdk
shoom3301 e06f0cd
chore: fux build
shoom3301 4443bf1
chore: up sdk version
shoom3301 bc44fcf
fix: add getQuote error message parsing
shoom3301 bded4e0
feat: add orderTypedData to quote response
shoom3301 7a0b81b
feat(trading): add postOrder method
shoom3301 50de46d
feat: get decimals for trade from erc20 repo
shoom3301 e61b80f
feat(trading): support pre-sign order signing schema
shoom3301 5f5ec0f
fix(trading): return decimals for native token
shoom3301 9f5eeb2
feat(trading): method to get eth-flow transaction
shoom3301 f09ba08
chore: import util from sdk
shoom3301 48a9d5b
refactor: move getPreSignTransaction to sdk
shoom3301 4958895
chore: make NativeCurrencyDecimals map
shoom3301 c374485
fix(trading): define signing scheme explicitly
shoom3301 6117150
chore: bump sdk version
shoom3301 a3ca35a
chore: update schemas
shoom3301 81bdf8c
chore: add advancedSettings to getQuote
shoom3301 8ac2b37
chore: simplify trading api params
shoom3301 c249bce
chore: update docs
shoom3301 3d5a70c
Merge branch 'main' of https://github.com/cowprotocol/bff into feat/t…
shoom3301 15b6ec1
chore: fix build
shoom3301 f4bb9fc
chore: fix build
shoom3301 3061dda
chore: rename endpoints
shoom3301 af371ad
chore: rename quote endpoint
shoom3301 d289f14
chore: rename endpoints
shoom3301 40d87dc
chore: update trading README
shoom3301 8c71a9a
chore: update trading README
shoom3301 2116397
chore: update deps
shoom3301 694375c
Merge branch 'main' of https://github.com/cowprotocol/bff into feat/t…
shoom3301 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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,183 @@ | ||
# CoW Trading API | ||
|
||
|
||
The **CoW Protocol** offers powerful and highly flexible trading capabilities, designed to facilitate complex decentralized finance (DeFi) interactions. However, its flexibility can also make it challenging for developers to interact [directly with the protocol](https://api.cow.fi/docs/#/default/post_api_v1_orders). | ||
|
||
This **CoW Trading API** aims to simplify the interaction by abstracting the complexities. It automatically handles critical aspects such as parameter configuration, accurate calculations for token amounts, and signing orders. | ||
|
||
This API functions as a wrapper around the [`@cowprotocol/cow-sdk`](https://github.com/cowprotocol/cow-sdk/blob/feat/swap-for-people/src/trading/README.md), making it easy to integrate CoW trading into your applications. | ||
|
||
--- | ||
|
||
## Core Features | ||
- **Simplified Order Management:** Abstracts the complexity of preparing, signing, and submitting orders. | ||
- **Native Token Support:** Allows trading Ethereum and other native tokens seamlessly. | ||
- **Smart-Contract Wallet Compatibility:** Includes support for wallets using EIP-1271 presigning. | ||
- **Robust Transaction Handling:** Automatically computes necessary amounts and costs for trades. | ||
|
||
--- | ||
|
||
## 1. **Get Quote** | ||
|
||
The `/quote-requests` method provides a price quote for your desired trade. This includes information necessary to prepare, sign, and submit the order. | ||
|
||
### API Endpoint | ||
**POST** `https://bff.cow.fi/trading/quote-requests` | ||
|
||
### Request Example | ||
|
||
```js | ||
fetch('https://bff.cow.fi/trading/quote-requests', {method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ | ||
trader: { | ||
account: '0xfb3c7eb936cAA12B5A884d612393969A557d4307', | ||
appCode: 'test1', | ||
chainId: 1, | ||
}, | ||
params: { | ||
kind: 'sell', | ||
sellToken: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", | ||
buyToken: "0xdef1ca1fb7fbcdc777520aa7f396b4e015f497ab", | ||
amount: '12000000000000000' | ||
} | ||
})}) | ||
``` | ||
|
||
## 2. Full Trading Flow | ||
|
||
This section demonstrates the complete trading flow, from retrieving a quote to signing and sending an order to the order book. | ||
|
||
### Steps | ||
1. **Get Quote**: Use the `/quote-requests` endpoint to retrieve the trade details. | ||
2. **Sign Order**: Connect your wallet and sign the order using EIP-712 typed data. | ||
3. **Submit Order**: Send the signed order to the order book. | ||
|
||
### Code Example | ||
|
||
```js | ||
(async function() { | ||
const trader = { | ||
account: '0xfb3c7eb936cAA12B5A884d612393969A557d4307', | ||
appCode: 'test1', | ||
chainId: 11155111 | ||
} | ||
const params = { | ||
kind: 'sell', | ||
sellToken: '0xfff9976782d46cc05630d1f6ebab18b2324d6b14', | ||
buyToken: '0x0625afb445c3b6b7b929342a04a22599fd5dbb59', | ||
amount: '100000000000000000' | ||
} | ||
|
||
const callApi = (method, body) => fetch('https://bff.cow.fi/trading/' + method, { | ||
method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) | ||
}).then(res => res.json()) | ||
|
||
// Get quote | ||
const { quoteResponse, orderToSign, orderTypedData, appDataInfo } = await callApi('quote-requests', { trader, params }) | ||
// Connect wallet | ||
const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' }) | ||
// Sign order | ||
const signature = await window.ethereum.request({ | ||
method: 'eth_signTypedData_v4', | ||
params: [accounts[0], JSON.stringify(orderTypedData)] | ||
}) | ||
// Send order | ||
const orderId = await callApi('orders', { | ||
trader, | ||
quoteId: quoteResponse.id, | ||
signature, // Add order typed data signature (EIP-712) | ||
orderToSign, | ||
appDataInfo | ||
}) | ||
|
||
console.log('Order Id:', orderId) | ||
})() | ||
``` | ||
|
||
## 3. Smart-Contract Wallet (EIP-1271 Pre-signing) | ||
|
||
For smart-contract wallets, orders are signed using the [EIP-1271](https://eips.ethereum.org/EIPS/eip-1271) standard. This involves presigning the order and sending a transaction. | ||
|
||
### Code Example | ||
|
||
```js | ||
(async function() { | ||
const trader = { | ||
account: '0xF568A3a2dfFd73C000E8E475B2D335A4A3818EBa', | ||
appCode: 'test1', | ||
chainId: 11155111 | ||
} | ||
const params = { | ||
kind: 'sell', | ||
sellToken: '0xfff9976782d46cc05630d1f6ebab18b2324d6b14', | ||
buyToken: '0x0625afb445c3b6b7b929342a04a22599fd5dbb59', | ||
amount: '100000000000000000' | ||
} | ||
|
||
const callApi = (method, body) => fetch('https://bff.cow.fi/trading/' + method, { | ||
method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) | ||
}).then(res => res.json()) | ||
|
||
// Get quote | ||
const { quoteResponse, orderToSign, appDataInfo } = await callApi('quote-requests', { trader, params }) | ||
// Send order | ||
const { orderId, preSignTransaction } = await callApi('orders', { | ||
trader, | ||
quoteId: quoteResponse.id, | ||
signingScheme: 'presign', // Signal to use pre-signing (smart-contract wallet) | ||
orderToSign, | ||
appDataInfo | ||
}) | ||
|
||
// ACTION NEEDED: Send <preSignTransaction> from smart-contract wallet | ||
|
||
console.log('Order Id:', orderId) | ||
console.log('preSignTransaction:', preSignTransaction) | ||
})() | ||
``` | ||
|
||
## 4. Trading Native Tokens (ETH Flow) | ||
|
||
To trade Ethereum (native token), use the `/sell-native-currency-requests` method, which generates a transaction object for direct submission to the network. | ||
|
||
### Code Example | ||
|
||
```js | ||
(async function() { | ||
const trader = { | ||
account: '0xfb3c7eb936cAA12B5A884d612393969A557d4307', | ||
appCode: 'test1', | ||
chainId: 11155111 | ||
} | ||
const params = { | ||
kind: 'sell', | ||
sellToken: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', | ||
buyToken: '0x0625afb445c3b6b7b929342a04a22599fd5dbb59', | ||
amount: '100000000000000000' | ||
} | ||
|
||
const callApi = (method, body) => fetch('https://bff.cow.fi/trading/' + method, { | ||
method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) | ||
}).then(res => res.json()) | ||
|
||
// Get quote | ||
const { quoteResponse, orderTypedData, appDataInfo, amountsAndCosts, tradeParameters } = await callApi('quote-requests', { trader, params }) | ||
// Get transaction | ||
const { orderId, transaction } = await callApi('sell-native-currency-requests', { | ||
trader, | ||
quoteId: quoteResponse.id, | ||
tradeParameters, | ||
amountsAndCosts, | ||
appDataInfo, | ||
}) | ||
// Connect wallet | ||
const [account] = await window.ethereum.request({ method: 'eth_requestAccounts' }) | ||
// Send transaction | ||
const txHash = await window.ethereum.request({ | ||
method: 'eth_sendTransaction', | ||
params: [{ ...transaction, from: account }] | ||
}) | ||
|
||
console.log('txHash:', txHash) | ||
console.log('orderId:', 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,59 @@ | ||
import { FastifyPluginAsync } from 'fastify'; | ||
|
||
import { FromSchema } from 'json-schema-to-ts'; | ||
import { apiContainer } from '../../inversify.config'; | ||
import { | ||
TradingService, | ||
tradingServiceSymbol | ||
} from '@cowprotocol/services'; | ||
|
||
import { errorSchema, ethFlowTxBodySchema, ethFlowTxSuccessSchema } from './schemas'; | ||
import { getErrorMessage } from './utils'; | ||
import { deserializeQuoteAmountsAndCosts } from './mapQuoteAmountsAndCosts'; | ||
|
||
type SuccessSchema = FromSchema<typeof ethFlowTxSuccessSchema>; | ||
type BodySchema = FromSchema<typeof ethFlowTxBodySchema>; | ||
type ErrorSchema = FromSchema<typeof errorSchema>; | ||
|
||
const tradingService: TradingService = apiContainer.get( | ||
tradingServiceSymbol | ||
); | ||
|
||
const root: FastifyPluginAsync = async (fastify): Promise<void> => { | ||
fastify.post<{ | ||
Reply: SuccessSchema | ErrorSchema; | ||
Body: BodySchema; | ||
}>( | ||
'/sell-native-currency-requests', | ||
{ | ||
schema: { | ||
body: ethFlowTxBodySchema, | ||
response: { | ||
'2XX': ethFlowTxSuccessSchema, | ||
'400': errorSchema, | ||
}, | ||
}, | ||
}, | ||
async function (request, reply) { | ||
const { trader, amountsAndCosts, quoteId, tradeParameters, appDataInfo } = request.body | ||
|
||
try { | ||
const result = await tradingService.getEthFlowTransaction( | ||
trader, | ||
quoteId, | ||
tradeParameters as Parameters<typeof tradingService.getEthFlowTransaction>[2], | ||
deserializeQuoteAmountsAndCosts(amountsAndCosts), | ||
appDataInfo, | ||
); | ||
|
||
reply.send(result); | ||
} catch (e) { | ||
const errorMessage = getErrorMessage(e) | ||
console.error('[Trading API] getEthFlowTransaction error', errorMessage) | ||
reply.code(500).send({ message: errorMessage }); | ||
} | ||
} | ||
); | ||
}; | ||
|
||
export default root; |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not adding the code to send the TX onhcain?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It very depends on a smart-contract wallet implementation.
With Safe it requires a lot of code here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For Safe you can go to Transaction build and put the tx data there