swap

package module
v0.0.0-...-193e617 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 18, 2026 License: MIT Imports: 45 Imported by: 0

Documentation

Index

Constants

View Source
const (
	OFFER_CHAINS          uint64 = 2
	OFFER_METADATA        uint64 = 4
	OFFER_CURRENCY        uint64 = 6
	OFFER_AMOUNT          uint64 = 8
	OFFER_DESCRIPTION     uint64 = 10
	OFFER_FEATURES        uint64 = 12
	OFFER_ABSOLUTE_EXPIRY uint64 = 14
	OFFER_PATHS           uint64 = 16
	OFFER_ISSUER          uint64 = 18
	OFFER_QUANTITY_MAX    uint64 = 20
	OFFER_ISSUER_ID       uint64 = 22

	INVOICE_PAYMENT_HASH uint64 = 168
	INVOICE_AMOUNT       uint64 = 170
)

BOLT12 TLV types

View Source
const (
	SwapTypeSubmarine = "submarine"
	SwapTypeChain     = "chain"
)

Variables

View Source
var ErrorNoVtxosFound = fmt.Errorf("no vtxos found for the given vhtlc opts")

Functions

func CombineFinalSig

func CombineFinalSig(
	combinedNoncePoint *btcec.PublicKey,
	allSigs []*musig2.PartialSignature,
	keys []*btcec.PublicKey,
	msg [32]byte,
	merkleRoot []byte,
) (*schnorr.Signature, error)

CombineFinalSig combines two partial signatures into a final Schnorr signature. Uses taproot tweaked combine so verification is against the tweaked output key.

func ComputeTweakedOutputKey

func ComputeTweakedOutputKey(keys []*btcec.PublicKey, merkleRoot []byte) (*btcec.PublicKey, error)

ComputeTweakedOutputKey computes the P2TR output key for {keys, merkleRoot}. Useful for debug verification before broadcast.

func IsBolt12Invoice

func IsBolt12Invoice(invoice string) bool

func IsBolt12Offer

func IsBolt12Offer(offer string) bool

func IsValidBolt12Offer

func IsValidBolt12Offer(offer string) bool

func NewPrevOutputFetcher

func NewPrevOutputFetcher(prevOut *wire.TxOut, prevOutPoint wire.OutPoint) txscript.PrevOutputFetcher

func ParsePartialSignatureScalar32

func ParsePartialSignatureScalar32(sigHex string) (*musig2.PartialSignature, error)

ParsePartialSignatureScalar32 parses Boltz partial sig format: 32-byte scalar S (hex). This is NOT musig2.PartialSignature encoding; do not call sig.Decode for this format.

func ParsePubNonce

func ParsePubNonce(nonceHex string) ([66]byte, error)

func SatsFromBolt12Offer

func SatsFromBolt12Offer(offer string) int

func SerializePubNonce

func SerializePubNonce(nonce [66]byte) string

func TaprootMessage

func TaprootMessage(
	tx *wire.MsgTx,
	inputIndex int,
	prevOutFetcher txscript.PrevOutputFetcher,
) ([32]byte, error)

TaprootMessage computes the BIP341 sighash (32 bytes) for key-path signing.

func VerifyFinalSig

func VerifyFinalSig(msg [32]byte, finalSig *schnorr.Signature, tweakedOutputKey *btcec.PublicKey) error

VerifyFinalSig verifies against the tweaked output key (recommended debug gate).

Types

type ChainSwap

type ChainSwap struct {
	Id       string
	Amount   uint64
	Preimage []byte

	UserBtcLockupAddress string

	VhtlcOpts vhtlc.Opts

	UserLockTxid   string
	ServerLockTxid string
	ClaimTxid      string
	RefundTxid     string

	Timestamp int64
	Status    ChainSwapStatus
	Error     string

	SwapRespJson string
	IsArkToBtc   bool
	// contains filtered or unexported fields
}

func NewChainSwap

func NewChainSwap(
	id string,
	amount uint64,
	preimage []byte,
	vhtlcOpts *vhtlc.Opts,
	swapRespJson string,
	isArkToBtc bool,
	userBtcLockupAddress string,
	eventCallback ChainSwapEventCallback,
) (*ChainSwap, error)

func (*ChainSwap) Claim

func (s *ChainSwap) Claim(txid string)

func (*ChainSwap) Fail

