From f061f9430d7c117eb1a7f69a90c7a95dad434dce Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rui=20Sim=C3=A3o?=
Date: Fri, 21 Jun 2024 15:00:40 +0100
Subject: [PATCH 1/3] refactor(evm): btc bridge api update
---
apps/evm/src/lib/react-query/keys.ts | 3 +-
.../components/BridgeForm/BtcBridgeForm.tsx | 33 ++++++++++++-------
apps/evm/src/utils/onramp-api-client.ts | 16 ++-------
3 files changed, 24 insertions(+), 28 deletions(-)
diff --git a/apps/evm/src/lib/react-query/keys.ts b/apps/evm/src/lib/react-query/keys.ts
index fdc85abc8..af33f5c27 100644
--- a/apps/evm/src/lib/react-query/keys.ts
+++ b/apps/evm/src/lib/react-query/keys.ts
@@ -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'
diff --git a/apps/evm/src/pages/Bridge/components/BridgeForm/BtcBridgeForm.tsx b/apps/evm/src/pages/Bridge/components/BridgeForm/BtcBridgeForm.tsx
index b450a21ad..d875fdad0 100644
--- a/apps/evm/src/pages/Bridge/components/BridgeForm/BtcBridgeForm.tsx
+++ b/apps/evm/src/pages/Bridge/components/BridgeForm/BtcBridgeForm.tsx
@@ -41,8 +41,6 @@ type BtcBridgeFormProps = {
onFailOnRamp: () => void;
};
-const MIN_DEPOSIT_AMOUNT = 40000;
-
const gasEstimatePlaceholder = CurrencyAmount.fromRawAmount(BITCOIN, 0n);
const nativeToken = Ether.onChain(L2_CHAIN);
@@ -87,22 +85,30 @@ const BtcBridgeForm = ({
toast.error(e.message);
}, []);
- const { data: availableLiquidity, isLoading: isLoadingLiquidity } = useQuery({
+ const { data: maxQuoteData, 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 onRampApiClient.getQuote(btcToken.raw.address);
- return CurrencyAmount.fromRawAmount(BITCOIN, total);
+ return {
+ availableLiquidity: CurrencyAmount.fromRawAmount(BITCOIN, maxQuoteData.satoshis),
+ minDepositAmount: maxQuoteData.dust_threshold
+ };
}
});
- const hasLiquidity = useMemo(() => availableLiquidity?.greaterThan(MIN_DEPOSIT_AMOUNT), [availableLiquidity]);
+ const { availableLiquidity, minDepositAmount } = maxQuoteData || {};
+
+ const hasLiquidity = useMemo(
+ () => availableLiquidity?.greaterThan(minDepositAmount || 0),
+ [availableLiquidity, minDepositAmount]
+ );
const quoteDataEnabled = useMemo(() => {
return Boolean(
@@ -110,10 +116,10 @@ const BtcBridgeForm = ({
btcToken &&
evmAddress &&
btcAddress &&
- CurrencyAmount.fromBaseAmount(BITCOIN, debouncedAmount || 0).greaterThan(MIN_DEPOSIT_AMOUNT) &&
+ CurrencyAmount.fromBaseAmount(BITCOIN, debouncedAmount || 0).greaterThan(minDepositAmount || 0) &&
hasLiquidity
);
- }, [currencyAmount, btcToken, evmAddress, btcAddress, debouncedAmount, hasLiquidity]);
+ }, [currencyAmount, btcToken, evmAddress, btcAddress, debouncedAmount, minDepositAmount, hasLiquidity]);
const quoteQueryKey = bridgeKeys.btcQuote(evmAddress, btcAddress, Number(currencyAmount?.numerator));
@@ -267,7 +273,10 @@ const BtcBridgeForm = ({
const params: BridgeFormValidationParams = {
[BRIDGE_AMOUNT]: {
- minAmount: currencyAmount && new Big(MIN_DEPOSIT_AMOUNT / 10 ** currencyAmount?.currency.decimals),
+ minAmount:
+ currencyAmount && minDepositAmount
+ ? new Big(minDepositAmount / 10 ** currencyAmount?.currency.decimals)
+ : undefined,
maxAmount: new Big(balanceAmount.toExact())
},
[BRIDGE_RECIPIENT]: !!isSmartAccount
@@ -289,7 +298,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);
@@ -361,7 +370,7 @@ const BtcBridgeForm = ({
)}
- {!hasLiquidity && !isLoadingLiquidity && (
+ {!hasLiquidity && !isLoadingMaxQuote && (
There is currently no available liquidity to onramp BTC into {btcToken?.currency.symbol}.
diff --git a/apps/evm/src/utils/onramp-api-client.ts b/apps/evm/src/utils/onramp-api-client.ts
index 74112fa7b..d0ba572c8 100644
--- a/apps/evm/src/utils/onramp-api-client.ts
+++ b/apps/evm/src/utils/onramp-api-client.ts
@@ -29,8 +29,8 @@ class OnRampApiClient {
this.baseUrl = baseUrl;
}
- async getQuote(address: string, atomicAmount: number | string): Promise {
- const response = await fetch(`${this.baseUrl}/quote/${address}/${atomicAmount}`, {
+ async getQuote(address: string, atomicAmount?: number | string): Promise {
+ const response = await fetch(`${this.baseUrl}/quote/${address}/${atomicAmount || ''}`, {
headers: {
'Content-Type': 'application/json',
Accept: 'application/json'
@@ -84,18 +84,6 @@ class OnRampApiClient {
return response.json();
}
-
- async getTotalLiquidity(assetAddress: Address): Promise {
- const response = await fetch(`${this.baseUrl}/total/${assetAddress.toLowerCase()}`, {
- method: 'GET',
- headers: {
- 'Content-Type': 'application/json',
- Accept: 'application/json'
- }
- });
-
- return response.json();
- }
}
export const onRampApiClient = new OnRampApiClient('/onramp-api');
From c4247dc4d119d2bcdefc832bad8701a25801af3c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rui=20Sim=C3=A3o?=
Date: Wed, 3 Jul 2024 11:01:28 +0100
Subject: [PATCH 2/3] feat: final
---
apps/evm/.env.example | 6 ++
apps/evm/package.json | 1 +
apps/evm/src/lib/bob-sdk/gateway.ts | 5 ++
apps/evm/src/lib/bob-sdk/index.ts | 1 +
.../components/BridgeForm/BtcBridgeForm.tsx | 12 +--
.../Bridge/hooks/useGetOnRampTransactions.ts | 7 +-
apps/evm/src/utils/index.ts | 1 -
apps/evm/src/utils/onramp-api-client.ts | 89 -------------------
packages/sats-wagmi/package.json | 2 +-
packages/sats-wagmi/src/connectors/base.ts | 8 +-
packages/sats-wagmi/src/connectors/mm-snap.ts | 4 +-
packages/sats-wagmi/src/hooks/useFeeRate.tsx | 4 +-
packages/utils/package.json | 2 +-
packages/utils/src/inscription.ts | 10 +--
packages/utils/src/utxo.ts | 8 +-
pnpm-lock.yaml | 30 ++++---
16 files changed, 62 insertions(+), 128 deletions(-)
create mode 100644 apps/evm/src/lib/bob-sdk/gateway.ts
create mode 100644 apps/evm/src/lib/bob-sdk/index.ts
delete mode 100644 apps/evm/src/utils/onramp-api-client.ts
diff --git a/apps/evm/.env.example b/apps/evm/.env.example
index 48b53e491..2cb8ff363 100644
--- a/apps/evm/.env.example
+++ b/apps/evm/.env.example
@@ -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"
diff --git a/apps/evm/package.json b/apps/evm/package.json
index 7e3257762..42c728f2d 100644
--- a/apps/evm/package.json
+++ b/apps/evm/package.json
@@ -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:^",
diff --git a/apps/evm/src/lib/bob-sdk/gateway.ts b/apps/evm/src/lib/bob-sdk/gateway.ts
new file mode 100644
index 000000000..f762d882b
--- /dev/null
+++ b/apps/evm/src/lib/bob-sdk/gateway.ts
@@ -0,0 +1,5 @@
+import { GatewayApiClient } from '@gobob/bob-sdk';
+
+const gatewayClient = new GatewayApiClient('/onramp-api');
+
+export { gatewayClient };
diff --git a/apps/evm/src/lib/bob-sdk/index.ts b/apps/evm/src/lib/bob-sdk/index.ts
new file mode 100644
index 000000000..fc6761695
--- /dev/null
+++ b/apps/evm/src/lib/bob-sdk/index.ts
@@ -0,0 +1 @@
+export * from './gateway';
diff --git a/apps/evm/src/pages/Bridge/components/BridgeForm/BtcBridgeForm.tsx b/apps/evm/src/pages/Bridge/components/BridgeForm/BtcBridgeForm.tsx
index d875fdad0..1173d586c 100644
--- a/apps/evm/src/pages/Bridge/components/BridgeForm/BtcBridgeForm.tsx
+++ b/apps/evm/src/pages/Bridge/components/BridgeForm/BtcBridgeForm.tsx
@@ -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';
@@ -94,7 +94,7 @@ const BtcBridgeForm = ({
queryFn: async () => {
if (!currencyAmount || !btcToken) return;
- const maxQuoteData = await onRampApiClient.getQuote(btcToken.raw.address);
+ const maxQuoteData = await gatewayClient.getQuote(btcToken.raw.address);
return {
availableLiquidity: CurrencyAmount.fromRawAmount(BITCOIN, maxQuoteData.satoshis),
@@ -139,7 +139,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
);
@@ -191,12 +191,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() };
},
@@ -226,7 +226,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
diff --git a/apps/evm/src/pages/Bridge/hooks/useGetOnRampTransactions.ts b/apps/evm/src/pages/Bridge/hooks/useGetOnRampTransactions.ts
index 782b4089b..cd59e06f7 100644
--- a/apps/evm/src/pages/Bridge/hooks/useGetOnRampTransactions.ts
+++ b/apps/evm/src/pages/Bridge/hooks/useGetOnRampTransactions.ts
@@ -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;
@@ -21,12 +22,12 @@ type OnRampTransaction = {
};
const getOnRampTransactions = async (address: Address, l2Tokens: TokenData[]): Promise => {
- 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 => {
- 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;
diff --git a/apps/evm/src/utils/index.ts b/apps/evm/src/utils/index.ts
index db82e8c5a..478c570b4 100644
--- a/apps/evm/src/utils/index.ts
+++ b/apps/evm/src/utils/index.ts
@@ -1,4 +1,3 @@
export * from './api-client';
export * from './electrs-client';
-export * from './onramp-api-client';
export * from './math';
diff --git a/apps/evm/src/utils/onramp-api-client.ts b/apps/evm/src/utils/onramp-api-client.ts
deleted file mode 100644
index d0ba572c8..000000000
--- a/apps/evm/src/utils/onramp-api-client.ts
+++ /dev/null
@@ -1,89 +0,0 @@
-import { Address } from 'viem';
-
-type OnRampQuote = {
- onramp_address: Address;
- dust_threshold: number;
- satoshis: number;
- fee: number;
- gratuity: string;
- bitcoin_address: string;
- tx_proof_difficulty_factor: number;
-};
-
-type OnRampOrderResponse = {
- onramp_address: Address;
- token_address: Address;
- txid: string;
- status: boolean;
- timestamp: number;
- tokens: string;
- satoshis: number;
- fee: number;
- tx_proof_difficulty_factor: number;
-};
-
-class OnRampApiClient {
- private baseUrl: string;
-
- constructor(baseUrl: string) {
- this.baseUrl = baseUrl;
- }
-
- async getQuote(address: string, atomicAmount?: number | string): Promise {
- const response = await fetch(`${this.baseUrl}/quote/${address}/${atomicAmount || ''}`, {
- headers: {
- 'Content-Type': 'application/json',
- Accept: 'application/json'
- }
- });
-
- return await response.json();
- }
-
- // TODO: add error handling
- async createOrder(contractAddress: string, userAddress: Address, atomicAmount: number | string): Promise {
- const response = await fetch(`${this.baseUrl}/order`, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- Accept: 'application/json'
- },
- body: JSON.stringify({ onramp_address: contractAddress, user_address: userAddress, satoshis: atomicAmount })
- });
-
- if (!response.ok) {
- throw new Error('Failed to create order');
- }
-
- return await response.json();
- }
-
- async updateOrder(id: string, tx: string) {
- const response = await fetch(`${this.baseUrl}/order/${id}`, {
- method: 'PATCH',
- headers: {
- 'Content-Type': 'application/json',
- Accept: 'application/json'
- },
- body: JSON.stringify({ bitcoin_tx: tx })
- });
-
- if (!response.ok) {
- throw new Error('Failed to update order');
- }
- }
-
- async getOrders(userAddress: Address): Promise {
- const response = await fetch(`${this.baseUrl}/orders/${userAddress}`, {
- method: 'GET',
- headers: {
- 'Content-Type': 'application/json',
- Accept: 'application/json'
- }
- });
-
- return response.json();
- }
-}
-
-export const onRampApiClient = new OnRampApiClient('/onramp-api');
diff --git a/packages/sats-wagmi/package.json b/packages/sats-wagmi/package.json
index 0dbab4b6f..10e2588a7 100644
--- a/packages/sats-wagmi/package.json
+++ b/packages/sats-wagmi/package.json
@@ -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:^",
diff --git a/packages/sats-wagmi/src/connectors/base.ts b/packages/sats-wagmi/src/connectors/base.ts
index 9622806aa..a9f470310 100644
--- a/packages/sats-wagmi/src/connectors/base.ts
+++ b/packages/sats-wagmi/src/connectors/base.ts
@@ -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';
@@ -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);
@@ -176,7 +176,7 @@ abstract class SatsConnector {
}
async getTransaction(txId: string): Promise {
- const electrsClient = new DefaultElectrsClient(this.network as string);
+ const electrsClient = new DefaultEsploraClient(this.network as string);
return retry(
async (bail) => {
@@ -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;
diff --git a/packages/sats-wagmi/src/connectors/mm-snap.ts b/packages/sats-wagmi/src/connectors/mm-snap.ts
index 962eb4526..674efa19e 100644
--- a/packages/sats-wagmi/src/connectors/mm-snap.ts
+++ b/packages/sats-wagmi/src/connectors/mm-snap.ts
@@ -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();
@@ -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);
diff --git a/packages/sats-wagmi/src/hooks/useFeeRate.tsx b/packages/sats-wagmi/src/hooks/useFeeRate.tsx
index db79aeddd..e3089d75d 100644
--- a/packages/sats-wagmi/src/hooks/useFeeRate.tsx
+++ b/packages/sats-wagmi/src/hooks/useFeeRate.tsx
@@ -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';
@@ -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);
diff --git a/packages/utils/package.json b/packages/utils/package.json
index d9d200319..11616f224 100644
--- a/packages/utils/package.json
+++ b/packages/utils/package.json
@@ -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",
diff --git a/packages/utils/src/inscription.ts b/packages/utils/src/inscription.ts
index e7a87f4c0..59a141b4b 100644
--- a/packages/utils/src/inscription.ts
+++ b/packages/utils/src/inscription.ts
@@ -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';
@@ -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);
@@ -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];
}
diff --git a/packages/utils/src/utxo.ts b/packages/utils/src/utxo.ts
index 047734279..1e1fadda8 100644
--- a/packages/utils/src/utxo.ts
+++ b/packages/utils/src/utxo.ts
@@ -1,4 +1,4 @@
-import { DefaultElectrsClient, ElectrsClient, UTXO } from '@gobob/bob-sdk';
+import { DefaultEsploraClient, EsploraClient, UTXO } from '@gobob/bob-sdk';
import { DefaultOrdinalsClient, TESTNET_ORD_BASE_PATH } from '@gobob/bob-sdk/dist/ordinal-api';
import { Transaction, Script, selectUTXO, TEST_NETWORK, NETWORK, p2wpkh, p2sh } from '@scure/btc-signer';
import { hex } from '@scure/base';
@@ -39,7 +39,7 @@ export interface Input {
}
export async function findUtxoForInscriptionId(
- electrsClient: ElectrsClient,
+ esploraClient: EsploraClient,
utxos: UTXO[],
inscriptionId: string
): Promise {
@@ -61,7 +61,7 @@ export async function findUtxoForInscriptionId(
return utxo;
}
} else if (txid == utxo.txid) {
- const inscriptions = await getTxInscriptions(electrsClient, utxo.txid);
+ const inscriptions = await getTxInscriptions(esploraClient, utxo.txid);
if (typeof inscriptions[index] !== 'undefined') {
return utxo;
@@ -105,7 +105,7 @@ export async function createTransferWithOpReturn(
addressType: string,
publicKey?: string
): Promise {
- const electrsClient = new DefaultElectrsClient(network);
+ const electrsClient = new DefaultEsploraClient(network);
// eslint-disable-next-line no-console
console.log('Payment address:', paymentAddress);
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 679f9d8b7..ea61f8172 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -180,6 +180,9 @@ importers:
'@ethersproject/providers':
specifier: ^5.7.2
version: 5.7.2
+ '@gobob/bob-sdk':
+ specifier: 1.3.0
+ version: 1.3.0
'@gobob/chains':
specifier: workspace:^
version: link:../../packages/chains
@@ -441,8 +444,8 @@ importers:
specifier: ^2.2.3
version: 2.2.3
'@gobob/bob-sdk':
- specifier: ^1.2.0
- version: 1.2.0
+ specifier: ^1.3.0
+ version: 1.3.0
'@gobob/react-query':
specifier: workspace:^
version: link:../react-query
@@ -680,8 +683,8 @@ importers:
packages/utils:
dependencies:
'@gobob/bob-sdk':
- specifier: ^1.2.0
- version: 1.2.0
+ specifier: ^1.3.0
+ version: 1.3.0
'@scure/base':
specifier: ^1.1.6
version: 1.1.6
@@ -3517,9 +3520,12 @@ packages:
ts-interface-checker: 0.1.13
dev: true
- /@gobob/bob-sdk@1.2.0:
- resolution: {integrity: sha512-qugfTrYMqM5AAK10+E6qgCZgxEtp6xvY8+q9FPh/HL0e2JP5SBTeyG4jzherCvxYP+nuz08TwSqQW2yihw46+g==}
+ /@gobob/bob-sdk@1.3.0:
+ resolution: {integrity: sha512-NFrkl8cqgK7vFYnXdijkr3kTP2ZVWVMWeawUKRJHljZT6QB/P170kObI6jF88Z+oDM8u5dchbf1nmTne2lGLEA==}
dependencies:
+ '@scure/base': 1.1.7
+ '@scure/btc-signer': 1.3.2
+ bitcoin-address-validation: 2.2.3
bitcoinjs-lib: 6.1.6
dev: false
@@ -4159,7 +4165,7 @@ packages:
'@ethereumjs/tx': 4.2.0
'@metamask/superstruct': 3.0.0
'@noble/hashes': 1.4.0
- '@scure/base': 1.1.6
+ '@scure/base': 1.1.7
'@types/debug': 4.1.12
debug: 4.3.5(supports-color@8.1.1)
pony-cause: 2.1.11
@@ -6437,6 +6443,10 @@ packages:
/@scure/base@1.1.6:
resolution: {integrity: sha512-ok9AWwhcgYuGG3Zfhyqg+zwl+Wn5uE+dwC0NV/2qQkx4dABbb/bx96vWu8NSj+BNjjSjno+JRYRjle1jV08k3g==}
+ /@scure/base@1.1.7:
+ resolution: {integrity: sha512-PPNYBslrLNNUQ/Yad37MHYsNQtK67EhWb6WtSvNLLPo7SdVZgkUjD6Dg+5On7zNwmskf8OX7I7Nx5oN+MIWE0g==}
+ dev: false
+
/@scure/bip32@1.3.2:
resolution: {integrity: sha512-N1ZhksgwD3OBlwTv3R6KFEcPojl/W4ElJOeCZdi+vuI5QmTFwLq3OFf2zd2ROpKvxFdgZ6hUpb0dx9bVNEwYCA==}
dependencies:
@@ -6449,7 +6459,7 @@ packages:
dependencies:
'@noble/curves': 1.4.0
'@noble/hashes': 1.4.0
- '@scure/base': 1.1.6
+ '@scure/base': 1.1.7
dev: false
/@scure/bip39@1.2.1:
@@ -6462,7 +6472,7 @@ packages:
resolution: {integrity: sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==}
dependencies:
'@noble/hashes': 1.4.0
- '@scure/base': 1.1.6
+ '@scure/base': 1.1.7
dev: false
/@scure/btc-signer@1.3.2:
@@ -16862,7 +16872,7 @@ packages:
/micro-packed@0.6.3:
resolution: {integrity: sha512-VmVkyc7lIzAq/XCPFuLc/CwQ7Ehs5XDK3IwqsZHiBIDttAI9Gs7go6Lv4lNRuAIKrGKcRTtthFKUNyHS0S4wJQ==}
dependencies:
- '@scure/base': 1.1.6
+ '@scure/base': 1.1.7
dev: false
/micromatch@4.0.5:
From 698aca77b85ab9802257e291c7112328482204c3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rui=20Sim=C3=A3o?=
Date: Wed, 3 Jul 2024 15:11:22 +0100
Subject: [PATCH 3/3] feat: final
---
.../components/BridgeForm/BtcBridgeForm.tsx | 24 +++++++------------
1 file changed, 9 insertions(+), 15 deletions(-)
diff --git a/apps/evm/src/pages/Bridge/components/BridgeForm/BtcBridgeForm.tsx b/apps/evm/src/pages/Bridge/components/BridgeForm/BtcBridgeForm.tsx
index 1173d586c..e031a3d0a 100644
--- a/apps/evm/src/pages/Bridge/components/BridgeForm/BtcBridgeForm.tsx
+++ b/apps/evm/src/pages/Bridge/components/BridgeForm/BtcBridgeForm.tsx
@@ -41,6 +41,8 @@ type BtcBridgeFormProps = {
onFailOnRamp: () => void;
};
+const MIN_DEPOSIT_AMOUNT = 4000;
+
const gasEstimatePlaceholder = CurrencyAmount.fromRawAmount(BITCOIN, 0n);
const nativeToken = Ether.onChain(L2_CHAIN);
@@ -85,7 +87,7 @@ const BtcBridgeForm = ({
toast.error(e.message);
}, []);
- const { data: maxQuoteData, isLoading: isLoadingMaxQuote } = useQuery({
+ const { data: availableLiquidity, isLoading: isLoadingMaxQuote } = useQuery({
enabled: Boolean(btcToken),
queryKey: bridgeKeys.btcQuote(evmAddress, btcAddress, 'max'),
refetchInterval: INTERVAL.MINUTE,
@@ -96,19 +98,11 @@ const BtcBridgeForm = ({
const maxQuoteData = await gatewayClient.getQuote(btcToken.raw.address);
- return {
- availableLiquidity: CurrencyAmount.fromRawAmount(BITCOIN, maxQuoteData.satoshis),
- minDepositAmount: maxQuoteData.dust_threshold
- };
+ return CurrencyAmount.fromRawAmount(BITCOIN, maxQuoteData.satoshis);
}
});
- const { availableLiquidity, minDepositAmount } = maxQuoteData || {};
-
- const hasLiquidity = useMemo(
- () => availableLiquidity?.greaterThan(minDepositAmount || 0),
- [availableLiquidity, minDepositAmount]
- );
+ const hasLiquidity = useMemo(() => availableLiquidity?.greaterThan(MIN_DEPOSIT_AMOUNT), [availableLiquidity]);
const quoteDataEnabled = useMemo(() => {
return Boolean(
@@ -116,10 +110,10 @@ const BtcBridgeForm = ({
btcToken &&
evmAddress &&
btcAddress &&
- CurrencyAmount.fromBaseAmount(BITCOIN, debouncedAmount || 0).greaterThan(minDepositAmount || 0) &&
+ CurrencyAmount.fromBaseAmount(BITCOIN, debouncedAmount || 0).greaterThan(MIN_DEPOSIT_AMOUNT) &&
hasLiquidity
);
- }, [currencyAmount, btcToken, evmAddress, btcAddress, debouncedAmount, minDepositAmount, hasLiquidity]);
+ }, [currencyAmount, btcToken, evmAddress, btcAddress, debouncedAmount, hasLiquidity]);
const quoteQueryKey = bridgeKeys.btcQuote(evmAddress, btcAddress, Number(currencyAmount?.numerator));
@@ -274,8 +268,8 @@ const BtcBridgeForm = ({
const params: BridgeFormValidationParams = {
[BRIDGE_AMOUNT]: {
minAmount:
- currencyAmount && minDepositAmount
- ? new Big(minDepositAmount / 10 ** currencyAmount?.currency.decimals)
+ currencyAmount && MIN_DEPOSIT_AMOUNT
+ ? new Big(MIN_DEPOSIT_AMOUNT / 10 ** currencyAmount?.currency.decimals)
: undefined,
maxAmount: new Big(balanceAmount.toExact())
},