Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Include kinobi IDL #84

Merged
merged 8 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/build-programs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,5 @@ jobs:
name: program-builds
# First wildcard ensures exported paths are consistently under the programs folder.
path: ./program*/.bin/*.so
include-hidden-files: true
if-no-files-found: error
3 changes: 3 additions & 0 deletions configs/kinobi-asset.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const anchorIdl = require("@kinobi-so/nodes-from-anchor");
const jsRenderer = require("@kinobi-so/renderers-js-umi");
const rustRenderer = require("@kinobi-so/renderers-rust");
const k = require("kinobi");
const { writeFileSync } = require("fs");

// Paths.
const path = require("path");
Expand Down Expand Up @@ -627,3 +628,5 @@ kinobi.accept(
}
)
);

writeFileSync(path.join(idlDir, "asset-program.kinobi.json"), kinobi.getJson());
1 change: 1 addition & 0 deletions idls/asset-program.kinobi.json

Large diffs are not rendered by default.

24 changes: 15 additions & 9 deletions include-idl-cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use std::path::PathBuf;

use goblin::error::Result;
use include_idl::parse_idl_from_program_binary;
// use goblin::error::Result;
use include_idl::parse::{parse_idl_from_program_binary, IdlType};

use clap::{Parser, Subcommand};
use clap::{Error, Parser, Subcommand};

#[derive(Parser)]
#[command(version, about, long_about = None)]
Expand All @@ -17,19 +17,25 @@ enum Commands {
Parse {
/// Read IDL from a solana program binary
path: PathBuf,
idl_type: IdlType,
},
}

pub fn main() -> Result<()> {
// This example uses ArgEnum, so this might not be necessary.

pub fn main() -> Result<(), Error> {
let cli = Cli::parse();

match &cli.command {
Some(Commands::Parse { path }) => {
Some(Commands::Parse { path, idl_type }) => {
let buffer = std::fs::read(path).expect("Could not read file.");
let idl = parse_idl_from_program_binary(&buffer)?;
println!(" Program IDL");
println!("============================");
println!("{}", idl);
if let Ok(idl) = parse_idl_from_program_binary(&buffer, idl_type.clone()) {
println!(" Program IDL");
println!("============================");
println!("{}", idl);
} else {
println!("Could not find {:?} IDL in program binary", idl_type);
}
}
None => {}
}
Expand Down
18 changes: 15 additions & 3 deletions include-idl/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
#[cfg(feature = "parse")]
mod parse;
#[cfg(feature = "parse")]
pub use parse::parse_idl_from_program_binary;
pub mod parse;

#[cfg(feature = "shrink")]
mod shrink;

#[cfg(feature = "shrink")]
pub use shrink::compress_idl;

Expand All @@ -20,3 +19,16 @@ macro_rules! include_idl {
pub static IDL_BYTES: &[u8] = include_bytes!($s);
};
}

#[macro_export]
macro_rules! include_kinobi_idl {
($s:expr) => {
#[cfg_attr(
any(target_arch = "sbf", target_arch = "bpf"),
link_section = ".kinobi.idl"
)]
#[allow(dead_code)]
#[no_mangle]
pub static KINOBI_IDL_BYTES: &[u8] = include_bytes!($s);
};
}
48 changes: 43 additions & 5 deletions include-idl/src/parse.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,55 @@
#[cfg(feature = "parse")]
use {
flate2::bufread::ZlibDecoder, goblin::elf::Elf, goblin::error::Result, serde_json::Value,
std::io::Read,
flate2::bufread::ZlibDecoder, goblin::elf::Elf, serde_json::Value, std::fmt, std::io::Read,
std::str::FromStr,
};

#[cfg(feature = "parse")]
pub fn parse_idl_from_program_binary(buffer: &[u8]) -> Result<Value> {
#[derive(Clone, Debug)]
pub enum IdlType {
Anchor,
Kinobi,
}

impl fmt::Display for IdlType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
IdlType::Anchor => write!(f, "Anchor"),
IdlType::Kinobi => write!(f, "Kinobi"),
}
}
}

impl FromStr for IdlType {
type Err = &'static str;

fn from_str(s: &str) -> Result<Self, &'static str> {
match s.to_lowercase().as_str() {
"anchor" => Ok(IdlType::Anchor),
"kinobi" => Ok(IdlType::Kinobi),
_ => Err("Invalid IDL type"),
}
}
}

fn get_section_name(idl_type: IdlType) -> String {
match idl_type {
IdlType::Anchor => ".solana.idl".to_string(),
IdlType::Kinobi => ".kinobi.idl".to_string(),
}
}

pub fn parse_idl_from_program_binary(
buffer: &[u8],
idl_type: IdlType,
) -> goblin::error::Result<Value> {
let elf = Elf::parse(buffer)?;

let section_name = get_section_name(idl_type);

// Iterate over section headers and print information
for sh in &elf.section_headers {
let name = elf.shdr_strtab.get_at(sh.sh_name).unwrap_or("<invalid>");
if name == ".solana.idl" {
if name == section_name {
// Get offset of .solana.idl section data
let offset = sh.sh_offset as usize;

Expand Down
9 changes: 7 additions & 2 deletions programs/asset/program/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,17 @@ fn main() {
.output()
.expect("Failed to run shank");

let _output = Command::new("pnpm")
.arg("generate:clients")
.output()
.expect("Failed to create the kinobi IDLs");

// Get the IDL path
let idl_path = PathBuf::from("../../../idls").join("asset_program.json");
let idl_path = PathBuf::from("../../../idls").join("asset-program.kinobi.json");

// Concat output path of compressed IDL
let out_dir = env::var("OUT_DIR").unwrap();
let dest_path = PathBuf::from(out_dir).join("idl.json.zip");
let dest_path = PathBuf::from(out_dir).join("kinobi.idl.zip");

compress_idl(&idl_path, &dest_path);
}
4 changes: 2 additions & 2 deletions programs/asset/program/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ pub mod utils;
pub use solana_program;

#[cfg(not(feature = "no-entrypoint"))]
use include_idl::include_idl;
use include_idl::include_kinobi_idl;

#[cfg(not(feature = "no-entrypoint"))]
use solana_security_txt::security_txt;

#[cfg(not(feature = "no-entrypoint"))]
include_idl!(concat!(env!("OUT_DIR"), "/idl.json.zip"));
include_kinobi_idl!(concat!(env!("OUT_DIR"), "/kinobi.idl.zip"));

#[cfg(not(feature = "no-entrypoint"))]
security_txt! {
Expand Down