From 0c0b2b3647ce51e6086d6c4d0972e02a2515c83f Mon Sep 17 00:00:00 2001 From: Zhen Lu Date: Thu, 30 May 2024 16:25:52 -0700 Subject: [PATCH] Add a function to set fees for request_withdrawal --- objects/on_chain_fee_target.go | 65 +++++++++++++++++++++++++++++ objects/request_withdrawal_input.go | 6 +++ objects/transaction_status.go | 2 +- scripts/request_withdrawal.go | 4 ++ services/lightspark_client.go | 21 ++++++++-- 5 files changed, 94 insertions(+), 4 deletions(-) create mode 100644 objects/on_chain_fee_target.go diff --git a/objects/on_chain_fee_target.go b/objects/on_chain_fee_target.go new file mode 100644 index 0000000..2db01b0 --- /dev/null +++ b/objects/on_chain_fee_target.go @@ -0,0 +1,65 @@ +// Copyright ©, 2023-present, Lightspark Group, Inc. - All Rights Reserved +package objects + +import ( + "encoding/json" +) + +type OnChainFeeTarget int + +const ( + OnChainFeeTargetUndefined OnChainFeeTarget = iota + + // OnChainFeeTargetHigh Transaction expected to be confirmed within 2 blocks. + OnChainFeeTargetHigh + // OnChainFeeTargetMedium Transaction expected to be confirmed within 6 blocks. + OnChainFeeTargetMedium + // OnChainFeeTargetLow Transaction expected to be confirmed within 18 blocks. + OnChainFeeTargetLow + // OnChainFeeTargetBackground Transaction expected to be confirmed within 50 blocks. + OnChainFeeTargetBackground +) + +func (a *OnChainFeeTarget) UnmarshalJSON(b []byte) error { + var s string + if err := json.Unmarshal(b, &s); err != nil { + return err + } + switch s { + default: + *a = OnChainFeeTargetUndefined + case "HIGH": + *a = OnChainFeeTargetHigh + case "MEDIUM": + *a = OnChainFeeTargetMedium + case "LOW": + *a = OnChainFeeTargetLow + case "BACKGROUND": + *a = OnChainFeeTargetBackground + + } + return nil +} + +func (a OnChainFeeTarget) StringValue() string { + var s string + switch a { + default: + s = "undefined" + case OnChainFeeTargetHigh: + s = "HIGH" + case OnChainFeeTargetMedium: + s = "MEDIUM" + case OnChainFeeTargetLow: + s = "LOW" + case OnChainFeeTargetBackground: + s = "BACKGROUND" + + } + return s +} + +func (a OnChainFeeTarget) MarshalJSON() ([]byte, error) { + s := a.StringValue() + return json.Marshal(s) +} diff --git a/objects/request_withdrawal_input.go b/objects/request_withdrawal_input.go index 0dab9b5..e2b66dd 100644 --- a/objects/request_withdrawal_input.go +++ b/objects/request_withdrawal_input.go @@ -17,4 +17,10 @@ type RequestWithdrawalInput struct { // IdempotencyKey The idempotency key of the request. The same result will be returned for the same idempotency key. IdempotencyKey *string `json:"request_withdrawal_input_idempotency_key"` + + // FeeTarget The target of the fee that should be used when crafting the L1 transaction. You should only set `fee_target` or `sats_per_vbyte`. If neither of them is set, default value of MEDIUM will be used as `fee_target`. + FeeTarget *OnChainFeeTarget `json:"request_withdrawal_input_fee_target"` + + // SatsPerVbyte A manual fee rate set in sat/vbyte that should be used when crafting the L1 transaction. You should only set `fee_target` or `sats_per_vbyte` + SatsPerVbyte *int64 `json:"request_withdrawal_input_sats_per_vbyte"` } diff --git a/objects/transaction_status.go b/objects/transaction_status.go index b50e849..f7f29d0 100644 --- a/objects/transaction_status.go +++ b/objects/transaction_status.go @@ -11,7 +11,7 @@ type TransactionStatus int const ( TransactionStatusUndefined TransactionStatus = iota - // TransactionStatusSuccess Transaction succeeded.. + // TransactionStatusSuccess Transaction succeeded. TransactionStatusSuccess // TransactionStatusFailed Transaction failed. TransactionStatusFailed diff --git a/scripts/request_withdrawal.go b/scripts/request_withdrawal.go index fa658f6..a2779ff 100644 --- a/scripts/request_withdrawal.go +++ b/scripts/request_withdrawal.go @@ -10,6 +10,8 @@ mutation RequestWithdrawal( $bitcoin_address: String! $withdrawal_mode: WithdrawalMode! $idempotency_key: String + $fee_target: OnChainFeeTarget + $sats_per_vbyte: Int ) { request_withdrawal(input: { node_id: $node_id @@ -17,6 +19,8 @@ mutation RequestWithdrawal( bitcoin_address: $bitcoin_address withdrawal_mode: $withdrawal_mode idempotency_key: $idempotency_key + fee_target: $fee_target + sats_per_vbyte: $sats_per_vbyte }) { request { ...WithdrawalRequestFragment diff --git a/services/lightspark_client.go b/services/lightspark_client.go index 5c88e19..614eb58 100644 --- a/services/lightspark_client.go +++ b/services/lightspark_client.go @@ -659,7 +659,13 @@ func (client *LightsparkClient) PayUmaInvoice(nodeId string, encodedInvoice stri func (client *LightsparkClient) RequestWithdrawal(nodeId string, amountSats int64, bitcoinAddress string, withdrawalMode objects.WithdrawalMode, ) (*objects.WithdrawalRequest, error) { - return client.RequestWithdrawalWithIdempotencyKey(nodeId, amountSats, bitcoinAddress, withdrawalMode, nil) + return client.RequestWithdrawalWithIdempotencyKeyAndFee(nodeId, amountSats, bitcoinAddress, withdrawalMode, nil, nil, nil) +} + +func (client *LightsparkClient) RequestWithdrawalWithIdempotencyKey(nodeId string, amountSats int64, + bitcoinAddress string, withdrawalMode objects.WithdrawalMode, idempotencyKey *string, +) (*objects.WithdrawalRequest, error) { + return client.RequestWithdrawalWithIdempotencyKeyAndFee(nodeId, amountSats, bitcoinAddress, withdrawalMode, idempotencyKey, nil, nil) } // RequestWithdrawalWithIdempotencyKey withdraws funds from the account and sends it to the requested @@ -680,8 +686,9 @@ func (client *LightsparkClient) RequestWithdrawal(nodeId string, amountSats int6 // idempotencyKey: A unique key that identifies this withdrawal. If a withdrawal with the same idempotency key has // already been made, the same WithdrawalRequest will be returned. This must be unique for each payment. If // you do not have a specific idempotency requirement, you can pass nil or just use `RequestWithdrawal`. -func (client *LightsparkClient) RequestWithdrawalWithIdempotencyKey(nodeId string, amountSats int64, - bitcoinAddress string, withdrawalMode objects.WithdrawalMode, idempotencyKey *string, +func (client *LightsparkClient) RequestWithdrawalWithIdempotencyKeyAndFee(nodeId string, amountSats int64, + bitcoinAddress string, withdrawalMode objects.WithdrawalMode, idempotencyKey *string, + feeTarget *objects.OnChainFeeTarget, satsPerVbyte *int, ) (*objects.WithdrawalRequest, error) { variables := map[string]interface{}{ "node_id": nodeId, @@ -694,6 +701,14 @@ func (client *LightsparkClient) RequestWithdrawalWithIdempotencyKey(nodeId strin variables["idempotency_key"] = *idempotencyKey } + if feeTarget != nil && satsPerVbyte != nil { + return nil, errors.New("feeTarget and satsPerVbyte cannot be set at the same time") + } else if feeTarget != nil { + variables["fee_target"] = *feeTarget + } else if satsPerVbyte != nil { + variables["sats_per_vbyte"] = *satsPerVbyte + } + signingKey, err := client.getNodeSigningKey(nodeId) if err != nil { return nil, err