func (s *ChainSwap) Fail(err string)

func (*ChainSwap) Refund

func (s *ChainSwap) Refund(txid string)

func (*ChainSwap) RefundFailed

func (s *ChainSwap) RefundFailed(err string)

func (*ChainSwap) RefundUnilaterally

func (s *ChainSwap) RefundUnilaterally(txid string)

func (*ChainSwap) ServerLock

func (s *ChainSwap) ServerLock(txid string)

func (*ChainSwap) UserLock

func (s *ChainSwap) UserLock(txid string)

func (*ChainSwap) UserLockedFailed

func (s *ChainSwap) UserLockedFailed(err string)

type ChainSwapEvent

type ChainSwapEvent interface {
	// contains filtered or unexported methods
}

ChainSwapEvent is a marker interface for typed domain events Each event type represents a specific state transition with its own data

type ChainSwapEventCallback

type ChainSwapEventCallback func(event ChainSwapEvent)

ChainSwapEventCallback is called whenever a chain swap event occurs

type ChainSwapEventHandler

type ChainSwapEventHandler interface {
	// HandleSwapCreated handles initial swap creation
	HandleSwapCreated(ctx context.Context, update boltz.SwapUpdate) error

	// HandleLockupFailed handles various failure scenarios
	HandleLockupFailed(ctx context.Context, update boltz.SwapUpdate) error

	HandleUserLockedMempool(ctx context.Context, update boltz.SwapUpdate) error

	// HandleUserLocked handles user lockup confirmation
	HandleUserLocked(ctx context.Context, update boltz.SwapUpdate) error

	// HandleServerLockedMempool handles server lockup (ready to claim)
	HandleServerLockedMempool(ctx context.Context, update boltz.SwapUpdate) error

	// HandleServerLocked handles server lockup (ready to claim)
	HandleServerLocked(ctx context.Context, update boltz.SwapUpdate) error

	HandleSwapExpired(ctx context.Context, update boltz.SwapUpdate) error

	HandleTransactionFailed(ctx context.Context, update boltz.SwapUpdate) error

	GetState() ChainSwapState
}

ChainSwapEventHandler defines swap-specific behavior for different swap directions. This interface uses the strategy pattern to extract common WebSocket monitoring logic.

func NewArkToBtcHandler

func NewArkToBtcHandler(
	swapHandler *SwapHandler,
	state ChainSwapState,
	network *chaincfg.Params,
	btcClaimPrivKey *btcec.PrivateKey,
	preimage []byte,
	btcDestinationAddress string,
	swapResp *boltz.CreateChainSwapResponse,
	boltzClaimPubKey *btcec.PublicKey,
	swapTree boltz.SwapTree,
) ChainSwapEventHandler

func NewBtcToArkHandler

func NewBtcToArkHandler(
	swapHandler *SwapHandler,
	chainSwapState ChainSwapState,
	preimage []byte,
	refundKey *btcec.PrivateKey,
	swapResp *boltz.CreateChainSwapResponse,
) ChainSwapEventHandler

type ChainSwapState

type ChainSwapState struct {
	SwapID                   string
	Timeout                  time.Duration
	EventCallback            ChainSwapEventCallback
	UnilateralRefundCallback func(swapId string, opts vhtlc.Opts) error
	Swap                     *ChainSwap
}

type ChainSwapStatus

type ChainSwapStatus int
const (
	// Pending states
	ChainSwapPending ChainSwapStatus = iota
	ChainSwapUserLocked
	ChainSwapServerLocked

	// Success states
	ChainSwapClaimed

	// Failed states
	ChainSwapUserLockedFailed
	ChainSwapFailed
	ChainSwapRefundFailed
	ChainSwapRefunded
	ChainSwapRefundedUnilaterally
)

type ClaimEvent

type ClaimEvent struct {
	SwapID string
	TxID   string
}

ClaimEvent is emitted when swap is successfully claimed

type ClaimTransactionParams

type ClaimTransactionParams struct {
	LockupTxid      string
	LockupVout      uint32
	LockupAmount    uint64
	DestinationAddr string
	Network         *chaincfg.Params
}

type CreateEvent

type CreateEvent struct {
	Id                   string
	Amount               uint64
	Preimage             []byte
	VhtlcOpts            vhtlc.Opts
	Timestamp            int64
	Status               ChainSwapStatus
	SwapRespJson         string
	IsArkToBtc           bool
	UserBtcLockupAddress string
}

