From 4f4e930161e7b788ca2498fe275b7897aac968e0 Mon Sep 17 00:00:00 2001 From: Derrek <80121818+derrekcoleman@users.noreply.github.com> Date: Mon, 1 Jul 2024 13:04:56 -0600 Subject: [PATCH 1/3] docs: create gateway page (WIP) --- docs/docs/build/bob-sdk/gateway.md | 120 ++++++++++++++++++++++++++ docs/docs/build/bob-sdk/relay.md | 8 +- docs/docs/build/bob-sdk/sats-wagmi.md | 21 +++-- 3 files changed, 136 insertions(+), 13 deletions(-) create mode 100644 docs/docs/build/bob-sdk/gateway.md diff --git a/docs/docs/build/bob-sdk/gateway.md b/docs/docs/build/bob-sdk/gateway.md new file mode 100644 index 00000000..56b3ff1b --- /dev/null +++ b/docs/docs/build/bob-sdk/gateway.md @@ -0,0 +1,120 @@ +--- +sidebar_position: 1 +--- + +# BOB Gateway + +## What is BOB Gateway? + +[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. + +You can use our SDK to build this UX directly into your app, bringing your app's functionality (lending, swapping, restaking, etc.) directly to Bitcoin hodlers. + +## Features + + + +## Installation + +To use sats-wagmi, all you need to do is install the +`@gobob/sats-wagmi`: + +```sh +# with Yarn +$ yarn add @gobob/sats-wagmi + +# with npm +$ npm i @gobob/sats-wagmi + +# with pnpm +$ pnpm add @gobob/sats-wagmi + +# with Bun +$ bun add @gobob/sats-wagmi +``` + +## Usage + +### Connector + +```ts +import { MMSnapConnector } from "./connectors"; + +const mmSnap = new MMSnapConnector(network); + +mmSnap.connect(); +``` + +### React Hooks + +1. Wrap your application with the `SatsWagmiConfig` provided by **@gobob/sats-wagmi**. + +```tsx +import { SatsWagmiConfig } from "@gobob/sats-wagmi"; + +// Do this at the root of your application +function App({ children }) { + return {children}; +} +``` + +2. Now start by connecting: + +```tsx +import { useConnect, SatsConnector } from "@gobob/sats-wagmi"; + +function Example() { + const { connectors, connect } = useConnect(); + + const handleConnect = (connector: SatsConnector) => { + connect({ + connector, + }); + }; + + return ( +
+ {connectors.map((connector) => ( + + ))} +
+ ); +} +``` + +3. Once connected, you should be able to use the connector utility and have access to the connected BTC account: + +```tsx +import { useConnect, SatsConnector } from "@gobob/sats-wagmi"; + +function Example() { + const { address, connector } = useSatsAccount(); + + const handleTransfer = () => { + connector?.sendToAddress( + "tb1p9gl248kp19jgennea98e2tv8acfrvfv0yws2tc5j6u72e84caapsh2hexs", + 100000000 + ); + }; + + return ( +
+

Address: {address}

+ +
+ ); +} +``` diff --git a/docs/docs/build/bob-sdk/relay.md b/docs/docs/build/bob-sdk/relay.md index ee1a6a08..2ae17848 100644 --- a/docs/docs/build/bob-sdk/relay.md +++ b/docs/docs/build/bob-sdk/relay.md @@ -1,5 +1,5 @@ --- -sidebar_position: 2 +sidebar_position: 3 sidebar_label: Interact with Bitcoin from BOB Smart Contracts --- @@ -21,14 +21,14 @@ A specific advantage of using the Simple Payment Verification (SPV) "Light Relay - The relay validates the chain and updates the expected difficulty for blocks in that epoch - A user can then submit a transaction proof in that or the last period - Requires header chain of at least `txProofDifficultyFactor` - + ## Using The Relay -The code for the light relay is in [`src/relay/LightRelay.sol`](https://github.com/bob-collective/bob/blob/master/src/relay/LightRelay.sol) which stores the difficulty for the current and previous epoch. To update this it is possible to use `retarget(headers)` with `proofLength * 2` block headers from Bitcoin (before and after the retarget) serialized sequentially. +The code for the light relay is in [`src/relay/LightRelay.sol`](https://github.com/bob-collective/bob/blob/master/src/relay/LightRelay.sol) which stores the difficulty for the current and previous epoch. To update this it is possible to use `retarget(headers)` with `proofLength * 2` block headers from Bitcoin (before and after the retarget) serialized sequentially. ### Adding BOB contracts as dependency -To add the BOB contracts to your own projects, if your project is using Foundry, you can simply run `forge install bob-collective/bob` to add BOB contracts as a dependency to your project. +To add the BOB contracts to your own projects, if your project is using Foundry, you can simply run `forge install bob-collective/bob` to add BOB contracts as a dependency to your project. ### Build the code diff --git a/docs/docs/build/bob-sdk/sats-wagmi.md b/docs/docs/build/bob-sdk/sats-wagmi.md index bf2a2be5..405ec31c 100644 --- a/docs/docs/build/bob-sdk/sats-wagmi.md +++ b/docs/docs/build/bob-sdk/sats-wagmi.md @@ -1,5 +1,5 @@ --- -sidebar_position: 1 +sidebar_position: 4 --- # sats-wagmi Bitcoin Wallet React Hooks @@ -45,7 +45,7 @@ $ bun add @gobob/sats-wagmi ### Connector ```ts -import { MMSnapConnector } from './connectors'; +import { MMSnapConnector } from "./connectors"; const mmSnap = new MMSnapConnector(network); @@ -57,25 +57,25 @@ mmSnap.connect(); 1. Wrap your application with the `SatsWagmiConfig` provided by **@gobob/sats-wagmi**. ```tsx -import { SatsWagmiConfig } from '@gobob/sats-wagmi'; +import { SatsWagmiConfig } from "@gobob/sats-wagmi"; // Do this at the root of your application function App({ children }) { - return {children}; + return {children}; } ``` 2. Now start by connecting: ```tsx -import { useConnect, SatsConnector } from '@gobob/sats-wagmi'; +import { useConnect, SatsConnector } from "@gobob/sats-wagmi"; function Example() { const { connectors, connect } = useConnect(); const handleConnect = (connector: SatsConnector) => { connect({ - connector + connector, }); }; @@ -94,13 +94,16 @@ function Example() { 3. Once connected, you should be able to use the connector utility and have access to the connected BTC account: ```tsx -import { useConnect, SatsConnector } from '@gobob/sats-wagmi'; +import { useConnect, SatsConnector } from "@gobob/sats-wagmi"; function Example() { const { address, connector } = useSatsAccount(); const handleTransfer = () => { - connector?.sendToAddress('tb1p9gl248kp19jgennea98e2tv8acfrvfv0yws2tc5j6u72e84caapsh2hexs', 100000000); + connector?.sendToAddress( + "tb1p9gl248kp19jgennea98e2tv8acfrvfv0yws2tc5j6u72e84caapsh2hexs", + 100000000 + ); }; return ( @@ -110,4 +113,4 @@ function Example() { ); } -``` \ No newline at end of file +``` From 57dcc5f9f2e77202eb69aa0bb5b3e8e3c540b910 Mon Sep 17 00:00:00 2001 From: Derrek <80121818+derrekcoleman@users.noreply.github.com> Date: Mon, 1 Jul 2024 18:41:47 -0600 Subject: [PATCH 2/3] docs: finish gateway SDK page --- docs/docs/build/bob-sdk/gateway.md | 202 +++++++++++------- .../docs/learn/guides/bitcoin-bridge/index.md | 4 + 2 files changed, 131 insertions(+), 75 deletions(-) diff --git a/docs/docs/build/bob-sdk/gateway.md b/docs/docs/build/bob-sdk/gateway.md index 56b3ff1b..be9e5fe5 100644 --- a/docs/docs/build/bob-sdk/gateway.md +++ b/docs/docs/build/bob-sdk/gateway.md @@ -2,119 +2,171 @@ sidebar_position: 1 --- -# BOB Gateway +# BOB Gateway Integration Guide ## What is BOB Gateway? [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. -You can use our SDK to build this UX directly into your app, bringing your app's functionality (lending, swapping, restaking, etc.) directly to Bitcoin hodlers. +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. -## Features +## How Does it Work? - +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. -## Installation +This SDK makes it possible to do steps 2 and 3 in your application's front-end. -To use sats-wagmi, all you need to do is install the -`@gobob/sats-wagmi`: +## Step-by-Step Integration Guide + +Follow these steps to add BOB Gateway's functionality to your application. + +### Install the BOB SDK + +Install the `@gobob/bob-sdk` package using your preferred package manager: ```sh # with Yarn -$ yarn add @gobob/sats-wagmi +$ yarn add @gobob/bob-sdk # with npm -$ npm i @gobob/sats-wagmi +$ npm i @gobob/bob-sdk # with pnpm -$ pnpm add @gobob/sats-wagmi +$ pnpm add @gobob/bob-sdk # with Bun -$ bun add @gobob/sats-wagmi +$ bun add @gobob/bob-sdk ``` -## Usage +### Initialize the API Client -### Connector +Import the `GatewayApiClient` class from the `@gobob/bob-sdk` package and create an instance of it: -```ts -import { MMSnapConnector } from "./connectors"; - -const mmSnap = new MMSnapConnector(network); +```ts title="/src/utils/gateway.ts" +import { GatewayApiClient } from "@gobob/bob-sdk"; -mmSnap.connect(); +const gatewayClient = new GatewayApiClient( + "https://onramp-api-mainnet.gobob.xyz" +); ``` -### React Hooks +### Get a Quote -1. Wrap your application with the `SatsWagmiConfig` provided by **@gobob/sats-wagmi**. +Call the `getQuote` method with two parameters: -```tsx -import { SatsWagmiConfig } from "@gobob/sats-wagmi"; +- 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. -// Do this at the root of your application -function App({ children }) { - return {children}; -} -``` +and receive two outputs: -2. Now start by connecting: +- `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 -```tsx -import { useConnect, SatsConnector } from "@gobob/sats-wagmi"; +```ts title="/src/utils/gateway.ts" +const { onramp_address: onrampAddress, bitcoin_address: bitcoinAddress } = + await gatewayClient.getQuote(BOB_TBTC_V2_TOKEN_ADDRESS, amount); +``` -function Example() { - const { connectors, connect } = useConnect(); +### Create an Order - const handleConnect = (connector: SatsConnector) => { - connect({ - connector, - }); - }; +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. - return ( -
- {connectors.map((connector) => ( - - ))} -
+```ts title="/src/utils/gateway.ts" +const orderId = await gatewayClient.createOrder( + onrampAddress, + evmAddress, + amount +); +``` + +### Send BTC + +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. + +:::tip Connecting to Bitcoin wallets +We recommend using our [sats-wagmi](./sats-wagmi.md) package to query your user's Bitcoin wallet address. +::: + +```ts title="/src/utils/gateway.ts" +import { createTransfer } from "@gobob/bob-sdk"; +import * as bitcoin from "bitcoinjs-lib"; +import { AddressType, getAddressInfo } from "bitcoin-address-validation"; +import { hex } from "@scure/base"; +import { Transaction as SigTx } 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 { + 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 psbtHex = hex.encode(psbt); + const signedPsbtHex = psbtHex; + const signedTx = SigTx.fromPSBT( + bitcoin.Psbt.fromHex(signedPsbtHex).toBuffer() + ); + signedTx.finalize(); + const tx = bitcoin.Transaction.fromBuffer(Buffer.from(signedTx.extract())); + + return tx; } ``` -3. Once connected, you should be able to use the connector utility and have access to the connected BTC account: +### Receive Wrapped BTC -```tsx -import { useConnect, SatsConnector } from "@gobob/sats-wagmi"; +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. -function Example() { - const { address, connector } = useSatsAccount(); +```ts +await gatewayClient.updateOrder(orderId, tx.toHex()); +``` - const handleTransfer = () => { - connector?.sendToAddress( - "tb1p9gl248kp19jgennea98e2tv8acfrvfv0yws2tc5j6u72e84caapsh2hexs", - 100000000 - ); - }; +## Conclusion - return ( -
-

Address: {address}

- -
- ); -} -``` +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. + +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! + +## 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)) diff --git a/docs/docs/learn/guides/bitcoin-bridge/index.md b/docs/docs/learn/guides/bitcoin-bridge/index.md index 218975c0..30ca9c7b 100644 --- a/docs/docs/learn/guides/bitcoin-bridge/index.md +++ b/docs/docs/learn/guides/bitcoin-bridge/index.md @@ -17,6 +17,10 @@ If you are interested in being an LP for the BOB Gateway bridge, please send us 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. +:::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). +::: + ## Video Tutorial From 3caf387718973a321257260939651e994b13e757 Mon Sep 17 00:00:00 2001 From: Derrek <80121818+derrekcoleman@users.noreply.github.com> Date: Mon, 1 Jul 2024 18:54:12 -0600 Subject: [PATCH 3/3] chore: typo --- docs/docs/build/bob-sdk/gateway.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/build/bob-sdk/gateway.md b/docs/docs/build/bob-sdk/gateway.md index be9e5fe5..cf6dd47e 100644 --- a/docs/docs/build/bob-sdk/gateway.md +++ b/docs/docs/build/bob-sdk/gateway.md @@ -16,7 +16,7 @@ You can use our SDK to add this UX directly into your app, bringing your app's f 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. -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 and 3 in your application's front end. ## Step-by-Step Integration Guide