pub async fn spawn_with_context<F, T>(
future: F,
) -> JoinHandle<Result<T, SignerError>>Expand description
Spawns a new task while preserving SignerContext if available.
§Why This Is Necessary
The SignerContext is stored in tokio::task_local! storage, which means it is
NOT automatically propagated to new tasks spawned with tokio::spawn. This is
a fundamental limitation of task-local storage - it’s only accessible within the
same task where it was set.
Without this function, the following would fail:
ⓘ
// WRONG - This will fail with "No signer context"
SignerContext::with_signer(signer, async {
let handle = tokio::spawn(async {
// This will fail - SignerContext is not available here!
let current = SignerContext::current().await?; // ERROR
transfer_sol("recipient", 1.0).await
});
handle.await?
}).awaitThe correct approach using spawn_with_context:
ⓘ
// CORRECT - This properly propagates the SignerContext
SignerContext::with_signer(signer, async {
let handle = spawn_with_context(async {
// SignerContext is available here!
transfer_sol("recipient", 1.0).await
}).await;
handle.await?
}).await§How It Works
This function:
- Checks if a SignerContext exists in the current task
- If yes, captures it and wraps the spawned future with
SignerContext::with_signer - If no, spawns the task normally without context
This ensures that tools requiring signing operations work correctly when executed through agent frameworks that use task spawning for parallelism.
Note: This function is async because it needs to check for the current signer. The future passed in should return a Result<T, SignerError>.