type ExplorerClient

type ExplorerClient interface {
	BroadcastTransaction(tx *wire.MsgTx) (string, error)
	GetFeeRate() (float64, error)
	GetCurrentBlockHeight() (uint32, error)
	GetTransactionStatus(txid string) (*TransactionStatus, error)
	GetTransaction(txid string) (string, error)
}

func NewExplorerClient

func NewExplorerClient(baseURL string) ExplorerClient

type FailEvent

type FailEvent struct {
	SwapID string
	Error  string
}

FailEvent is emitted when swap fails

type HTLCComponents

type HTLCComponents struct {
	PreimageHash [20]byte // HASH160 of the preimage (20 bytes)
	ClaimPubKey  [32]byte // X-only public key for claim (32 bytes)
}

HTLCComponents contains the parsed components from a Boltz HTLC script

type Invoice

type Invoice struct {
	Amount         uint64
	AmountInSats   uint64
	PaymentHash    []byte
	PaymentHash160 []byte
}

func DecodeBolt12Invoice

func DecodeBolt12Invoice(invoice string) (*Invoice, error)

type MuSigContext

type MuSigContext struct {
	// contains filtered or unexported fields
}

MuSigContext holds just what we need for the Boltz cooperative (2-of-2) MuSig2 flow. We intentionally DO NOT use musig2.Session API here to avoid tweak/sort/session mismatch and to match the proven working pattern from your tree signer code:

- GenNonces (keep SecNonce + PubNonce) - send PubNonce to Boltz - receive their PubNonce + their partial sig (S-only 32B scalar) - AggregateNonces - musig2.Sign(... WithTaprootSignTweak(merkleRoot) ...) - musig2.CombineSigs(... WithTaprootTweakedCombine(...))

func NewMuSigContext

func NewMuSigContext(ourPriv *btcec.PrivateKey, theirPub *btcec.PublicKey) (*MuSigContext, error)

NewMuSigContext creates a MuSig2 context for 2-of-2 signing. IMPORTANT: ordering must match Boltz expectation. We keep "their key first" in Keys().

func (*MuSigContext) AggregateNonces

func (c *MuSigContext) AggregateNonces(theirNonce [66]byte) ([66]byte, error)

AggregateNonces aggregates our pubnonce and their pubnonce.

func (*MuSigContext) GenerateNonce

func (c *MuSigContext) GenerateNonce() ([66]byte, error)

GenerateNonce generates a fresh MuSig2 nonce pair (secret+public). WARNING: Never reuse c.ourNonces.SecNonce across different messages/txs.

func (*MuSigContext) Keys

func (c *MuSigContext) Keys() []*btcec.PublicKey

Keys returns the signer keyset in the canonical order used in this swap flow. We intentionally return [their, ours] because you noted Boltz expects server first.

func (*MuSigContext) OurPartialSign

func (c *MuSigContext) OurPartialSign(
	combinedNonce [66]byte,
	keys []*btcec.PublicKey,
	msg [32]byte,
	merkleRoot []byte,
) (*musig2.PartialSignature, error)

OurPartialSign produces our partial signature for the given message, using the aggregated nonce and Taproot tweak (merkleRoot/scriptRoot).

merkleRoot MUST be 32 bytes (taproot script root).

type Offer

type Offer struct {
	ID             string
	Amount         uint64
	AmountInSats   uint64
	Description    []byte
	DescriptionStr string
	AbsoluteExpiry uint64
	QuantityMax    uint64
}

func DecodeBolt12Offer

func DecodeBolt12Offer(offer string) (*Offer, error)

type RefundEvent

type RefundEvent struct {
	SwapID string
	TxID   string
}

RefundEvent is emitted when swap is refunded

type RefundEventUnilaterally

type RefundEventUnilaterally struct {
	SwapID string
	TxID   string
}

RefundEventUnilaterally is emitted when swap is refunded

type RefundFailedEvent

type RefundFailedEvent struct {
	SwapID string
	Error  string
}

RefundFailedEvent is emitted when refund attempt fails

type RefundHTLCComponents

type RefundHTLCComponents struct {
	RefundPubKey [32]byte // X-only public key for refund (32 bytes)
	Timeout      uint32   // CSV timeout in blocks
}

