-
Notifications
You must be signed in to change notification settings - Fork 37
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
docs: Update Gateway pages for V3 #325
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,164 +2,135 @@ | |
sidebar_position: 1 | ||
--- | ||
|
||
# BOB Gateway Integration Guide | ||
# BOB Gateway | ||
|
||
## What is BOB Gateway? | ||
## Overview | ||
|
||
[BOB Gateway](https://docs.gobob.xyz/docs/learn/guides/bitcoin-bridge/) is a trustless, P2P bridge that enables users to bridge their BTC from Bitcoin mainnet to BOB. | ||
[BOB Gateway](https://docs.gobob.xyz/docs/learn/guides/bitcoin-bridge/) is a Bitcoin intent bridge that unlocks Bitcoin liquidity by reducing the number of steps to onboard users, saving time and money. Users can go from **BTC** on Bitcoin to **staked BTC LSTs** with a single Bitcoin transaction. | ||
|
||
You can use our SDK to add this UX directly into your app, bringing your app's functionality (lending, swapping, restaking, etc.) directly to Bitcoin hodlers. | ||
Our SDK makes it possible for you to bring this UX directly into your app. | ||
|
||
## How Does it Work? | ||
## How Gateway Works | ||
|
||
1. Liquidity providers (LPs) temporarily lock wrapped Bitcoin (WBTC or tBTC) in escrow smart contracts on BOB. | ||
2. A user submits a transaction to the Bitcoin network that sends BTC to the liquidity provider's Bitcoin address and publishes the user's EVM wallet address in the `OP_RETURN` of the transaction. | ||
3. BOB's relayer server calls an on-chain [Light Client](../examples/btc-swap/index.mdx) to trustlessly verify the Bitcoin transaction and transfer the LP's wrapped Bitcoin to the user's EVM address, including a "gratuity" amount of ETH for transaction fees on BOB. | ||
1. A user makes a request for wrapped or staked Bitcoin (e.g. WBTC, tBTC, or a Bitcoin LST/LRT). | ||
1. The user sends BTC to the liquidity provider's Bitcoin address. A hash of the user's order is included in the `OP_RETURN` of the transaction. | ||
1. Gateway finalizes the transaction. After trustlessly verifying the user's Bitcoin transaction with an on-chain [Light Client](../examples/btc-swap/index.mdx), Gateway sends the LP's wrapped Bitcoin to the user's EVM address. If the user requested a Bitcoin LST/LRT, that token is minted using the LP's wrapped Bitcoin before it is sent to the user. | ||
|
||
This SDK makes it possible to do steps 2 and 3 in your application's front end. | ||
This SDK makes it possible to do steps 2, 3, and 4 in your application's front end. | ||
|
||
## Step-by-Step Integration Guide | ||
|
||
Follow these steps to add BOB Gateway's functionality to your application. | ||
This is an example implementation of our SDK. You will need to decide how you handle asking your user to sign a partially-signed Bitcoin transaction (PSBT). We recommend using our [sats-wagmi](./sats-wagmi.md) package to connect to your users' wallets. | ||
|
||
### Install the BOB SDK | ||
|
||
Install the `@gobob/bob-sdk` package using your preferred package manager: | ||
Add `@gobob/bob-sdk` to your project using your preferred package manager. | ||
|
||
```sh | ||
# with Yarn | ||
$ yarn add @gobob/bob-sdk | ||
|
||
# with npm | ||
$ npm i @gobob/bob-sdk | ||
|
||
# with pnpm | ||
$ pnpm add @gobob/bob-sdk | ||
|
||
# with Bun | ||
$ bun add @gobob/bob-sdk | ||
```bash npm2yarn | ||
npm install @gobob/bob-sdk | ||
``` | ||
|
||
### Initialize the API Client | ||
|
||
Import the `GatewayApiClient` class from the `@gobob/bob-sdk` package and create an instance of it: | ||
Import the `GatewaySDK` class from `@gobob/bob-sdk` and create an instance of it. | ||
|
||
```ts title="/src/utils/gateway.ts" | ||
import { GatewayApiClient } from "@gobob/bob-sdk"; | ||
import { GatewayQuoteParams, GatewaySDK } from "@gobob/bob-sdk"; | ||
|
||
const gatewayClient = new GatewayApiClient( | ||
"https://onramp-api-mainnet.gobob.xyz" | ||
); | ||
const gatewaySDK = new GatewaySDK("bob"); // or "mainnet" | ||
``` | ||
|
||
### Get a Quote | ||
### Get Available Tokens | ||
|
||
Call the `getQuote` method with two parameters: | ||
Returns an array of available output tokens for you to offer the user. Typically rendered as a drop-down menu. See [our SDK's source code](https://github.com/bob-collective/bob/blob/9c52341033af1ccbe388e64ef97a23bf6c07ccc7/sdk/src/gateway/tokens.ts#L8) for type information. | ||
|
||
```ts | ||
const outputTokensWithInfo = await gatewaySDK.getTokensInfo(); | ||
``` | ||
|
||
- the address of the desired output token | ||
- WBTC: [0x03c7054bcb39f7b2e5b2c7acb37583e32d70cfa3](https://explorer.gobob.xyz/address/0x03c7054bcb39f7b2e5b2c7acb37583e32d70cfa3) | ||
- tBTC: [0xBBa2eF945D523C4e2608C9E1214C2Cc64D4fc2e2](https://explorer.gobob.xyz/address/0xBBa2eF945D523C4e2608C9E1214C2Cc64D4fc2e2) | ||
- the amount of BTC the user is bridging, expressed in satoshis. For example, 1 BTC is 100000000 satoshis. | ||
### Get a Quote | ||
|
||
and receive two outputs: | ||
Call the `getQuote` method with your `quoteParams`. Example values shown here. | ||
|
||
- `onrampAddress`, the smart contract holding funds from the LP with the most competitive offer | ||
- `bitcoinAddress`, the Bitcoin address where the user will send their BTC | ||
:::tip Updating the quote | ||
We recommend rendering `quote.fee` and [its other fields](https://github.com/bob-collective/bob/blob/9c52341033af1ccbe388e64ef97a23bf6c07ccc7/sdk/src/gateway/client.ts#L15) for a clear UX. You can update the quote dynamically, such as with the `onChange` event. | ||
::: | ||
|
||
```ts title="/src/utils/gateway.ts" | ||
const { onramp_address: onrampAddress, bitcoin_address: bitcoinAddress } = | ||
await gatewayClient.getQuote(BOB_TBTC_V2_TOKEN_ADDRESS, amount); | ||
```ts | ||
const quoteParams: GatewayQuoteParams = { | ||
fromChain: "Bitcoin", | ||
fromUserAddress: "bc1qafk4yhqvj4wep57m62dgrmutldusqde8adh20d", | ||
toChain: "BOB", | ||
toUserAddress: "0x2D2E86236a5bC1c8a5e5499C517E17Fb88Dbc18c", | ||
toToken: "tBTC", | ||
amount: 10000000, // 0.1 BTC | ||
gasRefill: 10000, // 0.0001 BTC. The amount of BTC to swap for ETH for tx fees. | ||
}; | ||
|
||
const quote = await gatewaySDK.getQuote(quoteParams); | ||
``` | ||
|
||
### Create an Order | ||
### Start the Order | ||
|
||
This locks in the quote a places a hold on the LP's funds. Pass `evmAddress`, the wallet address where your user would like to receive funds on BOB, and `amount`, the amount of BTC they would like to bridge expressed in satoshis. | ||
This locks in the quote, placing a hold on the LP's funds. Pass the same `quoteParams` as before and the `quote` returned from the previous step. | ||
|
||
```ts title="/src/utils/gateway.ts" | ||
const orderId = await gatewayClient.createOrder( | ||
onrampAddress, | ||
evmAddress, | ||
amount | ||
); | ||
Returns a `uuid` for the order and `psbtBase64`, a partially-signed Bitcoin transaction (PSBT) the user must sign. | ||
|
||
```ts | ||
const { uuid, psbtBase64 } = await gatewaySDK.startOrder(quote, quoteParams); | ||
``` | ||
|
||
### Send BTC | ||
### Sign the Bitcoin Transaction | ||
|
||
Create a Bitcoin transaction that sends the quoted `amount` of BTC from the user's wallet (`fromAddress`) to the LP's `bitcoinAddress`. This also publishes the user's `evmAddress` in the `OP_RETURN` of the transaction so the Gateway knows where to send wrapped BTC. | ||
Create a Bitcoin transaction that sends the quoted `amount` of BTC to the LP's `bitcoinAddress`. This also publishes a hash of the order's parameters in the `OP_RETURN` of the transaction so the Gateway can trustlessly verify the order on BOB. | ||
|
||
:::tip Connecting to Bitcoin wallets | ||
We recommend using our [sats-wagmi](./sats-wagmi.md) package to query your user's Bitcoin wallet address. | ||
We recommend using our [sats-wagmi](./sats-wagmi.md) package to interact with your user's Bitcoin wallet. | ||
::: | ||
|
||
```ts title="/src/utils/gateway.ts" | ||
import { createTransfer } from "@gobob/bob-sdk"; | ||
import { AddressType, getAddressInfo } from "bitcoin-address-validation"; | ||
import { Transaction } from '@scure/btc-signer'; | ||
|
||
const tx = await createTxWithOpReturn( | ||
fromAddress, | ||
bitcoinAddress, | ||
amount, | ||
evmAddress | ||
); | ||
|
||
async function createTxWithOpReturn( | ||
fromAddress: string, | ||
toAddress: string, | ||
amount: number, | ||
opReturn: string, | ||
fromPubKey?: string | ||
): Promise<Buffer> { | ||
const addressType = getAddressInfo(fromAddress).type; | ||
|
||
// Ensure this is not the P2TR address for ordinals (we don't want to spend from it) | ||
if (addressType === AddressType.p2tr) { | ||
throw new Error( | ||
"Cannot transfer using Taproot (P2TR) address. Please use another address type." | ||
); | ||
} | ||
|
||
// We need the public key to generate the redeem and witness script to spend the scripts | ||
if (addressType === (AddressType.p2sh || AddressType.p2wsh)) { | ||
if (!fromPubKey) { | ||
throw new Error( | ||
"Public key is required to spend from the selected address type" | ||
); | ||
} | ||
} | ||
|
||
const unsignedTx = await createTransfer( | ||
"mainnet", | ||
addressType, | ||
fromAddress, | ||
toAddress, | ||
amount, | ||
fromPubKey, | ||
opReturn | ||
); | ||
const psbt = unsignedTx.toPSBT(0); | ||
|
||
const signedTx = Transaction.fromPSBT(psbt); | ||
|
||
return Buffer.from(signedTx.extract()) | ||
} | ||
```ts | ||
import { base64 } from "@scure/base"; | ||
import { Transaction } from "@scure/btc-signer"; | ||
|
||
// NOTE: It is up to your implementation to sign the PSBT here! | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know it's not ready yet but we should really detail how to also integrate sats-wagmi as a default example to do this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed. Let's add the sats-wagmi example asap in a separate PR. |
||
const tx = Transaction.fromPSBT(base64.decode(psbtBase64!)); | ||
``` | ||
|
||
### Receive Wrapped BTC | ||
### Finalize the Order | ||
|
||
Submit the Bitcoin transaction as proof of transfer. This completes the process by transferring wrapped Bitcoin and ETH to the user's EVM address on BOB. | ||
|
||
Submit the Bitcoin transaction information as proof of transfer. This completes the process by transferring wrapped Bitcoin and ETH to the user's EVM address on BOB. | ||
Gateway can broadcast the Bitcoin transaction to the mempool; you can pass the transaction to the SDK without broadcasting from the user's wallet. | ||
|
||
```ts | ||
await gatewayClient.updateOrder(orderId, tx.toHex()); | ||
// NOTE: Gateway broadcasts the transaction | ||
await gatewaySDK.finalizeOrder(uuid, tx.hex); | ||
``` | ||
|
||
### Monitor the User's Orders | ||
|
||
Get an array of pending and completed orders for a specific EVM address. Typically rendered in a table. | ||
|
||
```ts | ||
const orders = await gatewaySDK.getOrders(userAddress); | ||
``` | ||
|
||
## Conclusion | ||
|
||
Following the steps above allows users to bridge BTC from Bitcoin mainnet to BOB within your application. From there, they can connect their EVM wallet and use their wrapped BTC in your dapp. | ||
BOB Gateway enables staking, swapping, lending, and bridging Bitcoin with a single transaction. The BOB SDK makes it possible for you to bring Gateway and Bitcoin LSTs directly to your users. | ||
|
||
See the [Code References](#code-references) below for a deeper look at the SDK and an example implementation file. | ||
|
||
You're always welcome to [reach out to us](../../learn/introduction/contribution.md) with questions, feedback, or ideas. We look forward to seeing what you Build on Bitcoin! | ||
|
||
## Security and Trust Assumptions | ||
|
||
The protocol requires zero trust between the market makers and users because it utilizes atomic cross-chain swaps. The verification of the Bitcoin transaction is performed cryptographically by an on-chain Bitcoin [Light Client](../examples/btc-swap/index.mdx), making the swap trustless between both parties. | ||
|
||
Furthermore, infrastructure run by the BOB team never has access to the market markers' tBTC, wBTC, or ETH funds stored in their smart contracts. The user interface and server manage order flow to prevent liquidity sniping and user errors (e.g. sending BTC without sufficient liquidity being available), but neither the front end or back end ever have access to users' or market makers' funds. | ||
|
||
## Code References | ||
|
||
- `/src/gateway.ts`: API client code ([GitHub](https://github.com/bob-collective/bob/blob/master/sdk/src/gateway.ts)) | ||
- `/examples/gateway.ts`: example client-side implementation ([GitHub](https://github.com/bob-collective/bob/blob/master/sdk/examples/gateway.ts)) | ||
- `bob/sdk/src/gateway/client.ts`: API client code ([GitHub](https://github.com/bob-collective/bob/blob/master/sdk/src/gateway/client.ts)) | ||
- `bob/sdk/examples/gateway.ts`: example client-side implementation ([GitHub](https://github.com/bob-collective/bob/blob/master/sdk/examples/gateway.ts)) |
This file was deleted.
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.
Do we wanna keep this?
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.
The
npm2yarn
package in the new version provides a tab-switcher between package managers, so we still have multiple options. I opted for that to strive for visual conciseness, but I'm happy to revert if you prefer.