Skip to content

Commit

Permalink
feat: second version of documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
reednaa committed Oct 1, 2024
1 parent 7d07c3c commit d301853
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 917 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@ sidebar:

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

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

### Bitcoin Deliveries

To determine whether an order involves a Bitcoin transaction, check the `GetOrderData.order.orderData.outputs[].token` field. If the token indicates Bitcoin, ensure the following conditions are met:

- The first 30 bytes of the token should be `0x000000000000000000000000BC0000000000000000000000000000000000`. The 13th byte is `0xBC`.
Expand Down Expand Up @@ -106,4 +102,4 @@ The following guidelines assume you are implementing this from the perspective o
- **Nested Witness Addresses/Outputs**:
- These are **P2SH** addresses and should be treated like any other **P2SH** address.

Once the address is generated, create a Bitcoin transaction with at least one output that **exactly** matches the described output from the initiated order. The transaction can have any number of inputs and outputs, as long as one output precisely matches the one specified by the order's output. This flexibility allows for batch filling, consolidation, and more. While having multiple matching outputs is permitted, it benefits only the user to ensure the order’s conditions are met.
Once the address is generated, create a Bitcoin transaction with at least one output that **exactly** matches the described output from the initiated order. The transaction can have any number of inputs and outputs, as long as one output precisely matches the one specified by the order's output. This flexibility allows for batch filling, consolidation, and more.
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ On VM chains, assets can be pulled from users via approvals – a feature not av

The simplest way to collect orderflow from EVM is via polling. The order server stores orders in a dictionary format, allowing for straightforward parsing by integrators and provides a high level of transparency in the implementation.

:::tip[Only order originating from a VM chains can be pulled]
The order server only stores user signed orders. Since users can only sign order originating from VM chains, orders originating from non-vm chains – including from Bitcoin – cannot be polled.
:::tip[Only order originating from VM chains can be pulled]
The order server only stores user signed orders. Since users can only sign order originating from VM chains, orders originating from non-vm chains – including from Bitcoin – cannot be pulled.
:::

<Tabs syncKey="lang">
<TabItem label="Typescript">

```typescript
// The type parameter (DutchAuctionData.type) should not be submitted on-chain but can be used to differentiate order types.
// The type parameter (DutchAuctionData.type) is not be submitted on-chain but is used to differentiate order types.
type DutchAuctionData = {
type: "DutchAuction"; // Not to be submitted
verificationContext: string;
Expand Down Expand Up @@ -134,7 +134,7 @@ Instead of polling for new orders, you can establish a WebSocket connection to t
Below is a simplified implementation in pure JavaScript that demonstrates how to connect to the WebSocket server, handle incoming messages, respond to ping events, and automatically attempt to reconnect if the connection is lost.

:::caution[Quote requests are optional but required for BTC to USDC]
It is optional to implement handle the `quote-request` and `quote-request-binding` event, however, if you want to solve BTC to USDC you have to respond to the `quote-request-binding` event. The response you make to this event is binding for 30 seconds. If you receive a message with the event `non-vm-order` you have to fill it – by filling empty slots & signing it – or you may get blacklisted.
It is optional to handle `quote-request` and `quote-request-binding` event, however, if you want to solve BTC to USDC you have to respond to the `quote-request-binding` event. The response you make to this event is binding for 30 seconds. If you receive a message with the event `non-vm-order` you have to fill it – by correcting empty slots & signing it – or you may get blacklisted.
:::

(TODO update typescript block)
Expand Down
82 changes: 46 additions & 36 deletions src/content/docs/cross-cats/Becoming a Solver/init-orders.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ There are 2 different initiation paths, EVM and Bitcoin. Generally, all orders h

## EVM initiation

After collecting order – either through pulling or websockets – order and verifying it, the next step is to submit it on-chain. Catalyst Orders are accompanied by a user signature (`OrderDto.signature`) that serves a dual purpose:
After collecting an order – either through pulling or websockets – and verifying it, the next step is to submit it on-chain. Catalyst Orders are accompanied by a user signature (`OrderDto.signature`) that serves a dual purpose:

1. **Permit2 Signature**: This signature acts as a Permit2 allowance, authorizing the Catalyst contracts to withdraw the submitter's tokens directly. This streamlines the process by eliminating the need for separate approval transactions.

Expand Down Expand Up @@ -105,7 +105,7 @@ Orders are processed on a first-come, first-served basis, emphasizing the import

#### Custom FillerData & Underwriting

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.
By default, if `fillerData` is not specified, the input assets (provided by the user) are sent directly to the caller (`msg.sender`). This behavior is generally suitable for most use cases, eliminating the need for additional customization.

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:

Expand All @@ -114,55 +114,65 @@ However, if there is a need to direct the input assets to another address or to
- **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`.
- **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).

<Tabs syncKey="lang">
<TabItem label="Typescript">
Another version (`v2`) allows for adding additional logic when the inputs are paid. You can find more information on `v2` in our smart contracts or by reaching out.

```typescript
const fillerDataVersion = "0x01";
const fillerAddress = "0x....".replace("0x", "");
// fillerAddress.length === 20*2;
const orderPurchaseDeadline = Number(1723199919)
.toString(16)
.padStart("0", 4 * 2);
//orderPurchaseDeadline.length === 4*2
const orderDiscount = Math.floor(0.01 * (2 ** 16 - 1))
.toString(16)
.padStart("0", 2 * 2);
// orderDiscount.length === 2*2

const fillerData =
fillerDataVersion + fillerAddress + orderPurchaseDeadline + orderDiscount;
```
<Tabs syncKey="lang">
<TabItem label="Typescript">

