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

refactor(evm): btc bridge api update #32

Merged
merged 3 commits into from
Jul 3, 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
6 changes: 6 additions & 0 deletions apps/evm/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,9 @@ VITE_FEATURE_FLAG_BTC_ONRAMP=disabled
VITE_INDEXER_BRIDGE_URL=""
VITE_SENTRY_URL=""
VITE_SENTRY_AUTH_TOKEN=""


/* MAINNET */
VITE_ONRAMP_API_URL="https://onramp-api-mainnet.gobob.xyz"
VITE_BTC_API_URL="https://btc-mainnet.gobob.xyz"
VITE_L1_CHAIN_NAME="ethereum"
1 change: 1 addition & 0 deletions apps/evm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"dependencies": {
"@eth-optimism/sdk": "^3.1.6",
"@ethersproject/providers": "^5.7.2",
"@gobob/bob-sdk": "1.3.0",
"@gobob/chains": "workspace:^",
"@gobob/connect-ui": "workspace:^",
"@gobob/currency": "workspace:^",
Expand Down
5 changes: 5 additions & 0 deletions apps/evm/src/lib/bob-sdk/gateway.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { GatewayApiClient } from '@gobob/bob-sdk';

const gatewayClient = new GatewayApiClient('/onramp-api');

export { gatewayClient };
1 change: 1 addition & 0 deletions apps/evm/src/lib/bob-sdk/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './gateway';
3 changes: 1 addition & 2 deletions apps/evm/src/lib/react-query/keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ export const bridgeKeys = {
proveTransaction: (address: Address | undefined, hash: Address) => [address, hash, 'prove'],
relayTransaction: (address: Address | undefined, hash: Address) => [address, hash, 'relay'],
btc: (address: Address | undefined, btcAddress: string | undefined) => ['btc', address, btcAddress],
btcTotalLiquidity: () => ['btc-total-liquidity'],
btcQuote: (address: Address | undefined, btcAddress: string | undefined, atomicAmount: number | undefined) => [
btcQuote: (address: Address | undefined, btcAddress: string | undefined, atomicAmount?: number | 'max') => [
...bridgeKeys.btc(address, btcAddress),
atomicAmount,
'quote'
Expand Down
29 changes: 16 additions & 13 deletions apps/evm/src/pages/Bridge/components/BridgeForm/BtcBridgeForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ import {
bridgeSchema
} from '../../../../lib/form/bridge';
import { isFormDisabled } from '../../../../lib/form/utils';
import { onRampApiClient } from '../../../../utils';
import { useGetTransactions } from '../../hooks';
import { OnRampData } from '../../types';
import { bridgeKeys } from '../../../../lib/react-query';
import { gatewayClient } from '../../../../lib/bob-sdk';

type BtcBridgeFormProps = {
type: 'deposit' | 'withdraw';
Expand All @@ -41,7 +41,7 @@ type BtcBridgeFormProps = {
onFailOnRamp: () => void;
};

const MIN_DEPOSIT_AMOUNT = 40000;
const MIN_DEPOSIT_AMOUNT = 4000;

const gasEstimatePlaceholder = CurrencyAmount.fromRawAmount(BITCOIN, 0n);

Expand Down Expand Up @@ -87,18 +87,18 @@ const BtcBridgeForm = ({
toast.error(e.message);
}, []);

const { data: availableLiquidity, isLoading: isLoadingLiquidity } = useQuery({
const { data: availableLiquidity, isLoading: isLoadingMaxQuote } = useQuery({
enabled: Boolean(btcToken),
queryKey: bridgeKeys.btcTotalLiquidity(),
queryKey: bridgeKeys.btcQuote(evmAddress, btcAddress, 'max'),
refetchInterval: INTERVAL.MINUTE,
refetchOnMount: false,
refetchOnWindowFocus: false,
queryFn: async () => {
if (!currencyAmount || !btcToken) return;

const total = await onRampApiClient.getTotalLiquidity(btcToken.raw.address);
const maxQuoteData = await gatewayClient.getQuote(btcToken.raw.address);

return CurrencyAmount.fromRawAmount(BITCOIN, total);
return CurrencyAmount.fromRawAmount(BITCOIN, maxQuoteData.satoshis);
}
});

Expand Down Expand Up @@ -133,7 +133,7 @@ const BtcBridgeForm = ({

const atomicAmount = currencyAmount.numerator.toString();

const { fee, onramp_address, bitcoin_address, gratuity } = await onRampApiClient.getQuote(
const { fee, onramp_address, bitcoin_address, gratuity } = await gatewayClient.getQuote(
btcToken.raw.address,
atomicAmount
);
Expand Down Expand Up @@ -185,12 +185,12 @@ const BtcBridgeForm = ({

const atomicAmount = Number(currencyAmount.numerator);

const orderId = await onRampApiClient.createOrder(onrampAddress, evmAddress, atomicAmount);
const orderId = await gatewayClient.createOrder(onrampAddress, evmAddress, atomicAmount);

const tx = await connector.createTxWithOpReturn(bitcoinAddress, atomicAmount, evmAddress);

// NOTE: relayer should broadcast the tx
await onRampApiClient.updateOrder(orderId, tx.toHex());
await gatewayClient.updateOrder(orderId, tx.toHex());

return { ...data, txid: tx.getId() };
},
Expand Down Expand Up @@ -220,7 +220,7 @@ const BtcBridgeForm = ({

if (type === 'deposit') {
return depositMutation.mutate({
onrampAddress: quoteData.onrampAddress,
onrampAddress: quoteData.onrampAddress as Address,
bitcoinAddress: quoteData.bitcoinAddress,
evmAddress: (data[BRIDGE_RECIPIENT] as Address) || evmAddress,
currencyAmount
Expand Down Expand Up @@ -267,7 +267,10 @@ const BtcBridgeForm = ({

const params: BridgeFormValidationParams = {
[BRIDGE_AMOUNT]: {
minAmount: currencyAmount && new Big(MIN_DEPOSIT_AMOUNT / 10 ** currencyAmount?.currency.decimals),
minAmount:
currencyAmount && MIN_DEPOSIT_AMOUNT
? new Big(MIN_DEPOSIT_AMOUNT / 10 ** currencyAmount?.currency.decimals)
: undefined,
maxAmount: new Big(balanceAmount.toExact())
},
[BRIDGE_RECIPIENT]: !!isSmartAccount
Expand All @@ -289,7 +292,7 @@ const BtcBridgeForm = ({
const isTapRootAddress = btcAddressType === BtcAddressType.p2tr;

const isDisabled =
isSubmitDisabled || !quoteData || isQuoteError || isTapRootAddress || isLoadingLiquidity || !hasLiquidity;
isSubmitDisabled || !quoteData || isQuoteError || isTapRootAddress || isLoadingMaxQuote || !hasLiquidity;

const isLoading = !isSubmitDisabled && (depositMutation.isPending || isFetchingQuote);

Expand Down Expand Up @@ -361,7 +364,7 @@ const BtcBridgeForm = ({
</P>
</Alert>
)}
{!hasLiquidity && !isLoadingLiquidity && (
{!hasLiquidity && !isLoadingMaxQuote && (
<Alert status='warning'>
<P size='s'>There is currently no available liquidity to onramp BTC into {btcToken?.currency.symbol}.</P>
</Alert>
Expand Down
7 changes: 4 additions & 3 deletions apps/evm/src/pages/Bridge/hooks/useGetOnRampTransactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import { Address, isAddressEqual } from 'viem';

import { L2_CHAIN } from '../../../constants';
import { FeatureFlags, TokenData, useFeatureFlag, useTokens } from '../../../hooks';
import { electrsClient, onRampApiClient } from '../../../utils';
import { electrsClient } from '../../../utils';
import { OnRampDepositSteps } from '../constants';
import { TransactionType } from '../types';
import { gatewayClient } from '../../../lib/bob-sdk';

type OnRampTransaction = {
status: OnRampDepositSteps;
Expand All @@ -21,12 +22,12 @@ type OnRampTransaction = {
};

const getOnRampTransactions = async (address: Address, l2Tokens: TokenData[]): Promise<OnRampTransaction[]> => {
const [orders, latestBlock] = await Promise.all([onRampApiClient.getOrders(address), electrsClient.getLatestBlock()]);
const [orders, latestBlock] = await Promise.all([gatewayClient.getOrders(address), electrsClient.getLatestBlock()]);

return (
await Promise.all(
orders.map(async (order): Promise<OnRampTransaction | undefined> => {
const token = l2Tokens.find((token) => isAddressEqual(token.raw.address, order.token_address));
const token = l2Tokens.find((token) => isAddressEqual(token.raw.address, order.token_address as Address));

if (!token) return undefined;

Expand Down
1 change: 0 additions & 1 deletion apps/evm/src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export * from './api-client';
export * from './electrs-client';
export * from './onramp-api-client';
export * from './math';
101 changes: 0 additions & 101 deletions apps/evm/src/utils/onramp-api-client.ts

This file was deleted.

2 changes: 1 addition & 1 deletion packages/sats-wagmi/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
},
"dependencies": {
"@bitcoin-js/tiny-secp256k1-asmjs": "^2.2.3",
"@gobob/bob-sdk": "^1.2.0",
"@gobob/bob-sdk": "^1.3.0",
"@gobob/react-query": "workspace:^",
"@gobob/types": "workspace:^",
"@gobob/utils": "workspace:^",
Expand Down
8 changes: 4 additions & 4 deletions packages/sats-wagmi/src/connectors/base.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DefaultElectrsClient, RemoteSigner } from '@gobob/bob-sdk';
import { DefaultEsploraClient, RemoteSigner } from '@gobob/bob-sdk';
import { Network as LibNetwork, Psbt, Transaction, networks } from 'bitcoinjs-lib';
import * as bitcoin from 'bitcoinjs-lib';
import retry from 'async-retry';
Expand Down Expand Up @@ -126,7 +126,7 @@ abstract class SatsConnector {

// const network = await this.getNetwork();

// const electrsClient = new DefaultElectrsClient(this.network as string);
// const electrsClient = new DefaultEsploraClient(this.network as string);

// const utxos = await electrsClient.getAddressUtxos(this.ordinalsAddress);

Expand Down Expand Up @@ -176,7 +176,7 @@ abstract class SatsConnector {
}

async getTransaction(txId: string): Promise<Transaction> {
const electrsClient = new DefaultElectrsClient(this.network as string);
const electrsClient = new DefaultEsploraClient(this.network as string);

return retry(
async (bail) => {
Expand Down Expand Up @@ -205,7 +205,7 @@ abstract class SatsConnector {
// throw new Error('Something went wrong while connecting');
// }

// const electrsClient = new DefaultElectrsClient(this.network as string);
// const electrsClient = new DefaultEsploraClient(this.network as string);

// let inscription;

Expand Down
4 changes: 2 additions & 2 deletions packages/sats-wagmi/src/connectors/mm-snap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ class MMSnapConnector extends SatsConnector {
// throw new Error('Public key missing');
// }

// const electrsClient = new DefaultElectrsClient(this.network as string);
// const electrsClient = new DefaultEsploraClient(this.network as string);

// const libNetwork = await this.getNetwork();
// const network = this.network.toString();
Expand Down Expand Up @@ -271,7 +271,7 @@ class MMSnapConnector extends SatsConnector {
// const libNetwork = await this.getNetwork();
// const senderAddress = bitcoin.payments.p2wpkh({ pubkey, network: libNetwork }).address!;

// const electrsClient = new DefaultElectrsClient(this.network as string);
// const electrsClient = new DefaultEsploraClient(this.network as string);

// const utxos = await electrsClient.getAddressUtxos(senderAddress);
// const inscriptionUtxo = await findUtxoForInscriptionId(electrsClient, utxos, inscriptionId);
Expand Down
4 changes: 2 additions & 2 deletions packages/sats-wagmi/src/hooks/useFeeRate.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DefaultElectrsClient } from '@gobob/bob-sdk';
import { DefaultEsploraClient } from '@gobob/bob-sdk';
import { CONFIRMATION_TARGET } from '@gobob/utils';
import { INTERVAL, UndefinedInitialDataOptions, useQuery } from '@gobob/react-query';

Expand All @@ -15,7 +15,7 @@ const useFeeRate = ({ query, confirmations = CONFIRMATION_TARGET }: UseFeeRatePr
return useQuery({
queryKey: ['sats-fee-rate', network],
queryFn: async () => {
const electrsClient = new DefaultElectrsClient(network);
const electrsClient = new DefaultEsploraClient(network);

const feeRate = await electrsClient.getFeeEstimate(confirmations);

Expand Down
2 changes: 1 addition & 1 deletion packages/utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"vitest": "^1.5.2"
},
"dependencies": {
"@gobob/bob-sdk": "^1.2.0",
"@gobob/bob-sdk": "^1.3.0",
"@scure/base": "^1.1.6",
"@scure/btc-signer": "^1.3.1",
"bitcoin-address-validation": "^2.2.3",
Expand Down
10 changes: 5 additions & 5 deletions packages/utils/src/inscription.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ElectrsClient } from '@gobob/bob-sdk';
import { EsploraClient } from '@gobob/bob-sdk';
import * as bitcoin from 'bitcoinjs-lib';
import { InscriptionId } from '@gobob/bob-sdk/dist/ordinal-api';

Expand Down Expand Up @@ -92,8 +92,8 @@ export function parseInscriptions(tx: bitcoin.Transaction) {
return inscriptions;
}

export async function getTxInscriptions(electrsClient: ElectrsClient, txid: string) {
const txHex = await electrsClient.getTransactionHex(txid);
export async function getTxInscriptions(esploraClient: EsploraClient, txid: string) {
const txHex = await esploraClient.getTransactionHex(txid);
const tx = bitcoin.Transaction.fromHex(txHex);

return parseInscriptions(tx);
Expand All @@ -116,9 +116,9 @@ export function createImageInscription(image: Buffer) {
return { contentType, content: image };
}

export async function getInscriptionFromId(electrsClient: ElectrsClient, inscriptionId: string) {
export async function getInscriptionFromId(esploraClient: EsploraClient, inscriptionId: string) {
const { txid, index } = InscriptionId.fromString(inscriptionId);
const inscriptions = await getTxInscriptions(electrsClient, txid);
const inscriptions = await getTxInscriptions(esploraClient, txid);

return inscriptions[index];
}
Expand Down
Loading