mirror of
https://github.com/Brotocol-xyz/bro-sdk.git
synced 2026-01-12 06:44:18 +08:00
Squashed commit of the following:
commit a9488404b028aaeef5b7ab867a2392a969834fb0 Author: c4605 <bolasblack@gmail.com> Date: Mon May 12 23:36:07 2025 +0800 docs: optimize deps commita50d05dca2Author: sofinico <nicolettisofia1@gmail.com> Date: Wed May 7 16:50:43 2025 +0200 chore: address bro-sdk team review commit47fcf33525Merge:d13a68d2188881Author: Sofía <36451685+sofinico@users.noreply.github.com> Date: Tue May 6 17:36:14 2025 +0200 Merge branch 'snapshots/v0.5' into feat/update-v0.5-readme commitd13a68d4f8Author: sofinico <nicolettisofia1@gmail.com> Date: Tue May 6 17:18:15 2025 +0200 fix: add temporal patch to prevent `pnpm docs:watch` from failing commitfef755490fAuthor: sofinico <nicolettisofia1@gmail.com> Date: Tue May 6 17:15:20 2025 +0200 chore(docs): fix lint errors and remove unsed packages commitf8739f7f17Author: Facundo Lerena <faculerena@gmail.com> Date: Wed Apr 30 16:17:59 2025 -0300 docs: Update dev-instructions file. commit78de614697Author: Facundo Lerena <faculerena@gmail.com> Date: Wed Apr 30 16:06:12 2025 -0300 docs: Update Readme to address example location commit4592f31a85Author: Facundo Lerena <faculerena@gmail.com> Date: Wed Apr 30 16:05:45 2025 -0300 docs: Update `Bitcoin.ts` mock commit355bec1a9bMerge:a3f0e9a4fe7500Author: Facundo Lerena <faculerena@gmail.com> Date: Wed Apr 30 15:56:15 2025 -0300 Merge branch 'snapshots/v0.5' of github.com:Brotocol-xyz/bro-sdk into feat/update-v0.5-readme commita3f0e9ab41Author: Facundo Lerena <faculerena@gmail.com> Date: Tue Apr 29 16:10:23 2025 -0300 docs: Remove `docs/readmeCodeSnippets.ts` commit23f725bfa9Author: Facundo Lerena <faculerena@gmail.com> Date: Tue Apr 29 16:08:55 2025 -0300 docs: Moved exampels into code-snippets, adressed comments in #20 commitf44e4382b7Merge:980907652d6e8cAuthor: Facundo Lerena <faculerena@gmail.com> Date: Tue Apr 29 11:48:05 2025 -0300 Merged snapshot commit9809076820Merge:f53158757f8b37Author: Sofía <36451685+sofinico@users.noreply.github.com> Date: Mon Apr 28 14:47:40 2025 +0200 Merge pull request #2 from CoinFabrik/feat/update-v0.5-readme-runes-brc20 Docs: Add code snippets for Runes and BRC20 commit57f8b3790fAuthor: Facundo Lerena <faculerena@gmail.com> Date: Fri Apr 25 15:29:48 2025 -0300 Docs: Update code snippets Added Runes and BRC20 bridging examples commitf5315877eeAuthor: sofinico <nicolettisofia1@gmail.com> Date: Fri Apr 25 17:47:04 2025 +0200 docs: address peer-review [wip] commit12d8f150e9Author: sofinico <nicolettisofia1@gmail.com> Date: Tue Apr 22 14:07:26 2025 +0200 docs: update readme basic operations and add table of contents commitc52e9b834aAuthor: sofinico <nicolettisofia1@gmail.com> Date: Tue Apr 22 12:28:42 2025 +0200 docs: update code snippets * Replace `getSupportedRoutes` with `getPossibleRoutes` * Ajust readmeCodeSnippets.ts to rebrand where applicable * Add note explaining `functionArgs` serialization design for bridge from Stacks * Add @types/node dev dependency for readmeCodeSnippets.ts commitfcddf91a43Author: sofinico <nicolettisofia1@gmail.com> Date: Tue Apr 22 11:17:49 2025 +0200 docs: update readme Changes include: * Removed static token support table and replaced it with SDK methods that dynamically retrieve supported tokens. * Replaced the supported chains table with a bullet-point list for improved readability. * Added a "Basic Operations" section to introcude general usage patterns of the SDK. * Improved code snippets, with correspondace to the docs/readmeCodeSnippets.ts file for consistency. commit029c19922dAuthor: sofinico <nicolettisofia1@gmail.com> Date: Tue Apr 22 11:05:19 2025 +0200 chore: add branded literal type doc commit13090aa374Author: sofinico <nicolettisofia1@gmail.com> Date: Tue Apr 22 11:04:53 2025 +0200 docs: create readme code snippets and dev instructions files done #20
This commit is contained in:
416
README.md
416
README.md
@@ -1,19 +1,39 @@
|
||||
# BroSDK
|
||||
|
||||
`@brotocol-xyz/bro-sdk` is a TypeScript SDK designed to integrate with Brotocol's on-chain and off-chain infrastructure. It is web3 library-agnostic, meaning you can use your preferred library to send and broadcast transactions while the SDK handles the rest.
|
||||
|
||||
🐙 **Brotocol isn't just a bridge—it's the liquidity layer for Bitcoin and the essential connector for Bitcoin DeFi** 🐙
|
||||
|
||||
BroSDK enables seamless asset transfers between Bitcoin, Stacks, and EVM-compatible blockchains. It supports cross-chain swaps, Runes & BRC20 metaprotocols, and DEX aggregator integrations.
|
||||
## Table of Contents
|
||||
|
||||
The SDK allows users to interact with Brotocol smart contracts from backend environments, browsers, and mobile apps. It securely handles cross-chain transfers, fee estimation, route planning, and transaction size calculations by using Brotocol's on-chain and off-chain infrastructure.
|
||||
- [BroSDK](#brosdk)
|
||||
- [Table of Contents](#table-of-contents)
|
||||
- [Features](#features)
|
||||
- [Installation](#installation)
|
||||
- [Usage](#usage)
|
||||
- [Supported Chains](#supported-chains)
|
||||
- [Mainnet Chains](#mainnet-chains)
|
||||
- [Testnet Chains](#testnet-chains)
|
||||
- [Helpers](#helpers)
|
||||
- [Supported Tokens](#supported-tokens)
|
||||
- [Retrieve a `TokenId`](#retrieve-a-tokenid)
|
||||
- [Available Routes](#available-routes)
|
||||
- [Basic Operations](#basic-operations)
|
||||
- [`bridgeInfoFrom` methods](#bridgeinfofrom-methods)
|
||||
- [`estimateBridgeTransactionFrom` methods](#estimatebridgetransactionfrom-methods)
|
||||
- [`bridgeFrom` methods](#bridgefrom-methods)
|
||||
- [License](#license)
|
||||
|
||||
## Features
|
||||
|
||||
- Asset transfers between Bitcoin, Stacks, and EVM-compatible blockchains
|
||||
- Support for Runes and BRC20 metaprotocols
|
||||
- Cross-chain swaps and DEX aggregator integrations
|
||||
- Flexible design, allowing integration with any Bitcoin and web3 library
|
||||
|
||||
## Installation
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- [Node.js](https://nodejs.org/en)
|
||||
- [pnpm](https://pnpm.io/)
|
||||
|
||||
### Install
|
||||
With [pnpm](https://pnpm.io/):
|
||||
|
||||
```bash
|
||||
pnpm install @brotocol-xyz/bro-sdk
|
||||
@@ -21,261 +41,203 @@ pnpm install @brotocol-xyz/bro-sdk
|
||||
|
||||
## Usage
|
||||
|
||||
The [`BroSDK`](./src/BroSDK.ts) class provides the core functions of the library. To create an instance:
|
||||
The [`BroSDK`](https://releases-latest.xlink-sdk.pages.dev/classes/index.BroSDK) class provides the core functions of the library. To create an instance:
|
||||
|
||||
```typescript
|
||||
```ts
|
||||
import { BroSDK } from "@brotocol-xyz/bro-sdk"
|
||||
const sdk = new BroSDK()
|
||||
```
|
||||
|
||||
For the full API reference, including a full list of available methods and their usage, visit the [SDK Documentation](https://releases-latest.xlink-sdk.pages.dev).
|
||||
|
||||
### Supported Blockchains and Tokens
|
||||
### Supported Chains
|
||||
|
||||
#### [`KnownChainId`](https://releases-latest.xlink-sdk.pages.dev/modules/index.KnownChainId)
|
||||
#### Mainnet Chains
|
||||
|
||||
Defines types and utility functions for supported networks, ensuring only valid chain IDs are used within the SDK.
|
||||
- **Bitcoin**, **Runes** & **BRC20**
|
||||
- **Stacks**
|
||||
- **EVM**: Ethereum, BSC, CoreDAO, Bsquared, BOB, Bitlayer, Lorenzo, Merlin, AILayer, Mode, XLayer, Arbitrum, Aurora, Manta, Linea, Base
|
||||
|
||||
#### Testnet Chains
|
||||
|
||||
- **Bitcoin**, **Runes** & **BRC20**
|
||||
- **Stacks**
|
||||
- **EVM**: Sepolia, BSC Testnet, CoreDAO Testnet, Blife Testnet, Bitboy Testnet, Bera Testnet
|
||||
|
||||
#### Helpers
|
||||
|
||||
The [`KnownChainId`](https://releases-latest.xlink-sdk.pages.dev/modules/index.KnownChainId) namespace defines types and utility functions for all supported mainnet and testnet networks.
|
||||
|
||||
Usage example:
|
||||
|
||||
```ts
|
||||
import { KnownChainId } from "@brotocol-xyz/bro-sdk"
|
||||
|
||||
// Bitcoin
|
||||
const bitcoinChainId = KnownChainId.Bitcoin.Mainnet
|
||||
const bitcoinTestnetChainId = KnownChainId.Bitcoin.Testnet
|
||||
|
||||
// EVM
|
||||
const ethereumChainId = KnownChainId.EVM.Ethereum
|
||||
const ethereumTestnetChainId = KnownChainId.EVM.Sepolia
|
||||
|
||||
// Utility function usage example
|
||||
KnownChainId.isEVMTestnetChain(KnownChainId.EVM.Sepolia) // Returns true
|
||||
KnownChainId.isEVMMainnetChain(KnownChainId.EVM.Sepolia) // Returns false
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> Runes and BRC20 metaprotocols are treated as distinct chains within the SDK, even though they share Bitcoin as the underlying blockchain.
|
||||
|
||||
<!--
|
||||
Decided to remove the table as it seemed a little bulky for the README. But left it here for future reference.
|
||||
|
||||
#### Available chains
|
||||
|
||||
| Namespace | Mainnet | Testnet |
|
||||
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
|
||||
| :---------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------: |
|
||||
| Bitcoin | `Mainnet` | `Testnet` |
|
||||
| Runes | `Mainnet` | `Testnet` |
|
||||
| BRC20 | `Mainnet` | `Testnet` |
|
||||
| Stacks | `Mainnet` | `Testnet` |
|
||||
| EVM | `Ethereum`, `BSC`, `CoreDAO`, `Bsquared`, `BOB`, `Bitlayer`, `Lorenzo`, `Merlin`, `AILayer`, `Mode`, `XLayer`, `Arbitrum`, `Aurora`, `Manta`, `Linea`, `Base` | `Sepolia`, `BSCTestnet`, `CoreDAOTestnet`, `BlifeTestnet`, `BitboyTestnet`, `BeraTestnet` |
|
||||
| EVM | `Ethereum`, `BSC`, `CoreDAO`, `Bsquared`, `BOB`, `Bitlayer`, `Lorenzo`, `Merlin`, `AILayer`, `Mode`, `XLayer`, `Arbitrum`, `Aurora`, `Manta`, `Linea`, `Base` | `Sepolia`, `BSCTestnet`, `CoreDAOTestnet`, `BlifeTestnet`, `BitboyTestnet`, `BeraTestnet` | -->
|
||||
|
||||
#### [`KnownTokenId`](https://releases-latest.xlink-sdk.pages.dev/modules/index.KnownTokenId)
|
||||
### Supported Tokens
|
||||
|
||||
Defines types, utility functions, and supported tokens within the SDK.
|
||||
Token support is **dynamic**, meaning new tokens can be added without requiring SDK updates. Instead of relying on a static list, the SDK provides methods to fetch supported tokens at runtime. Tokens are represented using the `TokenId` type — this is how the library internally handles and identifies tokens.
|
||||
|
||||
| Namespace | Tokens |
|
||||
| --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Bitcoin | `BTC` |
|
||||
| Runes | _To be confirmed_ |
|
||||
| BRC20 | _To be confirmed_ |
|
||||
| Stacks | `sUSDT`, `sLUNR`, `aBTC`, `ALEX`, `sSKO`, `vLiSTX`, `vLiALEX`, `vLiaBTC`,`uBTC`, `DB20`, `DOG`, `STX`, `TRUMP` |
|
||||
| EVM | `USDT`, `sUSDT`, `USDC`, `aBTC`, `WTCB`, `BTCB`, `cbBTC`, `uBTC`, `wuBTC`, `STX`, `vLiSTX`, `ALEX`, `vLiALEX`, `LUNR`, `SKO`, `DB20`, `DOG`, `TRUMP` |
|
||||
Also, check the [`KnownTokenId`](https://releases-latest.xlink-sdk.pages.dev/modules/index.KnownTokenId) namespace to see types and utility functions for all supported tokens.
|
||||
|
||||
### Use Cases
|
||||
#### Retrieve a `TokenId`
|
||||
|
||||
Create an instance of the SDK with default options:
|
||||
```ts
|
||||
// For BRC20 provide the tick symbol
|
||||
const brc20Token = await sdk.brc20TickToBRC20Token(
|
||||
KnownChainId.BRC20.Mainnet,
|
||||
"alex$",
|
||||
)
|
||||
|
||||
```typescript
|
||||
import { BroSDK } from "@brotocol-xyz/bro-sdk"
|
||||
const broSdk = new BroSDK()
|
||||
```
|
||||
// For Runes provide the runes ID
|
||||
const runesToken = await sdk.runesIdToRunesToken(
|
||||
KnownChainId.Runes.Mainnet,
|
||||
"500:20",
|
||||
)
|
||||
|
||||
#### Bridge from Stacks
|
||||
|
||||
Use case showcasing a transfer of 100 `sUSDT` from Stacks to `USDT` on Ethereum using BroSDK.
|
||||
|
||||
```typescript
|
||||
import {
|
||||
BridgeFromStacksInput,
|
||||
KnownChainId,
|
||||
KnownTokenId,
|
||||
toSDKNumberOrUndefined,
|
||||
} from '@brotocol-xyz/bro-sdk';
|
||||
import { serializeCVBytes, makeContractCall, broadcastTransaction } from '@stacks/transactions';
|
||||
|
||||
// Retrieve bridge information
|
||||
const bridgeInfo = await broSdk.bridgeInfoFromStacks({
|
||||
fromChain: KnownChainId.Stacks.Mainnet,
|
||||
toChain: KnownChainId.EVM.Ethereum,
|
||||
fromToken: KnownTokenId.Stacks.sUSDT,
|
||||
toToken: KnownTokenId.EVM.USDT,
|
||||
amount: toSDKNumberOrUndefined(100),
|
||||
});
|
||||
|
||||
console.log("Bridge Info:", bridgeInfo);
|
||||
|
||||
// Define bridge operation input
|
||||
const bridgeFromStacksInput: BridgeFromStacksInput = {
|
||||
fromChain: KnownChainId.Stacks.Mainnet,
|
||||
toChain: KnownChainId.EVM.Ethereum,
|
||||
fromToken: KnownTokenId.Stacks.sUSDT,
|
||||
toToken: KnownTokenId.EVM.USDT,
|
||||
fromAddress: /* Sender Stacks principal */,
|
||||
toAddress: /* Receiver EVM address */,
|
||||
amount: toSDKNumberOrUndefined(100),
|
||||
sendTransaction: async (tx: ContractCallOptions) => {
|
||||
/**
|
||||
* Implementation for sending transaction on Stacks mainnet.
|
||||
* Refer to: https://github.com/hirosystems/stacks.js/tree/main/packages/transactions#smart-contract-function-call
|
||||
*/
|
||||
const transaction = await makeContractCall({
|
||||
contractAddress: tx.contractAddress,
|
||||
contractName: tx.contractName,
|
||||
functionName: tx.functionName,
|
||||
functionArgs: tx.functionArgs,
|
||||
postConditions: /* Add post conditions if necessary */,
|
||||
validateWithAbi: true,
|
||||
senderKey: /* Sender private key */,
|
||||
network: "mainnet",
|
||||
});
|
||||
|
||||
const broadcastResponse = await broadcastTransaction(transaction, "mainnet");
|
||||
return { txid: broadcastResponse.txid };
|
||||
},
|
||||
};
|
||||
|
||||
// Example of how a `sendTransaction` argument would look like
|
||||
const contractCallOptionsExample: ContractCallOptions = {
|
||||
contractAddress: "SP2XD7417HGPRTREMKF748VNEQPDRR0RMANB7X1NK",
|
||||
contractName: "cross-peg-out-endpoint-v2-01",
|
||||
functionName: "transfer-to-unwrap",
|
||||
functionArgs: [].map(arg => serializeCVBytes(arg)), // Array elements must be Clarity values
|
||||
};
|
||||
|
||||
// Perform the bridge operation
|
||||
const result = await broSdk.bridgeFromStacks(bridgeFromStacksInput);
|
||||
console.log("Transaction ID:", result.txid);
|
||||
```
|
||||
|
||||
#### Bridge from EVM
|
||||
|
||||
Use case showcasing a transfer of 100 `USDT` from Ethereum to `UsSDT` on Stacks using BroSDK.
|
||||
|
||||
```typescript
|
||||
import {
|
||||
BridgeFromEVMInput,
|
||||
KnownChainId,
|
||||
KnownTokenId,
|
||||
toSDKNumberOrUndefined,
|
||||
} from "@brotocol-xyz/bro-sdk"
|
||||
import { ethers } from "ethers";
|
||||
|
||||
// Retrieve bridge information
|
||||
const bridgeInfo = await broSdk.bridgeInfoFromEVM({
|
||||
fromChain: KnownChainId.EVM.Ethereum,
|
||||
toChain: KnownChainId.Stacks.Mainnet,
|
||||
fromToken: KnownTokenId.EVM.USDT,
|
||||
toToken: KnownTokenId.Stacks.sUSDT,
|
||||
amount: toSDKNumberOrUndefined(100),
|
||||
});
|
||||
|
||||
console.log("Bridge Info:", bridgeInfo);
|
||||
|
||||
// Example signer setup using ethers.js
|
||||
const provider = new ethers.providers.JsonRpcProvider("https://mainnet.someprovider.io/YOUR_PROJECT_ID");
|
||||
const signer = new ethers.Wallet("SENDER_PRIVATE_KEY", provider);
|
||||
|
||||
const bridgeFromEVMInput: BridgeFromEVMInput = {
|
||||
fromChain: KnownChainId.EVM.Ethereum,
|
||||
toChain: KnownChainId.Stacks.Mainnet,
|
||||
fromToken: KnownTokenId.EVM.USDT,
|
||||
toToken: KnownTokenId.Stacks.sUSDT,
|
||||
fromAddress: /* Sender EVM address */,
|
||||
toAddress: /* Receiver Stacks principal */,
|
||||
amount: toSDKNumberOrUndefined(100),
|
||||
sendTransaction: async (tx:
|
||||
// For Stacks provide the contract address
|
||||
const stacksToken = await sdk.stacksAddressToStacksToken(
|
||||
KnownChainId.Stacks.Mainnet,
|
||||
{
|
||||
from: EVMAddress /* Sender EVM address */
|
||||
to: EVMAddress /* Bridge Endpoint address */
|
||||
data: Uint8Array /* Transaction data */
|
||||
recommendedGasLimit: SDKNumber /* Recommended gas limit */
|
||||
value?: SDKNumber /* Transaction value */
|
||||
}
|
||||
): Promise<{ txHash: string }> => {
|
||||
/**
|
||||
* Implementation for sending transaction on Ethereum mainnet
|
||||
* See https://docs.ethers.org/v5/api/contract/contract/ for reference
|
||||
*/
|
||||
const txRequest = {
|
||||
from: tx.from,
|
||||
to: tx.to,
|
||||
data: ethers.utils.hexlify(tx.data),
|
||||
gasLimit: ethers.BigNumber.from(tx.recommendedGasLimit.split(" ")[0]), // Convert string to BigNumber
|
||||
};
|
||||
|
||||
const sentTx = await signer.sendTransaction(txRequest);
|
||||
const receipt = await sentTx.wait();
|
||||
return { txHash: receipt.transactionHash };
|
||||
deployerAddress: "SP2XD7417HGPRTREMKF748VNEQPDRR0RMANB7X1NK",
|
||||
contractName: "token-abtc",
|
||||
},
|
||||
};
|
||||
)
|
||||
|
||||
// Perform the bridge operation
|
||||
const result = await broSdk.bridgeFromEVM(bridgeFromEVMInput);
|
||||
console.log("Transaction ID:", result.txHash);
|
||||
// For EVM tokens provide the contract address
|
||||
const evmToken = await sdk.evmAddressToEVMToken(
|
||||
KnownChainId.EVM.Ethereum,
|
||||
"0x31761a152F1e96F966C041291644129144233b0B",
|
||||
)
|
||||
```
|
||||
|
||||
#### Bridge from Bitcoin
|
||||
If a token is **unsupported**, these functions return `Promise<undefined>`.
|
||||
|
||||
Use case showcasing a transfer of 1 `BTC` from Bitcoin to `WBTC` on Ethereum using BroSDK.
|
||||
> [!NOTE]
|
||||
> Some Stacks and EVM tokens are still statically defined in `KnownTokenId.Stacks` and `KnownTokenId.EVM` for backward compatibility, but future additions will also be dynamically handled.
|
||||
|
||||
```typescript
|
||||
import {
|
||||
BridgeFromBitcoinInput,
|
||||
KnownChainId,
|
||||
KnownTokenId,
|
||||
toSDKNumberOrUndefined,
|
||||
} from "@brotocol-xyz/bro-sdk"
|
||||
/* Use your preferred Bitcoin libs here */
|
||||
import { Psbt, networks, Transaction, script } from "bitcoinjs-lib";
|
||||
import { ECPairFactory } from "ecpair";
|
||||
import * as tinysecp from "tiny-secp256k1";
|
||||
import axios from "axios";
|
||||
> [!WARNING]
|
||||
>
|
||||
> `TokenId` values **might change in future updates** (no backward compatibility guaranteed). To ensure validity, always get fresh `TokenId`s at runtime using SDK methods—never cache them or construct them manually.
|
||||
|
||||
// Retrieve bridge information
|
||||
const bridgeInfo = await broSdk.bridgeInfoFromBitcoin({
|
||||
fromChain: KnownChainId.Bitcoin.Mainnet,
|
||||
### Available Routes
|
||||
|
||||
```ts
|
||||
// Get all Brotocol available routes
|
||||
const allRoutes = await sdk.getPossibleRoutes()
|
||||
|
||||
// Get routes filtered by source chain
|
||||
const routesBySourceChain = await sdk.getPossibleRoutes({
|
||||
fromChain: KnownChainId.BRC20.Mainnet,
|
||||
})
|
||||
|
||||
// Get routes filtered by source and target chain
|
||||
const routesBySourceAndTargetChain = await sdk.getPossibleRoutes({
|
||||
fromChain: KnownChainId.BRC20.Mainnet,
|
||||
toChain: KnownChainId.EVM.Ethereum,
|
||||
fromToken: KnownTokenId.Bitcoin.BTC,
|
||||
toToken: KnownTokenId.EVM.WBTC,
|
||||
amount: toSDKNumberOrUndefined(1),
|
||||
});
|
||||
})
|
||||
|
||||
console.log("Bridge Info:", bridgeInfo)
|
||||
|
||||
const bridgeFromBitcoinInput: BridgeFromBitcoinInput = {
|
||||
fromChain: KnownChainId.Bitcoin.Mainnet,
|
||||
fromToken: KnownTokenId.Bitcoin.BTC,
|
||||
// Check if a specific token pair is supported for at least one route
|
||||
const isSupported = await sdk.isSupportedRoute({
|
||||
fromChain: KnownChainId.BRC20.Mainnet,
|
||||
toChain: KnownChainId.EVM.Ethereum,
|
||||
toToken: KnownTokenId.EVM.WBTC,
|
||||
fromAddress: /* Sender Bitcoin address */,
|
||||
toAddress: /* Receiver EVM address */,
|
||||
amount: toSDKNumberOrUndefined(1),
|
||||
networkFeeRate: 10n,
|
||||
reselectSpendableUTXOs: async (
|
||||
satsToSend: bigint,
|
||||
pinnedUTXOs: UTXOSpendable[],
|
||||
lastTimeSelectedUTXOs: UTXOSpendable[]
|
||||
): Promise<UTXOSpendable[]> => {
|
||||
/**
|
||||
* Implementation for selecting spendable UTXOs from the wallet
|
||||
* This should fetch available UTXOs from a Bitcoin node or explorer API
|
||||
*/
|
||||
return [];
|
||||
},
|
||||
signPsbt: async (tx: { psbt: Uint8Array; signInputs: number[] }): Promise<{ psbt: Uint8Array }> => {
|
||||
/**
|
||||
* Implementation for signing a Bitcoin PSBT (Partially Signed Bitcoin Transaction)
|
||||
* See https://github.com/bitcoinjs/bitcoinjs-lib for reference
|
||||
*/
|
||||
let psbt = Psbt.fromBuffer(tx.psbt);
|
||||
tx.signInputs.forEach((index) => {
|
||||
psbt.signInput(index, keyPair);
|
||||
});
|
||||
psbt.finalizeAllInputs();
|
||||
return { psbt: psbt.toBuffer() };
|
||||
},
|
||||
sendTransaction: async (tx: { hex: string }): Promise<{ txid: string }> => {
|
||||
/**
|
||||
* Implementation for broadcasting a Bitcoin transaction with Axios
|
||||
* Using a Bitcoin node or explorer API (e.g., Blockstream API)
|
||||
*/
|
||||
const response = await axios.post("https://some-mempool/api/tx", tx.hex, {
|
||||
headers: { "Content-Type": "text/plain" },
|
||||
});
|
||||
return { txid: response.data };
|
||||
},
|
||||
};
|
||||
fromToken: brc20Token as KnownTokenId.BRC20Token,
|
||||
toToken: evmToken as KnownTokenId.EVMToken,
|
||||
})
|
||||
|
||||
// Perform the bridge operation
|
||||
const result = await broSdk.bridgeFromBitcoin(bridgeFromBitcoinInput);
|
||||
console.log("Transaction ID:", result.txid);
|
||||
// If the token pair is supported, get available routes for that pair
|
||||
if (isSupported) {
|
||||
const routesByPair = await sdk.getPossibleRoutes({
|
||||
fromChain: KnownChainId.BRC20.Mainnet,
|
||||
toChain: KnownChainId.EVM.Ethereum,
|
||||
fromToken: brc20Token as KnownTokenId.BRC20Token,
|
||||
toToken: evmToken as KnownTokenId.EVMToken,
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
### Basic Operations
|
||||
|
||||
The SDK provides three main methods for handling cross-chain asset transfers.
|
||||
|
||||
- [`bridgeInfoFrom<Chain>`](#bridgeinfofrom-methods)
|
||||
- [`estimateBridgeTransactionFrom<Chain>`](#estimatebridgetransactionfrom-methods)
|
||||
- [`bridgeFrom<Chain>`](#bridgefrom-methods)
|
||||
|
||||
#### `bridgeInfoFrom` methods
|
||||
|
||||
Retrieve data to perform a cross-chain transfer:
|
||||
|
||||
- Validate whether the route is supported (throws an error if not).
|
||||
- Retrieve Brotocol fee values and the exact amount that will arrive on destination chain.
|
||||
|
||||
> [!NOTE]
|
||||
> These methods do not check the bridge's min/max amount limits. These checks are enforced on-chain, and the transaction will revert if the amount conditions are not met.
|
||||
|
||||
```ts
|
||||
import { toSDKNumberOrUndefined } from "@brotocol-xyz/bro-sdk"
|
||||
|
||||
// Retrieve bridge info to perform a transfer from Stacks to EVM
|
||||
const bridgeInfo = await sdk.bridgeInfoFromStacks({
|
||||
fromChain: KnownChainId.Stacks.Mainnet,
|
||||
toChain: KnownChainId.EVM.Ethereum,
|
||||
fromToken: stacksToken as KnownTokenId.StacksToken,
|
||||
toToken: evmToken as KnownTokenId.EVMToken,
|
||||
amount: toSDKNumberOrUndefined(100_000_000), // Assume 6 decimals
|
||||
})
|
||||
```
|
||||
|
||||
#### `estimateBridgeTransactionFrom` methods
|
||||
|
||||
Estimate the transaction fee and virtual size (vbytes) for bridging from Bitcoin-based networks (Bitcoin, Runes, BRC20). Fees are calculated as:
|
||||
|
||||
```any
|
||||
fee = virtualSize [vbytes] × networkFeeRate [sat/vbyte]
|
||||
```
|
||||
|
||||
`networkFeeRate` is provided by dev. Typical fee rates range from 1–100 sat/vbyte, depending on network congestion and desired confirmation speed. See this [reference](https://learnmeabitcoin.com/technical/transaction/size/) for more on transaction size.
|
||||
|
||||
**Why is this important?** Miners prioritize transactions with higher fees per vbyte. Accurately estimating the transaction virtual size allows to set an appropriate fee, so the transaction is confirmed in a timely manner.
|
||||
|
||||
See the [`examples/bridgeFrom/Bitcoin.ts`](https://github.com/Brotocol-xyz/bro-sdk/tree/master/examples/bridgeFrom/Bitcoin.ts) file for usage example.
|
||||
|
||||
#### `bridgeFrom` methods
|
||||
|
||||
Once the route is validated, the cross-chain transfer can be initiated. These methods **construct and submit** the transaction on the source chain.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> The SDK does **not always** broadcast transactions—it provides the data required to sign and send them. The `sendTransaction` function parameter must be implemented by the developer using their preferred web3 library. The SDK provides the necessary arguments, including contract addresses, function to call and call data.
|
||||
|
||||
Examples on how to use the `bridgeFrom` methods can be found in the [examples folder](https://github.com/Brotocol-xyz/bro-sdk/tree/master/examples/bridgeFrom/).
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the terms of the [MIT license](LICENSE).
|
||||
@@ -1,4 +1,4 @@
|
||||
# Test Instructions
|
||||
# Dev Instructions
|
||||
|
||||
## Visualize Typedoc Documentation
|
||||
|
||||
@@ -10,9 +10,19 @@ pnpm run docs:watch
|
||||
|
||||
In a new terminal window, run:
|
||||
|
||||
```bash
|
||||
pnpx http-server generated/docs
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```bash
|
||||
cd generated/docs
|
||||
python -m http.server 8080
|
||||
```
|
||||
|
||||
Open `http://localhost:8080` in your browser to view the documentation.
|
||||
|
||||
## README Examples
|
||||
|
||||
Version history of the README examples is tracked at [`../examples/bridgeFrom`](../examples/bridgeFrom).
|
||||
|
||||
161
examples/bridgeFrom/BRC20.ts
Normal file
161
examples/bridgeFrom/BRC20.ts
Normal file
@@ -0,0 +1,161 @@
|
||||
// Bridge From BRC20
|
||||
|
||||
import {
|
||||
GetConfirmedSpendableUTXOFn,
|
||||
reselectSpendableUTXOsFactory,
|
||||
UTXOBasic,
|
||||
} from "../../../src/bitcoinHelpers"
|
||||
import {
|
||||
BroSDK,
|
||||
KnownTokenId,
|
||||
KnownChainId,
|
||||
BridgeFromBRC20Input,
|
||||
} from "../../../src/index"
|
||||
|
||||
import { Psbt, payments, networks } from "bitcoinjs-lib"
|
||||
import axios from "axios"
|
||||
|
||||
const sdk = new BroSDK()
|
||||
|
||||
// For BRC20 provide the tick symbol
|
||||
const brc20Token: KnownTokenId.BRC20Token = (await sdk.brc20TickToBRC20Token(
|
||||
KnownChainId.BRC20.Mainnet,
|
||||
"alex$",
|
||||
))!
|
||||
|
||||
// For EVM tokens provide the contract address
|
||||
const evmToken: KnownTokenId.EVMToken = (await sdk.evmAddressToEVMToken(
|
||||
KnownChainId.EVM.Ethereum,
|
||||
"0x31761a152F1e96F966C041291644129144233b0B",
|
||||
))!
|
||||
|
||||
// Mock functions for key management
|
||||
const getPublicKey = async (): Promise<string> => {
|
||||
// This is a mock implementation
|
||||
// In a real implementation, this would return the user's public key
|
||||
return "02a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7"
|
||||
}
|
||||
|
||||
const signTx = async (hex: string): Promise<string> => {
|
||||
// This is a mock implementation
|
||||
// In a real implementation, this would sign the transaction with the user's private key
|
||||
return "mock_signature"
|
||||
}
|
||||
|
||||
const publicKey = await getPublicKey()
|
||||
const { address: senderAddress, output: scriptPubKey } = payments.p2wpkh({
|
||||
pubkey: Buffer.from(publicKey, "hex"),
|
||||
network: networks.bitcoin,
|
||||
})
|
||||
|
||||
// Select UTXOs to spend
|
||||
const reselectSpendableNetworkFeeUTXOs: BridgeFromBRC20Input["reselectSpendableNetworkFeeUTXOs"] =
|
||||
async (satsToSend, lastTimeSelectedUTXOs) => {
|
||||
// Example of available UTXOs from a Bitcoin node or API
|
||||
const availableUTXOs: UTXOBasic[] = [
|
||||
{
|
||||
txId: "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
|
||||
index: 0,
|
||||
amount: 5000n,
|
||||
},
|
||||
{
|
||||
txId: "abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890",
|
||||
index: 1,
|
||||
amount: 3000n,
|
||||
},
|
||||
{
|
||||
txId: "7890abcdef1234567890abcdef1234567890abcdef1234567890abcdef123456",
|
||||
index: 2,
|
||||
amount: 2000n,
|
||||
},
|
||||
]
|
||||
|
||||
const getUTXOSpendable: GetConfirmedSpendableUTXOFn = async (
|
||||
utxo: UTXOBasic,
|
||||
) => {
|
||||
// For this example, we'll create a simple UTXOSpendable object
|
||||
return {
|
||||
...utxo,
|
||||
scriptPubKey: scriptPubKey!,
|
||||
addressType: "p2wpkh",
|
||||
blockHeight: 800000n, // Example block height
|
||||
}
|
||||
}
|
||||
|
||||
// Create the reselect function with factory helper
|
||||
const reselectFn = reselectSpendableUTXOsFactory(
|
||||
availableUTXOs,
|
||||
getUTXOSpendable,
|
||||
)
|
||||
|
||||
return reselectFn(satsToSend, lastTimeSelectedUTXOs)
|
||||
}
|
||||
|
||||
const sendTransaction: BridgeFromBRC20Input["sendTransaction"] = async tx => {
|
||||
/**
|
||||
* Implementation example for broadcasting a Bitcoin transaction with Axios
|
||||
*/
|
||||
const response = await axios.post("https://blockstream.info/api/tx", tx.hex, {
|
||||
headers: { "Content-Type": "text/plain" },
|
||||
})
|
||||
return { txid: response.data }
|
||||
}
|
||||
|
||||
const bridgeFromBRC20Input: BridgeFromBRC20Input = {
|
||||
fromChain: KnownChainId.BRC20.Mainnet,
|
||||
fromToken: brc20Token,
|
||||
toChain: KnownChainId.EVM.Ethereum,
|
||||
toToken: evmToken,
|
||||
fromAddress: senderAddress!,
|
||||
fromAddressScriptPubKey: scriptPubKey!,
|
||||
toAddress: "0x31751a152F1e95F966C041291644129144233b0B",
|
||||
inputInscriptionUTXO: {
|
||||
txId: "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
|
||||
index: 0,
|
||||
amount: 1000n,
|
||||
scriptPubKey: scriptPubKey!,
|
||||
addressType: "p2wpkh",
|
||||
},
|
||||
networkFeeRate: 10n,
|
||||
reselectSpendableNetworkFeeUTXOs,
|
||||
networkFeeChangeAddress: senderAddress!,
|
||||
networkFeeChangeAddressScriptPubKey: scriptPubKey!,
|
||||
signPsbt: async tx => {
|
||||
const psbt = Psbt.fromBuffer(Buffer.from(tx.psbt))
|
||||
|
||||
for (const index of tx.signBitcoinInputs) {
|
||||
const signature = await signTx(psbt.toHex())
|
||||
|
||||
// Add the signature to the PSBT
|
||||
psbt.updateInput(index, {
|
||||
partialSig: [
|
||||
{
|
||||
pubkey: Buffer.from(await getPublicKey(), "hex"),
|
||||
signature: Buffer.from(signature, "hex"),
|
||||
},
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
for (const index of tx.signInscriptionInputs) {
|
||||
const signature = await signTx(psbt.toHex())
|
||||
|
||||
// Add the signature to the PSBT
|
||||
psbt.updateInput(index, {
|
||||
partialSig: [
|
||||
{
|
||||
pubkey: Buffer.from(await getPublicKey(), "hex"),
|
||||
signature: Buffer.from(signature, "hex"),
|
||||
},
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
psbt.finalizeAllInputs()
|
||||
return { psbt: psbt.toBuffer() }
|
||||
},
|
||||
sendTransaction,
|
||||
}
|
||||
|
||||
const result = await sdk.bridgeFromBRC20(bridgeFromBRC20Input)
|
||||
console.log("Bitcoin Transaction ID:", result.txid)
|
||||
167
examples/bridgeFrom/Bitcoin.ts
Normal file
167
examples/bridgeFrom/Bitcoin.ts
Normal file
@@ -0,0 +1,167 @@
|
||||
// Bridge From BTC
|
||||
|
||||
import {
|
||||
GetConfirmedSpendableUTXOFn,
|
||||
reselectSpendableUTXOsFactory,
|
||||
UTXOBasic,
|
||||
} from "@brotocol-xyz/bro-sdk/bitcoinHelpers"
|
||||
import {
|
||||
BroSDK,
|
||||
KnownTokenId,
|
||||
KnownChainId,
|
||||
toSDKNumberOrUndefined,
|
||||
BridgeFromBitcoinInput,
|
||||
} from "@brotocol-xyz/bro-sdk"
|
||||
import { Psbt, payments, networks } from "bitcoinjs-lib"
|
||||
import axios from "axios"
|
||||
|
||||
const sdk = new BroSDK()
|
||||
|
||||
// For EVM tokens provide the contract address
|
||||
const evmToken = await sdk.evmAddressToEVMToken(
|
||||
KnownChainId.EVM.Ethereum,
|
||||
"0x31761a152F1e96F966C041291644129144233b0B",
|
||||
)
|
||||
|
||||
// Mock functions for key management
|
||||
// In a real implementation, these would be provided by the user's environment
|
||||
const getPublicKey = async (): Promise<string> => {
|
||||
// This is a mock implementation
|
||||
// In a real implementation, this would return the user's public key
|
||||
return "02a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7"
|
||||
}
|
||||
|
||||
const signTx = async (hex: string): Promise<string> => {
|
||||
// This is a mock implementation
|
||||
// In a real implementation, this would sign the transaction with the user's private key
|
||||
return "mock_signature"
|
||||
}
|
||||
|
||||
// Get address and scriptPubKey
|
||||
const publicKey = await getPublicKey()
|
||||
const { address: senderAddress, output: scriptPubKey } = payments.p2wpkh({
|
||||
pubkey: Buffer.from(publicKey, "hex"),
|
||||
network: networks.bitcoin,
|
||||
})
|
||||
|
||||
// Select UTXOs to spend
|
||||
const reselectSpendableUTXOs: BridgeFromBitcoinInput["reselectSpendableUTXOs"] =
|
||||
async (satsToSend, lastTimeSelectedUTXOs) => {
|
||||
// Example of available UTXOs from a Bitcoin node or API
|
||||
const availableUTXOs: UTXOBasic[] = [
|
||||
{
|
||||
txId: "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
|
||||
index: 0,
|
||||
amount: 5000n,
|
||||
},
|
||||
{
|
||||
txId: "abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890",
|
||||
index: 1,
|
||||
amount: 3000n,
|
||||
},
|
||||
{
|
||||
txId: "7890abcdef1234567890abcdef1234567890abcdef1234567890abcdef123456",
|
||||
index: 2,
|
||||
amount: 2000n,
|
||||
},
|
||||
]
|
||||
|
||||
// Function to convert basic UTXOs to spendable UTXOs with scriptPubKey
|
||||
const getUTXOSpendable: GetConfirmedSpendableUTXOFn = async (
|
||||
utxo: UTXOBasic,
|
||||
) => {
|
||||
// For this example, we'll create a simple UTXOSpendable object
|
||||
return {
|
||||
...utxo,
|
||||
scriptPubKey: scriptPubKey!,
|
||||
addressType: "p2wpkh",
|
||||
blockHeight: 800000n, // Example block height
|
||||
}
|
||||
}
|
||||
|
||||
// Create the reselect function with factory helper
|
||||
const reselectFn = reselectSpendableUTXOsFactory(
|
||||
availableUTXOs,
|
||||
getUTXOSpendable,
|
||||
)
|
||||
|
||||
return reselectFn(satsToSend, lastTimeSelectedUTXOs)
|
||||
}
|
||||
|
||||
// Sign a Bitcoin PSBT
|
||||
const signPsbt: BridgeFromBitcoinInput["signPsbt"] = async tx => {
|
||||
/**
|
||||
* Implementation example for signing a Bitcoin PSBT (Partially Signed Bitcoin Transaction)
|
||||
*/
|
||||
const psbt = Psbt.fromBuffer(Buffer.from(tx.psbt))
|
||||
|
||||
// For each input that needs to be signed
|
||||
for (const index of tx.signInputs) {
|
||||
// Get the input's sighash
|
||||
const input = psbt.data.inputs[index]
|
||||
// @ts-ignore
|
||||
const sighash = input.sighashType
|
||||
|
||||
// Sign the transaction using the mocked signTx function
|
||||
const signature = await signTx(psbt.toHex())
|
||||
|
||||
// Add the signature to the PSBT
|
||||
psbt.updateInput(index, {
|
||||
partialSig: [
|
||||
{
|
||||
pubkey: Buffer.from(await getPublicKey(), "hex"),
|
||||
signature: Buffer.from(signature, "hex"),
|
||||
},
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
psbt.finalizeAllInputs()
|
||||
return { psbt: psbt.toBuffer() }
|
||||
}
|
||||
|
||||
// Broadcast the signed transaction
|
||||
const sendTransaction: BridgeFromBitcoinInput["sendTransaction"] = async tx => {
|
||||
/**
|
||||
* Implementation example for broadcasting a Bitcoin transaction with Axios
|
||||
*/
|
||||
const response = await axios.post("https://blockstream.info/api/tx", tx.hex, {
|
||||
headers: { "Content-Type": "text/plain" },
|
||||
})
|
||||
return { txid: response.data }
|
||||
}
|
||||
|
||||
// Estimate transaction fee and virtual size before performing the bridge operation
|
||||
const estimateTransaction = await sdk.estimateBridgeTransactionFromBitcoin({
|
||||
fromChain: KnownChainId.Bitcoin.Mainnet,
|
||||
fromToken: KnownTokenId.Bitcoin.BTC,
|
||||
toChain: KnownChainId.EVM.Ethereum,
|
||||
toToken: evmToken as KnownTokenId.EVMToken,
|
||||
fromAddressScriptPubKey: scriptPubKey!,
|
||||
fromAddress: senderAddress!,
|
||||
toAddress: "0x31751a152F1e95F966C041291644129144233b0B",
|
||||
amount: toSDKNumberOrUndefined(1),
|
||||
networkFeeRate: 10n,
|
||||
reselectSpendableUTXOs: reselectSpendableUTXOs,
|
||||
})
|
||||
|
||||
console.log("Estimated Transaction: ", estimateTransaction)
|
||||
|
||||
const bridgeFromBitcoinInput: BridgeFromBitcoinInput = {
|
||||
fromChain: KnownChainId.Bitcoin.Mainnet,
|
||||
fromToken: KnownTokenId.Bitcoin.BTC,
|
||||
toChain: KnownChainId.EVM.Ethereum,
|
||||
toToken: evmToken as KnownTokenId.EVMToken,
|
||||
fromAddressScriptPubKey: scriptPubKey!,
|
||||
fromAddress: senderAddress!,
|
||||
toAddress: "0x31751a152F1e95F966C041291644129144233b0B",
|
||||
amount: toSDKNumberOrUndefined(1),
|
||||
networkFeeRate: 10n, // Expressed in satoshis per virtual byte (sat/vbyte).
|
||||
reselectSpendableUTXOs,
|
||||
signPsbt,
|
||||
sendTransaction,
|
||||
}
|
||||
|
||||
// Perform the bridge operation
|
||||
const result = await sdk.bridgeFromBitcoin(bridgeFromBitcoinInput)
|
||||
console.log("Bitcoin Transaction ID:", result.txid)
|
||||
79
examples/bridgeFrom/EVM.ts
Normal file
79
examples/bridgeFrom/EVM.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
// Bridge From EVM
|
||||
|
||||
import {
|
||||
BroSDK,
|
||||
KnownTokenId,
|
||||
KnownChainId,
|
||||
toSDKNumberOrUndefined,
|
||||
BridgeFromEVMInput,
|
||||
EVMAddress,
|
||||
SDKNumber,
|
||||
formatSDKNumber,
|
||||
} from "@brotocol-xyz/bro-sdk"
|
||||
|
||||
// Choose your preferred web3 lib here
|
||||
import { ethers } from "ethers"
|
||||
|
||||
const sdk = new BroSDK()
|
||||
|
||||
// For Stacks provide the contract address
|
||||
const stacksToken: KnownTokenId.StacksToken =
|
||||
(await sdk.stacksAddressToStacksToken(KnownChainId.Stacks.Mainnet, {
|
||||
deployerAddress: "SP2XD7417HGPRTREMKF748VNEQPDRR0RMANB7X1NK",
|
||||
contractName: "token-abtc",
|
||||
}))!
|
||||
|
||||
// For EVM tokens provide the contract address
|
||||
const evmToken: KnownTokenId.EVMToken = (await sdk.evmAddressToEVMToken(
|
||||
KnownChainId.EVM.Ethereum,
|
||||
"0x31761a152F1e96F966C041291644129144233b0B",
|
||||
))!
|
||||
|
||||
// Example signer setup using ethers.js
|
||||
const provider = new ethers.JsonRpcProvider(
|
||||
"https://mainnet.someprovider.io/YOUR_PROJECT_ID",
|
||||
)
|
||||
const signer = new ethers.Wallet(
|
||||
"000000000000000000000000000000000000000000000000000000000000002d",
|
||||
provider,
|
||||
)
|
||||
const signerAddress = signer.address as `0x${string}`
|
||||
|
||||
const bridgeFromEVMInput: BridgeFromEVMInput = {
|
||||
fromChain: KnownChainId.EVM.Ethereum,
|
||||
toChain: KnownChainId.Stacks.Mainnet,
|
||||
fromToken: evmToken,
|
||||
toToken: stacksToken,
|
||||
// Sender Ethereum address
|
||||
fromAddress: signerAddress,
|
||||
// Receiver Stacks principal
|
||||
toAddress: "SP2ZD731ANQZT6J4K3F5N8A40ZXWXC1XFXHVVQFKE",
|
||||
amount: toSDKNumberOrUndefined(100),
|
||||
sendTransaction: async (tx: {
|
||||
from: EVMAddress // Sender Ethereum address
|
||||
to: EVMAddress // Bridge Endpoint address
|
||||
data: Uint8Array
|
||||
recommendedGasLimit: SDKNumber
|
||||
value?: SDKNumber
|
||||
}): Promise<{ txHash: string }> => {
|
||||
/**
|
||||
* Implementation for sending transaction on Ethereum mainnet
|
||||
* See https://docs.ethers.org/v6/api/contract/ for reference
|
||||
*/
|
||||
const txRequest = {
|
||||
from: tx.from,
|
||||
to: tx.to,
|
||||
data: ethers.hexlify(tx.data),
|
||||
gasLimit: formatSDKNumber(tx.recommendedGasLimit),
|
||||
}
|
||||
|
||||
const sentTx = await signer.sendTransaction(txRequest)
|
||||
const receipt = await sentTx.wait()
|
||||
if (receipt === null) throw new Error("Transaction receipt is null")
|
||||
return { txHash: receipt.hash }
|
||||
},
|
||||
}
|
||||
|
||||
// Perform the bridge operation
|
||||
const result = await sdk.bridgeFromEVM(bridgeFromEVMInput)
|
||||
console.log("Transaction ID:", result.txHash)
|
||||
189
examples/bridgeFrom/Runes.ts
Normal file
189
examples/bridgeFrom/Runes.ts
Normal file
@@ -0,0 +1,189 @@
|
||||
// Bridge From Runes
|
||||
import {
|
||||
GetConfirmedSpendableUTXOFn,
|
||||
reselectSpendableUTXOsFactory,
|
||||
UTXOBasic,
|
||||
} from "@brotocol-xyz/bro-sdk/bitcoinHelpers"
|
||||
import {
|
||||
BroSDK,
|
||||
KnownTokenId,
|
||||
KnownChainId,
|
||||
toSDKNumberOrUndefined,
|
||||
BridgeFromRunesInput,
|
||||
RunesUTXOSpendable,
|
||||
} from "@brotocol-xyz/bro-sdk"
|
||||
import { Psbt, payments, networks } from "bitcoinjs-lib"
|
||||
import axios from "axios"
|
||||
|
||||
const sdk = new BroSDK()
|
||||
|
||||
// For Runes provide the runes ID
|
||||
const runesToken: KnownTokenId.RunesToken = (await sdk.runesIdToRunesToken(
|
||||
KnownChainId.Runes.Mainnet,
|
||||
"500:20",
|
||||
))!
|
||||
|
||||
// For EVM tokens provide the contract address
|
||||
const evmToken: KnownTokenId.EVMToken = (await sdk.evmAddressToEVMToken(
|
||||
KnownChainId.EVM.Ethereum,
|
||||
"0x31761a152F1e96F966C041291644129144233b0B",
|
||||
))!
|
||||
|
||||
// Mock functions for key management
|
||||
// In a real implementation, these would be provided by the user's environment
|
||||
const getPublicKey = async (): Promise<string> => {
|
||||
// This is a mock implementation
|
||||
// In a real implementation, this would return the user's public key
|
||||
return "02a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7"
|
||||
}
|
||||
|
||||
const signTx = async (hex: string): Promise<string> => {
|
||||
// This is a mock implementation
|
||||
// In a real implementation, this would sign the transaction with the user's private key
|
||||
return "mock_signature"
|
||||
}
|
||||
|
||||
// Get address and scriptPubKey
|
||||
const publicKey = await getPublicKey()
|
||||
const { address: senderAddress, output: scriptPubKey } = payments.p2wpkh({
|
||||
pubkey: Buffer.from(publicKey, "hex"),
|
||||
network: networks.bitcoin,
|
||||
})
|
||||
|
||||
// Select UTXOs to spend for network fees
|
||||
const reselectSpendableNetworkFeeUTXOsForRunes: BridgeFromRunesInput["reselectSpendableNetworkFeeUTXOs"] =
|
||||
async (satsToSend, lastTimeSelectedUTXOs) => {
|
||||
// Example of available UTXOs from a Bitcoin node or API
|
||||
const availableUTXOs: UTXOBasic[] = [
|
||||
{
|
||||
txId: "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
|
||||
index: 0,
|
||||
amount: 5000n,
|
||||
},
|
||||
{
|
||||
txId: "abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890",
|
||||
index: 1,
|
||||
amount: 3000n,
|
||||
},
|
||||
{
|
||||
txId: "7890abcdef1234567890abcdef1234567890abcdef1234567890abcdef123456",
|
||||
index: 2,
|
||||
amount: 2000n,
|
||||
},
|
||||
]
|
||||
|
||||
// Function to convert basic UTXOs to spendable UTXOs with scriptPubKey
|
||||
const getUTXOSpendable: GetConfirmedSpendableUTXOFn = async (
|
||||
utxo: UTXOBasic,
|
||||
) => {
|
||||
// For this example, we'll create a simple UTXOSpendable object
|
||||
return {
|
||||
...utxo,
|
||||
scriptPubKey: scriptPubKey!,
|
||||
addressType: "p2wpkh",
|
||||
blockHeight: 800000n, // Example block height
|
||||
}
|
||||
}
|
||||
|
||||
// Create the reselect function with factory helper
|
||||
const reselectFn = reselectSpendableUTXOsFactory(
|
||||
availableUTXOs,
|
||||
getUTXOSpendable,
|
||||
)
|
||||
|
||||
return reselectFn(satsToSend, lastTimeSelectedUTXOs)
|
||||
}
|
||||
|
||||
// Example Runes UTXOs
|
||||
const runesUTXOs: RunesUTXOSpendable[] = [
|
||||
{
|
||||
txId: "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
|
||||
index: 0,
|
||||
amount: 1000n,
|
||||
scriptPubKey: scriptPubKey!,
|
||||
addressType: "p2wpkh",
|
||||
runes: [
|
||||
{
|
||||
runeId: "500:20",
|
||||
runeDivisibility: 8,
|
||||
runeAmount: 100000000n, // 1.0 rune
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
// Sign a Bitcoin PSBT for Runes
|
||||
const signPsbtForRunes: BridgeFromRunesInput["signPsbt"] = async tx => {
|
||||
const psbt = Psbt.fromBuffer(Buffer.from(tx.psbt))
|
||||
|
||||
// For each Bitcoin input that needs to be signed
|
||||
for (const index of tx.signBitcoinInputs) {
|
||||
// Sign the transaction using the mocked signTx function
|
||||
const signature = await signTx(psbt.toHex())
|
||||
|
||||
// Add the signature to the PSBT
|
||||
psbt.updateInput(index, {
|
||||
partialSig: [
|
||||
{
|
||||
pubkey: Buffer.from(await getPublicKey(), "hex"),
|
||||
signature: Buffer.from(signature, "hex"),
|
||||
},
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
// For each Runes input that needs to be signed
|
||||
for (const index of tx.signRunesInputs) {
|
||||
// Sign the transaction using the mocked signTx function
|
||||
const signature = await signTx(psbt.toHex())
|
||||
|
||||
// Add the signature to the PSBT
|
||||
psbt.updateInput(index, {
|
||||
partialSig: [
|
||||
{
|
||||
pubkey: Buffer.from(await getPublicKey(), "hex"),
|
||||
signature: Buffer.from(signature, "hex"),
|
||||
},
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
psbt.finalizeAllInputs()
|
||||
return { psbt: psbt.toBuffer() }
|
||||
}
|
||||
|
||||
// Broadcast the signed transaction
|
||||
const sendTransactionForRunes: BridgeFromRunesInput["sendTransaction"] =
|
||||
async tx => {
|
||||
const response = await axios.post(
|
||||
"https://blockstream.info/api/tx",
|
||||
tx.hex,
|
||||
{
|
||||
headers: { "Content-Type": "text/plain" },
|
||||
},
|
||||
)
|
||||
return { txid: response.data }
|
||||
}
|
||||
|
||||
// Create the bridge input
|
||||
const bridgeFromRunesInput: BridgeFromRunesInput = {
|
||||
fromChain: KnownChainId.Runes.Mainnet,
|
||||
fromToken: runesToken,
|
||||
toChain: KnownChainId.EVM.Ethereum,
|
||||
toToken: evmToken,
|
||||
fromAddress: senderAddress!,
|
||||
fromAddressScriptPubKey: scriptPubKey!,
|
||||
toAddress: "0x31751a152F1e95F966C041291644129144233b0B",
|
||||
amount: toSDKNumberOrUndefined(1), // 1.0 rune
|
||||
inputRuneUTXOs: runesUTXOs,
|
||||
networkFeeRate: 10n,
|
||||
reselectSpendableNetworkFeeUTXOs: reselectSpendableNetworkFeeUTXOsForRunes,
|
||||
networkFeeChangeAddress: senderAddress!,
|
||||
networkFeeChangeAddressScriptPubKey: scriptPubKey!,
|
||||
signPsbt: signPsbtForRunes,
|
||||
sendTransaction: sendTransactionForRunes,
|
||||
}
|
||||
|
||||
// Perform the bridge operation
|
||||
const result = await sdk.bridgeFromRunes(bridgeFromRunesInput)
|
||||
console.log("Bitcoin Transaction ID:", result.txid)
|
||||
80
examples/bridgeFrom/Stacks.ts
Normal file
80
examples/bridgeFrom/Stacks.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
// Bridge From Stacks
|
||||
import {
|
||||
BroSDK,
|
||||
KnownTokenId,
|
||||
KnownChainId,
|
||||
BridgeFromStacksInput,
|
||||
toSDKNumberOrUndefined,
|
||||
BridgeFromStacksInput_ContractCallOptions as ContractCallOptions,
|
||||
} from "@brotocol-xyz/bro-sdk"
|
||||
import {
|
||||
makeContractCall,
|
||||
broadcastTransaction,
|
||||
deserializeCV,
|
||||
} from "@stacks/transactions"
|
||||
|
||||
const sdk = new BroSDK()
|
||||
|
||||
// For Stacks provide the contract address
|
||||
const stacksToken: KnownTokenId.StacksToken =
|
||||
(await sdk.stacksAddressToStacksToken(KnownChainId.Stacks.Mainnet, {
|
||||
deployerAddress: "SP2XD7417HGPRTREMKF748VNEQPDRR0RMANB7X1NK",
|
||||
contractName: "token-abtc",
|
||||
}))!
|
||||
|
||||
// For EVM tokens provide the contract address
|
||||
const evmToken: KnownTokenId.EVMToken = (await sdk.evmAddressToEVMToken(
|
||||
KnownChainId.EVM.Ethereum,
|
||||
"0x31761a152F1e96F966C041291644129144233b0B",
|
||||
))!
|
||||
|
||||
const bridgeInfo = await sdk.bridgeInfoFromStacks({
|
||||
fromChain: KnownChainId.Stacks.Mainnet,
|
||||
toChain: KnownChainId.EVM.Ethereum,
|
||||
fromToken: stacksToken,
|
||||
toToken: evmToken,
|
||||
amount: toSDKNumberOrUndefined(100_000_000),
|
||||
})
|
||||
|
||||
console.log("Bridge Info:", bridgeInfo)
|
||||
|
||||
const bridgeFromStacksInput: BridgeFromStacksInput = {
|
||||
fromChain: KnownChainId.Stacks.Mainnet,
|
||||
toChain: KnownChainId.EVM.Ethereum,
|
||||
fromToken: stacksToken,
|
||||
toToken: evmToken,
|
||||
fromAddress: "SP2ZD731ANQZT6J4K3F5N8A40ZXWXC1XFXHVVQFKE",
|
||||
// Receiver EVM address
|
||||
toAddress: "0x31751a152F1e95F966C041291644129144233b0B",
|
||||
amount: toSDKNumberOrUndefined(100),
|
||||
sendTransaction: async (tx: ContractCallOptions) => {
|
||||
/**
|
||||
* Implementation for sending transaction on Stacks mainnet.
|
||||
* Refer to:
|
||||
* - https://github.com/hirosystems/stacks.js/tree/main/packages/transactions#smart-contract-function-call
|
||||
* - https://stacks.js.org/functions/_stacks_transactions.makeContractCall
|
||||
* - https://stacks.js.org/functions/_stacks_transactions.broadcastTransaction
|
||||
*/
|
||||
const transaction = await makeContractCall({
|
||||
contractAddress: tx.contractAddress,
|
||||
contractName: tx.contractName,
|
||||
functionName: tx.functionName,
|
||||
// Deserialize each element of functionArgs and convert it into ClarityValue[]
|
||||
functionArgs: tx.functionArgs.map(arg => deserializeCV(arg)),
|
||||
postConditions: [] /* Add post conditions */,
|
||||
validateWithAbi: true,
|
||||
senderKey:
|
||||
"b244296d5907de9864c0b0d51f98a13c52890be0404e83f273144cd5b9960eed01",
|
||||
network: "mainnet",
|
||||
})
|
||||
|
||||
const broadcastResponse = await broadcastTransaction({
|
||||
transaction,
|
||||
network: "mainnet",
|
||||
})
|
||||
return { txid: broadcastResponse.txid }
|
||||
},
|
||||
}
|
||||
|
||||
const result = await sdk.bridgeFromStacks(bridgeFromStacksInput)
|
||||
console.log("Transaction ID:", result.txid)
|
||||
20
examples/bridgeFrom/package.json
Normal file
20
examples/bridgeFrom/package.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "bro-sdk-bridgeFrom-example",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"private": true,
|
||||
"main": null,
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@brotocol-xyz/bro-sdk": "file:../..",
|
||||
"@types/node": "^22.15.17",
|
||||
"axios": "^1.9.0",
|
||||
"bitcoinjs-lib": "^6.1.7",
|
||||
"ethers": "^6.14.0"
|
||||
}
|
||||
}
|
||||
791
examples/bridgeFrom/pnpm-lock.yaml
generated
Normal file
791
examples/bridgeFrom/pnpm-lock.yaml
generated
Normal file
@@ -0,0 +1,791 @@
|
||||
lockfileVersion: '9.0'
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
importers:
|
||||
|
||||
.:
|
||||
dependencies:
|
||||
'@brotocol-xyz/bro-sdk':
|
||||
specifier: file:../..
|
||||
version: file:../..(@stacks/common@7.0.2)
|
||||
'@types/node':
|
||||
specifier: ^22.15.17
|
||||
version: 22.15.17
|
||||
axios:
|
||||
specifier: ^1.9.0
|
||||
version: 1.9.0
|
||||
bitcoinjs-lib:
|
||||
specifier: ^6.1.7
|
||||
version: 6.1.7
|
||||
ethers:
|
||||
specifier: ^6.14.0
|
||||
version: 6.14.0
|
||||
|
||||
packages:
|
||||
|
||||
'@adraffy/ens-normalize@1.10.1':
|
||||
resolution: {integrity: sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==}
|
||||
|
||||
'@brotocol-xyz/bro-sdk@file:../..':
|
||||
resolution: {directory: ../.., type: directory}
|
||||
|
||||
'@c4/btc-utils@0.3.1':
|
||||
resolution: {integrity: sha512-mhJ43BhjJP7KspiWZVNnvCy3VTmN8EksBiV+d49jVPBDwrj8dBGuhbv3aM+AVnIfq4Z0Ds6k6q2wkl/lKeNcOA==}
|
||||
|
||||
'@noble/curves@1.2.0':
|
||||
resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==}
|
||||
|
||||
'@noble/curves@1.8.2':
|
||||
resolution: {integrity: sha512-vnI7V6lFNe0tLAuJMu+2sX+FcL14TaCWy1qiczg1VwRmPrpQCdq5ESXQMqUc2tluRNf6irBXrWbl1mGN8uaU/g==}
|
||||
engines: {node: ^14.21.3 || >=16}
|
||||
|
||||
'@noble/curves@1.9.0':
|
||||
resolution: {integrity: sha512-7YDlXiNMdO1YZeH6t/kvopHHbIZzlxrCV9WLqCY6QhcXOoXiNCMDqJIglZ9Yjx5+w7Dz30TITFrlTjnRg7sKEg==}
|
||||
engines: {node: ^14.21.3 || >=16}
|
||||
|
||||
'@noble/hashes@1.1.5':
|
||||
resolution: {integrity: sha512-LTMZiiLc+V4v1Yi16TD6aX2gmtKszNye0pQgbaLqkvhIqP7nVsSaJsWloGQjJfJ8offaoP5GtX3yY5swbcJxxQ==}
|
||||
|
||||
'@noble/hashes@1.3.2':
|
||||
resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==}
|
||||
engines: {node: '>= 16'}
|
||||
|
||||
'@noble/hashes@1.7.2':
|
||||
resolution: {integrity: sha512-biZ0NUSxyjLLqo6KxEJ1b+C2NAx0wtDoFvCaXHGgUkeHzf3Xc1xKumFKREuT7f7DARNZ/slvYUwFG6B0f2b6hQ==}
|
||||
engines: {node: ^14.21.3 || >=16}
|
||||
|
||||
'@noble/hashes@1.8.0':
|
||||
resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==}
|
||||
engines: {node: ^14.21.3 || >=16}
|
||||
|
||||
'@noble/secp256k1@1.7.1':
|
||||
resolution: {integrity: sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==}
|
||||
|
||||
'@scure/base@1.2.5':
|
||||
resolution: {integrity: sha512-9rE6EOVeIQzt5TSu4v+K523F8u6DhBsoZWPGKlnCshhlDhy0kJzUX4V+tr2dWmzF1GdekvThABoEQBGBQI7xZw==}
|
||||
|
||||
'@scure/bip32@1.6.2':
|
||||
resolution: {integrity: sha512-t96EPDMbtGgtb7onKKqxRLfE5g05k7uHnHRM2xdE6BP/ZmxaLtPek4J4KfVn/90IQNrU1IOAqMgiDtUdtbe3nw==}
|
||||
|
||||
'@scure/bip39@1.5.4':
|
||||
resolution: {integrity: sha512-TFM4ni0vKvCfBpohoh+/lY05i9gRbSwXWngAsF4CABQxoaOHijxuaZ2R6cStDQ5CHtHO9aGJTr4ksVJASRRyMA==}
|
||||
|
||||
'@scure/btc-signer@1.8.0':
|
||||
resolution: {integrity: sha512-lzf9ugp2hZwP84bdRQuxdX2iib3wyUs7+8+Ph/hanVaXWGOZfSfgEZFaOyocj/Qh0Igt1WHkZh6hdh4KloynNQ==}
|
||||
|
||||
'@stacks/common@7.0.2':
|
||||
resolution: {integrity: sha512-+RSecHdkxOtswmE4tDDoZlYEuULpnTQVeDIG5eZ32opK8cFxf4EugAcK9CsIsHx/Se1yTEaQ21WGATmJGK84lQ==}
|
||||
|
||||
'@stacks/network@7.0.2':
|
||||
resolution: {integrity: sha512-XzHnoWqku/jRrTgMXhmh3c+I0O9vDH24KlhzGDZtBu+8CGGyHNPAZzGwvoUShonMXrXjEnfO9IYQwV5aJhfv6g==}
|
||||
|
||||
'@stacks/stacks-blockchain-api-types@7.14.1':
|
||||
resolution: {integrity: sha512-65hvhXxC+EUqHJAQsqlBCqXB+zwfxZICSKYJugdg6BCp9I9qniyfz5XyQeC4RMVo0tgEoRdS/b5ZCFo5kLWmxA==}
|
||||
|
||||
'@stacks/transactions@7.0.6':
|
||||
resolution: {integrity: sha512-qRGo4tNwOh+avUv/u4JGqqUWQ8xW/iUWtJV0o3BxpMyRxqDXmj+m+yeAEVYf9jRDouOo+NaWmwtRmWc0URZPdw==}
|
||||
|
||||
'@types/node@22.15.17':
|
||||
resolution: {integrity: sha512-wIX2aSZL5FE+MR0JlvF87BNVrtFWf6AE6rxSE9X7OwnVvoyCQjpzSRJ+M87se/4QCkCiebQAqrJ0y6fwIyi7nw==}
|
||||
|
||||
'@types/node@22.7.5':
|
||||
resolution: {integrity: sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==}
|
||||
|
||||
abitype@1.0.8:
|
||||
resolution: {integrity: sha512-ZeiI6h3GnW06uYDLx0etQtX/p8E24UaHHBj57RSjK7YBFe7iuVn07EDpOeP451D06sF27VOz9JJPlIKJmXgkEg==}
|
||||
peerDependencies:
|
||||
typescript: '>=5.0.4'
|
||||
zod: ^3 >=3.22.0
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
zod:
|
||||
optional: true
|
||||
|
||||
aes-js@4.0.0-beta.5:
|
||||
resolution: {integrity: sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==}
|
||||
|
||||
ansi-regex@5.0.1:
|
||||
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
ansi-styles@4.3.0:
|
||||
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
asynckit@0.4.0:
|
||||
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
|
||||
|
||||
axios@1.9.0:
|
||||
resolution: {integrity: sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==}
|
||||
|
||||
base-x@4.0.1:
|
||||
resolution: {integrity: sha512-uAZ8x6r6S3aUM9rbHGVOIsR15U/ZSc82b3ymnCPsT45Gk1DDvhDPdIgB5MrhirZWt+5K0EEPQH985kNqZgNPFw==}
|
||||
|
||||
bech32@2.0.0:
|
||||
resolution: {integrity: sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==}
|
||||
|
||||
big.js@6.2.2:
|
||||
resolution: {integrity: sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ==}
|
||||
|
||||
bip174@2.1.1:
|
||||
resolution: {integrity: sha512-mdFV5+/v0XyNYXjBS6CQPLo9ekCx4gtKZFnJm5PMto7Fs9hTTDpkkzOB7/FtluRI6JbUUAu+snTYfJRgHLZbZQ==}
|
||||
engines: {node: '>=8.0.0'}
|
||||
|
||||
bitcoinjs-lib@6.1.7:
|
||||
resolution: {integrity: sha512-tlf/r2DGMbF7ky1MgUqXHzypYHakkEnm0SZP23CJKIqNY/5uNAnMbFhMJdhjrL/7anfb/U8+AlpdjPWjPnAalg==}
|
||||
engines: {node: '>=8.0.0'}
|
||||
|
||||
bs58@5.0.0:
|
||||
resolution: {integrity: sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==}
|
||||
|
||||
bs58check@3.0.1:
|
||||
resolution: {integrity: sha512-hjuuJvoWEybo7Hn/0xOrczQKKEKD63WguEjlhLExYs2wUBcebDC1jDNK17eEAD2lYfw82d5ASC1d7K3SWszjaQ==}
|
||||
|
||||
c32check@2.0.0:
|
||||
resolution: {integrity: sha512-rpwfAcS/CMqo0oCqDf3r9eeLgScRE3l/xHDCXhM3UyrfvIn7PrLq63uHh7yYbv8NzaZn5MVsVhIRpQ+5GZ5HyA==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
call-bind-apply-helpers@1.0.2:
|
||||
resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
clarity-codegen@1.1.3:
|
||||
resolution: {integrity: sha512-/EXXaq5J8e9ldrQjsNPQwr2QOoIMBvLHFab5nahFwdfG18ZiyXSx9SvxHUbzMHBLUzsvgnlmopAlIj+R+2rwmw==}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
'@stacks/common': ^7.0.2
|
||||
'@stacks/transactions': ^7.0.2
|
||||
|
||||
cliui@8.0.1:
|
||||
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
color-convert@2.0.1:
|
||||
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
|
||||
engines: {node: '>=7.0.0'}
|
||||
|
||||
color-name@1.1.4:
|
||||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
||||
|
||||
combined-stream@1.0.8:
|
||||
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
cross-fetch@3.2.0:
|
||||
resolution: {integrity: sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==}
|
||||
|
||||
delayed-stream@1.0.0:
|
||||
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
|
||||
dunder-proto@1.0.1:
|
||||
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
emoji-regex@8.0.0:
|
||||
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
|
||||
|
||||
es-define-property@1.0.1:
|
||||
resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
es-errors@1.3.0:
|
||||
resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
es-object-atoms@1.1.1:
|
||||
resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
es-set-tostringtag@2.1.0:
|
||||
resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
escalade@3.2.0:
|
||||
resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
ethers@6.14.0:
|
||||
resolution: {integrity: sha512-KgHwltNSMdbrGWEyKkM0Rt2s+u1nDH/5BVDQakLinzGEJi4bWindBzZSCC4gKsbZjwDTI6ex/8suR9Ihbmz4IQ==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
|
||||
eventemitter3@5.0.1:
|
||||
resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==}
|
||||
|
||||
follow-redirects@1.15.9:
|
||||
resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==}
|
||||
engines: {node: '>=4.0'}
|
||||
peerDependencies:
|
||||
debug: '*'
|
||||
peerDependenciesMeta:
|
||||
debug:
|
||||
optional: true
|
||||
|
||||
form-data@4.0.2:
|
||||
resolution: {integrity: sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
function-bind@1.1.2:
|
||||
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
|
||||
|
||||
get-caller-file@2.0.5:
|
||||
resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
|
||||
engines: {node: 6.* || 8.* || >= 10.*}
|
||||
|
||||
get-intrinsic@1.3.0:
|
||||
resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
get-proto@1.0.1:
|
||||
resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
gopd@1.2.0:
|
||||
resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
has-symbols@1.1.0:
|
||||
resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
has-tostringtag@1.0.2:
|
||||
resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
hasown@2.0.2:
|
||||
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-fullwidth-code-point@3.0.0:
|
||||
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
isows@1.0.6:
|
||||
resolution: {integrity: sha512-lPHCayd40oW98/I0uvgaHKWCSvkzY27LjWLbtzOm64yQ+G3Q5npjjbdppU65iZXkK1Zt+kH9pfegli0AYfwYYw==}
|
||||
peerDependencies:
|
||||
ws: '*'
|
||||
|
||||
lodash.clonedeep@4.5.0:
|
||||
resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==}
|
||||
|
||||
lodash@4.17.21:
|
||||
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
|
||||
|
||||
math-intrinsics@1.1.0:
|
||||
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
micro-packed@0.7.3:
|
||||
resolution: {integrity: sha512-2Milxs+WNC00TRlem41oRswvw31146GiSaoCT7s3Xi2gMUglW5QBeqlQaZeHr5tJx9nm3i57LNXPqxOOaWtTYg==}
|
||||
|
||||
mime-db@1.52.0:
|
||||
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
mime-types@2.1.35:
|
||||
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
node-fetch@2.7.0:
|
||||
resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==}
|
||||
engines: {node: 4.x || >=6.0.0}
|
||||
peerDependencies:
|
||||
encoding: ^0.1.0
|
||||
peerDependenciesMeta:
|
||||
encoding:
|
||||
optional: true
|
||||
|
||||
ox@0.6.9:
|
||||
resolution: {integrity: sha512-wi5ShvzE4eOcTwQVsIPdFr+8ycyX+5le/96iAJutaZAvCes1J0+RvpEPg5QDPDiaR0XQQAvZVl7AwqQcINuUug==}
|
||||
peerDependencies:
|
||||
typescript: '>=5.4.0'
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
proxy-from-env@1.1.0:
|
||||
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
|
||||
|
||||
require-directory@2.1.1:
|
||||
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
safe-buffer@5.2.1:
|
||||
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
|
||||
|
||||
string-width@4.2.3:
|
||||
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
strip-ansi@6.0.1:
|
||||
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
tr46@0.0.3:
|
||||
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
|
||||
|
||||
tslib@2.7.0:
|
||||
resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==}
|
||||
|
||||
typeforce@1.18.0:
|
||||
resolution: {integrity: sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==}
|
||||
|
||||
undici-types@6.19.8:
|
||||
resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==}
|
||||
|
||||
undici-types@6.21.0:
|
||||
resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
|
||||
|
||||
varuint-bitcoin@1.1.2:
|
||||
resolution: {integrity: sha512-4EVb+w4rx+YfVM32HQX42AbbT7/1f5zwAYhIujKXKk8NQK+JfRVl3pqT3hjNn/L+RstigmGGKVwHA/P0wgITZw==}
|
||||
|
||||
viem@2.29.2:
|
||||
resolution: {integrity: sha512-cukRxab90jvQ+TDD84sU3qB3UmejYqgCw4cX8SfWzvh7JPfZXI3kAMUaT5OSR2As1Mgvx1EJawccwPjGqkSSwA==}
|
||||
peerDependencies:
|
||||
typescript: '>=5.0.4'
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
webidl-conversions@3.0.1:
|
||||
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
|
||||
|
||||
whatwg-url@5.0.0:
|
||||
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
|
||||
|
||||
wrap-ansi@7.0.0:
|
||||
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
ws@8.17.1:
|
||||
resolution: {integrity: sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
peerDependencies:
|
||||
bufferutil: ^4.0.1
|
||||
utf-8-validate: '>=5.0.2'
|
||||
peerDependenciesMeta:
|
||||
bufferutil:
|
||||
optional: true
|
||||
utf-8-validate:
|
||||
optional: true
|
||||
|
||||
ws@8.18.1:
|
||||
resolution: {integrity: sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
peerDependencies:
|
||||
bufferutil: ^4.0.1
|
||||
utf-8-validate: '>=5.0.2'
|
||||
peerDependenciesMeta:
|
||||
bufferutil:
|
||||
optional: true
|
||||
utf-8-validate:
|
||||
optional: true
|
||||
|
||||
y18n@5.0.8:
|
||||
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
yargs-parser@21.1.1:
|
||||
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
yargs@17.7.2:
|
||||
resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
yqueue@1.0.1:
|
||||
resolution: {integrity: sha512-DBxJZBRafFLA/tCc5uO8ZTGFr+sQgn1FRJkZ4cVrIQIk6bv2bInraE3mbpLAJw9z93JGrLkqDoyTLrrZaCNq5w==}
|
||||
|
||||
snapshots:
|
||||
|
||||
'@adraffy/ens-normalize@1.10.1': {}
|
||||
|
||||
'@brotocol-xyz/bro-sdk@file:../..(@stacks/common@7.0.2)':
|
||||
dependencies:
|
||||
'@c4/btc-utils': 0.3.1
|
||||
'@scure/btc-signer': 1.8.0
|
||||
'@stacks/network': 7.0.2
|
||||
'@stacks/transactions': 7.0.6
|
||||
big.js: 6.2.2
|
||||
c32check: 2.0.0
|
||||
clarity-codegen: 1.1.3(@stacks/common@7.0.2)(@stacks/transactions@7.0.6)
|
||||
viem: 2.29.2
|
||||
transitivePeerDependencies:
|
||||
- '@stacks/common'
|
||||
- bufferutil
|
||||
- debug
|
||||
- encoding
|
||||
- typescript
|
||||
- utf-8-validate
|
||||
- zod
|
||||
|
||||
'@c4/btc-utils@0.3.1':
|
||||
optionalDependencies:
|
||||
'@scure/btc-signer': 1.8.0
|
||||
|
||||
'@noble/curves@1.2.0':
|
||||
dependencies:
|
||||
'@noble/hashes': 1.3.2
|
||||
|
||||
'@noble/curves@1.8.2':
|
||||
dependencies:
|
||||
'@noble/hashes': 1.7.2
|
||||
|
||||
'@noble/curves@1.9.0':
|
||||
dependencies:
|
||||
'@noble/hashes': 1.8.0
|
||||
|
||||
'@noble/hashes@1.1.5': {}
|
||||
|
||||
'@noble/hashes@1.3.2': {}
|
||||
|
||||
'@noble/hashes@1.7.2': {}
|
||||
|
||||
'@noble/hashes@1.8.0': {}
|
||||
|
||||
'@noble/secp256k1@1.7.1': {}
|
||||
|
||||
'@scure/base@1.2.5': {}
|
||||
|
||||
'@scure/bip32@1.6.2':
|
||||
dependencies:
|
||||
'@noble/curves': 1.8.2
|
||||
'@noble/hashes': 1.7.2
|
||||
'@scure/base': 1.2.5
|
||||
|
||||
'@scure/bip39@1.5.4':
|
||||
dependencies:
|
||||
'@noble/hashes': 1.7.2
|
||||
'@scure/base': 1.2.5
|
||||
|
||||
'@scure/btc-signer@1.8.0':
|
||||
dependencies:
|
||||
'@noble/curves': 1.9.0
|
||||
'@noble/hashes': 1.8.0
|
||||
'@scure/base': 1.2.5
|
||||
micro-packed: 0.7.3
|
||||
|
||||
'@stacks/common@7.0.2': {}
|
||||
|
||||
'@stacks/network@7.0.2':
|
||||
dependencies:
|
||||
'@stacks/common': 7.0.2
|
||||
cross-fetch: 3.2.0
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
|
||||
'@stacks/stacks-blockchain-api-types@7.14.1': {}
|
||||
|
||||
'@stacks/transactions@7.0.6':
|
||||
dependencies:
|
||||
'@noble/hashes': 1.1.5
|
||||
'@noble/secp256k1': 1.7.1
|
||||
'@stacks/common': 7.0.2
|
||||
'@stacks/network': 7.0.2
|
||||
c32check: 2.0.0
|
||||
lodash.clonedeep: 4.5.0
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
|
||||
'@types/node@22.15.17':
|
||||
dependencies:
|
||||
undici-types: 6.21.0
|
||||
|
||||
'@types/node@22.7.5':
|
||||
dependencies:
|
||||
undici-types: 6.19.8
|
||||
|
||||
abitype@1.0.8: {}
|
||||
|
||||
aes-js@4.0.0-beta.5: {}
|
||||
|
||||
ansi-regex@5.0.1: {}
|
||||
|
||||
ansi-styles@4.3.0:
|
||||
dependencies:
|
||||
color-convert: 2.0.1
|
||||
|
||||
asynckit@0.4.0: {}
|
||||
|
||||
axios@1.9.0:
|
||||
dependencies:
|
||||
follow-redirects: 1.15.9
|
||||
form-data: 4.0.2
|
||||
proxy-from-env: 1.1.0
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
|
||||
base-x@4.0.1: {}
|
||||
|
||||
bech32@2.0.0: {}
|
||||
|
||||
big.js@6.2.2: {}
|
||||
|
||||
bip174@2.1.1: {}
|
||||
|
||||
bitcoinjs-lib@6.1.7:
|
||||
dependencies:
|
||||
'@noble/hashes': 1.8.0
|
||||
bech32: 2.0.0
|
||||
bip174: 2.1.1
|
||||
bs58check: 3.0.1
|
||||
typeforce: 1.18.0
|
||||
varuint-bitcoin: 1.1.2
|
||||
|
||||
bs58@5.0.0:
|
||||
dependencies:
|
||||
base-x: 4.0.1
|
||||
|
||||
bs58check@3.0.1:
|
||||
dependencies:
|
||||
'@noble/hashes': 1.8.0
|
||||
bs58: 5.0.0
|
||||
|
||||
c32check@2.0.0:
|
||||
dependencies:
|
||||
'@noble/hashes': 1.8.0
|
||||
base-x: 4.0.1
|
||||
|
||||
call-bind-apply-helpers@1.0.2:
|
||||
dependencies:
|
||||
es-errors: 1.3.0
|
||||
function-bind: 1.1.2
|
||||
|
||||
clarity-codegen@1.1.3(@stacks/common@7.0.2)(@stacks/transactions@7.0.6):
|
||||
dependencies:
|
||||
'@stacks/common': 7.0.2
|
||||
'@stacks/stacks-blockchain-api-types': 7.14.1
|
||||
'@stacks/transactions': 7.0.6
|
||||
axios: 1.9.0
|
||||
lodash: 4.17.21
|
||||
yargs: 17.7.2
|
||||
yqueue: 1.0.1
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
|
||||
cliui@8.0.1:
|
||||
dependencies:
|
||||
string-width: 4.2.3
|
||||
strip-ansi: 6.0.1
|
||||
wrap-ansi: 7.0.0
|
||||
|
||||
color-convert@2.0.1:
|
||||
dependencies:
|
||||
color-name: 1.1.4
|
||||
|
||||
color-name@1.1.4: {}
|
||||
|
||||
combined-stream@1.0.8:
|
||||
dependencies:
|
||||
delayed-stream: 1.0.0
|
||||
|
||||
cross-fetch@3.2.0:
|
||||
dependencies:
|
||||
node-fetch: 2.7.0
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
|
||||
delayed-stream@1.0.0: {}
|
||||
|
||||
dunder-proto@1.0.1:
|
||||
dependencies:
|
||||
call-bind-apply-helpers: 1.0.2
|
||||
es-errors: 1.3.0
|
||||
gopd: 1.2.0
|
||||
|
||||
emoji-regex@8.0.0: {}
|
||||
|
||||
es-define-property@1.0.1: {}
|
||||
|
||||
es-errors@1.3.0: {}
|
||||
|
||||
es-object-atoms@1.1.1:
|
||||
dependencies:
|
||||
es-errors: 1.3.0
|
||||
|
||||
es-set-tostringtag@2.1.0:
|
||||
dependencies:
|
||||
es-errors: 1.3.0
|
||||
get-intrinsic: 1.3.0
|
||||
has-tostringtag: 1.0.2
|
||||
hasown: 2.0.2
|
||||
|
||||
escalade@3.2.0: {}
|
||||
|
||||
ethers@6.14.0:
|
||||
dependencies:
|
||||
'@adraffy/ens-normalize': 1.10.1
|
||||
'@noble/curves': 1.2.0
|
||||
'@noble/hashes': 1.3.2
|
||||
'@types/node': 22.7.5
|
||||
aes-js: 4.0.0-beta.5
|
||||
tslib: 2.7.0
|
||||
ws: 8.17.1
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- utf-8-validate
|
||||
|
||||
eventemitter3@5.0.1: {}
|
||||
|
||||
follow-redirects@1.15.9: {}
|
||||
|
||||
form-data@4.0.2:
|
||||
dependencies:
|
||||
asynckit: 0.4.0
|
||||
combined-stream: 1.0.8
|
||||
es-set-tostringtag: 2.1.0
|
||||
mime-types: 2.1.35
|
||||
|
||||
function-bind@1.1.2: {}
|
||||
|
||||
get-caller-file@2.0.5: {}
|
||||
|
||||
get-intrinsic@1.3.0:
|
||||
dependencies:
|
||||
call-bind-apply-helpers: 1.0.2
|
||||
es-define-property: 1.0.1
|
||||
es-errors: 1.3.0
|
||||
es-object-atoms: 1.1.1
|
||||
function-bind: 1.1.2
|
||||
get-proto: 1.0.1
|
||||
gopd: 1.2.0
|
||||
has-symbols: 1.1.0
|
||||
hasown: 2.0.2
|
||||
math-intrinsics: 1.1.0
|
||||
|
||||
get-proto@1.0.1:
|
||||
dependencies:
|
||||
dunder-proto: 1.0.1
|
||||
es-object-atoms: 1.1.1
|
||||
|
||||
gopd@1.2.0: {}
|
||||
|
||||
has-symbols@1.1.0: {}
|
||||
|
||||
has-tostringtag@1.0.2:
|
||||
dependencies:
|
||||
has-symbols: 1.1.0
|
||||
|
||||
hasown@2.0.2:
|
||||
dependencies:
|
||||
function-bind: 1.1.2
|
||||
|
||||
is-fullwidth-code-point@3.0.0: {}
|
||||
|
||||
isows@1.0.6(ws@8.18.1):
|
||||
dependencies:
|
||||
ws: 8.18.1
|
||||
|
||||
lodash.clonedeep@4.5.0: {}
|
||||
|
||||
lodash@4.17.21: {}
|
||||
|
||||
math-intrinsics@1.1.0: {}
|
||||
|
||||
micro-packed@0.7.3:
|
||||
dependencies:
|
||||
'@scure/base': 1.2.5
|
||||
|
||||
mime-db@1.52.0: {}
|
||||
|
||||
mime-types@2.1.35:
|
||||
dependencies:
|
||||
mime-db: 1.52.0
|
||||
|
||||
node-fetch@2.7.0:
|
||||
dependencies:
|
||||
whatwg-url: 5.0.0
|
||||
|
||||
ox@0.6.9:
|
||||
dependencies:
|
||||
'@adraffy/ens-normalize': 1.10.1
|
||||
'@noble/curves': 1.8.2
|
||||
'@noble/hashes': 1.8.0
|
||||
'@scure/bip32': 1.6.2
|
||||
'@scure/bip39': 1.5.4
|
||||
abitype: 1.0.8
|
||||
eventemitter3: 5.0.1
|
||||
transitivePeerDependencies:
|
||||
- zod
|
||||
|
||||
proxy-from-env@1.1.0: {}
|
||||
|
||||
require-directory@2.1.1: {}
|
||||
|
||||
safe-buffer@5.2.1: {}
|
||||
|
||||
string-width@4.2.3:
|
||||
dependencies:
|
||||
emoji-regex: 8.0.0
|
||||
is-fullwidth-code-point: 3.0.0
|
||||
strip-ansi: 6.0.1
|
||||
|
||||
strip-ansi@6.0.1:
|
||||
dependencies:
|
||||
ansi-regex: 5.0.1
|
||||
|
||||
tr46@0.0.3: {}
|
||||
|
||||
tslib@2.7.0: {}
|
||||
|
||||
typeforce@1.18.0: {}
|
||||
|
||||
undici-types@6.19.8: {}
|
||||
|
||||
undici-types@6.21.0: {}
|
||||
|
||||
varuint-bitcoin@1.1.2:
|
||||
dependencies:
|
||||
safe-buffer: 5.2.1
|
||||
|
||||
viem@2.29.2:
|
||||
dependencies:
|
||||
'@noble/curves': 1.8.2
|
||||
'@noble/hashes': 1.7.2
|
||||
'@scure/bip32': 1.6.2
|
||||
'@scure/bip39': 1.5.4
|
||||
abitype: 1.0.8
|
||||
isows: 1.0.6(ws@8.18.1)
|
||||
ox: 0.6.9
|
||||
ws: 8.18.1
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- utf-8-validate
|
||||
- zod
|
||||
|
||||
webidl-conversions@3.0.1: {}
|
||||
|
||||
whatwg-url@5.0.0:
|
||||
dependencies:
|
||||
tr46: 0.0.3
|
||||
webidl-conversions: 3.0.1
|
||||
|
||||
wrap-ansi@7.0.0:
|
||||
dependencies:
|
||||
ansi-styles: 4.3.0
|
||||
string-width: 4.2.3
|
||||
strip-ansi: 6.0.1
|
||||
|
||||
ws@8.17.1: {}
|
||||
|
||||
ws@8.18.1: {}
|
||||
|
||||
y18n@5.0.8: {}
|
||||
|
||||
yargs-parser@21.1.1: {}
|
||||
|
||||
yargs@17.7.2:
|
||||
dependencies:
|
||||
cliui: 8.0.1
|
||||
escalade: 3.2.0
|
||||
get-caller-file: 2.0.5
|
||||
require-directory: 2.1.1
|
||||
string-width: 4.2.3
|
||||
y18n: 5.0.8
|
||||
yargs-parser: 21.1.1
|
||||
|
||||
yqueue@1.0.1: {}
|
||||
13
examples/bridgeFrom/tsconfig.json
Normal file
13
examples/bridgeFrom/tsconfig.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"lib": ["ESNext"],
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true
|
||||
}
|
||||
}
|
||||
8
pnpm-lock.yaml
generated
8
pnpm-lock.yaml
generated
@@ -791,8 +791,8 @@ packages:
|
||||
asynckit@0.4.0:
|
||||
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
|
||||
|
||||
axios@1.8.3:
|
||||
resolution: {integrity: sha512-iP4DebzoNlP/YN2dpwCgb8zoCmhtkajzS48JvwmkSkXvPI3DHc7m+XYL5tGnSlJtR6nImXZmdCuN5aP8dh1d8A==}
|
||||
axios@1.9.0:
|
||||
resolution: {integrity: sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==}
|
||||
|
||||
balanced-match@1.0.2:
|
||||
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
||||
@@ -2373,7 +2373,7 @@ snapshots:
|
||||
|
||||
asynckit@0.4.0: {}
|
||||
|
||||
axios@1.8.3:
|
||||
axios@1.9.0:
|
||||
dependencies:
|
||||
follow-redirects: 1.15.9
|
||||
form-data: 4.0.2
|
||||
@@ -2443,7 +2443,7 @@ snapshots:
|
||||
'@stacks/common': 7.0.2
|
||||
'@stacks/stacks-blockchain-api-types': 7.14.1
|
||||
'@stacks/transactions': 7.0.5
|
||||
axios: 1.8.3
|
||||
axios: 1.9.0
|
||||
lodash: 4.17.21
|
||||
yargs: 17.7.2
|
||||
yqueue: 1.0.1
|
||||
|
||||
@@ -4,6 +4,14 @@ import { EVMEndpointContract } from "../evmUtils/evmContractAddresses"
|
||||
import { BigNumber } from "../utils/BigNumber"
|
||||
import { InvalidMethodParametersError } from "../utils/errors"
|
||||
|
||||
/**
|
||||
* A branded literal type used for SDK-specific types `ChainId`, `TokenId` and `SDKNumber`.
|
||||
*
|
||||
* For example:
|
||||
* - `"bitcoin-mainnet (BroSDK ChainId)"` represents a valid `ChainId`
|
||||
* - `"brc20-something (BroSDK TokenId)"` represents a valid `TokenId`
|
||||
* - `"10 (BroSDK number)"` represents a valid `SDKNumber`
|
||||
*/
|
||||
type SDKBrandedLiteral<
|
||||
Type extends string,
|
||||
T extends string | number,
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig.json",
|
||||
"exclude": ["node_modules", "lib", "examples/cross-chain-swap"],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"lib",
|
||||
"examples/cross-chain-swap",
|
||||
"examples/bridgeFrom"
|
||||
],
|
||||
"compilerOptions": {
|
||||
"module": "esnext",
|
||||
"target": "esnext",
|
||||
|
||||
Reference in New Issue
Block a user