</TabItem>
<TabItem label="Python">
```typescript
const fillerDataVersion = "0x01";
const fillerAddress = "0x....".replace("0x", "");
// fillerAddress.length === 20*2;
const orderPurchaseDeadline = Number(1723199919)
.toString(16)
.padStart("0", 4 * 2);
//orderPurchaseDeadline.length === 4*2
const orderDiscount = Math.floor(0.01 * (2 ** 16 - 1))
.toString(16)
.padStart("0", 2 * 2);
// orderDiscount.length === 2*2

const fillerData =
fillerDataVersion + fillerAddress + orderPurchaseDeadline + orderDiscount;
```

```python
fillerDataVersion = "0x01";
fillerAddress = '0x....'.replace("0x", "");
# len(fillerAddress) === 20*2;
orderPurchaseDeadline = hex(1723199919).replace("0x", "").zfill(4*2);
# len(orderPurchaseDeadline) === 4*2
const orderDiscount = hex(int(0.01*(2**16-1))).replace("0x", "").zfill(2*2);
# len(orderDiscount) === 2*2
</TabItem>
<TabItem label="Python">

fillerData = fillerDataVersion + fillerAddress + orderPurchaseDeadline + orderDiscount;
```
```python
fillerDataVersion = "0x01";
fillerAddress = '0x....'.replace("0x", "");
# len(fillerAddress) === 20*2;
orderPurchaseDeadline = hex(1723199919).replace("0x", "").zfill(4*2);
# len(orderPurchaseDeadline) === 4*2
const orderDiscount = hex(int(0.01*(2**16-1))).replace("0x", "").zfill(2*2);
# len(orderDiscount) === 2*2

fillerData = fillerDataVersion + fillerAddress + orderPurchaseDeadline + orderDiscount;
```

</TabItem>
</TabItem>
</Tabs>

## Bitcoin Initiation

Bitcoin operates differently from VM chains in terms of script functionality. Bitcoin scripts only define spending conditions, meaning that, unlike VM chains, we cannot pull funds from a user after they have signed a message. Consequently, the order flow is reversed, and the solver is responsible for signing the VM order.

Additionally, as previous chapters have described you cannot pull for BTC -> EVM orders. Instead you have to respond to the `quote-request-binding` event and get selected for a `non-vm-order` event.

### Encode your Bitcoin address

Your solver must be capable of generating a Bitcoin deposit address. Although it's possible to use the same address for every order, it is crucial to ensure that each order amount is unique if you choose this approach. It is generally recommended to use different addresses for each order. Bitcoin does not impose additional fees for collecting UTXOs from multiple addresses.
Your solver must be capable of generating 1 or multiple Bitcoin deposit address. Cross Cats supports all 5 address types in common use: P2PKH, P2SH, P2WPKH, P2WSH, and P2TR. We recommend using either P2WPKH, P2TR, or P2WSH.

:::caution[Ensure that amount + address is unique]
To prove if an output has been paid, we look for an exact amount of Bitcoin sent to a specific address. Any transaction that matches both and is included in a block 3 days before the `fillDeadline` allows the order to be proven.

If the same address is used every order, it becomes crucial to ensure that the **amount** is unique. It is generally recommended to use different addresses for each order. Bitcoin does not impose additional fees for collecting UTXOs from multiple addresses.
:::

Bitcoin addresses are encoded in two fields: `token` and `address`.

- **`token`**: This field serves to differentiate VM tokens from Bitcoin orders, encode relevant context like confirmations and address version. Refer to the [UTXO type table](/cross-cats/bitcoin-primer/#utxo-type-table) for details on converting address types to versions.
- **`token`**: This field serves to differentiate VM tokens from Bitcoin orders, encode relevant context like confirmations and address version. Refer to the [UTXO type table](/cross-cats/bitcoin-primer/#utxo-type-table) for details on converting address types to versions. The field should consists of the bitcoin signifier (BC in the 12'th byte), number of confirmations in the 31st, UTXO type in the 32'th, and otherwise 0s.

- **`address`**: This field encodes the public key hash, script hash, or witness hash. Use the decoding schemes listed in the [UTXO type table](/cross-cats/bitcoin-primer/#utxo-type-table) for various address versions. For addresses involving hashes of 20 bytes (P2PKH, P2SH, and P2WPKH), end pad the hashes with zeros (e.g., `0xabcdef...00000`).

Expand All @@ -171,7 +181,7 @@ Bitcoin addresses are encoded in two fields: `token` and `address`.
For solvers handling BTC to VM conversions, quoting orders for comparison with other solvers is essential. To begin quoting:

1. **Subscription**: Solvers must subscribe to quote requests from the order server.
2. **Response**: When a quote request is received, the solver must respond with a quote that remains valid for at least 60 seconds. If a signed order is requested within 30 seconds of the quote, the solver should provide a signed order with a lifetime of 30 seconds.
2. **Response**: When a quote request is received, the solver must respond with a quote that remains valid for at least 60 seconds. If a signed order is requested within 30 seconds of the quote, the solver should provide a signed order with a lifetime of 30 seconds. The 60 seconds is the sum of these.

Failure to respond with a signed order that matches or improves upon the quote within the 30-second window may result in blacklisting of the solver.

Expand Down
Loading

0 comments on commit d301853

Please sign in to comment.