RefundHTLCComponents contains the parsed components from a Boltz HTLC refund leaf script

func ValidateRefundLeafScript

func ValidateRefundLeafScript(outputHex string) (*RefundHTLCComponents, error)

ValidateRefundLeafScript parses and validates a Boltz HTLC refund leaf script. The expected structure follows Boltz's refund format:

OP_PUSHBYTES_32 <refund_pubkey>
OP_CHECKSIGVERIFY
OP_PUSHBYTES_2 <timeout>
OP_CHECKLOCKTIMEVERIFY (absolute block height)

Note: Boltz uses CLTV (absolute timelock) not CSV (relative timelock) for refund paths.

Example:

input: "207599756afc49ebf5a6f3ac5848ef0afe934edd7b669bca02029acf10cc7f83acad02f802b1"
-> refundPubKey: 7599756afc49ebf5a6f3ac5848ef0afe934edd7b669bca02029acf10cc7f83ac
-> timeout: 760 blocks (0x02f8 little-endian)

type ResumeChainSwapParams

type ResumeChainSwapParams struct {
	SwapID             string
	From               boltz.Currency
	To                 boltz.Currency
	Amount             uint64
	PreimageHex        string
	BoltzResponseJSON  string
	UserBtcAddress     string
	UserLockTxid       string
	ServerLockTxid     string
	ClaimTxid          string
	RefundTxid         string
	Status             ChainSwapStatus
	Error              string
	Timestamp          int64
	Network            *chaincfg.Params
	EventCallback      ChainSwapEventCallback
	UnilateralRefundCB func(swapId string, opts vhtlc.Opts) error
}

type ServerLockEvent

type ServerLockEvent struct {
	SwapID string
	TxID   string
}

ServerLockEvent is emitted when server (Boltz) locks funds

type Swap

type Swap struct {
	Id           string
	Invoice      string
	TxId         string
	Timestamp    int64
	RedeemTxid   string
	Status       SwapStatus
	PreimageHash []byte
	TimeoutInfo  boltz.TimeoutBlockHeights
	Opts         *vhtlc.Opts
	Amount       uint64
}

type SwapHandler

type SwapHandler struct {
	// contains filtered or unexported fields
}

func NewSwapHandler

func NewSwapHandler(
	arkClient arksdk.ArkClient,
	transportClient client.TransportClient,
	indexerClient indexer.Indexer,
	boltzSvc *boltz.Api,
	esploraURL string,
	privateKey *btcec.PrivateKey,
	timeout uint32,
) (*SwapHandler, error)

func (*SwapHandler) ChainSwapArkToBtc

func (h *SwapHandler) ChainSwapArkToBtc(
	ctx context.Context,
	amount uint64,
	btcDestinationAddress string,
	network *chaincfg.Params,
	eventCallback ChainSwapEventCallback,
	unilateralRefundCallback func(swapId string, opts vhtlc.Opts) error,
) (*ChainSwap, error)

ChainSwapArkToBtc performs an Ark → Bitcoin on-chain atomic swap This is the main entry point for swapping Ark VTXOs to Bitcoin on-chain Send ARK VTXO -> Receive BTC UTXO Boltz locks BTC UTXO and it sends details on how user can claim it in claimDetails and where to send ARK VTXO in lockupDetails claimLeaf(claimDetials) is used by user to cooperative claim BTC tx LockupDetails should container VHTLC address where Boltz's Fulmine is receiver 1. generate preimage 2. POST /swap/chain: preimageHash, claimPubKey, refundPubKey

{
	"id": "KEBsfLtqhsmA",
	"claimDetails": {
		"serverPublicKey": "02a9750704fdf536a573472938b4457be73e75513ff5ba3d017b2d73e070055026",
		"amount": 2797,
		"lockupAddress": "bcrt1pyz4djuc8eqn9na9s5l5lqg24uawv5ycaw6a3r9vaz0w3ewen7maq7ldt8q",
		"timeoutBlockHeight": 542,
		"swapTree": {
			"claimLeaf": {
				"version": 192,
				"output": "82012088a914608bc8a727928e8aa18c7a2489c003deb47ff08388207599756afc49ebf5a6f3ac5848ef0afe934edd7b669bca02029acf10cc7f83acac"
			},
			"refundLeaf": {
				"version": 192,
				"output": "20a9750704fdf536a573472938b4457be73e75513ff5ba3d017b2d73e070055026ad021e02b1"
			}
		}
	},
	"lockupDetails": {
		"serverPublicKey": "025067f8c4f61cf3bcbf131edbe0256d890332d2cdba64355a4153db1101e84cd0",
		"amount": 3000,
		"lockupAddress": "tark1qz4a0tydelxxun8w62zz3zjk36sr6aqrs58gmne23r9ea37jwx9awtw542kccdpm6nsuwfdw808r56humw46hqrrrg8dsem5v6hqu5d97zgl6c",
		"timeoutBlockHeight": 1769647586,
		"timeouts": {
			"refund": 1769647586,
			"unilateralClaim": 6144,
			"unilateralRefund": 6144,
			"unilateralRefundWithoutReceiver": 12288
		}
	}
}

