ApplicationContext

Struct ApplicationContext 

Source
pub struct ApplicationContext {
    pub config: Config,
    pub rate_limiter: Arc<RateLimiter>,
    /* private fields */
}
Expand description

Chain-agnostic context for dependency injection and resource management.

The ApplicationContext serves as a dependency injection container for the riglr ecosystem, enabling tools and workers to access shared resources (RPC clients, signers, database connections) without creating circular dependencies.

§Chain-Agnostic Design

The context uses type erasure (Arc<dyn Any>) to store blockchain clients without depending on their concrete types. This allows riglr-core to remain independent of blockchain SDKs while still providing access to them at runtime.

§Extension System

Resources are stored as “extensions” - type-erased objects that can be retrieved by their original type. This enables clean separation between riglr-core (which defines the interfaces) and chain-specific crates (which provide the implementations).

§Accessing Chain-Specific Clients

To maintain its chain-agnostic nature, riglr-core does not have direct methods like solana_client() on the ApplicationContext. Instead, these ergonomic accessors are provided via extension traits in chain-specific crates.

For example, riglr-solana-tools provides the SolanaAppContextProvider trait, which adds the .solana_client() method to ApplicationContext.

See the [riglr_core::provider_extensions] module for more details on this pattern.

§Examples

use riglr_core::provider::ApplicationContext;
use riglr_config::ConfigBuilder;
use std::sync::Arc;

// Application layer creates context and injects dependencies
let config = ConfigBuilder::default().build().unwrap();
let context = ApplicationContext::from_config(&config);

// Inject Solana RPC client (in real code, from riglr-solana-tools)
// let solana_client = Arc::new(solana_client::rpc_client::RpcClient::new(...));
// context.set_extension(solana_client.clone());

// Inject EVM provider (in real code, from riglr-evm-tools)  
// let evm_provider = Arc::new(alloy::providers::Provider::new(...));
// context.set_extension(evm_provider.clone());

// Tools retrieve clients by type
// let client: Option<Arc<RpcClient>> = context.get_extension();

Fields§

§config: Config

Configuration for the application

§rate_limiter: Arc<RateLimiter>

Rate limiter for controlling request rates per client/user

Implementations§

Source§

impl ApplicationContext

Source

pub fn from_config(config: &Config) -> Self

Create a new ApplicationContext from configuration

Source

pub fn from_env() -> Self

👎Deprecated since 0.3.0: Use Config::from_env() followed by ApplicationContext::from_config() instead. This ensures proper separation of concerns.

Create a new ApplicationContext from environment variables

DEPRECATED: Configuration should be loaded in the application binary using riglr_config::Config::from_env() and passed to ApplicationContext::from_config(). This ensures proper separation of concerns where riglr-core consumes configuration but does not load it, reinforcing the unidirectional dependency flow.

§Migration Guide

Instead of:

use riglr_core::provider::ApplicationContext;
let context = ApplicationContext::from_env();

Use:

use riglr_core::provider::ApplicationContext;
use riglr_config::Config;

let config = Config::from_env();
let context = ApplicationContext::from_config(&config);
Source

pub fn set_extension<T: Send + Sync + 'static>(&self, extension: Arc<T>)

Add an extension to the context

Extensions are stored by their type, allowing type-safe retrieval later. This is the recommended pattern for injecting RPC clients and other resources.

§Examples
use riglr_core::provider::ApplicationContext;
use riglr_config::ConfigBuilder;
use std::sync::Arc;

let config = ConfigBuilder::default().build().unwrap();
let context = ApplicationContext::from_config(&config);

// Add blockchain RPC clients as extensions
// Example: Add Solana RPC client
// let solana_client = Arc::new(solana_client::rpc_client::RpcClient::new(...));
// context.set_extension(solana_client);

// Example: Add EVM provider
// let evm_provider = Arc::new(alloy::Provider::new(...));
// context.set_extension(evm_provider);
Source

pub fn get_extension<T: Send + Sync + 'static>(&self) -> Option<Arc<T>>

Get an extension by type

Returns None if no extension of the given type has been set.

§Examples
use riglr_core::provider::ApplicationContext;
use riglr_config::ConfigBuilder;
use std::sync::Arc;

let config = ConfigBuilder::default().build().unwrap();
let context = ApplicationContext::from_config(&config);
// Add a typed extension (e.g., an RPC client)
// let client = Arc::new(MyRpcClient::new(...));
// context.set_extension(client.clone());

// Retrieve the client later by type
// let retrieved: Arc<MyRpcClient> = context.get_extension()
    // .expect("RPC client not found");
Source

pub fn has_extension<T: Send + Sync + 'static>(&self) -> bool

Check if an extension of the given type exists

Source

pub fn remove_extension<T: Send + Sync + 'static>(&self) -> Option<Arc<T>>

Remove an extension by type

Returns the removed extension if it existed.

Source

pub fn clear_extensions(&self)

Clear all extensions

Source

pub fn extension_count(&self) -> usize

Get the number of extensions

Trait Implementations§

Source§

impl Clone for ApplicationContext

Source§

fn clone(&self) -> ApplicationContext

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ApplicationContext

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for ApplicationContext

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> ErasedDestructor for T
where T: 'static,