chore(twap_oracle): scaffold twap_oracle program

Closes #114
This commit is contained in:
Ricardo Guilherme Schmidt 2026-05-14 00:20:14 -03:00 committed by r4bbit
parent 9efef64b54
commit 291149b114
18 changed files with 4300 additions and 5 deletions

32
Cargo.lock generated
View File

@ -3045,6 +3045,7 @@ dependencies = [
"risc0-zkvm",
"serde",
"spel-framework-macros",
"twap_oracle_core",
]
[[package]]
@ -3468,6 +3469,33 @@ version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
[[package]]
name = "twap-oracle-methods"
version = "0.1.0"
dependencies = [
"risc0-build",
"risc0-zkvm",
"twap_oracle_core",
]
[[package]]
name = "twap_oracle_core"
version = "0.1.0"
dependencies = [
"borsh",
"nssa_core",
"serde",
"spel-framework-macros",
]
[[package]]
name = "twap_oracle_program"
version = "0.1.0"
dependencies = [
"nssa_core",
"twap_oracle_core",
]
[[package]]
name = "typenum"
version = "1.20.0"
@ -4081,9 +4109,9 @@ dependencies = [
[[package]]
name = "zerofrom"
version = "0.1.7"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df"
checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272"
dependencies = [
"zerofrom-derive",
]

View File

@ -9,6 +9,9 @@ members = [
"ata/core",
"ata",
"ata/methods",
"twap_oracle/core",
"twap_oracle",
"twap_oracle/methods",
"stablecoin/core",
"stablecoin",
"stablecoin/methods",
@ -20,6 +23,7 @@ exclude = [
"amm/methods/guest",
"ata/methods/guest",
"stablecoin/methods/guest",
"twap_oracle/methods/guest"
]
resolver = "2"
@ -32,10 +36,12 @@ amm_core = { path = "amm/core" }
amm_program = { path = "amm" }
ata_core = { path = "ata/core" }
ata_program = { path = "ata" }
twap_oracle_core = { path = "twap_oracle/core" }
twap_oracle_program = { path = "twap_oracle" }
stablecoin_core = { path = "stablecoin/core" }
stablecoin_program = { path = "stablecoin" }
serde = { version = "1.0", features = ["derive"] }
borsh = { version = "1.0", features = ["derive"] }
borsh = { version = "1.5", features = ["derive"] }
risc0-zkvm = { version = "=3.0.5" }
serde_json = "1.0"
tokio = { version = "1.28.2", features = ["net", "rt-multi-thread", "sync", "macros"] }

View File

@ -189,6 +189,38 @@
}
]
}
},
{
"name": "OraclePriceAccount",
"type": {
"kind": "struct",
"fields": [
{
"name": "base_asset",
"type": "account_id"
},
{
"name": "quote_asset",
"type": "account_id"
},
{
"name": "price",
"type": "u128"
},
{
"name": "timestamp",
"type": "u64"
},
{
"name": "source_id",
"type": "string"
},
{
"name": "confidence_interval",
"type": "u128"
}
]
}
}
],
"types": [

View File

@ -0,0 +1,46 @@
{
"version": "0.1.0",
"name": "twap_oracle",
"instructions": [
{
"name": "noop",
"accounts": [],
"args": []
}
],
"accounts": [
{
"name": "OraclePriceAccount",
"type": {
"kind": "struct",
"fields": [
{
"name": "base_asset",
"type": "account_id"
},
{
"name": "quote_asset",
"type": "account_id"
},
{
"name": "price",
"type": "u128"
},
{
"name": "timestamp",
"type": "u64"
},
{
"name": "source_id",
"type": "string"
},
{
"name": "confidence_interval",
"type": "u128"
}
]
}
}
],
"instruction_type": "twap_oracle_core::Instruction"
}

View File

@ -7,5 +7,6 @@ edition = "2021"
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3", features = ["host"] }
borsh = { version = "1.5", features = ["derive"] }
serde = { version = "1.0", features = ["derive"] }
twap_oracle_core = { path = "../../twap_oracle/core" }
risc0-zkvm = { version = "=3.0.5", default-features = false }
spel-framework-macros = { git = "https://github.com/logos-co/spel.git", tag = "v0.3.0", package = "spel-framework-macros" }

View File

@ -2938,6 +2938,7 @@ dependencies = [
"stablecoin_core",
"stablecoin_program",
"token_core",
"twap_oracle_core",
]
[[package]]
@ -2949,6 +2950,7 @@ dependencies = [
"risc0-zkvm",
"serde",
"spel-framework-macros",
"twap_oracle_core",
]
[[package]]
@ -3355,6 +3357,16 @@ version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
[[package]]
name = "twap_oracle_core"
version = "0.1.0"
dependencies = [
"borsh",
"nssa_core",
"serde",
"spel-framework-macros",
]
[[package]]
name = "typenum"
version = "1.20.0"
@ -3968,9 +3980,9 @@ dependencies = [
[[package]]
name = "zerofrom"
version = "0.1.7"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df"
checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272"
dependencies = [
"zerofrom-derive",
]

View File

@ -13,6 +13,7 @@ path = "src/bin/stablecoin.rs"
spel-framework = { git = "https://github.com/logos-co/spel.git", tag = "v0.3.0", package = "spel-framework" }
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3" }
risc0-zkvm = { version = "=3.0.5", default-features = false }
twap_oracle_core = { path = "../../../twap_oracle/core" }
stablecoin_core = { path = "../../core" }
stablecoin_program = { path = "../..", package = "stablecoin_program" }
token_core = { path = "../../../token/core" }

8
twap_oracle/Cargo.toml Normal file
View File

@ -0,0 +1,8 @@
[package]
name = "twap_oracle_program"
version = "0.1.0"
edition = "2021"
[dependencies]
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3", features = ["host"] }
twap_oracle_core = { path = "core" }

View File

@ -0,0 +1,10 @@
[package]
name = "twap_oracle_core"
version = "0.1.0"
edition = "2021"
[dependencies]
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3", features = ["host"] }
borsh = { version = "1.5", features = ["derive"] }
serde = { version = "1.0", features = ["derive"] }
spel-framework-macros = { git = "https://github.com/logos-co/spel.git", tag = "v0.3.0", package = "spel-framework-macros" }

View File

@ -0,0 +1,53 @@
use borsh::{BorshDeserialize, BorshSerialize};
use nssa_core::account::{AccountId, Data};
use serde::{Deserialize, Serialize};
use spel_framework_macros::account_type;
/// TWAP Oracle Program Instruction.
#[derive(Debug, Serialize, Deserialize)]
pub enum Instruction {
/// No-op instruction. Does nothing and returns no state changes.
Noop,
}
/// Canonical oracle price account consumed by LEZ programs.
///
/// Oracle producers own how this account is written; consumers only read and validate it.
#[account_type]
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
pub struct OraclePriceAccount {
/// Canonical identifier for the priced asset.
pub base_asset: AccountId,
/// Canonical identifier for the quote asset that denominates `price`.
pub quote_asset: AccountId,
/// Amount of `quote_asset` one unit of `base_asset` is worth.
///
/// `u128` keeps the consumer-side interface non-negative; zero is rejected on read.
pub price: u128,
/// Price observation timestamp. Consumers choose the time unit by matching this with
/// `max_age`.
pub timestamp: u64,
/// Identifier of the source that populated this account, such as a TWAP or external adaptor.
pub source_id: String,
/// Source-provided confidence interval, or zero when the source does not provide one.
pub confidence_interval: u128,
}
impl TryFrom<&Data> for OraclePriceAccount {
type Error = std::io::Error;
fn try_from(data: &Data) -> Result<Self, Self::Error> {
Self::try_from_slice(data.as_ref())
}
}
impl From<&OraclePriceAccount> for Data {
fn from(price_account: &OraclePriceAccount) -> Self {
let serialized_len =
borsh::object_length(price_account).expect("Oracle price account length must be known");
let mut data = Vec::with_capacity(serialized_len);
BorshSerialize::serialize(price_account, &mut data)
.expect("Serialization to Vec should not fail");
Self::try_from(data).expect("Oracle price account encoded data should fit into Data")
}
}

View File

@ -0,0 +1,14 @@
[package]
name = "twap-oracle-methods"
version = "0.1.0"
edition = "2021"
[build-dependencies]
risc0-build = "=3.0.5"
[dependencies]
risc0-zkvm = { version = "=3.0.5", features = ["std"] }
twap_oracle_core = { path = "../core" }
[package.metadata.risc0]
methods = ["guest"]

View File

@ -0,0 +1,3 @@
fn main() {
risc0_build::embed_methods();
}

4034
twap_oracle/methods/guest/Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,19 @@
[package]
name = "twap-oracle-guest"
version = "0.1.0"
edition = "2021"
[workspace]
[[bin]]
name = "twap_oracle"
path = "src/bin/twap_oracle.rs"
[dependencies]
spel-framework = { git = "https://github.com/logos-co/spel.git", tag = "v0.3.0", package = "spel-framework" }
nssa_core = { git = "https://github.com/logos-blockchain/logos-execution-zone.git", tag = "v0.2.0-rc3" }
risc0-zkvm = { version = "=3.0.5", default-features = false }
twap_oracle_core = { path = "../../core" }
twap_oracle_program = { path = "../..", package = "twap_oracle_program" }
serde = { version = "1.0", features = ["derive"] }
borsh = "1.5"

View File

@ -0,0 +1,17 @@
#![no_main]
use spel_framework::prelude::*;
risc0_zkvm::guest::entry!(main);
#[lez_program(instruction = "twap_oracle_core::Instruction")]
mod twap_oracle {
#[allow(unused_imports)]
use super::*;
/// No-op instruction. Does nothing and returns no state changes.
#[instruction]
pub fn noop() -> SpelResult {
Ok(spel_framework::SpelOutput::execute(twap_oracle_program::noop::noop(), vec![]))
}
}

View File

@ -0,0 +1 @@
include!(concat!(env!("OUT_DIR"), "/methods.rs"));

5
twap_oracle/src/lib.rs Normal file
View File

@ -0,0 +1,5 @@
//! The TWAP Oracle Program implementation.
pub use twap_oracle_core as core;
pub mod noop;

5
twap_oracle/src/noop.rs Normal file
View File

@ -0,0 +1,5 @@
use nssa_core::program::AccountPostState;
pub fn noop() -> Vec<AccountPostState> {
vec![]
}