Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions crates/sof-tx/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ categories = ["network-programming", "cryptography::cryptocurrencies"]
[lints]
workspace = true

[features]
default = []
sof-adapters = ["dep:sof"]

[dependencies]
async-trait = "0.1"
base64 = "0.22"
Expand All @@ -29,5 +33,6 @@ solana-signature = "3.1.0"
solana-signer = "3.0.0"
solana-system-interface = { version = "3.0.0", features = ["bincode"] }
solana-transaction = { version = "3.0.2", features = ["bincode"] }
sof = { version = "0.1.0", path = "../sof-observer", default-features = false, optional = true }
thiserror = "2.0"
tokio = { version = "1.48", features = ["macros", "rt-multi-thread", "net", "sync", "time"] }
65 changes: 65 additions & 0 deletions crates/sof-tx/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ It provides:
cargo add sof-tx
```

Enable SOF runtime adapters when you want provider values from live `sof` plugin events:

```toml
sof-tx = { version = "0.1", features = ["sof-adapters"] }
```

## Core Types

- `TxBuilder`: compose transaction instructions and signing inputs.
Expand All @@ -27,6 +33,65 @@ cargo add sof-tx
- `RoutingPolicy`: leader/backup fanout controls.
- `LeaderProvider` and `RecentBlockhashProvider`: provider boundaries.

## SOF Adapter Layer

With `sof-adapters` enabled, `PluginHostTxProviderAdapter` can be:

- registered as a SOF plugin to ingest blockhash/leader/topology events, and
- passed directly into `TxSubmitClient` as both providers.

```rust
use std::sync::Arc;

use sof::framework::{ObserverPlugin, PluginHost};
use sof_tx::{
SubmitMode, SubmitReliability, TxBuilder, TxSubmitClient,
adapters::PluginHostTxProviderAdapter,
submit::{JsonRpcTransport, UdpDirectTransport},
};
use solana_keypair::Keypair;
use solana_signer::Signer;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let adapter = Arc::new(PluginHostTxProviderAdapter::default());
let host = PluginHost::builder()
.add_shared_plugin(adapter.clone() as Arc<dyn ObserverPlugin>)
.build();

// If SOF runtime was already running, optionally seed from host snapshots.
adapter.prime_from_plugin_host(&host);

let client = TxSubmitClient::new(adapter.clone(), adapter.clone())
.with_reliability(SubmitReliability::Balanced)
.with_rpc_transport(Arc::new(JsonRpcTransport::new("https://api.mainnet-beta.solana.com")?))
.with_direct_transport(Arc::new(UdpDirectTransport));

let payer = Keypair::new();
let recipient = Keypair::new();
let builder = TxBuilder::new(payer.pubkey())
.with_compute_unit_limit(450_000)
.with_priority_fee_micro_lamports(100_000)
.add_instruction(solana_system_interface::instruction::transfer(
&payer.pubkey(),
&recipient.pubkey(),
1,
));

let _ = client
.submit_builder(builder, &[&payer], SubmitMode::Hybrid)
.await?;

Ok(())
}
```

Direct submit needs TPU endpoints for scheduled leaders. The adapter gets these from
`on_cluster_topology` events, or you can inject them manually with:

- `set_leader_tpu_addr(pubkey, tpu_addr)`
- `remove_leader_tpu_addr(pubkey)`

## Quickstart

```rust
Expand Down
5 changes: 5 additions & 0 deletions crates/sof-tx/src/adapters/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//! Optional adapter layer for integrating `sof` runtime signals with `sof-tx`.

mod plugin_host;

pub use plugin_host::{PluginHostTxProviderAdapter, PluginHostTxProviderAdapterConfig};
Loading