Oracle VRF is available on the following Solana networks:
To use Oracle VRF, your program needs SOL to pay for VRF requests. You can fund your program in two ways:
// Initialize a program treasury PDA
pub fn initialize_treasury(ctx: Context) -> Result<()> {
// Treasury PDA is created and can receive SOL
Ok(())
}
To request random values, implement the following in your Solana program:
#[program]
pub mod my_program {
use oracle_vrf::{self, RequestRandomness};
pub fn request_random(ctx: Context) -> Result<()> {
let request = RequestRandomness {
seed: *ctx.accounts.seed.key,
callback: *ctx.accounts.callback.key,
payer: *ctx.accounts.payer.key,
};
ctx.accounts.vrf_program.request_random(request)?;
Ok(())
}
}
Mainnet (beta):
Devnet:
Testnet:
Here's a complete example of a coin flip program using Oracle VRF:
use anchor_lang::prelude::*;
use oracle_vrf::{self, VrfCallback};
#[program]
pub mod coin_flip {
use super::*;
pub fn initialize(ctx: Context) -> Result<()> {
Ok(())
}
pub fn flip(ctx: Context) -> Result<()> {
// Request random value
let request = RequestRandomness {
seed: *ctx.accounts.player.key,
callback: *ctx.accounts.callback.key,
payer: *ctx.accounts.payer.key,
};
ctx.accounts.vrf_program.request_random(request)?;
Ok(())
}
// Callback handler
pub fn handle_vrf(ctx: Context, value: [u8; 32]) -> Result<()> {
// Convert bytes to number 0-99
let random = value[0] as u8 % 100;
// Player wins on heads (value < 50)
if random < 50 {
emit!(Winner {
player: *ctx.accounts.player.key
});
}
Ok(())
}
}
Each random value comes with a VRF proof that can be verified on-chain:
pub fn verify_proof(
ctx: Context,
value: [u8; 32],
proof: VrfProof
) -> Result {
require!(
verify_vrf_proof(&proof, &value),
VrfError::InvalidProof
);
Ok(true)
}
Oracle VRF provides real-time results through WebSocket subscriptions to the Solana network. You can listen for VRF events and update your UI before the callback is processed:
// Subscribe to VRF events
const subscribeToVrfEvents = (connection: Connection, callback: Function) => {
connection.onLogs(
vrf_program_id,
(logs) => {
if (logs.logs.includes("VRF Request")) {
callback(logs);
}
},
"confirmed"
);
};