what user needs to validate? - from claimDetails validate claimLeaf ? maybe we dont needs since for us it is important that we can refund vhtlc , validate HTLC - from lockupDetails validate(recreate) vhtlc address claimPubKey and preimage are used to claim BTC tx refundPubKey is used to refund ARK VTXO tx after timeout if something goes wrong

  1. SendOffchain -> send VTXO to address claimable by Boltz Fulmine(receiverPubKey)
  2. Once Boltz notices VTXO, it will send(lock) coins on BTC mainnet - BTC lockup TX
  3. Boltz send server.mempool and server.confimed events via WebSocket and we than decide when to claim 5.1 Cooperative claim so Boltz doesnt need to scan mainchain for preimage 5.2 Unilateral claim if Boltz not responsive
  4. User Refunds in case something goes wrong, we should schedule unilateral refund? 6.1 Try Cooperative Refund 6.2 Try Unilateral Refund
  5. Quote mechanism: What if user sends(locks) less amount than what he announced in swap request? in transaction.lockupfailed get quote and accept quote

func (*SwapHandler) ChainSwapBtcToArk

func (h *SwapHandler) ChainSwapBtcToArk(
	_ context.Context,
	amount uint64,
	network *chaincfg.Params,
	eventCallback ChainSwapEventCallback,
) (*ChainSwap, error)
ChainSwapBtcToArk performs a Bitcoin on-chain → Ark atomic swap

This is the reverse direction: user locks BTC on-chain, receives Ark VTXOs Send BTC -> Receive VTXO

{
	"id": "rZfDV8vtQ5Jk",
	"claimDetails": {
		"serverPublicKey": "025067f8c4f61cf3bcbf131edbe0256d890332d2cdba64355a4153db1101e84cd0",
		"amount": 2801,
		"lockupAddress": "tark1qz4a0tydelxxun8w62zz3zjk36sr6aqrs58gmne23r9ea37jwx9a0g5xczda6llpnevn3gnw3muwwnw9cze8988g0j2dvhssdfqkkg8n4jt5ln",
		"timeoutBlockHeight": 1769678334,
		"timeouts": {
			"refund": 1769678334,
			"unilateralClaim": 6144,
			"unilateralRefund": 6144,
			"unilateralRefundWithoutReceiver": 12288
		}
	},
	"lockupDetails": {
		"serverPublicKey": "028923258347dd79d51195e2054d9f92a6c4cfcbce86a92e3b9e2f7b51a0750d2b",
		"amount": 3000,
		"lockupAddress": "bcrt1pugmgfs2zx4w48w2cgnsvvrhpdy0zlntdz8gch2rz6tafnm8v8ewqm5mpjg",
		"timeoutBlockHeight": 760,
		"swapTree": {
			"claimLeaf": {
				"version": 192,
				"output": "82012088a9140f49a45d0bea33b5be812590dc8d284a0ebe195c88208923258347dd79d51195e2054d9f92a6c4cfcbce86a92e3b9e2f7b51a0750d2bac"
			},
			"refundLeaf": {
				"version": 192,
				"output": "207599756afc49ebf5a6f3ac5848ef0afe934edd7b669bca02029acf10cc7f83acad02f802b1"
			}
		},
	}
}

func (*SwapHandler) ClaimVHTLC

func (h *SwapHandler) ClaimVHTLC(
	ctx context.Context, preimage []byte, vhtlcOpts vhtlc.Opts,
) (string, error)

func (*SwapHandler) GetInvoice

