mirror of
https://github.com/Brotocol-xyz/bro-sdk.git
synced 2026-01-12 14:54:21 +08:00
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
190 lines
5.5 KiB
TypeScript
190 lines
5.5 KiB
TypeScript
// 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)
|