Skip to content

Commit e70eeea

Browse files
committed
wip
1 parent 77e795e commit e70eeea

File tree

5 files changed

+103
-137
lines changed

5 files changed

+103
-137
lines changed

crates/cli/src/args.rs

Lines changed: 43 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use url::Url;
3737
use crate::file::NodeArgsConfig;
3838
use crate::options::*;
3939
#[cfg(feature = "cartridge")]
40-
use crate::sidecar::{bootstrap_and_start_sidecars, PaymasterSidecarInfo};
40+
use crate::sidecar::bootstrap_and_start_sidecars;
4141
#[cfg(feature = "vrf")]
4242
use crate::sidecar::{build_vrf_config, VrfSidecarInfo};
4343
use crate::utils::{self, parse_chain_config_dir, parse_seed};
@@ -174,12 +174,6 @@ impl SequencerNodeArgs {
174174
None => None,
175175
};
176176

177-
#[cfg(feature = "cartridge")]
178-
let paymaster_sidecar = match self.paymaster_config(&config.chain)? {
179-
Some((_, sidecar)) => sidecar,
180-
None => None,
181-
};
182-
183177
if config.forking.is_some() {
184178
let node =
185179
Node::build_forked(config.clone()).await.context("failed to build forked node")?;
@@ -191,22 +185,24 @@ impl SequencerNodeArgs {
191185
// Launch the node
192186
let handle = node.launch().await.context("failed to launch forked node")?;
193187

194-
#[cfg(feature = "cartridge")]
195-
let mut sidecars = if config.paymaster.is_some() {
196-
let sidecars = bootstrap_and_start_sidecars(
197-
paymaster_sidecar.as_ref(),
188+
#[cfg(feature = "paymaster")]
189+
let paymaster = if !self.paymaster.is_external() {
190+
use crate::sidecar::bootstrap_paymaster;
191+
192+
let rpc_url = Url::parse(&format!("http://{}", handle.rpc().addr()))?;
193+
let chain_spec = &handle.node().config().chain;
194+
195+
let paymaster = bootstrap_paymaster(
198196
&self.paymaster,
199-
#[cfg(feature = "vrf")]
200-
&self.vrf,
201-
&handle.node().config().chain,
202-
handle.rpc().addr(),
203-
#[cfg(feature = "vrf")]
204-
vrf_sidecar.as_ref(),
205-
handle.node().config().dev.fee,
197+
config.paymaster.unwrap().url.clone(),
198+
rpc_url,
199+
&chain_spec,
206200
)
201+
.await?
202+
.start()
207203
.await?;
208204

209-
sidecars
205+
Some(paymaster)
210206
} else {
211207
None
212208
};
@@ -221,10 +217,9 @@ impl SequencerNodeArgs {
221217
_ = handle.stopped() => { }
222218
}
223219

224-
// Shutdown sidecar processes
225-
#[cfg(feature = "cartridge")]
226-
if let Some(ref mut s) = sidecars {
227-
s.shutdown().await;
220+
#[cfg(feature = "paymaster")]
221+
if let Some(ref mut s) = paymaster {
222+
s.shutdown().await?;
228223
}
229224
} else {
230225
let node = Node::build(config.clone()).context("failed to build node")?;
@@ -235,22 +230,24 @@ impl SequencerNodeArgs {
235230

236231
let handle = node.launch().await.context("failed to launch node")?;
237232

238-
#[cfg(feature = "cartridge")]
239-
let mut sidecars = if config.paymaster.is_some() {
240-
let sidecars = bootstrap_and_start_sidecars(
241-
paymaster_sidecar.as_ref(),
233+
#[cfg(feature = "paymaster")]
234+
let paymaster = if !self.paymaster.is_external() {
235+
use crate::sidecar::bootstrap_paymaster;
236+
237+
let rpc_url = Url::parse(&format!("http://{}", handle.rpc().addr()))?;
238+
let chain_spec = &handle.node().config().chain;
239+
240+
let paymaster = bootstrap_paymaster(
242241
&self.paymaster,
243-
#[cfg(feature = "vrf")]
244-
&self.vrf,
245-
&handle.node().config().chain,
246-
handle.rpc().addr(),
247-
#[cfg(feature = "vrf")]
248-
vrf_sidecar.as_ref(),
249-
handle.node().config().dev.fee,
242+
config.paymaster.unwrap().url.clone(),
243+
rpc_url,
244+
&chain_spec,
250245
)
246+
.await?
247+
.start()
251248
.await?;
252249

253-
sidecars
250+
Some(paymaster)
254251
} else {
255252
None
256253
};
@@ -265,10 +262,9 @@ impl SequencerNodeArgs {
265262
_ = handle.stopped() => { }
266263
}
267264

268-
// Shutdown sidecar processes
269-
#[cfg(feature = "cartridge")]
270-
if let Some(ref mut s) = sidecars {
271-
s.shutdown().await;
265+
#[cfg(feature = "paymaster")]
266+
if let Some(ref mut s) = paymaster {
267+
s.shutdown().await?;
272268
}
273269
}
274270

@@ -288,8 +284,8 @@ impl SequencerNodeArgs {
288284
let execution = self.execution_config();
289285
let sequencing = self.sequencer_config();
290286

291-
#[cfg(feature = "cartridge")]
292-
let paymaster = self.paymaster_config(&chain)?.map(|(config, _)| config);
287+
#[cfg(feature = "paymaster")]
288+
let paymaster = self.paymaster_config(&chain)?;
293289

294290
#[cfg(feature = "vrf")]
295291
let vrf = self.vrf_config()?.map(|(config, _)| config);
@@ -558,23 +554,21 @@ impl SequencerNodeArgs {
558554
fn paymaster_config(
559555
&self,
560556
chain_spec: &Arc<katana_chain_spec::ChainSpec>,
561-
) -> Result<Option<(PaymasterConfig, Option<PaymasterSidecarInfo>)>> {
557+
) -> Result<Option<PaymasterConfig>> {
562558
if !self.paymaster.enabled {
563559
return Ok(None);
564560
}
565561

566562
use crate::sidecar::DEFAULT_PAYMASTER_API_KEY;
567563

568-
let (mut config, sidecar_info) = if self.paymaster.is_external() {
564+
let mut config = if self.paymaster.is_external() {
569565
let url = self.paymaster.url.clone().expect("URL must be set in external mode");
570566
let api_key = self.paymaster.api_key.clone();
571-
(PaymasterConfig { url, api_key, cartridge_api: None }, None)
567+
PaymasterConfig { url, api_key, cartridge_api: None }
572568
} else {
573569
// find free port
574570
let listener = std::net::TcpListener::bind("127.0.0.1:0")?;
575-
let addr = listener.local_addr()?;
576-
let port = addr.port();
577-
let url = Url::parse(&format!("http://{addr}"))?;
571+
let url = Url::parse(&format!("http://{}", listener.local_addr()?))?;
578572

579573
let api_key = self
580574
.paymaster
@@ -588,11 +582,7 @@ impl SequencerNodeArgs {
588582
);
589583
}
590584

591-
let sidecar_info = PaymasterSidecarInfo { port, api_key: api_key.clone() };
592-
(
593-
PaymasterConfig { url, api_key: Some(api_key), cartridge_api: None },
594-
Some(sidecar_info),
595-
)
585+
PaymasterConfig { url, api_key: Some(api_key), cartridge_api: None }
596586
};
597587

598588
#[cfg(feature = "cartridge")]
@@ -624,7 +614,7 @@ impl SequencerNodeArgs {
624614
});
625615
}
626616

627-
Ok(Some((config, sidecar_info)))
617+
Ok(Some(config))
628618
}
629619

630620
#[cfg(feature = "vrf")]

crates/cli/src/options.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,7 @@ pub struct PaymasterOptions {
565565
pub url: Option<Url>,
566566

567567
/// API key to send via `x-paymaster-api-key` when proxying requests.
568-
#[arg(requires = "paymaster_enabled")]
568+
#[arg(requires = "paymaster_url")]
569569
#[arg(long = "paymaster.api-key", value_name = "KEY")]
570570
#[serde(default)]
571571
pub api_key: Option<String>,

crates/cli/src/sidecar.rs

Lines changed: 37 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@ pub use cartridge::vrf::{
1919
use katana_chain_spec::ChainSpec;
2020
use katana_genesis::allocation::GenesisAccountAlloc;
2121
use katana_genesis::constant::{DEFAULT_ETH_FEE_TOKEN_ADDRESS, DEFAULT_STRK_FEE_TOKEN_ADDRESS};
22+
use katana_node::config::paymaster::PaymasterConfig;
2223
#[cfg(feature = "vrf")]
2324
use katana_node::config::paymaster::VrfConfig;
25+
use katana_node::config::Config;
2426
pub use katana_paymaster::{
25-
format_felt, wait_for_paymaster_ready, PaymasterConfig, PaymasterConfigBuilder,
26-
PaymasterSidecar, PaymasterSidecarProcess,
27+
format_felt, wait_for_paymaster_ready, PaymasterService, PaymasterServiceConfig,
28+
PaymasterServiceConfigBuilder, PaymasterSidecarProcess,
2729
};
2830
use katana_primitives::chain::ChainId;
2931
use katana_primitives::{ContractAddress, Felt};
@@ -92,7 +94,6 @@ pub fn build_vrf_config(
9294
/// Result of bootstrapping sidecars.
9395
#[derive(Debug, Default)]
9496
pub struct BootstrapResult {
95-
pub paymaster: Option<PaymasterBootstrapInfo>,
9697
#[cfg(feature = "vrf")]
9798
pub vrf: Option<VrfBootstrapResult>,
9899
}
@@ -120,7 +121,6 @@ pub struct PaymasterBootstrapInfo {
120121

121122
/// Configuration for bootstrapping sidecars.
122123
pub struct BootstrapConfig {
123-
pub paymaster: Option<PaymasterBootstrapInput>,
124124
#[cfg(feature = "vrf")]
125125
pub vrf: Option<VrfBootstrapConfig>,
126126
#[allow(dead_code)]
@@ -139,17 +139,9 @@ pub struct PaymasterBootstrapInput {
139139
/// Bootstrap sidecars by deploying necessary contracts and preparing configuration.
140140
///
141141
/// This must be called after the node is launched but before sidecars are started.
142-
pub async fn bootstrap_sidecars(
143-
config: &BootstrapConfig,
144-
chain_spec: &ChainSpec,
145-
) -> Result<BootstrapResult> {
142+
pub async fn bootstrap_sidecars(config: &BootstrapConfig) -> Result<BootstrapResult> {
146143
let mut result = BootstrapResult::default();
147144

148-
if let Some(paymaster_input) = &config.paymaster {
149-
let bootstrap = bootstrap_paymaster_from_genesis(paymaster_input, chain_spec).await?;
150-
result.paymaster = Some(bootstrap);
151-
}
152-
153145
#[cfg(feature = "vrf")]
154146
if let Some(vrf_cfg) = &config.vrf {
155147
let bootstrap = bootstrap_vrf(vrf_cfg).await?;
@@ -159,48 +151,35 @@ pub async fn bootstrap_sidecars(
159151
Ok(result)
160152
}
161153

162-
/// Bootstrap the paymaster using genesis accounts from the backend.
163-
///
164-
/// Always uses accounts 0, 1, 2 from genesis for relayer, gas tank, and estimate account.
165-
async fn bootstrap_paymaster_from_genesis(
166-
input: &PaymasterBootstrapInput,
167-
chain_spec: &ChainSpec,
168-
) -> Result<PaymasterBootstrapInfo> {
169-
// Extract account info from genesis - always use accounts 0, 1, 2
170-
let (relayer_address, relayer_private_key) = prefunded_account(chain_spec, 0)?;
171-
let (gas_tank_address, gas_tank_private_key) = prefunded_account(chain_spec, 1)?;
172-
let (estimate_account_address, estimate_account_private_key) =
173-
prefunded_account(chain_spec, 2)?;
174-
175-
// Build config without on-chain validation (accounts are from genesis)
176-
let config = PaymasterConfigBuilder::new()
177-
.rpc_url(input.rpc_url.clone())
178-
.port(0) // Port not needed for bootstrap
179-
.api_key(String::new())
180-
.relayer(relayer_address, relayer_private_key)
181-
.gas_tank(gas_tank_address, gas_tank_private_key)
182-
.estimate_account(estimate_account_address, estimate_account_private_key)
183-
.tokens(DEFAULT_ETH_FEE_TOKEN_ADDRESS, DEFAULT_STRK_FEE_TOKEN_ADDRESS)
184-
.build_unchecked()?;
185-
186-
// Create sidecar and bootstrap (deploys forwarder and gets chain_id)
187-
let mut sidecar = PaymasterSidecar::new(config);
188-
let forwarder_address = sidecar.bootstrap().await?;
189-
190-
// Extract chain_id (set during bootstrap)
191-
let chain_id =
192-
sidecar.get_chain_id().ok_or_else(|| anyhow!("chain_id not set after bootstrap"))?;
193-
194-
Ok(PaymasterBootstrapInfo {
195-
relayer_address,
196-
relayer_private_key,
197-
gas_tank_address,
198-
gas_tank_private_key,
199-
estimate_account_address,
200-
estimate_account_private_key,
201-
forwarder_address,
202-
chain_id,
203-
})
154+
pub async fn bootstrap_paymaster(
155+
options: &PaymasterOptions,
156+
paymaster_url: Url,
157+
rpc_url: Url,
158+
chain: &ChainSpec,
159+
) -> Result<PaymasterService> {
160+
let (relayer_addr, relayer_pk) = prefunded_account(chain, 0)?;
161+
let (gas_tank_addr, gas_tank_pk) = prefunded_account(chain, 1)?;
162+
let (estimate_account_addr, estimate_account_pk) = prefunded_account(chain, 2)?;
163+
164+
let port = paymaster_url.port().unwrap();
165+
166+
let mut builder = PaymasterServiceConfigBuilder::new()
167+
.rpc_url(rpc_url)
168+
.port(port)
169+
.api_key(DEFAULT_PAYMASTER_API_KEY)
170+
.relayer(relayer_addr, relayer_pk)
171+
.gas_tank(gas_tank_addr, gas_tank_pk)
172+
.estimate_account(estimate_account_addr, estimate_account_pk)
173+
.tokens(DEFAULT_ETH_FEE_TOKEN_ADDRESS, DEFAULT_STRK_FEE_TOKEN_ADDRESS);
174+
175+
if let Some(bin) = &options.bin {
176+
builder = builder.program_path(bin.clone());
177+
}
178+
179+
let mut paymaster = PaymasterService::new(builder.build().await?);
180+
paymaster.bootstrap().await?;
181+
182+
Ok(paymaster)
204183
}
205184

206185
fn prefunded_account(chain_spec: &ChainSpec, index: u16) -> Result<(ContractAddress, Felt)> {
@@ -276,7 +255,6 @@ impl Drop for SidecarProcesses {
276255

277256
/// Configuration for starting sidecars.
278257
pub struct SidecarStartConfig<'a> {
279-
pub paymaster: Option<PaymasterStartConfig<'a>>,
280258
#[cfg(feature = "vrf")]
281259
pub vrf: Option<VrfStartConfig<'a>>,
282260
}
@@ -309,7 +287,7 @@ pub async fn start_sidecars(
309287
(&config.paymaster, bootstrap.paymaster.as_ref())
310288
{
311289
// Build config using the builder pattern (unchecked since accounts are from genesis)
312-
let mut builder = PaymasterConfigBuilder::new()
290+
let mut builder = PaymasterServiceConfigBuilder::new()
313291
.rpc_url(paymaster_cfg.rpc_url.clone())
314292
.port(paymaster_cfg.port)
315293
.api_key(paymaster_cfg.api_key.clone())
@@ -335,7 +313,7 @@ pub async fn start_sidecars(
335313
let paymaster_config = builder.build_unchecked()?;
336314

337315
// Create sidecar with forwarder and chain_id from bootstrap
338-
let sidecar = PaymasterSidecar::new(paymaster_config)
316+
let sidecar = PaymasterService::new(paymaster_config)
339317
.forwarder(paymaster_bootstrap.forwarder_address)
340318
.chain_id(paymaster_bootstrap.chain_id);
341319

@@ -412,14 +390,13 @@ pub async fn bootstrap_and_start_sidecars(
412390
};
413391

414392
let bootstrap_config = BootstrapConfig {
415-
paymaster: paymaster_sidecar.map(|_| PaymasterBootstrapInput { rpc_url: rpc_url.clone() }),
416393
#[cfg(feature = "vrf")]
417394
vrf: vrf_bootstrap_config,
418395
fee_enabled,
419396
};
420397

421398
// Bootstrap contracts
422-
let bootstrap = bootstrap_sidecars(&bootstrap_config, chain_spec).await?;
399+
let bootstrap = bootstrap_sidecars(&bootstrap_config).await?;
423400

424401
// Build sidecar start config
425402
let paymaster_start_config = paymaster_sidecar.map(|info| PaymasterStartConfig {
@@ -434,7 +411,6 @@ pub async fn bootstrap_and_start_sidecars(
434411
vrf_sidecar.map(|info| VrfStartConfig { options: vrf_options, port: info.port });
435412

436413
let start_config = SidecarStartConfig {
437-
paymaster: paymaster_start_config,
438414
#[cfg(feature = "vrf")]
439415
vrf: vrf_config,
440416
};

0 commit comments

Comments
 (0)