Skip to content
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

Merged
merged 4 commits into from
Aug 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
191 changes: 83 additions & 108 deletions docs/docs/build/bob-sdk/gateway.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,164 +2,139 @@
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:

```sh
# with Yarn
$ yarn add @gobob/bob-sdk
:::warning Staking only on testnet
BOB Gateway's newest functionality (i.e. staking for LSTs) is only available on testnet. We will update this page once mainnet is upgraded.
:::

# with npm
$ npm i @gobob/bob-sdk
### Install the BOB SDK

# with pnpm
$ pnpm add @gobob/bob-sdk
Add `@gobob/bob-sdk` to your project using your preferred package manager.

# 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.

- 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.
```ts
const outputTokensWithInfo = await gatewaySDK.getTokensInfo();
```

and receive two outputs:
### Get a Quote

- `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
Call the `getQuote` method with your `quoteParams`. Example values shown here.

```ts title="/src/utils/gateway.ts"
const { onramp_address: onrampAddress, bitcoin_address: bitcoinAddress } =
await gatewayClient.getQuote(BOB_TBTC_V2_TOKEN_ADDRESS, amount);
:::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
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!
Copy link
Contributor

Choose a reason for hiding this comment

The 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

Copy link
Contributor Author

@derrekcoleman derrekcoleman Aug 28, 2024

Choose a reason for hiding this comment

The 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!));
```

### 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.

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
// NOTE: Gateway broadcasts the transaction
await gatewaySDK.finalizeOrder(uuid, tx.hex);
```

### Receive Wrapped BTC
### Monitor the User's Orders

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.
Get an array of pending and completed orders for a specific EVM address. Typically rendered in a table.

```ts
await gatewayClient.updateOrder(orderId, tx.toHex());
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))
2 changes: 0 additions & 2 deletions docs/docs/learn/guides/bob-fusion/_category_.yml

This file was deleted.

11 changes: 8 additions & 3 deletions docs/docs/learn/guides/bob-fusion/index.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
---
sidebar_position: 2
sidebar_label: BOB Fusion
---

import styles from './bob-fusion.module.css';

