Skip to content

Commit 6492349

Browse files
committed
feat: Bitcoin docs
1 parent e57849a commit 6492349

File tree

5 files changed

+173
-209
lines changed

5 files changed

+173
-209
lines changed

src/content/docs/cross-cats/Becoming a Solver/evm-orders.mdx

Lines changed: 0 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -213,161 +213,6 @@ function reconnect() {
213213
connectToOrderServer();
214214
```
215215

216-
### Evaluate Orders
217-
218-
After fetching an order, the solver must thoroughly evaluate it to determine its viability and potential execution. To facilitate this evaluation, several contextual pointers are available within the returned order data. Key aspects to consider include:
219-
220-
1. **Quote Validation**: Use the `OrderDto.quote` field to access the price context, which provides the pricing details for the inputs and outputs of the order. If you trust the order server, you can primarily rely on this quote to validate the order’s pricing. However, it’s crucial to verify that the solver supports the specific origin chain (`OrderDto.order.originChainId`) and output chains (`OrderDto.order.orderData.outputs[...].chainId`) as well as their respective tokens (`input[].token` and `output[].token`). These parameters are guaranteed to be present across all order types.
221-
222-
2. **Solver-Exclusive Orders**: Some orders may initially be restricted to specific solvers. This is indicated by the `OrderDto.order.orderData.verificationContract` field. If this field is defined and not equal to `address(0)`, the order is exclusive to the designated solver until the `slopeStartingTime` elapses, after which the order becomes available for anyone to fulfill.
223-
224-
3. **Mutually Exclusive Orders**: Be aware of potential conflicts between orders. If you encounter two orders with the same `OrderDto.order.swapper` and `OrderDto.order.nonce`, these orders are mutually exclusive, meaning only one of them can be submitted on-chain. This mechanism prevents double submissions and ensures the integrity of the order processing.
225-
226-
Evaluating orders carefully ensures that solvers can accurately determine the feasibility of executing an order, adhere to exclusivity rules, and avoid conflicts, thereby maintaining the integrity and efficiency of the order fulfillment process.
227-
228-
### Initiate Orders
229-
230-
Once an order has been fetched and validated, the next step is to submit it on-chain. Catalyst Orders are accompanied by a signature (`OrderDto.signature`) that serves a dual purpose:
231-
232-
1. **Permit2 Signature**: This signature acts as a Permit2, authorizing the Catalyst contracts to withdraw the submitter's tokens directly. This streamlines the process by eliminating the need for separate approval transactions.
233-
234-
2. **User Authorization**: The signature also confirms that the user has approved the order, ensuring consent and alignment with the terms of execution.
235-
236-
Orders are processed on a first-come, first-served basis, emphasizing the importance of swift submission to secure the desired transaction. By leveraging the Permit2 signature mechanism, Catalyst simplifies the initiation process, reducing overhead and ensuring seamless order execution.
237-
238-
<Tabs syncKey="lang">
239-
<TabItem label="Typescript">
240-
241-
```typescript
242-
// This tutorial uses ethersjs but you can easily replace it by similar libraries.
243-
import { ethers } from "ethers";
244-
245-
const reactorAbi = "...";
246-
const signer = "ethers.signer...";
247-
248-
async function initiateOrder() {
249-
// Get an order
250-
const orders = await getOrders();
251-
const order = orders.orders[0];
252-
253-
// Define the reactor we will call. You can get the reactor address from the order
254-
const reactorAddress = order.order.settlementContract;
255-
const reactor = new ethers.Contract(reactorAddress, reactorAbi, signer);
256-
257-
// TODO: Set approvals for the reactorAddress for all inputs & collateral.
258-
259-
// The order arrives almost ready to use,
260-
// we just need to remove the type from the orderdata.
261-
const { type: _, ...cleanedOrderData } = order.order.orderData;
262-
const cleanedOrder = { ...order.order, orderData: cleanedOrderData };
263-
const signature = order.signature;
264-
const fillerData = "0x"; // #custom-fillerdata--underwriting
265-
266-
// Call the reactor to initiate the order.
267-
return reactor.initiate(cleanedOrder, signature, fillerData);
268-
}
269-
```
270-
271-
</TabItem>
272-
<TabItem label="Python">
273-
274-
```python
275-
from web3 import Web3
276-
277-
rpc_url = ""
278-
web3 = Web3(Web3.HTTPProvider(eth_node_url))
279-
280-
# Your ABI and signer details
281-
reactor_abi = "..."
282-
signer_private_key = "your_private_key_here"
283-
signer_address = web3.eth.account.from_key(signer_private_key).address
284-
285-
def initiate_order():
286-
# Get an order
287-
orders = get_orders()
288-
order = orders['orders'][0]
289-
290-
# Define the reactor we will call. You can get the reactor address from the order
291-
reactor_address = order['order']['settlementContract']
292-
reactor = web3.eth.contract(address=reactor_address, abi=reactor_abi)
293-
294-
# TODO: Set approvals for the reactorAddress for all inputs & collateral.
295-
# This will depend on the specific ERC20 tokens you're using,
296-
# you need to call approve() on the ERC20 token contracts
297-
298-
# Clean the order data by removing the type field
299-
cleaned_order_data = order['order']['orderData'].copy()
300-
cleaned_order_data.pop('type')
301-
cleaned_order = {**order['order'], 'orderData': cleaned_order_data}
302-
signature = order['signature']
303-
filler_data = "0x" # #custom-fillerdata--underwriting
304-
305-
# Build the transaction
306-
txn = reactor.functions.initiate(cleaned_order, signature, filler_data).build_transaction({
307-
'from': signer_address,
308-
'nonce': web3.eth.get_transaction_count(signer_address)
309-
})
310-
# Sign the transaction
311-
signed_txn = web3.eth.account.sign_transaction(txn, private_key=signer_private_key)
312-
# Send the transaction
313-
tx_hash = web3.eth.send_raw_transaction(signed_txn.rawTransaction)
314-
# Wait for the transaction receipt
315-
receipt = web3.eth.wait_for_transaction_receipt(tx_hash)
316-
return receipt
317-
```
318-
319-
</TabItem>
320-
</Tabs>
321-
322-
#### Custom FillerData & Underwriting
323-
324-
By default, if `fillerData` is not specified, the input assets (provided by the user) are sent directly to the caller. This behavior is generally suitable for most use cases, eliminating the need for additional customization.
325-
326-
However, if there is a need to direct the input assets to another address or to enable underwriting, a customized `fillerData` must be utilized. Currently, only one custom version (`v1`) is supported. The `v1` structure includes:
327-
328-
- **Version Byte (0x01)**: Identifies the custom data version.
329-
- **fillerAddress**: The address that will receive the input assets and collateral.
330-
- **orderPurchaseDeadline**: A timestamp that allows an alternative buyer to purchase the order before this time. "Buying" the order in this context means transferring all of the input assets and collateral to the `fillerAddress`.
331-
- **orderDiscount**: Provides buyers with a discount on the inputs, represented as a fraction of 2^16 - 1. For example, to offer a 1% discount, the value would be calculated as `0.01 * (2^16 - 1) = 655`. This feature is particularly useful for chains with slower block confirmations (e.g., Bitcoin), enabling the solver to be paid after 0-1 confirmations while assuring the user of higher finality (3-6 confirmations).
332-
333-
<Tabs syncKey="lang">
334-
<TabItem label="Typescript">
335-
336-
```typescript
337-
const fillerDataVersion = "0x01";
338-
const fillerAddress = "0x....".replace("0x", "");
339-
// fillerAddress.length === 20*2;
340-
const orderPurchaseDeadline = Number(1723199919)
341-
.toString(16)
342-
.padStart("0", 4 * 2);
343-
//orderPurchaseDeadline.length === 4*2
344-
const orderDiscount = Math.floor(0.01 * (2 ** 16 - 1))
345-
.toString(16)
346-
.padStart("0", 2 * 2);
347-
// orderDiscount.length === 2*2
348-
349-
const fillerData =
350-
fillerDataVersion + fillerAddress + orderPurchaseDeadline + orderDiscount;
351-
```
352-
353-
</TabItem>
354-
<TabItem label="Python">
355-
356-
```python
357-
fillerDataVersion = "0x01";
358-
fillerAddress = '0x....'.replace("0x", "");
359-
# len(fillerAddress) === 20*2;
360-
orderPurchaseDeadline = hex(1723199919).replace("0x", "").zfill(4*2);
361-
# len(orderPurchaseDeadline) === 4*2
362-
const orderDiscount = hex(int(0.01*(2**16-1))).replace("0x", "").zfill(2*2);
363-
# len(orderDiscount) === 2*2
364-
365-
fillerData = fillerDataVersion + fillerAddress + orderPurchaseDeadline + orderDiscount;
366-
```
367-
368-
</TabItem>
369-
</Tabs>
370-
371216
## Delivery
372217

373218
The delivery of assets varies based on the destination type: VM chains or Bitcoin.

src/content/docs/cross-cats/Becoming a Solver/introduction.mdx

Lines changed: 156 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: "Introduction to solving"
2+
title: "Solving for Cross Cats"
33
description: "Cross Cats allows solvers to collect order flow to and from various VM chains and to and from Bitcoin. Compared to competing solution, capital hungry solvers can improve their capital turnaround by using the underwriting network to their advantage."
44
sidebar:
55
order: 3
@@ -89,3 +89,158 @@ struct OutputDescription {
8989
Users generate a `CrossChainOrder` with the appropriate order data and sign it as a Permit2 witness, thereby approving both the order description and its associated inputs with a single signature. The signed struct will be a new structure where `orderData` is an ABI-encoded order type.
9090

9191
Cross Cats has directionality. That means the ways orders are initiated depends on the initiating chain (where the user is swapping out of). In the current iteration, there are 2 important origin types: EVM and Bitcoin. In the future, all virtual machine chains (including EVM) will generally be initiated similarly and all non-VM chains (including Bitcoin) will be initiated similarly but different from VM chains.
92+
93+
### Evaluate Orders
94+
95+
After fetching an order, the solver must thoroughly evaluate it to determine its viability and potential execution. To facilitate this evaluation, several contextual pointers are available within the returned order data. Key aspects to consider include:
96+
97+
1. **Quote Validation**: Use the `OrderDto.quote` field to access the price context, which provides the pricing details for the inputs and outputs of the order. If you trust the order server, you can primarily rely on this quote to validate the order’s pricing. However, it’s crucial to verify that the solver supports the specific origin chain (`OrderDto.order.originChainId`) and output chains (`OrderDto.order.orderData.outputs[...].chainId`) as well as their respective tokens (`input[].token` and `output[].token`). These parameters are guaranteed to be present across all order types.
98+
99+
2. **Solver-Exclusive Orders**: Some orders may initially be restricted to specific solvers. This is indicated by the `OrderDto.order.orderData.verificationContract` field. If this field is defined and not equal to `address(0)`, the order is exclusive to the designated solver until the `slopeStartingTime` elapses, after which the order becomes available for anyone to fulfill.
100+
101+
3. **Mutually Exclusive Orders**: Be aware of potential conflicts between orders. If you encounter two orders with the same `OrderDto.order.swapper` and `OrderDto.order.nonce`, these orders are mutually exclusive, meaning only one of them can be submitted on-chain. This mechanism prevents double submissions and ensures the integrity of the order processing.
102+
103+
Evaluating orders carefully ensures that solvers can accurately determine the feasibility of executing an order, adhere to exclusivity rules, and avoid conflicts, thereby maintaining the integrity and efficiency of the order fulfillment process.
104+
105+
### Initiate Orders
106+
107+
Once an order has been fetched and validated, the next step is to submit it on-chain. Catalyst Orders are accompanied by a signature (`OrderDto.signature`) that serves a dual purpose:
108+
109+
1. **Permit2 Signature**: This signature acts as a Permit2, authorizing the Catalyst contracts to withdraw the submitter's tokens directly. This streamlines the process by eliminating the need for separate approval transactions.
110+
111+
2. **User Authorization**: The signature also confirms that the user has approved the order, ensuring consent and alignment with the terms of execution.
112+
113+
Orders are processed on a first-come, first-served basis, emphasizing the importance of swift submission to secure the desired transaction. By leveraging the Permit2 signature mechanism, Catalyst simplifies the initiation process, reducing overhead and ensuring seamless order execution.
114+
115+
<Tabs syncKey="lang">
116+
<TabItem label="Typescript">
117+
118+
```typescript
119+
// This tutorial uses ethersjs but you can easily replace it by similar libraries.
120+
import { ethers } from "ethers";
121+
122+
const reactorAbi = "...";
123+
const signer = "ethers.signer...";
124+
125+
async function initiateOrder() {
126+
// Get an order
127+
const orders = await getOrders();
128+
const order = orders.orders[0];
129+
130+
// Define the reactor we will call. You can get the reactor address from the order
131+
const reactorAddress = order.order.settlementContract;
132+
const reactor = new ethers.Contract(reactorAddress, reactorAbi, signer);
133+
134+
// TODO: Set approvals for the reactorAddress for all inputs & collateral.
135+
136+
// The order arrives almost ready to use,
137+
// we just need to remove the type from the orderdata.
138+
const { type: _, ...cleanedOrderData } = order.order.orderData;
139+
const cleanedOrder = { ...order.order, orderData: cleanedOrderData };
140+
const signature = order.signature;
141+
const fillerData = "0x"; // #custom-fillerdata--underwriting
142+
143+
// Call the reactor to initiate the order.
144+
return reactor.initiate(cleanedOrder, signature, fillerData);
145+
}
146+
```
147+
148+
</TabItem>
149+
<TabItem label="Python">
150+
151+
```python
152+
from web3 import Web3
153+
154+
rpc_url = ""
155+
web3 = Web3(Web3.HTTPProvider(eth_node_url))
156+
157+
# Your ABI and signer details
158+
reactor_abi = "..."
159+
signer_private_key = "your_private_key_here"
160+
signer_address = web3.eth.account.from_key(signer_private_key).address
161+
162+
def initiate_order():
163+
# Get an order
164+
orders = get_orders()
165+
order = orders['orders'][0]
166+
167+
# Define the reactor we will call. You can get the reactor address from the order
168+
reactor_address = order['order']['settlementContract']
169+
reactor = web3.eth.contract(address=reactor_address, abi=reactor_abi)
170+
171+
# TODO: Set approvals for the reactorAddress for all inputs & collateral.
172+
# This will depend on the specific ERC20 tokens you're using,
173+
# you need to call approve() on the ERC20 token contracts
174+
175+
# Clean the order data by removing the type field
176+
cleaned_order_data = order['order']['orderData'].copy()
177+
cleaned_order_data.pop('type')
178+
cleaned_order = {**order['order'], 'orderData': cleaned_order_data}
179+
signature = order['signature']
180+
filler_data = "0x" # #custom-fillerdata--underwriting
181+
182+
# Build the transaction
183+
txn = reactor.functions.initiate(cleaned_order, signature, filler_data).build_transaction({
184+
'from': signer_address,
185+
'nonce': web3.eth.get_transaction_count(signer_address)
186+
})
187+
# Sign the transaction
188+
signed_txn = web3.eth.account.sign_transaction(txn, private_key=signer_private_key)
189+
# Send the transaction
190+
tx_hash = web3.eth.send_raw_transaction(signed_txn.rawTransaction)
191+
# Wait for the transaction receipt
192+
receipt = web3.eth.wait_for_transaction_receipt(tx_hash)
193+
return receipt
194+
```
195+
196+
</TabItem>
197+
</Tabs>
198+
199+
#### Custom FillerData & Underwriting
200+
201+
By default, if `fillerData` is not specified, the input assets (provided by the user) are sent directly to the caller. This behavior is generally suitable for most use cases, eliminating the need for additional customization.
202+
203+
However, if there is a need to direct the input assets to another address or to enable underwriting, a customized `fillerData` must be utilized. Currently, only one custom version (`v1`) is supported. The `v1` structure includes:
204+
205+
- **Version Byte (0x01)**: Identifies the custom data version.
206+
- **fillerAddress**: The address that will receive the input assets and collateral.
207+
- **orderPurchaseDeadline**: A timestamp that allows an alternative buyer to purchase the order before this time. "Buying" the order in this context means transferring all of the input assets and collateral to the `fillerAddress`.
208+
- **orderDiscount**: Provides buyers with a discount on the inputs, represented as a fraction of 2^16 - 1. For example, to offer a 1% discount, the value would be calculated as `0.01 * (2^16 - 1) = 655`. This feature is particularly useful for chains with slower block confirmations (e.g., Bitcoin), enabling the solver to be paid after 0-1 confirmations while assuring the user of higher finality (3-6 confirmations).
209+
210+
<Tabs syncKey="lang">
211+
<TabItem label="Typescript">
212+
213+
```typescript
214+
const fillerDataVersion = "0x01";
215+
const fillerAddress = "0x....".replace("0x", "");
216+
// fillerAddress.length === 20*2;
217+
const orderPurchaseDeadline = Number(1723199919)
218+
.toString(16)
219+
.padStart("0", 4 * 2);
220+
//orderPurchaseDeadline.length === 4*2
221+
const orderDiscount = Math.floor(0.01 * (2 ** 16 - 1))
222+
.toString(16)
223+
.padStart("0", 2 * 2);
224+
// orderDiscount.length === 2*2
225+
226+
const fillerData =
227+
fillerDataVersion + fillerAddress + orderPurchaseDeadline + orderDiscount;
228+
```
229+
230+
</TabItem>
231+
<TabItem label="Python">
232+
233+
```python
234+
fillerDataVersion = "0x01";
235+
fillerAddress = '0x....'.replace("0x", "");
236+
# len(fillerAddress) === 20*2;
237+
orderPurchaseDeadline = hex(1723199919).replace("0x", "").zfill(4*2);
238+
# len(orderPurchaseDeadline) === 4*2
239+
const orderDiscount = hex(int(0.01*(2**16-1))).replace("0x", "").zfill(2*2);
240+
# len(orderDiscount) === 2*2
241+
242+
fillerData = fillerDataVersion + fillerAddress + orderPurchaseDeadline + orderDiscount;
243+
```
244+
245+
</TabItem>
246+
</Tabs>

src/content/docs/cross-cats/Becoming a Solver/solver copy.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
title: "Becoming a Cross Cats solver"
33
description: "Cross Cats allows solvers to collect order flow to and from various VM chains and to and from Bitcoin. Compared to competing solution, capital hungry solvers can improve their capital turnaround by using the underwriting network to their advantage."
44
sidebar:
5-
order: 3
5+
order: 1000000
66
---
77

88
import { Tabs, TabItem } from "@astrojs/starlight/components";

0 commit comments

Comments
 (0)