sb_functions_sdk

Crates.iosb_functions_sdk
lib.rssb_functions_sdk
version0.1.8
sourcesrc
created_at2023-06-08 17:46:25.147582
updated_at2023-09-01 17:07:59.126703
descriptionThis crate is the utility sdk for writing Switchboard verifiable functions
homepage
repositoryhttps://github.com/switchboard-xyz/sb_functions_sdk/tree/main
max_upload_size
id885641
size27,530
(mgild)

documentation

README

Switchboard Functions SDK

crates.io

This SDK is the master utility SDK for writing verifiable functions off chain.

Switchboard functions provide TEEs as a blockchain primitive.

Using Switchboard functions, you can validate that any code being signed by Switchboard was run inside SGX using Switchboard's oracle network.

Fire and Forget

Switchboard allows you to run any code on a cron or on-demand schedule.

Solana Function Example

const DEMO_PID: Pubkey = pubkey!("8kjszBCEgkzAsU6QySHSZvr9yFaboau2RnarCQFFvasS");

#[derive(Clone, AnchorSerialize, AnchorDeserialize, Debug, Default)]
pub struct PingParams {
    pub prices: Vec<BorshDecimal>,
    pub volumes: Vec<BorshDecimal>,
    pub twaps: Vec<BorshDecimal>,
}
impl Discriminator for PingParams {
    const DISCRIMINATOR: [u8; 8] = [0; 8];
    fn discriminator() -> [u8; 8] {
        ix_discriminator("ping")
    }
}
impl InstructionData for PingParams {}

#[allow(non_snake_case)]
#[derive(Deserialize, Clone, Debug)]
struct Ticker {
    symbol: String,
    weightedAvgPrice: String,
    lastPrice: String,
    volume: String,
}

#[tokio::main(worker_threads = 12)]
async fn main() {
    let symbols = ["BTCUSDC", "ETHUSDC", "SOLUSDT"];

    let symbols = symbols.map(|x| format!("\"{}\"", x)).join(",");
    let tickers = reqwest::get(format!(
        "https://api.binance.com/api/v3/ticker?symbols=[{}]&windowSize=1h",
        symbols
    ))
    .await
    .unwrap()
    .json::<Vec<Ticker>>()
    .await
    .unwrap();
    println!("{:#?}", tickers);

    let enclave_signer = generate_signer();
    let (fn_key, fn_quote) = fn_accounts();
    let ix = Instruction {
        program_id: DEMO_PID,
        accounts: vec![
            AccountMeta::new_readonly(fn_key, false),
            AccountMeta::new_readonly(fn_quote, false),
            AccountMeta::new_readonly(enclave_signer.pubkey(), true),
        ],
        data: PingParams {
            prices: tickers
                .iter()
                .map(|x| BorshDecimal::from(&x.lastPrice))
                .collect(),
            volumes: tickers
                .iter()
                .map(|x| BorshDecimal::from(&x.volume))
                .collect(),
            twaps: tickers
                .iter()
                .map(|x| BorshDecimal::from(&x.weightedAvgPrice))
                .collect(),
        }
        .data(),
    };
    FunctionResult::generate_verifiable_solana_tx(enclave_signer, vec![ix])
        .await
        .unwrap()
        .emit();
}

Solana On-chain verification

For Receiving the result and verifying the SGX quote passed, please use this crate on chain: https://crates.io/crates/solana_attestation_sdk

To see example output of such a function: See https://explorer.solana.com/tx/FnJ13SxdKmMadsnUg884msNnM76QuJkV8gxj9CEikBYbcJzgS3x1KLBiZzrav3tntJezhfYyn2KqrA7AoLRpf9k?cluster=devnet

Example Function

To see an example function container, refer to: https://github.com/switchboard-xyz/sbv3-function-example

Adding your function to a cron schedule

For running your function at a regular cadence, use our typescript sdk to attach it to an attestation queue:

import {
  SwitchboardProgram,
  FunctionAccount,
  AttestationQueueAccount,
} from "@switchboard-xyz/solana.js";

// ...
const functionKeypair = anchor.web3.Keypair.generate();
const [functionAccount] = await FunctionAccount.create(switchboard, {
  name: "FUNCTION_NAME",
  metadata: "FUNCTION_METADATA",
  schedule: "30 * * * * *", // every 30 seconds
  container: "switchboardlabs/function-example",
  version: "v1",
  mrEnclave: new Uint8Array(0), // Leave blank to auto-populate after first run
  attestationQueue: new AttestationQueueAccount(
    switchboard,
    <QUEUE_PUBKEY>
  ),
  keypair: functionKeypair,
});
console.log(`Function: ${functionAccount.publicKey.toString()}`);
Commit count: 0

cargo fmt