# BOB Fusion
Expand Down Expand Up @@ -27,7 +32,7 @@ DApps can use the BOB Fusion system to bootstrap their launch on BOB.
Checkout the information on the official [BOB Fusion page](https://app.gobob.xyz/fusion?tab=info) for more details.
:::

:::tip Running a Project on BOB?
:::tip Running a Project on BOB?
Reach out to the team on [Telegram](https://t.me/gobobxyz) to learn more about the opportunities for builders to grow their projects with our BOB Fusion campaign or read our [project checklist](https://build-on-bitcoin.notion.site/BOB-Launch-Partner-Checklist-12b6da11f607438c82494be34c0f0c58) that includes information about how to whitelist your dApp or add custom assets to the BOB Fusion campaign.
:::

Expand All @@ -48,12 +53,12 @@ Thus users who get spice via gas fees are essentially paying for that spice, whi

Please note some dApps plan to distribute spice retroactively at some point in the future, so if you have used the dApp during that snapshot time, you will get your spice, albeit the distribution timelines depend on the dApps.

If you are unhappy about a dApp’s Spice distribution, your best options are to either voice your concerns to that dApp or look for other opportunities in the BOB Fusion campaign.
If you are unhappy about a dApp’s Spice distribution, your best options are to either voice your concerns to that dApp or look for other opportunities in the BOB Fusion campaign.

### Inflation of Spice from Season 1 to Season 2

Season 2 inherently requires more effort, research, smart contract interactions, and gas fees than Season 1. (IL risk, protocol risk, smart contract risk, capital deployments, minting, trading, lending, etc.)
By actively engaging with the ecosystem in Season 2, you climb the ranks against users who just deployed capital in Season 1 and did not contribute to Season 2.
By actively engaging with the ecosystem in Season 2, you climb the ranks against users who just deployed capital in Season 1 and did not contribute to Season 2.
We believe this is a fair outcome as the main mission behind BOB Fusion is to track active participation across the BOB ecosystem.

### What’s the maximum amount of Spice for the Fusion campaign?
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
---
sidebar_position: 3
sidebar_label: Bridge from Bitcoin to BOB
sidebar_position: 1
sidebar_label: BOB Gateway
---

# BOB Gateway

## Bridge from Bitcoin to BOB

[BOB Gateway](https://app.gobob.xyz) allows you to swap your Bitcoin into wrapped Bitcoin with a single, unified interface so you can put your bitcoin to work earning yield faster than ever before.
[BOB Gateway](https://app.gobob.xyz) lets you stake, swap, or lend your bitcoin from a single, unified interface so you can put your bitcoin to work earning yield faster than ever before.

It's built on a trustless, RFQ-based cross-chain [swap protocol](../../../build/examples/btc-swap/) that connects professional LPs with users through a seamless swapping experience. Essentially, LPs handle the complexities of bridging on behalf of users in exchange for a fee.
It's built on a trustless, RFQ-based cross-chain [swap protocol](../../../build/examples/btc-swap/) that connects professional LPs with users through a seamless swapping experience. Essentially, LPs handle the complexities of bridging and staking on behalf of users in exchange for a fee.

:::tip Interested in providing liquidity?
If you are interested in being an LP for the BOB Gateway bridge, please send us an email at `gateway [ at ] gobob.xyz`.
:::

All you need is a Bitcoin wallet with some BTC to send and an EVM-compatible wallet to receive your wrapped Bitcoin on BOB. We'll even send you some ETH to cover the fees of your first few transactions on BOB.
All you need is a Bitcoin wallet with some BTC to send and an EVM-compatible wallet to receive your Bitcoin LST/LRT or wrapped Bitcoin on BOB. We'll even send you some ETH to cover the fees of your first few transactions on BOB.

:::tip Want to add BOB Gateway to your dapp?
Check out our guide to see how you can [integrate BOB Gateway into your dapp](../../../build/bob-sdk/gateway.md).
Expand Down
19 changes: 12 additions & 7 deletions docs/docusaurus.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// @ts-check
// Note: type annotations allow type checking and IDEs autocompletion

const {themes} = require('prism-react-renderer');
const { themes } = require("prism-react-renderer");
const lightCodeTheme = themes.github;
const darkCodeTheme = themes.dracula;

Expand All @@ -12,15 +12,17 @@ const DISCORD = "https://discord.gg/gobob";
const TWITTER = "https://twitter.com/build_on_bob";
const TELEGRAM = "https://t.me/+CyIcLW2nfaFlNDc1";
const FORUM = "https://forum.gobob.xyz";
const PRESS_KIT = "https://build-on-bitcoin.notion.site/BOB-Press-Kit-1be66c38713d480eab01000bdd164206";
const BRAND_KIT = "https://drive.google.com/drive/u/0/folders/1c30QDkyWgaV8xSEpCXFWJj1WQyUjSm7N";
const ONE_PAGER = "https://build-on-bitcoin.notion.site/BOB-Summary-23fad2d446ff467d8551b924eb3338fc";
const PRESS_KIT =
"https://build-on-bitcoin.notion.site/BOB-Press-Kit-1be66c38713d480eab01000bdd164206";
const BRAND_KIT =
"https://drive.google.com/drive/u/0/folders/1c30QDkyWgaV8xSEpCXFWJj1WQyUjSm7N";
const ONE_PAGER =
"https://build-on-bitcoin.notion.site/BOB-Summary-23fad2d446ff467d8551b924eb3338fc";

/** @type {import('@docusaurus/types').Config} */
const config = {
title: "BOB - Build on Bitcoin",
tagline:
"A hybrid layer-2 powered by Bitcoin and Ethereum.",
tagline: "A hybrid layer-2 powered by Bitcoin and Ethereum.",
favicon: "img/favicon.ico",
url: DOCS_PAGE,
baseUrl: "/",
Expand Down Expand Up @@ -49,6 +51,9 @@ const config = {
docs: {
sidebarPath: require.resolve("./sidebars.js"),
editUrl: `${GITHUB_LINK}/tree/master/docs/`,
remarkPlugins: [
[require("@docusaurus/remark-plugin-npm2yarn"), { sync: true }],
],
},
theme: {
customCss: require.resolve("./src/css/custom.css"),
Expand Down Expand Up @@ -172,7 +177,7 @@ const config = {
prism: {
theme: lightCodeTheme,
darkTheme: darkCodeTheme,
additionalLanguages: ['solidity'],
additionalLanguages: ["solidity"],
},
colorMode: {
defaultMode: "dark",
Expand Down
1 change: 1 addition & 0 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"dependencies": {
"@docusaurus/core": "^3.5.2",
"@docusaurus/preset-classic": "^3.5.2",
"@docusaurus/remark-plugin-npm2yarn": "^3.5.2",
"@docusaurus/theme-live-codeblock": "^3.5.2",
"@docusaurus/theme-mermaid": "^3.5.2",
"@easyops-cn/docusaurus-search-local": "^0.44.5",
Expand Down