diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 8c388a8..bf1646a 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -4,7 +4,7 @@ on: pull_request: env: - solana_version: v1.18.0 + solana_version: v1.18.1 anchor_version: 0.29.0 jobs: @@ -30,6 +30,7 @@ jobs: run: | sudo apt-get update sudo apt-get install -y pkg-config build-essential libudev-dev + npm install --global yarn - name: Cache node dependencies uses: actions/cache@v3 @@ -146,10 +147,21 @@ jobs: echo ${{ secrets.SYSTEM_FLY }} > target/deploy/system_fly-keypair.json echo ${{ secrets.SYSTEM_SIMPLE_MOVEMENT }} > target/deploy/system_simple_movement-keypair.json + - name: run build + run: | + export PATH="/home/runner/.local/share/solana/install/active_release/bin:$PATH" + npm i -g @coral-xyz/anchor-cli@${{ env.anchor_version }} ts-mocha typescript + solana-test-validator > /dev/null & + sleep 5 + solana airdrop -u l 100 tEsT3eV6RFCWs1BZ7AXTzasHqTtMnMLCB2tjQ42TDXD + anchor build + anchor idl build + anchor deploy + pkill -9 -f solana-test-validator + - name: run tests run: | export PATH="/home/runner/.local/share/solana/install/active_release/bin:$PATH" - ls node_modules/.bin npm i -g @coral-xyz/anchor-cli@${{ env.anchor_version }} ts-mocha typescript anchor test @@ -158,7 +170,12 @@ jobs: export PATH="/home/runner/.local/share/solana/install/active_release/bin:$PATH" cargo install --path cli --force --locked bolt init test-project --force - cd test-project && bolt build + cd test-project + cargo add --package position --path "../crates/bolt-lang" # Overrides the version with the local version + cargo add --package movement --path "../crates/bolt-lang" # - + yarn add file:../clients/bolt-sdk/ -D # Overrides the bolt ts SDK with the local version + bolt build + bolt test - uses: actions/upload-artifact@v3 if: always() diff --git a/Anchor.toml b/Anchor.toml index 36f7b93..652bad3 100644 --- a/Anchor.toml +++ b/Anchor.toml @@ -1,16 +1,16 @@ [toolchain] [features] -seeds = false +seeds = true skip-lint = false [programs.localnet] bolt-component = "CmP2djJgABZ4cRokm4ndxuq6LerqpNHLBsaUv2XKEJua" bolt-system = "7X4EFsDJ5aYTcEjKzJ94rD8FRKgQeXC89fkpeTS4KaqP" -component-position = "Fn1JzzEdyb55fsyduWS94mYHizGhJZuhvjX6DVvrmGbQ" -component-velocity = "CbHEFbSQdRN4Wnoby9r16umnJ1zWbULBHg4yqzGQonU1" +position = "Fn1JzzEdyb55fsyduWS94mYHizGhJZuhvjX6DVvrmGbQ" +velocity = "CbHEFbSQdRN4Wnoby9r16umnJ1zWbULBHg4yqzGQonU1" system-apply-velocity = "6LHhFVwif6N9Po3jHtSmMVtPjF6zRfL3xMosSzcrQAS8" -system-fly = "BAQXfRwpNE43pdkeajsffA4rEkFQxwmUEDZKJjQHuvAN" +system-fly = "HT2YawJjkNmqWcLNfPAMvNsLdWwPvvvbKA5bpMw4eUpq" system-simple-movement = "FSa6qoJXFBR3a7ThQkTAMrC15p6NkchPEjBdd4n6dXxA" world = "WorLD15A7CrDwLcLy4fRqtaTb9fbd8o8iqiEMUDse2n" diff --git a/Cargo.lock b/Cargo.lock index 8380693..b09f349 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -382,6 +382,7 @@ dependencies = [ "anchor-derive-accounts 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)", "anchor-derive-serde 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)", "anchor-derive-space 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)", + "anchor-syn 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)", "arrayref", "base64 0.13.1", "bincode", @@ -908,25 +909,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" [[package]] -name = "bolt-attribute-bolt-account" +name = "bolt-attribute-bolt-component" version = "0.0.1" dependencies = [ + "bolt-utils", "proc-macro2", "quote", "syn 1.0.109", ] [[package]] -name = "bolt-attribute-bolt-component" +name = "bolt-attribute-bolt-component-deserialize" version = "0.0.1" dependencies = [ + "bolt-utils", "proc-macro2", "quote", "syn 1.0.109", ] [[package]] -name = "bolt-attribute-bolt-component-deserialize" +name = "bolt-attribute-bolt-component-id" +version = "0.0.1" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "bolt-attribute-bolt-program" version = "0.0.1" dependencies = [ "proc-macro2", @@ -943,6 +955,15 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "bolt-attribute-bolt-system-input" +version = "0.0.1" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "bolt-cli" version = "0.0.1" @@ -965,7 +986,25 @@ dependencies = [ [[package]] name = "bolt-helpers" -version = "0.1.0" +version = "0.0.1" + +[[package]] +name = "bolt-helpers-system-template" +version = "0.0.1" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "bolt-helpers-world-apply" +version = "0.0.1" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] [[package]] name = "bolt-lang" @@ -973,10 +1012,12 @@ version = "0.0.1" dependencies = [ "ahash 0.8.6", "anchor-lang 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bolt-attribute-bolt-account", "bolt-attribute-bolt-component", "bolt-attribute-bolt-component-deserialize", + "bolt-attribute-bolt-component-id", + "bolt-attribute-bolt-program", "bolt-attribute-bolt-system", + "bolt-attribute-bolt-system-input", "bolt-system", "serde", "serde_json", @@ -988,6 +1029,16 @@ name = "bolt-system" version = "0.0.1" dependencies = [ "anchor-lang 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bolt-helpers-system-template", +] + +[[package]] +name = "bolt-utils" +version = "0.0.1" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] @@ -1323,22 +1374,6 @@ dependencies = [ "unreachable", ] -[[package]] -name = "component-position" -version = "0.1.0" -dependencies = [ - "anchor-lang 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bolt-lang", -] - -[[package]] -name = "component-velocity" -version = "0.1.0" -dependencies = [ - "anchor-lang 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bolt-lang", -] - [[package]] name = "concurrent-queue" version = "2.4.0" @@ -3106,6 +3141,14 @@ dependencies = [ "rand 0.8.5", ] +[[package]] +name = "position" +version = "0.0.1" +dependencies = [ + "anchor-lang 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bolt-lang", +] + [[package]] name = "powerfmt" version = "0.2.0" @@ -4981,12 +5024,12 @@ dependencies = [ [[package]] name = "system-apply-velocity" -version = "0.1.0" +version = "0.0.1" dependencies = [ "anchor-lang 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)", "bolt-lang", - "component-position", - "component-velocity", + "position", + "velocity", ] [[package]] @@ -5012,16 +5055,16 @@ dependencies = [ [[package]] name = "system-fly" -version = "0.1.0" +version = "0.0.1" dependencies = [ "anchor-lang 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)", "bolt-lang", - "component-position", + "position", ] [[package]] name = "system-simple-movement" -version = "0.1.0" +version = "0.0.1" dependencies = [ "anchor-lang 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)", "bolt-lang", @@ -5378,6 +5421,12 @@ dependencies = [ "webpki-roots 0.24.0", ] +[[package]] +name = "tuple-conv" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd6314683350324c1bb3d71a65fbeacb4e870cb4faf30b28d8a7787fb8116dd" + [[package]] name = "typenum" version = "1.17.0" @@ -5508,6 +5557,14 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" +[[package]] +name = "velocity" +version = "0.0.1" +dependencies = [ + "anchor-lang 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bolt-lang", +] + [[package]] name = "version_check" version = "0.9.4" @@ -5905,8 +5962,10 @@ version = "0.0.1" dependencies = [ "anchor-lang 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)", "bolt-component", + "bolt-helpers-world-apply", "bolt-system", "solana-security-txt", + "tuple-conv", ] [[package]] diff --git a/cli/src/lib.rs b/cli/src/lib.rs index 8c3c4fc..364a1a1 100644 --- a/cli/src/lib.rs +++ b/cli/src/lib.rs @@ -2,7 +2,8 @@ mod rust_template; use crate::rust_template::{create_component, create_system}; use anchor_cli::config::{ - Config, ConfigOverride, ProgramDeployment, TestValidator, Validator, WithPath, + BootstrapMode, Config, ConfigOverride, GenesisEntry, ProgramArch, ProgramDeployment, + TestValidator, Validator, WithPath, }; use anchor_client::Cluster; use anyhow::{anyhow, Result}; @@ -16,6 +17,8 @@ use std::process::Stdio; pub const VERSION: &str = env!("CARGO_PKG_VERSION"); pub const ANCHOR_VERSION: &str = anchor_cli::VERSION; +pub const WORLD_PROGRAM: &str = "WorLD15A7CrDwLcLy4fRqtaTb9fbd8o8iqiEMUDse2n"; + #[derive(Debug, Subcommand)] pub enum BoltCommand { #[clap(about = "Create a new component")] @@ -54,8 +57,8 @@ pub struct Opts { pub fn entry(opts: Opts) -> Result<()> { match opts.command { - BoltCommand::Anchor(command) => { - if let anchor_cli::Command::Init { + BoltCommand::Anchor(command) => match command { + anchor_cli::Command::Init { name, javascript, solidity, @@ -63,27 +66,54 @@ pub fn entry(opts: Opts) -> Result<()> { jest, template, force, - } = command - { - init( - &opts.cfg_override, - name, - javascript, - solidity, - no_git, - jest, - template, - force, - ) - } else { - // Delegate to the existing anchor_cli handler + } => init( + &opts.cfg_override, + name, + javascript, + solidity, + no_git, + jest, + template, + force, + ), + anchor_cli::Command::Build { + idl, + idl_ts, + verifiable, + program_name, + solana_version, + docker_image, + bootstrap, + cargo_args, + env, + skip_lint, + no_docs, + arch, + } => build( + &opts.cfg_override, + idl, + idl_ts, + verifiable, + skip_lint, + program_name, + solana_version, + docker_image, + bootstrap, + None, + None, + env, + cargo_args, + no_docs, + arch, + ), + _ => { let opts = anchor_cli::Opts { cfg_override: opts.cfg_override, command, }; anchor_cli::entry(opts) } - } + }, BoltCommand::Component(command) => new_component(&opts.cfg_override, command.name), BoltCommand::System(command) => new_system(&opts.cfg_override, command.name), } @@ -203,18 +233,11 @@ fn init( rpc_port: 8899, bind_address: "0.0.0.0".to_owned(), ledger: ".bolt/test-ledger".to_owned(), - clone: Some(vec![ - // World program - anchor_cli::config::CloneEntry { - address: "WorLD15A7CrDwLcLy4fRqtaTb9fbd8o8iqiEMUDse2n".to_owned(), - }, - // World executable data - anchor_cli::config::CloneEntry { - address: "CrsqUXPpJYpVAAx5qMKU6K8RT1TzT81T8BL6JndWSeo3".to_owned(), - }, - // Registry - anchor_cli::config::CloneEntry { + account: Some(vec![ + // Registry account + anchor_cli::config::AccountEntry { address: "EHLkWwAT9oebVv9ht3mtqrvHhRVMKrt54tF3MfHTey2K".to_owned(), + filename: "tests/fixtures/registry.json".to_owned(), }, ]), ..Default::default() @@ -224,6 +247,11 @@ fn init( startup_wait: 5000, shutdown_wait: 2000, validator: Some(validator), + genesis: Some(vec![GenesisEntry { + address: WORLD_PROGRAM.to_owned(), + program: "tests/fixtures/world.so".to_owned(), + upgradeable: Some(false), + }]), ..Default::default() }; @@ -256,16 +284,54 @@ fn init( if solidity { anchor_cli::solidity_template::create_program(&project_name)?; } else { - create_component(component_name)?; create_system(system_name)?; + create_component(component_name)?; anchor_cli::rust_template::create_program(&project_name, template)?; + + // Add the component as a dependency to the system + std::process::Command::new("cargo") + .arg("add") + .arg("--package") + .arg(system_name) + .arg("--path") + .arg(format!("programs-ecs/components/{}", component_name)) + .arg("--features") + .arg("cpi") + .stdout(Stdio::inherit()) + .stderr(Stdio::inherit()) + .spawn() + .map_err(|e| { + anyhow::format_err!( + "error adding component as dependency to the system: {}", + e.to_string() + ) + })?; } // Build the test suite. - fs::create_dir_all("tests")?; + fs::create_dir_all("tests/fixtures")?; // Build the migrations directory. fs::create_dir_all("migrations")?; + // Create the registry account + fs::write( + "tests/fixtures/registry.json", + rust_template::registry_account(), + )?; + + // Dump the World program into tests/fixtures/world.so + std::process::Command::new("solana") + .arg("program") + .arg("dump") + .arg("-u") + .arg("d") + .arg(WORLD_PROGRAM) + .arg("tests/fixtures/world.so") + .stdout(Stdio::inherit()) + .stderr(Stdio::inherit()) + .spawn() + .map_err(|e| anyhow::format_err!("solana program dump failed: {}", e.to_string()))?; + if javascript { // Build javascript config let mut package_json = File::create("package.json")?; @@ -332,6 +398,43 @@ fn init( Ok(()) } +#[allow(clippy::too_many_arguments)] +pub fn build( + cfg_override: &ConfigOverride, + idl: Option, + idl_ts: Option, + verifiable: bool, + skip_lint: bool, + program_name: Option, + solana_version: Option, + docker_image: Option, + bootstrap: BootstrapMode, + stdout: Option, + stderr: Option, + env_vars: Vec, + cargo_args: Vec, + no_docs: bool, + arch: ProgramArch, +) -> Result<()> { + anchor_cli::build( + cfg_override, + idl, + idl_ts, + verifiable, + skip_lint, + program_name, + solana_version, + docker_image, + bootstrap, + stdout, + stderr, + env_vars, + cargo_args, + no_docs, + arch, + ) +} + // Install node modules fn install_node_modules(cmd: &str) -> Result { let mut command = std::process::Command::new(if cfg!(target_os = "windows") { diff --git a/cli/src/rust_template.rs b/cli/src/rust_template.rs index 4ab80cc..a1ca271 100644 --- a/cli/src/rust_template.rs +++ b/cli/src/rust_template.rs @@ -46,14 +46,7 @@ fn create_component_template_simple(name: &str, program_path: &Path) -> Files { declare_id!("{}"); -#[component({})] -#[program] -pub mod {} {{ - use super::*; -}} - -#[account] -#[bolt_account(component_id = "")] +#[component] pub struct {} {{ pub x: i64, pub y: i64, @@ -64,8 +57,6 @@ pub struct {} {{ "#, anchor_cli::rust_template::get_or_create_program_id(name), name.to_upper_camel_case(), - name.to_snake_case(), - name.to_upper_camel_case(), ), )] } @@ -76,34 +67,25 @@ fn create_system_template_simple(name: &str, program_path: &Path) -> Files { program_path.join("src").join("lib.rs"), format!( r#"use bolt_lang::*; +use position::Position; declare_id!("{}"); #[system] -#[program] pub mod {} {{ - use super::*; - pub fn execute(ctx: Context, args: Vec) -> Result {{ - let mut position = Position::from_account_info(&ctx.accounts.position)?; + pub fn execute(ctx: Context, args_p: Vec) -> Result {{ + let position = &mut ctx.accounts.position; position.x += 1; - Ok(position) + position.y += 1; + Ok(ctx.accounts) }} -}} -// Define the Account to parse from the component -#[derive(Accounts)] -pub struct Component<'info> {{ - /// CHECK: check that the component is the expected account - pub position: AccountInfo<'info>, -}} + #[system_input] + pub struct Components {{ + pub position: Position, + }} -#[component_deserialize] -pub struct Position {{ - pub x: i64, - pub y: i64, - pub z: i64, - pub description: String, }} "#, anchor_cli::rust_template::get_or_create_program_id(name), @@ -422,7 +404,7 @@ fn cargo_toml(name: &str) -> String { format!( r#"[package] name = "{0}" -version = "0.1.0" +version = "0.0.1" description = "Created with Bolt" edition = "2021" @@ -436,6 +418,7 @@ no-idl = [] no-log-ix-name = [] cpi = ["no-entrypoint"] default = [] +idl-build = ["anchor-lang/idl-build"] [dependencies] bolt-lang = "{2}" @@ -478,3 +461,22 @@ build test-ledger "# } + +pub fn registry_account() -> &'static str { + r#" +{ + "pubkey": "EHLkWwAT9oebVv9ht3mtqrvHhRVMKrt54tF3MfHTey2K", + "account": { + "lamports": 1002240, + "data": [ + "L65u9ri2/NoCAAAAAAAAAA==", + "base64" + ], + "owner": "WorLD15A7CrDwLcLy4fRqtaTb9fbd8o8iqiEMUDse2n", + "executable": false, + "rentEpoch": 18446744073709551615, + "space": 16 + } +} +"# +} diff --git a/clients/bolt-sdk/idl/world.json b/clients/bolt-sdk/idl/world.json index 8521f5a..b81a6d1 100644 --- a/clients/bolt-sdk/idl/world.json +++ b/clients/bolt-sdk/idl/world.json @@ -105,6 +105,16 @@ "isMut": false, "isSigner": false }, + { + "name": "authority", + "isMut": false, + "isSigner": false + }, + { + "name": "instructionSysvarAccount", + "isMut": false, + "isSigner": false + }, { "name": "systemProgram", "isMut": false, @@ -130,6 +140,16 @@ "name": "boltComponent", "isMut": true, "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": false + }, + { + "name": "instructionSysvarAccount", + "isMut": false, + "isSigner": false } ], "args": [ @@ -166,6 +186,16 @@ "name": "boltComponent2", "isMut": true, "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": false + }, + { + "name": "instructionSysvarAccount", + "isMut": false, + "isSigner": false } ], "args": [ @@ -212,6 +242,16 @@ "name": "boltComponent3", "isMut": true, "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": false + }, + { + "name": "instructionSysvarAccount", + "isMut": false, + "isSigner": false } ], "args": [ @@ -224,46 +264,53 @@ ], "accounts": [ { - "name": "Registry", + "name": "Entity", "type": { "kind": "struct", "fields": [ { - "name": "worlds", + "name": "id", "type": "u64" } ] } }, { - "name": "World", + "name": "Registry", "type": { "kind": "struct", "fields": [ { - "name": "id", - "type": "u64" - }, - { - "name": "entities", + "name": "worlds", "type": "u64" } ] } }, { - "name": "Entity", + "name": "World", "type": { "kind": "struct", "fields": [ { "name": "id", "type": "u64" + }, + { + "name": "entities", + "type": "u64" } ] } } ], + "errors": [ + { + "code": 6000, + "name": "InvalidAuthority", + "msg": "Invalid authority for instruction" + } + ], "metadata": { "address": "WorLD15A7CrDwLcLy4fRqtaTb9fbd8o8iqiEMUDse2n", "origin": "anchor", diff --git a/clients/bolt-sdk/lib/accounts/Entity.d.ts b/clients/bolt-sdk/lib/accounts/Entity.d.ts index de935e4..2cb66cc 100644 --- a/clients/bolt-sdk/lib/accounts/Entity.d.ts +++ b/clients/bolt-sdk/lib/accounts/Entity.d.ts @@ -20,8 +20,8 @@ export declare class Entity implements EntityArgs { commitmentOrConfig?: web3.Commitment | web3.GetAccountInfoConfig ): Promise; static gpaBuilder(programId?: web3.PublicKey): beetSolana.GpaBuilder<{ - accountDiscriminator: any; id: any; + accountDiscriminator: any; }>; static deserialize(buf: Buffer, offset?: number): [Entity, number]; serialize(): [Buffer, number]; diff --git a/clients/bolt-sdk/lib/accounts/Registry.d.ts b/clients/bolt-sdk/lib/accounts/Registry.d.ts index 0df16b1..23deb8b 100644 --- a/clients/bolt-sdk/lib/accounts/Registry.d.ts +++ b/clients/bolt-sdk/lib/accounts/Registry.d.ts @@ -20,8 +20,8 @@ export declare class Registry implements RegistryArgs { commitmentOrConfig?: web3.Commitment | web3.GetAccountInfoConfig ): Promise; static gpaBuilder(programId?: web3.PublicKey): beetSolana.GpaBuilder<{ - worlds: any; accountDiscriminator: any; + worlds: any; }>; static deserialize(buf: Buffer, offset?: number): [Registry, number]; serialize(): [Buffer, number]; diff --git a/clients/bolt-sdk/lib/accounts/World.d.ts b/clients/bolt-sdk/lib/accounts/World.d.ts index 8ade8bb..8adbfe2 100644 --- a/clients/bolt-sdk/lib/accounts/World.d.ts +++ b/clients/bolt-sdk/lib/accounts/World.d.ts @@ -22,8 +22,8 @@ export declare class World implements WorldArgs { commitmentOrConfig?: web3.Commitment | web3.GetAccountInfoConfig ): Promise; static gpaBuilder(programId?: web3.PublicKey): beetSolana.GpaBuilder<{ - accountDiscriminator: any; id: any; + accountDiscriminator: any; entities: any; }>; static deserialize(buf: Buffer, offset?: number): [World, number]; diff --git a/clients/bolt-sdk/lib/accounts/index.d.ts b/clients/bolt-sdk/lib/accounts/index.d.ts index ec82a45..a5ea994 100644 --- a/clients/bolt-sdk/lib/accounts/index.d.ts +++ b/clients/bolt-sdk/lib/accounts/index.d.ts @@ -1,12 +1,12 @@ +import { Entity } from "./Entity"; import { Registry } from "./Registry"; import { World } from "./World"; -import { Entity } from "./Entity"; export * from "./Entity"; export * from "./Registry"; export * from "./World"; export declare const accountProviders: { + Entity: typeof Entity; Registry: typeof Registry; World: typeof World; - Entity: typeof Entity; }; //# sourceMappingURL=index.d.ts.map diff --git a/clients/bolt-sdk/lib/accounts/index.d.ts.map b/clients/bolt-sdk/lib/accounts/index.d.ts.map index 6443266..29a1dba 100644 --- a/clients/bolt-sdk/lib/accounts/index.d.ts.map +++ b/clients/bolt-sdk/lib/accounts/index.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/generated/accounts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AAExB,eAAO,MAAM,gBAAgB;;;;CAA8B,CAAC"} \ No newline at end of file +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/generated/accounts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AAExB,eAAO,MAAM,gBAAgB;;;;CAA8B,CAAC"} \ No newline at end of file diff --git a/clients/bolt-sdk/lib/accounts/index.js b/clients/bolt-sdk/lib/accounts/index.js index a958c29..992af65 100644 --- a/clients/bolt-sdk/lib/accounts/index.js +++ b/clients/bolt-sdk/lib/accounts/index.js @@ -31,15 +31,15 @@ var __exportStar = }; Object.defineProperty(exports, "__esModule", { value: true }); exports.accountProviders = void 0; +var Entity_1 = require("./Entity"); var Registry_1 = require("./Registry"); var World_1 = require("./World"); -var Entity_1 = require("./Entity"); __exportStar(require("./Entity"), exports); __exportStar(require("./Registry"), exports); __exportStar(require("./World"), exports); exports.accountProviders = { + Entity: Entity_1.Entity, Registry: Registry_1.Registry, World: World_1.World, - Entity: Entity_1.Entity, }; //# sourceMappingURL=index.js.map diff --git a/clients/bolt-sdk/lib/accounts/index.js.map b/clients/bolt-sdk/lib/accounts/index.js.map index 3cf7e74..53acdd8 100644 --- a/clients/bolt-sdk/lib/accounts/index.js.map +++ b/clients/bolt-sdk/lib/accounts/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/generated/accounts/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,uCAAsC;AACtC,iCAAgC;AAChC,mCAAkC;AAElC,2CAAyB;AACzB,6CAA2B;AAC3B,0CAAwB;AAEX,QAAA,gBAAgB,GAAG,EAAE,QAAQ,qBAAA,EAAE,KAAK,eAAA,EAAE,MAAM,iBAAA,EAAE,CAAC"} \ No newline at end of file +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/generated/accounts/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,mCAAkC;AAClC,uCAAsC;AACtC,iCAAgC;AAEhC,2CAAyB;AACzB,6CAA2B;AAC3B,0CAAwB;AAEX,QAAA,gBAAgB,GAAG,EAAE,MAAM,iBAAA,EAAE,QAAQ,qBAAA,EAAE,KAAK,eAAA,EAAE,CAAC"} \ No newline at end of file diff --git a/clients/bolt-sdk/lib/errors/index.d.ts b/clients/bolt-sdk/lib/errors/index.d.ts new file mode 100644 index 0000000..f8c3dba --- /dev/null +++ b/clients/bolt-sdk/lib/errors/index.d.ts @@ -0,0 +1,13 @@ +type ErrorWithCode = Error & { + code: number; +}; +type MaybeErrorWithCode = ErrorWithCode | null | undefined; +export declare class InvalidAuthorityError extends Error { + readonly code: number; + readonly name: string; + constructor(); +} +export declare function errorFromCode(code: number): MaybeErrorWithCode; +export declare function errorFromName(name: string): MaybeErrorWithCode; +export {}; +//# sourceMappingURL=index.d.ts.map diff --git a/clients/bolt-sdk/lib/errors/index.d.ts.map b/clients/bolt-sdk/lib/errors/index.d.ts.map new file mode 100644 index 0000000..970e1f1 --- /dev/null +++ b/clients/bolt-sdk/lib/errors/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/generated/errors/index.ts"],"names":[],"mappings":"AAOA,KAAK,aAAa,GAAG,KAAK,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAC9C,KAAK,kBAAkB,GAAG,aAAa,GAAG,IAAI,GAAG,SAAS,CAAC;AAW3D,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAU;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAsB;;CAO5C;AAaD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,CAG9D;AAOD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,CAG9D"} \ No newline at end of file diff --git a/clients/bolt-sdk/lib/errors/index.js b/clients/bolt-sdk/lib/errors/index.js new file mode 100644 index 0000000..02fb58f --- /dev/null +++ b/clients/bolt-sdk/lib/errors/index.js @@ -0,0 +1,70 @@ +"use strict"; +var __extends = + (this && this.__extends) || + (function () { + var extendStatics = function (d, b) { + extendStatics = + Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && + function (d, b) { + d.__proto__ = b; + }) || + function (d, b) { + for (var p in b) + if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; + }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError( + "Class extends value " + String(b) + " is not a constructor or null" + ); + extendStatics(d, b); + function __() { + this.constructor = d; + } + d.prototype = + b === null + ? Object.create(b) + : ((__.prototype = b.prototype), new __()); + }; + })(); +Object.defineProperty(exports, "__esModule", { value: true }); +exports.errorFromName = + exports.errorFromCode = + exports.InvalidAuthorityError = + void 0; +var createErrorFromCodeLookup = new Map(); +var createErrorFromNameLookup = new Map(); +var InvalidAuthorityError = (function (_super) { + __extends(InvalidAuthorityError, _super); + function InvalidAuthorityError() { + var _this = _super.call(this, "Invalid authority for instruction") || this; + _this.code = 0x1770; + _this.name = "InvalidAuthority"; + if (typeof Error.captureStackTrace === "function") { + Error.captureStackTrace(_this, InvalidAuthorityError); + } + return _this; + } + return InvalidAuthorityError; +})(Error); +exports.InvalidAuthorityError = InvalidAuthorityError; +createErrorFromCodeLookup.set(0x1770, function () { + return new InvalidAuthorityError(); +}); +createErrorFromNameLookup.set("InvalidAuthority", function () { + return new InvalidAuthorityError(); +}); +function errorFromCode(code) { + var createError = createErrorFromCodeLookup.get(code); + return createError != null ? createError() : null; +} +exports.errorFromCode = errorFromCode; +function errorFromName(name) { + var createError = createErrorFromNameLookup.get(name); + return createError != null ? createError() : null; +} +exports.errorFromName = errorFromName; +//# sourceMappingURL=index.js.map diff --git a/clients/bolt-sdk/lib/errors/index.js.map b/clients/bolt-sdk/lib/errors/index.js.map new file mode 100644 index 0000000..3be5dca --- /dev/null +++ b/clients/bolt-sdk/lib/errors/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/generated/errors/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAUA,IAAM,yBAAyB,GAAG,IAAI,GAAG,EAA+B,CAAC;AACzE,IAAM,yBAAyB,GAAG,IAAI,GAAG,EAA+B,CAAC;AAQzE;IAA2C,yCAAK;IAG9C;QAAA,YACE,kBAAM,mCAAmC,CAAC,SAI3C;QAPQ,UAAI,GAAW,MAAM,CAAC;QACtB,UAAI,GAAW,kBAAkB,CAAC;QAGzC,IAAI,OAAO,KAAK,CAAC,iBAAiB,KAAK,UAAU,EAAE;YACjD,KAAK,CAAC,iBAAiB,CAAC,KAAI,EAAE,qBAAqB,CAAC,CAAC;SACtD;;IACH,CAAC;IACH,4BAAC;AAAD,CAAC,AATD,CAA2C,KAAK,GAS/C;AATY,sDAAqB;AAWlC,yBAAyB,CAAC,GAAG,CAAC,MAAM,EAAE,cAAM,OAAA,IAAI,qBAAqB,EAAE,EAA3B,CAA2B,CAAC,CAAC;AACzE,yBAAyB,CAAC,GAAG,CAC3B,kBAAkB,EAClB,cAAM,OAAA,IAAI,qBAAqB,EAAE,EAA3B,CAA2B,CAClC,CAAC;AAOF,SAAgB,aAAa,CAAC,IAAY;IACxC,IAAM,WAAW,GAAG,yBAAyB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACxD,OAAO,WAAW,IAAI,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACpD,CAAC;AAHD,sCAGC;AAOD,SAAgB,aAAa,CAAC,IAAY;IACxC,IAAM,WAAW,GAAG,yBAAyB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACxD,OAAO,WAAW,IAAI,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACpD,CAAC;AAHD,sCAGC"} \ No newline at end of file diff --git a/clients/bolt-sdk/lib/index.d.ts b/clients/bolt-sdk/lib/index.d.ts index 7bb5de3..e50e16a 100644 --- a/clients/bolt-sdk/lib/index.d.ts +++ b/clients/bolt-sdk/lib/index.d.ts @@ -4,6 +4,7 @@ export * from "./accounts"; export * from "./instructions"; export declare const PROGRAM_ADDRESS = "WorLD15A7CrDwLcLy4fRqtaTb9fbd8o8iqiEMUDse2n"; +export declare const SYSVAR_INSTRUCTIONS_PUBKEY: PublicKey; export declare const PROGRAM_ID: PublicKey; export declare function FindWorldRegistryPda(programId?: PublicKey): PublicKey; export declare function FindWorldPda(id: BN, programId?: PublicKey): PublicKey; diff --git a/clients/bolt-sdk/lib/index.d.ts.map b/clients/bolt-sdk/lib/index.d.ts.map index 476a490..2afd17e 100644 --- a/clients/bolt-sdk/lib/index.d.ts.map +++ b/clients/bolt-sdk/lib/index.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/generated/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,EAAE,MAAM,OAAO,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAQ/B,eAAO,MAAM,eAAe,gDAAgD,CAAC;AAQ7E,eAAO,MAAM,UAAU,WAAiC,CAAC;AAEzD,wBAAgB,oBAAoB,CAClC,SAAS,GAAE,SAAqC,aAMjD;AAED,wBAAgB,YAAY,CAC1B,EAAE,EAAE,EAAE,EACN,SAAS,GAAE,SAAqC,aAMjD;AAED,wBAAgB,aAAa,CAC3B,OAAO,EAAE,EAAE,EACX,QAAQ,EAAE,EAAE,EACZ,SAAS,CAAC,EAAE,MAAM,EAClB,SAAS,GAAE,SAAqC,aAUjD;AAED,wBAAgB,gBAAgB,CAC5B,kBAAkB,EAAE,SAAS,EAC7B,MAAM,EAAE,SAAS,EACjB,WAAW,GAAE,MAAW,aAM3B"} \ No newline at end of file +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/generated/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,EAAE,MAAM,OAAO,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAQ/B,eAAO,MAAM,eAAe,gDAAgD,CAAC;AAE7E,eAAO,MAAM,0BAA0B,WAEtC,CAAC;AAQF,eAAO,MAAM,UAAU,WAAiC,CAAC;AAEzD,wBAAgB,oBAAoB,CAClC,SAAS,GAAE,SAAqC,aAMjD;AAED,wBAAgB,YAAY,CAC1B,EAAE,EAAE,EAAE,EACN,SAAS,GAAE,SAAqC,aAMjD;AAED,wBAAgB,aAAa,CAC3B,OAAO,EAAE,EAAE,EACX,QAAQ,EAAE,EAAE,EACZ,SAAS,CAAC,EAAE,MAAM,EAClB,SAAS,GAAE,SAAqC,aAUjD;AAED,wBAAgB,gBAAgB,CAC9B,kBAAkB,EAAE,SAAS,EAC7B,MAAM,EAAE,SAAS,EACjB,WAAW,GAAE,MAAW,aAMzB"} \ No newline at end of file diff --git a/clients/bolt-sdk/lib/index.js b/clients/bolt-sdk/lib/index.js index 5c411a1..474860f 100644 --- a/clients/bolt-sdk/lib/index.js +++ b/clients/bolt-sdk/lib/index.js @@ -35,12 +35,16 @@ exports.FindComponentPda = exports.FindWorldPda = exports.FindWorldRegistryPda = exports.PROGRAM_ID = + exports.SYSVAR_INSTRUCTIONS_PUBKEY = exports.PROGRAM_ADDRESS = void 0; var web3_js_1 = require("@solana/web3.js"); __exportStar(require("./accounts"), exports); __exportStar(require("./instructions"), exports); exports.PROGRAM_ADDRESS = "WorLD15A7CrDwLcLy4fRqtaTb9fbd8o8iqiEMUDse2n"; +exports.SYSVAR_INSTRUCTIONS_PUBKEY = new web3_js_1.PublicKey( + "Sysvar1nstructions1111111111111111111111111" +); exports.PROGRAM_ID = new web3_js_1.PublicKey(exports.PROGRAM_ADDRESS); function FindWorldRegistryPda(programId) { if (programId === void 0) { diff --git a/clients/bolt-sdk/lib/index.js.map b/clients/bolt-sdk/lib/index.js.map index d66c36d..4a18d5c 100644 --- a/clients/bolt-sdk/lib/index.js.map +++ b/clients/bolt-sdk/lib/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/generated/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,2CAA4C;AAE5C,6CAA2B;AAC3B,iDAA+B;AAQlB,QAAA,eAAe,GAAG,6CAA6C,CAAC;AAQhE,QAAA,UAAU,GAAG,IAAI,mBAAS,CAAC,uBAAe,CAAC,CAAC;AAEzD,SAAgB,oBAAoB,CAClC,SAAgD;IAAhD,0BAAA,EAAA,gBAA2B,mBAAS,CAAC,kBAAU,CAAC;IAEhD,OAAO,mBAAS,CAAC,sBAAsB,CACrC,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,EACzB,SAAS,CACV,CAAC,CAAC,CAAC,CAAC;AACP,CAAC;AAPD,oDAOC;AAED,SAAgB,YAAY,CAC1B,EAAM,EACN,SAAgD;IAAhD,0BAAA,EAAA,gBAA2B,mBAAS,CAAC,kBAAU,CAAC;IAEhD,OAAO,mBAAS,CAAC,sBAAsB,CACrC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAC5C,SAAS,CACV,CAAC,CAAC,CAAC,CAAC;AACP,CAAC;AARD,oCAQC;AAED,SAAgB,aAAa,CAC3B,OAAW,EACX,QAAY,EACZ,SAAkB,EAClB,SAAgD;IAAhD,0BAAA,EAAA,gBAA2B,mBAAS,CAAC,kBAAU,CAAC;IAEhD,IAAM,KAAK,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACjE,IAAI,SAAS,IAAI,IAAI,EAAE;QACrB,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3C,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;KACpC;SAAM;QACL,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;KACxC;IACD,OAAO,mBAAS,CAAC,sBAAsB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/D,CAAC;AAdD,sCAcC;AAED,SAAgB,gBAAgB,CAC5B,kBAA6B,EAC7B,MAAiB,EACjB,WAAwB;IAAxB,4BAAA,EAAA,gBAAwB;IAE1B,OAAO,mBAAS,CAAC,sBAAsB,CACrC,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,EAC5C,kBAAkB,CACnB,CAAC,CAAC,CAAC,CAAC;AACP,CAAC;AATD,4CASC"} \ No newline at end of file +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/generated/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,2CAA4C;AAE5C,6CAA2B;AAC3B,iDAA+B;AAQlB,QAAA,eAAe,GAAG,6CAA6C,CAAC;AAEhE,QAAA,0BAA0B,GAAG,IAAI,mBAAS,CACrD,6CAA6C,CAC9C,CAAC;AAQW,QAAA,UAAU,GAAG,IAAI,mBAAS,CAAC,uBAAe,CAAC,CAAC;AAEzD,SAAgB,oBAAoB,CAClC,SAAgD;IAAhD,0BAAA,EAAA,gBAA2B,mBAAS,CAAC,kBAAU,CAAC;IAEhD,OAAO,mBAAS,CAAC,sBAAsB,CACrC,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,EACzB,SAAS,CACV,CAAC,CAAC,CAAC,CAAC;AACP,CAAC;AAPD,oDAOC;AAED,SAAgB,YAAY,CAC1B,EAAM,EACN,SAAgD;IAAhD,0BAAA,EAAA,gBAA2B,mBAAS,CAAC,kBAAU,CAAC;IAEhD,OAAO,mBAAS,CAAC,sBAAsB,CACrC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAC5C,SAAS,CACV,CAAC,CAAC,CAAC,CAAC;AACP,CAAC;AARD,oCAQC;AAED,SAAgB,aAAa,CAC3B,OAAW,EACX,QAAY,EACZ,SAAkB,EAClB,SAAgD;IAAhD,0BAAA,EAAA,gBAA2B,mBAAS,CAAC,kBAAU,CAAC;IAEhD,IAAM,KAAK,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACjE,IAAI,SAAS,IAAI,IAAI,EAAE;QACrB,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3C,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;KACpC;SAAM;QACL,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;KACxC;IACD,OAAO,mBAAS,CAAC,sBAAsB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/D,CAAC;AAdD,sCAcC;AAED,SAAgB,gBAAgB,CAC9B,kBAA6B,EAC7B,MAAiB,EACjB,WAAwB;IAAxB,4BAAA,EAAA,gBAAwB;IAExB,OAAO,mBAAS,CAAC,sBAAsB,CACrC,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,EAC5C,kBAAkB,CACnB,CAAC,CAAC,CAAC,CAAC;AACP,CAAC;AATD,4CASC"} \ No newline at end of file diff --git a/clients/bolt-sdk/lib/instructions/apply.d.ts b/clients/bolt-sdk/lib/instructions/apply.d.ts index 5ef9b1f..346d173 100644 --- a/clients/bolt-sdk/lib/instructions/apply.d.ts +++ b/clients/bolt-sdk/lib/instructions/apply.d.ts @@ -12,6 +12,8 @@ export interface ApplyInstructionAccounts { componentProgram: web3.PublicKey; boltSystem: web3.PublicKey; boltComponent: web3.PublicKey; + authority?: web3.PublicKey; + instructionSysvarAccount?: web3.PublicKey; anchorRemainingAccounts?: web3.AccountMeta[]; } export declare const applyInstructionDiscriminator: number[]; diff --git a/clients/bolt-sdk/lib/instructions/apply.d.ts.map b/clients/bolt-sdk/lib/instructions/apply.d.ts.map index 29c6039..e99e6bd 100644 --- a/clients/bolt-sdk/lib/instructions/apply.d.ts.map +++ b/clients/bolt-sdk/lib/instructions/apply.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../src/generated/instructions/apply.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,IAAI,MAAM,2BAA2B,CAAC;AAClD,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AAOxC,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,UAAU,CAAC;CAClB;AAMD,eAAO,MAAM,WAAW;8BAEM,MAAM,EAAE;EAQrC,CAAC;AAWF,MAAM,WAAW,wBAAwB;IACvC,gBAAgB,EAAE,IAAI,CAAC,SAAS,CAAC;IACjC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC;IAC3B,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC;IAC9B,uBAAuB,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC;CAC9C;AAED,eAAO,MAAM,6BAA6B,UAEzC,CAAC;AAYF,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,wBAAwB,EAClC,IAAI,EAAE,oBAAoB,EAC1B,SAAS,iBAAoE,+BAoC9E"} \ No newline at end of file +{"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../src/generated/instructions/apply.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,IAAI,MAAM,2BAA2B,CAAC;AAClD,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AAQxC,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,UAAU,CAAC;CAClB;AAMD,eAAO,MAAM,WAAW;8BAEM,MAAM,EAAE;EAQrC,CAAC;AAaF,MAAM,WAAW,wBAAwB;IACvC,gBAAgB,EAAE,IAAI,CAAC,SAAS,CAAC;IACjC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC;IAC3B,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC;IAC9B,SAAS,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC;IAC3B,wBAAwB,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC;IAC1C,uBAAuB,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC;CAC9C;AAED,eAAO,MAAM,6BAA6B,UAEzC,CAAC;AAYF,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,wBAAwB,EAClC,IAAI,EAAE,oBAAoB,EAC1B,SAAS,iBAAoE,+BA8C9E"} \ No newline at end of file diff --git a/clients/bolt-sdk/lib/instructions/apply.js b/clients/bolt-sdk/lib/instructions/apply.js index e191494..91f8653 100644 --- a/clients/bolt-sdk/lib/instructions/apply.js +++ b/clients/bolt-sdk/lib/instructions/apply.js @@ -65,6 +65,7 @@ exports.createApplyInstruction = void 0; var beet = __importStar(require("@metaplex-foundation/beet")); var web3 = __importStar(require("@solana/web3.js")); +var index_1 = require("../index"); exports.applyStruct = new beet.FixableBeetArgsStruct( [ ["instructionDiscriminator", beet.uniformFixedSizeArray(beet.u8, 8)], @@ -74,6 +75,7 @@ exports.applyStruct = new beet.FixableBeetArgsStruct( ); exports.applyInstructionDiscriminator = [248, 243, 145, 24, 105, 50, 162, 225]; function createApplyInstruction(accounts, args, programId) { + var _a, _b; if (programId === void 0) { programId = new web3.PublicKey( "WorLD15A7CrDwLcLy4fRqtaTb9fbd8o8iqiEMUDse2n" @@ -101,14 +103,28 @@ function createApplyInstruction(accounts, args, programId) { isWritable: true, isSigner: false, }, + { + pubkey: + (_a = accounts.authority) !== null && _a !== void 0 ? _a : programId, + isWritable: false, + isSigner: false, + }, + { + pubkey: + (_b = accounts.instructionSysvarAccount) !== null && _b !== void 0 + ? _b + : index_1.SYSVAR_INSTRUCTIONS_PUBKEY, + isWritable: false, + isSigner: false, + }, ]; if (accounts.anchorRemainingAccounts != null) { for ( - var _i = 0, _a = accounts.anchorRemainingAccounts; - _i < _a.length; + var _i = 0, _c = accounts.anchorRemainingAccounts; + _i < _c.length; _i++ ) { - var acc = _a[_i]; + var acc = _c[_i]; keys.push(acc); } } diff --git a/clients/bolt-sdk/lib/instructions/apply.js.map b/clients/bolt-sdk/lib/instructions/apply.js.map index f241831..ac787cb 100644 --- a/clients/bolt-sdk/lib/instructions/apply.js.map +++ b/clients/bolt-sdk/lib/instructions/apply.js.map @@ -1 +1 @@ -{"version":3,"file":"apply.js","sourceRoot":"","sources":["../../src/generated/instructions/apply.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOA,8DAAkD;AAClD,oDAAwC;AAe3B,QAAA,WAAW,GAAG,IAAI,IAAI,CAAC,qBAAqB,CAKvD;IACE,CAAC,0BAA0B,EAAE,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IACpE,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC;CACrB,EACD,sBAAsB,CACvB,CAAC;AAkBW,QAAA,6BAA6B,GAAG;IAC3C,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG;CACrC,CAAC;AAYF,SAAgB,sBAAsB,CACpC,QAAkC,EAClC,IAA0B,EAC1B,SAA6E;IAA7E,0BAAA,EAAA,gBAAgB,IAAI,CAAC,SAAS,CAAC,6CAA6C,CAAC;IAEtE,IAAA,IAAI,GAAI,mBAAW,CAAC,SAAS,YAClC,wBAAwB,EAAE,qCAA6B,IACpD,IAAI,EACP,GAHS,CAGR;IACH,IAAM,IAAI,GAAuB;QAC/B;YACE,MAAM,EAAE,QAAQ,CAAC,gBAAgB;YACjC,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,QAAQ,CAAC,UAAU;YAC3B,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,QAAQ,CAAC,aAAa;YAC9B,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,KAAK;SAChB;KACF,CAAC;IAEF,IAAI,QAAQ,CAAC,uBAAuB,IAAI,IAAI,EAAE;QAC5C,KAAkB,UAAgC,EAAhC,KAAA,QAAQ,CAAC,uBAAuB,EAAhC,cAAgC,EAAhC,IAAgC,EAAE;YAA/C,IAAM,GAAG,SAAA;YACZ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;SAChB;KACF;IAED,IAAM,EAAE,GAAG,IAAI,IAAI,CAAC,sBAAsB,CAAC;QACzC,SAAS,WAAA;QACT,IAAI,MAAA;QACJ,IAAI,MAAA;KACL,CAAC,CAAC;IACH,OAAO,EAAE,CAAC;AACZ,CAAC;AAvCD,wDAuCC"} \ No newline at end of file +{"version":3,"file":"apply.js","sourceRoot":"","sources":["../../src/generated/instructions/apply.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOA,8DAAkD;AAClD,oDAAwC;AACxC,kCAAsD;AAezC,QAAA,WAAW,GAAG,IAAI,IAAI,CAAC,qBAAqB,CAKvD;IACE,CAAC,0BAA0B,EAAE,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IACpE,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC;CACrB,EACD,sBAAsB,CACvB,CAAC;AAsBW,QAAA,6BAA6B,GAAG;IAC3C,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG;CACrC,CAAC;AAYF,SAAgB,sBAAsB,CACpC,QAAkC,EAClC,IAA0B,EAC1B,SAA6E;;IAA7E,0BAAA,EAAA,gBAAgB,IAAI,CAAC,SAAS,CAAC,6CAA6C,CAAC;IAEtE,IAAA,IAAI,GAAI,mBAAW,CAAC,SAAS,YAClC,wBAAwB,EAAE,qCAA6B,IACpD,IAAI,EACP,GAHS,CAGR;IACH,IAAM,IAAI,GAAuB;QAC/B;YACE,MAAM,EAAE,QAAQ,CAAC,gBAAgB;YACjC,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,QAAQ,CAAC,UAAU;YAC3B,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,QAAQ,CAAC,aAAa;YAC9B,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,MAAA,QAAQ,CAAC,SAAS,mCAAI,SAAS;YACvC,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,MAAA,QAAQ,CAAC,wBAAwB,mCAAI,kCAA0B;YACvE,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;SAChB;KACF,CAAC;IAEF,IAAI,QAAQ,CAAC,uBAAuB,IAAI,IAAI,EAAE;QAC5C,KAAkB,UAAgC,EAAhC,KAAA,QAAQ,CAAC,uBAAuB,EAAhC,cAAgC,EAAhC,IAAgC,EAAE;YAA/C,IAAM,GAAG,SAAA;YACZ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;SAChB;KACF;IAED,IAAM,EAAE,GAAG,IAAI,IAAI,CAAC,sBAAsB,CAAC;QACzC,SAAS,WAAA;QACT,IAAI,MAAA;QACJ,IAAI,MAAA;KACL,CAAC,CAAC;IACH,OAAO,EAAE,CAAC;AACZ,CAAC;AAjDD,wDAiDC"} \ No newline at end of file diff --git a/clients/bolt-sdk/lib/instructions/apply2.d.ts b/clients/bolt-sdk/lib/instructions/apply2.d.ts index ffe5025..fcfa2d6 100644 --- a/clients/bolt-sdk/lib/instructions/apply2.d.ts +++ b/clients/bolt-sdk/lib/instructions/apply2.d.ts @@ -14,6 +14,8 @@ export interface Apply2InstructionAccounts { boltComponent1: web3.PublicKey; componentProgram2: web3.PublicKey; boltComponent2: web3.PublicKey; + authority?: web3.PublicKey; + instructionSysvarAccount?: web3.PublicKey; anchorRemainingAccounts?: web3.AccountMeta[]; } export declare const apply2InstructionDiscriminator: number[]; diff --git a/clients/bolt-sdk/lib/instructions/apply2.d.ts.map b/clients/bolt-sdk/lib/instructions/apply2.d.ts.map index 94bce7c..aef0cd9 100644 --- a/clients/bolt-sdk/lib/instructions/apply2.d.ts.map +++ b/clients/bolt-sdk/lib/instructions/apply2.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"apply2.d.ts","sourceRoot":"","sources":["../../src/generated/instructions/apply2.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,IAAI,MAAM,2BAA2B,CAAC;AAClD,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AAOxC,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,UAAU,CAAC;CAClB;AAMD,eAAO,MAAM,YAAY;8BAEK,MAAM,EAAE;EAQrC,CAAC;AAaF,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC;IAC3B,iBAAiB,EAAE,IAAI,CAAC,SAAS,CAAC;IAClC,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC;IAC/B,iBAAiB,EAAE,IAAI,CAAC,SAAS,CAAC;IAClC,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC;IAC/B,uBAAuB,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC;CAC9C;AAED,eAAO,MAAM,8BAA8B,UAE1C,CAAC;AAYF,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,yBAAyB,EACnC,IAAI,EAAE,qBAAqB,EAC3B,SAAS,iBAAoE,+BA8C9E"} \ No newline at end of file +{"version":3,"file":"apply2.d.ts","sourceRoot":"","sources":["../../src/generated/instructions/apply2.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,IAAI,MAAM,2BAA2B,CAAC;AAClD,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AAQxC,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,UAAU,CAAC;CAClB;AAMD,eAAO,MAAM,YAAY;8BAEK,MAAM,EAAE;EAQrC,CAAC;AAeF,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC;IAC3B,iBAAiB,EAAE,IAAI,CAAC,SAAS,CAAC;IAClC,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC;IAC/B,iBAAiB,EAAE,IAAI,CAAC,SAAS,CAAC;IAClC,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC;IAC/B,SAAS,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC;IAC3B,wBAAwB,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC;IAC1C,uBAAuB,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC;CAC9C;AAED,eAAO,MAAM,8BAA8B,UAE1C,CAAC;AAYF,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,yBAAyB,EACnC,IAAI,EAAE,qBAAqB,EAC3B,SAAS,iBAAoE,+BAwD9E"} \ No newline at end of file diff --git a/clients/bolt-sdk/lib/instructions/apply2.js b/clients/bolt-sdk/lib/instructions/apply2.js index 614cc52..e51ed8c 100644 --- a/clients/bolt-sdk/lib/instructions/apply2.js +++ b/clients/bolt-sdk/lib/instructions/apply2.js @@ -65,6 +65,7 @@ exports.createApply2Instruction = void 0; var beet = __importStar(require("@metaplex-foundation/beet")); var web3 = __importStar(require("@solana/web3.js")); +var index_1 = require("../index"); exports.apply2Struct = new beet.FixableBeetArgsStruct( [ ["instructionDiscriminator", beet.uniformFixedSizeArray(beet.u8, 8)], @@ -74,6 +75,7 @@ exports.apply2Struct = new beet.FixableBeetArgsStruct( ); exports.apply2InstructionDiscriminator = [120, 32, 116, 154, 158, 159, 208, 73]; function createApply2Instruction(accounts, args, programId) { + var _a, _b; if (programId === void 0) { programId = new web3.PublicKey( "WorLD15A7CrDwLcLy4fRqtaTb9fbd8o8iqiEMUDse2n" @@ -111,14 +113,28 @@ function createApply2Instruction(accounts, args, programId) { isWritable: true, isSigner: false, }, + { + pubkey: + (_a = accounts.authority) !== null && _a !== void 0 ? _a : programId, + isWritable: false, + isSigner: false, + }, + { + pubkey: + (_b = accounts.instructionSysvarAccount) !== null && _b !== void 0 + ? _b + : index_1.SYSVAR_INSTRUCTIONS_PUBKEY, + isWritable: false, + isSigner: false, + }, ]; if (accounts.anchorRemainingAccounts != null) { for ( - var _i = 0, _a = accounts.anchorRemainingAccounts; - _i < _a.length; + var _i = 0, _c = accounts.anchorRemainingAccounts; + _i < _c.length; _i++ ) { - var acc = _a[_i]; + var acc = _c[_i]; keys.push(acc); } } diff --git a/clients/bolt-sdk/lib/instructions/apply2.js.map b/clients/bolt-sdk/lib/instructions/apply2.js.map index 3987cdb..ee71af3 100644 --- a/clients/bolt-sdk/lib/instructions/apply2.js.map +++ b/clients/bolt-sdk/lib/instructions/apply2.js.map @@ -1 +1 @@ -{"version":3,"file":"apply2.js","sourceRoot":"","sources":["../../src/generated/instructions/apply2.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOA,8DAAkD;AAClD,oDAAwC;AAe3B,QAAA,YAAY,GAAG,IAAI,IAAI,CAAC,qBAAqB,CAKxD;IACE,CAAC,0BAA0B,EAAE,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IACpE,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC;CACrB,EACD,uBAAuB,CACxB,CAAC;AAsBW,QAAA,8BAA8B,GAAG;IAC5C,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;CACrC,CAAC;AAYF,SAAgB,uBAAuB,CACrC,QAAmC,EACnC,IAA2B,EAC3B,SAA6E;IAA7E,0BAAA,EAAA,gBAAgB,IAAI,CAAC,SAAS,CAAC,6CAA6C,CAAC;IAEtE,IAAA,IAAI,GAAI,oBAAY,CAAC,SAAS,YACnC,wBAAwB,EAAE,sCAA8B,IACrD,IAAI,EACP,GAHS,CAGR;IACH,IAAM,IAAI,GAAuB;QAC/B;YACE,MAAM,EAAE,QAAQ,CAAC,UAAU;YAC3B,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,QAAQ,CAAC,iBAAiB;YAClC,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,QAAQ,CAAC,cAAc;YAC/B,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,QAAQ,CAAC,iBAAiB;YAClC,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,QAAQ,CAAC,cAAc;YAC/B,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,KAAK;SAChB;KACF,CAAC;IAEF,IAAI,QAAQ,CAAC,uBAAuB,IAAI,IAAI,EAAE;QAC5C,KAAkB,UAAgC,EAAhC,KAAA,QAAQ,CAAC,uBAAuB,EAAhC,cAAgC,EAAhC,IAAgC,EAAE;YAA/C,IAAM,GAAG,SAAA;YACZ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;SAChB;KACF;IAED,IAAM,EAAE,GAAG,IAAI,IAAI,CAAC,sBAAsB,CAAC;QACzC,SAAS,WAAA;QACT,IAAI,MAAA;QACJ,IAAI,MAAA;KACL,CAAC,CAAC;IACH,OAAO,EAAE,CAAC;AACZ,CAAC;AAjDD,0DAiDC"} \ No newline at end of file +{"version":3,"file":"apply2.js","sourceRoot":"","sources":["../../src/generated/instructions/apply2.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOA,8DAAkD;AAClD,oDAAwC;AACxC,kCAAsD;AAezC,QAAA,YAAY,GAAG,IAAI,IAAI,CAAC,qBAAqB,CAKxD;IACE,CAAC,0BAA0B,EAAE,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IACpE,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC;CACrB,EACD,uBAAuB,CACxB,CAAC;AA0BW,QAAA,8BAA8B,GAAG;IAC5C,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;CACrC,CAAC;AAYF,SAAgB,uBAAuB,CACrC,QAAmC,EACnC,IAA2B,EAC3B,SAA6E;;IAA7E,0BAAA,EAAA,gBAAgB,IAAI,CAAC,SAAS,CAAC,6CAA6C,CAAC;IAEtE,IAAA,IAAI,GAAI,oBAAY,CAAC,SAAS,YACnC,wBAAwB,EAAE,sCAA8B,IACrD,IAAI,EACP,GAHS,CAGR;IACH,IAAM,IAAI,GAAuB;QAC/B;YACE,MAAM,EAAE,QAAQ,CAAC,UAAU;YAC3B,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,QAAQ,CAAC,iBAAiB;YAClC,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,QAAQ,CAAC,cAAc;YAC/B,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,QAAQ,CAAC,iBAAiB;YAClC,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,QAAQ,CAAC,cAAc;YAC/B,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,MAAA,QAAQ,CAAC,SAAS,mCAAI,SAAS;YACvC,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,MAAA,QAAQ,CAAC,wBAAwB,mCAAI,kCAA0B;YACvE,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;SAChB;KACF,CAAC;IAEF,IAAI,QAAQ,CAAC,uBAAuB,IAAI,IAAI,EAAE;QAC5C,KAAkB,UAAgC,EAAhC,KAAA,QAAQ,CAAC,uBAAuB,EAAhC,cAAgC,EAAhC,IAAgC,EAAE;YAA/C,IAAM,GAAG,SAAA;YACZ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;SAChB;KACF;IAED,IAAM,EAAE,GAAG,IAAI,IAAI,CAAC,sBAAsB,CAAC;QACzC,SAAS,WAAA;QACT,IAAI,MAAA;QACJ,IAAI,MAAA;KACL,CAAC,CAAC;IACH,OAAO,EAAE,CAAC;AACZ,CAAC;AA3DD,0DA2DC"} \ No newline at end of file diff --git a/clients/bolt-sdk/lib/instructions/apply3.d.ts b/clients/bolt-sdk/lib/instructions/apply3.d.ts index c29a4aa..7c02d18 100644 --- a/clients/bolt-sdk/lib/instructions/apply3.d.ts +++ b/clients/bolt-sdk/lib/instructions/apply3.d.ts @@ -16,6 +16,8 @@ export interface Apply3InstructionAccounts { boltComponent2: web3.PublicKey; componentProgram3: web3.PublicKey; boltComponent3: web3.PublicKey; + authority?: web3.PublicKey; + instructionSysvarAccount?: web3.PublicKey; anchorRemainingAccounts?: web3.AccountMeta[]; } export declare const apply3InstructionDiscriminator: number[]; diff --git a/clients/bolt-sdk/lib/instructions/apply3.d.ts.map b/clients/bolt-sdk/lib/instructions/apply3.d.ts.map index d2f1a1f..302276d 100644 --- a/clients/bolt-sdk/lib/instructions/apply3.d.ts.map +++ b/clients/bolt-sdk/lib/instructions/apply3.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"apply3.d.ts","sourceRoot":"","sources":["../../src/generated/instructions/apply3.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,IAAI,MAAM,2BAA2B,CAAC;AAClD,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AAOxC,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,UAAU,CAAC;CAClB;AAMD,eAAO,MAAM,YAAY;8BAEK,MAAM,EAAE;EAQrC,CAAC;AAeF,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC;IAC3B,iBAAiB,EAAE,IAAI,CAAC,SAAS,CAAC;IAClC,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC;IAC/B,iBAAiB,EAAE,IAAI,CAAC,SAAS,CAAC;IAClC,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC;IAC/B,iBAAiB,EAAE,IAAI,CAAC,SAAS,CAAC;IAClC,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC;IAC/B,uBAAuB,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC;CAC9C;AAED,eAAO,MAAM,8BAA8B,UAE1C,CAAC;AAYF,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,yBAAyB,EACnC,IAAI,EAAE,qBAAqB,EAC3B,SAAS,iBAAoE,+BAwD9E"} \ No newline at end of file +{"version":3,"file":"apply3.d.ts","sourceRoot":"","sources":["../../src/generated/instructions/apply3.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,IAAI,MAAM,2BAA2B,CAAC;AAClD,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AAQxC,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,UAAU,CAAC;CAClB;AAMD,eAAO,MAAM,YAAY;8BAEK,MAAM,EAAE;EAQrC,CAAC;AAiBF,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC;IAC3B,iBAAiB,EAAE,IAAI,CAAC,SAAS,CAAC;IAClC,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC;IAC/B,iBAAiB,EAAE,IAAI,CAAC,SAAS,CAAC;IAClC,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC;IAC/B,iBAAiB,EAAE,IAAI,CAAC,SAAS,CAAC;IAClC,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC;IAC/B,SAAS,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC;IAC3B,wBAAwB,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC;IAC1C,uBAAuB,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC;CAC9C;AAED,eAAO,MAAM,8BAA8B,UAE1C,CAAC;AAYF,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,yBAAyB,EACnC,IAAI,EAAE,qBAAqB,EAC3B,SAAS,iBAAoE,+BAkE9E"} \ No newline at end of file diff --git a/clients/bolt-sdk/lib/instructions/apply3.js b/clients/bolt-sdk/lib/instructions/apply3.js index b69d3dc..6e715d0 100644 --- a/clients/bolt-sdk/lib/instructions/apply3.js +++ b/clients/bolt-sdk/lib/instructions/apply3.js @@ -65,6 +65,7 @@ exports.createApply3Instruction = void 0; var beet = __importStar(require("@metaplex-foundation/beet")); var web3 = __importStar(require("@solana/web3.js")); +var index_1 = require("../index"); exports.apply3Struct = new beet.FixableBeetArgsStruct( [ ["instructionDiscriminator", beet.uniformFixedSizeArray(beet.u8, 8)], @@ -74,6 +75,7 @@ exports.apply3Struct = new beet.FixableBeetArgsStruct( ); exports.apply3InstructionDiscriminator = [254, 146, 49, 7, 236, 131, 105, 221]; function createApply3Instruction(accounts, args, programId) { + var _a, _b; if (programId === void 0) { programId = new web3.PublicKey( "WorLD15A7CrDwLcLy4fRqtaTb9fbd8o8iqiEMUDse2n" @@ -121,14 +123,28 @@ function createApply3Instruction(accounts, args, programId) { isWritable: true, isSigner: false, }, + { + pubkey: + (_a = accounts.authority) !== null && _a !== void 0 ? _a : programId, + isWritable: false, + isSigner: false, + }, + { + pubkey: + (_b = accounts.instructionSysvarAccount) !== null && _b !== void 0 + ? _b + : index_1.SYSVAR_INSTRUCTIONS_PUBKEY, + isWritable: false, + isSigner: false, + }, ]; if (accounts.anchorRemainingAccounts != null) { for ( - var _i = 0, _a = accounts.anchorRemainingAccounts; - _i < _a.length; + var _i = 0, _c = accounts.anchorRemainingAccounts; + _i < _c.length; _i++ ) { - var acc = _a[_i]; + var acc = _c[_i]; keys.push(acc); } } diff --git a/clients/bolt-sdk/lib/instructions/apply3.js.map b/clients/bolt-sdk/lib/instructions/apply3.js.map index 9d8f3d6..60c59f0 100644 --- a/clients/bolt-sdk/lib/instructions/apply3.js.map +++ b/clients/bolt-sdk/lib/instructions/apply3.js.map @@ -1 +1 @@ -{"version":3,"file":"apply3.js","sourceRoot":"","sources":["../../src/generated/instructions/apply3.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOA,8DAAkD;AAClD,oDAAwC;AAe3B,QAAA,YAAY,GAAG,IAAI,IAAI,CAAC,qBAAqB,CAKxD;IACE,CAAC,0BAA0B,EAAE,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IACpE,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC;CACrB,EACD,uBAAuB,CACxB,CAAC;AA0BW,QAAA,8BAA8B,GAAG;IAC5C,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG;CACpC,CAAC;AAYF,SAAgB,uBAAuB,CACrC,QAAmC,EACnC,IAA2B,EAC3B,SAA6E;IAA7E,0BAAA,EAAA,gBAAgB,IAAI,CAAC,SAAS,CAAC,6CAA6C,CAAC;IAEtE,IAAA,IAAI,GAAI,oBAAY,CAAC,SAAS,YACnC,wBAAwB,EAAE,sCAA8B,IACrD,IAAI,EACP,GAHS,CAGR;IACH,IAAM,IAAI,GAAuB;QAC/B;YACE,MAAM,EAAE,QAAQ,CAAC,UAAU;YAC3B,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,QAAQ,CAAC,iBAAiB;YAClC,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,QAAQ,CAAC,cAAc;YAC/B,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,QAAQ,CAAC,iBAAiB;YAClC,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,QAAQ,CAAC,cAAc;YAC/B,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,QAAQ,CAAC,iBAAiB;YAClC,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,QAAQ,CAAC,cAAc;YAC/B,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,KAAK;SAChB;KACF,CAAC;IAEF,IAAI,QAAQ,CAAC,uBAAuB,IAAI,IAAI,EAAE;QAC5C,KAAkB,UAAgC,EAAhC,KAAA,QAAQ,CAAC,uBAAuB,EAAhC,cAAgC,EAAhC,IAAgC,EAAE;YAA/C,IAAM,GAAG,SAAA;YACZ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;SAChB;KACF;IAED,IAAM,EAAE,GAAG,IAAI,IAAI,CAAC,sBAAsB,CAAC;QACzC,SAAS,WAAA;QACT,IAAI,MAAA;QACJ,IAAI,MAAA;KACL,CAAC,CAAC;IACH,OAAO,EAAE,CAAC;AACZ,CAAC;AA3DD,0DA2DC"} \ No newline at end of file +{"version":3,"file":"apply3.js","sourceRoot":"","sources":["../../src/generated/instructions/apply3.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOA,8DAAkD;AAClD,oDAAwC;AACxC,kCAAsD;AAezC,QAAA,YAAY,GAAG,IAAI,IAAI,CAAC,qBAAqB,CAKxD;IACE,CAAC,0BAA0B,EAAE,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IACpE,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC;CACrB,EACD,uBAAuB,CACxB,CAAC;AA8BW,QAAA,8BAA8B,GAAG;IAC5C,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG;CACpC,CAAC;AAYF,SAAgB,uBAAuB,CACrC,QAAmC,EACnC,IAA2B,EAC3B,SAA6E;;IAA7E,0BAAA,EAAA,gBAAgB,IAAI,CAAC,SAAS,CAAC,6CAA6C,CAAC;IAEtE,IAAA,IAAI,GAAI,oBAAY,CAAC,SAAS,YACnC,wBAAwB,EAAE,sCAA8B,IACrD,IAAI,EACP,GAHS,CAGR;IACH,IAAM,IAAI,GAAuB;QAC/B;YACE,MAAM,EAAE,QAAQ,CAAC,UAAU;YAC3B,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,QAAQ,CAAC,iBAAiB;YAClC,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,QAAQ,CAAC,cAAc;YAC/B,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,QAAQ,CAAC,iBAAiB;YAClC,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,QAAQ,CAAC,cAAc;YAC/B,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,QAAQ,CAAC,iBAAiB;YAClC,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,QAAQ,CAAC,cAAc;YAC/B,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,MAAA,QAAQ,CAAC,SAAS,mCAAI,SAAS;YACvC,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,MAAA,QAAQ,CAAC,wBAAwB,mCAAI,kCAA0B;YACvE,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;SAChB;KACF,CAAC;IAEF,IAAI,QAAQ,CAAC,uBAAuB,IAAI,IAAI,EAAE;QAC5C,KAAkB,UAAgC,EAAhC,KAAA,QAAQ,CAAC,uBAAuB,EAAhC,cAAgC,EAAhC,IAAgC,EAAE;YAA/C,IAAM,GAAG,SAAA;YACZ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;SAChB;KACF;IAED,IAAM,EAAE,GAAG,IAAI,IAAI,CAAC,sBAAsB,CAAC;QACzC,SAAS,WAAA;QACT,IAAI,MAAA;QACJ,IAAI,MAAA;KACL,CAAC,CAAC;IACH,OAAO,EAAE,CAAC;AACZ,CAAC;AArED,0DAqEC"} \ No newline at end of file diff --git a/clients/bolt-sdk/lib/instructions/initializeComponent.d.ts b/clients/bolt-sdk/lib/instructions/initializeComponent.d.ts index 523f62e..23510f9 100644 --- a/clients/bolt-sdk/lib/instructions/initializeComponent.d.ts +++ b/clients/bolt-sdk/lib/instructions/initializeComponent.d.ts @@ -8,6 +8,8 @@ export interface InitializeComponentInstructionAccounts { data: web3.PublicKey; entity: web3.PublicKey; componentProgram: web3.PublicKey; + authority?: web3.PublicKey; + instructionSysvarAccount?: web3.PublicKey; systemProgram?: web3.PublicKey; anchorRemainingAccounts?: web3.AccountMeta[]; } diff --git a/clients/bolt-sdk/lib/instructions/initializeComponent.d.ts.map b/clients/bolt-sdk/lib/instructions/initializeComponent.d.ts.map index 0789507..4f20c0e 100644 --- a/clients/bolt-sdk/lib/instructions/initializeComponent.d.ts.map +++ b/clients/bolt-sdk/lib/instructions/initializeComponent.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"initializeComponent.d.ts","sourceRoot":"","sources":["../../src/generated/instructions/initializeComponent.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,IAAI,MAAM,2BAA2B,CAAC;AAClD,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AAOxC,eAAO,MAAM,yBAAyB;8BACV,MAAM,EAAE;EAInC,CAAC;AAYF,MAAM,WAAW,sCAAsC;IACrD,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC;IACtB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;IACrB,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC;IACvB,gBAAgB,EAAE,IAAI,CAAC,SAAS,CAAC;IACjC,aAAa,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC;IAC/B,uBAAuB,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC;CAC9C;AAED,eAAO,MAAM,2CAA2C,UAEvD,CAAC;AAUF,wBAAgB,oCAAoC,CAClD,QAAQ,EAAE,sCAAsC,EAChD,SAAS,iBAAoE,+BA6C9E"} \ No newline at end of file +{"version":3,"file":"initializeComponent.d.ts","sourceRoot":"","sources":["../../src/generated/instructions/initializeComponent.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,IAAI,MAAM,2BAA2B,CAAC;AAClD,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AAQxC,eAAO,MAAM,yBAAyB;8BACV,MAAM,EAAE;EAInC,CAAC;AAcF,MAAM,WAAW,sCAAsC;IACrD,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC;IACtB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;IACrB,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC;IACvB,gBAAgB,EAAE,IAAI,CAAC,SAAS,CAAC;IACjC,SAAS,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC;IAC3B,wBAAwB,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC;IAC1C,aAAa,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC;IAC/B,uBAAuB,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC;CAC9C;AAED,eAAO,MAAM,2CAA2C,UAEvD,CAAC;AAUF,wBAAgB,oCAAoC,CAClD,QAAQ,EAAE,sCAAsC,EAChD,SAAS,iBAAoE,+BAuD9E"} \ No newline at end of file diff --git a/clients/bolt-sdk/lib/instructions/initializeComponent.js b/clients/bolt-sdk/lib/instructions/initializeComponent.js index 3d9a404..2e688c0 100644 --- a/clients/bolt-sdk/lib/instructions/initializeComponent.js +++ b/clients/bolt-sdk/lib/instructions/initializeComponent.js @@ -50,6 +50,7 @@ exports.createInitializeComponentInstruction = void 0; var beet = __importStar(require("@metaplex-foundation/beet")); var web3 = __importStar(require("@solana/web3.js")); +var index_1 = require("../index"); exports.initializeComponentStruct = new beet.BeetArgsStruct( [["instructionDiscriminator", beet.uniformFixedSizeArray(beet.u8, 8)]], "InitializeComponentInstructionArgs" @@ -58,7 +59,7 @@ exports.initializeComponentInstructionDiscriminator = [ 36, 143, 233, 113, 12, 234, 61, 30, ]; function createInitializeComponentInstruction(accounts, programId) { - var _a; + var _a, _b, _c; if (programId === void 0) { programId = new web3.PublicKey( "WorLD15A7CrDwLcLy4fRqtaTb9fbd8o8iqiEMUDse2n" @@ -91,8 +92,22 @@ function createInitializeComponentInstruction(accounts, programId) { }, { pubkey: - (_a = accounts.systemProgram) !== null && _a !== void 0 - ? _a + (_a = accounts.authority) !== null && _a !== void 0 ? _a : programId, + isWritable: false, + isSigner: false, + }, + { + pubkey: + (_b = accounts.instructionSysvarAccount) !== null && _b !== void 0 + ? _b + : index_1.SYSVAR_INSTRUCTIONS_PUBKEY, + isWritable: false, + isSigner: false, + }, + { + pubkey: + (_c = accounts.systemProgram) !== null && _c !== void 0 + ? _c : web3.SystemProgram.programId, isWritable: false, isSigner: false, @@ -100,11 +115,11 @@ function createInitializeComponentInstruction(accounts, programId) { ]; if (accounts.anchorRemainingAccounts != null) { for ( - var _i = 0, _b = accounts.anchorRemainingAccounts; - _i < _b.length; + var _i = 0, _d = accounts.anchorRemainingAccounts; + _i < _d.length; _i++ ) { - var acc = _b[_i]; + var acc = _d[_i]; keys.push(acc); } } diff --git a/clients/bolt-sdk/lib/instructions/initializeComponent.js.map b/clients/bolt-sdk/lib/instructions/initializeComponent.js.map index fb190de..5507984 100644 --- a/clients/bolt-sdk/lib/instructions/initializeComponent.js.map +++ b/clients/bolt-sdk/lib/instructions/initializeComponent.js.map @@ -1 +1 @@ -{"version":3,"file":"initializeComponent.js","sourceRoot":"","sources":["../../src/generated/instructions/initializeComponent.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAOA,8DAAkD;AAClD,oDAAwC;AAO3B,QAAA,yBAAyB,GAAG,IAAI,IAAI,CAAC,cAAc,CAG9D,CAAC,CAAC,0BAA0B,EAAE,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EACtE,oCAAoC,CACrC,CAAC;AAqBW,QAAA,2CAA2C,GAAG;IACzD,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE;CACnC,CAAC;AAUF,SAAgB,oCAAoC,CAClD,QAAgD,EAChD,SAA6E;;IAA7E,0BAAA,EAAA,gBAAgB,IAAI,CAAC,SAAS,CAAC,6CAA6C,CAAC;IAEtE,IAAA,IAAI,GAAI,iCAAyB,CAAC,SAAS,CAAC;QACjD,wBAAwB,EAAE,mDAA2C;KACtE,CAAC,GAFS,CAER;IACH,IAAM,IAAI,GAAuB;QAC/B;YACE,MAAM,EAAE,QAAQ,CAAC,KAAK;YACtB,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,IAAI;SACf;QACD;YACE,MAAM,EAAE,QAAQ,CAAC,IAAI;YACrB,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,QAAQ,CAAC,gBAAgB;YACjC,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,MAAA,QAAQ,CAAC,aAAa,mCAAI,IAAI,CAAC,aAAa,CAAC,SAAS;YAC9D,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;SAChB;KACF,CAAC;IAEF,IAAI,QAAQ,CAAC,uBAAuB,IAAI,IAAI,EAAE;QAC5C,KAAkB,UAAgC,EAAhC,KAAA,QAAQ,CAAC,uBAAuB,EAAhC,cAAgC,EAAhC,IAAgC,EAAE;YAA/C,IAAM,GAAG,SAAA;YACZ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;SAChB;KACF;IAED,IAAM,EAAE,GAAG,IAAI,IAAI,CAAC,sBAAsB,CAAC;QACzC,SAAS,WAAA;QACT,IAAI,MAAA;QACJ,IAAI,MAAA;KACL,CAAC,CAAC;IACH,OAAO,EAAE,CAAC;AACZ,CAAC;AA/CD,oFA+CC"} \ No newline at end of file +{"version":3,"file":"initializeComponent.js","sourceRoot":"","sources":["../../src/generated/instructions/initializeComponent.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAOA,8DAAkD;AAClD,oDAAwC;AACxC,kCAAsD;AAOzC,QAAA,yBAAyB,GAAG,IAAI,IAAI,CAAC,cAAc,CAG9D,CAAC,CAAC,0BAA0B,EAAE,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EACtE,oCAAoC,CACrC,CAAC;AAyBW,QAAA,2CAA2C,GAAG;IACzD,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE;CACnC,CAAC;AAUF,SAAgB,oCAAoC,CAClD,QAAgD,EAChD,SAA6E;;IAA7E,0BAAA,EAAA,gBAAgB,IAAI,CAAC,SAAS,CAAC,6CAA6C,CAAC;IAEtE,IAAA,IAAI,GAAI,iCAAyB,CAAC,SAAS,CAAC;QACjD,wBAAwB,EAAE,mDAA2C;KACtE,CAAC,GAFS,CAER;IACH,IAAM,IAAI,GAAuB;QAC/B;YACE,MAAM,EAAE,QAAQ,CAAC,KAAK;YACtB,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,IAAI;SACf;QACD;YACE,MAAM,EAAE,QAAQ,CAAC,IAAI;YACrB,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,QAAQ,CAAC,gBAAgB;YACjC,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,MAAA,QAAQ,CAAC,SAAS,mCAAI,SAAS;YACvC,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,MAAA,QAAQ,CAAC,wBAAwB,mCAAI,kCAA0B;YACvE,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;SAChB;QACD;YACE,MAAM,EAAE,MAAA,QAAQ,CAAC,aAAa,mCAAI,IAAI,CAAC,aAAa,CAAC,SAAS;YAC9D,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;SAChB;KACF,CAAC;IAEF,IAAI,QAAQ,CAAC,uBAAuB,IAAI,IAAI,EAAE;QAC5C,KAAkB,UAAgC,EAAhC,KAAA,QAAQ,CAAC,uBAAuB,EAAhC,cAAgC,EAAhC,IAAgC,EAAE;YAA/C,IAAM,GAAG,SAAA;YACZ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;SAChB;KACF;IAED,IAAM,EAAE,GAAG,IAAI,IAAI,CAAC,sBAAsB,CAAC;QACzC,SAAS,WAAA;QACT,IAAI,MAAA;QACJ,IAAI,MAAA;KACL,CAAC,CAAC;IACH,OAAO,EAAE,CAAC;AACZ,CAAC;AAzDD,oFAyDC"} \ No newline at end of file diff --git a/clients/bolt-sdk/src/generated/accounts/index.ts b/clients/bolt-sdk/src/generated/accounts/index.ts index b9a3ead..67dd624 100644 --- a/clients/bolt-sdk/src/generated/accounts/index.ts +++ b/clients/bolt-sdk/src/generated/accounts/index.ts @@ -1,9 +1,9 @@ +import { Entity } from "./Entity"; import { Registry } from "./Registry"; import { World } from "./World"; -import { Entity } from "./Entity"; export * from "./Entity"; export * from "./Registry"; export * from "./World"; -export const accountProviders = { Registry, World, Entity }; +export const accountProviders = { Entity, Registry, World }; diff --git a/clients/bolt-sdk/src/generated/errors/index.ts b/clients/bolt-sdk/src/generated/errors/index.ts new file mode 100644 index 0000000..4ff4e04 --- /dev/null +++ b/clients/bolt-sdk/src/generated/errors/index.ts @@ -0,0 +1,55 @@ +/** + * This code was GENERATED using the solita package. + * Please DO NOT EDIT THIS FILE, instead rerun solita to update it or write a wrapper to add functionality. + * + * See: https://github.com/metaplex-foundation/solita + */ + +type ErrorWithCode = Error & { code: number }; +type MaybeErrorWithCode = ErrorWithCode | null | undefined; + +const createErrorFromCodeLookup = new Map ErrorWithCode>(); +const createErrorFromNameLookup = new Map ErrorWithCode>(); + +/** + * InvalidAuthority: 'Invalid authority for instruction' + * + * @category Errors + * @category generated + */ +export class InvalidAuthorityError extends Error { + readonly code: number = 0x1770; + readonly name: string = "InvalidAuthority"; + constructor() { + super("Invalid authority for instruction"); + if (typeof Error.captureStackTrace === "function") { + Error.captureStackTrace(this, InvalidAuthorityError); + } + } +} + +createErrorFromCodeLookup.set(0x1770, () => new InvalidAuthorityError()); +createErrorFromNameLookup.set( + "InvalidAuthority", + () => new InvalidAuthorityError() +); + +/** + * Attempts to resolve a custom program error from the provided error code. + * @category Errors + * @category generated + */ +export function errorFromCode(code: number): MaybeErrorWithCode { + const createError = createErrorFromCodeLookup.get(code); + return createError != null ? createError() : null; +} + +/** + * Attempts to resolve a custom program error from the provided error name, i.e. 'Unauthorized'. + * @category Errors + * @category generated + */ +export function errorFromName(name: string): MaybeErrorWithCode { + const createError = createErrorFromNameLookup.get(name); + return createError != null ? createError() : null; +} diff --git a/clients/bolt-sdk/src/generated/index.ts b/clients/bolt-sdk/src/generated/index.ts index 6273b2d..1a988d0 100644 --- a/clients/bolt-sdk/src/generated/index.ts +++ b/clients/bolt-sdk/src/generated/index.ts @@ -11,6 +11,10 @@ export * from "./instructions"; */ export const PROGRAM_ADDRESS = "WorLD15A7CrDwLcLy4fRqtaTb9fbd8o8iqiEMUDse2n"; +export const SYSVAR_INSTRUCTIONS_PUBKEY = new PublicKey( + "Sysvar1nstructions1111111111111111111111111" +); + /** * Program public key * diff --git a/clients/bolt-sdk/src/generated/instructions/apply.ts b/clients/bolt-sdk/src/generated/instructions/apply.ts index 5a195a8..b1528fe 100644 --- a/clients/bolt-sdk/src/generated/instructions/apply.ts +++ b/clients/bolt-sdk/src/generated/instructions/apply.ts @@ -7,6 +7,7 @@ import * as beet from "@metaplex-foundation/beet"; import * as web3 from "@solana/web3.js"; +import { SYSVAR_INSTRUCTIONS_PUBKEY } from "../index"; /** * @category Instructions @@ -38,6 +39,8 @@ export const applyStruct = new beet.FixableBeetArgsStruct< * @property [] componentProgram * @property [] boltSystem * @property [_writable_] boltComponent + * @property [] authority + * @property [] instructionSysvarAccount * @category Instructions * @category Apply * @category generated @@ -46,6 +49,8 @@ export interface ApplyInstructionAccounts { componentProgram: web3.PublicKey; boltSystem: web3.PublicKey; boltComponent: web3.PublicKey; + authority?: web3.PublicKey; + instructionSysvarAccount?: web3.PublicKey; anchorRemainingAccounts?: web3.AccountMeta[]; } @@ -88,6 +93,16 @@ export function createApplyInstruction( isWritable: true, isSigner: false, }, + { + pubkey: accounts.authority ?? programId, + isWritable: false, + isSigner: false, + }, + { + pubkey: accounts.instructionSysvarAccount ?? SYSVAR_INSTRUCTIONS_PUBKEY, + isWritable: false, + isSigner: false, + }, ]; if (accounts.anchorRemainingAccounts != null) { diff --git a/clients/bolt-sdk/src/generated/instructions/apply2.ts b/clients/bolt-sdk/src/generated/instructions/apply2.ts index 54ca8c1..ab94334 100644 --- a/clients/bolt-sdk/src/generated/instructions/apply2.ts +++ b/clients/bolt-sdk/src/generated/instructions/apply2.ts @@ -7,6 +7,7 @@ import * as beet from "@metaplex-foundation/beet"; import * as web3 from "@solana/web3.js"; +import { SYSVAR_INSTRUCTIONS_PUBKEY } from "../index"; /** * @category Instructions @@ -40,6 +41,8 @@ export const apply2Struct = new beet.FixableBeetArgsStruct< * @property [_writable_] boltComponent1 * @property [] componentProgram2 * @property [_writable_] boltComponent2 + * @property [] authority + * @property [] instructionSysvarAccount * @category Instructions * @category Apply2 * @category generated @@ -50,6 +53,8 @@ export interface Apply2InstructionAccounts { boltComponent1: web3.PublicKey; componentProgram2: web3.PublicKey; boltComponent2: web3.PublicKey; + authority?: web3.PublicKey; + instructionSysvarAccount?: web3.PublicKey; anchorRemainingAccounts?: web3.AccountMeta[]; } @@ -102,6 +107,16 @@ export function createApply2Instruction( isWritable: true, isSigner: false, }, + { + pubkey: accounts.authority ?? programId, + isWritable: false, + isSigner: false, + }, + { + pubkey: accounts.instructionSysvarAccount ?? SYSVAR_INSTRUCTIONS_PUBKEY, + isWritable: false, + isSigner: false, + }, ]; if (accounts.anchorRemainingAccounts != null) { diff --git a/clients/bolt-sdk/src/generated/instructions/apply3.ts b/clients/bolt-sdk/src/generated/instructions/apply3.ts index 5dca4c7..75ec6de 100644 --- a/clients/bolt-sdk/src/generated/instructions/apply3.ts +++ b/clients/bolt-sdk/src/generated/instructions/apply3.ts @@ -7,6 +7,7 @@ import * as beet from "@metaplex-foundation/beet"; import * as web3 from "@solana/web3.js"; +import { SYSVAR_INSTRUCTIONS_PUBKEY } from "../index"; /** * @category Instructions @@ -42,6 +43,8 @@ export const apply3Struct = new beet.FixableBeetArgsStruct< * @property [_writable_] boltComponent2 * @property [] componentProgram3 * @property [_writable_] boltComponent3 + * @property [] authority + * @property [] instructionSysvarAccount * @category Instructions * @category Apply3 * @category generated @@ -54,6 +57,8 @@ export interface Apply3InstructionAccounts { boltComponent2: web3.PublicKey; componentProgram3: web3.PublicKey; boltComponent3: web3.PublicKey; + authority?: web3.PublicKey; + instructionSysvarAccount?: web3.PublicKey; anchorRemainingAccounts?: web3.AccountMeta[]; } @@ -116,6 +121,16 @@ export function createApply3Instruction( isWritable: true, isSigner: false, }, + { + pubkey: accounts.authority ?? programId, + isWritable: false, + isSigner: false, + }, + { + pubkey: accounts.instructionSysvarAccount ?? SYSVAR_INSTRUCTIONS_PUBKEY, + isWritable: false, + isSigner: false, + }, ]; if (accounts.anchorRemainingAccounts != null) { diff --git a/clients/bolt-sdk/src/generated/instructions/initializeComponent.ts b/clients/bolt-sdk/src/generated/instructions/initializeComponent.ts index 6e0303f..4656380 100644 --- a/clients/bolt-sdk/src/generated/instructions/initializeComponent.ts +++ b/clients/bolt-sdk/src/generated/instructions/initializeComponent.ts @@ -7,6 +7,7 @@ import * as beet from "@metaplex-foundation/beet"; import * as web3 from "@solana/web3.js"; +import { SYSVAR_INSTRUCTIONS_PUBKEY } from "../index"; /** * @category Instructions @@ -26,6 +27,8 @@ export const initializeComponentStruct = new beet.BeetArgsStruct<{ * @property [_writable_] data * @property [] entity * @property [] componentProgram + * @property [] authority + * @property [] instructionSysvarAccount * @category Instructions * @category InitializeComponent * @category generated @@ -35,6 +38,8 @@ export interface InitializeComponentInstructionAccounts { data: web3.PublicKey; entity: web3.PublicKey; componentProgram: web3.PublicKey; + authority?: web3.PublicKey; + instructionSysvarAccount?: web3.PublicKey; systemProgram?: web3.PublicKey; anchorRemainingAccounts?: web3.AccountMeta[]; } @@ -79,6 +84,16 @@ export function createInitializeComponentInstruction( isWritable: false, isSigner: false, }, + { + pubkey: accounts.authority ?? programId, + isWritable: false, + isSigner: false, + }, + { + pubkey: accounts.instructionSysvarAccount ?? SYSVAR_INSTRUCTIONS_PUBKEY, + isWritable: false, + isSigner: false, + }, { pubkey: accounts.systemProgram ?? web3.SystemProgram.programId, isWritable: false, diff --git a/crates/bolt-helpers/Cargo.toml b/crates/bolt-helpers/Cargo.toml index a31b5fb..c65d85c 100644 --- a/crates/bolt-helpers/Cargo.toml +++ b/crates/bolt-helpers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bolt-helpers" -version = "0.1.0" +version = "0.0.1" edition = "2021" [dependencies] \ No newline at end of file diff --git a/crates/bolt-helpers/attribute/system-template/Cargo.toml b/crates/bolt-helpers/attribute/system-template/Cargo.toml index e122df5..a096842 100644 --- a/crates/bolt-helpers/attribute/system-template/Cargo.toml +++ b/crates/bolt-helpers/attribute/system-template/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bolt-helpers-system-template" -version = "0.1.0" +version = "0.0.1" edition = "2021" [lib] diff --git a/crates/bolt-helpers/attribute/system-template/src/lib.rs b/crates/bolt-helpers/attribute/system-template/src/lib.rs index 331982d..cb8a712 100644 --- a/crates/bolt-helpers/attribute/system-template/src/lib.rs +++ b/crates/bolt-helpers/attribute/system-template/src/lib.rs @@ -6,8 +6,6 @@ use syn::parse::{Parse, ParseStream, Result}; use syn::{parse_macro_input, Ident, LitInt, Token}; /// This macro attribute is a helper used for defining BOLT systems execute proxy instructions. -/// -/// ``` #[proc_macro_attribute] pub fn system_template(attr: TokenStream, item: TokenStream) -> TokenStream { let attr_p = parse_macro_input!(attr as SystemTemplateInput); @@ -20,7 +18,7 @@ pub fn system_template(attr: TokenStream, item: TokenStream) -> TokenStream { // Generate a function for execute instruction let funcs = (2..=max_components).map(|i| { let func_name = syn::Ident::new(&format!("execute_{}", i), proc_macro2::Span::call_site()); - let data_struct = syn::Ident::new("SetData", proc_macro2::Span::call_site()); + let data_struct = syn::Ident::new(&format!("SetData{}", i), proc_macro2::Span::call_site()); let return_values = vec![quote!(Vec::::new()); i]; let return_types = vec![quote!(Vec); i]; quote! { @@ -49,11 +47,11 @@ pub fn system_template(attr: TokenStream, item: TokenStream) -> TokenStream { quote! { #[account()] /// CHECK: unchecked account - pub #field_name: anchor_lang::prelude::UncheckedAccount<'info>, + pub #field_name: UncheckedAccount<'info>, } }); let struct_def = quote! { - #[derive(Accounts, BorshDeserialize, BorshSerialize, Clone)] + #[derive(Accounts)] pub struct #data_struct<'info> { #(#fields)* } diff --git a/crates/bolt-helpers/attribute/world-apply/Cargo.toml b/crates/bolt-helpers/attribute/world-apply/Cargo.toml new file mode 100644 index 0000000..827779a --- /dev/null +++ b/crates/bolt-helpers/attribute/world-apply/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "bolt-helpers-world-apply" +version = "0.0.1" +edition = "2021" + +[lib] +proc-macro = true + +[dependencies] +proc-macro2 = "1.0" +quote = "1.0" +syn = "1.0" \ No newline at end of file diff --git a/crates/bolt-helpers/attribute/world-apply/src/lib.rs b/crates/bolt-helpers/attribute/world-apply/src/lib.rs new file mode 100644 index 0000000..0c6da23 --- /dev/null +++ b/crates/bolt-helpers/attribute/world-apply/src/lib.rs @@ -0,0 +1,150 @@ +extern crate proc_macro; + +use proc_macro::TokenStream; +use quote::quote; +use syn::parse::{Parse, ParseStream, Result}; +use syn::{parse_macro_input, Ident, LitInt, Token}; + +/// This macro attribute is a helper used for defining BOLT apply proxy instructions. +#[proc_macro_attribute] +pub fn apply_system(attr: TokenStream, item: TokenStream) -> TokenStream { + let attr_p = parse_macro_input!(attr as SystemTemplateInput); + + let max_components = attr_p.max_components; + + // Parse the original module content + let mut input: syn::ItemMod = syn::parse(item).expect("Failed to parse input module"); + + // Generate a function for execute instruction + let funcs = (2..=max_components).map(|i| { + let apply_func_name = syn::Ident::new(&format!("apply{}", i), proc_macro2::Span::call_site()); + let execute_func_name = syn::Ident::new(&format!("execute_{}", i), proc_macro2::Span::call_site()); + let data_struct = syn::Ident::new(&format!("ApplySystem{}", i), proc_macro2::Span::call_site()); + + let updates = (1..=i).enumerate().map(|(index, n)| { + let component_program_name = syn::Ident::new(&format!("component_program_{}", n), proc_macro2::Span::call_site()); + let bolt_component_name = syn::Ident::new(&format!("bolt_component_{}", n), proc_macro2::Span::call_site()); + + quote! { + let update_result = bolt_component::cpi::update( + build_update_context( + ctx.accounts.#component_program_name.clone(), + ctx.accounts.#bolt_component_name.clone(), + ctx.accounts.authority.clone(), + ctx.accounts.instruction_sysvar_account.clone(), + ), + res[#index].to_owned() + )?; + } + }); + + quote! { + pub fn #apply_func_name(ctx: Context<#data_struct>, args: Vec) -> Result<()> { + if !ctx.accounts.authority.is_signer && ctx.accounts.authority.key != &ID { + return Err(WorldError::InvalidAuthority.into()); + } + let res = bolt_system::cpi::#execute_func_name(ctx.accounts.build(), args)?.get().to_vec(); + #(#updates)* + Ok(()) + } + } + }); + + // Append each generated function to the module's items + if let Some((brace, mut content)) = input.content.take() { + for func in funcs { + let parsed_func: syn::Item = + syn::parse2(func).expect("Failed to parse generated function"); + content.push(parsed_func); + } + + input.content = Some((brace, content)); + } + + let data_def = (2..=max_components).map(|i| { + let data_struct = + syn::Ident::new(&format!("ApplySystem{}", i), proc_macro2::Span::call_site()); + let fields = (1..=i).map(|n| { + let component_program_name = syn::Ident::new( + &format!("component_program_{}", n), + proc_macro2::Span::call_site(), + ); + let component_name = syn::Ident::new( + &format!("bolt_component_{}", n), + proc_macro2::Span::call_site(), + ); + quote! { + /// CHECK: bolt component program check + pub #component_program_name: UncheckedAccount<'info>, + #[account(mut)] + /// CHECK: component account + pub #component_name: UncheckedAccount<'info>, + } + }); + let struct_def = quote! { + #[derive(Accounts)] + pub struct #data_struct<'info> { + /// CHECK: bolt system program check + pub bolt_system: UncheckedAccount<'info>, + #(#fields)* + /// CHECK: authority check + pub authority: UncheckedAccount<'info>, + #[account(address = anchor_lang::solana_program::sysvar::instructions::id())] + /// CHECK: instruction sysvar check + pub instruction_sysvar_account: UncheckedAccount<'info>, + } + }; + quote! { + #struct_def + } + }); + + let impl_build_def = (2..=max_components).map(|i| { + let data_struct = syn::Ident::new(&format!("ApplySystem{}", i), proc_macro2::Span::call_site()); + let set_data_struct = syn::Ident::new(&format!("SetData{}", i), proc_macro2::Span::call_site()); + let fields: Vec<_> = (1..=i).map(|n| { + let component_key = syn::Ident::new(&format!("component{}", n), proc_macro2::Span::call_site()); + let component_name = syn::Ident::new(&format!("bolt_component_{}", n), proc_macro2::Span::call_site()); + quote! { + #component_key: self.#component_name.to_account_info(), + } + }).collect(); + quote! { + impl<'info> #data_struct<'info> { + pub fn build(&self) -> CpiContext<'_, '_, '_, 'info, bolt_system::cpi::accounts::#set_data_struct<'info>> { + let cpi_program = self.bolt_system.to_account_info(); + let cpi_accounts = bolt_system::cpi::accounts::#set_data_struct { + #(#fields)* + }; + CpiContext::new(cpi_program, cpi_accounts) + } + } + } + }); + + // Return the modified module + let output = quote! { + #input + #(#data_def)* + #(#impl_build_def)* + }; + output.into() +} + +// Define a struct to parse macro input +struct SystemTemplateInput { + max_components: usize, +} + +// Implement parsing for the macro input +impl Parse for SystemTemplateInput { + fn parse(input: ParseStream) -> Result { + let _ = input.parse::()?; // Parse the key (e.g., "max_components") + let _ = input.parse::()?; // Parse the '=' + let max_components: LitInt = input.parse()?; // Parse the value + let max_value = max_components.base10_parse()?; + Ok(SystemTemplateInput { + max_components: max_value, + }) + } +} diff --git a/crates/bolt-lang/Cargo.toml b/crates/bolt-lang/Cargo.toml index b531dd3..e12179d 100644 --- a/crates/bolt-lang/Cargo.toml +++ b/crates/bolt-lang/Cargo.toml @@ -9,10 +9,12 @@ license = "MIT" anchor-lang = { version = "0.29.0"} # Bolt Attributes +bolt-attribute-bolt-program = { path = "./attribute/bolt-program", version = "0.0.1" } bolt-attribute-bolt-component = { path = "./attribute/component", version = "0.0.1" } -bolt-attribute-bolt-account = { path = "./attribute/account", version = "0.0.1" } bolt-attribute-bolt-system = { path = "./attribute/system", version = "0.0.1" } +bolt-attribute-bolt-system-input = { path = "./attribute/system-input", version = "0.0.1" } bolt-attribute-bolt-component-deserialize = { path = "./attribute/component-deserialize", version = "0.0.1" } +bolt-attribute-bolt-component-id = { path = "./attribute/component-id", version = "0.0.1" } # Bolt Programs world = { path = "../../programs/world", features = ["cpi"], version = "0.0.1"} diff --git a/crates/bolt-lang/attribute/account/src/lib.rs b/crates/bolt-lang/attribute/account/src/lib.rs deleted file mode 100644 index 57856bc..0000000 --- a/crates/bolt-lang/attribute/account/src/lib.rs +++ /dev/null @@ -1,75 +0,0 @@ -use proc_macro::TokenStream; -use quote::quote; -use syn::{parse_macro_input, parse_quote, Attribute, DeriveInput, Lit, Meta, NestedMeta}; - -/// This BoltAccount attribute is used to automatically generate the seed and size functions -/// -/// The component_id define the seed used to generate the PDA which stores the component data. -/// The macro also adds the InitSpace and Default derives to the struct. -/// -/// #[account] -/// #[bolt_account] -/// pub struct Position { -/// pub x: i64, -/// pub y: i64, -/// pub z: i64, -/// } -/// ``` -#[proc_macro_attribute] -pub fn bolt_account(attr: TokenStream, item: TokenStream) -> TokenStream { - let mut input = parse_macro_input!(item as DeriveInput); - let mut component_id_value = None; - - if !attr.is_empty() { - let attr_meta = parse_macro_input!(attr as Meta); - - component_id_value = match attr_meta { - Meta::Path(_) => None, - Meta::NameValue(meta_name_value) if meta_name_value.path.is_ident("component_id") => { - if let Lit::Str(lit) = meta_name_value.lit { - Some(lit.value()) - } else { - None - } - } - Meta::List(meta) => meta.nested.into_iter().find_map(|nested_meta| { - if let NestedMeta::Meta(Meta::NameValue(meta_name_value)) = nested_meta { - if meta_name_value.path.is_ident("component_id") { - if let Lit::Str(lit) = meta_name_value.lit { - Some(lit.value()) - } else { - None - } - } else { - None - } - } else { - None - } - }), - _ => None, - }; - } - - let component_id_value = component_id_value.unwrap_or_else(|| "".to_string()); - - let additional_derives: Attribute = parse_quote! { #[derive(InitSpace, Default)] }; - input.attrs.push(additional_derives); - - let name = &input.ident; - let expanded = quote! { - #input - - #[automatically_derived] - impl ComponentTraits for #name { - fn seed() -> &'static [u8] { - #component_id_value.as_bytes() - } - - fn size() -> usize { - 8 + <#name>::INIT_SPACE - } - } - }; - expanded.into() -} diff --git a/crates/bolt-lang/attribute/bolt-program/Cargo.toml b/crates/bolt-lang/attribute/bolt-program/Cargo.toml new file mode 100644 index 0000000..dad43f0 --- /dev/null +++ b/crates/bolt-lang/attribute/bolt-program/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "bolt-attribute-bolt-program" +version = "0.0.1" +edition = "2021" +description = "Bolt attribute-bolt-program" +license = "MIT" + +[lib] +proc-macro = true + +[dependencies] +syn = { version = "1.0", features = ["full"] } +quote = "1.0" +proc-macro2 = "1.0" diff --git a/crates/bolt-lang/attribute/bolt-program/src/lib.rs b/crates/bolt-lang/attribute/bolt-program/src/lib.rs new file mode 100644 index 0000000..955ae1e --- /dev/null +++ b/crates/bolt-lang/attribute/bolt-program/src/lib.rs @@ -0,0 +1,186 @@ +use proc_macro::TokenStream; +use proc_macro2::TokenStream as TokenStream2; +use quote::{quote, ToTokens}; +use syn::{ + parse_macro_input, parse_quote, Attribute, AttributeArgs, Field, Fields, ItemMod, ItemStruct, + NestedMeta, Type, +}; + +/// This macro attribute is used to define a BOLT component. +/// +/// Bolt components are themselves programs that can be called by other programs. +/// +/// # Example +/// ```ignore +/// #[bolt_program(Position)] +/// #[program] +/// pub mod component_position { +/// use super::*; +/// } +/// +/// #[account] +/// #[component] +/// pub struct Position { +/// pub x: i64, +/// pub y: i64, +/// pub z: i64, +/// } +/// ``` +#[proc_macro_attribute] +pub fn bolt_program(args: TokenStream, input: TokenStream) -> TokenStream { + let ast = parse_macro_input!(input as syn::ItemMod); + let args = parse_macro_input!(args as syn::AttributeArgs); + let component_type = + extract_type_name(&args).expect("Expected a component type in macro arguments"); + let modified = modify_component_module(ast, &component_type); + let additional_macro: Attribute = parse_quote! { #[program] }; + TokenStream::from(quote! { + #additional_macro + #modified + }) +} + +/// Modifies the component module and adds the necessary functions and structs. +fn modify_component_module(mut module: ItemMod, component_type: &Type) -> ItemMod { + let (initialize_fn, initialize_struct) = generate_initialize(component_type); + //let (apply_fn, apply_struct, apply_impl, update_fn, update_struct) = generate_instructions(component_type); + let (update_fn, update_struct) = generate_update(component_type); + + module.content = module.content.map(|(brace, mut items)| { + items.extend( + vec![initialize_fn, initialize_struct, update_fn, update_struct] + .into_iter() + .map(|item| syn::parse2(item).unwrap()) + .collect::>(), + ); + + let modified_items = items + .into_iter() + .map(|item| match item { + syn::Item::Struct(mut struct_item) if struct_item.ident == "Apply" => { + modify_apply_struct(&mut struct_item); + syn::Item::Struct(struct_item) + } + _ => item, + }) + .collect(); + (brace, modified_items) + }); + + module +} + +/// Extracts the type name from attribute arguments. +fn extract_type_name(args: &AttributeArgs) -> Option { + args.iter().find_map(|arg| { + if let NestedMeta::Meta(syn::Meta::Path(path)) = arg { + Some(Type::Path(syn::TypePath { + qself: None, + path: path.clone(), + })) + } else { + None + } + }) +} + +/// Modifies the Apply struct, change the bolt system to accept any compatible system. +fn modify_apply_struct(struct_item: &mut ItemStruct) { + if let Fields::Named(fields_named) = &mut struct_item.fields { + fields_named + .named + .iter_mut() + .filter(|field| is_expecting_program(field)) + .for_each(|field| { + field.ty = syn::parse_str("UncheckedAccount<'info>").expect("Failed to parse type"); + field.attrs.push(create_check_attribute()); + }); + } +} + +/// Creates the check attribute. +fn create_check_attribute() -> Attribute { + parse_quote! { + #[doc = "CHECK: This program can modify the data of the component"] + } +} + +/// Generates the initialize function and struct. +fn generate_initialize(component_type: &Type) -> (TokenStream2, TokenStream2) { + ( + quote! { + #[automatically_derived] + pub fn initialize(ctx: Context) -> Result<()> { + let instruction = anchor_lang::solana_program::sysvar::instructions::get_instruction_relative( + 0, &ctx.accounts.instruction_sysvar_account.to_account_info() + ).unwrap(); + if instruction.program_id != World::id() { + return Err(BoltError::InvalidCaller.into()); + } + ctx.accounts.data.set_inner(<#component_type>::default()); + ctx.accounts.data.bolt_metadata.authority = *ctx.accounts.authority.key; + Ok(()) + } + }, + quote! { + #[automatically_derived] + #[derive(Accounts)] + pub struct Initialize<'info> { + #[account(mut)] + pub payer: Signer<'info>, + #[account(init_if_needed, payer = payer, space = <#component_type>::size(), seeds = [<#component_type>::seed(), entity.key().as_ref()], bump)] + pub data: Account<'info, #component_type>, + #[account()] + pub entity: Account<'info, Entity>, + #[account()] + pub authority: AccountInfo<'info>, + #[account(address = anchor_lang::solana_program::sysvar::instructions::id())] + pub instruction_sysvar_account: UncheckedAccount<'info>, + pub system_program: Program<'info, System>, + } + }, + ) +} + +/// Generates the instructions and related structs to inject in the component. +fn generate_update(component_type: &Type) -> (TokenStream2, TokenStream2) { + ( + quote! { + #[automatically_derived] + pub fn update(ctx: Context, data: Vec) -> Result<()> { + // Check if the instruction is called from the world program + let instruction = anchor_lang::solana_program::sysvar::instructions::get_instruction_relative( + 0, &ctx.accounts.instruction_sysvar_account.to_account_info() + ).unwrap(); + if instruction.program_id != World::id() { + return Err(BoltError::InvalidCaller.into()); + } + // Check if the authority is authorized to modify the data + if ctx.accounts.bolt_component.bolt_metadata.authority != World::id() && ctx.accounts.bolt_component.bolt_metadata.authority != *ctx.accounts.authority.key { + return Err(BoltError::InvalidAuthority.into()); + } + + ctx.accounts.bolt_component.set_inner(<#component_type>::try_from_slice(&data)?); + Ok(()) + } + }, + quote! { + #[automatically_derived] + #[derive(Accounts)] + pub struct Update<'info> { + #[account(mut)] + pub bolt_component: Account<'info, #component_type>, + #[account()] + /// CHECK: The authority of the component + pub authority: AccountInfo<'info>, + #[account(address = anchor_lang::solana_program::sysvar::instructions::id())] + pub instruction_sysvar_account: UncheckedAccount<'info>, + } + }, + ) +} + +/// Checks if the field is expecting a program. +fn is_expecting_program(field: &Field) -> bool { + field.ty.to_token_stream().to_string().contains("Program") +} diff --git a/crates/bolt-lang/attribute/component-deserialize/Cargo.toml b/crates/bolt-lang/attribute/component-deserialize/Cargo.toml index dbe8d25..70c768e 100644 --- a/crates/bolt-lang/attribute/component-deserialize/Cargo.toml +++ b/crates/bolt-lang/attribute/component-deserialize/Cargo.toml @@ -10,5 +10,6 @@ proc-macro = true [dependencies] syn = { version = "1.0", features = ["full"] } +bolt-utils = { path = "../../utils", version = "0.0.1" } quote = "1.0" proc-macro2 = "1.0" diff --git a/crates/bolt-lang/attribute/component-deserialize/src/lib.rs b/crates/bolt-lang/attribute/component-deserialize/src/lib.rs index 640af4d..87a3aba 100644 --- a/crates/bolt-lang/attribute/component-deserialize/src/lib.rs +++ b/crates/bolt-lang/attribute/component-deserialize/src/lib.rs @@ -1,7 +1,18 @@ +use bolt_utils::add_bolt_metadata; use proc_macro::TokenStream; use quote::quote; use syn::{parse_macro_input, Attribute, DeriveInput}; +/// This macro is used to defined a struct as a BOLT component and automatically implements the +/// `ComponentDeserialize` and `AccountDeserialize` traits for the struct. +/// +/// #[component] +/// pub struct Position { +/// pub x: i64, +/// pub y: i64, +/// pub z: i64, +/// } +/// ``` #[proc_macro_attribute] pub fn component_deserialize(_attr: TokenStream, item: TokenStream) -> TokenStream { let mut input = parse_macro_input!(item as DeriveInput); @@ -10,6 +21,8 @@ pub fn component_deserialize(_attr: TokenStream, item: TokenStream) -> TokenStre let additional_derives: Attribute = syn::parse_quote! { #[derive(anchor_lang::AnchorDeserialize, anchor_lang::AnchorSerialize)] }; input.attrs.push(additional_derives); + add_bolt_metadata(&mut input); + let name = &input.ident; let expanded = quote! { #input diff --git a/crates/bolt-lang/attribute/account/Cargo.toml b/crates/bolt-lang/attribute/component-id/Cargo.toml similarity index 66% rename from crates/bolt-lang/attribute/account/Cargo.toml rename to crates/bolt-lang/attribute/component-id/Cargo.toml index d1b6eeb..c630766 100644 --- a/crates/bolt-lang/attribute/account/Cargo.toml +++ b/crates/bolt-lang/attribute/component-id/Cargo.toml @@ -1,8 +1,8 @@ [package] -name = "bolt-attribute-bolt-account" +name = "bolt-attribute-bolt-component-id" version = "0.0.1" edition = "2021" -description = "Bolt attribute-bolt-account" +description = "Bolt attribute-bolt-component-id" license = "MIT" [lib] diff --git a/crates/bolt-lang/attribute/component-id/src/lib.rs b/crates/bolt-lang/attribute/component-id/src/lib.rs new file mode 100644 index 0000000..2217bec --- /dev/null +++ b/crates/bolt-lang/attribute/component-id/src/lib.rs @@ -0,0 +1,15 @@ +use proc_macro::TokenStream; +use quote::quote; +use syn::{parse_macro_input, DeriveInput}; + +/// Macro to specify the on-chain ID of a component. +/// +/// ``` +#[proc_macro_attribute] +pub fn component_id(_attr: TokenStream, item: TokenStream) -> TokenStream { + let input = parse_macro_input!(item as DeriveInput); + let expanded = quote! { + #input + }; + TokenStream::from(expanded) +} diff --git a/crates/bolt-lang/attribute/component/Cargo.toml b/crates/bolt-lang/attribute/component/Cargo.toml index 4d98c45..d485e39 100644 --- a/crates/bolt-lang/attribute/component/Cargo.toml +++ b/crates/bolt-lang/attribute/component/Cargo.toml @@ -10,5 +10,6 @@ proc-macro = true [dependencies] syn = { version = "1.0", features = ["full"] } +bolt-utils = { path = "../../utils", version = "0.0.1" } quote = "1.0" -proc-macro2 = "1.0" +proc-macro2 = "1.0" \ No newline at end of file diff --git a/crates/bolt-lang/attribute/component/src/lib.rs b/crates/bolt-lang/attribute/component/src/lib.rs index cdc8256..4ee1b7e 100644 --- a/crates/bolt-lang/attribute/component/src/lib.rs +++ b/crates/bolt-lang/attribute/component/src/lib.rs @@ -1,25 +1,15 @@ +use bolt_utils::add_bolt_metadata; use proc_macro::TokenStream; -use proc_macro2::TokenStream as TokenStream2; -use quote::{quote, ToTokens}; -use syn::{ - parse_macro_input, parse_quote, Attribute, AttributeArgs, Field, Fields, ItemMod, ItemStruct, - NestedMeta, Type, -}; +use quote::quote; +use syn::{parse_macro_input, parse_quote, Attribute, DeriveInput, Lit, Meta, NestedMeta}; -/// This macro attribute is used to define a BOLT component. +/// This Component attribute is used to automatically generate the seed and size functions /// -/// Bolt components are themselves programs that can be called by other programs. +/// The component_id can be used to define the seed used to generate the PDA which stores the component data. +/// The macro also adds the InitSpace and Default derives to the struct. /// -/// # Example -/// ```ignore -/// #[component(Position)] -/// #[program] -/// pub mod component_position { -/// use super::*; -/// } -/// -/// #[account] -/// #[bolt_account] +/// #[component_deserialize] +/// #[derive(Clone)] /// pub struct Position { /// pub x: i64, /// pub y: i64, @@ -27,128 +17,75 @@ use syn::{ /// } /// ``` #[proc_macro_attribute] -pub fn component(args: TokenStream, input: TokenStream) -> TokenStream { - let ast = parse_macro_input!(input as syn::ItemMod); - let args = parse_macro_input!(args as syn::AttributeArgs); - let component_type = - extract_type_name(&args).expect("Expected a component type in macro arguments"); - let modified = modify_component_module(ast, &component_type); - TokenStream::from(quote! { #modified }) -} +pub fn component(attr: TokenStream, item: TokenStream) -> TokenStream { + let mut input = parse_macro_input!(item as DeriveInput); + let mut component_id_value = None; -/// Modifies the component module and adds the necessary functions and structs. -fn modify_component_module(mut module: ItemMod, component_type: &Type) -> ItemMod { - let (initialize_fn, initialize_struct) = generate_initialize(component_type); - //let (apply_fn, apply_struct, apply_impl, update_fn, update_struct) = generate_instructions(component_type); - let (update_fn, update_struct) = generate_update(component_type); + if !attr.is_empty() { + let attr_meta = parse_macro_input!(attr as Meta); - module.content = module.content.map(|(brace, mut items)| { - items.extend( - vec![initialize_fn, initialize_struct, update_fn, update_struct] - .into_iter() - .map(|item| syn::parse2(item).unwrap()) - .collect::>(), - ); - - let modified_items = items - .into_iter() - .map(|item| match item { - syn::Item::Struct(mut struct_item) if struct_item.ident == "Apply" => { - modify_apply_struct(&mut struct_item); - syn::Item::Struct(struct_item) + component_id_value = match attr_meta { + Meta::Path(_) => None, + Meta::NameValue(meta_name_value) if meta_name_value.path.is_ident("component_id") => { + if let Lit::Str(lit) = meta_name_value.lit { + Some(lit.value()) + } else { + None + } + } + Meta::List(meta) => meta.nested.into_iter().find_map(|nested_meta| { + if let NestedMeta::Meta(Meta::NameValue(meta_name_value)) = nested_meta { + if meta_name_value.path.is_ident("component_id") { + if let Lit::Str(lit) = meta_name_value.lit { + Some(lit.value()) + } else { + None + } + } else { + None + } + } else { + None } - _ => item, - }) - .collect(); - (brace, modified_items) - }); + }), + _ => None, + }; + } - module -} + let component_id_value = component_id_value.unwrap_or_else(|| "".to_string()); + + let additional_macro: Attribute = parse_quote! { #[account] }; + let additional_derives: Attribute = parse_quote! { #[derive(InitSpace, Default)] }; + input.attrs.push(additional_derives); + + add_bolt_metadata(&mut input); + + let name = &input.ident; + let component_name = syn::Ident::new(&name.to_string().to_lowercase(), input.ident.span()); -/// Extracts the type name from attribute arguments. -fn extract_type_name(args: &AttributeArgs) -> Option { - args.iter().find_map(|arg| { - if let NestedMeta::Meta(syn::Meta::Path(path)) = arg { - Some(Type::Path(syn::TypePath { - qself: None, - path: path.clone(), - })) - } else { - None + let anchor_program = quote! { + #[bolt_program(#name)] + pub mod #component_name { + use super::*; } - }) -} + }; -/// Modifies the Apply struct, change the bolt system to accept any compatible system. -fn modify_apply_struct(struct_item: &mut ItemStruct) { - if let Fields::Named(fields_named) = &mut struct_item.fields { - fields_named - .named - .iter_mut() - .filter(|field| is_expecting_program(field)) - .for_each(|field| { - field.ty = syn::parse_str("UncheckedAccount<'info>").expect("Failed to parse type"); - field.attrs.push(create_check_attribute()); - }); - } -} + let expanded = quote! { + #anchor_program -/// Creates the check attribute. -fn create_check_attribute() -> Attribute { - parse_quote! { - #[doc = "CHECK: This program can modify the data of the component"] - } -} + #additional_macro + #input -/// Generates the initialize function and struct. -fn generate_initialize(component_type: &Type) -> (TokenStream2, TokenStream2) { - ( - quote! { - #[automatically_derived] - pub fn initialize(ctx: Context) -> Result<()> { - ctx.accounts.data.set_inner(<#component_type>::default()); - Ok(()) - } - }, - quote! { - #[automatically_derived] - #[derive(Accounts)] - pub struct Initialize<'info> { - #[account(mut)] - pub payer: Signer<'info>, - #[account(init_if_needed, payer = payer, space = <#component_type>::size(), seeds = [<#component_type>::seed(), entity.key().as_ref()], bump)] - pub data: Account<'info, #component_type>, - #[account()] - pub entity: Account<'info, Entity>, - pub system_program: Program<'info, System>, + #[automatically_derived] + impl ComponentTraits for #name { + fn seed() -> &'static [u8] { + #component_id_value.as_bytes() } - }, - ) -} -/// Generates the instructions and related structs to inject in the component. -fn generate_update(component_type: &Type) -> (TokenStream2, TokenStream2) { - ( - quote! { - #[automatically_derived] - pub fn update(ctx: Context, data: Vec) -> Result<()> { - ctx.accounts.bolt_component.set_inner(<#component_type>::try_from_slice(&data)?); - Ok(()) - } - }, - quote! { - #[automatically_derived] - #[derive(Accounts)] - pub struct Update<'info> { - #[account(mut)] - pub bolt_component: Account<'info, #component_type>, + fn size() -> usize { + 8 + <#name>::INIT_SPACE } - }, - ) -} - -/// Checks if the field is expecting a program. -fn is_expecting_program(field: &Field) -> bool { - field.ty.to_token_stream().to_string().contains("Program") + } + }; + expanded.into() } diff --git a/crates/bolt-lang/attribute/system-input/Cargo.toml b/crates/bolt-lang/attribute/system-input/Cargo.toml new file mode 100644 index 0000000..959f3c8 --- /dev/null +++ b/crates/bolt-lang/attribute/system-input/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "bolt-attribute-bolt-system-input" +version = "0.0.1" +edition = "2021" +description = "Bolt attribute-bolt-system-input" +license = "MIT" + +[lib] +proc-macro = true + +[dependencies] +syn = { version = "1.0", features = ["full", "visit-mut"] } +quote = "1.0" +proc-macro2 = "1.0" \ No newline at end of file diff --git a/crates/bolt-lang/attribute/system-input/src/lib.rs b/crates/bolt-lang/attribute/system-input/src/lib.rs new file mode 100644 index 0000000..bd1a7ac --- /dev/null +++ b/crates/bolt-lang/attribute/system-input/src/lib.rs @@ -0,0 +1,121 @@ +use proc_macro::TokenStream; +use quote::quote; +use syn::{parse_macro_input, Fields, ItemStruct, Lit, Meta, MetaNameValue}; + +/// This macro attribute is used to define a BOLT system input. +/// +/// The input can be defined as a struct and will be transformed into an Anchor context. +/// +/// +/// # Example +/// ```ignore +///#[system_input] +///pub struct Components { +/// pub position: Position, +///} +/// +/// ``` +#[proc_macro_attribute] +pub fn system_input(_attr: TokenStream, item: TokenStream) -> TokenStream { + // Parse the input TokenStream (the struct) into a Rust data structure + let input = parse_macro_input!(item as ItemStruct); + + // Ensure the struct has named fields + let fields = if let Fields::Named(fields) = &input.fields { + &fields.named + } else { + panic!("system_input macro only supports structs with named fields"); + }; + let name = &input.ident; + + // Impls Owner for each account and + let owners_impls = fields.iter().filter_map(|field| { + field.attrs.iter().find_map(|attr| { + if let Ok(Meta::List(meta_list)) = attr.parse_meta() { + if meta_list.path.is_ident("component_id") { + for nested_meta in meta_list.nested.iter() { + if let syn::NestedMeta::Meta(Meta::NameValue(MetaNameValue { + path, + lit: Lit::Str(lit_str), + .. + })) = nested_meta + { + if path.is_ident("address") { + let address = lit_str.value(); + let field_type = &field.ty; + return Some(quote! { + use std::str::FromStr; + impl Owner for #field_type { + + fn owner() -> Pubkey { + Pubkey::from_str(#address).unwrap() + } + } + impl AccountSerialize for #field_type { + fn try_serialize(&self, _writer: &mut W) -> Result<()> { + Ok(()) + } + } + }); + } + } + } + } + } + None + }) + }); + + // Transform fields for the struct definition + let transformed_fields = fields.iter().map(|f| { + let field_name = &f.ident; + let field_type = &f.ty; + quote! { + #[account()] + pub #field_name: Account<'info, #field_type>, + } + }); + + // Generate the new struct with the Accounts derive and transformed fields + let output_struct = quote! { + #[derive(Accounts)] + pub struct #name<'info> { + #(#transformed_fields)* + } + }; + + // Generate the try_to_vec method + let try_to_vec_fields = fields.iter().map(|f| { + let field_name = &f.ident; + quote! { + self.#field_name.try_to_vec()? + } + }); + + let tuple_elements = (0..try_to_vec_fields.len()) + .map(|_| quote! {Vec}) + .collect::>(); + let generated_tuple_type = match tuple_elements.len() { + 0 => panic!("system_input macro only supports structs with named fields"), + 1 => quote! { (Vec,) }, + _ => quote! { (#(#tuple_elements),*) }, + }; + + // Generate the implementation of try_to_vec for the struct + let output_impl = quote! { + impl<'info> #name<'info> { + pub fn try_to_vec(&self) -> Result<#generated_tuple_type> { + Ok((#(#try_to_vec_fields,)*)) + } + } + }; + + // Combine the struct definition and its implementation into the final TokenStream + let output = quote! { + #output_struct + #output_impl + #(#owners_impls)* + }; + + TokenStream::from(output) +} diff --git a/crates/bolt-lang/attribute/system/src/lib.rs b/crates/bolt-lang/attribute/system/src/lib.rs index e69e0f6..f68a7a7 100644 --- a/crates/bolt-lang/attribute/system/src/lib.rs +++ b/crates/bolt-lang/attribute/system/src/lib.rs @@ -2,11 +2,20 @@ use proc_macro::TokenStream; use proc_macro2::Ident; use quote::quote; use syn::{ - parse_macro_input, parse_quote, visit_mut::VisitMut, Expr, GenericArgument, ItemFn, ItemMod, - PathArguments, ReturnType, Stmt, Type, TypePath, + parse_macro_input, parse_quote, visit_mut::VisitMut, Expr, FnArg, GenericArgument, ItemFn, + ItemMod, ItemStruct, PathArguments, ReturnType, Stmt, Type, TypePath, }; -struct SystemTransform; +#[derive(Default)] +struct SystemTransform { + return_values: usize, +} + +#[derive(Default)] +struct Extractor { + context_struct_name: Option, + field_count: Option, +} /// This macro attribute is used to define a BOLT system. /// @@ -15,10 +24,7 @@ struct SystemTransform; /// # Example /// ```ignore /// #[system] -/// #[program] /// pub mod system_fly { -/// use super::*; -/// /// pub fn execute(ctx: Context, _args: Vec) -> Result { /// let pos = Position { /// x: ctx.accounts.position.x, @@ -31,11 +37,37 @@ struct SystemTransform; /// ``` #[proc_macro_attribute] pub fn system(attr: TokenStream, item: TokenStream) -> TokenStream { - let mut input = parse_macro_input!(item as ItemMod); + let mut ast = parse_macro_input!(item as ItemMod); let _attr = parse_macro_input!(attr as syn::AttributeArgs); - let mut transform = SystemTransform; - transform.visit_item_mod_mut(&mut input); - TokenStream::from(quote! { #input }) + + // Extract the number of components from the module + let mut extractor = Extractor::default(); + extractor.visit_item_mod_mut(&mut ast); + + if let Some(components_len) = extractor.field_count { + let use_super = syn::parse_quote! { use super::*; }; + if let Some(ref mut content) = ast.content { + content.1.insert(0, syn::Item::Use(use_super)); + } + + let mut transform = SystemTransform { + return_values: components_len, + }; + transform.visit_item_mod_mut(&mut ast); + + // Add `#[program]` macro and try_to_vec implementation + let expanded = quote! { + #[program] + #ast + }; + + TokenStream::from(expanded) + } else { + panic!( + "Could not find the component bundle: {} in the module", + extractor.context_struct_name.unwrap() + ); + } } /// Visits the AST and modifies the system function @@ -51,28 +83,29 @@ impl VisitMut for SystemTransform { parse_quote! { Ok((#(#tuple_elements),*)) } } _ => { - parse_quote! { Ok((#inner_variable).try_to_vec()?) } + parse_quote! { + #inner_variable.try_to_vec() + } } }; *expr = new_return_expr; } } - // Modify the return type of the system function to Result> + // Modify the return type of the system function to Result,*> fn visit_item_fn_mut(&mut self, item_fn: &mut ItemFn) { if item_fn.sig.ident == "execute" { // Modify the return type to Result> if necessary if let ReturnType::Type(_, type_box) = &item_fn.sig.output { if let Type::Path(type_path) = &**type_box { - let ret_values = Self::extract_return_value(type_path); - if ret_values > 1 { + if self.return_values > 1 { item_fn.sig.ident = Ident::new( - format!("execute_{}", ret_values).as_str(), + format!("execute_{}", self.return_values).as_str(), item_fn.sig.ident.span(), ); } if !Self::check_is_vec_u8(type_path) { - Self::modify_fn_return_type(item_fn, ret_values); + Self::modify_fn_return_type(item_fn, self.return_values); // Modify the return statement inside the function body let block = &mut item_fn.block; for stmt in &mut block.stmts { @@ -136,28 +169,10 @@ impl SystemTransform { false } - // Helper function to extract the number of return values from a type - fn extract_return_value(ty: &TypePath) -> usize { - if let Some(segment) = ty.path.segments.last() { - if segment.ident == "Result" { - if let PathArguments::AngleBracketed(args) = &segment.arguments { - return if let Some(GenericArgument::Type(Type::Tuple(tuple))) = - args.args.first() - { - tuple.elems.len() - } else { - 1 - }; - } - } - } - 0 - } - // Helper function to modify the return type of a function to be Result> or Result<(Vec, Vec, ...)> - fn modify_fn_return_type(item_fn: &mut syn::ItemFn, ret_values: usize) { + fn modify_fn_return_type(item_fn: &mut ItemFn, ret_values: usize) { item_fn.sig.output = if ret_values == 1 { - parse_quote! { -> Result> } + parse_quote! { -> Result<(Vec,)> } } else { let types = std::iter::repeat(quote! { Vec }) .take(ret_values) @@ -201,3 +216,34 @@ impl SystemTransform { None } } + +/// Visits the AST to extract the number of input components +impl VisitMut for Extractor { + fn visit_item_fn_mut(&mut self, i: &mut ItemFn) { + for input in &i.sig.inputs { + if let FnArg::Typed(pat_type) = input { + if let Type::Path(type_path) = &*pat_type.ty { + let last_segment = type_path.path.segments.last().unwrap(); + if last_segment.ident == "Context" { + if let PathArguments::AngleBracketed(args) = &last_segment.arguments { + if let Some(syn::GenericArgument::Type(syn::Type::Path(type_path))) = + args.args.first() + { + let ident = &type_path.path.segments.first().unwrap().ident; + self.context_struct_name = Some(ident.to_string()); + } + } + } + } + } + } + } + + fn visit_item_struct_mut(&mut self, i: &mut ItemStruct) { + if let Some(name) = &self.context_struct_name { + if i.ident == name { + self.field_count = Some(i.fields.len()); + } + } + } +} diff --git a/crates/bolt-lang/src/errors.rs b/crates/bolt-lang/src/errors.rs new file mode 100644 index 0000000..6b4fb3f --- /dev/null +++ b/crates/bolt-lang/src/errors.rs @@ -0,0 +1,11 @@ +use anchor_lang::prelude::*; + +#[error_code] +pub enum BoltError { + /// Returned if the wrong authority attempts to sign for an instruction + #[msg("Invalid authority for instruction")] + InvalidAuthority, + /// Returned if the wrong authority attempts to sign for an instruction + #[msg("Invalid caller: must be called from a CPI instruction")] + InvalidCaller, +} diff --git a/crates/bolt-lang/src/lib.rs b/crates/bolt-lang/src/lib.rs index 69f289d..bb658d6 100644 --- a/crates/bolt-lang/src/lib.rs +++ b/crates/bolt-lang/src/lib.rs @@ -1,12 +1,15 @@ pub use anchor_lang::prelude::*; -pub use bolt_attribute_bolt_account::bolt_account; pub use bolt_attribute_bolt_component::component; pub use bolt_attribute_bolt_component_deserialize::component_deserialize; +pub use bolt_attribute_bolt_component_id::component_id; +pub use bolt_attribute_bolt_program::bolt_program; pub use bolt_attribute_bolt_system::system; +pub use bolt_attribute_bolt_system_input::system_input; pub use bolt_system; pub use world; +pub use world::program::World; pub use world::Entity; pub use serde; @@ -14,6 +17,9 @@ pub use serde::{Deserialize as BoltDeserialize, Serialize as BoltSerialize}; use std::str; +mod errors; +pub use crate::errors::BoltError; + /// Parses the arguments from a byte array. pub fn parse_args(args_p: &[u8]) -> T { let args_string = str::from_utf8(args_p).expect("Failed to convert to string"); @@ -36,3 +42,9 @@ pub trait ComponentDeserialize: Sized { /// `Account`. fn from_account_info(account: &anchor_lang::prelude::AccountInfo) -> Result; } + +/// Metadata for the component. +#[derive(InitSpace, AnchorSerialize, AnchorDeserialize, Default, Copy, Clone)] +pub struct BoltMetadata { + pub authority: Pubkey, +} diff --git a/crates/bolt-lang/utils/Cargo.toml b/crates/bolt-lang/utils/Cargo.toml new file mode 100644 index 0000000..255a0bd --- /dev/null +++ b/crates/bolt-lang/utils/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "bolt-utils" +version = "0.0.1" +edition = "2021" +description = "Bolt utils" +license = "MIT" + +[lib] + +[dependencies] +syn = { version = "1.0", features = ["full"] } +quote = "1.0" +proc-macro2 = "1.0" \ No newline at end of file diff --git a/crates/bolt-lang/utils/src/lib.rs b/crates/bolt-lang/utils/src/lib.rs new file mode 100644 index 0000000..1d44e75 --- /dev/null +++ b/crates/bolt-lang/utils/src/lib.rs @@ -0,0 +1,22 @@ +use proc_macro2::Ident; +use syn::{DeriveInput, Field, Type, Visibility}; + +pub fn add_bolt_metadata(input: &mut DeriveInput) { + let authority_field: Field = Field { + attrs: vec![], + vis: Visibility::Public(syn::VisPublic { + pub_token: Default::default(), + }), + ident: Some(Ident::new("bolt_metadata", proc_macro2::Span::call_site())), + colon_token: Some(Default::default()), + ty: Type::Path(syn::TypePath { + qself: None, + path: syn::Path::from(Ident::new("BoltMetadata", proc_macro2::Span::call_site())), + }), + }; + if let syn::Data::Struct(ref mut data) = input.data { + if let syn::Fields::Named(ref mut fields) = data.fields { + fields.named.push(authority_field); + } + } +} diff --git a/examples/component-position/Cargo.toml b/examples/component-position/Cargo.toml index 5ae2d4e..1e72fe6 100644 --- a/examples/component-position/Cargo.toml +++ b/examples/component-position/Cargo.toml @@ -1,12 +1,12 @@ [package] -name = "component-position" -version = "0.1.0" -description = "Created with Anchor" +name = "position" +version = "0.0.1" +description = "Created with Bolt" edition = "2021" [lib] crate-type = ["cdylib", "lib"] -name = "component_position" +name = "position" [features] no-entrypoint = [] @@ -14,6 +14,7 @@ no-idl = [] no-log-ix-name = [] cpi = ["no-entrypoint"] default = [] +idl-build = ["anchor-lang/idl-build"] [dependencies] anchor-lang = { version = "0.29.0" } diff --git a/examples/component-position/src/lib.rs b/examples/component-position/src/lib.rs index e37aa3c..81f8921 100644 --- a/examples/component-position/src/lib.rs +++ b/examples/component-position/src/lib.rs @@ -2,14 +2,7 @@ use bolt_lang::*; declare_id!("Fn1JzzEdyb55fsyduWS94mYHizGhJZuhvjX6DVvrmGbQ"); -#[component(Position)] -#[program] -pub mod component_position { - use super::*; -} - -#[account] -#[bolt_account] +#[component] #[derive(Copy)] pub struct Position { pub x: i64, diff --git a/examples/component-velocity/Cargo.toml b/examples/component-velocity/Cargo.toml index 126e989..3505ff0 100644 --- a/examples/component-velocity/Cargo.toml +++ b/examples/component-velocity/Cargo.toml @@ -1,12 +1,12 @@ [package] -name = "component-velocity" -version = "0.1.0" -description = "Created with Anchor" +name = "velocity" +version = "0.0.1" +description = "Created with Bolt" edition = "2021" [lib] crate-type = ["cdylib", "lib"] -name = "component_velocity" +name = "velocity" [features] no-entrypoint = [] @@ -14,6 +14,7 @@ no-idl = [] no-log-ix-name = [] cpi = ["no-entrypoint"] default = [] +idl-build = ["anchor-lang/idl-build"] [dependencies] anchor-lang = "0.29.0" diff --git a/examples/component-velocity/src/lib.rs b/examples/component-velocity/src/lib.rs index 03f7d83..8b82df8 100644 --- a/examples/component-velocity/src/lib.rs +++ b/examples/component-velocity/src/lib.rs @@ -2,70 +2,7 @@ use bolt_lang::*; declare_id!("CbHEFbSQdRN4Wnoby9r16umnJ1zWbULBHg4yqzGQonU1"); -#[program] -pub mod component_velocity { - use super::*; - - pub fn initialize(_ctx: Context) -> Result<()> { - Ok(()) - } - - pub fn apply(ctx: Context, args: Vec) -> Result<()> { - let result = bolt_system::cpi::execute(ctx.accounts.set_data_ctx(), args)?; - let res = Velocity::try_from_slice(&result.get())?; - ctx.accounts.bolt_component.set_inner(res); - Ok(()) - } - - #[derive(Accounts)] - pub struct Apply<'info> { - #[account(mut)] - pub bolt_component: Account<'info, Velocity>, - /// CHECK: The system can modify the data of the component - pub bolt_system: UncheckedAccount<'info>, - } - - impl<'info> Apply<'info> { - pub fn set_data_ctx( - &self, - ) -> CpiContext<'_, '_, '_, 'info, bolt_system::cpi::accounts::SetData<'info>> { - let cpi_program = self.bolt_system.to_account_info(); - let cpi_accounts = bolt_system::cpi::accounts::SetData { - component: self.bolt_component.to_account_info().clone(), - }; - CpiContext::new(cpi_program, cpi_accounts) - } - } - - pub fn update(ctx: Context, data: Vec) -> Result<()> { - ctx.accounts - .bolt_component - .set_inner(Velocity::try_from_slice(&data)?); - Ok(()) - } - - #[derive(Accounts)] - pub struct Update<'info> { - #[account(mut)] - pub bolt_component: Account<'info, Velocity>, - } -} - -#[derive(Accounts)] -pub struct Initialize<'info> { - #[account(mut)] - pub payer: Signer<'info>, - #[account(init_if_needed, payer = payer, space = Velocity::size(), seeds = [Velocity::seed(), entity.key().as_ref()], bump)] - pub data: Account<'info, Velocity>, - #[account()] - /// CHECK: A generic entity account - pub entity: UncheckedAccount<'info>, - pub system_program: Program<'info, System>, -} - -// Component data -#[account] -#[derive(InitSpace, Default)] +#[component(component_id = "component-velocity")] pub struct Velocity { pub x: i64, pub y: i64, @@ -74,12 +11,3 @@ pub struct Velocity { #[max_len(20)] pub description: String, } - -impl Velocity { - pub fn size() -> usize { - 8 + Velocity::INIT_SPACE - } - pub fn seed() -> &'static [u8] { - b"component-velocity" - } -} diff --git a/examples/system-apply-velocity/Cargo.toml b/examples/system-apply-velocity/Cargo.toml index a183fdc..7a6d1b6 100644 --- a/examples/system-apply-velocity/Cargo.toml +++ b/examples/system-apply-velocity/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "system-apply-velocity" -version = "0.1.0" -description = "Created with Anchor" +version = "0.0.1" +description = "Created with Bolt" edition = "2021" [lib] @@ -14,9 +14,10 @@ no-idl = [] no-log-ix-name = [] cpi = ["no-entrypoint"] default = [] +idl-build = ["anchor-lang/idl-build"] [dependencies] anchor-lang = "0.29.0" bolt-lang = { path = "../../crates/bolt-lang" } -component-velocity = { path = "../component-velocity", features = ["cpi"]} -component-position = { path = "../component-position", features = ["cpi"]} +velocity = { path = "../component-velocity", features = ["cpi"]} +position = { path = "../component-position", features = ["cpi"]} diff --git a/examples/system-apply-velocity/src/lib.rs b/examples/system-apply-velocity/src/lib.rs index 71923ac..3267e4e 100644 --- a/examples/system-apply-velocity/src/lib.rs +++ b/examples/system-apply-velocity/src/lib.rs @@ -1,15 +1,13 @@ use bolt_lang::*; -use component_position::Position; -use component_velocity::Velocity; +use position::Position; +use velocity::Velocity; declare_id!("6LHhFVwif6N9Po3jHtSmMVtPjF6zRfL3xMosSzcrQAS8"); #[system] -#[program] pub mod system_apply_velocity { - use super::*; - pub fn execute(ctx: Context, _args: Vec) -> Result<(Velocity, Position)> { + pub fn execute(ctx: Context, _args: Vec) -> Result { ctx.accounts.velocity.x = 10; let clock = Clock::get()?; ctx.accounts.velocity.last_applied = clock.unix_timestamp; @@ -17,14 +15,12 @@ pub mod system_apply_velocity { msg!("last applied: {}", ctx.accounts.velocity.last_applied); msg!("Position: {}", ctx.accounts.position.x); msg!("Remaining accounts: {}", ctx.remaining_accounts.len()); - Ok((*ctx.accounts.velocity, *ctx.accounts.position)) + Ok(ctx.accounts) } -} -#[derive(Accounts)] -pub struct Component<'info> { - #[account()] - pub velocity: Account<'info, Velocity>, - #[account()] - pub position: Account<'info, Position>, + #[system_input] + pub struct Components { + pub velocity: Velocity, + pub position: Position, + } } diff --git a/examples/system-fly/Cargo.toml b/examples/system-fly/Cargo.toml index 2069898..feb8781 100644 --- a/examples/system-fly/Cargo.toml +++ b/examples/system-fly/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "system-fly" -version = "0.1.0" -description = "Created with Anchor" +version = "0.0.1" +description = "Created with Bolt" edition = "2021" [lib] @@ -14,10 +14,11 @@ no-idl = [] no-log-ix-name = [] cpi = ["no-entrypoint"] default = [] +idl-build = ["anchor-lang/idl-build"] [dependencies] anchor-lang = { version = "0.29.0" } bolt-lang = { path = "../../crates/bolt-lang" } -component-position = { path = "../component-position", features = ["cpi"]} +position = { path = "../component-position", features = ["cpi"]} diff --git a/examples/system-fly/src/lib.rs b/examples/system-fly/src/lib.rs index dd5ba3b..c605a28 100644 --- a/examples/system-fly/src/lib.rs +++ b/examples/system-fly/src/lib.rs @@ -1,25 +1,19 @@ use bolt_lang::*; -use component_position::Position; +use position::Position; declare_id!("HT2YawJjkNmqWcLNfPAMvNsLdWwPvvvbKA5bpMw4eUpq"); #[system] -#[program] pub mod system_fly { - use super::*; - pub fn execute(ctx: Context, _args: Vec) -> Result { - let pos = Position { - x: ctx.accounts.position.x, - y: ctx.accounts.position.y, - z: ctx.accounts.position.z + 1, - }; - Ok(pos) + pub fn execute(ctx: Context, _args: Vec) -> Result { + let pos = &mut ctx.accounts.position; + pos.z += 1; + Ok(ctx.accounts) } -} -#[derive(Accounts)] -pub struct Component<'info> { - #[account()] - pub position: Account<'info, Position>, + #[system_input] + pub struct Components { + pub position: Position, + } } diff --git a/examples/system-simple-movement/Cargo.toml b/examples/system-simple-movement/Cargo.toml index 714919f..c6f85a9 100644 --- a/examples/system-simple-movement/Cargo.toml +++ b/examples/system-simple-movement/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "system-simple-movement" -version = "0.1.0" -description = "Created with Anchor" +version = "0.0.1" +description = "Created with Bolt" edition = "2021" [lib] @@ -14,6 +14,7 @@ no-idl = [] no-log-ix-name = [] cpi = ["no-entrypoint"] default = [] +idl-build = ["anchor-lang/idl-build"] [dependencies] anchor-lang = "0.29.0" diff --git a/examples/system-simple-movement/src/lib.rs b/examples/system-simple-movement/src/lib.rs index 9d7125a..e33277a 100644 --- a/examples/system-simple-movement/src/lib.rs +++ b/examples/system-simple-movement/src/lib.rs @@ -3,15 +3,11 @@ use bolt_lang::*; declare_id!("FSa6qoJXFBR3a7ThQkTAMrC15p6NkchPEjBdd4n6dXxA"); #[system] -#[program] pub mod system_simple_movement { - use super::*; - pub fn execute(ctx: Context, args_p: Vec) -> Result { + pub fn execute(ctx: Context, args_p: Vec) -> Result { let args = parse_args::(&args_p); - let mut position = Position::from_account_info(&ctx.accounts.position)?; - // Compute the new position based on the direction let (dx, dy) = match args.direction { Direction::Left => (-1, 0), @@ -19,37 +15,37 @@ pub mod system_simple_movement { Direction::Up => (0, 1), Direction::Down => (0, -1), }; - position.x += dx; - position.y += dy; + ctx.accounts.position.x += dx; + ctx.accounts.position.y += dy; - Ok(position) + Ok(ctx.accounts) } -} -// Define the Account to parse from the component -#[derive(Accounts)] -pub struct Component<'info> { - /// CHECK: check that the component is the expected account - pub position: AccountInfo<'info>, -} + #[system_input] + pub struct Components { + #[component_id(address = "Fn1JzzEdyb55fsyduWS94mYHizGhJZuhvjX6DVvrmGbQ")] + pub position: Position, + } -#[component_deserialize] -pub struct Position { - pub x: i64, - pub y: i64, - pub z: i64, -} + #[component_deserialize] + #[derive(Clone)] + pub struct Position { + pub x: i64, + pub y: i64, + pub z: i64, + } -// Define the structs to deserialize the arguments -#[derive(BoltSerialize, BoltDeserialize)] -struct Args { - direction: Direction, -} + // Define the structs to deserialize the arguments + #[derive(BoltSerialize, BoltDeserialize)] + struct Args { + direction: Direction, + } -#[derive(BoltSerialize, BoltDeserialize)] -pub enum Direction { - Left, - Right, - Up, - Down, + #[derive(BoltSerialize, BoltDeserialize)] + pub enum Direction { + Left, + Right, + Up, + Down, + } } diff --git a/programs/bolt-component/Cargo.toml b/programs/bolt-component/Cargo.toml index 3166cd0..23637e6 100644 --- a/programs/bolt-component/Cargo.toml +++ b/programs/bolt-component/Cargo.toml @@ -15,6 +15,7 @@ no-idl = [] no-log-ix-name = [] cpi = ["no-entrypoint"] default = [] +idl-build = ["anchor-lang/idl-build"] [dependencies] anchor-lang = { version = "0.29.0", features = ["init-if-needed"] } diff --git a/programs/bolt-component/src/lib.rs b/programs/bolt-component/src/lib.rs index be3364e..5c75607 100644 --- a/programs/bolt-component/src/lib.rs +++ b/programs/bolt-component/src/lib.rs @@ -6,7 +6,17 @@ declare_id!("CmP2djJgABZ4cRokm4ndxuq6LerqpNHLBsaUv2XKEJua"); pub mod bolt_component { use super::*; - pub fn initialize(_ctx: Context) -> Result<()> { + pub fn initialize(ctx: Context) -> Result<()> { + let instruction = + anchor_lang::solana_program::sysvar::instructions::get_instruction_relative( + 0, + &ctx.accounts.instruction_sysvar_account.to_account_info(), + ) + .unwrap(); + if instruction.program_id == id() { + panic!("The instruction must be called from a CPI"); + } + ctx.accounts.data.bolt_metadata.authority = *ctx.accounts.authority.key; Ok(()) } @@ -17,7 +27,7 @@ pub mod bolt_component { #[derive(Accounts)] pub struct Apply<'info> { #[account(mut)] - pub bolt_component: Account<'info, ComponentData>, + pub bolt_component: Account<'info, Component>, /// CHECK: The system can modify the data of the component pub bolt_system: UncheckedAccount<'info>, } @@ -34,14 +44,28 @@ pub mod bolt_component { } } - pub fn update(_ctx: Context, _data: Vec) -> Result<()> { + pub fn update(ctx: Context, _data: Vec) -> Result<()> { + let instruction = + anchor_lang::solana_program::sysvar::instructions::get_instruction_relative( + 0, + &ctx.accounts.instruction_sysvar_account.to_account_info(), + ) + .unwrap(); + if instruction.program_id == id() { + panic!("The instruction must be called from a CPI"); + } Ok(()) } #[derive(Accounts)] pub struct Update<'info> { #[account(mut)] - pub bolt_component: Account<'info, ComponentData>, + pub bolt_component: Account<'info, Component>, + #[account()] + /// CHECK: The authority of the component + pub authority: AccountInfo<'info>, + #[account(address = anchor_lang::solana_program::sysvar::instructions::id())] + pub instruction_sysvar_account: UncheckedAccount<'info>, } } @@ -49,25 +73,30 @@ pub mod bolt_component { pub struct Initialize<'info> { #[account(mut)] pub payer: Signer<'info>, - #[account(init_if_needed, payer = payer, space = ComponentData::size(), seeds = [ComponentData::seed(), entity.key().as_ref()], bump)] - pub data: Account<'info, ComponentData>, + #[account(init_if_needed, payer = payer, space = Component::size(), seeds = [Component::seed(), entity.key().as_ref()], bump)] + pub data: Account<'info, Component>, #[account()] /// CHECK: A generic entity account - pub entity: UncheckedAccount<'info>, + pub entity: AccountInfo<'info>, + #[account()] + /// CHECK: The authority of the component + pub authority: AccountInfo<'info>, + #[account(address = anchor_lang::solana_program::sysvar::instructions::id())] + pub instruction_sysvar_account: UncheckedAccount<'info>, pub system_program: Program<'info, System>, } // Component data #[account] #[derive(InitSpace, Default, Copy)] -pub struct ComponentData { - pub id: u64, +pub struct Component { pub position: Position, + pub bolt_metadata: BoltMetadata, } -impl ComponentData { +impl Component { pub fn size() -> usize { - 8 + ComponentData::INIT_SPACE + 8 + Component::INIT_SPACE } pub fn seed() -> &'static [u8] { b"origin-component" @@ -80,3 +109,8 @@ pub struct Position { pub y: i64, pub z: i64, } + +#[derive(InitSpace, AnchorSerialize, AnchorDeserialize, Default, Copy, Clone)] +pub struct BoltMetadata { + pub authority: Pubkey, +} diff --git a/programs/bolt-system/Cargo.toml b/programs/bolt-system/Cargo.toml index df0ed56..74b0a9a 100644 --- a/programs/bolt-system/Cargo.toml +++ b/programs/bolt-system/Cargo.toml @@ -15,6 +15,8 @@ no-idl = [] no-log-ix-name = [] cpi = ["no-entrypoint"] default = [] +idl-build = ["anchor-lang/idl-build"] [dependencies] -anchor-lang = "0.29.0" \ No newline at end of file +anchor-lang = "0.29.0" +bolt-helpers-system-template = { path = "../../crates/bolt-helpers/attribute/system-template", version = "0.0.1" } \ No newline at end of file diff --git a/programs/bolt-system/src/lib.rs b/programs/bolt-system/src/lib.rs index 3eddb48..3d38684 100644 --- a/programs/bolt-system/src/lib.rs +++ b/programs/bolt-system/src/lib.rs @@ -1,107 +1,21 @@ use anchor_lang::prelude::borsh::{BorshDeserialize, BorshSerialize}; use anchor_lang::prelude::*; -//use bolt_helpers_system_template::*; +use bolt_helpers_system_template::system_template; declare_id!("7X4EFsDJ5aYTcEjKzJ94rD8FRKgQeXC89fkpeTS4KaqP"); -//#[system_template(max_components = 2)] +#[system_template(max_components = 3)] #[program] pub mod bolt_system { use super::*; - pub fn execute(_ctx: Context, _args: Vec) -> Result> { Ok(Vec::new()) } - - pub fn execute_2(_ctx: Context, _args: Vec) -> Result<(Vec, Vec)> { - Ok((Vec::new(), Vec::new())) - } - - pub fn execute_3( - _ctx: Context, - _args: Vec, - ) -> Result<(Vec, Vec, Vec)> { - Ok((Vec::new(), Vec::new(), Vec::new())) - } - - #[allow(clippy::type_complexity)] - pub fn execute_4( - _ctx: Context, - _args: Vec, - ) -> Result<(Vec, Vec, Vec, Vec)> { - Ok((Vec::new(), Vec::new(), Vec::new(), Vec::new())) - } - - #[allow(clippy::type_complexity)] - pub fn execute_5( - _ctx: Context, - _args: Vec, - ) -> Result<(Vec, Vec, Vec, Vec, Vec)> { - Ok((Vec::new(), Vec::new(), Vec::new(), Vec::new(), Vec::new())) - } } -#[derive(Accounts, BorshDeserialize, BorshSerialize, Clone)] +#[derive(Accounts, Clone)] pub struct SetData<'info> { #[account()] /// CHECK: unchecked account pub component: UncheckedAccount<'info>, } - -#[derive(Accounts, BorshDeserialize, BorshSerialize, Clone)] -pub struct SetData2<'info> { - #[account()] - /// CHECK: unchecked account - pub component1: UncheckedAccount<'info>, - #[account()] - /// CHECK: unchecked account - pub component2: UncheckedAccount<'info>, -} - -#[derive(Accounts, BorshDeserialize, BorshSerialize, Clone)] -pub struct SetData3<'info> { - #[account()] - /// CHECK: unchecked account - pub component1: UncheckedAccount<'info>, - #[account()] - /// CHECK: unchecked account - pub component2: UncheckedAccount<'info>, - #[account()] - /// CHECK: unchecked account - pub component3: UncheckedAccount<'info>, -} - -#[derive(Accounts, BorshDeserialize, BorshSerialize, Clone)] -pub struct SetData4<'info> { - #[account()] - /// CHECK: unchecked account - pub component1: UncheckedAccount<'info>, - #[account()] - /// CHECK: unchecked account - pub component2: UncheckedAccount<'info>, - #[account()] - /// CHECK: unchecked account - pub component3: UncheckedAccount<'info>, - #[account()] - /// CHECK: unchecked account - pub component4: UncheckedAccount<'info>, -} - -#[derive(Accounts, BorshDeserialize, BorshSerialize, Clone)] -pub struct SetData5<'info> { - #[account()] - /// CHECK: unchecked account - pub component1: UncheckedAccount<'info>, - #[account()] - /// CHECK: unchecked account - pub component2: UncheckedAccount<'info>, - #[account()] - /// CHECK: unchecked account - pub component3: UncheckedAccount<'info>, - #[account()] - /// CHECK: unchecked account - pub component4: UncheckedAccount<'info>, - #[account()] - /// CHECK: unchecked account - pub component5: UncheckedAccount<'info>, -} diff --git a/programs/world/Cargo.toml b/programs/world/Cargo.toml index 3a5c34a..7ec9c1f 100644 --- a/programs/world/Cargo.toml +++ b/programs/world/Cargo.toml @@ -15,9 +15,13 @@ no-idl = [] no-log-ix-name = [] cpi = ["no-entrypoint"] default = [] +idl-build = ["anchor-lang/idl-build"] [dependencies] anchor-lang = { version = "0.29.0", features = ["init-if-needed"] } bolt-component = { path = "../../programs/bolt-component", features = ["cpi"], version = "0.0.1"} +bolt-helpers-world-apply = { path = "../../crates/bolt-helpers/attribute/world-apply", version = "0.0.1" } bolt-system = { path = "../../programs/bolt-system", features = ["cpi"], version = "0.0.1"} solana-security-txt = "1.1.1" +tuple-conv = "1.0.1" + diff --git a/programs/world/src/error.rs b/programs/world/src/error.rs new file mode 100644 index 0000000..0390df7 --- /dev/null +++ b/programs/world/src/error.rs @@ -0,0 +1,8 @@ +use anchor_lang::prelude::*; + +#[error_code] +pub enum WorldError { + /// Returned if the wrong authority attempts to sign for an instruction + #[msg("Invalid authority for instruction")] + InvalidAuthority, +} diff --git a/programs/world/src/lib.rs b/programs/world/src/lib.rs index da893fb..1700a60 100644 --- a/programs/world/src/lib.rs +++ b/programs/world/src/lib.rs @@ -1,4 +1,6 @@ use anchor_lang::prelude::*; +use bolt_helpers_world_apply::apply_system; +use tuple_conv::RepeatedTuple; #[cfg(not(feature = "no-entrypoint"))] use solana_security_txt::security_txt; @@ -15,9 +17,13 @@ security_txt! { source_code: "https://github.com/magicblock-labs/bolt" } +mod error; + +#[apply_system(max_components = 3)] #[program] pub mod world { use super::*; + use crate::error::WorldError; pub fn initialize_registry(_ctx: Context) -> Result<()> { Ok(()) @@ -31,163 +37,59 @@ pub mod world { #[allow(unused_variables)] pub fn add_entity(ctx: Context, extra_seed: Option) -> Result<()> { - msg!( - "extra seeds: {:?}", - match extra_seed { - Some(ref seed) => seed.as_bytes(), - None => &[], - } - ); ctx.accounts.entity.id = ctx.accounts.world.entities; ctx.accounts.world.entities += 1; - msg!("entity id: {}", ctx.accounts.entity.id); - msg!("world entities: {}", ctx.accounts.world.entities); Ok(()) } pub fn initialize_component(ctx: Context) -> Result<()> { + if !ctx.accounts.authority.is_signer && ctx.accounts.authority.key != &ID { + return Err(WorldError::InvalidAuthority.into()); + } bolt_component::cpi::initialize(ctx.accounts.build())?; Ok(()) } pub fn apply(ctx: Context, args: Vec) -> Result<()> { + if !ctx.accounts.authority.is_signer && ctx.accounts.authority.key != &ID { + return Err(WorldError::InvalidAuthority.into()); + } let res = bolt_system::cpi::execute(ctx.accounts.build(), args)?; - bolt_component::cpi::update(ctx.accounts.build_update(), res.get())?; - Ok(()) - } - - // Apply to 2 components - pub fn apply2(ctx: Context, args: Vec) -> Result<()> { - let res = bolt_system::cpi::execute_2(ctx.accounts.build(), args)?; - let (result1, result2) = res.get(); bolt_component::cpi::update( - ctx.accounts.build_update( - ctx.accounts.component_program_1.clone(), - ctx.accounts.bolt_component_1.clone(), + build_update_context( + ctx.accounts.component_program.clone(), + ctx.accounts.bolt_component.clone(), + ctx.accounts.authority.clone(), + ctx.accounts.instruction_sysvar_account.clone(), ), - result1, - )?; - bolt_component::cpi::update( - ctx.accounts.build_update( - ctx.accounts.component_program_2.clone(), - ctx.accounts.bolt_component_2.clone(), - ), - result2, + res.get(), )?; Ok(()) } #[derive(Accounts)] - pub struct ApplySystem2<'info> { - /// CHECK: bolt system program check - pub bolt_system: UncheckedAccount<'info>, + pub struct ApplySystem<'info> { /// CHECK: bolt component program check - pub component_program_1: UncheckedAccount<'info>, - #[account(mut)] - /// CHECK: component account - pub bolt_component_1: UncheckedAccount<'info>, - /// CHECK: bolt component program check - pub component_program_2: UncheckedAccount<'info>, - #[account(mut)] - /// CHECK: component account - pub bolt_component_2: UncheckedAccount<'info>, - } - - impl<'info> ApplySystem2<'info> { - pub fn build( - &self, - ) -> CpiContext<'_, '_, '_, 'info, bolt_system::cpi::accounts::SetData2<'info>> { - let cpi_program = self.bolt_system.to_account_info(); - let cpi_accounts = bolt_system::cpi::accounts::SetData2 { - component1: self.bolt_component_1.to_account_info(), - component2: self.bolt_component_2.to_account_info(), - }; - CpiContext::new(cpi_program, cpi_accounts) - } - - pub fn build_update( - &self, - component_program: UncheckedAccount<'info>, - component: UncheckedAccount<'info>, - ) -> CpiContext<'_, '_, '_, 'info, bolt_component::cpi::accounts::Update<'info>> { - let cpi_program = component_program.to_account_info(); - let cpi_accounts = bolt_component::cpi::accounts::Update { - bolt_component: component.to_account_info(), - }; - CpiContext::new(cpi_program, cpi_accounts) - } - } - - // Apply to 3 components - pub fn apply3(ctx: Context, args: Vec) -> Result<()> { - let res = bolt_system::cpi::execute_3(ctx.accounts.build(), args)?; - let (result1, result2, result3) = res.get(); - bolt_component::cpi::update( - ctx.accounts.build_update( - ctx.accounts.component_program_1.clone(), - ctx.accounts.bolt_component_1.clone(), - ), - result1, - )?; - bolt_component::cpi::update( - ctx.accounts.build_update( - ctx.accounts.component_program_2.clone(), - ctx.accounts.bolt_component_2.clone(), - ), - result2, - )?; - bolt_component::cpi::update( - ctx.accounts.build_update( - ctx.accounts.component_program_3.clone(), - ctx.accounts.bolt_component_3.clone(), - ), - result3, - )?; - Ok(()) - } - - #[derive(Accounts)] - pub struct ApplySystem3<'info> { + pub component_program: UncheckedAccount<'info>, /// CHECK: bolt system program check pub bolt_system: UncheckedAccount<'info>, - /// CHECK: bolt component program check - pub component_program_1: UncheckedAccount<'info>, #[account(mut)] /// CHECK: component account - pub bolt_component_1: UncheckedAccount<'info>, - /// CHECK: bolt component program check - pub component_program_2: UncheckedAccount<'info>, - #[account(mut)] - /// CHECK: component account - pub bolt_component_2: UncheckedAccount<'info>, - /// CHECK: bolt component program check - pub component_program_3: UncheckedAccount<'info>, - #[account(mut)] - /// CHECK: component account - pub bolt_component_3: UncheckedAccount<'info>, + pub bolt_component: UncheckedAccount<'info>, + /// CHECK: authority check + pub authority: UncheckedAccount<'info>, + #[account(address = anchor_lang::solana_program::sysvar::instructions::id())] + /// CHECK: instruction sysvar check + pub instruction_sysvar_account: UncheckedAccount<'info>, } - impl<'info> ApplySystem3<'info> { + impl<'info> ApplySystem<'info> { pub fn build( &self, - ) -> CpiContext<'_, '_, '_, 'info, bolt_system::cpi::accounts::SetData3<'info>> { + ) -> CpiContext<'_, '_, '_, 'info, bolt_system::cpi::accounts::SetData<'info>> { let cpi_program = self.bolt_system.to_account_info(); - let cpi_accounts = bolt_system::cpi::accounts::SetData3 { - component1: self.bolt_component_1.to_account_info(), - component2: self.bolt_component_2.to_account_info(), - component3: self.bolt_component_3.to_account_info(), - }; - CpiContext::new(cpi_program, cpi_accounts) - } - - pub fn build_update( - &self, - component_program: UncheckedAccount<'info>, - component: UncheckedAccount<'info>, - ) -> CpiContext<'_, '_, '_, 'info, bolt_component::cpi::accounts::Update<'info>> { - let cpi_program = component_program.to_account_info(); - let cpi_accounts = bolt_component::cpi::accounts::Update { - bolt_component: component.to_account_info(), + let cpi_accounts = bolt_system::cpi::accounts::SetData { + component: self.bolt_component.to_account_info(), }; CpiContext::new(cpi_program, cpi_accounts) } @@ -240,11 +142,16 @@ pub struct InitializeComponent<'info> { pub payer: Signer<'info>, #[account(mut)] /// CHECK: component data check - pub data: UncheckedAccount<'info>, + pub data: AccountInfo<'info>, #[account()] pub entity: Account<'info, Entity>, /// CHECK: component program check - pub component_program: UncheckedAccount<'info>, + pub component_program: AccountInfo<'info>, + /// CHECK: authority check + pub authority: AccountInfo<'info>, + #[account(address = anchor_lang::solana_program::sysvar::instructions::id())] + /// CHECK: instruction sysvar check + pub instruction_sysvar_account: UncheckedAccount<'info>, pub system_program: Program<'info, System>, } @@ -253,51 +160,19 @@ impl<'info> InitializeComponent<'info> { &self, ) -> CpiContext<'_, '_, '_, 'info, bolt_component::cpi::accounts::Initialize<'info>> { let cpi_program = self.component_program.to_account_info(); + let cpi_accounts = bolt_component::cpi::accounts::Initialize { payer: self.payer.to_account_info(), data: self.data.to_account_info(), entity: self.entity.to_account_info(), + authority: self.authority.to_account_info(), + instruction_sysvar_account: self.instruction_sysvar_account.to_account_info(), system_program: self.system_program.to_account_info(), }; CpiContext::new(cpi_program, cpi_accounts) } } -#[derive(Accounts)] -pub struct ApplySystem<'info> { - /// CHECK: bolt component program check - pub component_program: UncheckedAccount<'info>, - /// CHECK: bolt system program check - pub bolt_system: UncheckedAccount<'info>, - #[account(mut)] - /// CHECK: component account - pub bolt_component: UncheckedAccount<'info>, -} - -impl<'info> ApplySystem<'info> { - pub fn build( - &self, - ) -> CpiContext<'_, '_, '_, 'info, bolt_system::cpi::accounts::SetData<'info>> { - let cpi_program = self.bolt_system.to_account_info(); - let cpi_accounts = bolt_system::cpi::accounts::SetData { - component: self.bolt_component.to_account_info(), - }; - CpiContext::new(cpi_program, cpi_accounts) - } - - pub fn build_update( - &self, - ) -> CpiContext<'_, '_, '_, 'info, bolt_component::cpi::accounts::Update<'info>> { - let cpi_program = self.component_program.to_account_info(); - let cpi_accounts = bolt_component::cpi::accounts::Update { - bolt_component: self.bolt_component.to_account_info(), - }; - CpiContext::new(cpi_program, cpi_accounts) - } -} - -// Accounts - #[account] #[derive(InitSpace, Default, Copy)] pub struct Registry { @@ -350,3 +225,19 @@ impl Entity { b"entity" } } + +/// Builds the context for updating a component. +pub fn build_update_context<'info>( + component_program: UncheckedAccount<'info>, + component: UncheckedAccount<'info>, + authority: UncheckedAccount<'info>, + instruction_sysvar_account: UncheckedAccount<'info>, +) -> CpiContext<'info, 'info, 'info, 'info, bolt_component::cpi::accounts::Update<'info>> { + let cpi_program = component_program.to_account_info(); + let cpi_accounts = bolt_component::cpi::accounts::Update { + bolt_component: component.to_account_info(), + authority: authority.to_account_info(), + instruction_sysvar_account: instruction_sysvar_account.to_account_info(), + }; + CpiContext::new(cpi_program, cpi_accounts) +} diff --git a/tests/bolt.ts b/tests/bolt.ts index ebf04ce..12f749c 100644 --- a/tests/bolt.ts +++ b/tests/bolt.ts @@ -1,20 +1,22 @@ import * as anchor from "@coral-xyz/anchor"; -import { Program } from "@coral-xyz/anchor"; -import { PublicKey } from "@solana/web3.js"; -import { ComponentPosition } from "../target/types/component_position"; -import { ComponentVelocity } from "../target/types/component_velocity"; -import { BoltComponent } from "../target/types/bolt_component"; -import { SystemSimpleMovement } from "../target/types/system_simple_movement"; -import { SystemFly } from "../target/types/system_fly"; -import { SystemApplyVelocity } from "../target/types/system_apply_velocity"; -import { World } from "../target/types/world"; +import { type Program } from "@coral-xyz/anchor"; +import { type PublicKey } from "@solana/web3.js"; +import { type Position } from "../target/types/position"; +import { type Velocity } from "../target/types/velocity"; +import { type BoltComponent } from "../target/types/bolt_component"; +import { type SystemSimpleMovement } from "../target/types/system_simple_movement"; +import { type SystemFly } from "../target/types/system_fly"; +import { type SystemApplyVelocity } from "../target/types/system_apply_velocity"; +import { type World } from "../target/types/world"; import { expect } from "chai"; import BN from "bn.js"; import { + createInitializeRegistryInstruction, FindComponentPda, FindEntityPda, FindWorldPda, FindWorldRegistryPda, + SYSVAR_INSTRUCTIONS_PUBKEY, } from "../clients/bolt-sdk"; enum Direction { @@ -41,9 +43,9 @@ describe("bolt", () => { const worldProgram = anchor.workspace.World as Program; const boltComponentPositionProgram = anchor.workspace - .ComponentPosition as Program; + .Position as Program; const boltComponentVelocityProgram = anchor.workspace - .ComponentVelocity as Program; + .Velocity as Program; const boltComponentProgramOrigin = anchor.workspace .BoltComponent as Program; @@ -58,19 +60,21 @@ describe("bolt", () => { let entity1: PublicKey; let entity2: PublicKey; + let entity5: PublicKey; let componentPositionEntity1: PublicKey; let componentPositionEntity2: PublicKey; + let componentPositionEntity5: PublicKey; let componentVelocityEntity1: PublicKey; it("InitializeWorldsRegistry", async () => { const registryPda = FindWorldRegistryPda(worldProgram.programId); - await worldProgram.methods - .initializeRegistry() - .accounts({ - registry: registryPda, - payer: provider.wallet.publicKey, - }) - .rpc(); + const initializeRegistryIx = createInitializeRegistryInstruction({ + registry: registryPda, + payer: provider.wallet.publicKey, + }); + + const tx = new anchor.web3.Transaction().add(initializeRegistryIx); + await provider.sendAndConfirm(tx); }); it("InitializeNewWorld", async () => { @@ -150,7 +154,7 @@ describe("bolt", () => { it("Add entity 4 with extra seeds", async () => { const worldPda = FindWorldPda(new BN(0), worldProgram.programId); const seed = "extra-seed"; - let entity3 = FindEntityPda( + const entity4 = FindEntityPda( new BN(0), new BN(3), seed, @@ -161,14 +165,28 @@ describe("bolt", () => { .addEntity(seed) .accounts({ world: worldPda, - entity: entity3, + entity: entity4, + payer: provider.wallet.publicKey, + }) + .rpc(); + }); + + it("Add entity 5", async () => { + const worldPda = FindWorldPda(new BN(0), worldProgram.programId); + entity5 = FindEntityPda(new BN(0), new BN(4), null, worldProgram.programId); + + await worldProgram.methods + .addEntity(null) + .accounts({ + world: worldPda, + entity: entity5, payer: provider.wallet.publicKey, }) .rpc(); }); it("Initialize Original Component on Entity 1, trough the world instance", async () => { - let componentEntity1 = FindComponentPda( + const componentEntity1 = FindComponentPda( boltComponentProgramOrigin.programId, entity1, "origin-component" @@ -180,12 +198,14 @@ describe("bolt", () => { data: componentEntity1, componentProgram: boltComponentProgramOrigin.programId, entity: entity1, + instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY, + authority: provider.wallet.publicKey, }) .rpc(); }); it("Initialize Original Component on Entity 2, trough the world instance", async () => { - let componentEntity2 = FindComponentPda( + const componentEntity2 = FindComponentPda( boltComponentProgramOrigin.programId, entity2, "origin-component" @@ -197,6 +217,8 @@ describe("bolt", () => { data: componentEntity2, componentProgram: boltComponentProgramOrigin.programId, entity: entity2, + instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY, + authority: provider.wallet.publicKey, }) .rpc(); }); @@ -216,6 +238,8 @@ describe("bolt", () => { data: componentPositionEntity1, componentProgram: boltComponentPositionProgram.programId, entity: entity1, + instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY, + authority: worldProgram.programId, }) .rpc(); }); @@ -234,6 +258,8 @@ describe("bolt", () => { data: componentVelocityEntity1, componentProgram: boltComponentVelocityProgram.programId, entity: entity1, + instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY, + authority: worldProgram.programId, }) .rpc(); }); @@ -251,6 +277,27 @@ describe("bolt", () => { data: componentPositionEntity2, componentProgram: boltComponentPositionProgram.programId, entity: entity2, + instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY, + authority: worldProgram.programId, + }) + .rpc(); + }); + + it("Initialize Position Component on Entity 5", async () => { + componentPositionEntity5 = FindComponentPda( + boltComponentPositionProgram.programId, + entity5 + ); + + await worldProgram.methods + .initializeComponent() + .accounts({ + payer: provider.wallet.publicKey, + data: componentPositionEntity5, + componentProgram: boltComponentPositionProgram.programId, + entity: entity5, + instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY, + authority: provider.wallet.publicKey, }) .rpc(); }); @@ -289,6 +336,8 @@ describe("bolt", () => { componentProgram: boltComponentPositionProgram.programId, boltSystem: systemSimpleMovement, boltComponent: componentPositionEntity1, + instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY, + authority: worldProgram.programId, }) .rpc({ skipPreflight: true }); @@ -320,6 +369,7 @@ describe("bolt", () => { console.log("+----------------+------------+"); console.log("| |"); console.log("+-----------------------------+"); + console.log("Component Position: ", componentPositionEntity1.toString()); }); it("Simple Movement System and Right direction on Entity 1", async () => { @@ -332,8 +382,10 @@ describe("bolt", () => { componentProgram: boltComponentPositionProgram.programId, boltSystem: systemSimpleMovement, boltComponent: componentPositionEntity1, + instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY, + authority: worldProgram.programId, }) - .rpc({ skipPreflight: true }); + .rpc(); expect( ( @@ -379,6 +431,8 @@ describe("bolt", () => { componentProgram: boltComponentPositionProgram.programId, boltSystem: systemFly, boltComponent: componentPositionEntity1, + instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY, + authority: worldProgram.programId, }) .rpc(); @@ -421,6 +475,8 @@ describe("bolt", () => { boltSystem: applyVelocity, boltComponent1: componentVelocityEntity1, boltComponent2: componentPositionEntity1, + instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY, + authority: worldProgram.programId, }) .remainingAccounts([ { @@ -433,7 +489,7 @@ describe("bolt", () => { console.log("Component Velocity: ", componentVelocityEntity1.toBase58()); - let componentData = + const componentData = await boltComponentVelocityProgram.account.velocity.fetch( componentVelocityEntity1 ); @@ -457,7 +513,7 @@ describe("bolt", () => { console.log("| |"); console.log("+-----------------------------+"); - let positionData = + const positionData = await boltComponentPositionProgram.account.position.fetch( componentPositionEntity1 ); @@ -478,4 +534,85 @@ describe("bolt", () => { console.log("| |"); console.log("+-----------------------------+"); }); + + // Check illegal authority usage + it("Check invalid component update", async () => { + const componentDataPrev = + await boltComponentPositionProgram.account.position.fetch( + componentPositionEntity5 + ); + + try { + await worldProgram.methods + .apply(Buffer.alloc(0)) // Move Up + .accounts({ + componentProgram: boltComponentPositionProgram.programId, + boltSystem: systemFly, + boltComponent: componentPositionEntity5, + instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY, + authority: worldProgram.programId, + }) + .rpc(); + } catch (e) { + expect(e.message).to.contain("Invalid authority"); + } + + const componentData = + await boltComponentPositionProgram.account.position.fetch( + componentPositionEntity5 + ); + + expect( + componentDataPrev.x.toNumber() === componentData.x.toNumber() && + componentDataPrev.y.toNumber() === componentData.y.toNumber() && + componentDataPrev.z.toNumber() === componentData.z.toNumber() + ).to.equal(true); + }); + + // Check illegal call, without CPI + it("Check invalid init without CPI", async () => { + let invalid = false; + const componentVelocityEntity5 = FindComponentPda( + boltComponentVelocityProgram.programId, + entity5 + ); + try { + await boltComponentProgramOrigin.methods + .initialize() + .accounts({ + payer: provider.wallet.publicKey, + data: componentVelocityEntity5, + entity: entity5, + instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY, + systemProgram: anchor.web3.SystemProgram.programId, + authority: provider.wallet.publicKey, + }) + .rpc(); + } catch (e) { + invalid = true; + } + expect(invalid).to.equal(true); + }); + + // Check illegal call, without CPI + it("Check invalid update without CPI", async () => { + let invalid = false; + const componentVelocityEntity5 = FindComponentPda( + boltComponentVelocityProgram.programId, + entity5 + ); + try { + await boltComponentProgramOrigin.methods + .update(null) + .accounts({ + boltComponent: componentVelocityEntity5, + instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY, + authority: provider.wallet.publicKey, + }) + .rpc(); + } catch (e) { + invalid = true; + } + expect(invalid).to.equal(true); + }); });