BSA Integration Guide
This guide intends to demonstrate the steps needed to lock and unlock native Bitcoin in the Bitcoin Smart Account architecture
Terminology
- Smart Account Registry (SAR): The smart contract on Ethereum that records UTXOs and is used by the SC and AO to decide whether BTC should remain in a depositors self-custodial vault, or whether the BTC is allowed to be rebalanced to the Security Consortium.
- Security Consortium (SC): Lombard’s Security Consortium, where a two-thirds quorum are required to authorize Lombard Protocol operations (mint, redeem, timelocked configuration changes). The SC has secured an average 14,000 BTC over the past 18 months.
- Arbitration Oracle (AO): A Trusted Execution Environment which validates Bitcoin and SAR state, authorizing return of depositor funds if the Security Consortium performs a malicious act.
- Lombard’s API: Used for non-critical co-ordination of activities with the Security Consortium and relaying transactions to Ethereum and Bitcoin (untrusted) for non-critical activites.
Prerequisites
- Install the Go package
go get github.com/lombard-finance/bsa-core@v0.0.1-rc8- Note: This is pre-release software, provide Github ID to Lombard team for access
- Import with
import bsa "github.com/lombard-finance/bsa-core"import bsalock "github.com/lombard-finance/bsa-core/lock"import "github.com/btcsuite/btcd/wire"import "github.com/btcsuite/btcd/btcutil/psbt"
- A valid
API_KEYissued by Lombard (contact institutional@lombard.finance if required).
Locking Bitcoin
1. Generate PSBTs and deposit transaction
bsalock.GenerateLock(
depositorPK []byte,
unlockAddressScript []byte,
arbitrationPKs [][]byte,
defiAddress []byte,
defiChainID []byte,
nonce uint32,
tranches []uint64,
fundingUTXOs []*bsalock.FundingUTXO,
lockFeeRate *int64
) (*btcutil.AddressTaproot, *psbt.Packet, map[string]*bsalock.PSBT, error)where
// PSBT contains PSBTs related to a single deposit UTXO
type PSBT struct {
UnlockChallengePSBT *psbt.Packet // Unlocking → Unlock challenge
RebalanceChallengePSBT *psbt.Packet // Vault → Rebalance challenge
CooperativeUnlockPSBT *psbt.Packet // Vault → destination (coop unlock)
}
// FundingUTXO represents a UTXO used to fund the locked transaction
type FundingUTXO struct {
OutPoint *wire.OutPoint
ScriptPubKey []byte
Amount int64
}Notes:
fundingUTXOsmust be Segwit or TaprootunlockAddressScriptis the address where Bitcoin will be unlocked to. Any valid address type.defiChainIDcan be retrieved as a constant value in the Ethereum value.
2. Sign PSBTs and deposit transaction
Use your existing cryptographic wallet infrastructure to sign all returned unsignedPSBTs and the deposit transaction.
3. Submit signed PSBTs to Lombard
Lombard’s API will co-ordinate in the background with the Security Consortium’s ledger to sign required PSBTs from the Security Consortium’s perspective, and publish on Ethereum.
Note: The signed deposit transaction is not submitted, this is relayed directly to the Bitcoin network in step 6 after state validation.
POST /api/v2/bsa/locks/initiate
HEADER "X-Auth-Api-Key-Token" "API_KEY"
{
"signer_pk": "fa030...",
"unlock_address": "bc1qabc...",
"arbitration_pks": [ "6ff31..." ],
"defi_address": "0x123abc...",
"defi_chain_id": "0x0000...000aa36a7",
"nonce": 0,
"version" : 0,
"vault_address": "tb1p....",
"tranches": [
{
"tranche": {
"amount_sat": 100000,
"outpoint": "bc2r3:4"
},
"unlock_challenge_sig": "",
"rebalance_challenge_sig": "",
"cooperative_unlock_sig": ""
}
]
}
RESPONSE 200 { "request_ids": ["12412"] }4. Fetch the security state on Ethereum
Get tweaks and stored Security Consortium signature from SAR for each tranche using:
{
lockedAmount,
defiAddress,
operatorUnlockSig,
unlockChallengeResolutionSig,
rebalanceChallengeResolutionSig,
rawTweak,
minerFee,
unlockAddressScript
} = SAR.getUTXODetailsWithTweak(txId, vout)- Note: The data is available after
BondPending (address account, bytes32 txId, uint32 vout, uint256 value)event is emitted by SAR.
5. Verify the security state
bsalock.VerifyLock(
conf *Conf,
txID []byte,
vout uint32,
lockedAmount int64,
minerFee int64,
unlockAddressScript []byte,
rawTweak []byte,
defiAddress []byte,
sigs [3][]byte
) errorsigsis an ordered array of the values[operatorUnlockSig, unlockChallengeResolutionSig, rebalanceChallengeResolutionSig]. No error means the state is verified and safe.
6. Lock BTC on Bitcoin
Relay the deposit transaction previously generated to the Bitcoin network. After approximately 1 hour (6 Bitcoin block confirmations), BTC.b will be minted to the previously specified defiAddress.
If also running an AO, remember to monitor new Bitcoin Smart Accounts, to add the extra protection that AO’s provide for your clients’ funds.
Unlocking Bitcoin
Unlocking Bitcoin requires only one transaction on the destination chain (Ethereum).
To get all unlockable amounts from the SAR, for depositor selection of UTXO’s to unlock, use the SAR.getUTXOsForAccount(address) view function. Any UTXO’s with the status CollateralActive can be unlocked.
- On the SAR, call the write function
SAR.unlock([]utxo). This will burn the corresponding amount of BTC.b from the DeFi Controller address and set the on-chain status toSpentOnRebalance.
Lombard will orchestrate all operations with the Security Consortium to authorize the return of Bitcoin and relay the transaction to the Bitcoin network.
Note: a web-based user interface tool will be provided via DeFi wallets (supporting WalletConnect).
(Optional) Unilateral Unlock on Bitcoin
If the Security Consortium does not co-operate within a reasonable timeframe after triggering an unlock on the SAR, a unilateral unlock procedure may be initiated.
- Get tweaks and stored Security Consortium signature from SAR using
{ lockedAmount, tweakKey, defiAddress, operatorUnlockSig, rawTweak, minerFee, unlockAddress } = SAR.getUTXODetailsWithTweak(txId, vout) bsa.CreateUnlockPSBT(conf *Conf, txID []byte, vout uint32, lockedAmount int64, minerFee int64, rawTweak []byte, defiAddress []byte)- Use existing infrastructure to sign
- Combine with using
bsa.ExtractUnlockTx(signedPsbt *psbt.Packet, rawTweak []byte, operatorUnlockSig []byte)to generate the Bitcoin transaction to relay to the network.
Confirm the depositor has requested unlock on the SAR before triggering a Unilateral Unlock, otherwise the state can be successfully challenged by the Security Consortium.