func (h *SwapHandler) GetInvoice(
	ctx context.Context, amount uint64, postProcess func(swap Swap) error,
) (Swap, error)

func (*SwapHandler) GetVHTLCFunds

func (h *SwapHandler) GetVHTLCFunds(
	ctx context.Context, vhtlcOpts []vhtlc.Opts,
) ([]types.Vtxo, error)

func (*SwapHandler) PayInvoice

func (h *SwapHandler) PayInvoice(
	ctx context.Context, invoice string, unilateralRefund func(swap Swap) error,
) (*Swap, error)

func (*SwapHandler) PayOffer

func (h *SwapHandler) PayOffer(
	ctx context.Context, offer string, lightningUrl string, unilateralRefund func(swap Swap) error,
) (*Swap, error)

func (*SwapHandler) RefundArkToBTCSwap

func (h *SwapHandler) RefundArkToBTCSwap(
	ctx context.Context,
	swapId string,
	vhtlcOpts vhtlc.Opts,
	unilateralRefundCallback func(swapId string, opts vhtlc.Opts) error,
) (string, error)

func (*SwapHandler) RefundBtcToArkSwap

func (h *SwapHandler) RefundBtcToArkSwap(
	ctx context.Context,
	swapId string,
	amount uint64,
	userLockupTxid string,
	boltzSwapRespJson string,
) (string, error)

RefundBtcToArkSwap performs a BTC→ARK refund by: 1. Reading swap data from the ChainSwap struct (populated by service layer from DB) 2. Checking if CLTV timeout has passed 3. Creating and signing a refund transaction spending the lockup UTXO via script-path 4. Sending BTC to fulmine boarding address 5. Broadcasting the transaction 6. Waiting for confirmation 7. Calling Settle() to board the BTC as VTXO

This function is called when a BTC→ARK swap fails and needs to be refunded. The BTC is claimed from the lockup address using the refund script path (CLTV timeout) and sent to a fulmine boarding address, then settled to become a VTXO.

The swap data is persisted in the DB by the service layer and passed in via the ChainSwap struct (BoltzCreateResponseJSON and UserLockupTxHex fields). Refunds work even after service restart and even if Boltz API is unavailable.

func (*SwapHandler) RefundSwap

func (h *SwapHandler) RefundSwap(
	ctx context.Context, swapType, swapId string, withReceiver bool, vhtlcOpts vhtlc.Opts,
) (string, error)

func (*SwapHandler) ResumeChainSwap

func (h *SwapHandler) ResumeChainSwap(
	ctx context.Context,
	params ResumeChainSwapParams,
) (*ChainSwap, error)

func (*SwapHandler) SettleVHTLCWithClaimPath

func (h *SwapHandler) SettleVHTLCWithClaimPath(
	ctx context.Context, vhtlcOpts vhtlc.Opts, preimage []byte,
) (string, error)

SettleVHTLCWithClaimPath settles a VHTLC using the claim path (revealing preimage) via batch session. This is used for reverse submarine swaps where Fulmine is the receiver.

func (*SwapHandler) SettleVHTLCWithCollaborativeRefundPath

func (h *SwapHandler) SettleVHTLCWithCollaborativeRefundPath(
	ctx context.Context, vhtlcOpts vhtlc.Opts,
	partialForfeitTx, proof, message string, signerSession tree.SignerSession,
) (string, error)

func (*SwapHandler) SettleVhtlcWithRefundPath

func (h *SwapHandler) SettleVhtlcWithRefundPath(
	ctx context.Context, vhtlcOpts vhtlc.Opts,
) (string, error)

SettleVhtlcWithRefundPath settles a VHTLC using the refund path via batch session. This is used for submarine swaps where Fulmine is the sender and needs to recover funds.

type SwapStatus

type SwapStatus int
const (
	SwapPending SwapStatus = iota
	SwapFailed
	SwapSuccess
)

type TransactionStatus

type TransactionStatus struct {
	Confirmed   bool
	BlockHeight uint32
	BlockHash   string
	BlockTime   uint64
}

type UserLockEvent

type UserLockEvent struct {
	SwapID string
	TxID   string
}

UserLockEvent is emitted when user locks funds (Ark VTXO or BTC UTXO)

type UserLockFailedEvent

type UserLockFailedEvent struct {
	SwapID string
	Error  string
}

UserLockFailedEvent is emitted when user lock fails

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL