feat(api): add POST /channel/deposit (#2443)

Co-authored-by: Alejandro Cabeza Romero <alex93cabeza@gmail.com>
This commit is contained in:
Youngjoon Lee
2026-04-02 11:04:31 +09:00
committed by GitHub
co-authored by Alejandro Cabeza Romero
parent f77ca73324
commit 6dde6161b6
7 changed files with 166 additions and 8 deletions
+9 -1
View File
@@ -46,7 +46,9 @@ use super::handlers::{
use crate::{
WalletService,
api::{
handlers::{leader_claim, post_activity, post_declaration, post_withdrawal},
handlers::{
channel_deposit, leader_claim, post_activity, post_declaration, post_withdrawal,
},
openapi::ApiDoc,
},
};
@@ -215,6 +217,12 @@ where
paths::MEMPOOL_ADD_TX,
routing::post(add_tx::<MempoolStorageAdapter, RuntimeServiceId>),
)
.route(
paths::CHANNEL_DEPOSIT,
routing::post(
channel_deposit::<WalletService, MempoolStorageAdapter, RuntimeServiceId>,
),
)
.route(
paths::SDP_POST_DECLARATION,
routing::post(
+106 -4
View File
@@ -19,12 +19,17 @@ use lb_chain_service::ConsensusMsg;
use lb_core::{
block::Block,
header::HeaderId,
mantle::{SignedMantleTx, Transaction},
mantle::{
Op, SignedMantleTx, Transaction, gas::MainnetGasConstants, tx_builder::MantleTxBuilder,
},
};
use lb_http_api_common::{
bodies::wallet::{
balance::WalletBalanceResponseBody,
transfer_funds::{WalletTransferFundsRequestBody, WalletTransferFundsResponseBody},
bodies::{
channel::{ChannelDepositRequestBody, ChannelDepositResponseBody},
wallet::{
balance::WalletBalanceResponseBody,
transfer_funds::{WalletTransferFundsRequestBody, WalletTransferFundsResponseBody},
},
},
paths,
};
@@ -360,6 +365,103 @@ where
>(&handle, tx, Transaction::hash))
}
#[utoipa::path(
post,
path = paths::CHANNEL_DEPOSIT,
responses(
(status = 200, description = "Submit a channel deposit"),
(status = 500, description = "Internal server error", body = String),
)
)]
pub async fn channel_deposit<WalletService, StorageAdapter, RuntimeServiceId>(
State(handle): State<OverwatchHandle<RuntimeServiceId>>,
Json(req): Json<ChannelDepositRequestBody>,
) -> Response
where
WalletService: WalletServiceData,
StorageAdapter: lb_tx_service::storage::MempoolStorageAdapter<
RuntimeServiceId,
Item = SignedMantleTx,
Key = <SignedMantleTx as Transaction>::Hash,
> + Send
+ Sync
+ Clone
+ 'static,
StorageAdapter::Error: Debug,
RuntimeServiceId: Debug
+ Display
+ Send
+ Sync
+ 'static
+ AsServiceId<WalletService>
+ AsServiceId<
TxMempoolService<
MempoolNetworkAdapter<
SignedMantleTx,
<SignedMantleTx as Transaction>::Hash,
RuntimeServiceId,
>,
Mempool<
HeaderId,
SignedMantleTx,
<SignedMantleTx as Transaction>::Hash,
StorageAdapter,
RuntimeServiceId,
>,
StorageAdapter,
RuntimeServiceId,
>,
>,
{
make_request_and_return_response!(async {
let wallet = WalletApi::<WalletService, RuntimeServiceId>::new(
handle.relay::<WalletService>().await?,
);
let tx_builder = MantleTxBuilder::new()
.push_op(Op::ChannelDeposit(req.deposit))
.push_op(Op::Transfer(req.burn));
let lb_wallet_service::TipResponse {
tip,
response: funded_tx_builder,
} = wallet
.fund_tx(
None,
tx_builder,
req.change_public_key,
req.funding_public_keys,
)
.await?;
let tx_fee = funded_tx_builder.gas_cost::<MainnetGasConstants>();
if tx_fee > req.max_tx_fee {
return Err(overwatch::DynError::from(format!(
"tx_fee({tx_fee}) exceeds max_tx_fee({})",
req.max_tx_fee
)));
}
let signed_tx = wallet.sign_tx(Some(tip), funded_tx_builder).await?.response;
let tx_hash = signed_tx.hash();
mempool::add_tx::<
Libp2pNetworkBackend,
MempoolNetworkAdapter<
SignedMantleTx,
<SignedMantleTx as Transaction>::Hash,
RuntimeServiceId,
>,
StorageAdapter,
SignedMantleTx,
<SignedMantleTx as Transaction>::Hash,
RuntimeServiceId,
>(&handle, signed_tx, Transaction::hash)
.await?;
Ok(ChannelDepositResponseBody { hash: tx_hash })
})
}
#[utoipa::path(
post,
path = paths::SDP_POST_DECLARATION,