Advanced Usage
Advanced configuration and usage patterns for the Succinct Prover Network.
To use advanced features, you must set up a ProverClient
using ProverClient::builder().network()
instead of ProverClient::from_env()
.
// Default network client (uses `NETWORK_PRIVATE_KEY` env variable)
let client = ProverClient::builder()
.network()
.build();
// Network client with custom parameters
let client = ProverClient::builder()
.network()
.private_key("<PRIVATE_KEY>")
.rpc_url("<RPC_URL>")
.build();
You can see a full list of the builder parameters you can configure in the sp1-sdk docs.rs.
Skip Simulation
Skipping simulation locally can save minutes of latency depending on proof request size.
By default, the SDK will simulate program execution locally before submitting a proof request. This simulation takes anywhere from a few seconds to many minutes, depending on the size of your program. By adding .skip_simulation(true)
, you can skip the simulation step and send the proof optimistically. However, this means that if the program fails to execute, the proof request will fail with an "Unexecutable" error.
Since the network uses PGUs (prover gas units) for fee calculation, each request has a gas_limit
parameter that sets the maximum PGUs allowed for proof generation. This value is normally set during simulation. If you skip simulation, you should manually set a gas_limit
high enough to cover typical gas usage of your program.
let proof = client.prove(&pk, stdin)
.compressed()
.skip_simulation(true) // Skip simulation
.gas_limit(10_000_000_000) // 10B PGUs
.run()
.unwrap();
Async Operations
For non-blocking proof requests, use async methods to submit and track proofs separately:
use sp1_sdk::network::ProofRequestStatus;
// Submit proof request
let request_id = client.prove(&pk, &stdin)
.compressed()
.request_async()
.await?;
// Get proof status
let (status, maybe_proof) = client.get_proof_status(request_id).await?;
// Get request info
let maybe_request = client.get_proof_request(request_id).await?;
// Wait for completion
let proof = client.wait_proof(request_id, Some(Duration::from_secs(3600)), None)
.await?;
Timeout Configuration
If you set the timeout too low, it may be impossible for provers to fulfill.
Set custom timeouts for proof requests. If a proof request is not fulfilled within the timeout, it will be aborted and fees will not be refunded.
use std::time::Duration;
let proof = client.prove(&pk, &stdin)
.timeout(Duration::from_secs(3600)) // 1 hour timeout
.run()
.await?;
Auction Configuration
If you set the max price too low, it may not receive any bids from provers. We suggest using the default setting.
Make sure the network
feature is enabled on sp1-sdk
in script/Cargo.toml
:
[dependencies]
sp1-sdk = { version = "...", default-features = false, features = ["network"] }
The SDK will use the Auction
strategy with default parameters, but you can configure custom parameters as follows:
use std::time::Duration;
use sp1_sdk::network::FulfillmentStrategy;
let proof = client.prove(&pk, &stdin)
.compressed()
.strategy(FulfillmentStrategy::Auction)
.auction_timeout(Duration::from_secs(60))
.max_price_per_pgu(1_000_000_000_000u64) // 1 PROVE per 1M PGUs
.run()
.await?;
You can see a full list of parameters you can configure in the sp1-sdk docs.rs.
AWS KMS
As of sp1-sdk >= v5.1.1
, you can pass a signer
instead using of the NETWORK_PRIVATE_KEY
environment variable or the private_key
argument. This lets you use AWS KMS without storing your private key in plaintext.
Make sure the Key ARN is in this format: arn:aws:kms:REGION:ACCOUNT:key/KEY_ID
.
// Network client with AWS KMS signer
let signer = NetworkSigner::aws_kms("<KMS_KEY_ARN>").await.unwrap();
let client = ProverClient::builder()
.network()
.signer(signer)
.build();
AWS Credentials
To use the AWS KMS signer, you need AWS credentials configured on your host machine via one of:
- Environment variables (
AWS_ACCESS_KEY_ID
,AWS_SECRET_ACCESS_KEY
) - IAM role with appropriate permissions attached to your instance or container
- AWS credentials file
The credentials must have the kms:Sign
and kms:GetPublicKey
permissions.
Create a KMS key
You can create a KMS key in the AWS Console or via the AWS CLI. Make sure to select:
- Type: Asymmetric
- Usage: Sign and Verify
- Spec:
ECC_SECG_P256K1
- Signing algorithm:
ECDSA_SHA_256
For more details, see the AWS KMS Developer Guide.
Get the Address
To get the address that corresponds to the KMS key, you can either print it when setting up the NetworkSigner
or use a script.
let signer = NetworkSigner::aws_kms("<KMS_KEY_ARN>").await.unwrap();
println!("address: {:?}", signer.address());
Or use a simple Python script:
import boto3
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.backends import default_backend
from eth_utils import keccak, to_checksum_address
# 1. Fetch the DER‐encoded public key from KMS
kms = boto3.client("kms")
resp = kms.get_public_key(
KeyId="<KMS_KEY_ARN>"
)
pub_der = resp["PublicKey"]
# 2. Load it and extract (x, y)
pub = serialization.load_der_public_key(pub_der, backend=default_backend())
nums = pub.public_numbers()
raw = nums.x.to_bytes(32, "big") + nums.y.to_bytes(32, "big")
# 3. Keccak hash, take last 20 bytes, checksum it
addr = to_checksum_address(keccak(raw)[-20:])
print(addr)
Make sure that the machine running the script has AWS credentials with kms:GetPublicKey
permissions.