diff --git a/.gitignore b/.gitignore index 48bbf22..563bfa3 100644 --- a/.gitignore +++ b/.gitignore @@ -9,5 +9,8 @@ node_modules test-ledger .yarn-error +# Yarn - ignore entire yarn directories +.yarn/ + lib .crates \ No newline at end of file diff --git a/.mcp.json b/.mcp.json new file mode 100644 index 0000000..695bb8f --- /dev/null +++ b/.mcp.json @@ -0,0 +1,8 @@ +{ + "mcpServers": { + "linear": { + "command": "npx", + "args": ["-y", "mcp-remote", "https://mcp.linear.app/sse"] + } + } +} \ No newline at end of file diff --git a/.yarnrc.yml b/.yarnrc.yml new file mode 100644 index 0000000..a1feb90 --- /dev/null +++ b/.yarnrc.yml @@ -0,0 +1,3 @@ +nodeLinker: node-modules + +yarnPath: .yarn/releases/yarn-1.22.22.cjs diff --git a/Anchor.toml b/Anchor.toml index e698be8..6bc0b58 100644 --- a/Anchor.toml +++ b/Anchor.toml @@ -23,5 +23,9 @@ url = "https://api.devnet.solana.com" address = "8UuqDAqe9UQx9e9Sjj4Gs3msrWGfzb4CJHGK3U3tcCEX" filename = "tests/fixtures/pre-rent-collector/multisig-account.json" +[[test.genesis]] +address = "noopb9bkMVfRPU8AsbpTUg8AQkHtKwMYZiFUjNRtMmV" +program = "tests/fixtures/noop.so" + [scripts] test = "npx mocha --node-option require=ts-node/register --extension ts -t 1000000 tests/index.ts" diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..1c9623a --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,285 @@ +# Squads Smart Account Program Summary + +## Core Architecture + +**Smart Account** = Multi-signature wallet with configurable governance and spending controls + +## Three Transaction Execution Modes + +### 1. Consensus-Based Transactions (Full Governance) +- **Purpose**: Any blockchain operation requiring multi-sig approval +- **Flow**: Create Transaction → Create Proposal → Vote → Time Lock → Execute +- **Components**: + - **Settings**: Signers, threshold, time lock configuration + - **Proposals**: Voting records (approved/rejected/cancelled) + - **Permissions**: Initiate, Vote, Execute roles + - **Stale Protection**: Settings changes invalidate old proposals + +### 2. Synchronous Transactions (Immediate Execution) +- **Purpose**: Same as consensus transactions but executed immediately +- **Flow**: Single instruction with all required signatures +- **Requirements**: + - Time lock must be 0 (no deliberation period) + - All required signers present simultaneously + - Combined permissions must include Initiate + Vote + Execute + - Meet threshold requirements +- **Benefits**: Gas efficient, atomic execution, reduced latency +- **Limitations**: No time lock support, requires coordination of all signers + +### 3. Spending Limits (Pre-Authorized Bypass) +- **Purpose**: Token transfers within pre-approved parameters +- **Flow**: Create Spending Limit → Use Spending Limit (direct execution) +- **Parameters**: + - Amount & token type + - Reset periods (OneTime, Daily, Weekly, Monthly) + - Authorized signers + - Destination allowlist + - Expiration date + +## Key Security Mechanisms + +### Stale Transaction Protection +- `transaction_index`: Latest transaction number +- `stale_transaction_index`: Staleness boundary +- When signers/threshold/timelock change → all pending transactions become stale +- Settings transactions cannot execute if stale (security critical) +- Regular transactions can execute if stale (but approved before staleness) + +### Permission System +- **Initiate**: Create transactions/proposals +- **Vote**: Approve/reject/cancel proposals +- **Execute**: Execute approved transactions + +### Time Locks +- Mandatory delay between approval and execution +- Prevents immediate execution attacks +- Can be removed by settings authority + +## Account Types +- **Autonomous**: Self-governed via proposals +- **Controlled**: Has settings authority that can bypass consensus for configuration + +## Transaction Mode Comparison +- **Consensus Transactions**: Any operation, full governance with voting + time lock +- **Synchronous Transactions**: Any operation, immediate execution with all signatures +- **Spending Limits**: Token transfers only, pre-authorized bypass +- All three are separate flows with no overlap or conflict + +This creates a flexible system balancing security (consensus) with efficiency (spending limits) for treasury management. + +## Policy Framework (Proposed Extension) + +### Overview +Spending limits are being evolved into a generalized **Policy Framework** where spending limits become just one type of policy among many. This creates a unified governance system for all types of smart account policies. + +### Policy Account Structure (Conceptual) +```rust +pub struct Policy { + // Core governance (unified across all policy types) + pub smart_account: Pubkey, // Parent smart account + pub transaction_index: u64, // Stale transaction protection + pub stale_transaction_index: u64, // Staleness boundary + pub signers: Vec, // Members with permissions + pub threshold: u16, // Approval threshold + pub time_lock: u32, // Delay before execution + + // Policy-specific configuration + pub policy_type: PolicyType, // Enum defining policy type + pub policy_data: Vec, // Serialized policy-specific parameters + pub vault_scopes: Vec, // Which vaults this policy applies to + + // Metadata + pub bump: u8, + pub created_at: i64, + pub updated_at: i64, +} + +pub struct PolicySigner { + pub key: Pubkey, + pub permissions: Permissions, // Initiate, Vote, Execute +} + +pub enum PolicyType { + SpendingLimit, // Current spending limits (token transfers) + ProgramInteraction, // Arbitrary program calls with constraints + // Future types: MultiSigOverride, ComplianceRule, etc. +} +``` + +### Policy Requirements (From GRID-600) +1. **Every signer on every policy has permissions** - PolicySigner structure with Initiate/Vote/Execute +2. **Every policy has thresholds** - Unified threshold field across all policy types +3. **Every policy can specify which vaults it's active on** - vault_scopes field +4. **Every policy offers alternate form of consensus** - Alternative to full smart account governance +5. **Overflowing amounts per spending limit duration** - Enhanced spending limit features +6. **Start date for spending limits** - Time-based activation +7. **Declarable remaining amount in Spending Limits** - Better limit tracking + +### Policy Types + +#### SpendingLimit Policy (Current Implementation → Policy Type) +- **Purpose**: Token transfers within pre-approved parameters +- **Parameters**: Amount, token, period, destinations, expiration +- **Execution**: Direct bypass of consensus when conditions met + +#### ProgramInteraction Policy (Proposed) +- **Purpose**: Allow specific program calls with granular constraints +- **Constraint Types**: + - **Instruction Data**: Bytes 0-8 (discriminator) must equal specific values + - **Account Constraints**: Specific accounts or accounts owned by certain programs + - **Parameter Validation**: Validate specific instruction data fields + +**Example Policy Configurations**: +```rust +pub struct ProgramInteractionConstraints { + pub program_id: Pubkey, + pub allowed_discriminators: Vec<[u8; 8]>, // Instruction discriminators allowed + pub account_constraints: Vec, + pub data_constraints: Vec, // Validate specific data fields +} + +pub enum AccountConstraint { + MustBe(Pubkey), // Account must be specific pubkey + MustBeOwnedBy(Pubkey), // Account must be owned by program + MustBeDerivedFrom { program: Pubkey, seeds: Vec> }, // PDA constraints +} + +pub enum DataConstraint { + BytesAtOffset { offset: usize, bytes: Vec }, // Specific bytes at offset + U64AtOffset { offset: usize, max_value: u64 }, // Numeric constraints +} +``` + +**Use Cases**: +- "Allow Jupiter swaps but only for amounts < 1000 USDC" +- "Allow Serum DEX orders but only on specific markets" +- "Allow staking but only to approved validators" +- **Execution**: Validate instruction matches all policy constraints before execution + +### Consensus Trait/Interface (Core Design Concept) +Since policy accounts and smart account settings share so much structure (signers, thresholds, permissions, stale transaction protection), the plan is to create a **unified consensus trait/interface** that allows execution on both: + +```rust +pub trait Consensus { + fn signers(&self) -> &[ConsensusSigner]; + fn threshold(&self) -> u16; + fn time_lock(&self) -> u32; + fn transaction_index(&self) -> u64; + fn stale_transaction_index(&self) -> u64; + fn validate_execution(&self, signers: &[Pubkey]) -> Result<()>; + // etc. +} + +impl Consensus for Settings { /* smart account implementation */ } +impl Consensus for Policy { /* policy account implementation */ } +``` + +This means you can execute transactions/proposals on both smart account settings AND individual policy accounts using the same interface and validation logic. + +### Benefits +1. **Unified Governance**: All policies use same stale transaction protection, permissions, consensus +2. **Extensible**: New policy types can be added without changing core infrastructure +3. **Consistent UX**: All policies work the same way from governance perspective +4. **Vault Scoping**: Each policy can specify which smart account indices it applies to +5. **Alternative Consensus**: Policies provide lighter-weight governance than full proposals +6. **Code Reuse**: Same consensus logic works for both smart accounts and policies + +### Swig Wallet Deep Analysis (Anagram) +**Repository**: https://github.com/anagrambuild/swig-wallet + +After analyzing the source code, Swig implements a **sophisticated structured authorization system**, not a general-purpose VM: + +#### Core Architecture +- **Role-Based Access Control**: Each wallet has multiple roles, each with specific authorities and actions +- **Action-Based Permissions**: Predefined action types (TokenLimit, SolLimit, ProgramScope, StakeLimit, etc.) +- **Multi-Authority Support**: ED25519, SECP256k1, SECP256r1 cryptographic authorities +- **Session Management**: Time-bounded temporary permissions with slot-based expiration + +#### Key Policy Components (from state-x/) + +**Role Structure**: +```rust +// Each role contains: +- Authority type + data +- Set of actions/permissions +- Unique role ID +- Position/boundary markers +``` + +**Action Types**: +- **TokenLimit**: Per-mint spending limits with `current_amount` tracking +- **SolLimit**: Native SOL spending limits +- **ProgramScope**: External program interaction policies with 3 scope types: + - Basic (unrestricted) + - Fixed Limit (total amount cap) + - Recurring Limit (time-windowed amounts) +- **StakeLimit**: Staking operation constraints +- **All**: Unrestricted access + +#### Policy Enforcement Mechanism +1. **Pre-execution validation**: Check role permissions and limits +2. **Real-time tracking**: Update `current_amount` during execution +3. **Account snapshots**: Validate post-execution state changes +4. **Automatic resets**: Time-based limit resets for recurring policies + +#### Key Insights for Our Framework +1. **Structured vs VM**: They use predefined action enums, not arbitrary logic +2. **Real-time enforcement**: Validation happens during execution, not pre-authorization +3. **Granular tracking**: Per-mint, per-program, per-operation limits +4. **Session model**: Temporary permissions complement persistent roles +5. **Account snapshots**: Post-execution validation ensures policy compliance + +#### Arbitrary Instruction Execution Analysis + +**Program Scope System** (from `state-x/src/action/program_scope.rs`): +- **3 Scope Types**: + - **Basic**: Unrestricted program interaction + - **Fixed Limit**: Total amount cap across all interactions + - **Recurring Limit**: Time-windowed (slot-based) amount limits with automatic resets +- **Balance Tracking**: Reads specific byte ranges in account data to track balances/amounts +- **Automatic Resets**: Time-based limit resets using Solana slot numbers + +**Program Permission System** (from `state-x/src/action/program.rs`): +- **Explicit Program Allowlist**: 32-byte program ID matching for allowed interactions +- **Repeatable Permissions**: Multiple program interactions allowed per role +- **Strict Validation**: Exact byte-level matching of program identifiers + +**Instruction Execution Constraints** (from `program/src/actions/sign_v1.rs`): +- **Pre-Execution**: Role authentication, program scope check, account classification, balance validation +- **Execution Control**: Account snapshots, controlled execution, post-execution validation +- **Balance Tracking**: Updates `current_amount` for limit enforcement + +**What Swig Does NOT Constrain**: +- **No Instruction Discriminator Filtering**: Doesn't restrict specific instruction types within allowed programs +- **No Instruction Data Validation**: Doesn't parse or constrain instruction data content +- **No Account Constraint Logic**: Doesn't enforce "account must be owned by X" style rules + +**Swig's Execution Model**: +```rust +// Simple program allowlist + balance limits +ProgramScope { + program_id: Pubkey, // Which program can be called + scope_type: Basic/Fixed/Recurring, // How much interaction allowed + balance_range: (offset, length), // What balance field to track + current_amount: u64, // Real-time usage tracking +} +``` + +**Key Characteristics**: +- **Program-level permissions** rather than instruction-level granularity +- **"How much" focus** - tracks amounts/balances rather than constraining specific operations +- **Real-time enforcement** during execution with account snapshots +- **Balance tracking within account data** for DeFi interactions + +**Relevance**: Swig validates our policy account approach but with more sophisticated real-time enforcement and granular action tracking. Their "policy engine" is actually a structured permission system with predefined types. + +### Migration Path +- Current spending limits → SpendingLimit policy type +- Existing spending limit accounts can be migrated or left as-is +- New policies created using unified Policy account structure + +## Key File Locations +- Core state: `programs/squads_smart_account_program/src/state/` +- Instructions: `programs/squads_smart_account_program/src/instructions/` +- Tests: `tests/suites/examples/` +- SDK: `sdk/smart-account/` \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index d46d37f..b98dabe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -495,11 +495,11 @@ dependencies = [ [[package]] name = "borsh" -version = "1.5.3" +version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2506947f73ad44e344215ccd6403ac2ae18cd8e046e581a441bf8d199f257f03" +checksum = "ad8646f98db542e39fc66e68a20b2144f6a732636df7c2354e74645faaa433ce" dependencies = [ - "borsh-derive 1.5.3", + "borsh-derive 1.5.7", "cfg_aliases", ] @@ -531,9 +531,9 @@ dependencies = [ [[package]] name = "borsh-derive" -version = "1.5.3" +version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2593a3b8b938bd68373196c9832f516be11fa487ef4ae745eb282e6a56a7244" +checksum = "fdd1d3c0c2f5833f22386f252fe8ed005c7f59fdcddeef025c01b4c3b9fd9ac3" dependencies = [ "once_cell", "proc-macro-crate 3.2.0", @@ -1879,7 +1879,7 @@ dependencies = [ "blake3", "borsh 0.10.4", "borsh 0.9.3", - "borsh 1.5.3", + "borsh 1.5.7", "bs58 0.4.0", "bv", "bytemuck", @@ -1928,7 +1928,7 @@ dependencies = [ "base64 0.21.7", "bincode", "bitflags", - "borsh 1.5.3", + "borsh 1.5.7", "bs58 0.4.0", "bytemuck", "byteorder", diff --git a/EVENT_LOGGING_OVERVIEW.md b/EVENT_LOGGING_OVERVIEW.md new file mode 100644 index 0000000..afd43b2 --- /dev/null +++ b/EVENT_LOGGING_OVERVIEW.md @@ -0,0 +1,96 @@ +# Event Logging System Overview + +The smart account program includes a custom event logging mechanism that allows program-controlled accounts to emit structured events. + +## Core Components + +### LogEvent Instruction + +**File**: `programs/squads_smart_account_program/src/instructions/log_event.rs` + +```rust +pub struct LogEventArgsV2 { + pub event: Vec, +} + +#[derive(Accounts)] +pub struct LogEvent<'info> { + #[account( + constraint = Self::validate_log_authority(&log_authority).is_ok(), + owner = crate::id(), + )] + pub log_authority: Signer<'info>, +} +``` + +The instruction itself is minimal - it accepts event data and validates the log authority but doesn't process the data. + +### Log Authority Validation + +Only accounts owned by the smart account program with non-empty, non-zero data can log events: + +```rust +pub fn validate_log_authority(log_authority: &Signer<'info>) -> Result<()> { + let data_len = log_authority.data_len(); + require!(data_len > 0, SmartAccountError::ProtectedInstruction); + + let uninit_data = vec![0; data_len]; + let data = log_authority.try_borrow_data()?; + require!( + &**data != &uninit_data, + SmartAccountError::ProtectedInstruction + ); + Ok(()) +} +``` + +This prevents unauthorized logging by ensuring only legitimate program accounts (with actual state) can emit events. + +## Event Types + +**File**: `programs/squads_smart_account_program/src/events/account_events.rs` + +The system defines structured events for major operations: + +- **CreateSmartAccountEvent**: New smart account creation +- **SynchronousTransactionEvent**: Sync transaction execution +- **SynchronousSettingsTransactionEvent**: Sync settings changes +- **AddSpendingLimitEvent**: Spending limit creation +- **RemoveSpendingLimitEvent**: Spending limit removal +- **UseSpendingLimitEvent**: Spending limit usage +- **AuthoritySettingsEvent**: Authority-based settings changes +- **AuthorityChangeEvent**: Authority transfers + +## Event Emission + +**File**: `programs/squads_smart_account_program/src/events/mod.rs` + +Events are emitted by constructing a cross-program invocation to the LogEvent instruction: + +```rust +impl SmartAccountEvent { + pub fn log<'info>(&self, authority_info: &LogAuthorityInfo<'info>) -> Result<()> { + let data = LogEventArgsV2 { + event: self.try_to_vec()?, + }; + + let ix = solana_program::instruction::Instruction { + program_id: authority_info.program.key(), + accounts: vec![AccountMeta::new_readonly( + authority_info.authority.key(), + true, + )], + data: instruction_data, + }; + + invoke_signed(&ix, &[authority_account_info], &[signer_seeds.as_slice()])?; + Ok(()) + } +} +``` +## File Locations + +- **Instruction**: `programs/squads_smart_account_program/src/instructions/log_event.rs` +- **Event Types**: `programs/squads_smart_account_program/src/events/account_events.rs` +- **Event Logic**: `programs/squads_smart_account_program/src/events/mod.rs` +- **Entry Point**: `programs/squads_smart_account_program/src/lib.rs:337-342` \ No newline at end of file diff --git a/POLICIES_OVERVIEW.md b/POLICIES_OVERVIEW.md new file mode 100644 index 0000000..154a050 --- /dev/null +++ b/POLICIES_OVERVIEW.md @@ -0,0 +1,195 @@ +# Policy System Overview + +The policy system provides an alternative consensus mechanism to full smart account governance. Policies allow pre-approved, parameterized actions that can be executed with reduced overhead compared to the full proposal/voting process. + +## Core Architecture + +### Consensus Interface + +Both smart account settings and policies implement the same `Consensus` trait, allowing them to be used interchangeably for transaction validation. The `ConsensusAccount` enum wraps both types and provides unified access to consensus operations. + +**File**: `programs/squads_smart_account_program/src/interface/consensus.rs` + +```rust +#[derive(Clone)] +pub enum ConsensusAccount { + Settings(Settings), + Policy(Policy), +} +``` + +### Policy Account Structure + +**File**: `programs/squads_smart_account_program/src/state/policies/policy_core/policy.rs` + +```rust +pub struct Policy { + pub settings: Pubkey, // Parent smart account + pub seed: u64, // Unique policy identifier + pub transaction_index: u64, // Latest transaction number + pub stale_transaction_index: u64, // Staleness boundary + pub signers: Vec, // Members with permissions + pub threshold: u16, // Approval threshold + pub time_lock: u32, // Execution delay (seconds) + pub policy_state: PolicyState, // Type-specific configuration + pub start: i64, // Activation timestamp + pub expiration: Option, // Expiration rules +} +``` + +### Stale Transaction Protection + +Policies use the same stale transaction protection as smart account settings. When signers, threshold, or timelock change, all pending transactions become stale and cannot be executed. + +### Permission System + +Each policy signer has granular permissions: +- **Initiate**: Create transactions/proposals +- **Vote**: Approve/reject/cancel proposals +- **Execute**: Execute approved transactions + +## Policy Lifecycle + +### Policy Creation + +Policies are created through `SettingsAction::PolicyCreate` in a settings transaction: + +**File**: `programs/squads_smart_account_program/src/state/settings_transaction.rs` + +```rust +SettingsAction::PolicyCreate { + policy_seed: u64, + policy_signers: Vec, + policy_threshold: u16, + policy_time_lock: u32, + policy_creation_payload: PolicyCreationPayload, + policy_start: i64, + policy_expiration: Option, +} +``` + +### Policy Updates + +Updates use `SettingsAction::PolicyUpdate` and require full smart account governance. Updates invalidate prior transactions via `invalidate_prior_transactions()`. + +### Policy Deletion + +Policies can be deleted using `SettingsAction::PolicyRemove`: + +**File**: `programs/squads_smart_account_program/src/state/settings_transaction.rs` + +```rust +SettingsAction::PolicyRemove { + policy: Pubkey // The policy account to remove +} +``` + +The deletion process verifies policy ownership and closes the account. + +## Policy Expiration + +**File**: `programs/squads_smart_account_program/src/state/policies/policy_core/policy.rs` + +```rust +pub enum PolicyExpiration { + /// Policy expires at a specific timestamp + Timestamp(i64), + /// Policy expires when the core settings hash mismatches the stored hash + SettingsState([u8; 32]), +} +``` + +- **Timestamp**: Unix timestamp-based expiration +- **SettingsState**: Hash-based expiration when parent smart account changes + +## Policy Types + +### 1. SpendingLimitPolicy + +**File**: `programs/squads_smart_account_program/src/state/policies/implementations/spending_limit_policy.rs` + +Allows token and SOL transfers within predefined parameters: +- Source account scoping (specific vault index) +- Destination allowlist +- Time-based limits with automatic resets +- Usage tracking + +### 2. SettingsChangePolicy + +**File**: `programs/squads_smart_account_program/src/state/policies/implementations/settings_change.rs` + +Pre-approved modifications to smart account settings: +- AddSigner with optional constraints +- RemoveSigner with optional constraints +- ChangeThreshold +- ChangeTimeLock + +### 3. ProgramInteractionPolicy + +**File**: `programs/squads_smart_account_program/src/state/policies/implementations/program_interaction.rs` + +Constrained execution of arbitrary program instructions: +- Program ID filtering +- Account constraints +- Data constraints (discriminators, amounts, etc.) +- Optional spending limits integration + +Data constraint system supports: +```rust +pub enum DataValue { + U8(u8), U16Le(u16), U32Le(u32), U64Le(u64), U128Le(u128), + U8Slice(Vec), // For discriminators +} + +pub enum DataOperator { + Equals, NotEquals, GreaterThan, GreaterThanOrEqualTo, + LessThan, LessThanOrEqualTo, +} +``` + +### 4. InternalFundTransferPolicy + +**File**: `programs/squads_smart_account_program/src/state/policies/implementations/internal_fund_transfer.rs` + +Transfer funds between smart account vaults: +- Bitmask representation of allowed source/destination indices +- Mint allowlist (optional) + +## Transaction Execution Modes + +### Consensus-Based (Asynchronous) +Full governance process: Policy Transaction → Proposal → Voting → Time Lock → Execution + +### Synchronous Execution +Direct execution with all required signatures present. Requires time lock = 0 and all signers present. + +### Policy-Specific Execution +Direct policy execution bypassing consensus for pre-approved actions like spending limits. + +## Transaction Cleanup + +### Close Empty Policy Transaction + +**File**: `programs/squads_smart_account_program/src/instructions/transaction_close.rs` + +Cleans up transactions and proposals associated with deleted policy accounts. Validates that the policy account is empty and owned by the system program, then allows unconditional cleanup since the policy address can never be reused. + +## File Locations + +**Core Policy System**: +- `programs/squads_smart_account_program/src/state/policies/policy_core/` +- `programs/squads_smart_account_program/src/interface/consensus.rs` + +**Policy Implementations**: +- `programs/squads_smart_account_program/src/state/policies/implementations/` + +**Settings Integration**: +- `programs/squads_smart_account_program/src/state/settings.rs` +- `programs/squads_smart_account_program/src/state/settings_transaction.rs` + +**Instructions**: +- `programs/squads_smart_account_program/src/instructions/transaction_close.rs` +- `programs/squads_smart_account_program/src/lib.rs` (entry points) + +**Tests**: +- `tests/suites/instructions/policy*.ts` \ No newline at end of file diff --git a/context.md b/context.md new file mode 100644 index 0000000..d0cfe47 --- /dev/null +++ b/context.md @@ -0,0 +1,176 @@ +# Policy Account Implementation Context + +## Project Overview + +We are working on the **Squads Smart Account Program**, a Solana-based multi-signature wallet with configurable governance and spending controls. The project implements a unified policy framework that allows different types of policies to be executed through a common consensus mechanism. + +## Key Architecture Components + +### Smart Account Transaction Modes + +1. **Consensus-Based Transactions**: Full governance with multi-sig approval, voting, time locks +2. **Synchronous Transactions**: Immediate execution with all required signatures +3. **Spending Limits**: Pre-authorized token transfers within defined parameters +4. **Policy Framework**: Extensible system for custom governance rules + +### Core Policy Framework + +The policy system provides: +- **Unified Interface**: All policies implement the same consensus mechanism (signers, thresholds, time locks) +- **Type-Safe Execution**: Each policy type has its own validation and execution logic +- **Extensible Design**: New policy types can be added without breaking existing code + +## Recent Implementation Work + +### Phase 1: Enhanced Policy Execution Pattern (COMPLETED ✅) + +**Problem**: The original policy system had inconsistent execution patterns with manual pattern matching and unused abstractions. + +**Solution**: Implemented a clean trait-based execution system: + +1. **Enhanced PolicyExecutor Trait**: + ```rust + pub trait PolicyExecutor { + type Payload; + fn validate_payload(&self, payload: &Self::Payload) -> Result<()>; + fn execute_payload(&mut self, payload: &Self::Payload, accounts: &[AccountInfo]) -> Result<()>; + } + ``` + +2. **Type-Safe Dispatch Method**: + ```rust + impl PolicyType { + pub fn execute(&mut self, payload: &PolicyPayload, accounts: &[AccountInfo]) -> Result<()> { + match (self, payload) { + (PolicyType::InternalFundTransfer(policy), PolicyPayload::InternalFundTransfer(payload)) => { + policy.validate_payload(payload)?; + policy.execute_payload(payload, accounts) + } + _ => err!(SmartAccountError::InvalidPolicyPayload), + } + } + } + ``` + +3. **Clean Transaction Execution**: Replaced manual pattern matching with single dispatch call: + ```rust + // Before: Manual pattern matching with TODOs + // After: Clean dispatch + policy.policy_type.execute(payload, ctx.remaining_accounts)?; + ``` + +**Results**: +- ✅ All tests passing (3 execution pattern tests) +- ✅ Type safety with compile-time guarantees +- ✅ Preserved unified interface (`InterfaceAccount`) +- ✅ 90% code reuse for consensus logic + +### Phase 2: Directory Reorganization (COMPLETED ✅) + +**Problem**: The policy directory structure was messy and convoluted with mixed concerns. + +**Solution**: Implemented clean separation of concerns: + +``` +src/state/policies/ +├── core/ # Core policy framework +│ ├── traits.rs # PolicyExecutor trait +│ ├── policy.rs # Policy struct + PolicyType enum +│ ├── payloads.rs # PolicyPayload enum +│ └── creation_payloads.rs # Policy creation payloads +├── implementations/ # Specific policy implementations +│ ├── internal_fund_transfer.rs # Internal fund transfer policy +│ ├── spending_limit.rs # Spending limit policy +│ ├── program_interaction.rs # Program interaction policy +│ └── settings_change.rs # Settings change policy +└── tests/ # All policy tests + └── execution_pattern.rs # Framework execution tests +``` + +**Benefits**: +- ✅ Clear separation of framework vs implementations +- ✅ Easy navigation and extensibility +- ✅ Logical grouping of related functionality +- ✅ Clean imports with re-exports + +### Phase 3: Policy Creation via SettingsAction (IN PROGRESS 🔄) + +**Current Goal**: Implement policy creation and removal through SettingsAction for both synchronous and consensus-based execution. + +**Implementation Progress**: + +1. **Added PolicyCreationPayload Framework** ✅: + ```rust + #[derive(AnchorSerialize, AnchorDeserialize, Clone, PartialEq, Eq)] + pub enum PolicyCreationPayload { + InternalFundTransfer(InternalFundTransferPolicyCreationPayload), + } + ``` + +2. **Extended SettingsAction Enum** ✅: + ```rust + pub enum SettingsAction { + // ... existing actions + PolicyCreate { + seed: Pubkey, + policy_creation_payload: PolicyCreationPayload, + signers: Vec, + threshold: u16, + time_lock: u32, + vault_scopes: Vec, + }, + PolicyRemove { + policy: Pubkey + }, + } + ``` + +3. **Implemented Policy Creation/Removal Logic** ✅: + - Added policy creation logic in `Settings::modify_with_action()` + - Handles PDA derivation, account creation, and serialization + - Added policy removal logic with proper ownership validation + - Integrated with existing rent payer and system program patterns + +**Next Steps**: +- Test compilation and fix any issues +- Add comprehensive tests for policy creation/removal +- Test integration with both sync and async settings transactions + +## Key Files and Locations + +### Core Framework +- `src/state/policies/core/policy.rs` - Main Policy struct and PolicyType enum +- `src/state/policies/core/traits.rs` - PolicyExecutor trait definition +- `src/state/policies/core/payloads.rs` - Unified policy payloads +- `src/state/policies/core/creation_payloads.rs` - Policy creation payloads + +### Policy Implementations +- `src/state/policies/implementations/internal_fund_transfer.rs` - Internal fund transfers +- `src/state/policies/implementations/spending_limit.rs` - Token spending limits +- `src/state/policies/implementations/program_interaction.rs` - Constrained program calls + +### Execution Infrastructure +- `src/instructions/transaction_execute.rs` - Policy execution via consensus +- `src/instructions/settings_transaction_execute.rs` - Settings actions via consensus +- `src/instructions/settings_transaction_sync.rs` - Settings actions synchronously +- `src/state/settings.rs` - Settings::modify_with_action() method + +### Tests +- `src/state/policies/tests/execution_pattern.rs` - Core framework tests + +## Design Principles + +1. **Type Safety**: Compile-time guarantees for policy-specific operations +2. **Unified Interface**: Single consensus mechanism for all policy types +3. **Extensibility**: New policies require only trait implementation +4. **Performance**: Zero serialization overhead for state changes +5. **Code Reuse**: 90% shared consensus logic across all policy types + +## Testing Strategy + +- Unit tests for policy validation logic +- Integration tests for creation/removal via SettingsAction +- End-to-end tests with both sync and async execution paths +- All tests use `cargo test --features no-entrypoint` to avoid allocator issues + +This implementation creates a robust, type-safe, and extensible policy framework that maintains the excellent unified interface while providing production-grade ergonomics for smart account governance. \ No newline at end of file diff --git a/package.json b/package.json index 404b0d6..c79e856 100644 --- a/package.json +++ b/package.json @@ -1,33 +1,34 @@ { - "private": true, - "workspaces": [ - "sdk/*" - ], - "scripts": { - "build": "turbo run build", - "test:detached": "turbo run build && anchor test --detach -- --features=testing && echo \"\n⚠️ Don't forget to recompile the .so file before deployment\n\"", - "test": "turbo run build && anchor test -- --features=testing && echo \"\n⚠️ Don't forget to recompile the .so file before deployment\n\"", - "pretest": "mkdir -p target/deploy && cp ./test-program-keypair.json ./target/deploy/squads_smart_account_program-keypair.json", - "ts": "turbo run ts && yarn tsc --noEmit" - }, - "devDependencies": { - "@solana/spl-memo": "^0.2.3", - "@solana/spl-token": "*", - "@types/bn.js": "5.1.0", - "@types/mocha": "10.0.1", - "@types/node-fetch": "2.6.2", - "mocha": "10.2.0", - "prettier": "2.6.2", - "ts-node": "10.9.1", - "turbo": "1.6.3", - "typescript": "*" - }, - "resolutions": { - "@solana/web3.js": "1.70.3", - "@solana/spl-token": "0.3.6", - "typescript": "4.9.4" - }, - "dependencies": { - "@solana/web3.js": "^1.95.5" - } + "private": true, + "workspaces": [ + "sdk/*" + ], + "scripts": { + "build": "turbo run build", + "test:detached": "turbo run build && anchor test --detach -- --features=testing && echo \"\n⚠️ Don't forget to recompile the .so file before deployment\n\"", + "test:detached:nb": "anchor test --detach -- --features=testing && echo \"\n⚠️ Don't forget to recompile the .so file before deployment\n\"", + "test": "turbo run build && anchor test -- --features=testing && echo \"\n⚠️ Don't forget to recompile the .so file before deployment\n\"", + "pretest": "mkdir -p target/deploy && cp ./test-program-keypair.json ./target/deploy/squads_smart_account_program-keypair.json", + "ts": "turbo run ts && yarn tsc --noEmit" + }, + "devDependencies": { + "@solana/spl-memo": "^0.2.3", + "@solana/spl-token": "*", + "@types/mocha": "10.0.1", + "@types/node-fetch": "2.6.2", + "mocha": "10.2.0", + "prettier": "2.6.2", + "ts-node": "10.9.1", + "turbo": "1.6.3", + "typescript": "*" + }, + "resolutions": { + "@solana/web3.js": "1.70.3", + "@solana/spl-token": "0.3.6", + "typescript": "4.9.4" + }, + "dependencies": { + "@solana/web3.js": "^1.95.5" + }, + "packageManager": "yarn@1.22.22" } diff --git a/programs/squads_smart_account_program/src/allocator.rs b/programs/squads_smart_account_program/src/allocator.rs index 61c7128..c0baad2 100644 --- a/programs/squads_smart_account_program/src/allocator.rs +++ b/programs/squads_smart_account_program/src/allocator.rs @@ -129,5 +129,6 @@ unsafe impl std::alloc::GlobalAlloc for BumpAllocator { // Only use the allocator if we're not in a no-entrypoint context #[cfg(not(feature = "no-entrypoint"))] +#[cfg(not(test))] #[global_allocator] static A: BumpAllocator = BumpAllocator; diff --git a/programs/squads_smart_account_program/src/errors.rs b/programs/squads_smart_account_program/src/errors.rs index 5596594..fe50f4e 100644 --- a/programs/squads_smart_account_program/src/errors.rs +++ b/programs/squads_smart_account_program/src/errors.rs @@ -60,8 +60,6 @@ pub enum SmartAccountError { SpendingLimitExceeded, #[msg("Decimals don't match the mint")] DecimalsMismatch, - #[msg("Spending limit is expired")] - SpendingLimitExpired, #[msg("Signer has unknown permission")] UnknownPermission, #[msg("Account is protected, it cannot be passed into a CPI as writable")] @@ -110,4 +108,182 @@ pub enum SmartAccountError { TimeLockNotZero, #[msg("Feature not implemented")] NotImplemented, + #[msg("Invalid cadence configuration")] + SpendingLimitInvalidCadenceConfiguration, + #[msg("Invalid data constraint")] + InvalidDataConstraint, + + + #[msg("Invalid payload")] + InvalidPayload, + #[msg("Protected instruction")] + ProtectedInstruction, + #[msg("Placeholder error")] + PlaceholderError, + + // =============================================== + // Overall Policy Errors + // =============================================== + #[msg("Invalid policy payload")] + InvalidPolicyPayload, + #[msg("Invalid empty policy")] + InvalidEmptyPolicy, + #[msg("Transaction is for another policy")] + TransactionForAnotherPolicy, + + // =============================================== + // Program Interaction Policy Errors + // =============================================== + #[msg("Program interaction sync payload not allowed with async transaction")] + ProgramInteractionAsyncPayloadNotAllowedWithSyncTransaction, + #[msg("Program interaction sync payload not allowed with sync transaction")] + ProgramInteractionSyncPayloadNotAllowedWithAsyncTransaction, + #[msg("Program interaction data constraint failed: instruction data too short")] + ProgramInteractionDataTooShort, + #[msg("Program interaction data constraint failed: invalid numeric value")] + ProgramInteractionInvalidNumericValue, + #[msg("Program interaction data constraint failed: invalid byte sequence")] + ProgramInteractionInvalidByteSequence, + #[msg("Program interaction data constraint failed: unsupported operator for byte slice")] + ProgramInteractionUnsupportedSliceOperator, + #[msg("Program interaction constraint failed: instruction data parsing error")] + ProgramInteractionDataParsingError, + #[msg("Program interaction constraint failed: program ID mismatch")] + ProgramInteractionProgramIdMismatch, + #[msg("Program interaction constraint violation: account constraint")] + ProgramInteractionAccountConstraintViolated, + #[msg("Program interaction constraint violation: instruction constraint index out of bounds")] + ProgramInteractionConstraintIndexOutOfBounds, + #[msg("Program interaction constraint violation: instruction count mismatch")] + ProgramInteractionInstructionCountMismatch, + #[msg("Program interaction constraint violation: insufficient remaining lamport allowance")] + ProgramInteractionInsufficientLamportAllowance, + #[msg("Program interaction constraint violation: insufficient remaining token allowance")] + ProgramInteractionInsufficientTokenAllowance, + #[msg("Program interaction constraint violation: modified illegal balance")] + ProgramInteractionModifiedIllegalBalance, + #[msg("Program interaction constraint violation: illegal token account modification")] + ProgramInteractionIllegalTokenAccountModification, + #[msg("Program interaction invariant violation: duplicate spending limit for the same mint")] + ProgramInteractionDuplicateSpendingLimit, + #[msg("Program interaction constraint violation: too many instruction constraints. Max is 20")] + ProgramInteractionTooManyInstructionConstraints, + #[msg("Program interaction constraint violation: too many spending limits. Max is 10")] + ProgramInteractionTooManySpendingLimits, + #[msg("Program interaction hook violation: template hook error")] + ProgramInteractionTemplateHookError, + #[msg("Program interaction hook violation: hook authority cannot be part of hook accounts")] + ProgramInteractionHookAuthorityCannotBePartOfHookAccounts, + + // =============================================== + // Spending Limit Policy Errors + // =============================================== + #[msg("Spending limit is not active")] + SpendingLimitNotActive, + #[msg("Spending limit is expired")] + SpendingLimitExpired, + #[msg("Spending limit policy invariant violation: usage state cannot be Some() if accumulate_unused is true")] + SpendingLimitPolicyInvariantAccumulateUnused, + #[msg("Amount violates exact quantity constraint")] + SpendingLimitViolatesExactQuantityConstraint, + #[msg("Amount violates max per use constraint")] + SpendingLimitViolatesMaxPerUseConstraint, + #[msg("Spending limit is insufficient")] + SpendingLimitInsufficientRemainingAmount, + #[msg("Spending limit invariant violation: max per period must be non-zero")] + SpendingLimitInvariantMaxPerPeriodZero, + #[msg("Spending limit invariant violation: start time must be positive")] + SpendingLimitInvariantStartTimePositive, + #[msg("Spending limit invariant violation: expiration must be greater than start")] + SpendingLimitInvariantExpirationSmallerThanStart, + #[msg("Spending limit invariant violation: overflow enabled must have expiration")] + SpendingLimitInvariantOverflowEnabledMustHaveExpiration, + #[msg("Spending limit invariant violation: one time period cannot have overflow enabled")] + SpendingLimitInvariantOneTimePeriodCannotHaveOverflowEnabled, + #[msg("Spending limit invariant violation: remaining amount must be less than max amount")] + SpendingLimitInvariantOverflowRemainingAmountGreaterThanMaxAmount, + #[msg("Spending limit invariant violation: remaining amount must be less than or equal to max per period")] + SpendingLimitInvariantRemainingAmountGreaterThanMaxPerPeriod, + #[msg("Spending limit invariant violation: exact quantity must have max per use non-zero")] + SpendingLimitInvariantExactQuantityMaxPerUseZero, + #[msg("Spending limit invariant violation: max per use must be less than or equal to max per period")] + SpendingLimitInvariantMaxPerUseGreaterThanMaxPerPeriod, + #[msg("Spending limit invariant violation: custom period must be positive")] + SpendingLimitInvariantCustomPeriodNegative, + #[msg("Spending limit policy invariant violation: cannot have duplicate destinations for the same mint")] + SpendingLimitPolicyInvariantDuplicateDestinations, + #[msg("Spending limit invariant violation: last reset must be between start and expiration")] + SpendingLimitInvariantLastResetOutOfBounds, + #[msg("Spending limit invariant violation: last reset must be greater than start")] + SpendingLimitInvariantLastResetSmallerThanStart, + + // =============================================== + // Internal Fund Transfer Policy Errors + // =============================================== + #[msg("Internal fund transfer policy invariant violation: source account index is not allowed")] + InternalFundTransferPolicyInvariantSourceAccountIndexNotAllowed, + #[msg("Internal fund transfer policy invariant violation: destination account index is not allowed")] + InternalFundTransferPolicyInvariantDestinationAccountIndexNotAllowed, + #[msg("Internal fund transfer policy invariant violation: source and destination cannot be the same")] + InternalFundTransferPolicyInvariantSourceAndDestinationCannotBeTheSame, + #[msg("Internal fund transfer policy invariant violation: mint is not allowed")] + InternalFundTransferPolicyInvariantMintNotAllowed, + #[msg("Internal fund transfer policy invariant violation: amount must be greater than 0")] + InternalFundTransferPolicyInvariantAmountZero, + #[msg("Internal fund transfer policy invariant violation: cannot have duplicate mints")] + InternalFundTransferPolicyInvariantDuplicateMints, + + // =============================================== + // Consensus Account Errors + // =============================================== + #[msg("Consensus account is not a settings")] + ConsensusAccountNotSettings, + #[msg("Consensus account is not a policy")] + ConsensusAccountNotPolicy, + + // =============================================== + // Settings Change Policy Errors + // =============================================== + #[msg("Settings change policy invariant violation: actions must be non-zero")] + SettingsChangePolicyActionsMustBeNonZero, + #[msg("Settings change policy violation: submitted settings account must match policy settings key")] + SettingsChangeInvalidSettingsKey, + #[msg("Settings change policy violation: submitted settings account must be writable")] + SettingsChangeInvalidSettingsAccount, + #[msg("Settings change policy violation: rent payer must be writable and signer")] + SettingsChangeInvalidRentPayer, + #[msg("Settings change policy violation: system program must be the system program")] + SettingsChangeInvalidSystemProgram, + #[msg("Settings change policy violation: signer does not match allowed signer")] + SettingsChangeAddSignerViolation, + #[msg("Settings change policy violation: signer permissions does not match allowed signer permissions")] + SettingsChangeAddSignerPermissionsViolation, + #[msg("Settings change policy violation: signer removal does not mach allowed signer removal")] + SettingsChangeRemoveSignerViolation, + #[msg("Settings change policy violation: time lock does not match allowed time lock")] + SettingsChangeChangeTimelockViolation, + #[msg("Settings change policy violation: action does not match allowed action")] + SettingsChangeActionMismatch, + #[msg("Settings change policy invariant violation: cannot have duplicate actions")] + SettingsChangePolicyInvariantDuplicateActions, + #[msg("Settings change policy invariant violation: action indices must match actions length")] + SettingsChangePolicyInvariantActionIndicesActionsLengthMismatch, + #[msg("Settings change policy invariant violation: action index out of bounds")] + SettingsChangePolicyInvariantActionIndexOutOfBounds, + + // =============================================== + // Policy Expiration Errors + // =============================================== + #[msg("Policy is not active yet")] + PolicyNotActiveYet, + #[msg("Policy invariant violation: invalid policy expiration")] + PolicyInvariantInvalidExpiration, + #[msg("Policy expiration violation: submitted settings key does not match policy settings key")] + PolicyExpirationViolationPolicySettingsKeyMismatch, + #[msg("Policy expiration violation: state expiration requires the settings to be submitted")] + PolicyExpirationViolationSettingsAccountNotPresent, + #[msg("Policy expiration violation: state hash has expired")] + PolicyExpirationViolationHashExpired, + #[msg("Policy expiration violation: timestamp has expired")] + PolicyExpirationViolationTimestampExpired, } diff --git a/programs/squads_smart_account_program/src/events/account_events.rs b/programs/squads_smart_account_program/src/events/account_events.rs index 8f90125..8d689f1 100644 --- a/programs/squads_smart_account_program/src/events/account_events.rs +++ b/programs/squads_smart_account_program/src/events/account_events.rs @@ -1,15 +1,36 @@ +use crate::{ + consensus_trait::ConsensusAccountType, state::SettingsAction, LimitedSettingsAction, Policy, + PolicyPayload, Proposal, Settings, SettingsTransaction, SmartAccountCompiledInstruction, + SpendingLimit, Transaction, +}; use anchor_lang::prelude::*; use borsh::{BorshDeserialize, BorshSerialize}; -use crate::{state::SettingsAction, Settings, SmartAccountCompiledInstruction, SmartAccountSigner, SpendingLimit}; - - #[derive(BorshSerialize, BorshDeserialize)] pub struct CreateSmartAccountEvent { pub new_settings_pubkey: Pubkey, pub new_settings_content: Settings, } +#[derive(BorshSerialize, BorshDeserialize)] +pub struct SynchronousTransactionEventV2 { + pub consensus_account: Pubkey, + pub consensus_account_type: ConsensusAccountType, + pub signers: Vec, + pub payload: SynchronousTransactionEventPayload, + pub instruction_accounts: Vec, +} +#[derive(BorshSerialize, BorshDeserialize)] +pub enum SynchronousTransactionEventPayload { + TransactionPayload { + account_index: u8, + instructions: Vec, + }, + PolicyPayload { + policy_payload: PolicyPayload, + }, +} + #[derive(BorshSerialize, BorshDeserialize)] pub struct SynchronousTransactionEvent { pub settings_pubkey: Pubkey, @@ -19,13 +40,12 @@ pub struct SynchronousTransactionEvent { pub instruction_accounts: Vec, } - #[derive(BorshSerialize, BorshDeserialize)] pub struct SynchronousSettingsTransactionEvent { pub settings_pubkey: Pubkey, pub signers: Vec, pub settings: Settings, - pub changes: Vec + pub changes: Vec, } #[derive(BorshSerialize, BorshDeserialize)] @@ -41,6 +61,22 @@ pub struct RemoveSpendingLimitEvent { pub spending_limit_pubkey: Pubkey, } +#[derive(BorshSerialize, BorshDeserialize)] +pub struct PolicyEvent { + pub event_type: PolicyEventType, + pub settings_pubkey: Pubkey, + pub policy_pubkey: Pubkey, + pub policy: Option, +} + +#[derive(BorshSerialize, BorshDeserialize)] +pub enum PolicyEventType { + Create, + Update, + UpdateDuringExecution, + Remove, +} + #[derive(BorshSerialize, BorshDeserialize)] pub struct UseSpendingLimitEvent { pub settings_pubkey: Pubkey, @@ -61,7 +97,7 @@ pub struct AuthoritySettingsEvent { pub settings: Settings, pub settings_pubkey: Pubkey, pub authority: Pubkey, - pub change: SettingsAction + pub change: SettingsAction, } #[derive(BorshSerialize, BorshDeserialize)] @@ -69,5 +105,63 @@ pub struct AuthorityChangeEvent { pub settings: Settings, pub settings_pubkey: Pubkey, pub authority: Pubkey, - pub new_authority: Option -} \ No newline at end of file + pub new_authority: Option, +} + +#[derive(BorshSerialize, BorshDeserialize)] +pub struct TransactionEvent { + pub consensus_account: Pubkey, + pub consensus_account_type: ConsensusAccountType, + pub event_type: TransactionEventType, + pub transaction_pubkey: Pubkey, + pub transaction_index: u64, + pub signer: Option, + pub memo: Option, + pub transaction_content: Option, +} + +#[derive(BorshSerialize, BorshDeserialize)] +pub enum TransactionContent { + Transaction(Transaction), + SettingsTransaction { + settings: Settings, + transaction: SettingsTransaction, + changes: Vec, + }, +} + +#[derive(BorshSerialize, BorshDeserialize)] +pub enum TransactionEventType { + Create, + Execute, + Close, +} + +#[derive(BorshSerialize, BorshDeserialize)] +pub struct ProposalEvent { + pub consensus_account: Pubkey, + pub consensus_account_type: ConsensusAccountType, + pub event_type: ProposalEventType, + pub proposal_pubkey: Pubkey, + pub transaction_index: u64, + pub signer: Option, + pub memo: Option, + pub proposal: Option, +} + +#[derive(BorshSerialize, BorshDeserialize)] +pub enum ProposalEventType { + Create, + Approve, + Reject, + Cancel, + Execute, + Close, +} + +#[derive(BorshSerialize, BorshDeserialize)] +pub struct SettingsChangePolicyEvent { + pub settings_pubkey: Pubkey, + pub settings: Settings, + pub changes: Vec, +} diff --git a/programs/squads_smart_account_program/src/events/mod.rs b/programs/squads_smart_account_program/src/events/mod.rs index 63693a2..d4f260e 100644 --- a/programs/squads_smart_account_program/src/events/mod.rs +++ b/programs/squads_smart_account_program/src/events/mod.rs @@ -2,7 +2,7 @@ use anchor_lang::{ prelude::borsh::*, prelude::*, solana_program::program::invoke_signed, Discriminator, }; -use crate::LogEventArgs; +use crate::{LogEventArgsV2}; pub mod account_events; pub use account_events::*; @@ -16,7 +16,12 @@ pub enum SmartAccountEvent { RemoveSpendingLimitEvent(RemoveSpendingLimitEvent), UseSpendingLimitEvent(UseSpendingLimitEvent), AuthoritySettingsEvent(AuthoritySettingsEvent), - AuthorityChangeEvent(AuthorityChangeEvent) + AuthorityChangeEvent(AuthorityChangeEvent), + TransactionEvent(TransactionEvent), + ProposalEvent(ProposalEvent), + SynchronousTransactionEventV2(SynchronousTransactionEventV2), + SettingsChangePolicyEvent(SettingsChangePolicyEvent), + PolicyEvent(PolicyEvent), } pub struct LogAuthorityInfo<'info> { pub authority: AccountInfo<'info>, @@ -34,13 +39,11 @@ impl SmartAccountEvent { let bump_slice = &[authority_info.bump]; signer_seeds.push(bump_slice); - let data = LogEventArgs { - account_seeds: authority_info.authority_seeds.clone(), - bump: authority_info.bump, + let data = LogEventArgsV2 { event: self.try_to_vec()?, }; let mut instruction_data = - Vec::with_capacity(8 + 4 + authority_info.authority_seeds.len() + 4 + data.event.len()); + Vec::with_capacity(8 + 4 + data.event.len()); instruction_data.extend_from_slice(&crate::instruction::LogEvent::DISCRIMINATOR); instruction_data.extend_from_slice(&data.try_to_vec()?); diff --git a/programs/squads_smart_account_program/src/instructions/activate_proposal.rs b/programs/squads_smart_account_program/src/instructions/activate_proposal.rs index 3b547d2..aa3a86c 100644 --- a/programs/squads_smart_account_program/src/instructions/activate_proposal.rs +++ b/programs/squads_smart_account_program/src/instructions/activate_proposal.rs @@ -1,5 +1,6 @@ use anchor_lang::prelude::*; +use crate::consensus_trait::Consensus; use crate::errors::*; use crate::state::*; diff --git a/programs/squads_smart_account_program/src/instructions/authority_settings_transaction_execute.rs b/programs/squads_smart_account_program/src/instructions/authority_settings_transaction_execute.rs index 5b562eb..6eecb9e 100644 --- a/programs/squads_smart_account_program/src/instructions/authority_settings_transaction_execute.rs +++ b/programs/squads_smart_account_program/src/instructions/authority_settings_transaction_execute.rs @@ -1,8 +1,7 @@ use anchor_lang::prelude::*; use crate::{ - errors::*, program::SquadsSmartAccountProgram, state::*, AuthorityChangeEvent, - AuthoritySettingsEvent, LogAuthorityInfo, SmartAccountEvent, + consensus_trait::Consensus, errors::*, program::SquadsSmartAccountProgram, state::*, AuthorityChangeEvent, AuthoritySettingsEvent, LogAuthorityInfo, SmartAccountEvent }; #[derive(AnchorSerialize, AnchorDeserialize)] diff --git a/programs/squads_smart_account_program/src/instructions/authority_spending_limit_add.rs b/programs/squads_smart_account_program/src/instructions/authority_spending_limit_add.rs index df4c775..bb6a792 100644 --- a/programs/squads_smart_account_program/src/instructions/authority_spending_limit_add.rs +++ b/programs/squads_smart_account_program/src/instructions/authority_spending_limit_add.rs @@ -1,8 +1,8 @@ use anchor_lang::prelude::*; use crate::program::SquadsSmartAccountProgram; -use crate::{state::*, LogAuthorityInfo, SmartAccountEvent}; use crate::{errors::*, AuthoritySettingsEvent}; +use crate::{state::*, LogAuthorityInfo, SmartAccountEvent}; #[derive(AnchorSerialize, AnchorDeserialize)] pub struct AddSpendingLimitArgs { diff --git a/programs/squads_smart_account_program/src/instructions/batch_add_transaction.rs b/programs/squads_smart_account_program/src/instructions/batch_add_transaction.rs index 99c4667..241bea2 100644 --- a/programs/squads_smart_account_program/src/instructions/batch_add_transaction.rs +++ b/programs/squads_smart_account_program/src/instructions/batch_add_transaction.rs @@ -1,5 +1,5 @@ use anchor_lang::prelude::*; - +use crate::consensus_trait::Consensus; use crate::errors::*; use crate::state::*; use crate::TransactionMessage; @@ -17,7 +17,7 @@ pub struct AddTransactionToBatch<'info> { /// Settings account this batch belongs to. #[account( seeds = [SEED_PREFIX, SEED_SETTINGS, settings.seed.to_le_bytes().as_ref()], - bump = settings.bump, + bump )] pub settings: Account<'info, Settings>, diff --git a/programs/squads_smart_account_program/src/instructions/batch_create.rs b/programs/squads_smart_account_program/src/instructions/batch_create.rs index 61c5c48..8a3c262 100644 --- a/programs/squads_smart_account_program/src/instructions/batch_create.rs +++ b/programs/squads_smart_account_program/src/instructions/batch_create.rs @@ -1,5 +1,6 @@ use anchor_lang::prelude::*; +use crate::consensus_trait::Consensus; use crate::errors::*; use crate::state::*; @@ -15,7 +16,7 @@ pub struct CreateBatch<'info> { #[account( mut, seeds = [SEED_PREFIX, SEED_SETTINGS, settings.seed.to_le_bytes().as_ref()], - bump = settings.bump, + bump )] pub settings: Account<'info, Settings>, @@ -46,7 +47,9 @@ pub struct CreateBatch<'info> { impl CreateBatch<'_> { fn validate(&self) -> Result<()> { let Self { - settings, creator, .. + settings, + creator, + .. } = self; // creator @@ -72,7 +75,10 @@ impl CreateBatch<'_> { let settings_key = settings.key(); // Increment the transaction index. - let index = settings.transaction_index.checked_add(1).expect("overflow"); + let index = settings + .transaction_index + .checked_add(1) + .expect("overflow"); let smart_account_seeds = &[ SEED_PREFIX, @@ -95,8 +101,8 @@ impl CreateBatch<'_> { batch.invariant()?; - // Updated last transaction index in the settings account. - settings.transaction_index = index; + // Updated last transaction index in the consensus account. + settings.set_transaction_index(index)?; settings.invariant()?; diff --git a/programs/squads_smart_account_program/src/instructions/batch_execute_transaction.rs b/programs/squads_smart_account_program/src/instructions/batch_execute_transaction.rs index 8375c05..686f9fd 100644 --- a/programs/squads_smart_account_program/src/instructions/batch_execute_transaction.rs +++ b/programs/squads_smart_account_program/src/instructions/batch_execute_transaction.rs @@ -1,5 +1,6 @@ use anchor_lang::prelude::*; +use crate::consensus_trait::Consensus; use crate::errors::*; use crate::state::*; use crate::utils::*; @@ -9,7 +10,7 @@ pub struct ExecuteBatchTransaction<'info> { /// Settings account this batch belongs to. #[account( seeds = [SEED_PREFIX, SEED_SETTINGS, settings.seed.to_le_bytes().as_ref()], - bump = settings.bump, + bump )] pub settings: Account<'info, Settings>, diff --git a/programs/squads_smart_account_program/src/instructions/log_event.rs b/programs/squads_smart_account_program/src/instructions/log_event.rs index 3d36990..a38e441 100644 --- a/programs/squads_smart_account_program/src/instructions/log_event.rs +++ b/programs/squads_smart_account_program/src/instructions/log_event.rs @@ -1,35 +1,130 @@ -use anchor_lang::prelude::*; +use crate::{ + instruction::LogEvent as LogEventInstruction, state::ProgramConfig, + Policy, Proposal, Settings, SettingsTransaction, Transaction, +}; +use anchor_lang::{prelude::*, Discriminator}; +use solana_program::instruction::Instruction; +use crate::errors::SmartAccountError; + +// ===== Log Event Instruction ===== +// This custom log instruction saves bytes by not requiring a custom event authority. +// Instead it relies on the log authority to be some signing account with non-zero data in +// it owned by our program. +// +// This means even if you assign a random keypair to the smart account via +// `assign` and `allocate`, it won't be able to log events as it's data will be +// either empty, or zero-initialized to its data length +// ================================ + +// Allowed discriminators for logging events +const ALLOWED_DISCRIMINATORS: [[u8; 8]; 6] = [ + Settings::DISCRIMINATOR, + Policy::DISCRIMINATOR, + Proposal::DISCRIMINATOR, + Transaction::DISCRIMINATOR, + SettingsTransaction::DISCRIMINATOR, + ProgramConfig::DISCRIMINATOR, +]; + +// Legacy log event instruction args. +#[allow(dead_code)] #[derive(AnchorSerialize, AnchorDeserialize, Debug)] pub struct LogEventArgs { pub account_seeds: Vec>, pub bump: u8, pub event: Vec, } +#[derive(AnchorSerialize, AnchorDeserialize, Debug)] +pub struct LogEventArgsV2 { + pub event: Vec, +} #[derive(Accounts)] -#[instruction(args: LogEventArgs)] +#[instruction(args: LogEventArgsV2)] pub struct LogEvent<'info> { #[account( - // Any account owned by the Smart Account Program, except for individual smart accounts, should be able to - // log data. Smart accounts are the only accounts owned by the System Program. + // Any Account owned by our program can log, as long as it's discriminator is allowed + constraint = Self::validate_log_authority(&log_authority).is_ok() @ SmartAccountError::ProtectedInstruction, owner = crate::id(), )] pub log_authority: Signer<'info>, } impl<'info> LogEvent<'info> { - fn validate(&self, args: &LogEventArgs) -> Result<()> { - let mut collected_seeds: Vec<&[u8]> = - args.account_seeds.iter().map(|v| v.as_slice()).collect(); - let bump_slice = &[args.bump]; - collected_seeds.push(bump_slice); - - let derived_address = - Pubkey::create_program_address(collected_seeds.as_slice(), &crate::ID).unwrap(); - assert_eq!(&derived_address, self.log_authority.key); + pub fn log_event( + _ctx: Context<'_, '_, 'info, 'info, Self>, + _args: LogEventArgsV2, + ) -> Result<()> { + Ok(()) + } +} + +impl<'info> LogEvent<'info> { + // Validates that a given log authority is an account that has actual data + // in it. I.e has to have been mutated by the smart account program. + pub fn validate_log_authority(log_authority: &Signer<'info>) -> Result<()> { + // Get the data of the log authority + let data = log_authority.try_borrow_data()?; + + // Extract the discriminator + let discriminator: &[u8; 8] = data + .get(0..8) + .and_then(|slice| slice.try_into().ok()) + .ok_or(SmartAccountError::ProtectedInstruction)?; + + // Check if the discriminator is allowed + require!( + ALLOWED_DISCRIMINATORS.contains(discriminator), + SmartAccountError::ProtectedInstruction + ); + Ok(()) } - #[access_control(ctx.accounts.validate(&args))] - pub fn log_event(ctx: Context<'_, '_, 'info, 'info, Self>, args: LogEventArgs) -> Result<()> { + // Util fn to help check we're not invoking the log event instruction + // from our own program during arbitrary instruction execution. + pub fn check_instruction(ix: &Instruction) -> Result<()> { + // Make sure we're not calling self logging instruction + if ix.program_id == crate::ID { + if let Some(discriminator) = ix.data.get(0..8) { + // Check if the discriminator is the log event discriminator + require!( + discriminator != LogEventInstruction::DISCRIMINATOR, + SmartAccountError::ProtectedInstruction + ); + } + } Ok(()) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_check_instruction() { + // Invalid instruction + let ix = Instruction { + program_id: crate::ID, + accounts: vec![], + data: vec![0x05, 0x09, 0x5a, 0x8d, 0xdf, 0x86, 0x39, 0xd9], + }; + assert!(LogEvent::check_instruction(&ix).is_err()); + + // Valid instruction + let ix = Instruction { + // Valid since we're not calling our program + program_id: Pubkey::default(), + accounts: vec![], + data: vec![0x05, 0x09, 0x5a, 0x8d, 0xdf, 0x86, 0x39, 0xd9], + }; + assert!(LogEvent::check_instruction(&ix).is_ok()); + + // Valid instruction since we're not calling the log event instruction + let ix = Instruction { + program_id: crate::ID, + accounts: vec![], + data: vec![0x05, 0x09, 0x5a, 0x8d, 0xdf, 0x86, 0x39, 0x39], + }; + assert!(LogEvent::check_instruction(&ix).is_ok()); + } +} diff --git a/programs/squads_smart_account_program/src/instructions/mod.rs b/programs/squads_smart_account_program/src/instructions/mod.rs index 6b589e5..07a1f8f 100644 --- a/programs/squads_smart_account_program/src/instructions/mod.rs +++ b/programs/squads_smart_account_program/src/instructions/mod.rs @@ -1,51 +1,53 @@ pub use activate_proposal::*; +pub use authority_settings_transaction_execute::*; +pub use authority_spending_limit_add::*; +pub use authority_spending_limit_remove::*; pub use batch_add_transaction::*; pub use batch_create::*; pub use batch_execute_transaction::*; +pub use log_event::*; +pub use program_config_change::*; +pub use program_config_init::*; pub use proposal_create::*; +pub use proposal_vote::*; pub use settings_transaction_create::*; -pub use smart_account_create::*; -pub use transaction_create::*; pub use settings_transaction_execute::*; -pub use transaction_execute::*; -pub use program_config_init::*; -pub use authority_spending_limit_add::*; -pub use authority_settings_transaction_execute::*; -pub use authority_spending_limit_remove::*; -pub use program_config_change::*; -pub use proposal_vote::*; -pub use use_spending_limit::*; pub use settings_transaction_sync::*; -pub use transaction_close::*; +pub use smart_account_create::*; pub use transaction_buffer_close::*; pub use transaction_buffer_create::*; pub use transaction_buffer_extend::*; +pub use transaction_close::*; +pub use transaction_create::*; pub use transaction_create_from_buffer::*; +pub use transaction_execute::*; pub use transaction_execute_sync::*; -pub use log_event::*; +pub use transaction_execute_sync_legacy::*; +pub use use_spending_limit::*; mod activate_proposal; +mod authority_settings_transaction_execute; +mod authority_spending_limit_add; +mod authority_spending_limit_remove; mod batch_add_transaction; mod batch_create; mod batch_execute_transaction; +mod log_event; +mod program_config_change; +mod program_config_init; mod proposal_create; +mod proposal_vote; mod settings_transaction_create; -mod smart_account_create; -mod transaction_create; mod settings_transaction_execute; -mod transaction_execute; -mod program_config_init; -mod authority_spending_limit_add; -mod authority_settings_transaction_execute; -mod authority_spending_limit_remove; -mod program_config_change; -mod proposal_vote; -mod use_spending_limit; mod settings_transaction_sync; -mod transaction_close; +mod smart_account_create; mod transaction_buffer_close; mod transaction_buffer_create; mod transaction_buffer_extend; +mod transaction_close; +mod transaction_create; mod transaction_create_from_buffer; +mod transaction_execute; mod transaction_execute_sync; -mod log_event; \ No newline at end of file +mod transaction_execute_sync_legacy; +mod use_spending_limit; diff --git a/programs/squads_smart_account_program/src/instructions/proposal_create.rs b/programs/squads_smart_account_program/src/instructions/proposal_create.rs index f71b983..782e610 100644 --- a/programs/squads_smart_account_program/src/instructions/proposal_create.rs +++ b/programs/squads_smart_account_program/src/instructions/proposal_create.rs @@ -1,6 +1,10 @@ use anchor_lang::prelude::*; +use crate::consensus_trait::Consensus; use crate::errors::*; +use crate::interface::consensus::ConsensusAccount; +use crate::events::*; +use crate::program::SquadsSmartAccountProgram; use crate::state::*; #[derive(AnchorSerialize, AnchorDeserialize)] @@ -15,18 +19,17 @@ pub struct CreateProposalArgs { #[instruction(args: CreateProposalArgs)] pub struct CreateProposal<'info> { #[account( - seeds = [SEED_PREFIX, SEED_SETTINGS, settings.seed.to_le_bytes().as_ref()], - bump = settings.bump, + constraint = consensus_account.check_derivation(consensus_account.key()).is_ok() )] - pub settings: Account<'info, Settings>, + pub consensus_account: InterfaceAccount<'info, ConsensusAccount>, #[account( init, payer = rent_payer, - space = Proposal::size(settings.signers.len()), + space = Proposal::size(consensus_account.signers_len()), seeds = [ SEED_PREFIX, - settings.key().as_ref(), + consensus_account.key().as_ref(), SEED_TRANSACTION, &args.transaction_index.to_le_bytes(), SEED_PROPOSAL, @@ -43,41 +46,44 @@ pub struct CreateProposal<'info> { pub rent_payer: Signer<'info>, pub system_program: Program<'info, System>, + pub program: Program<'info, SquadsSmartAccountProgram>, } impl CreateProposal<'_> { - fn validate(&self, args: &CreateProposalArgs) -> Result<()> { + fn validate(&self, ctx: &Context, args: &CreateProposalArgs) -> Result<()> { let Self { - settings, creator, .. + consensus_account, creator, .. } = self; let creator_key = creator.key(); + // Check if the consensus account is active + consensus_account.is_active(&ctx.remaining_accounts)?; + // args // We can only create a proposal for an existing transaction. require!( - args.transaction_index <= settings.transaction_index, + args.transaction_index <= consensus_account.transaction_index(), SmartAccountError::InvalidTransactionIndex ); // We can't create a proposal for a stale transaction. require!( - args.transaction_index > settings.stale_transaction_index, + args.transaction_index > consensus_account.stale_transaction_index(), SmartAccountError::StaleProposal ); // creator // Has to be a signer on the smart account. require!( - self.settings.is_signer(self.creator.key()).is_some(), + consensus_account.is_signer(creator.key()).is_some(), SmartAccountError::NotASigner ); // Must have at least one of the following permissions: Initiate or Vote. require!( - self.settings + consensus_account .signer_has_permission(creator_key, Permission::Initiate) - || self - .settings + || consensus_account .signer_has_permission(creator_key, Permission::Vote), SmartAccountError::Unauthorized ); @@ -86,13 +92,13 @@ impl CreateProposal<'_> { } /// Create a new proposal. - #[access_control(ctx.accounts.validate(&args))] + #[access_control(ctx.accounts.validate(&ctx, &args))] pub fn create_proposal(ctx: Context, args: CreateProposalArgs) -> Result<()> { let proposal = &mut ctx.accounts.proposal; - let settings = &ctx.accounts.settings; + let consensus_account = &ctx.accounts.consensus_account; let rent_payer = &mut ctx.accounts.rent_payer; - proposal.settings = settings.key(); + proposal.settings = consensus_account.key(); proposal.transaction_index = args.transaction_index; proposal.rent_collector = rent_payer.key(); proposal.status = if args.draft { @@ -109,6 +115,25 @@ impl CreateProposal<'_> { proposal.rejected = vec![]; proposal.cancelled = vec![]; + // Log the event + let event = ProposalEvent { + event_type: ProposalEventType::Create, + consensus_account: consensus_account.key(), + consensus_account_type: consensus_account.account_type(), + proposal_pubkey: proposal.key(), + transaction_index: args.transaction_index, + signer: Some(ctx.accounts.creator.key()), + proposal: Some(proposal.clone().into_inner()), + memo: None, + }; + let log_authority_info = LogAuthorityInfo { + authority: consensus_account.to_account_info(), + authority_seeds: consensus_account.get_signer_seeds(), + bump: consensus_account.bump(), + program: ctx.accounts.program.to_account_info(), + }; + SmartAccountEvent::ProposalEvent(event).log(&log_authority_info)?; + Ok(()) } } diff --git a/programs/squads_smart_account_program/src/instructions/proposal_vote.rs b/programs/squads_smart_account_program/src/instructions/proposal_vote.rs index 1bf6ea5..335448c 100644 --- a/programs/squads_smart_account_program/src/instructions/proposal_vote.rs +++ b/programs/squads_smart_account_program/src/instructions/proposal_vote.rs @@ -1,6 +1,11 @@ use anchor_lang::prelude::*; +use crate::consensus_trait::Consensus; use crate::errors::*; +use crate::events::*; +use crate::interface::consensus::ConsensusAccount; +use crate::program::SquadsSmartAccountProgram; + use crate::state::*; #[derive(AnchorSerialize, AnchorDeserialize)] @@ -11,10 +16,9 @@ pub struct VoteOnProposalArgs { #[derive(Accounts)] pub struct VoteOnProposal<'info> { #[account( - seeds = [SEED_PREFIX, SEED_SETTINGS, settings.seed.to_le_bytes().as_ref()], - bump = settings.bump, + constraint = consensus_account.check_derivation(consensus_account.key()).is_ok() )] - pub settings: Account<'info, Settings>, + pub consensus_account: InterfaceAccount<'info, ConsensusAccount>, #[account(mut)] pub signer: Signer<'info>, @@ -23,7 +27,7 @@ pub struct VoteOnProposal<'info> { mut, seeds = [ SEED_PREFIX, - settings.key().as_ref(), + consensus_account.key().as_ref(), SEED_TRANSACTION, &proposal.transaction_index.to_le_bytes(), SEED_PROPOSAL, @@ -34,24 +38,28 @@ pub struct VoteOnProposal<'info> { // Only required for cancelling a proposal. pub system_program: Option>, + pub program: Program<'info, SquadsSmartAccountProgram>, } impl VoteOnProposal<'_> { - fn validate(&self, vote: Vote) -> Result<()> { + fn validate(&self, ctx: &Context, vote: Vote) -> Result<()> { let Self { - settings, + consensus_account, proposal, signer, .. } = self; + // Check if the consensus account is active + consensus_account.is_active(&ctx.remaining_accounts)?; + // signer require!( - settings.is_signer(signer.key()).is_some(), + consensus_account.is_signer(signer.key()).is_some(), SmartAccountError::NotASigner ); require!( - settings.signer_has_permission(signer.key(), Permission::Vote), + consensus_account.signer_has_permission(signer.key(), Permission::Vote), SmartAccountError::Unauthorized ); @@ -64,7 +72,7 @@ impl VoteOnProposal<'_> { ); // CANNOT approve or reject a stale proposal require!( - proposal.transaction_index > settings.stale_transaction_index, + proposal.transaction_index > consensus_account.stale_transaction_index(), SmartAccountError::StaleProposal ); } @@ -82,37 +90,76 @@ impl VoteOnProposal<'_> { /// Approve a smart account proposal on behalf of the `signer`. /// The proposal must be `Active`. - #[access_control(ctx.accounts.validate(Vote::Approve))] - pub fn approve_proposal(ctx: Context, _args: VoteOnProposalArgs) -> Result<()> { - let settings = &mut ctx.accounts.settings; + #[access_control(ctx.accounts.validate(&ctx, Vote::Approve))] + pub fn approve_proposal(ctx: Context, args: VoteOnProposalArgs) -> Result<()> { + let consensus_account = &mut ctx.accounts.consensus_account; + let proposal = &mut ctx.accounts.proposal; let signer = &mut ctx.accounts.signer; - proposal.approve(signer.key(), usize::from(settings.threshold))?; + proposal.approve(signer.key(), usize::from(consensus_account.threshold()))?; + + // Log the vote event with proposal state + let vote_event = ProposalEvent { + event_type: ProposalEventType::Approve, + consensus_account: consensus_account.key(), + consensus_account_type: consensus_account.account_type(), + proposal_pubkey: proposal.key(), + transaction_index: proposal.transaction_index, + signer: Some(signer.key()), + memo: args.memo, + proposal: Some(Proposal::try_from_slice(&proposal.try_to_vec()?)?), + }; + let log_authority_info = LogAuthorityInfo { + authority: consensus_account.to_account_info(), + authority_seeds: consensus_account.get_signer_seeds(), + bump: consensus_account.bump(), + program: ctx.accounts.program.to_account_info(), + }; + SmartAccountEvent::ProposalEvent(vote_event).log(&log_authority_info)?; Ok(()) } /// Reject a smart account proposal on behalf of the `signer`. /// The proposal must be `Active`. - #[access_control(ctx.accounts.validate(Vote::Reject))] - pub fn reject_proposal(ctx: Context, _args: VoteOnProposalArgs) -> Result<()> { - let settings = &mut ctx.accounts.settings; + #[access_control(ctx.accounts.validate(&ctx, Vote::Reject))] + pub fn reject_proposal(ctx: Context, args: VoteOnProposalArgs) -> Result<()> { + let consensus_account = &mut ctx.accounts.consensus_account; let proposal = &mut ctx.accounts.proposal; let signer = &mut ctx.accounts.signer; - let cutoff = Settings::cutoff(&settings); + let cutoff = consensus_account.cutoff(); proposal.reject(signer.key(), cutoff)?; + // Log the vote event with proposal state + let vote_event = ProposalEvent { + event_type: ProposalEventType::Reject, + consensus_account: consensus_account.key(), + consensus_account_type: consensus_account.account_type(), + proposal_pubkey: proposal.key(), + transaction_index: proposal.transaction_index, + signer: Some(signer.key()), + memo: args.memo, + proposal: Some(proposal.clone().into_inner()), + }; + let log_authority_info = LogAuthorityInfo { + authority: consensus_account.to_account_info(), + authority_seeds: consensus_account.get_signer_seeds(), + bump: consensus_account.bump(), + program: ctx.accounts.program.to_account_info(), + }; + SmartAccountEvent::ProposalEvent(vote_event).log(&log_authority_info)?; + Ok(()) } /// Cancel a smart account proposal on behalf of the `signer`. /// The proposal must be `Approved`. - #[access_control(ctx.accounts.validate(Vote::Cancel))] - pub fn cancel_proposal(ctx: Context, _args: VoteOnProposalArgs) -> Result<()> { - let settings = &mut ctx.accounts.settings; + #[access_control(ctx.accounts.validate(&ctx, Vote::Cancel))] + pub fn cancel_proposal(ctx: Context, args: VoteOnProposalArgs) -> Result<()> { + let consensus_account = &mut ctx.accounts.consensus_account; let proposal = &mut ctx.accounts.proposal; let signer = &mut ctx.accounts.signer; let system_program = &ctx @@ -123,17 +170,36 @@ impl VoteOnProposal<'_> { proposal .cancelled - .retain(|k| settings.is_signer(*k).is_some()); + .retain(|k| consensus_account.is_signer(*k).is_some()); - proposal.cancel(signer.key(), usize::from(settings.threshold))?; + proposal.cancel(signer.key(), usize::from(consensus_account.threshold()))?; Proposal::realloc_if_needed( proposal.to_account_info().clone(), - settings.signers.len(), + consensus_account.signers_len(), Some(signer.to_account_info().clone()), Some(system_program.to_account_info().clone()), )?; + // Log the vote event with proposal state + let vote_event = ProposalEvent { + event_type: ProposalEventType::Cancel, + consensus_account: consensus_account.key(), + consensus_account_type: consensus_account.account_type(), + proposal_pubkey: proposal.key(), + transaction_index: proposal.transaction_index, + signer: Some(signer.key()), + memo: args.memo, + proposal: Some(proposal.clone().into_inner()), + }; + let log_authority_info = LogAuthorityInfo { + authority: consensus_account.to_account_info(), + authority_seeds: consensus_account.get_signer_seeds(), + bump: consensus_account.bump(), + program: ctx.accounts.program.to_account_info(), + }; + SmartAccountEvent::ProposalEvent(vote_event).log(&log_authority_info)?; + Ok(()) } } diff --git a/programs/squads_smart_account_program/src/instructions/settings_transaction_create.rs b/programs/squads_smart_account_program/src/instructions/settings_transaction_create.rs index c1f6b7a..5d51098 100644 --- a/programs/squads_smart_account_program/src/instructions/settings_transaction_create.rs +++ b/programs/squads_smart_account_program/src/instructions/settings_transaction_create.rs @@ -1,8 +1,11 @@ use anchor_lang::prelude::*; -use crate::errors::*; -use crate::state::*; +use crate::consensus_trait::{Consensus, ConsensusAccountType}; +use crate::program::SquadsSmartAccountProgram; +use crate::{state::*, SmartAccountEvent}; use crate::utils::validate_settings_actions; +use crate::LogAuthorityInfo; +use crate::{errors::*, TransactionContent, TransactionEvent, TransactionEventType}; #[derive(AnchorSerialize, AnchorDeserialize)] pub struct CreateSettingsTransactionArgs { @@ -42,6 +45,8 @@ pub struct CreateSettingsTransaction<'info> { pub rent_payer: Signer<'info>, pub system_program: Program<'info, System>, + + pub program: Program<'info, SquadsSmartAccountProgram>, } impl CreateSettingsTransaction<'_> { @@ -91,16 +96,37 @@ impl CreateSettingsTransaction<'_> { transaction.rent_collector = rent_payer.key(); transaction.index = transaction_index; transaction.bump = ctx.bumps.transaction; - transaction.actions = args.actions; + transaction.actions = args.actions.clone(); // Updated last transaction index in the settings account. settings.transaction_index = transaction_index; settings.invariant()?; - // Logs for indexing. - msg!("transaction index: {}", transaction_index); - + // Log event authority info + let log_authority_info = LogAuthorityInfo { + authority: settings.to_account_info().clone(), + authority_seeds: get_settings_signer_seeds(settings.seed), + bump: settings.bump, + program: ctx.accounts.program.to_account_info(), + }; + + // Log the event + let event = TransactionEvent { + event_type: TransactionEventType::Create, + consensus_account: settings.key(), + consensus_account_type: ConsensusAccountType::Settings, + transaction_pubkey: transaction.key(), + transaction_index, + signer: Some(creator.key()), + transaction_content: Some(TransactionContent::SettingsTransaction { + settings: settings.clone().into_inner(), + transaction: transaction.clone().into_inner(), + changes: args.actions, + }), + memo: None, + }; + SmartAccountEvent::TransactionEvent(event).log(&log_authority_info)?; Ok(()) } } diff --git a/programs/squads_smart_account_program/src/instructions/settings_transaction_execute.rs b/programs/squads_smart_account_program/src/instructions/settings_transaction_execute.rs index 6aa173f..d2b1af5 100644 --- a/programs/squads_smart_account_program/src/instructions/settings_transaction_execute.rs +++ b/programs/squads_smart_account_program/src/instructions/settings_transaction_execute.rs @@ -1,7 +1,17 @@ use anchor_lang::prelude::*; +use crate::consensus_trait::Consensus; +use crate::consensus_trait::ConsensusAccountType; use crate::errors::*; +use crate::program::SquadsSmartAccountProgram; use crate::state::*; +use crate::LogAuthorityInfo; +use crate::ProposalEvent; +use crate::ProposalEventType; +use crate::SmartAccountEvent; +use crate::TransactionContent; +use crate::TransactionEvent; +use crate::TransactionEventType; #[derive(Accounts)] pub struct ExecuteSettingsTransaction<'info> { @@ -50,6 +60,9 @@ pub struct ExecuteSettingsTransaction<'info> { /// We might need it in case reallocation is needed. pub system_program: Option>, + + pub program: Program<'info, SquadsSmartAccountProgram>, + // In case the transaction contains Add(Remove)SpendingLimit actions, // `remaining_accounts` must contain the SpendingLimit accounts to be initialized/closed. // remaining_accounts @@ -117,6 +130,14 @@ impl<'info> ExecuteSettingsTransaction<'info> { let rent = Rent::get()?; + // Log event authority info + let log_authority_info = LogAuthorityInfo { + authority: settings.to_account_info().clone(), + authority_seeds: get_settings_signer_seeds(settings.seed), + bump: settings.bump, + program: ctx.accounts.program.to_account_info(), + }; + // Execute the actions one by one. for action in transaction.actions.iter() { settings.modify_with_action( @@ -127,6 +148,7 @@ impl<'info> ExecuteSettingsTransaction<'info> { &ctx.accounts.system_program, &ctx.remaining_accounts, &ctx.program_id, + Some(&log_authority_info), )?; } @@ -152,6 +174,37 @@ impl<'info> ExecuteSettingsTransaction<'info> { timestamp: Clock::get()?.unix_timestamp, }; + // Transaction event + let event = TransactionEvent { + event_type: TransactionEventType::Execute, + consensus_account: settings.key(), + consensus_account_type: ConsensusAccountType::Settings, + transaction_pubkey: transaction.key(), + transaction_index: transaction.index, + signer: Some(ctx.accounts.signer.key()), + transaction_content: Some(TransactionContent::SettingsTransaction { + settings: settings.clone().into_inner(), + transaction: transaction.clone().into_inner(), + changes: transaction.actions.clone(), + }), + memo: None, + }; + + // Proposal event + let proposal_event = ProposalEvent { + event_type: ProposalEventType::Execute, + consensus_account: settings.key(), + consensus_account_type: ConsensusAccountType::Settings, + proposal_pubkey: proposal.key(), + transaction_index: transaction.index, + signer: Some(ctx.accounts.signer.key()), + memo: None, + proposal: Some(proposal.clone().into_inner()), + }; + + SmartAccountEvent::TransactionEvent(event).log(&log_authority_info)?; + SmartAccountEvent::ProposalEvent(proposal_event).log(&log_authority_info)?; + Ok(()) } } diff --git a/programs/squads_smart_account_program/src/instructions/settings_transaction_sync.rs b/programs/squads_smart_account_program/src/instructions/settings_transaction_sync.rs index 148888d..c607688 100644 --- a/programs/squads_smart_account_program/src/instructions/settings_transaction_sync.rs +++ b/programs/squads_smart_account_program/src/instructions/settings_transaction_sync.rs @@ -1,7 +1,6 @@ -use account_events::{AddSpendingLimitEvent, RemoveSpendingLimitEvent}; use anchor_lang::prelude::*; -use crate::{errors::*, events::*, program::SquadsSmartAccountProgram, state::*, utils::*}; +use crate::{consensus::ConsensusAccount, consensus_trait::{Consensus, ConsensusAccountType}, errors::*, events::*, program::SquadsSmartAccountProgram, state::*, utils::*}; #[derive(AnchorSerialize, AnchorDeserialize)] pub struct SyncSettingsTransactionArgs { @@ -16,10 +15,10 @@ pub struct SyncSettingsTransactionArgs { pub struct SyncSettingsTransaction<'info> { #[account( mut, - seeds = [SEED_PREFIX, SEED_SETTINGS, settings.seed.to_le_bytes().as_ref()], - bump = settings.bump, + constraint = consensus_account.check_derivation(consensus_account.key()).is_ok(), + constraint = consensus_account.account_type() == ConsensusAccountType::Settings )] - pub settings: Box>, + pub consensus_account: Box>, /// The account that will be charged/credited in case the settings transaction causes space reallocation, /// for example when adding a new signer, adding or removing a spending limit. @@ -41,7 +40,9 @@ impl<'info> SyncSettingsTransaction<'info> { args: &SyncSettingsTransactionArgs, remaining_accounts: &[AccountInfo], ) -> Result<()> { - let Self { settings, .. } = self; + let Self { consensus_account, .. } = self; + // Get the settings + let settings = consensus_account.read_only_settings()?; // Settings must not be controlled require_keys_eq!( @@ -54,7 +55,7 @@ impl<'info> SyncSettingsTransaction<'info> { validate_settings_actions(&args.actions)?; // Validates synchronous consensus across the signers - validate_synchronous_consensus(settings, args.num_signers, remaining_accounts)?; + validate_synchronous_consensus(&consensus_account, args.num_signers, remaining_accounts)?; Ok(()) } @@ -64,10 +65,23 @@ impl<'info> SyncSettingsTransaction<'info> { ctx: Context<'_, '_, 'info, 'info, Self>, args: SyncSettingsTransactionArgs, ) -> Result<()> { - let settings = &mut ctx.accounts.settings; - let settings_key = settings.key(); + // Wrapper consensus account + let consensus_account = &mut ctx.accounts.consensus_account; + let settings_key = consensus_account.key(); + let settings_account_info = consensus_account.to_account_info(); + + let settings = consensus_account.settings()?; + let rent = Rent::get()?; + // Build the log authority info + let log_authority_info = LogAuthorityInfo { + authority: settings_account_info.clone(), + authority_seeds: get_settings_signer_seeds(settings.seed), + bump: settings.bump, + program: ctx.accounts.program.to_account_info(), + }; + // Execute the actions one by one for action in args.actions.iter() { settings.modify_with_action( @@ -78,12 +92,13 @@ impl<'info> SyncSettingsTransaction<'info> { &ctx.accounts.system_program, &ctx.remaining_accounts, &ctx.program_id, + Some(&log_authority_info), )?; } // Make sure the smart account can fit the updated state: added signers or newly set archival_authority. Settings::realloc_if_needed( - settings.to_account_info(), + settings_account_info, settings.signers.len(), ctx.accounts .rent_payer @@ -98,65 +113,19 @@ impl<'info> SyncSettingsTransaction<'info> { // Make sure the settings state is valid after applying the actions settings.invariant()?; - // Log the events + // Log the event let event = SynchronousSettingsTransactionEvent { settings_pubkey: settings_key, signers: ctx.remaining_accounts[..args.num_signers as usize] .iter() .map(|acc| acc.key.clone()) .collect::>(), - settings: Settings::try_from_slice(&settings.try_to_vec()?)?, + settings: settings.clone(), changes: args.actions.clone(), }; - let log_authority_info = LogAuthorityInfo { - authority: settings.to_account_info(), - authority_seeds: get_settings_signer_seeds(settings.seed), - bump: settings.bump, - program: ctx.accounts.program.to_account_info(), - }; + SmartAccountEvent::SynchronousSettingsTransactionEvent(event).log(&log_authority_info)?; - for action in args.actions.iter() { - match action { - SettingsAction::AddSpendingLimit { seed, .. } => { - let spending_limit_pubkey = Pubkey::find_program_address( - &[ - SEED_PREFIX, - settings_key.as_ref(), - SEED_SPENDING_LIMIT, - seed.as_ref(), - ], - &ctx.accounts.program.key(), - ) - .0; - - let spending_limit_data = ctx - .remaining_accounts - .iter() - .find(|acc| acc.key == &spending_limit_pubkey) - .ok_or(SmartAccountError::MissingAccount)? - .try_borrow_data()?; - - - let event = AddSpendingLimitEvent { - settings_pubkey: settings_key, - spending_limit_pubkey: spending_limit_pubkey, - spending_limit: SpendingLimit::try_from_slice(&spending_limit_data[8..])?, - }; - SmartAccountEvent::AddSpendingLimitEvent(event).log(&log_authority_info)?; - } - SettingsAction::RemoveSpendingLimit { spending_limit, .. } => { - let event = RemoveSpendingLimitEvent { - settings_pubkey: settings_key, - spending_limit_pubkey: spending_limit.key(), - }; - SmartAccountEvent::RemoveSpendingLimitEvent(event).log(&log_authority_info)?; - } - _ => { - continue; - } - } - } Ok(()) } } diff --git a/programs/squads_smart_account_program/src/instructions/smart_account_create.rs b/programs/squads_smart_account_program/src/instructions/smart_account_create.rs index dfaac67..b35a824 100644 --- a/programs/squads_smart_account_program/src/instructions/smart_account_create.rs +++ b/programs/squads_smart_account_program/src/instructions/smart_account_create.rs @@ -1,5 +1,3 @@ -#![allow(deprecated)] -use std::borrow::Borrow; use account_events::CreateSmartAccountEvent; use anchor_lang::prelude::*; @@ -97,7 +95,7 @@ impl<'info> CreateSmartAccount<'info> { bump: settings_bump, signers, account_utilization: 0, - _reserved1: 0, + policy_seed: Some(0), _reserved2: 0, }; @@ -128,7 +126,6 @@ impl<'info> CreateSmartAccount<'info> { ), creation_fee, )?; - msg!("Creation fee: {}", creation_fee / LAMPORTS_PER_SOL); } // Increment the smart account index. diff --git a/programs/squads_smart_account_program/src/instructions/transaction_buffer_close.rs b/programs/squads_smart_account_program/src/instructions/transaction_buffer_close.rs index f3f4cb7..31693b9 100644 --- a/programs/squads_smart_account_program/src/instructions/transaction_buffer_close.rs +++ b/programs/squads_smart_account_program/src/instructions/transaction_buffer_close.rs @@ -1,15 +1,16 @@ use anchor_lang::prelude::*; +use crate::consensus_trait::Consensus; use crate::errors::*; +use crate::interface::consensus::ConsensusAccount; use crate::state::*; #[derive(Accounts)] pub struct CloseTransactionBuffer<'info> { #[account( - seeds = [SEED_PREFIX, SEED_SETTINGS, settings.seed.to_le_bytes().as_ref()], - bump = settings.bump, + constraint = consensus_account.check_derivation(consensus_account.key()).is_ok() )] - pub settings: Account<'info, Settings>, + pub consensus_account: InterfaceAccount<'info, ConsensusAccount>, #[account( mut, @@ -21,7 +22,7 @@ pub struct CloseTransactionBuffer<'info> { // current settings transaction index seeds = [ SEED_PREFIX, - settings.key().as_ref(), + consensus_account.key().as_ref(), SEED_TRANSACTION_BUFFER, creator.key().as_ref(), &transaction_buffer.buffer_index.to_le_bytes() diff --git a/programs/squads_smart_account_program/src/instructions/transaction_buffer_create.rs b/programs/squads_smart_account_program/src/instructions/transaction_buffer_create.rs index 21b587e..57efb4f 100644 --- a/programs/squads_smart_account_program/src/instructions/transaction_buffer_create.rs +++ b/programs/squads_smart_account_program/src/instructions/transaction_buffer_create.rs @@ -1,6 +1,8 @@ use anchor_lang::prelude::*; +use crate::consensus_trait::Consensus; use crate::errors::*; +use crate::interface::consensus::ConsensusAccount; use crate::state::MAX_BUFFER_SIZE; use crate::state::*; @@ -22,10 +24,9 @@ pub struct CreateTransactionBufferArgs { #[instruction(args: CreateTransactionBufferArgs)] pub struct CreateTransactionBuffer<'info> { #[account( - seeds = [SEED_PREFIX, SEED_SETTINGS, settings.seed.to_le_bytes().as_ref()], - bump = settings.bump, + constraint = consensus_account.check_derivation(consensus_account.key()).is_ok() )] - pub settings: Account<'info, Settings>, + pub consensus_account: InterfaceAccount<'info, ConsensusAccount>, #[account( init, @@ -33,7 +34,7 @@ pub struct CreateTransactionBuffer<'info> { space = TransactionBuffer::size(args.final_buffer_size)?, seeds = [ SEED_PREFIX, - settings.key().as_ref(), + consensus_account.key().as_ref(), SEED_TRANSACTION_BUFFER, creator.key().as_ref(), &args.buffer_index.to_le_bytes(), @@ -55,17 +56,17 @@ pub struct CreateTransactionBuffer<'info> { impl CreateTransactionBuffer<'_> { fn validate(&self, args: &CreateTransactionBufferArgs) -> Result<()> { let Self { - settings, creator, .. + consensus_account, creator, .. } = self; // creator is a signer on the smart account require!( - settings.is_signer(creator.key()).is_some(), + consensus_account.is_signer(creator.key()).is_some(), SmartAccountError::NotASigner ); // creator has initiate permissions require!( - settings.signer_has_permission(creator.key(), Permission::Initiate), + consensus_account.signer_has_permission(creator.key(), Permission::Initiate), SmartAccountError::Unauthorized ); @@ -86,14 +87,14 @@ impl CreateTransactionBuffer<'_> { // Readonly Accounts let transaction_buffer = &mut ctx.accounts.transaction_buffer; - let settings = &ctx.accounts.settings; + let consensus_account = &ctx.accounts.consensus_account; let creator = &mut ctx.accounts.creator; // Get the buffer index. let buffer_index = args.buffer_index; // Initialize the transaction fields. - transaction_buffer.settings = settings.key(); + transaction_buffer.settings = consensus_account.key(); transaction_buffer.creator = creator.key(); transaction_buffer.account_index = args.account_index; transaction_buffer.buffer_index = buffer_index; diff --git a/programs/squads_smart_account_program/src/instructions/transaction_buffer_extend.rs b/programs/squads_smart_account_program/src/instructions/transaction_buffer_extend.rs index 6c1037a..ae9162a 100644 --- a/programs/squads_smart_account_program/src/instructions/transaction_buffer_extend.rs +++ b/programs/squads_smart_account_program/src/instructions/transaction_buffer_extend.rs @@ -1,6 +1,8 @@ use anchor_lang::prelude::*; +use crate::consensus_trait::Consensus; use crate::errors::*; +use crate::interface::consensus::ConsensusAccount; use crate::state::*; #[derive(AnchorSerialize, AnchorDeserialize)] @@ -13,10 +15,9 @@ pub struct ExtendTransactionBufferArgs { #[instruction(args: ExtendTransactionBufferArgs)] pub struct ExtendTransactionBuffer<'info> { #[account( - seeds = [SEED_PREFIX, SEED_SETTINGS, settings.seed.to_le_bytes().as_ref()], - bump = settings.bump, + constraint = consensus_account.check_derivation(consensus_account.key()).is_ok() )] - pub settings: Account<'info, Settings>, + pub consensus_account: InterfaceAccount<'info, ConsensusAccount>, #[account( mut, @@ -24,7 +25,7 @@ pub struct ExtendTransactionBuffer<'info> { constraint = transaction_buffer.creator == creator.key() @ SmartAccountError::Unauthorized, seeds = [ SEED_PREFIX, - settings.key().as_ref(), + consensus_account.key().as_ref(), SEED_TRANSACTION_BUFFER, creator.key().as_ref(), &transaction_buffer.buffer_index.to_le_bytes() @@ -40,7 +41,7 @@ pub struct ExtendTransactionBuffer<'info> { impl ExtendTransactionBuffer<'_> { fn validate(&self, args: &ExtendTransactionBufferArgs) -> Result<()> { let Self { - settings, + consensus_account, creator, transaction_buffer, .. @@ -48,13 +49,13 @@ impl ExtendTransactionBuffer<'_> { // creator is still a signer on the smart account require!( - settings.is_signer(creator.key()).is_some(), + consensus_account.is_signer(creator.key()).is_some(), SmartAccountError::NotASigner ); // creator still has initiate permissions require!( - settings.signer_has_permission(creator.key(), Permission::Initiate), + consensus_account.signer_has_permission(creator.key(), Permission::Initiate), SmartAccountError::Unauthorized ); diff --git a/programs/squads_smart_account_program/src/instructions/transaction_close.rs b/programs/squads_smart_account_program/src/instructions/transaction_close.rs index 3b8fb3f..b63244b 100644 --- a/programs/squads_smart_account_program/src/instructions/transaction_close.rs +++ b/programs/squads_smart_account_program/src/instructions/transaction_close.rs @@ -10,10 +10,18 @@ //! allows adding the `close` attribute only to `Account<'info, XXX>` types, which forces us //! into having 3 different `Accounts` structs. use anchor_lang::prelude::*; +use anchor_lang::system_program; +use crate::consensus::ConsensusAccount; +use crate::consensus_trait::Consensus; +use crate::consensus_trait::ConsensusAccountType; use crate::errors::*; +use crate::program::SquadsSmartAccountProgram; use crate::state::*; -use crate::utils; +use crate::LogAuthorityInfo; +use crate::SmartAccountEvent; +use crate::TransactionEvent; +use crate::TransactionEventType; #[derive(Accounts)] pub struct CloseSettingsTransaction<'info> { @@ -60,6 +68,7 @@ pub struct CloseSettingsTransaction<'info> { pub transaction_rent_collector: AccountInfo<'info>, pub system_program: Program<'info, System>, + pub program: Program<'info, SquadsSmartAccountProgram>, } impl CloseSettingsTransaction<'_> { @@ -111,11 +120,19 @@ impl CloseSettingsTransaction<'_> { require!(can_close, SmartAccountError::InvalidProposalStatus); + let log_authority_info = LogAuthorityInfo { + authority: settings.to_account_info(), + authority_seeds: get_settings_signer_seeds(settings.seed), + bump: settings.bump, + program: ctx.accounts.program.to_account_info(), + }; // Close the `proposal` account if exists. Proposal::close_if_exists( proposal_account, proposal.to_account_info(), proposal_rent_collector.clone(), + &log_authority_info, + ConsensusAccountType::Settings, )?; // Anchor will close the `transaction` account for us. @@ -126,10 +143,9 @@ impl CloseSettingsTransaction<'_> { #[derive(Accounts)] pub struct CloseTransaction<'info> { #[account( - seeds = [SEED_PREFIX, SEED_SETTINGS, settings.seed.to_le_bytes().as_ref()], - bump = settings.bump, + constraint = consensus_account.check_derivation(consensus_account.key()).is_ok() )] - pub settings: Account<'info, Settings>, + pub consensus_account: InterfaceAccount<'info, ConsensusAccount>, /// CHECK: `seeds` and `bump` verify that the account is the canonical Proposal, /// the logic within `transaction_close` does the rest of the checks. @@ -137,7 +153,7 @@ pub struct CloseTransaction<'info> { mut, seeds = [ SEED_PREFIX, - settings.key().as_ref(), + consensus_account.key().as_ref(), SEED_TRANSACTION, &transaction.index.to_le_bytes(), SEED_PROPOSAL, @@ -149,7 +165,7 @@ pub struct CloseTransaction<'info> { /// Transaction corresponding to the `proposal`. #[account( mut, - has_one = settings @ SmartAccountError::TransactionForAnotherSmartAccount, + has_one = consensus_account @ SmartAccountError::TransactionForAnotherSmartAccount, close = transaction_rent_collector )] pub transaction: Account<'info, Transaction>, @@ -168,6 +184,7 @@ pub struct CloseTransaction<'info> { pub transaction_rent_collector: AccountInfo<'info>, pub system_program: Program<'info, System>, + pub program: Program<'info, SquadsSmartAccountProgram>, } impl CloseTransaction<'_> { @@ -176,12 +193,12 @@ impl CloseTransaction<'_> { /// - the `proposal` is in a terminal state: `Executed`, `Rejected`, or `Cancelled`. /// - the `proposal` is stale and not `Approved`. pub fn close_transaction(ctx: Context) -> Result<()> { - let settings = &ctx.accounts.settings; + let consensus_account = &ctx.accounts.consensus_account; let transaction = &ctx.accounts.transaction; let proposal = &mut ctx.accounts.proposal; let proposal_rent_collector = &ctx.accounts.proposal_rent_collector; - let is_stale = transaction.index <= settings.stale_transaction_index; + let is_stale = transaction.index <= consensus_account.stale_transaction_index(); let proposal_account = if proposal.data.borrow().is_empty() { None @@ -219,13 +236,33 @@ impl CloseTransaction<'_> { require!(can_close, SmartAccountError::InvalidProposalStatus); + let log_authority_info = LogAuthorityInfo { + authority: consensus_account.to_account_info(), + authority_seeds: consensus_account.get_signer_seeds(), + bump: consensus_account.bump(), + program: ctx.accounts.program.to_account_info(), + }; // Close the `proposal` account if exists. Proposal::close_if_exists( proposal_account, proposal.to_account_info(), proposal_rent_collector.clone(), + &log_authority_info, + consensus_account.account_type(), )?; + let event = TransactionEvent { + event_type: TransactionEventType::Close, + consensus_account: consensus_account.key(), + consensus_account_type: consensus_account.account_type(), + transaction_pubkey: transaction.key(), + transaction_index: transaction.index, + signer: None, + transaction_content: None, + memo: None, + }; + + SmartAccountEvent::TransactionEvent(event).log(&log_authority_info)?; // Anchor will close the `transaction` account for us. Ok(()) } @@ -403,6 +440,7 @@ pub struct CloseBatch<'info> { pub batch_rent_collector: AccountInfo<'info>, pub system_program: Program<'info, System>, + pub program: Program<'info, SquadsSmartAccountProgram>, } impl CloseBatch<'_> { @@ -458,15 +496,116 @@ impl CloseBatch<'_> { // Batch must be empty. require_eq!(batch.size, 0, SmartAccountError::BatchNotEmpty); + let log_authority_info = LogAuthorityInfo { + authority: settings.to_account_info(), + authority_seeds: get_settings_signer_seeds(settings.seed), + bump: settings.bump, + program: ctx.accounts.program.to_account_info(), + }; // Close the `proposal` account if exists. Proposal::close_if_exists( proposal_account, proposal.to_account_info(), proposal_rent_collector.clone(), + &log_authority_info, + ConsensusAccountType::Settings, )?; // Anchor will close the `batch` account for us. Ok(()) } } -//endregion + +#[derive(Accounts)] +pub struct CloseEmptyPolicyTransaction<'info> { + /// Global program config account. (Just using this for logging purposes, + /// since we no longer have the consensus account) + #[account(mut, seeds = [SEED_PREFIX, SEED_PROGRAM_CONFIG], bump)] + pub program_config: Account<'info, ProgramConfig>, + + + /// CHECK: We only need to validate the address. + #[account( + constraint = empty_policy.data_is_empty() @ SmartAccountError::InvalidEmptyPolicy, + constraint = empty_policy.owner == &system_program::ID @ SmartAccountError::InvalidEmptyPolicy, + )] + pub empty_policy: AccountInfo<'info>, + + /// CHECK: `seeds` and `bump` verify that the account is the canonical Proposal, + /// the logic within `close_empty_policy_transaction` does the rest of the checks. + #[account( + mut, + seeds = [ + SEED_PREFIX, + empty_policy.key().as_ref(), + SEED_TRANSACTION, + &transaction.index.to_le_bytes(), + SEED_PROPOSAL, + ], + bump, + )] + pub proposal: AccountInfo<'info>, + + /// Transaction corresponding to the `proposal`. + #[account( + mut, + constraint = transaction.consensus_account == empty_policy.key() @ SmartAccountError::TransactionForAnotherPolicy, + close = transaction_rent_collector + )] + pub transaction: Account<'info, Transaction>, + + /// The rent collector for the proposal account. + /// CHECK: validated later inside of `close_empty_policy_transaction`. + #[account(mut)] + pub proposal_rent_collector: AccountInfo<'info>, + + /// The rent collector. + /// CHECK: We only need to validate the address. + #[account( + mut, + address = transaction.rent_collector @ SmartAccountError::InvalidRentCollector, + )] + pub transaction_rent_collector: AccountInfo<'info>, + + pub system_program: Program<'info, System>, + + pub program: Program<'info, SquadsSmartAccountProgram>, +} + +impl CloseEmptyPolicyTransaction<'_> { + /// Closes a `Transaction` and the corresponding `Proposal` for + /// empty/deleted policies. + /// + /// Since a policy can never exist at the same address again after being + /// closed, any transaction & proposal associated with it can be closed safely. + pub fn close_empty_policy_transaction(ctx: Context) -> Result<()> { + let proposal = &mut ctx.accounts.proposal; + let proposal_rent_collector = &ctx.accounts.proposal_rent_collector; + + let proposal_account = if proposal.data.borrow().is_empty() { + None + } else { + Some(Proposal::try_deserialize( + &mut &**proposal.data.borrow_mut(), + )?) + }; + + let log_authority_info = LogAuthorityInfo { + authority: ctx.accounts.program_config.to_account_info(), + authority_seeds: vec![SEED_PREFIX.to_vec(), SEED_PROGRAM_CONFIG.to_vec()], + bump: ctx.bumps.program_config, + program: ctx.accounts.program.to_account_info(), + }; + // Close the `proposal` account if exists. + Proposal::close_if_exists( + proposal_account, + proposal.to_account_info(), + proposal_rent_collector.clone(), + &log_authority_info, + ConsensusAccountType::Policy, + )?; + + // Anchor will close the `transaction` account for us. + Ok(()) + } +} diff --git a/programs/squads_smart_account_program/src/instructions/transaction_create.rs b/programs/squads_smart_account_program/src/instructions/transaction_create.rs index 0ed20d5..c7b7a35 100644 --- a/programs/squads_smart_account_program/src/instructions/transaction_create.rs +++ b/programs/squads_smart_account_program/src/instructions/transaction_create.rs @@ -1,38 +1,56 @@ use anchor_lang::prelude::*; +use crate::consensus_trait::Consensus; use crate::errors::*; +use crate::interface::consensus::ConsensusAccount; +use crate::interface::consensus_trait::ConsensusAccountType; +use crate::events::*; +use crate::program::SquadsSmartAccountProgram; use crate::state::*; use crate::utils::*; -#[derive(AnchorSerialize, AnchorDeserialize)] -pub struct CreateTransactionArgs { - /// Index of the smart account this transaction belongs to. +#[derive(AnchorSerialize, AnchorDeserialize, Clone)] +pub struct TransactionPayload { pub account_index: u8, - /// Number of ephemeral signing PDAs required by the transaction. pub ephemeral_signers: u8, pub transaction_message: Vec, pub memo: Option, } +#[derive(AnchorSerialize, AnchorDeserialize)] +pub enum CreateTransactionArgs { + TransactionPayload(TransactionPayload), + PolicyPayload { + /// The payload of the policy transaction. + payload: PolicyPayload, + }, +} + #[derive(Accounts)] #[instruction(args: CreateTransactionArgs)] pub struct CreateTransaction<'info> { #[account( mut, - seeds = [SEED_PREFIX, SEED_SETTINGS, settings.seed.to_le_bytes().as_ref()], - bump = settings.bump, + constraint = consensus_account.check_derivation(consensus_account.key()).is_ok() )] - pub settings: Account<'info, Settings>, + pub consensus_account: InterfaceAccount<'info, ConsensusAccount>, #[account( init, payer = rent_payer, - space = Transaction::size(args.ephemeral_signers, &args.transaction_message)?, + space = match &args { + CreateTransactionArgs::TransactionPayload(TransactionPayload { ephemeral_signers, transaction_message, .. }) => { + Transaction::size_for_transaction(*ephemeral_signers, transaction_message)? + }, + CreateTransactionArgs::PolicyPayload { payload } => { + Transaction::size_for_policy(payload)? + } + }, seeds = [ SEED_PREFIX, - settings.key().as_ref(), + consensus_account.key().as_ref(), SEED_TRANSACTION, - &settings.transaction_index.checked_add(1).unwrap().to_le_bytes(), + &consensus_account.transaction_index().checked_add(1).unwrap().to_le_bytes(), ], bump )] @@ -46,21 +64,49 @@ pub struct CreateTransaction<'info> { pub rent_payer: Signer<'info>, pub system_program: Program<'info, System>, + pub program: Program<'info, SquadsSmartAccountProgram>, } impl<'info> CreateTransaction<'info> { - pub fn validate(&self) -> Result<()> { + pub fn validate(&self, ctx: &Context, args: &CreateTransactionArgs) -> Result<()> { let Self { - settings, creator, .. + consensus_account, + creator, + .. } = self; + // Check if the consensus account is active + consensus_account.is_active(&ctx.remaining_accounts)?; + + // Validate the transaction payload + match consensus_account.account_type() { + ConsensusAccountType::Settings => { + assert!(matches!( + args, + CreateTransactionArgs::TransactionPayload { .. } + )); + } + ConsensusAccountType::Policy => { + let policy = consensus_account.read_only_policy()?; + // Validate that the args match the policy type + match args { + CreateTransactionArgs::PolicyPayload { payload } => { + // Validate the policy payload against the policy state + policy.validate_payload(PolicyExecutionContext::Asynchronous, payload)?; + } + _ => { + return Err(SmartAccountError::InvalidTransactionMessage.into()); + } + } + } + } // creator require!( - settings.is_signer(creator.key()).is_some(), + consensus_account.is_signer(creator.key()).is_some(), SmartAccountError::NotASigner ); require!( - settings.signer_has_permission(creator.key(), Permission::Initiate), + consensus_account.signer_has_permission(creator.key(), Permission::Initiate), SmartAccountError::Unauthorized ); @@ -68,64 +114,94 @@ impl<'info> CreateTransaction<'info> { } /// Create a new vault transaction. - #[access_control(ctx.accounts.validate())] + #[access_control(ctx.accounts.validate(&ctx, &args))] pub fn create_transaction(ctx: Context, args: CreateTransactionArgs) -> Result<()> { - let settings = &mut ctx.accounts.settings; + let consensus_account = &mut ctx.accounts.consensus_account; let transaction = &mut ctx.accounts.transaction; let creator = &mut ctx.accounts.creator; let rent_payer = &mut ctx.accounts.rent_payer; - let transaction_message = - TransactionMessage::deserialize(&mut args.transaction_message.as_slice())?; - - let settings_key = settings.key(); let transaction_key = transaction.key(); - let smart_account_seeds = &[ - SEED_PREFIX, - settings_key.as_ref(), - SEED_SMART_ACCOUNT, - &args.account_index.to_le_bytes(), - ]; - let (_, smart_account_bump) = - Pubkey::find_program_address(smart_account_seeds, ctx.program_id); - - let ephemeral_signer_bumps: Vec = (0..args.ephemeral_signers) - .map(|ephemeral_signer_index| { - let ephemeral_signer_seeds = &[ - SEED_PREFIX, - transaction_key.as_ref(), - SEED_EPHEMERAL_SIGNER, - &ephemeral_signer_index.to_le_bytes(), - ]; - - let (_, bump) = - Pubkey::find_program_address(ephemeral_signer_seeds, ctx.program_id); - bump - }) - .collect(); - // Increment the transaction index. - let transaction_index = settings.transaction_index.checked_add(1).unwrap(); + let transaction_index = consensus_account + .transaction_index() + .checked_add(1) + .unwrap(); // Initialize the transaction fields. - transaction.settings = settings_key; + transaction.consensus_account = consensus_account.key(); transaction.creator = creator.key(); transaction.rent_collector = rent_payer.key(); transaction.index = transaction_index; - transaction.bump = ctx.bumps.transaction; - transaction.account_index = args.account_index; - transaction.account_bump = smart_account_bump; - transaction.ephemeral_signer_bumps = ephemeral_signer_bumps; - transaction.message = transaction_message.try_into()?; + match (args, consensus_account.account_type()) { + ( + CreateTransactionArgs::TransactionPayload(TransactionPayload { + account_index, + ephemeral_signers, + transaction_message, + memo: _, + }), + ConsensusAccountType::Settings, + ) => { + let transaction_message_parsed = + TransactionMessage::deserialize(&mut transaction_message.as_slice())?; + + let ephemeral_signer_bumps: Vec = (0..ephemeral_signers) + .map(|ephemeral_signer_index| { + let ephemeral_signer_seeds = &[ + SEED_PREFIX, + transaction_key.as_ref(), + SEED_EPHEMERAL_SIGNER, + &ephemeral_signer_index.to_le_bytes(), + ]; + + let (_, bump) = + Pubkey::find_program_address(ephemeral_signer_seeds, ctx.program_id); + bump + }) + .collect(); + + transaction.payload = Payload::TransactionPayload(TransactionPayloadDetails { + account_index: account_index, + ephemeral_signer_bumps, + message: transaction_message_parsed.try_into()?, + }); + } + (CreateTransactionArgs::PolicyPayload { payload }, ConsensusAccountType::Policy) => { + transaction.payload = + Payload::PolicyPayload(PolicyActionPayloadDetails { payload: payload }); + } + _ => { + return Err(SmartAccountError::InvalidTransactionMessage.into()); + } + } // Updated last transaction index in the settings account. - settings.transaction_index = transaction_index; - - settings.invariant()?; - - // Logs for indexing. - msg!("transaction index: {}", transaction_index); + consensus_account.set_transaction_index(transaction_index)?; + + consensus_account.invariant()?; + + // Transaction event + let event = TransactionEvent { + event_type: TransactionEventType::Create, + consensus_account: consensus_account.key(), + consensus_account_type: consensus_account.account_type(), + transaction_pubkey: transaction.key(), + transaction_index, + signer: Some(creator.key()), + transaction_content: Some(TransactionContent::Transaction(transaction.clone().into_inner())), + memo: None, + }; + + // Log event authority info + let log_authority_info = LogAuthorityInfo { + authority: consensus_account.to_account_info(), + authority_seeds: consensus_account.get_signer_seeds(), + bump: consensus_account.bump(), + program: ctx.accounts.program.to_account_info(), + }; + SmartAccountEvent::TransactionEvent(event).log(&log_authority_info)?; Ok(()) } diff --git a/programs/squads_smart_account_program/src/instructions/transaction_create_from_buffer.rs b/programs/squads_smart_account_program/src/instructions/transaction_create_from_buffer.rs index 22aff95..db6b503 100644 --- a/programs/squads_smart_account_program/src/instructions/transaction_create_from_buffer.rs +++ b/programs/squads_smart_account_program/src/instructions/transaction_create_from_buffer.rs @@ -16,7 +16,7 @@ pub struct CreateTransactionFromBuffer<'info> { constraint = transaction_buffer.creator == creator.key() @ SmartAccountError::Unauthorized, seeds = [ SEED_PREFIX, - transaction_create.settings.key().as_ref(), + transaction_create.consensus_account.key().as_ref(), SEED_TRANSACTION_BUFFER, creator.key().as_ref(), &transaction_buffer.buffer_index.to_le_bytes(), @@ -38,11 +38,21 @@ impl<'info> CreateTransactionFromBuffer<'info> { pub fn validate(&self, args: &CreateTransactionArgs) -> Result<()> { let transaction_buffer_account = &self.transaction_buffer; - // Check that the transaction message is "empty" - require!( - args.transaction_message == vec![0, 0, 0, 0, 0, 0], - SmartAccountError::InvalidInstructionArgs - ); + // Check that the transaction message is "empty" and this is a TransactionPayload + match args { + CreateTransactionArgs::PolicyPayload { .. } => { + return Err(SmartAccountError::InvalidInstructionArgs.into()) + } + CreateTransactionArgs::TransactionPayload(TransactionPayload { + transaction_message, + .. + }) => { + require!( + transaction_message == &vec![0, 0, 0, 0, 0, 0], + SmartAccountError::InvalidInstructionArgs + ); + } + } // Validate that the final hash matches the buffer transaction_buffer_account.validate_hash()?; @@ -63,11 +73,7 @@ impl<'info> CreateTransactionFromBuffer<'info> { .transaction_create .transaction .to_account_info(); - let rent_payer_account_info = &ctx - .accounts - .transaction_create - .rent_payer - .to_account_info(); + let rent_payer_account_info = &ctx.accounts.transaction_create.rent_payer.to_account_info(); let system_program = &ctx .accounts @@ -80,8 +86,17 @@ impl<'info> CreateTransactionFromBuffer<'info> { // Calculate the new required length of the transaction account, // since it was initialized with an empty transaction message - let new_len = - Transaction::size(args.ephemeral_signers, transaction_buffer.buffer.as_slice())?; + let new_len = match &args { + CreateTransactionArgs::TransactionPayload(TransactionPayload { + ephemeral_signers, + .. + }) => { + Transaction::size_for_transaction(*ephemeral_signers, &transaction_buffer.buffer)? + } + CreateTransactionArgs::PolicyPayload { .. } => { + return Err(SmartAccountError::InvalidInstructionArgs.into()) + } + }; // Calculate the rent exemption for new length let rent_exempt_lamports = Rent::get().unwrap().minimum_balance(new_len).max(1); @@ -105,11 +120,21 @@ impl<'info> CreateTransactionFromBuffer<'info> { AccountInfo::realloc(&transaction_account_info, new_len, true)?; // Create the args for the `create_transaction` instruction - let create_args = CreateTransactionArgs { - account_index: args.account_index, - ephemeral_signers: args.ephemeral_signers, - transaction_message: transaction_buffer.buffer.clone(), - memo: args.memo, + let create_args = match &args { + CreateTransactionArgs::TransactionPayload(TransactionPayload { + account_index, + ephemeral_signers, + memo, + .. + }) => CreateTransactionArgs::TransactionPayload(TransactionPayload { + account_index: *account_index, + ephemeral_signers: *ephemeral_signers, + transaction_message: transaction_buffer.buffer.clone(), + memo: memo.clone(), + }), + CreateTransactionArgs::PolicyPayload { .. } => { + return Err(SmartAccountError::InvalidInstructionArgs.into()) + } }; // Create the context for the `create_transaction` instruction let context = Context::new( diff --git a/programs/squads_smart_account_program/src/instructions/transaction_execute.rs b/programs/squads_smart_account_program/src/instructions/transaction_execute.rs index 739910f..206d8e9 100644 --- a/programs/squads_smart_account_program/src/instructions/transaction_execute.rs +++ b/programs/squads_smart_account_program/src/instructions/transaction_execute.rs @@ -1,23 +1,28 @@ use anchor_lang::prelude::*; +use crate::consensus_trait::Consensus; +use crate::consensus_trait::ConsensusAccountType; use crate::errors::*; +use crate::events::*; +use crate::interface::consensus::ConsensusAccount; +use crate::program::SquadsSmartAccountProgram; use crate::state::*; use crate::utils::*; #[derive(Accounts)] pub struct ExecuteTransaction<'info> { #[account( - seeds = [SEED_PREFIX, SEED_SETTINGS, settings.seed.to_le_bytes().as_ref()], - bump = settings.bump, + mut, + constraint = consensus_account.check_derivation(consensus_account.key()).is_ok() )] - pub settings: Box>, + pub consensus_account: InterfaceAccount<'info, ConsensusAccount>, /// The proposal account associated with the transaction. #[account( mut, seeds = [ SEED_PREFIX, - settings.key().as_ref(), + consensus_account.key().as_ref(), SEED_TRANSACTION, &transaction.index.to_le_bytes(), SEED_PROPOSAL, @@ -30,37 +35,47 @@ pub struct ExecuteTransaction<'info> { #[account( seeds = [ SEED_PREFIX, - settings.key().as_ref(), + consensus_account.key().as_ref(), SEED_TRANSACTION, &transaction.index.to_le_bytes(), ], - bump = transaction.bump, + bump )] pub transaction: Account<'info, Transaction>, pub signer: Signer<'info>, - // `remaining_accounts` must include the following accounts in the exact order: + pub program: Program<'info, SquadsSmartAccountProgram>, + // `remaining_accounts` must include the following accounts in the exact + // order: + // For transaction execution: // 1. AddressLookupTable accounts in the order they appear in `message.address_table_lookups`. // 2. Accounts in the order they appear in `message.account_keys`. // 3. Accounts in the order they appear in `message.address_table_lookups`. + // + // For policy execution: + // 1. Settings account if the policy has a settings state expiration + // 2. Any remaining accounts associated with the policy } -impl ExecuteTransaction<'_> { - fn validate(&self) -> Result<()> { +impl<'info> ExecuteTransaction<'info> { + fn validate(&self, ctx: &Context>) -> Result<()> { let Self { - settings, + consensus_account, proposal, signer, .. } = self; + // Check if the consensus account is active + consensus_account.is_active(&ctx.remaining_accounts)?; + // signer require!( - settings.is_signer(signer.key()).is_some(), + consensus_account.is_signer(signer.key()).is_some(), SmartAccountError::NotASigner ); require!( - settings.signer_has_permission(signer.key(), Permission::Execute), + consensus_account.signer_has_permission(signer.key(), Permission::Execute), SmartAccountError::Unauthorized ); @@ -68,7 +83,8 @@ impl ExecuteTransaction<'_> { match proposal.status { ProposalStatus::Approved { timestamp } => { require!( - Clock::get()?.unix_timestamp - timestamp >= i64::from(settings.time_lock), + Clock::get()?.unix_timestamp - timestamp + >= i64::from(consensus_account.time_lock()), SmartAccountError::TimeLockNotReleased ); } @@ -84,73 +100,154 @@ impl ExecuteTransaction<'_> { /// Execute the smart account transaction. /// The transaction must be `Approved`. - #[access_control(ctx.accounts.validate())] - pub fn execute_transaction(ctx: Context) -> Result<()> { - let settings = &mut ctx.accounts.settings; + #[access_control(ctx.accounts.validate(&ctx))] + pub fn execute_transaction(ctx: Context<'_, '_, 'info, 'info, Self>) -> Result<()> { + let consensus_account = &mut ctx.accounts.consensus_account; let proposal = &mut ctx.accounts.proposal; - // NOTE: After `take()` is called, the Transaction is reduced to - // its default empty value, which means it should no longer be referenced or - // used after this point to avoid faulty behavior. - // Instead only make use of the returned `transaction` value. - let transaction = ctx.accounts.transaction.take(); + let transaction = &ctx.accounts.transaction; - let settings_key = settings.key(); - let transaction_key = ctx.accounts.transaction.key(); + let consensus_account_key = consensus_account.key(); + let transaction_key = transaction.key(); + let transaction_payload = &transaction.payload; - let smart_account_seeds = &[ - SEED_PREFIX, - settings_key.as_ref(), - SEED_SMART_ACCOUNT, - &transaction.account_index.to_le_bytes(), - &[transaction.account_bump], - ]; - - let transaction_message = transaction.message; - let num_lookups = transaction_message.address_table_lookups.len(); - - let message_account_infos = ctx - .remaining_accounts - .get(num_lookups..) - .ok_or(SmartAccountError::InvalidNumberOfAccounts)?; - let address_lookup_table_account_infos = ctx - .remaining_accounts - .get(..num_lookups) - .ok_or(SmartAccountError::InvalidNumberOfAccounts)?; - - let smart_account_pubkey = - Pubkey::create_program_address(smart_account_seeds, ctx.program_id).unwrap(); - - let (ephemeral_signer_keys, ephemeral_signer_seeds) = - derive_ephemeral_signers(transaction_key, &transaction.ephemeral_signer_bumps); - - let executable_message = ExecutableTransactionMessage::new_validated( - transaction_message, - message_account_infos, - address_lookup_table_account_infos, - &smart_account_pubkey, - &ephemeral_signer_keys, - )?; - - let protected_accounts = &[proposal.key()]; - - // Execute the transaction message instructions one-by-one. - // NOTE: `execute_message()` calls `self.to_instructions_and_accounts()` - // which in turn calls `take()` on - // `self.message.instructions`, therefore after this point no more - // references or usages of `self.message` should be made to avoid - // faulty behavior. - executable_message.execute_message( - smart_account_seeds, - &ephemeral_signer_seeds, - protected_accounts, - )?; + // Log authority info + let log_authority_info = LogAuthorityInfo { + authority: consensus_account.to_account_info(), + authority_seeds: consensus_account.get_signer_seeds(), + bump: consensus_account.bump(), + program: ctx.accounts.program.to_account_info(), + }; + + match consensus_account.account_type() { + ConsensusAccountType::Settings => { + let transaction_payload = transaction_payload.transaction_payload()?; + let smart_account_seeds = &[ + SEED_PREFIX, + consensus_account_key.as_ref(), + SEED_SMART_ACCOUNT, + &transaction_payload.account_index.to_le_bytes(), + ]; + + let (smart_account_key, smart_account_bump) = + Pubkey::find_program_address(smart_account_seeds, &ctx.program_id); + + let smart_account_signer_seeds = &[ + smart_account_seeds[0], + smart_account_seeds[1], + smart_account_seeds[2], + smart_account_seeds[3], + &[smart_account_bump], + ]; + + let num_lookups = transaction_payload.message.address_table_lookups.len(); + + let message_account_infos = &ctx + .remaining_accounts + .get(num_lookups..) + .ok_or(SmartAccountError::InvalidNumberOfAccounts)?; + let address_lookup_table_account_infos = &ctx + .remaining_accounts + .get(..num_lookups) + .ok_or(SmartAccountError::InvalidNumberOfAccounts)?; + + let (ephemeral_signer_keys, ephemeral_signer_seeds) = derive_ephemeral_signers( + transaction_key, + &transaction_payload.ephemeral_signer_bumps, + ); + + let executable_message = ExecutableTransactionMessage::new_validated( + transaction_payload.message.clone(), + message_account_infos, + address_lookup_table_account_infos, + &smart_account_key, + &ephemeral_signer_keys, + )?; + + let protected_accounts = &[proposal.key()]; + + // Execute the transaction message instructions one-by-one. + // NOTE: `execute_message()` calls `self.to_instructions_and_accounts()` + // which in turn calls `take()` on + // `self.message.instructions`, therefore after this point no more + // references or usages of `self.message` should be made to avoid + // faulty behavior. + executable_message.execute_message( + smart_account_signer_seeds, + &ephemeral_signer_seeds, + protected_accounts, + )?; + } + ConsensusAccountType::Policy => { + let policy_payload = transaction_payload.policy_payload()?; + // Extract the policy from the consensus account and execute using dispatch + let policy = consensus_account.policy()?; + // Determine account offset based on policy expiration type + let account_offset = policy + .expiration + .as_ref() + .map(|exp| match exp { + // The settings is the first extra remaining account + PolicyExpiration::SettingsState(_) => 1, + _ => 0, + }) + .unwrap_or(0); + + let remaining_accounts = &ctx.remaining_accounts[account_offset..]; + + policy.execute( + Some(&transaction), + Some(&proposal), + &policy_payload.payload, + remaining_accounts, + )?; + + // Policy may updated during execution, log the event + let policy_event = PolicyEvent { + event_type: PolicyEventType::UpdateDuringExecution, + settings_pubkey: policy.settings, + policy_pubkey: consensus_account_key, + policy: Some(policy.clone()), + }; + SmartAccountEvent::PolicyEvent(policy_event).log(&log_authority_info)?; + } + } // Mark the proposal as executed. proposal.status = ProposalStatus::Executed { timestamp: Clock::get()?.unix_timestamp, }; + // Check the account invariants + consensus_account.invariant()?; + + + // Log the execution event + let execute_event = TransactionEvent { + consensus_account: consensus_account.key(), + consensus_account_type: consensus_account.account_type(), + event_type: TransactionEventType::Execute, + transaction_pubkey: ctx.accounts.transaction.key(), + transaction_index: transaction.index, + signer: Some(ctx.accounts.signer.key()), + memo: None, + transaction_content: Some(TransactionContent::Transaction(transaction.clone().into_inner())), + }; + + // Log the proposal vote event with execution state + let proposal_event = ProposalEvent { + event_type: ProposalEventType::Execute, + consensus_account: consensus_account.key(), + consensus_account_type: consensus_account.account_type(), + proposal_pubkey: proposal.key(), + transaction_index: transaction.index, + signer: Some(ctx.accounts.signer.key()), + memo: None, + proposal: Some(proposal.clone().into_inner()), + }; + SmartAccountEvent::TransactionEvent(execute_event).log(&log_authority_info)?; + SmartAccountEvent::ProposalEvent(proposal_event).log(&log_authority_info)?; + Ok(()) } } diff --git a/programs/squads_smart_account_program/src/instructions/transaction_execute_sync.rs b/programs/squads_smart_account_program/src/instructions/transaction_execute_sync.rs index c5d8ec8..a4bdf9f 100644 --- a/programs/squads_smart_account_program/src/instructions/transaction_execute_sync.rs +++ b/programs/squads_smart_account_program/src/instructions/transaction_execute_sync.rs @@ -1,7 +1,8 @@ -use account_events::SynchronousTransactionEvent; use anchor_lang::prelude::*; use crate::{ + consensus::ConsensusAccount, + consensus_trait::{Consensus, ConsensusAccountType}, errors::*, events::*, program::SquadsSmartAccountProgram, @@ -12,104 +13,233 @@ use crate::{ use super::CompiledInstruction; +#[derive(AnchorSerialize, AnchorDeserialize)] +pub enum SyncPayload { + Transaction(Vec), + Policy(PolicyPayload), +} + +impl SyncPayload { + pub fn to_transaction_payload(&self) -> Result<&Vec> { + match self { + SyncPayload::Transaction(payload) => Ok(payload), + _ => err!(SmartAccountError::InvalidPayload), + } + } + + pub fn to_policy_payload(&self) -> Result<&PolicyPayload> { + match self { + SyncPayload::Policy(payload) => Ok(payload), + _ => err!(SmartAccountError::InvalidPayload), + } + } +} #[derive(AnchorSerialize, AnchorDeserialize)] pub struct SyncTransactionArgs { - /// The index of the smart account this transaction is for pub account_index: u8, - /// The number of signers to reach threshold and adequate permissions pub num_signers: u8, - /// Expected to be serialized as a SmallVec - pub instructions: Vec, + pub payload: SyncPayload, } #[derive(Accounts)] pub struct SyncTransaction<'info> { #[account( - seeds = [SEED_PREFIX, SEED_SETTINGS, settings.seed.to_le_bytes().as_ref()], - bump = settings.bump, + mut, + constraint = consensus_account.check_derivation(consensus_account.key()).is_ok(), )] - pub settings: Box>, + pub consensus_account: Box>, pub program: Program<'info, SquadsSmartAccountProgram>, // `remaining_accounts` must include the following accounts in the exact order: // 1. The exact amount of signers required to reach the threshold - // 2. Any remaining accounts associated with the instructions + // 2. For transaction execution: + // 2.1. Any remaining accounts associated with the instructions + // 3. For policy execution: + // 3.1 Settings account if the policy has a settings state expiration + // 3.2 Any remaining accounts associated with the policy } -impl SyncTransaction<'_> { - #[access_control(validate_synchronous_consensus( &ctx.accounts.settings, args.num_signers, &ctx.remaining_accounts))] - pub fn sync_transaction(ctx: Context, args: SyncTransactionArgs) -> Result<()> { +impl<'info> SyncTransaction<'info> { + fn validate( + &self, + args: &SyncTransactionArgs, + remaining_accounts: &[AccountInfo], + ) -> Result<()> { + let Self { + consensus_account, .. + } = self; + + // Check that the consensus account is active (policy) + consensus_account.is_active(&remaining_accounts[args.num_signers as usize..])?; + + // Validate policy payload if necessary + if consensus_account.account_type() == ConsensusAccountType::Policy { + let policy = consensus_account.read_only_policy()?; + match &args.payload { + SyncPayload::Policy(payload) => { + // Validate the payload against the policy state + policy.validate_payload(PolicyExecutionContext::Synchronous, payload)?; + } + _ => { + return Err(SmartAccountError::ProgramInteractionAsyncPayloadNotAllowedWithSyncTransaction.into()); + } + } + } + + // Synchronous consensus validation + validate_synchronous_consensus(&consensus_account, args.num_signers, remaining_accounts) + } +} + +impl<'info> SyncTransaction<'info> { + #[access_control(ctx.accounts.validate(&args, &ctx.remaining_accounts))] + pub fn sync_transaction( + ctx: Context<'_, '_, 'info, 'info, Self>, + args: SyncTransactionArgs, + ) -> Result<()> { // Readonly Accounts - let settings = &ctx.accounts.settings; - - let settings_key = settings.key(); - // Deserialize the instructions - let compiled_instructions = - SmallVec::::try_from_slice(&args.instructions) - .map_err(|_| SmartAccountError::InvalidInstructionArgs)?; - // Convert to SmartAccountCompiledInstruction - let settings_compiled_instructions: Vec = - Vec::from(compiled_instructions) - .into_iter() - .map(SmartAccountCompiledInstruction::from) - .collect(); - - let smart_account_seeds = &[ - SEED_PREFIX, - settings_key.as_ref(), - SEED_SMART_ACCOUNT, - &args.account_index.to_le_bytes(), - ]; - - let (smart_account_pubkey, smart_account_bump) = - Pubkey::find_program_address(smart_account_seeds, ctx.program_id); - - // Get the signer seeds for the smart account - let smart_account_signer_seeds = &[ - smart_account_seeds[0], - smart_account_seeds[1], - smart_account_seeds[2], - smart_account_seeds[3], - &[smart_account_bump], - ]; - - let executable_message = SynchronousTransactionMessage::new_validated( - &settings.key(), - &settings, - &smart_account_pubkey, - settings_compiled_instructions, - &ctx.remaining_accounts, - )?; - - // Execute the transaction message instructions one-by-one. - // NOTE: `execute_message()` calls `self.to_instructions_and_accounts()` - // which in turn calls `take()` on - // `self.message.instructions`, therefore after this point no more - // references or usages of `self.message` should be made to avoid - // faulty behavior. - executable_message.execute(smart_account_signer_seeds)?; - - // Log the event - let event = SynchronousTransactionEvent { - settings_pubkey: settings.key(), - signers: ctx.remaining_accounts[..args.num_signers as usize] - .iter() - .map(|acc| acc.key.clone()) - .collect(), - account_index: args.account_index, - instructions: executable_message.instructions, - instruction_accounts: executable_message - .accounts - .iter() - .map(|a| a.key.clone()) - .collect(), - }; + let consensus_account = &mut ctx.accounts.consensus_account; + // Remove the signers from the remaining accounts + let remaining_accounts = &ctx.remaining_accounts[args.num_signers as usize..]; + + let consensus_account_key = consensus_account.key(); + + // Log authority info let log_authority_info = LogAuthorityInfo { - authority: settings.to_account_info(), - authority_seeds: get_settings_signer_seeds(settings.seed), - bump: settings.bump, + authority: consensus_account.to_account_info(), + authority_seeds: consensus_account.get_signer_seeds(), + bump: consensus_account.bump(), program: ctx.accounts.program.to_account_info(), }; - SmartAccountEvent::SynchronousTransactionEvent(event).log(&log_authority_info)?; + let event = match consensus_account.account_type() { + ConsensusAccountType::Settings => { + // Get the payload + let payload = args.payload.to_transaction_payload()?; + + let settings = consensus_account.read_only_settings()?; + let settings_key = consensus_account_key; + // Deserialize the instructions + let compiled_instructions = + SmallVec::::try_from_slice(&payload) + .map_err(|_| SmartAccountError::InvalidInstructionArgs)?; + // Convert to SmartAccountCompiledInstruction + let settings_compiled_instructions: Vec = + Vec::from(compiled_instructions) + .into_iter() + .map(SmartAccountCompiledInstruction::from) + .collect(); + + let smart_account_seeds = &[ + SEED_PREFIX, + settings_key.as_ref(), + SEED_SMART_ACCOUNT, + &args.account_index.to_le_bytes(), + ]; + + let (smart_account_pubkey, smart_account_bump) = + Pubkey::find_program_address(smart_account_seeds, ctx.program_id); + + // Get the signer seeds for the smart account + let smart_account_signer_seeds = &[ + smart_account_seeds[0], + smart_account_seeds[1], + smart_account_seeds[2], + smart_account_seeds[3], + &[smart_account_bump], + ]; + + let executable_message = SynchronousTransactionMessage::new_validated( + &settings_key, + &smart_account_pubkey, + &settings.signers, + &settings_compiled_instructions, + &remaining_accounts, + )?; + + // Execute the transaction message instructions one-by-one. + // NOTE: `execute_message()` calls `self.to_instructions_and_accounts()` + // which in turn calls `take()` on + // `self.message.instructions`, therefore after this point no more + // references or usages of `self.message` should be made to avoid + // faulty behavior. + executable_message.execute(smart_account_signer_seeds)?; + + // Create the event + let event = SynchronousTransactionEventV2 { + consensus_account: settings_key, + consensus_account_type: ConsensusAccountType::Settings, + payload: SynchronousTransactionEventPayload::TransactionPayload { + account_index: args.account_index, + instructions: executable_message.instructions.to_vec(), + }, + signers: ctx.remaining_accounts[..args.num_signers as usize] + .iter() + .map(|acc| acc.key.clone()) + .collect(), + instruction_accounts: executable_message + .accounts + .iter() + .map(|a| a.key.clone()) + .collect(), + }; + event + } + ConsensusAccountType::Policy => { + let payload = args.payload.to_policy_payload()?; + let policy = consensus_account.policy()?; + + // Determine account offset based on policy expiration type + let account_offset = policy + .expiration + .as_ref() + .map(|exp| match exp { + // The settings is the first extra remaining account + PolicyExpiration::SettingsState(_) => 1, + _ => 0, + }) + .unwrap_or(0); + + // Potentially remove the settings account for expiration from + // the remaining accounts + let remaining_accounts = &remaining_accounts[account_offset..]; + + // Execute the policy + policy.execute(None, None, payload, &remaining_accounts)?; + + // Policy may updated during execution, log the event + let policy_update_event = PolicyEvent { + event_type: PolicyEventType::UpdateDuringExecution, + settings_pubkey: policy.settings, + policy_pubkey: consensus_account_key, + policy: Some(policy.clone()), + }; + + SmartAccountEvent::PolicyEvent(policy_update_event).log(&log_authority_info)?; + + // Create the event + let event = SynchronousTransactionEventV2 { + consensus_account: consensus_account_key, + consensus_account_type: ConsensusAccountType::Policy, + payload: SynchronousTransactionEventPayload::PolicyPayload { + policy_payload: payload.clone(), + }, + signers: ctx.remaining_accounts[..args.num_signers as usize] + .iter() + .map(|acc| acc.key.clone()) + .collect(), + instruction_accounts: remaining_accounts + .iter() + .map(|acc| acc.key.clone()) + .collect(), + }; + event + } + }; + + // Check the policy invariant + consensus_account.invariant()?; + + SmartAccountEvent::SynchronousTransactionEventV2(event).log(&log_authority_info)?; + Ok(()) } } diff --git a/programs/squads_smart_account_program/src/instructions/transaction_execute_sync_legacy.rs b/programs/squads_smart_account_program/src/instructions/transaction_execute_sync_legacy.rs new file mode 100644 index 0000000..7a573de --- /dev/null +++ b/programs/squads_smart_account_program/src/instructions/transaction_execute_sync_legacy.rs @@ -0,0 +1,128 @@ +use account_events::SynchronousTransactionEvent; +use anchor_lang::prelude::*; + +use crate::{ + consensus::ConsensusAccount, + consensus_trait::{Consensus, ConsensusAccountType}, + errors::*, + events::*, + program::SquadsSmartAccountProgram, + state::*, + utils::{validate_synchronous_consensus, SynchronousTransactionMessage}, + SmallVec, +}; + +use super::CompiledInstruction; + +#[derive(AnchorSerialize, AnchorDeserialize)] +pub struct LegacySyncTransactionArgs { + /// The index of the smart account this transaction is for + pub account_index: u8, + /// The number of signers to reach threshold and adequate permissions + pub num_signers: u8, + /// Expected to be serialized as a SmallVec + pub instructions: Vec, +} + +#[derive(Accounts)] +pub struct LegacySyncTransaction<'info> { + #[account( + constraint = consensus_account.check_derivation(consensus_account.key()).is_ok(), + // Legacy sync transactions only support settings + constraint = consensus_account.account_type() == ConsensusAccountType::Settings + )] + pub consensus_account: Box>, + pub program: Program<'info, SquadsSmartAccountProgram>, + // `remaining_accounts` must include the following accounts in the exact order: + // 1. The exact amount of signers required to reach the threshold + // 2. Any remaining accounts associated with the instructions +} + +impl LegacySyncTransaction<'_> { + fn validate( + &self, + args: &LegacySyncTransactionArgs, + remaining_accounts: &[AccountInfo], + ) -> Result<()> { + let Self { consensus_account, .. } = self; + validate_synchronous_consensus(&consensus_account, args.num_signers, remaining_accounts) + } + #[access_control(ctx.accounts.validate(&args, &ctx.remaining_accounts))] + pub fn sync_transaction(ctx: Context, args: LegacySyncTransactionArgs) -> Result<()> { + // Wrapper consensus account + let consensus_account = &ctx.accounts.consensus_account; + let settings = consensus_account.read_only_settings()?; + let settings_key = consensus_account.key(); + let settings_account_info = consensus_account.to_account_info(); + + // Deserialize the instructions + let compiled_instructions = + SmallVec::::try_from_slice(&args.instructions) + .map_err(|_| SmartAccountError::InvalidInstructionArgs)?; + // Convert to SmartAccountCompiledInstruction + let settings_compiled_instructions: Vec = + Vec::from(compiled_instructions) + .into_iter() + .map(SmartAccountCompiledInstruction::from) + .collect(); + + let smart_account_seeds = &[ + SEED_PREFIX, + settings_key.as_ref(), + SEED_SMART_ACCOUNT, + &args.account_index.to_le_bytes(), + ]; + + let (smart_account_pubkey, smart_account_bump) = + Pubkey::find_program_address(smart_account_seeds, ctx.program_id); + + // Get the signer seeds for the smart account + let smart_account_signer_seeds = &[ + smart_account_seeds[0], + smart_account_seeds[1], + smart_account_seeds[2], + smart_account_seeds[3], + &[smart_account_bump], + ]; + + let executable_message = SynchronousTransactionMessage::new_validated( + &settings_key, + &smart_account_pubkey, + &settings.signers, + &settings_compiled_instructions, + &ctx.remaining_accounts, + )?; + + // Execute the transaction message instructions one-by-one. + // NOTE: `execute_message()` calls `self.to_instructions_and_accounts()` + // which in turn calls `take()` on + // `self.message.instructions`, therefore after this point no more + // references or usages of `self.message` should be made to avoid + // faulty behavior. + executable_message.execute(smart_account_signer_seeds)?; + + // Log the event + let event = SynchronousTransactionEvent { + settings_pubkey: settings_key, + signers: ctx.remaining_accounts[..args.num_signers as usize] + .iter() + .map(|acc| acc.key.clone()) + .collect(), + account_index: args.account_index, + instructions: executable_message.instructions.to_vec(), + instruction_accounts: executable_message + .accounts + .iter() + .map(|a| a.key.clone()) + .collect(), + }; + let log_authority_info = LogAuthorityInfo { + authority: settings_account_info, + authority_seeds: get_settings_signer_seeds(settings.seed), + bump: settings.bump, + program: ctx.accounts.program.to_account_info(), + }; + SmartAccountEvent::SynchronousTransactionEvent(event).log(&log_authority_info)?; + Ok(()) + } +} diff --git a/programs/squads_smart_account_program/src/interface/consensus.rs b/programs/squads_smart_account_program/src/interface/consensus.rs new file mode 100644 index 0000000..54c43f8 --- /dev/null +++ b/programs/squads_smart_account_program/src/interface/consensus.rs @@ -0,0 +1,216 @@ +use anchor_lang::{ + prelude::{AccountInfo, Pubkey}, + AccountDeserialize, AccountSerialize, Discriminator, Owners, Result, +}; + +use crate::{ + errors::SmartAccountError, get_policy_signer_seeds, get_settings_signer_seeds, state::{Policy, Settings}, SmartAccountSigner +}; + +use super::consensus_trait::{Consensus, ConsensusAccountType}; + +#[derive(Clone)] +pub enum ConsensusAccount { + Settings(Settings), + Policy(Policy), +} + +static OWNERS: [Pubkey; 1] = [crate::ID]; + +// Implemented for InterfaceAccount +impl Owners for ConsensusAccount { + // Just our own program ID, since the interface account is just to wrap the trait + fn owners() -> &'static [Pubkey] { + &OWNERS + } +} + +// Implemented for InterfaceAccount +impl AccountSerialize for ConsensusAccount { + fn try_serialize(&self, writer: &mut W) -> anchor_lang::Result<()> { + match self { + ConsensusAccount::Settings(settings) => settings.try_serialize(writer), + ConsensusAccount::Policy(policy) => policy.try_serialize(writer), + } + } +} + +// Implemented for InterfaceAccount +impl AccountDeserialize for ConsensusAccount { + fn try_deserialize(reader: &mut &[u8]) -> anchor_lang::Result { + let discriminator: [u8; 8] = reader[..8].try_into().unwrap(); + match discriminator { + Settings::DISCRIMINATOR => Ok(ConsensusAccount::Settings(Settings::try_deserialize( + reader, + )?)), + Policy::DISCRIMINATOR => Ok(ConsensusAccount::Policy(Policy::try_deserialize(reader)?)), + _ => Err(anchor_lang::error::Error::from( + anchor_lang::error::ErrorCode::AccountDiscriminatorMismatch, + )), + } + } + + fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result { + let discriminator: [u8; 8] = buf[..8].try_into().unwrap(); + match discriminator { + Settings::DISCRIMINATOR => Ok(ConsensusAccount::Settings( + Settings::try_deserialize_unchecked(buf)?, + )), + Policy::DISCRIMINATOR => Ok(ConsensusAccount::Policy( + Policy::try_deserialize_unchecked(buf)?, + )), + _ => Err(anchor_lang::error::Error::from( + anchor_lang::error::ErrorCode::AccountDiscriminatorMismatch, + )), + } + } +} + +impl ConsensusAccount { + /// Returns the number of signers in the consensus account. + pub fn signers_len(&self) -> usize { + self.signers().len() + } + + /// Returns the bump for the consensus account. + pub fn bump(&self) -> u8 { + match self { + ConsensusAccount::Settings(settings) => settings.bump, + ConsensusAccount::Policy(policy) => policy.bump, + } + } + /// Returns the signer seeds for the consensus account. + pub fn get_signer_seeds(&self) -> Vec> { + match self { + ConsensusAccount::Settings(settings) => get_settings_signer_seeds(settings.seed), + ConsensusAccount::Policy(policy) => get_policy_signer_seeds(&policy.settings, policy.seed), + } + } + /// Returns the settings if the consensus account is a settings. + pub fn settings(&mut self) -> Result<&mut Settings> { + match self { + ConsensusAccount::Settings(settings) => Ok(settings), + ConsensusAccount::Policy(_) => { + Err(SmartAccountError::ConsensusAccountNotSettings.into()) + } + } + } + + /// Returns the settings if the consensus account is a settings. + pub fn read_only_settings(&self) -> Result<&Settings> { + match self { + ConsensusAccount::Settings(settings) => Ok(settings), + ConsensusAccount::Policy(_) => { + Err(SmartAccountError::ConsensusAccountNotSettings.into()) + } + } + } + + /// Returns the policy if the consensus account is a policy. + pub fn policy(&mut self) -> Result<&mut Policy> { + match self { + ConsensusAccount::Settings(_) => { + return Err(SmartAccountError::ConsensusAccountNotPolicy.into()) + } + ConsensusAccount::Policy(policy) => Ok(policy), + } + } + + /// Returns the policy if the consensus account is a policy. + pub fn read_only_policy(&self) -> Result<&Policy> { + match self { + ConsensusAccount::Settings(_) => { + return Err(SmartAccountError::ConsensusAccountNotPolicy.into()) + } + ConsensusAccount::Policy(policy) => Ok(policy), + } + } + + /// Helper method to delegate to the underlying consensus implementation + fn as_consensus(&self) -> &dyn Consensus { + match self { + ConsensusAccount::Settings(settings) => settings, + ConsensusAccount::Policy(policy) => policy, + } + } + + /// Helper method to delegate to the underlying consensus implementation (mutable) + fn as_consensus_mut(&mut self) -> &mut dyn Consensus { + match self { + ConsensusAccount::Settings(settings) => settings, + ConsensusAccount::Policy(policy) => policy, + } + } +} + +impl Consensus for ConsensusAccount { + fn is_active(&self, accounts: &[AccountInfo]) -> Result<()> { + self.as_consensus().is_active(accounts) + } + + fn check_derivation(&self, key: Pubkey) -> Result<()> { + self.as_consensus().check_derivation(key) + } + + fn account_type(&self) -> ConsensusAccountType { + self.as_consensus().account_type() + } + + fn signers(&self) -> &[SmartAccountSigner] { + self.as_consensus().signers() + } + + fn threshold(&self) -> u16 { + self.as_consensus().threshold() + } + + fn time_lock(&self) -> u32 { + self.as_consensus().time_lock() + } + + fn transaction_index(&self) -> u64 { + self.as_consensus().transaction_index() + } + + fn set_transaction_index(&mut self, transaction_index: u64) -> Result<()> { + self.as_consensus_mut() + .set_transaction_index(transaction_index) + } + + fn stale_transaction_index(&self) -> u64 { + self.as_consensus().stale_transaction_index() + } + + fn invalidate_prior_transactions(&mut self) { + self.as_consensus_mut().invalidate_prior_transactions() + } + + fn is_signer(&self, signer_pubkey: Pubkey) -> Option { + self.as_consensus().is_signer(signer_pubkey) + } + + fn signer_has_permission(&self, signer_pubkey: Pubkey, permission: crate::Permission) -> bool { + self.as_consensus() + .signer_has_permission(signer_pubkey, permission) + } + + fn num_voters(&self) -> usize { + self.as_consensus().num_voters() + } + + fn num_proposers(&self) -> usize { + self.as_consensus().num_proposers() + } + + fn num_executors(&self) -> usize { + self.as_consensus().num_executors() + } + + fn cutoff(&self) -> usize { + self.as_consensus().cutoff() + } + + fn invariant(&self) -> Result<()> { + self.as_consensus().invariant() + } +} diff --git a/programs/squads_smart_account_program/src/interface/consensus_trait.rs b/programs/squads_smart_account_program/src/interface/consensus_trait.rs new file mode 100644 index 0000000..08ce7eb --- /dev/null +++ b/programs/squads_smart_account_program/src/interface/consensus_trait.rs @@ -0,0 +1,78 @@ +use anchor_lang::prelude::*; +use borsh::{BorshDeserialize, BorshSerialize}; + +use crate::{Permission, SmartAccountSigner}; + +#[derive(BorshSerialize, BorshDeserialize, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug)] +pub enum ConsensusAccountType { + Settings, + Policy, +} + +pub trait Consensus { + fn account_type(&self) -> ConsensusAccountType; + fn check_derivation(&self, key: Pubkey) -> Result<()>; + fn is_active(&self, accounts: &[AccountInfo]) -> Result<()>; + + // Core consensus fields + fn signers(&self) -> &[SmartAccountSigner]; + fn threshold(&self) -> u16; + fn time_lock(&self) -> u32; + fn transaction_index(&self) -> u64; + fn set_transaction_index(&mut self, transaction_index: u64) -> Result<()>; + fn stale_transaction_index(&self) -> u64; + + // Returns `Some(index)` if `signer_pubkey` is a signer, with `index` into the `signers` vec. + /// `None` otherwise. + fn is_signer(&self, signer_pubkey: Pubkey) -> Option { + self.signers() + .binary_search_by_key(&signer_pubkey, |s| s.key) + .ok() + } + + fn signer_has_permission(&self, signer_pubkey: Pubkey, permission: Permission) -> bool { + match self.is_signer(signer_pubkey) { + Some(index) => self.signers()[index].permissions.has(permission), + _ => false, + } + } + + // Permission counting methods + fn num_voters(&self) -> usize { + self.signers() + .iter() + .filter(|s| s.permissions.has(Permission::Vote)) + .count() + } + + fn num_proposers(&self) -> usize { + self.signers() + .iter() + .filter(|s| s.permissions.has(Permission::Initiate)) + .count() + } + + fn num_executors(&self) -> usize { + self.signers() + .iter() + .filter(|s| s.permissions.has(Permission::Execute)) + .count() + } + + /// How many "reject" votes are enough to make the transaction "Rejected". + /// The cutoff must be such that it is impossible for the remaining voters to reach the approval threshold. + /// For example: total voters = 7, threshold = 3, cutoff = 5. + fn cutoff(&self) -> usize { + self.num_voters() + .checked_sub(usize::from(self.threshold())) + .unwrap() + .checked_add(1) + .unwrap() + } + + // Stale transaction protection (ported from Settings) + fn invalidate_prior_transactions(&mut self); + + // Consensus validation (ported from Settings invariant) + fn invariant(&self) -> Result<()>; +} diff --git a/programs/squads_smart_account_program/src/interface/mod.rs b/programs/squads_smart_account_program/src/interface/mod.rs new file mode 100644 index 0000000..55ed2aa --- /dev/null +++ b/programs/squads_smart_account_program/src/interface/mod.rs @@ -0,0 +1,2 @@ +pub mod consensus; +pub mod consensus_trait; \ No newline at end of file diff --git a/programs/squads_smart_account_program/src/lib.rs b/programs/squads_smart_account_program/src/lib.rs index cf05546..5c36d5d 100644 --- a/programs/squads_smart_account_program/src/lib.rs +++ b/programs/squads_smart_account_program/src/lib.rs @@ -10,18 +10,20 @@ use anchor_lang::prelude::*; #[cfg(not(feature = "no-entrypoint"))] use solana_security_txt::security_txt; +pub use events::*; pub use instructions::ProgramConfig; pub use instructions::*; +pub use interface::*; pub use state::*; pub use utils::SmallVec; -pub use events::*; pub mod allocator; pub mod errors; +pub mod events; pub mod instructions; +pub mod interface; pub mod state; mod utils; -pub mod events; #[cfg(not(feature = "no-entrypoint"))] security_txt! { @@ -204,7 +206,9 @@ pub mod squads_smart_account_program { /// Execute a smart account transaction. /// The transaction must be `Approved`. - pub fn execute_transaction(ctx: Context) -> Result<()> { + pub fn execute_transaction<'info>( + ctx: Context<'_, '_, 'info, 'info, ExecuteTransaction<'info>>, + ) -> Result<()> { ExecuteTransaction::execute_transaction(ctx) } @@ -255,10 +259,12 @@ pub mod squads_smart_account_program { } /// Use a spending limit to transfer tokens from a smart account vault to a destination account. + #[deprecated(note = "Use the spending limit policy instead")] pub fn use_spending_limit( ctx: Context, args: UseSpendingLimitArgs, ) -> Result<()> { + msg!("Method is being deprecated. Use the new spending limit policy instead"); UseSpendingLimit::use_spending_limit(ctx, args) } @@ -278,6 +284,12 @@ pub mod squads_smart_account_program { CloseTransaction::close_transaction(ctx) } + /// Closes a `Transaction` and the corresponding `Proposal` for + /// empty/deleted policies. + pub fn close_empty_policy_transaction(ctx: Context) -> Result<()> { + CloseEmptyPolicyTransaction::close_empty_policy_transaction(ctx) + } + /// Closes a `BatchTransaction` belonging to the `batch` and `proposal`. /// `transaction` can be closed if either: /// - it's marked as executed within the `batch`; @@ -297,8 +309,18 @@ pub mod squads_smart_account_program { } /// Synchronously execute a transaction + #[deprecated(note = "Use `execute_transaction_sync_v2` instead")] pub fn execute_transaction_sync( - ctx: Context, + ctx: Context, + args: LegacySyncTransactionArgs, + ) -> Result<()> { + msg!("Method is being deprecated. Use `execute_transaction_sync_v2` instead"); + LegacySyncTransaction::sync_transaction(ctx, args) + } + + /// Synchronously execute a policy transaction + pub fn execute_transaction_sync_v2<'info>( + ctx: Context<'_, '_, 'info, 'info, SyncTransaction<'info>>, args: SyncTransactionArgs, ) -> Result<()> { SyncTransaction::sync_transaction(ctx, args) @@ -312,7 +334,10 @@ pub mod squads_smart_account_program { SyncSettingsTransaction::sync_settings_transaction(ctx, args) } /// Log an event - pub fn log_event<'info>(ctx: Context<'_, '_, 'info, 'info, LogEvent<'info>>, args: LogEventArgs) -> Result<()> { + pub fn log_event<'info>( + ctx: Context<'_, '_, 'info, 'info, LogEvent<'info>>, + args: LogEventArgsV2, + ) -> Result<()> { LogEvent::log_event(ctx, args) } } diff --git a/programs/squads_smart_account_program/src/state/batch.rs b/programs/squads_smart_account_program/src/state/batch.rs index ecd9815..a52012e 100644 --- a/programs/squads_smart_account_program/src/state/batch.rs +++ b/programs/squads_smart_account_program/src/state/batch.rs @@ -10,7 +10,7 @@ use crate::{TransactionMessage, SmartAccountTransactionMessage}; #[account] #[derive(InitSpace)] pub struct Batch { - /// The settings this belongs to. + /// The consensus account (settings or policy) this belongs to. pub settings: Pubkey, /// Signer of the smart account who submitted the batch. pub creator: Pubkey, diff --git a/programs/squads_smart_account_program/src/state/legacy_transaction.rs b/programs/squads_smart_account_program/src/state/legacy_transaction.rs new file mode 100644 index 0000000..6fb2331 --- /dev/null +++ b/programs/squads_smart_account_program/src/state/legacy_transaction.rs @@ -0,0 +1,244 @@ +use anchor_lang::prelude::*; +use anchor_lang::solana_program::borsh0_10::get_instance_packed_len; + +use crate::errors::*; +use crate::instructions::{CompiledInstruction, MessageAddressTableLookup, TransactionMessage}; + +/// Stores data required for tracking the voting and execution status of a smart +///account transaction. +/// Smart Account transaction is a transaction that's executed on behalf of the +/// smart account PDA +/// and wraps arbitrary Solana instructions, typically calling into other Solana programs. +#[account] +#[derive(Default)] +pub struct LegacyTransaction { + /// The consensus account this belongs to. + pub smart_account_settings: Pubkey, + /// Signer of the Smart Account who submitted the transaction. + pub creator: Pubkey, + /// The rent collector for the transaction account. + pub rent_collector: Pubkey, + /// Index of this transaction within the smart account. + pub index: u64, + /// bump for the transaction seeds. + pub bump: u8, + /// The account index of the smart account this transaction belongs to. + pub account_index: u8, + /// Derivation bump of the smart account PDA this transaction belongs to. + pub account_bump: u8, + /// Derivation bumps for additional signers. + /// Some transactions require multiple signers. Often these additional signers are "ephemeral" keypairs + /// that are generated on the client with a sole purpose of signing the transaction and be discarded immediately after. + /// When wrapping such transactions into smart account ones, we replace these "ephemeral" signing keypairs + /// with PDAs derived from the SmartAccountTransaction's `transaction_index` + /// and controlled by the Smart Account Program; + /// during execution the program includes the seeds of these PDAs into the `invoke_signed` calls, + /// thus "signing" on behalf of these PDAs. + pub ephemeral_signer_bumps: Vec, + /// data required for executing the transaction. + pub message: SmartAccountTransactionMessage, +} + +impl LegacyTransaction { + pub fn size(ephemeral_signers_length: u8, transaction_message: &[u8]) -> Result { + let transaction_message: SmartAccountTransactionMessage = + TransactionMessage::deserialize(&mut &transaction_message[..])?.try_into()?; + let message_size = get_instance_packed_len(&transaction_message).unwrap_or_default(); + + Ok( + 8 + // anchor account discriminator + 32 + // settings + 32 + // creator + 32 + // rent_collector + 8 + // index + 1 + // bump + 1 + // account_index + 1 + // account_bump + (4 + usize::from(ephemeral_signers_length)) + // ephemeral_signers_bumps vec + message_size, // message + ) + } + /// Reduces the Transaction to its default empty value and moves + /// ownership of the data to the caller/return value. + pub fn take(&mut self) -> LegacyTransaction { + core::mem::take(self) + } +} + +#[derive(AnchorSerialize, AnchorDeserialize, Clone, Default, Eq, PartialEq)] +pub struct SmartAccountTransactionMessage { + /// The number of signer pubkeys in the account_keys vec. + pub num_signers: u8, + /// The number of writable signer pubkeys in the account_keys vec. + pub num_writable_signers: u8, + /// The number of writable non-signer pubkeys in the account_keys vec. + pub num_writable_non_signers: u8, + /// Unique account pubkeys (including program IDs) required for execution of the tx. + /// The signer pubkeys appear at the beginning of the vec, with writable pubkeys first, and read-only pubkeys following. + /// The non-signer pubkeys follow with writable pubkeys first and read-only ones following. + /// Program IDs are also stored at the end of the vec along with other non-signer non-writable pubkeys: + /// + /// ```plaintext + /// [pubkey1, pubkey2, pubkey3, pubkey4, pubkey5, pubkey6, pubkey7, pubkey8] + /// |---writable---| |---readonly---| |---writable---| |---readonly---| + /// |------------signers-------------| |----------non-singers-----------| + /// ``` + pub account_keys: Vec, + /// List of instructions making up the tx. + pub instructions: Vec, + /// List of address table lookups used to load additional accounts + /// for this transaction. + pub address_table_lookups: Vec, +} + +impl SmartAccountTransactionMessage { + /// Returns the number of all the account keys (static + dynamic) in the message. + pub fn num_all_account_keys(&self) -> usize { + let num_account_keys_from_lookups = self + .address_table_lookups + .iter() + .map(|lookup| lookup.writable_indexes.len() + lookup.readonly_indexes.len()) + .sum::(); + + self.account_keys.len() + num_account_keys_from_lookups + } + + /// Returns true if the account at the specified index is a part of static `account_keys` and was requested to be writable. + pub fn is_static_writable_index(&self, key_index: usize) -> bool { + let num_account_keys = self.account_keys.len(); + let num_signers = usize::from(self.num_signers); + let num_writable_signers = usize::from(self.num_writable_signers); + let num_writable_non_signers = usize::from(self.num_writable_non_signers); + + if key_index >= num_account_keys { + // `index` is not a part of static `account_keys`. + return false; + } + + if key_index < num_writable_signers { + // `index` is within the range of writable signer keys. + return true; + } + + if key_index >= num_signers { + // `index` is within the range of non-signer keys. + let index_into_non_signers = key_index.saturating_sub(num_signers); + // Whether `index` is within the range of writable non-signer keys. + return index_into_non_signers < num_writable_non_signers; + } + + false + } + + /// Returns true if the account at the specified index was requested to be a signer. + pub fn is_signer_index(&self, key_index: usize) -> bool { + key_index < usize::from(self.num_signers) + } +} + +impl TryFrom for SmartAccountTransactionMessage { + type Error = Error; + + fn try_from(message: TransactionMessage) -> Result { + let account_keys: Vec = message.account_keys.into(); + let instructions: Vec = message.instructions.into(); + let instructions: Vec = instructions + .into_iter() + .map(SmartAccountCompiledInstruction::from) + .collect(); + let address_table_lookups: Vec = + message.address_table_lookups.into(); + + let num_all_account_keys = account_keys.len() + + address_table_lookups + .iter() + .map(|lookup| lookup.writable_indexes.len() + lookup.readonly_indexes.len()) + .sum::(); + + require!( + usize::from(message.num_signers) <= account_keys.len(), + SmartAccountError::InvalidTransactionMessage + ); + require!( + message.num_writable_signers <= message.num_signers, + SmartAccountError::InvalidTransactionMessage + ); + require!( + usize::from(message.num_writable_non_signers) + <= account_keys + .len() + .saturating_sub(usize::from(message.num_signers)), + SmartAccountError::InvalidTransactionMessage + ); + + // Validate that all program ID indices and account indices are within the bounds of the account keys. + for instruction in &instructions { + require!( + usize::from(instruction.program_id_index) < num_all_account_keys, + SmartAccountError::InvalidTransactionMessage + ); + + for account_index in &instruction.account_indexes { + require!( + usize::from(*account_index) < num_all_account_keys, + SmartAccountError::InvalidTransactionMessage + ); + } + } + + Ok(Self { + num_signers: message.num_signers, + num_writable_signers: message.num_writable_signers, + num_writable_non_signers: message.num_writable_non_signers, + account_keys, + instructions, + address_table_lookups: address_table_lookups + .into_iter() + .map(SmartAccountMessageAddressTableLookup::from) + .collect(), + }) + } +} + +/// Concise serialization schema for instructions that make up a transaction. +/// Closely mimics the Solana transaction wire format. +#[derive(AnchorSerialize, AnchorDeserialize, Clone, Eq, PartialEq)] +pub struct SmartAccountCompiledInstruction { + pub program_id_index: u8, + /// Indices into the tx's `account_keys` list indicating which accounts to pass to the instruction. + pub account_indexes: Vec, + /// Instruction data. + pub data: Vec, +} + +impl From for SmartAccountCompiledInstruction { + fn from(compiled_instruction: CompiledInstruction) -> Self { + Self { + program_id_index: compiled_instruction.program_id_index, + account_indexes: compiled_instruction.account_indexes.into(), + data: compiled_instruction.data.into(), + } + } +} + +/// Address table lookups describe an on-chain address lookup table to use +/// for loading more readonly and writable accounts into a transaction. +#[derive(AnchorSerialize, AnchorDeserialize, Clone, Eq, PartialEq)] +pub struct SmartAccountMessageAddressTableLookup { + /// Address lookup table account key. + pub account_key: Pubkey, + /// List of indexes used to load writable accounts. + pub writable_indexes: Vec, + /// List of indexes used to load readonly accounts. + pub readonly_indexes: Vec, +} + +impl From for SmartAccountMessageAddressTableLookup { + fn from(m: MessageAddressTableLookup) -> Self { + Self { + account_key: m.account_key, + writable_indexes: m.writable_indexes.into(), + readonly_indexes: m.readonly_indexes.into(), + } + } +} diff --git a/programs/squads_smart_account_program/src/state/mod.rs b/programs/squads_smart_account_program/src/state/mod.rs index bf9d501..9180509 100644 --- a/programs/squads_smart_account_program/src/state/mod.rs +++ b/programs/squads_smart_account_program/src/state/mod.rs @@ -1,19 +1,23 @@ pub use self::settings::*; pub use batch::*; -pub use settings_transaction::*; +pub use policies::*; pub use program_config::*; pub use proposal::*; pub use seeds::*; +pub use settings_transaction::*; pub use spending_limit::*; +pub use legacy_transaction::*; pub use transaction_buffer::*; pub use transaction::*; mod batch; -mod settings_transaction; -mod settings; +mod policies; mod program_config; mod proposal; mod seeds; +mod settings; +mod settings_transaction; mod spending_limit; +mod legacy_transaction; mod transaction_buffer; mod transaction; diff --git a/programs/squads_smart_account_program/src/state/policies/implementations/internal_fund_transfer.rs b/programs/squads_smart_account_program/src/state/policies/implementations/internal_fund_transfer.rs new file mode 100644 index 0000000..557b730 --- /dev/null +++ b/programs/squads_smart_account_program/src/state/policies/implementations/internal_fund_transfer.rs @@ -0,0 +1,447 @@ +use crate::{ + errors::SmartAccountError, get_smart_account_seeds, state::policies::policy_core::PolicyTrait, + SEED_PREFIX, SEED_SMART_ACCOUNT, +}; +use crate::{PolicyExecutionContext, PolicyPayloadConversionTrait, PolicySizeTrait}; +use anchor_lang::prelude::InterfaceAccount; +use anchor_lang::{prelude::*, system_program, Ids}; +use anchor_spl::token_interface::{self, TokenAccount, TokenInterface, TransferChecked}; + +/// == InternalFundTransferPolicy == +/// This policy allows for the transfer of SOL and SPL tokens between +/// a set of source and destination accounts. +/// +/// The policy is defined by a set of source and destination account indices +/// and a set of allowed mints. +///=============================================== +/// +#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug, PartialEq, Eq)] +pub struct InternalFundTransferPolicy { + // Using bitmasks here not only saves space, but it also prevents us from + // having to deduplicate or sort the account indices. + // Bitmask of allowed source account indices + pub source_account_mask: [u8; 32], + // Bitmask of allowed destination account indices + pub destination_account_mask: [u8; 32], + pub allowed_mints: Vec, +} + +impl InternalFundTransferPolicy { + /// Convert a bitmask to a list of indices + pub fn mask_to_indices(mask: &[u8; 32]) -> Vec { + let mut indices = Vec::new(); + for i in 0..32 { + for j in 0..8 { + if mask[i] & (1 << j) != 0 { + indices.push((i * 8 + j) as u8); + } + } + } + indices + } + + /// Convert a list of indices to a bitmask + pub fn indices_to_mask(indices: &[u8]) -> [u8; 32] { + let mut mask = [0u8; 32]; + for index in indices { + mask[*index as usize / 8] |= 1 << (*index as usize % 8); + } + mask + } + /// Checks if the given index is in the given mask + pub fn has_account_index(index: u8, mask: &[u8; 32]) -> bool { + let byte_idx = (index / 8) as usize; + let bit_idx = index % 8; + (mask[byte_idx] & (1 << bit_idx)) != 0 + } + + /// Checks if the given index is in the source account mask + pub fn has_source_account_index(&self, index: u8) -> bool { + Self::has_account_index(index, &self.source_account_mask) + } + + /// Checks if the given index is in the destination account mask + pub fn has_destination_account_index(&self, index: u8) -> bool { + Self::has_account_index(index, &self.destination_account_mask) + } +} + +#[derive(AnchorSerialize, AnchorDeserialize, Clone, PartialEq, Eq)] +pub struct InternalFundTransferPayload { + pub source_index: u8, + pub destination_index: u8, + pub mint: Pubkey, + pub decimals: u8, + pub amount: u64, +} + +#[derive(AnchorSerialize, AnchorDeserialize, Clone, PartialEq, Eq)] +pub struct InternalFundTransferPolicyCreationPayload { + pub source_account_indices: Vec, + pub destination_account_indices: Vec, + pub allowed_mints: Vec, +} + +impl PolicySizeTrait for InternalFundTransferPolicyCreationPayload { + fn creation_payload_size(&self) -> usize { + 4 + self.source_account_indices.len() + // source_account_indices vec + 4 + self.destination_account_indices.len() + // destination_account_indices vec + 4 + self.allowed_mints.len() * 32 // allowed_mints vec + } + + fn policy_state_size(&self) -> usize { + 32 + // source_account_mask + 32 + // destination_account_mask + 4 + self.allowed_mints.len() * 32 // allowed_mints vec + } +} + +impl PolicyPayloadConversionTrait for InternalFundTransferPolicyCreationPayload { + type PolicyState = InternalFundTransferPolicy; + + fn to_policy_state(self) -> Result { + // Sort the allowed mints to ensure the invariant function can apply. + let mut sorted_allowed_mints = self.allowed_mints.clone(); + sorted_allowed_mints.sort_by_key(|mint| mint.clone()); + + // Create the policy state + Ok(InternalFundTransferPolicy { + source_account_mask: InternalFundTransferPolicy::indices_to_mask( + &self.source_account_indices, + ), + destination_account_mask: InternalFundTransferPolicy::indices_to_mask( + &self.destination_account_indices, + ), + allowed_mints: sorted_allowed_mints, + }) + } +} + +pub struct InternalFundTransferExecutionArgs { + pub settings_key: Pubkey, +} + +impl PolicyTrait for InternalFundTransferPolicy { + type PolicyState = Self; + type CreationPayload = InternalFundTransferPolicyCreationPayload; + type UsagePayload = InternalFundTransferPayload; + type ExecutionArgs = InternalFundTransferExecutionArgs; + + fn invariant(&self) -> Result<()> { + // There can't be duplicate mints. Requires the mints are sorted. + let has_duplicates = self.allowed_mints.windows(2).any(|win| win[0] == win[1]); + require!( + !has_duplicates, + SmartAccountError::InternalFundTransferPolicyInvariantDuplicateMints + ); + Ok(()) + } + + /// Validates a given usage payload. + fn validate_payload( + &self, + // No difference between synchronous and asynchronous execution + _context: PolicyExecutionContext, + payload: &Self::UsagePayload, + ) -> Result<()> { + // Validate source account index is allowed + require!( + self.has_source_account_index(payload.source_index), + SmartAccountError::InternalFundTransferPolicyInvariantSourceAccountIndexNotAllowed + ); + + // Validate destination account index is allowed + require!( + self.has_destination_account_index(payload.destination_index), + SmartAccountError::InternalFundTransferPolicyInvariantDestinationAccountIndexNotAllowed + ); + + // Validate mint is allowed (empty allowed_mints means all mints are allowed) + if !self.allowed_mints.is_empty() { + require!( + self.allowed_mints.contains(&payload.mint), + SmartAccountError::InternalFundTransferPolicyInvariantMintNotAllowed + ); + } + + // Validate amount is non-zero + require!( + payload.amount > 0, + SmartAccountError::InternalFundTransferPolicyInvariantAmountZero + ); + + // Validate source and destination are different + require!( + payload.source_index != payload.destination_index, + SmartAccountError::InternalFundTransferPolicyInvariantSourceAndDestinationCannotBeTheSame + ); + + Ok(()) + } + + /// Execute the internal fund transfer policy + /// Expects the following accounts: + /// - Source account + /// - Source account token account + /// - Destination account token account + fn execute_payload<'info>( + &mut self, + args: Self::ExecutionArgs, + payload: &Self::UsagePayload, + accounts: &'info [AccountInfo<'info>], + ) -> Result<()> { + let validated_accounts = Self::validate_accounts(&args.settings_key, &payload, accounts)?; + + match validated_accounts { + ValidatedAccounts::NativeTransfer { + source_account_info, + source_account_bump, + destination_account_info, + system_program, + } => { + // Transfer SOL + anchor_lang::system_program::transfer( + CpiContext::new_with_signer( + system_program.to_account_info(), + anchor_lang::system_program::Transfer { + from: source_account_info.clone(), + to: destination_account_info.clone(), + }, + &[&[ + SEED_PREFIX, + args.settings_key.as_ref(), + SEED_SMART_ACCOUNT, + &payload.source_index.to_le_bytes(), + &[source_account_bump], + ]], + ), + payload.amount, + )? + } + ValidatedAccounts::TokenTransfer { + source_account_info, + source_account_bump, + source_token_account_info, + destination_token_account_info, + mint, + token_program, + } => { + // Transfer SPL token + token_interface::transfer_checked( + CpiContext::new_with_signer( + token_program.to_account_info(), + TransferChecked { + from: source_token_account_info.to_account_info(), + mint: mint.to_account_info(), + to: destination_token_account_info.to_account_info(), + authority: source_account_info.clone(), + }, + &[&[ + SEED_PREFIX, + args.settings_key.as_ref(), + SEED_SMART_ACCOUNT, + &payload.source_index.to_le_bytes(), + &[source_account_bump], + ]], + ), + payload.amount, + payload.decimals, + )?; + } + } + + Ok(()) + } +} + +enum ValidatedAccounts<'info> { + NativeTransfer { + source_account_info: &'info AccountInfo<'info>, + source_account_bump: u8, + destination_account_info: &'info AccountInfo<'info>, + system_program: &'info AccountInfo<'info>, + }, + TokenTransfer { + source_account_info: &'info AccountInfo<'info>, + source_account_bump: u8, + source_token_account_info: &'info AccountInfo<'info>, + destination_token_account_info: &'info AccountInfo<'info>, + mint: &'info AccountInfo<'info>, + token_program: &'info AccountInfo<'info>, + }, +} +impl InternalFundTransferPolicy { + /// Validates the accounts passed in and returns a struct with the accounts + fn validate_accounts<'info>( + settings_key: &Pubkey, + args: &InternalFundTransferPayload, + accounts: &'info [AccountInfo<'info>], + ) -> Result> { + // Derive source and destination account keys + let source_account_index_bytes = args.source_index.to_le_bytes(); + let destination_account_index_bytes = args.destination_index.to_le_bytes(); + let source_account_seeds = + get_smart_account_seeds(settings_key, &source_account_index_bytes); + let destination_account_seeds = + get_smart_account_seeds(settings_key, &destination_account_index_bytes); + + // Derive source and destination account keys + let (source_account_key, source_account_bump) = + Pubkey::find_program_address(source_account_seeds.as_slice(), &crate::ID); + // Derive the destination account from the destination index + let (destination_account_key, _) = + Pubkey::find_program_address(destination_account_seeds.as_slice(), &crate::ID); + + // Mint specific logic + match args.mint { + // Native SOL transfer + mint if mint == Pubkey::default() => { + // Parse out the accounts + let (source_account_info, destination_account_info, system_program) = if let [source_account_info, destination_account_info, system_program, _remaining @ ..] = + accounts + { + ( + source_account_info, + destination_account_info, + system_program, + ) + } else { + return err!(SmartAccountError::InvalidNumberOfAccounts); + }; + // Check that the source account is the same as the source account info + require!( + source_account_key == source_account_info.key(), + SmartAccountError::InvalidAccount + ); + // Check that the destination account is the same as the destination account info + require!( + destination_account_key == destination_account_info.key(), + SmartAccountError::InvalidAccount + ); + // Check the system program + require!( + system_program.key() == system_program::ID, + SmartAccountError::InvalidAccount + ); + + // Sanity check for the decimals. Similar to the one in token_interface::transfer_checked. + require!(args.decimals == 9, SmartAccountError::DecimalsMismatch); + + Ok(ValidatedAccounts::NativeTransfer { + source_account_info, + source_account_bump, + destination_account_info, + system_program, + }) + } + // Token transfer + _ => { + // Parse out the accounts + let ( + source_account_info, + source_token_account_info, + destination_token_account_info, + mint, + token_program, + ) = if let [source_account_info, source_token_account_info, destination_token_account_info, mint, token_program, _remaining @ ..] = + accounts + { + ( + source_account_info, + source_token_account_info, + destination_token_account_info, + mint, + token_program, + ) + } else { + return err!(SmartAccountError::InvalidNumberOfAccounts); + }; + + // Check the source account key + require!( + source_account_key == source_account_info.key(), + SmartAccountError::InvalidAccount + ); + // Deserialize the source and destination token accounts. Either + // T22 or TokenKeg accounts + let source_token_account = + InterfaceAccount::<'info, TokenAccount>::try_from(source_token_account_info)?; + let destination_token_account = + InterfaceAccount::::try_from(destination_token_account_info)?; + // Check the mint against the payload + require_eq!(args.mint, mint.key()); + + // Assert the ownership and mint of the token accounts + require!( + source_token_account.owner == source_account_key + && source_token_account.mint == args.mint, + SmartAccountError::InvalidAccount + ); + require!( + destination_token_account.owner == destination_account_key + && destination_token_account.mint == args.mint, + SmartAccountError::InvalidAccount + ); + // Check the token program + require_eq!(TokenInterface::ids().contains(&token_program.key()), true); + + Ok(ValidatedAccounts::TokenTransfer { + source_account_info, + source_account_bump, + source_token_account_info, + destination_token_account_info, + mint, + token_program, + }) + } + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_indices_to_mask_and_back() { + let indices = vec![0, 1, 8, 15, 31, 63, 127, 255]; + let mask = InternalFundTransferPolicy::indices_to_mask(&indices); + let result_indices = InternalFundTransferPolicy::mask_to_indices(&mask); + assert_eq!(indices, result_indices); + } + + #[test] + fn test_has_account_index() { + let indices = vec![2, 5, 10, 20]; + let mask = InternalFundTransferPolicy::indices_to_mask(&indices); + let policy = InternalFundTransferPolicy { + source_account_mask: mask, + destination_account_mask: [0u8; 32], + allowed_mints: vec![], + }; + for &idx in &indices { + assert!(InternalFundTransferPolicy::has_account_index(idx, &policy.source_account_mask)); + } + assert!(!InternalFundTransferPolicy::has_account_index(3, &policy.source_account_mask)); + assert!(!InternalFundTransferPolicy::has_account_index(0, &policy.destination_account_mask)); + } + + #[test] + fn test_has_source_and_destination_account_index() { + let source_indices = vec![1, 3, 5]; + let dest_indices = vec![2, 4, 6]; + let policy = InternalFundTransferPolicy { + source_account_mask: InternalFundTransferPolicy::indices_to_mask(&source_indices), + destination_account_mask: InternalFundTransferPolicy::indices_to_mask(&dest_indices), + allowed_mints: vec![], + }; + for &idx in &source_indices { + assert!(policy.has_source_account_index(idx)); + } + for &idx in &dest_indices { + assert!(policy.has_destination_account_index(idx)); + } + assert!(!policy.has_source_account_index(2)); + assert!(!policy.has_destination_account_index(1)); + } +} diff --git a/programs/squads_smart_account_program/src/state/policies/implementations/mod.rs b/programs/squads_smart_account_program/src/state/policies/implementations/mod.rs new file mode 100644 index 0000000..c10985a --- /dev/null +++ b/programs/squads_smart_account_program/src/state/policies/implementations/mod.rs @@ -0,0 +1,14 @@ +//! Policy implementations +//! +//! This module contains specific policy implementations that use the core policy framework. +//! Each policy type implements the PolicyExecutor trait for type-safe execution. + +pub mod internal_fund_transfer; +pub mod spending_limit_policy; +pub mod program_interaction; +pub mod settings_change; + +pub use internal_fund_transfer::*; +pub use spending_limit_policy::*; +pub use program_interaction::*; +pub use settings_change::*; \ No newline at end of file diff --git a/programs/squads_smart_account_program/src/state/policies/implementations/program_interaction.rs b/programs/squads_smart_account_program/src/state/policies/implementations/program_interaction.rs new file mode 100644 index 0000000..d5e405c --- /dev/null +++ b/programs/squads_smart_account_program/src/state/policies/implementations/program_interaction.rs @@ -0,0 +1,1503 @@ +use crate::{ + errors::*, + state::policies::utils::{ + check_pre_balances, PeriodV2, QuantityConstraints, SpendingLimitV2, TimeConstraints, + UsageState, + }, + utils::{ + derive_ephemeral_signers, ExecutableTransactionMessage, SynchronousTransactionMessage, + }, + CompiledInstruction, PolicyExecutionContext, PolicyPayloadConversionTrait, PolicySizeTrait, + PolicyTrait, SmallVec, SmartAccountCompiledInstruction, SmartAccountSigner, TransactionMessage, + TransactionPayload, TransactionPayloadDetails, HOOK_AUTHORITY_PUBKEY, SEED_EPHEMERAL_SIGNER, + SEED_HOOK_AUTHORITY, SEED_PREFIX, SEED_SMART_ACCOUNT, +}; +use anchor_lang::prelude::*; +use solana_program::instruction::Instruction; + +// ============================================================================= +// CORE POLICY STRUCTURES +// ============================================================================= + +#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug)] +pub struct ProgramInteractionPolicy { + /// The account index of the account that will be used to execute the policy + pub account_index: u8, + /// Constraints evaluated as a logical OR + pub instructions_constraints: Vec, + /// Hook invoked before inner instruction execution + pub pre_hook: Option, + /// Hook invoked after inner instruction execution + pub post_hook: Option, + /// Spending limits applied during policy execution + pub spending_limits: Vec, +} + +#[derive(AnchorSerialize, AnchorDeserialize, Clone, PartialEq, Eq, Debug)] +pub struct InstructionConstraint { + /// The program that this constraint applies to + pub program_id: Pubkey, + /// Account constraints (evaluated as logical AND) + pub account_constraints: Vec, + /// Data constraints (evaluated as logical AND) + pub data_constraints: Vec, +} + +#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug)] +pub struct Hook { + // Dictates how many extra accounts are required for the hook, beyond the program ID + pub num_extra_accounts: u8, + // Dictates constraints for the hook accounts + pub account_constraints: Vec, + // Dictates which instruction data will be invoked + pub instruction_data: Vec, + // The program that will be invoked + pub program_id: Pubkey, + // Dictates if inner instruction data & account will be passed to the + // instruction on top of the instruction data + pub pass_inner_instructions: bool, +} + +impl Hook { + pub fn size(&self) -> usize { + 1 + // num_accounts + 4 + self.account_constraints.iter().map(|c| c.size()).sum::() + // account_constraints vec + 4 + self.instruction_data.len() + // instruction_data + 32 + // program_id + 1 // pass_inner_instructions + } + + // Get the total number of accounts required for the hook + pub fn num_accounts(&self) -> usize { + // Program ID also needs to get passed in, therefore add 1 + self.num_extra_accounts + .checked_add(1) + .map(|v| v as usize) + .unwrap() + } +} +// ============================================================================= +// CONSTRAINT TYPES AND OPERATORS +// ============================================================================= + +impl InstructionConstraint { + pub fn size(&self) -> usize { + 32 + // program_id + 4 + self.account_constraints.iter().map(|c| c.size()).sum::() + // account_constraints vec + 4 + self.data_constraints.iter().map(|c| c.size()).sum::() // data_constraints vec + } +} + +#[derive(AnchorSerialize, AnchorDeserialize, Clone, PartialEq, Eq, Debug)] +pub enum DataOperator { + Equals, + NotEquals, + GreaterThan, + GreaterThanOrEqualTo, + LessThan, + LessThanOrEqualTo, +} + +#[derive(AnchorSerialize, AnchorDeserialize, Clone, PartialEq, Eq, Debug)] +pub enum DataValue { + U8(u8), + /// Little-endian u16 + U16Le(u16), + /// Little-endian u32 + U32Le(u32), + /// Little-endian u64 + U64Le(u64), + /// Little-endian u128 + U128Le(u128), + /// Byte slice for discriminators etc. Only supports Equals/NotEquals + U8Slice(Vec), +} + +impl DataValue { + pub fn size(&self) -> usize { + 1 + // enum discriminator + match self { + DataValue::U8(_) => 1, + DataValue::U16Le(_) => 2, + DataValue::U32Le(_) => 4, + DataValue::U64Le(_) => 8, + DataValue::U128Le(_) => 16, + DataValue::U8Slice(bytes) => 4 + bytes.len(), // vec length + bytes + } + } +} + +#[derive(AnchorSerialize, AnchorDeserialize, Clone, PartialEq, Eq, Debug)] +pub struct DataConstraint { + pub data_offset: u64, + pub data_value: DataValue, + pub operator: DataOperator, +} + +#[derive(AnchorSerialize, AnchorDeserialize, Clone, PartialEq, Eq, Debug)] +pub enum AccountConstraintType { + Pubkey(Vec), + AccountData(Vec), +} + +impl AccountConstraintType { + pub fn size(&self) -> usize { + match self { + AccountConstraintType::Pubkey(keys) => 1 + 4 + keys.len() * 32, + AccountConstraintType::AccountData(constraints) => { + 1 + 4 + constraints.iter().map(|c| c.size()).sum::() + } + } + } +} +#[derive(AnchorSerialize, AnchorDeserialize, Clone, PartialEq, Eq, Debug)] +pub struct AccountConstraint { + pub account_index: u8, + pub account_constraint: AccountConstraintType, + pub owner: Option, +} + +// ============================================================================= +// SIZE CALCULATIONS +// ============================================================================= + +impl DataConstraint { + pub fn size(&self) -> usize { + 8 + // data_offset + self.data_value.size() + // data_value + 1 // operator + } +} + +impl AccountConstraint { + pub fn size(&self) -> usize { + 1 + // account_index + 4 + self.account_constraint.size() + // account_constraint + 32 + // owner + 1 // owner discriminator + } +} + +// ============================================================================= +// CONSTRAINT EVALUATION LOGIC +// ============================================================================= + +impl DataConstraint { + /// Evaluate constraint against instruction data + pub fn evaluate(&self, data: &[u8]) -> Result<()> { + let offset = self.data_offset as usize; + + let constraint_passed = match &self.data_value { + DataValue::U8(expected) => { + // Check bounds + if offset >= data.len() { + return Err(SmartAccountError::ProgramInteractionDataTooShort.into()); + } + let actual = data[offset]; + self.compare(actual, *expected)? + } + DataValue::U16Le(expected) => { + // Check bounds for 2 bytes + if offset + 2 > data.len() { + return Err(SmartAccountError::ProgramInteractionDataTooShort.into()); + } + let bytes = &data[offset..offset + 2]; + let actual = u16::from_le_bytes([bytes[0], bytes[1]]); + self.compare(actual, *expected)? + } + DataValue::U32Le(expected) => { + // Check bounds for 4 bytes + if offset + 4 > data.len() { + return Err(SmartAccountError::ProgramInteractionDataTooShort.into()); + } + let bytes = &data[offset..offset + 4]; + let actual = u32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]); + self.compare(actual, *expected)? + } + DataValue::U64Le(expected) => { + // Check bounds for 8 bytes + if offset + 8 > data.len() { + return Err(SmartAccountError::ProgramInteractionDataTooShort.into()); + } + let actual = u64::from_le_bytes( + data[offset..offset + 8] + .try_into() + .map_err(|_| SmartAccountError::ProgramInteractionDataParsingError)?, + ); + self.compare(actual, *expected)? + } + DataValue::U128Le(expected) => { + // Check bounds for 16 bytes + if offset + 16 > data.len() { + return Err(SmartAccountError::ProgramInteractionDataTooShort.into()); + } + let actual = u128::from_le_bytes( + data[offset..offset + 16] + .try_into() + .map_err(|_| SmartAccountError::ProgramInteractionDataParsingError)?, + ); + self.compare(actual, *expected)? + } + DataValue::U8Slice(expected) => { + // Check bounds for slice length + if offset + expected.len() > data.len() { + return Err(SmartAccountError::ProgramInteractionDataTooShort.into()); + } + let actual = &data[offset..offset + expected.len()]; + match self.operator { + DataOperator::Equals => actual == expected.as_slice(), + DataOperator::NotEquals => actual != expected.as_slice(), + _ => { + return Err( + SmartAccountError::ProgramInteractionUnsupportedSliceOperator.into(), + ); + } + } + } + }; + + if constraint_passed { + Ok(()) + } else { + Err(SmartAccountError::ProgramInteractionInvalidNumericValue.into()) + } + } + + /// Compare two values using the specified operator + fn compare(&self, actual: T, expected: T) -> Result { + Ok(match self.operator { + DataOperator::Equals => actual == expected, + DataOperator::NotEquals => actual != expected, + DataOperator::GreaterThan => actual > expected, + DataOperator::GreaterThanOrEqualTo => actual >= expected, + DataOperator::LessThan => actual < expected, + DataOperator::LessThanOrEqualTo => actual <= expected, + }) + } +} + +impl AccountConstraint { + /// Evaluate the account constraint for a given set of instruction_account_indices and accounts + pub fn evaluate_against_instruction_indices_and_accounts( + &self, + instruction_account_indices: &[u8], + accounts: &[AccountInfo], + ) -> Result<()> { + // Get the account at the given constraint index + let mapped_account_index = instruction_account_indices[self.account_index as usize]; + let account = &accounts[mapped_account_index as usize]; + + self.evaluate_against_account_info(account)?; + + Ok(()) + } + + /// Simply evaluate the account constraint against a single AccountInfo + pub fn evaluate_against_account_info(&self, account: &AccountInfo) -> Result<()> { + // Evaluate the owner constraint + if let Some(owner) = self.owner { + require_eq!( + account.owner, + &owner, + SmartAccountError::IllegalAccountOwner + ); + }; + // Evaluate the account constraint + match &self.account_constraint { + AccountConstraintType::Pubkey(keys) => { + if !keys.contains(&account.key) { + return Err( + SmartAccountError::ProgramInteractionAccountConstraintViolated.into(), + ); + } + } + AccountConstraintType::AccountData(constraints) => { + let data = account.try_borrow_data()?; + for constraint in constraints { + constraint.evaluate(&data)?; + } + } + } + Ok(()) + } + + /// Evaluate the account constraint against a set of AccountInfos + pub fn evaluate_against_account_infos<'info>( + &self, + account_infos: &'info [AccountInfo<'info>], + ) -> Result<()> { + let account_info_to_evalute = account_infos + .get(self.account_index as usize) + .ok_or(SmartAccountError::ProgramInteractionAccountConstraintViolated) + .unwrap(); + + self.evaluate_against_account_info(account_info_to_evalute)?; + + Ok(()) + } +} + +// ============================================================================= +// CREATION PAYLOAD TYPES +// ============================================================================= + +/// Limited subset of TimeConstraints +#[derive(AnchorSerialize, AnchorDeserialize, Clone, PartialEq, Eq)] +pub struct LimitedTimeConstraints { + pub start: i64, + pub expiration: Option, + pub period: PeriodV2, +} + +/// Limited subset of QuantityConstraints +#[derive(AnchorSerialize, AnchorDeserialize, Clone, PartialEq, Eq)] +pub struct LimitedQuantityConstraints { + pub max_per_period: u64, +} + +/// Limited subset of BalanceConstraint used to create a policy +#[derive(AnchorSerialize, AnchorDeserialize, Clone, PartialEq, Eq)] +pub struct LimitedSpendingLimit { + pub mint: Pubkey, + pub time_constraints: LimitedTimeConstraints, + pub quantity_constraints: LimitedQuantityConstraints, +} + +/// Payload used to create a program interaction policy +#[derive(AnchorSerialize, AnchorDeserialize, Clone)] +pub struct ProgramInteractionPolicyCreationPayload { + pub account_index: u8, + pub instructions_constraints: Vec, + pub pre_hook: Option, + pub post_hook: Option, + pub spending_limits: Vec, +} + +// ============================================================================= +// TRANSACTION PAYLOAD TYPES +// ============================================================================= +#[derive(AnchorSerialize, AnchorDeserialize, Clone)] +pub struct ProgramInteractionPayload { + pub instruction_constraint_indices: Option>, + pub transaction_payload: ProgramInteractionTransactionPayload, +} + +#[derive(AnchorSerialize, AnchorDeserialize, Clone)] +pub enum ProgramInteractionTransactionPayload { + AsyncTransaction(TransactionPayload), + SyncTransaction(SyncTransactionPayloadDetails), +} + +#[derive(AnchorSerialize, AnchorDeserialize, Clone)] +pub struct SyncTransactionPayloadDetails { + pub account_index: u8, + pub instructions: Vec, +} + +pub struct ProgramInteractionExecutionArgs { + pub settings_key: Pubkey, + pub transaction_key: Pubkey, + pub proposal_key: Pubkey, + pub policy_signers: Vec, +} + +// ============================================================================= +// CORE POLICY IMPLEMENTATION +// ============================================================================= + +impl Hook { + pub fn execute<'info>( + &self, + hook_accounts: &'info [AccountInfo<'info>], + instructions: &[SmartAccountCompiledInstruction], + instruction_accounts: &[AccountInfo<'info>], + ) -> Result<()> { + use borsh::BorshSerialize; + + // Evaluate the hook accounts + for account_constraint in self.account_constraints.iter() { + account_constraint.evaluate_against_account_infos(hook_accounts)?; + } + + // Build the necessary account metas + let mut account_metas = + Vec::with_capacity(1 + hook_accounts.len() + instruction_accounts.len()); + + // Add the hook accounts to the account metas + for account in hook_accounts.iter() { + let meta = if account.key == &HOOK_AUTHORITY_PUBKEY { + AccountMeta::new_readonly(*account.key, true) + } else if account.is_writable { + AccountMeta::new(*account.key, account.is_signer) + } else { + AccountMeta::new_readonly(*account.key, account.is_signer) + }; + account_metas.push(meta); + } + + // Build the instruction data + let mut instruction_data = self.instruction_data.clone(); + + if self.pass_inner_instructions { + // Serialized Vec represenation of the instructions length + instruction_data.extend_from_slice(&(instructions.len() as u32).to_le_bytes()); + + // Serialize the instructions + for ix in instructions { + ix.serialize(&mut instruction_data) + .map_err(|_| SmartAccountError::ProgramInteractionTemplateHookError)?; + } + + // Add the instruction accounts + for account in instruction_accounts.iter() { + // Allow the hook authority, as long as it is readonly + let meta = if account.key == &HOOK_AUTHORITY_PUBKEY { + AccountMeta::new_readonly(*account.key, true) + } else if account.is_writable { + AccountMeta::new(*account.key, account.is_signer) + } else { + AccountMeta::new_readonly(*account.key, account.is_signer) + }; + account_metas.push(meta); + } + } + + // Build the instruction + let instruction = Instruction { + program_id: self.program_id, + accounts: account_metas, + data: instruction_data, + }; + + // Invoke the instruction + anchor_lang::solana_program::program::invoke_signed( + &instruction, + // Concatenate the hook accounts and the instruction accounts + &[hook_accounts, instruction_accounts].concat(), + &[&[SEED_HOOK_AUTHORITY]], + )?; + Ok(()) + } +} +impl ProgramInteractionPolicy { + /// Evaluate the instruction constraints for a given instruction + pub fn evaluate_instruction_constraints<'info>( + &self, + instruction_constraint_indices: &[u8], + instructions: &[SmartAccountCompiledInstruction], + accounts: &[AccountInfo<'info>], + ) -> Result<()> { + // Iterate over instruction and their corresponding instruction constraint + for (instruction, instruction_constraint_index) in + instructions.iter().zip(instruction_constraint_indices) + { + let instruction_constraint = + &self.instructions_constraints[*instruction_constraint_index as usize]; + // Evaluate the program id constraint + require!( + accounts[instruction.program_id_index as usize].key + == &instruction_constraint.program_id, + SmartAccountError::ProgramInteractionProgramIdMismatch + ); + + // Evaluate the account constraints + for account_constraint in &instruction_constraint.account_constraints { + account_constraint.evaluate_against_instruction_indices_and_accounts( + &instruction.account_indexes, + accounts, + )?; + } + // Evaluate the data constraints + for data_constraint in &instruction_constraint.data_constraints { + data_constraint.evaluate(instruction.data.as_slice())?; + } + } + Ok(()) + } + + // Parses hook accounts from the accounts slice and returns them + pub fn parse_hook_accounts<'info, 'a>( + &self, + accounts: &mut &'a [AccountInfo<'info>], + ) -> (&'a [AccountInfo<'info>], &'a [AccountInfo<'info>]) { + // Split all accounts into pre hook accounts, post_hook accounts and + // transaction related accounts including lookups + let mut pre_hook_accounts_intermediate: &[AccountInfo<'info>] = &[]; + let mut post_hook_accounts_intermediate: &[AccountInfo<'info>] = &[]; + let mut transaction_accounts = *accounts; + + if self.pre_hook.is_some() { + let (pre_hook_accounts, remaining_accounts) = transaction_accounts + .split_at(self.pre_hook.as_ref().unwrap().num_accounts() as usize); + pre_hook_accounts_intermediate = pre_hook_accounts; + transaction_accounts = remaining_accounts; + }; + if self.post_hook.is_some() { + let (post_hook_accounts, remaining_accounts) = transaction_accounts + .split_at(self.post_hook.as_ref().unwrap().num_accounts() as usize); + post_hook_accounts_intermediate = post_hook_accounts; + transaction_accounts = remaining_accounts; + } + + // Re-set transaction accounts + *accounts = transaction_accounts; + + ( + pre_hook_accounts_intermediate, + post_hook_accounts_intermediate, + ) + } +} + +// ============================================================================= +// SIZE IMPLEMENTATIONS FOR CREATION PAYLOAD TYPES +// ============================================================================= + +impl LimitedTimeConstraints { + pub fn size(&self) -> usize { + 8 + // start + 1 + // option discriminator for expiration + match self.expiration { + Some(_) => 8, // expiration value + None => 0, + } + + 1 // period enum discriminator (PeriodV2 is small enum) + } +} + +impl LimitedQuantityConstraints { + pub fn size(&self) -> usize { + 8 // max_per_period + } +} + +impl LimitedSpendingLimit { + pub fn size(&self) -> usize { + 32 + // mint + self.time_constraints.size() + // time_constraints + self.quantity_constraints.size() // quantity_constraints + } +} + +// ============================================================================= +// PAYLOAD CONVERSION IMPLEMENTATIONS +// ============================================================================= + +impl PolicyPayloadConversionTrait for ProgramInteractionPolicyCreationPayload { + type PolicyState = ProgramInteractionPolicy; + + fn to_policy_state(self) -> Result { + // For sanity sake, we limit the number of instruction constraints and + // spending limits + require!( + self.instructions_constraints.len() <= 20, + SmartAccountError::ProgramInteractionTooManyInstructionConstraints + ); + require!( + self.spending_limits.len() <= 10, + SmartAccountError::ProgramInteractionTooManySpendingLimits + ); + + let mut spending_limits = self.spending_limits.clone(); + spending_limits.sort_by_key(|c| c.mint); + + let current_timestamp = Clock::get()?.unix_timestamp; + Ok(ProgramInteractionPolicy { + account_index: self.account_index, + instructions_constraints: self.instructions_constraints, + pre_hook: self.pre_hook, + post_hook: self.post_hook, + spending_limits: spending_limits + .iter() + .map(|spending_limit| { + // Determine the start timestamp + let start = if spending_limit.time_constraints.start == 0 { + current_timestamp + } else { + spending_limit.time_constraints.start + }; + SpendingLimitV2 { + mint: spending_limit.mint, + time_constraints: TimeConstraints { + start, + period: spending_limit.time_constraints.period, + expiration: spending_limit.time_constraints.expiration, + accumulate_unused: false, + }, + quantity_constraints: QuantityConstraints { + max_per_period: spending_limit.quantity_constraints.max_per_period, + max_per_use: 0, + enforce_exact_quantity: false, + }, + usage: UsageState { + remaining_in_period: spending_limit.quantity_constraints.max_per_period, + last_reset: start, + }, + } + }) + .collect(), + }) + } +} + +impl PolicySizeTrait for ProgramInteractionPolicyCreationPayload { + fn creation_payload_size(&self) -> usize { + 1 + // account_scope + 4 + self.instructions_constraints.iter().map(|c| c.size()).sum::() + // instructions_constraints vec + 1 + self.pre_hook.as_ref().map(|h| h.size()).unwrap_or(0) + // pre_hook + 1 + self.post_hook.as_ref().map(|h| h.size()).unwrap_or(0) + // post_hook + 4 + self.spending_limits.iter().map(|constraint| constraint.size()).sum::() + // spending_limits vec + } + + fn policy_state_size(&self) -> usize { + 1 + // account_index (account_scope becomes account_index in policy state) + 4 + self.instructions_constraints.iter().map(|c| c.size()).sum::() + // instructions_constraints vec + 1 + self.pre_hook.as_ref().map(|h| h.size()).unwrap_or(0) + // pre_hook + 1 + self.post_hook.as_ref().map(|h| h.size()).unwrap_or(0) + // post_hook + 4 + self.spending_limits.iter().map(|_| SpendingLimitV2::INIT_SPACE).sum::() + // spending_limits vec + } +} + +// ============================================================================= +// TRANSACTION PAYLOAD IMPLEMENTATIONS +// ============================================================================= +impl ProgramInteractionPayload { + /// Get the async transaction payload details for the policy + pub fn get_transaction_payload( + &self, + transaction_key: Pubkey, + ) -> Result { + match &self.transaction_payload { + ProgramInteractionTransactionPayload::AsyncTransaction(transaction_payload) => { + // Deserialize the transaction message + let transaction_message = TransactionMessage::deserialize( + &mut transaction_payload.transaction_message.as_slice(), + )?; + // Derive the ephemeral signer bumps + let ephemeral_signer_bumps: Vec = (0..transaction_payload.ephemeral_signers) + .map(|ephemeral_signer_index| { + let ephemeral_signer_seeds = &[ + SEED_PREFIX, + transaction_key.as_ref(), + SEED_EPHEMERAL_SIGNER, + &ephemeral_signer_index.to_le_bytes(), + ]; + + let (_, bump) = + Pubkey::find_program_address(ephemeral_signer_seeds, &crate::ID); + bump + }) + .collect(); + + // Create the transaction payload details + Ok(TransactionPayloadDetails { + account_index: transaction_payload.account_index, + ephemeral_signer_bumps, + message: transaction_message.try_into()?, + }) + } + _ => Err(SmartAccountError::InvalidPayload.into()), + } + } + + /// Get the sync transaction payload details for the policy + pub fn get_sync_transaction_payload(&self) -> Result<&SyncTransactionPayloadDetails> { + match &self.transaction_payload { + ProgramInteractionTransactionPayload::SyncTransaction(sync_transaction_payload) => { + Ok(sync_transaction_payload) + } + _ => Err(SmartAccountError::InvalidPayload.into()), + } + } +} + +impl ProgramInteractionTransactionPayload { + /// Get the account index for the transaction payload + pub fn get_account_index(&self) -> u8 { + match self { + ProgramInteractionTransactionPayload::AsyncTransaction(transaction_payload) => { + transaction_payload.account_index + } + ProgramInteractionTransactionPayload::SyncTransaction(sync_transaction_payload) => { + sync_transaction_payload.account_index + } + } + } + + /// Get the number of instructions for the transaction payload + pub fn instructions_len(&self) -> Result { + match self { + ProgramInteractionTransactionPayload::AsyncTransaction(transaction_payload) => { + // TODO: Inefficient to deserialize the transaction message and + // not do anything with it. + Ok(TransactionMessage::deserialize( + &mut transaction_payload.transaction_message.as_slice(), + ) + .map_err(|_| SmartAccountError::InvalidInstructionArgs)? + .instructions + .len()) + } + ProgramInteractionTransactionPayload::SyncTransaction(sync_transaction_payload) => { + // Since its a small vec, we can get the length directly from + // the first byte + Ok(sync_transaction_payload.instructions[0] as usize) + } + } + } +} + +// ============================================================================= +// POLICY TRAIT IMPLEMENTATION +// ============================================================================= + +impl PolicyTrait for ProgramInteractionPolicy { + type PolicyState = Self; + type CreationPayload = ProgramInteractionPolicyCreationPayload; + type UsagePayload = ProgramInteractionPayload; + type ExecutionArgs = ProgramInteractionExecutionArgs; + + /// Validate the policy invariant + fn invariant(&self) -> Result<()> { + // There can't be duplicate balance constraint for the same mint + // Assumes that the balance constraints are sorted by mint + let has_duplicate = self + .spending_limits + .windows(2) + .any(|window| window[0].mint == window[1].mint); + require!( + !has_duplicate, + SmartAccountError::ProgramInteractionDuplicateSpendingLimit + ); + + // Each spending limits invariant must be valid + for spending_limit in &self.spending_limits { + spending_limit.invariant()?; + } + + Ok(()) + } + + /// Validate the payload for the policy + fn validate_payload( + &self, + context: PolicyExecutionContext, + payload: &Self::UsagePayload, + ) -> Result<()> { + // Validate that the payload is valid for the context + match (context, &payload.transaction_payload) { + ( + PolicyExecutionContext::Synchronous, + ProgramInteractionTransactionPayload::AsyncTransaction(..), + ) => { + return Err( + SmartAccountError::ProgramInteractionAsyncPayloadNotAllowedWithSyncTransaction + .into(), + ); + } + ( + PolicyExecutionContext::Asynchronous, + ProgramInteractionTransactionPayload::SyncTransaction(..), + ) => { + return Err( + SmartAccountError::ProgramInteractionSyncPayloadNotAllowedWithAsyncTransaction + .into(), + ); + } + // Both other variants are valid + (_, _) => {} + } + + // Get the account index and instructions length + let payload_account_index = payload.transaction_payload.get_account_index(); + let instructions_len = match &payload.transaction_payload { + ProgramInteractionTransactionPayload::AsyncTransaction(transaction_payload) => { + // TODO: Inefficient to deserialize the transaction message and + // not do anything with it. + TransactionMessage::deserialize( + &mut transaction_payload.transaction_message.as_slice(), + )? + .instructions + .len() + } + ProgramInteractionTransactionPayload::SyncTransaction(sync_transaction_payload) => { + let instructions: SmallVec = + SmallVec::::try_from_slice( + &sync_transaction_payload.instructions, + ) + .map_err(|_| SmartAccountError::InvalidInstructionArgs)?; + instructions.len() + } + }; + require_eq!( + payload_account_index, + self.account_index, + SmartAccountError::InvalidPayload + ); + + // If there are instruction constraints, ensure that the submitted instruction constraints are valid + if !self.instructions_constraints.is_empty() { + if let Some(instruction_constraint_indices) = &payload.instruction_constraint_indices { + // Ensure that the instruction indices match the number of + // instructions + require_eq!( + instruction_constraint_indices.len(), + instructions_len, + SmartAccountError::ProgramInteractionInstructionCountMismatch + ); + // Ensure that the instruction constraint index is within the bounds + // of the instructions constraints + for instruction_constraint_index in instruction_constraint_indices { + require!( + *instruction_constraint_index < self.instructions_constraints.len() as u8, + SmartAccountError::ProgramInteractionConstraintIndexOutOfBounds + ); + } + } else { + return Err(SmartAccountError::ProgramInteractionInstructionCountMismatch.into()); + } + } + Ok(()) + } + + // Wrapper method to distinguish between transaction and sync transaction payloads + fn execute_payload<'info>( + &mut self, + args: Self::ExecutionArgs, + payload: &Self::UsagePayload, + accounts: &'info [AccountInfo<'info>], + ) -> Result<()> { + match &payload.transaction_payload { + ProgramInteractionTransactionPayload::AsyncTransaction(..) => { + self.execute_payload_async(args, payload, accounts) + } + ProgramInteractionTransactionPayload::SyncTransaction(..) => { + self.execute_payload_sync(args, payload, accounts) + } + } + } +} + +// ============================================================================= +// ASYNC TRANSACTION EXECUTION +// ============================================================================= + +impl ProgramInteractionPolicy { + /// Execute an async transaction through the policy + fn execute_payload_async<'info>( + &mut self, + args: ProgramInteractionExecutionArgs, + payload: &ProgramInteractionPayload, + mut accounts: &'info [AccountInfo<'info>], + ) -> Result<()> { + // Get the transaction payload + let transaction_payload = payload.get_transaction_payload(args.transaction_key)?; + + // Largely copied from `transaction_execute.rs` + let smart_account_seeds = &[ + SEED_PREFIX, + args.settings_key.as_ref(), + SEED_SMART_ACCOUNT, + &transaction_payload.account_index.to_le_bytes(), + ]; + let (smart_account_pubkey, smart_account_bump) = + Pubkey::find_program_address(smart_account_seeds, &crate::ID); + + let smart_account_signer_seeds = &[ + smart_account_seeds[0], + smart_account_seeds[1], + smart_account_seeds[2], + smart_account_seeds[3], + &[smart_account_bump], + ]; + + // Parse out the hook accounts from the accounts slice + let (pre_hook_accounts, post_hook_accounts) = self.parse_hook_accounts(&mut accounts); + + // Get the message account infos and address lookup table account infos + let num_lookups = transaction_payload.message.address_table_lookups.len(); + // Execute the transaction + let message_account_infos = accounts + .get(num_lookups..) + .ok_or(SmartAccountError::InvalidNumberOfAccounts)?; + let address_lookup_table_account_infos = accounts + .get(..num_lookups) + .ok_or(SmartAccountError::InvalidNumberOfAccounts)?; + + // Evaluate the instruction constraints + if let Some(instruction_constraint_indices) = &payload.instruction_constraint_indices { + self.evaluate_instruction_constraints( + instruction_constraint_indices, + &transaction_payload.message.instructions, + message_account_infos, + )?; + } + + // Execute the pre hook + if let Some(pre_hook) = &self.pre_hook { + pre_hook.execute( + pre_hook_accounts, + &transaction_payload.message.instructions, + &accounts[num_lookups..], + )?; + } + let (ephemeral_signer_keys, ephemeral_signer_seeds) = derive_ephemeral_signers( + args.transaction_key, + &transaction_payload.ephemeral_signer_bumps, + ); + + let executable_message = ExecutableTransactionMessage::new_validated( + transaction_payload.message.clone(), + message_account_infos, + address_lookup_table_account_infos, + &smart_account_pubkey, + &ephemeral_signer_keys, + )?; + + let protected_accounts = &[args.proposal_key]; + + // Update the spending limits if present + if !self.spending_limits.is_empty() { + let current_timestamp = Clock::get()?.unix_timestamp; + // Reset the spending limits if needed + for spending_limit in &mut self.spending_limits { + spending_limit.reset_if_needed(current_timestamp); + } + + let tracked_pre_balances = check_pre_balances(smart_account_pubkey, accounts); + // Execute the transaction message instructions one-by-one. + // NOTE: `execute_message()` calls `self.to_instructions_and_accounts()` + // which in turn calls `take()` on + // `self.message.instructions`, therefore after this point no more + // references or usages of `self.message` should be made to avoid + // faulty behavior. + executable_message.execute_message( + smart_account_signer_seeds, + &ephemeral_signer_seeds, + protected_accounts, + )?; + // Evaluate the balance changes post-execution + tracked_pre_balances.evaluate_balance_changes(&mut self.spending_limits)?; + } else { + // Execute the transaction message instructions one-by-one. + // NOTE: `execute_message()` calls `self.to_instructions_and_accounts()` + // which in turn calls `take()` on + // `self.message.instructions`, therefore after this point no more + // references or usages of `self.message` should be made to avoid + // faulty behavior. + executable_message.execute_message( + smart_account_signer_seeds, + &ephemeral_signer_seeds, + protected_accounts, + )?; + } + + // Execute post hook + if let Some(post_hook) = &self.post_hook { + post_hook.execute( + post_hook_accounts, + &transaction_payload.message.instructions, + &accounts[num_lookups..], + )?; + } + Ok(()) + } + + // ============================================================================= + // SYNC TRANSACTION EXECUTION + // ============================================================================= + + /// Execute a synchronous transaction through the policy + fn execute_payload_sync<'info>( + &mut self, + args: ProgramInteractionExecutionArgs, + payload: &ProgramInteractionPayload, + mut accounts: &'info [AccountInfo<'info>], + ) -> Result<()> { + // Get the sync transaction payload + let sync_transaction_payload = payload.get_sync_transaction_payload()?; + // Get the settings key + let settings_key = args.settings_key; + // Validate the instructions + let instructions = SmallVec::::try_from_slice( + &sync_transaction_payload.instructions, + ) + .map_err(|_| SmartAccountError::InvalidInstructionArgs)?; + + // Convert to SmartAccountCompiledInstruction + let settings_compiled_instructions: Vec = + Vec::from(instructions) + .into_iter() + .map(SmartAccountCompiledInstruction::from) + .collect(); + // Get the smart account seeds + let smart_account_seeds = &[ + SEED_PREFIX, + settings_key.as_ref(), + SEED_SMART_ACCOUNT, + &sync_transaction_payload.account_index.to_le_bytes(), + ]; + let (smart_account_pubkey, smart_account_bump) = + Pubkey::find_program_address(smart_account_seeds, &crate::ID); + + // Get the signer seeds for the smart account + let smart_account_signer_seeds = &[ + smart_account_seeds[0], + smart_account_seeds[1], + smart_account_seeds[2], + smart_account_seeds[3], + &[smart_account_bump], + ]; + + // Parse out the hook accounts from the accounts slice + let (pre_hook_accounts, post_hook_accounts) = self.parse_hook_accounts(&mut accounts); + + // Evaluate the instruction constraints + if let Some(instruction_constraint_indices) = &payload.instruction_constraint_indices { + self.evaluate_instruction_constraints( + instruction_constraint_indices, + &settings_compiled_instructions, + accounts, + )?; + } + + // Execute the pre hook + if let Some(pre_hook) = &self.pre_hook { + pre_hook.execute( + pre_hook_accounts, + &settings_compiled_instructions, + &accounts, + )?; + } + + let executable_message = SynchronousTransactionMessage::new_validated( + &settings_key, + &smart_account_pubkey, + &args.policy_signers, + &settings_compiled_instructions, + accounts, + )?; + + // Update the spending limits if present + if !self.spending_limits.is_empty() { + let current_timestamp = Clock::get()?.unix_timestamp; + // Reset the spending limits if needed + for spending_limit in &mut self.spending_limits { + spending_limit.reset_if_needed(current_timestamp); + } + + let tracked_pre_balances = check_pre_balances(smart_account_pubkey, accounts); + // Execute the transaction message instructions one-by-one. + // NOTE: `execute_message()` calls `self.to_instructions_and_accounts()` + // which in turn calls `take()` on + // `self.message.instructions`, therefore after this point no more + // references or usages of `self.message` should be made to avoid + // faulty behavior. + executable_message.execute(smart_account_signer_seeds)?; + // Evaluate the balance changes post-execution + tracked_pre_balances.evaluate_balance_changes(&mut self.spending_limits)?; + } else { + // Execute the transaction message instructions one-by-one. + // NOTE: `execute_message()` calls `self.to_instructions_and_accounts()` + // which in turn calls `take()` on + // `self.message.instructions`, therefore after this point no more + // references or usages of `self.message` should be made to avoid + // faulty behavior. + executable_message.execute(smart_account_signer_seeds)?; + } + // Execute the post hook + if let Some(post_hook) = &self.post_hook { + post_hook.execute( + post_hook_accounts, + &settings_compiled_instructions, + &accounts, + )?; + } + + Ok(()) + } +} + +// ============================================================================= +// TESTS +// ============================================================================= + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_data_constraint_u8_equals() { + let constraint = DataConstraint { + data_offset: 0, + data_value: DataValue::U8(42), + operator: DataOperator::Equals, + }; + + assert!(constraint.evaluate(&[42]).is_ok()); + + assert_eq!( + constraint.evaluate(&[41]).err().unwrap(), + SmartAccountError::ProgramInteractionInvalidNumericValue.into() + ); + } + + #[test] + fn test_data_constraint_u8_greater_than() { + let constraint = DataConstraint { + data_offset: 0, + data_value: DataValue::U8(10), + operator: DataOperator::GreaterThan, + }; + + assert!(constraint.evaluate(&[11]).is_ok()); + + assert_eq!( + constraint.evaluate(&[10]).err().unwrap(), + SmartAccountError::ProgramInteractionInvalidNumericValue.into() + ); + assert_eq!( + constraint.evaluate(&[9]).err().unwrap(), + SmartAccountError::ProgramInteractionInvalidNumericValue.into() + ); + } + + #[test] + fn test_data_constraint_u16_little_endian() { + let constraint = DataConstraint { + data_offset: 1, + data_value: DataValue::U16Le(0x1234), + operator: DataOperator::Equals, + }; + + // Little endian: 0x1234 = [0x34, 0x12] + assert!(constraint.evaluate(&[0x00, 0x34, 0x12]).is_ok()); + + assert_eq!( + constraint.evaluate(&[0x00, 0x12, 0x34]).err().unwrap(), + SmartAccountError::ProgramInteractionInvalidNumericValue.into() + ); + } + + #[test] + fn test_data_constraint_u32_less_than_or_equal() { + let constraint = DataConstraint { + data_offset: 0, + data_value: DataValue::U32Le(1000), + operator: DataOperator::LessThanOrEqualTo, + }; + + // Little endian: 1000 = 0x03E8 = [0xE8, 0x03, 0x00, 0x00] + assert!(constraint.evaluate(&[0xE8, 0x03, 0x00, 0x00]).is_ok()); // 1000 + assert!(constraint.evaluate(&[0xE7, 0x03, 0x00, 0x00]).is_ok()); // 999 + assert_eq!( + constraint + .evaluate(&[0xE9, 0x03, 0x00, 0x00]) + .err() + .unwrap(), + SmartAccountError::ProgramInteractionInvalidNumericValue.into() + ); // 1001 + } + + #[test] + fn test_data_constraint_u64_not_equals() { + let constraint = DataConstraint { + data_offset: 0, + data_value: DataValue::U64Le(0x123456789ABCDEF0), + operator: DataOperator::NotEquals, + }; + + let target_bytes = 0x123456789ABCDEF0u64.to_le_bytes(); + let different_bytes = 0x123456789ABCDEF1u64.to_le_bytes(); + + assert_eq!( + constraint.evaluate(&target_bytes).err().unwrap(), + SmartAccountError::ProgramInteractionInvalidNumericValue.into() + ); + assert!(constraint.evaluate(&different_bytes).is_ok()); + } + + #[test] + fn test_data_constraint_u128_greater_than_or_equal() { + let constraint = DataConstraint { + data_offset: 0, + data_value: DataValue::U128Le(1000), + operator: DataOperator::GreaterThanOrEqualTo, + }; + + let equal_bytes = 1000u128.to_le_bytes(); + let greater_bytes = 1001u128.to_le_bytes(); + let lesser_bytes = 999u128.to_le_bytes(); + + assert!(constraint.evaluate(&equal_bytes).is_ok()); + assert!(constraint.evaluate(&greater_bytes).is_ok()); + assert_eq!( + constraint.evaluate(&lesser_bytes).err().unwrap(), + SmartAccountError::ProgramInteractionInvalidNumericValue.into() + ); + } + + #[test] + fn test_data_constraint_u8_slice_equals() { + let constraint = DataConstraint { + data_offset: 8, + data_value: DataValue::U8Slice(vec![0xDE, 0xAD, 0xBE, 0xEF]), + operator: DataOperator::Equals, + }; + + let mut data = vec![0; 12]; + data[8..12].copy_from_slice(&[0xDE, 0xAD, 0xBE, 0xEF]); + + assert!(constraint.evaluate(&data).is_ok()); + + // Different bytes + data[8] = 0xFF; + assert_eq!( + constraint.evaluate(&data).err().unwrap(), + SmartAccountError::ProgramInteractionInvalidNumericValue.into() + ); + } + + #[test] + fn test_data_constraint_u8_slice_not_equals() { + let constraint = DataConstraint { + data_offset: 0, + data_value: DataValue::U8Slice(vec![0x01, 0x02, 0x03]), + operator: DataOperator::NotEquals, + }; + + assert!(constraint.evaluate(&[0x01, 0x02, 0x04]).is_ok()); + assert_eq!( + constraint.evaluate(&[0x01, 0x02, 0x03]).err().unwrap(), + SmartAccountError::ProgramInteractionInvalidNumericValue.into() + ); + } + + #[test] + fn test_data_constraint_u8_slice_invalid_operator() { + let constraint = DataConstraint { + data_offset: 0, + data_value: DataValue::U8Slice(vec![0x01]), + operator: DataOperator::GreaterThan, // Invalid for U8Slice + }; + + assert_eq!( + constraint.evaluate(&[0x01]).err().unwrap(), + SmartAccountError::ProgramInteractionUnsupportedSliceOperator.into() + ); + } + + #[test] + fn test_data_constraint_out_of_bounds() { + let constraint = DataConstraint { + data_offset: 5, + data_value: DataValue::U8(42), + operator: DataOperator::Equals, + }; + + // Data too short + assert!( + constraint.evaluate(&[1, 2, 3]).err().unwrap() + == SmartAccountError::ProgramInteractionDataTooShort.into() + ); + + // Exact boundary + assert_eq!( + constraint.evaluate(&[1, 2, 3, 4, 5]).err().unwrap(), + SmartAccountError::ProgramInteractionDataTooShort.into() + ); + + // Just enough data + assert_eq!( + constraint.evaluate(&[1, 2, 3, 4, 5, 41]).err().unwrap(), + SmartAccountError::ProgramInteractionInvalidNumericValue.into() + ); + assert!(constraint.evaluate(&[1, 2, 3, 4, 5, 42]).is_ok()); + } + + #[test] + fn test_data_constraint_multi_byte_out_of_bounds() { + let constraint = DataConstraint { + data_offset: 2, + data_value: DataValue::U32Le(1000), + operator: DataOperator::Equals, + }; + + // Need 4 bytes starting at offset 2, so need at least 6 bytes total + assert_eq!( + constraint.evaluate(&[1, 2, 3, 4, 5]).err().unwrap(), + SmartAccountError::ProgramInteractionDataTooShort.into() + ); // Only 5 bytes + + let mut data = vec![0; 6]; + data[2..6].copy_from_slice(&1000u32.to_le_bytes()); + assert!(constraint.evaluate(&data).is_ok()); + } + + #[test] + fn test_data_constraint_solana_instruction_discriminator() { + // Simulate checking for a specific Solana instruction discriminator + let swap_discriminator = [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF]; + + let constraint = DataConstraint { + data_offset: 0, + data_value: DataValue::U8Slice(swap_discriminator.to_vec()), + operator: DataOperator::Equals, + }; + + // Create instruction data with correct discriminator + some payload + let mut instruction_data = swap_discriminator.to_vec(); + instruction_data.extend_from_slice(&[0xFF, 0xEE, 0xDD, 0xCC]); // Additional data + + assert!(constraint.evaluate(&instruction_data).is_ok()); + + // Wrong discriminator + let wrong_discriminator = [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEE]; + let mut wrong_data = wrong_discriminator.to_vec(); + wrong_data.extend_from_slice(&[0xFF, 0xEE, 0xDD, 0xCC]); + + assert_eq!( + constraint.evaluate(&wrong_data).err().unwrap(), + SmartAccountError::ProgramInteractionInvalidNumericValue.into() + ); + } + + #[test] + fn test_data_constraint_amount_validation() { + // Simulate validating a swap amount in instruction data + // Amount at offset 12 (after 8-byte discriminator + 4-byte other data) + let max_amount = 1000u64; + + let constraint = DataConstraint { + data_offset: 12, + data_value: DataValue::U64Le(max_amount), + operator: DataOperator::LessThanOrEqualTo, + }; + + // Create instruction with amount = 500 (valid) + let mut instruction_data = vec![0; 20]; // Discriminator + other data + amount + instruction_data[12..20].copy_from_slice(&500u64.to_le_bytes()); + assert!(constraint.evaluate(&instruction_data).is_ok()); + + // Create instruction with amount = 1500 (invalid) + instruction_data[12..20].copy_from_slice(&1500u64.to_le_bytes()); + assert_eq!( + constraint.evaluate(&instruction_data).err().unwrap(), + SmartAccountError::ProgramInteractionInvalidNumericValue.into() + ); + + // Exactly at limit (valid) + instruction_data[12..20].copy_from_slice(&1000u64.to_le_bytes()); + assert!(constraint.evaluate(&instruction_data).is_ok()); + } + + #[test] + fn test_creation_payload_size_calculation() { + let payload = ProgramInteractionPolicyCreationPayload { + account_index: 1, + pre_hook: None, + post_hook: None, + instructions_constraints: vec![InstructionConstraint { + program_id: Pubkey::new_unique(), + account_constraints: vec![AccountConstraint { + account_index: 0, + account_constraint: AccountConstraintType::Pubkey(vec![ + Pubkey::new_unique(), + Pubkey::new_unique(), + ]), + owner: None, + }], + data_constraints: vec![ + DataConstraint { + data_offset: 0, + data_value: DataValue::U8Slice(vec![ + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + ]), + operator: DataOperator::Equals, + }, + DataConstraint { + data_offset: 12, + data_value: DataValue::U64Le(1000), + operator: DataOperator::LessThanOrEqualTo, + }, + ], + }], + spending_limits: vec![LimitedSpendingLimit { + mint: Pubkey::new_unique(), + time_constraints: LimitedTimeConstraints { + start: 1640995200, // Jan 1, 2022 + expiration: Some(1672531200), // Jan 1, 2023 + period: PeriodV2::Daily, + }, + quantity_constraints: LimitedQuantityConstraints { + max_per_period: 1000, + }, + }], + }; + + let calculated_size = payload.creation_payload_size(); + let actual_serialized = payload.try_to_vec().unwrap(); + let actual_size = actual_serialized.len(); + + // Since InitSpace overestimates size, we only check that the calculated + // size is greater than or equal to the actual size to make sure + // serialization succeeds + assert!(calculated_size >= actual_size); + } + + #[test] + fn test_policy_state_size_calculation() { + let payload = ProgramInteractionPolicyCreationPayload { + account_index: 1, + pre_hook: None, + post_hook: None, + instructions_constraints: vec![InstructionConstraint { + program_id: Pubkey::new_unique(), + account_constraints: vec![AccountConstraint { + account_index: 0, + account_constraint: AccountConstraintType::Pubkey(vec![ + Pubkey::new_unique(), + Pubkey::new_unique(), + ]), + owner: None, + }], + data_constraints: vec![ + DataConstraint { + data_offset: 0, + data_value: DataValue::U8Slice(vec![ + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + ]), + operator: DataOperator::Equals, + }, + DataConstraint { + data_offset: 12, + data_value: DataValue::U64Le(1000), + operator: DataOperator::LessThanOrEqualTo, + }, + ], + }], + spending_limits: vec![LimitedSpendingLimit { + mint: Pubkey::new_unique(), + time_constraints: LimitedTimeConstraints { + start: 1640995200, + expiration: Some(1672531200), + period: PeriodV2::Daily, + }, + quantity_constraints: LimitedQuantityConstraints { + max_per_period: 1000, + }, + }], + }; + + let policy = payload.clone().to_policy_state().unwrap(); + let calculated_size = payload.policy_state_size(); + let actual_serialized = policy.try_to_vec().unwrap(); + let actual_size = actual_serialized.len(); + + // Since InitSpace overestimates size, we only check that the calculated + // size is greater than or equal to the actual size to make sure + // serialization succeeds + assert!(calculated_size >= actual_size); + } +} diff --git a/programs/squads_smart_account_program/src/state/policies/implementations/settings_change.rs b/programs/squads_smart_account_program/src/state/policies/implementations/settings_change.rs new file mode 100644 index 0000000..6a50911 --- /dev/null +++ b/programs/squads_smart_account_program/src/state/policies/implementations/settings_change.rs @@ -0,0 +1,567 @@ +use anchor_lang::prelude::*; + +use crate::{ + errors::SmartAccountError, get_settings_signer_seeds, program::SquadsSmartAccountProgram, + state::Settings, LogAuthorityInfo, Permissions, PolicyExecutionContext, + PolicyPayloadConversionTrait, PolicySizeTrait, PolicyTrait, SettingsAction, + SettingsChangePolicyEvent, SmartAccountEvent, SmartAccountSigner, +}; + +/// == SettingsChangePolicy == +/// This policy allows for the modification of the settings of a smart account. +/// +/// The policy is defined by a set of allowed settings changes. +///=============================================== + +// ============================================================================= +// CORE POLICY STRUCTURES +// ============================================================================= +#[derive(AnchorSerialize, AnchorDeserialize, Clone, PartialEq, Eq, Debug)] +pub struct SettingsChangePolicy { + pub actions: Vec, +} +/// Defines which settings changes are allowed by the policy +#[derive(AnchorSerialize, AnchorDeserialize, Clone, PartialEq, Eq, Debug, InitSpace)] +pub enum AllowedSettingsChange { + AddSigner { + /// Some() - add a specific signer, None - add any signer + new_signer: Option, + /// Some() - only allow certain permissions, None - allow all permissions + new_signer_permissions: Option, + }, + RemoveSigner { + /// Some() - remove a specific signer, None - remove any signer + old_signer: Option, + }, + ChangeThreshold, + ChangeTimeLock { + /// Some() - change timelock to a specific value, None - change timelock to any value + new_time_lock: Option, + }, +} + +// ============================================================================= +// CREATION PAYLOAD TYPES +// ============================================================================= + +#[derive(AnchorSerialize, AnchorDeserialize, Clone, PartialEq, Eq, Debug)] +pub struct SettingsChangePolicyCreationPayload { + pub actions: Vec, +} + +// ============================================================================= +// EXECUTION PAYLOAD TYPES +// ============================================================================= + +/// Limited subset of settings change actions for execution +#[derive(AnchorSerialize, AnchorDeserialize, Clone, PartialEq, Eq)] +pub enum LimitedSettingsAction { + AddSigner { new_signer: SmartAccountSigner }, + RemoveSigner { old_signer: Pubkey }, + ChangeThreshold { new_threshold: u16 }, + SetTimeLock { new_time_lock: u32 }, +} + +#[derive(AnchorSerialize, AnchorDeserialize, Clone, PartialEq, Eq)] +pub struct SettingsChangePayload { + pub action_index: Vec, + pub actions: Vec, +} + +pub struct SettingsChangeExecutionArgs { + pub settings_key: Pubkey, +} + +pub struct ValidatedAccounts<'info> { + pub settings: Account<'info, Settings>, + /// Optional just to comply with later use of Settings::modify_with_action + pub rent_payer: Option>, + /// Optional just to comply with later use of Settings::modify_with_action + pub system_program: Option>, + /// Program account used for logging + pub program: Program<'info, SquadsSmartAccountProgram>, +} + +// ============================================================================= +// CONVERSION IMPLEMENTATIONS +// ============================================================================= + +impl From for SettingsAction { + fn from(action: LimitedSettingsAction) -> Self { + match action { + LimitedSettingsAction::AddSigner { new_signer } => { + SettingsAction::AddSigner { new_signer } + } + LimitedSettingsAction::RemoveSigner { old_signer } => { + SettingsAction::RemoveSigner { old_signer } + } + LimitedSettingsAction::ChangeThreshold { new_threshold } => { + SettingsAction::ChangeThreshold { new_threshold } + } + LimitedSettingsAction::SetTimeLock { new_time_lock } => { + SettingsAction::SetTimeLock { new_time_lock } + } + } + } +} + +impl PolicyPayloadConversionTrait for SettingsChangePolicyCreationPayload { + type PolicyState = SettingsChangePolicy; + + fn to_policy_state(self) -> Result { + let mut sorted_actions = self.actions.clone(); + // Sort the actions to ensure the invariant function can apply + sorted_actions.sort_by_key(|action| match action { + AllowedSettingsChange::AddSigner { new_signer, .. } => (0, new_signer.clone()), + AllowedSettingsChange::RemoveSigner { old_signer } => (1, old_signer.clone()), + AllowedSettingsChange::ChangeThreshold => (2, None), + AllowedSettingsChange::ChangeTimeLock { .. } => (3, None), + }); + Ok(SettingsChangePolicy { + actions: sorted_actions, + }) + } +} + +impl PolicySizeTrait for SettingsChangePolicyCreationPayload { + fn creation_payload_size(&self) -> usize { + 4 + self.actions.len() * AllowedSettingsChange::INIT_SPACE // actions vec + } + + fn policy_state_size(&self) -> usize { + // Same as creation payload size + self.creation_payload_size() + } +} + +// ============================================================================= +// POLICY TRAIT IMPLEMENTATION +// ============================================================================= +impl PolicyTrait for SettingsChangePolicy { + type PolicyState = Self; + type CreationPayload = SettingsChangePolicyCreationPayload; + type UsagePayload = SettingsChangePayload; + type ExecutionArgs = SettingsChangeExecutionArgs; + + /// Validate policy invariants - no duplicate actions + fn invariant(&self) -> Result<()> { + // Check for adjacent duplicates (assumes sorted actions by enum and pubkey) + // Rules: + // - AddSigner and RemoveSigner can only be present once with any given pubkey + // - ChangeThreshold and ChangeTimeLock can only each be present once + let has_duplicate = self.actions.windows(2).any(|win| match (&win[0], &win[1]) { + ( + AllowedSettingsChange::AddSigner { + new_signer: signer1, + .. + }, + AllowedSettingsChange::AddSigner { + new_signer: signer2, + .. + }, + ) => signer1 == signer2, + ( + AllowedSettingsChange::RemoveSigner { + old_signer: signer1, + }, + AllowedSettingsChange::RemoveSigner { + old_signer: signer2, + }, + ) => signer1 == signer2, + (AllowedSettingsChange::ChangeThreshold, AllowedSettingsChange::ChangeThreshold) => { + true + } + ( + AllowedSettingsChange::ChangeTimeLock { .. }, + AllowedSettingsChange::ChangeTimeLock { .. }, + ) => true, + _ => false, + }); + + if has_duplicate { + return Err(SmartAccountError::SettingsChangePolicyInvariantDuplicateActions.into()); + } + Ok(()) + } + + /// Validate that the payload actions match allowed policy actions + fn validate_payload( + &self, + // No difference between synchronous and asynchronous execution + _context: PolicyExecutionContext, + payload: &Self::UsagePayload, + ) -> Result<()> { + // Actions need to be non-zero + require!( + !payload.actions.is_empty(), + SmartAccountError::SettingsChangePolicyActionsMustBeNonZero + ); + // Action indices must match actions length + require!( + payload.action_index.len() == payload.actions.len(), + SmartAccountError::SettingsChangePolicyInvariantActionIndicesActionsLengthMismatch + ); + + // This is safe because we checked that the action indices match the actions length + for (action_index, action) in payload.action_index.iter().zip(payload.actions.iter()) { + // Get the corresponding action from the policy state + let allowed_action = if let Some(action) = self.actions.get(*action_index as usize) { + action + } else { + return Err( + SmartAccountError::SettingsChangePolicyInvariantActionIndexOutOfBounds.into(), + ); + }; + match (allowed_action, action) { + ( + AllowedSettingsChange::AddSigner { + new_signer: allowed_signer, + new_signer_permissions: allowed_permissions, + }, + LimitedSettingsAction::AddSigner { new_signer }, + ) => { + if let Some(allowed_signer) = allowed_signer { + // If None, any signer can be added + require!( + &new_signer.key == allowed_signer, + SmartAccountError::SettingsChangeAddSignerViolation + ); + } + // If None, any permissions can be used + if let Some(allowed_permissions) = allowed_permissions { + require!( + &new_signer.permissions == allowed_permissions, + SmartAccountError::SettingsChangeAddSignerPermissionsViolation + ); + } + } + ( + AllowedSettingsChange::RemoveSigner { + old_signer: allowed_removal_signer, + }, + LimitedSettingsAction::RemoveSigner { old_signer }, + ) => { + // If None, any signer can be removed + if let Some(allowed_removal_signer) = allowed_removal_signer { + require!( + old_signer == allowed_removal_signer, + SmartAccountError::SettingsChangeRemoveSignerViolation + ); + } + } + ( + AllowedSettingsChange::ChangeThreshold, + LimitedSettingsAction::ChangeThreshold { new_threshold: _ }, + ) => {} + ( + AllowedSettingsChange::ChangeTimeLock { + new_time_lock: allowed_time_lock, + }, + LimitedSettingsAction::SetTimeLock { new_time_lock }, + ) => { + // If None, any time lock can be used + if let Some(allowed_time_lock) = allowed_time_lock { + require!( + new_time_lock == allowed_time_lock, + SmartAccountError::SettingsChangeChangeTimelockViolation + ); + } + } + _ => { + return Err(SmartAccountError::SettingsChangeActionMismatch.into()); + } + } + } + Ok(()) + } + + /// Execute the settings change actions + fn execute_payload<'info>( + &mut self, + args: Self::ExecutionArgs, + payload: &Self::UsagePayload, + accounts: &'info [AccountInfo<'info>], + ) -> Result<()> { + // Validate and grab the settings account + let mut validated_accounts = self.validate_accounts(args.settings_key, accounts)?; + for action in payload.actions.iter() { + let settings_action = SettingsAction::from(action.clone()); + validated_accounts.settings.modify_with_action( + &args.settings_key, + &settings_action, + &Rent::get()?, + &validated_accounts.rent_payer, + &validated_accounts.system_program, + // Only policies and spending limits use remaining accounts, and + // those actions are excluded from LimitedSettingsAction + &[], + &crate::ID, + None, + )?; + + // Run settings invariant + validated_accounts.settings.invariant()?; + + let log_authority_info = LogAuthorityInfo { + authority: validated_accounts.settings.to_account_info().clone(), + authority_seeds: get_settings_signer_seeds(validated_accounts.settings.seed), + bump: validated_accounts.settings.bump, + program: validated_accounts.program.to_account_info(), + }; + + // Log the event since we're modifying the settings state + let event = SettingsChangePolicyEvent { + settings_pubkey: validated_accounts.settings.key(), + settings: validated_accounts.settings.clone().into_inner(), + changes: payload.actions.clone(), + }; + SmartAccountEvent::SettingsChangePolicyEvent(event).log(&log_authority_info)?; + } + // Reallocate the settings account if needed + Settings::realloc_if_needed( + validated_accounts.settings.to_account_info(), + validated_accounts.settings.signers.len(), + validated_accounts + .rent_payer + .map(|rent_payer| rent_payer.to_account_info()), + validated_accounts + .system_program + .map(|system_program| system_program.to_account_info()), + )?; + Ok(()) + } +} + +// ============================================================================= +// ACCOUNT VALIDATION +// ============================================================================= + +impl SettingsChangePolicy { + /// Validate the accounts needed for settings change execution + pub fn validate_accounts<'info>( + &self, + settings_key: Pubkey, + accounts: &'info [AccountInfo<'info>], + ) -> Result> { + let (settings_account_info, rent_payer_info, system_program_info, program_info) = if let [settings_account_info, rent_payer_info, system_program_info, program_info, _remaining @ ..] = + accounts + { + ( + settings_account_info, + rent_payer_info, + system_program_info, + program_info, + ) + } else { + return err!(SmartAccountError::InvalidNumberOfAccounts); + }; + + // Settings account validation + require!( + settings_account_info.key() == settings_key, + SmartAccountError::SettingsChangeInvalidSettingsKey + ); + require!( + settings_account_info.is_writable, + SmartAccountError::SettingsChangeInvalidSettingsAccount + ); + let settings: Account<'info, Settings> = Account::try_from(settings_account_info)?; + + // Settings authority validation + require!( + settings.settings_authority == Pubkey::default(), + SmartAccountError::NotSupportedForControlled + ); + + // Rent payer validation + let rent_payer = Signer::try_from(rent_payer_info) + .map_err(|_| SmartAccountError::SettingsChangeInvalidRentPayer)?; + require!( + rent_payer.is_writable, + SmartAccountError::SettingsChangeInvalidRentPayer + ); + + // System program validation + let system_program: Program<'info, System> = Program::try_from(system_program_info) + .map_err(|_| SmartAccountError::SettingsChangeInvalidSystemProgram)?; + + // Program validation + let program: Program<'info, SquadsSmartAccountProgram> = + Program::try_from(program_info).map_err(|_| SmartAccountError::InvalidAccount)?; + + Ok(ValidatedAccounts { + settings, + rent_payer: Some(rent_payer), + system_program: Some(system_program), + program, + }) + } +} + +// ============================================================================= +// TESTS +// ============================================================================= +#[cfg(test)] +mod tests { + use crate::Permission; + + use super::*; + + #[test] + fn test_invariant_valid_configuration() { + let payload = SettingsChangePolicyCreationPayload { + actions: vec![ + AllowedSettingsChange::AddSigner { + new_signer: Some(Pubkey::new_unique()), + new_signer_permissions: None, + }, + AllowedSettingsChange::RemoveSigner { + old_signer: Some(Pubkey::new_unique()), + }, + AllowedSettingsChange::ChangeThreshold, + AllowedSettingsChange::ChangeTimeLock { + new_time_lock: Some(1800), + }, + ], + }; + + let policy = payload.to_policy_state().unwrap(); + assert!(policy.invariant().is_ok()); + } + #[test] + fn test_invariant_duplicate_add_signer_same_pubkey() { + let duplicate_signer = Pubkey::new_unique(); + let payload = SettingsChangePolicyCreationPayload { + actions: vec![ + AllowedSettingsChange::AddSigner { + new_signer: Some(duplicate_signer), + new_signer_permissions: None, + }, + AllowedSettingsChange::RemoveSigner { + old_signer: Some(duplicate_signer), + }, + AllowedSettingsChange::AddSigner { + new_signer: Some(duplicate_signer), + new_signer_permissions: Some(Permissions::from_vec(&[Permission::Initiate])), + }, + ], + }; + + let policy = payload.to_policy_state().unwrap(); + assert!(policy.invariant().is_err()); + } + + #[test] + fn test_invariant_duplicate_remove_signer_same_pubkey_out_of_order() { + let duplicate_signer = Pubkey::new_unique(); + let payload = SettingsChangePolicyCreationPayload { + actions: vec![ + AllowedSettingsChange::RemoveSigner { + old_signer: Some(duplicate_signer), + }, + AllowedSettingsChange::AddSigner { + new_signer: Some(duplicate_signer), + new_signer_permissions: None, + }, + AllowedSettingsChange::RemoveSigner { + old_signer: Some(duplicate_signer), + }, + ], + }; + + let policy = payload.to_policy_state().unwrap(); + assert!(policy.invariant().is_err()); + } + + #[test] + fn test_invariant_duplicate_none_values_invalid() { + let payload = SettingsChangePolicyCreationPayload { + actions: vec![ + AllowedSettingsChange::AddSigner { + new_signer: None, + new_signer_permissions: Some(Permissions::from_vec(&[Permission::Initiate])), + }, + AllowedSettingsChange::AddSigner { + new_signer: None, + new_signer_permissions: Some(Permissions::from_vec(&[Permission::Execute])), + }, + AllowedSettingsChange::RemoveSigner { old_signer: None }, + AllowedSettingsChange::RemoveSigner { old_signer: None }, + ], + }; + + let policy = payload.to_policy_state().unwrap(); + assert!(policy.invariant().is_err()); + } + + #[test] + fn test_invariant_duplicate_change_time_lock() { + let payload = SettingsChangePolicyCreationPayload { + actions: vec![ + AllowedSettingsChange::ChangeTimeLock { + new_time_lock: Some(1800), + }, + AllowedSettingsChange::ChangeTimeLock { + new_time_lock: Some(3600), + }, + ], + }; + + let policy = payload.to_policy_state().unwrap(); + assert!(policy.invariant().is_err()); + } + + #[test] + fn test_creation_payload_size_calculation() { + let payload = SettingsChangePolicyCreationPayload { + actions: vec![ + AllowedSettingsChange::AddSigner { + new_signer: Some(Pubkey::new_unique()), + new_signer_permissions: Some(Permissions::all()), + }, + AllowedSettingsChange::RemoveSigner { + old_signer: Some(Pubkey::new_unique()), + }, + AllowedSettingsChange::ChangeThreshold, + AllowedSettingsChange::ChangeTimeLock { + new_time_lock: Some(3600), + }, + ], + }; + + let calculated_size = payload.creation_payload_size(); + let actual_serialized = payload.try_to_vec().unwrap(); + let actual_size = actual_serialized.len(); + + assert!(calculated_size >= actual_size); + } + + #[test] + fn test_policy_state_size_calculation() { + let payload = SettingsChangePolicyCreationPayload { + actions: vec![ + AllowedSettingsChange::AddSigner { + new_signer: Some(Pubkey::new_unique()), + new_signer_permissions: Some(Permissions::all()), + }, + AllowedSettingsChange::RemoveSigner { + old_signer: Some(Pubkey::new_unique()), + }, + AllowedSettingsChange::ChangeThreshold, + AllowedSettingsChange::ChangeTimeLock { + new_time_lock: Some(3600), + }, + ], + }; + + let policy = payload.clone().to_policy_state().unwrap(); + let calculated_size = payload.policy_state_size(); + let actual_serialized = policy.try_to_vec().unwrap(); + let actual_size = actual_serialized.len(); + + // Since InitSpace overestimates size, we only check that the calculated + // size is greater than or equal to the actual size to make sure + // serialization succeeds + assert!(calculated_size >= actual_size); + } +} diff --git a/programs/squads_smart_account_program/src/state/policies/implementations/spending_limit_policy.rs b/programs/squads_smart_account_program/src/state/policies/implementations/spending_limit_policy.rs new file mode 100644 index 0000000..02f84cc --- /dev/null +++ b/programs/squads_smart_account_program/src/state/policies/implementations/spending_limit_policy.rs @@ -0,0 +1,421 @@ +use anchor_lang::{prelude::*, system_program, Ids}; +use anchor_spl::token_interface::{self, TokenAccount, TokenInterface, TransferChecked}; + +use crate::{ + errors::*, + get_smart_account_seeds, + state::policies::utils::{QuantityConstraints, SpendingLimitV2, TimeConstraints, UsageState}, + PolicyExecutionContext, PolicyPayloadConversionTrait, PolicySizeTrait, PolicyTrait, + SEED_PREFIX, SEED_SMART_ACCOUNT, +}; + +/// == SpendingLimitPolicy == +/// This policy allows for the transfer of SOL and SPL tokens between +/// a source account and a set of destination accounts. +/// +/// The policy is defined by a spending limit configuration and a source account index. +/// The spending limit configuration includes a mint, time constraints, quantity constraints, +/// and usage state. +///=============================================== + +// ============================================================================= +// CORE POLICY STRUCTURES +// ============================================================================= + +/// Main spending limit policy structure +#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug, PartialEq, Eq)] +pub struct SpendingLimitPolicy { + /// The source account index + pub source_account_index: u8, + /// The destination addresses the spending limit is allowed to send funds to + /// If empty, funds can be sent to any address + pub destinations: Vec, + /// Spending limit configuration (timing, constraints, usage, mint) + pub spending_limit: SpendingLimitV2, +} + +// ============================================================================= +// CREATION PAYLOAD TYPES +// ============================================================================= + +/// Setup parameters for creating a spending limit +#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug, PartialEq, Eq)] +pub struct SpendingLimitPolicyCreationPayload { + pub mint: Pubkey, + pub source_account_index: u8, + pub time_constraints: TimeConstraints, + pub quantity_constraints: QuantityConstraints, + /// Optionally this can be submitted to update a spending limit policy + /// Cannot be Some() if accumulate_unused is true, to avoid invariant behavior + pub usage_state: Option, + pub destinations: Vec, +} + +// ============================================================================= +// EXECUTION PAYLOAD TYPES +// ============================================================================= + +/// Payload for using a spending limit policy +#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug, PartialEq, Eq)] +pub struct SpendingLimitPayload { + pub amount: u64, + pub destination: Pubkey, + pub decimals: u8, +} + +pub struct SpendingLimitExecutionArgs { + pub settings_key: Pubkey, +} + +/// Validated account information for different transfer types +enum ValidatedAccounts<'info> { + NativeTransfer { + source_account_info: &'info AccountInfo<'info>, + source_account_bump: u8, + destination_account_info: &'info AccountInfo<'info>, + system_program: &'info AccountInfo<'info>, + }, + TokenTransfer { + source_account_info: &'info AccountInfo<'info>, + source_account_bump: u8, + source_token_account_info: &'info AccountInfo<'info>, + destination_token_account_info: &'info AccountInfo<'info>, + mint: &'info AccountInfo<'info>, + token_program: &'info AccountInfo<'info>, + }, +} + +// ============================================================================= +// PAYLOAD CONVERSION IMPLEMENTATIONS +// ============================================================================= + +impl PolicyPayloadConversionTrait for SpendingLimitPolicyCreationPayload { + type PolicyState = SpendingLimitPolicy; + + /// Convert creation payload to policy state + /// Used by Settings.modify_with_action() to instantiate policy state + fn to_policy_state(self) -> Result { + let now = Clock::get().unwrap().unix_timestamp; + // Sort the destinations + let mut destinations = self.destinations; + destinations.sort_by_key(|d| d.to_bytes()); + + // Modify time constraints to start at the current timestamp if set to 0 + let mut modified_time_constraints = self.time_constraints; + if self.time_constraints.start == 0 { + modified_time_constraints.start = now; + } + + // Determine usage state based on surrounding constraints + let usage_state = if let Some(usage_state) = self.usage_state { + // This is the only invariant that needs to be checked on the arg level + require!( + !self.time_constraints.accumulate_unused, + SmartAccountError::SpendingLimitPolicyInvariantAccumulateUnused + ); + usage_state + } else { + UsageState { + remaining_in_period: self.quantity_constraints.max_per_period, + last_reset: modified_time_constraints.start, + } + }; + + Ok(SpendingLimitPolicy { + spending_limit: SpendingLimitV2 { + mint: self.mint, + time_constraints: modified_time_constraints, + quantity_constraints: self.quantity_constraints, + usage: usage_state, + }, + source_account_index: self.source_account_index, + destinations, + }) + } +} + +impl PolicySizeTrait for SpendingLimitPolicyCreationPayload { + fn creation_payload_size(&self) -> usize { + 32 + // mint + 1 + // source_account_index + TimeConstraints::INIT_SPACE + // time_constraints + QuantityConstraints::INIT_SPACE + // quantity_constraints + 4 + self.destinations.len() * 32 // destinations vec + } + + fn policy_state_size(&self) -> usize { + 32 + // mint (in SpendingLimitV2) + TimeConstraints::INIT_SPACE + // time_constraints (in SpendingLimitV2) + QuantityConstraints::INIT_SPACE + // quantity_constraints (in SpendingLimitV2) + UsageState::INIT_SPACE + // usage (in SpendingLimitV2) + 1 + // source_account_index + 4 + self.destinations.len() * 32 // destinations vec + } +} + +// ============================================================================= +// POLICY TRAIT IMPLEMENTATION +// ============================================================================= + +impl PolicyTrait for SpendingLimitPolicy { + type PolicyState = Self; + type CreationPayload = SpendingLimitPolicyCreationPayload; + type UsagePayload = SpendingLimitPayload; + type ExecutionArgs = SpendingLimitExecutionArgs; + + /// Validate policy invariants - no duplicate destinations and valid spending limit + fn invariant(&self) -> Result<()> { + // Check that the destinations are not duplicated (assumes sorted destinations) + let has_duplicates = self.destinations.windows(2).any(|w| w[0] == w[1]); + require!( + !has_duplicates, + SmartAccountError::SpendingLimitPolicyInvariantDuplicateDestinations + ); + + // Check the spending limit invariant + self.spending_limit.invariant()?; + Ok(()) + } + + /// Validate that the destination is allowed + fn validate_payload( + &self, + // No difference between synchronous and asynchronous execution + _context: PolicyExecutionContext, + payload: &Self::UsagePayload, + ) -> Result<()> { + // If destinations are set, check that the destination is in the list of allowed destinations + if !self.destinations.is_empty() { + require!( + self.destinations.contains(&payload.destination), + SmartAccountError::InvalidDestination + ); + } + Ok(()) + } + + /// Execute the spending limit transfer + fn execute_payload<'info>( + &mut self, + args: Self::ExecutionArgs, + payload: &Self::UsagePayload, + accounts: &'info [AccountInfo<'info>], + ) -> Result<()> { + let current_timestamp = Clock::get()?.unix_timestamp; + + // Check that the spending limit is active + self.spending_limit.is_active(current_timestamp)?; + + // Reset the period & amount + self.spending_limit.reset_if_needed(current_timestamp); + + // Check that the amount complies with the spending limit + self.spending_limit.check_amount(payload.amount)?; + + // Validate the accounts + let validated_accounts = self.validate_accounts(&args.settings_key, &payload, accounts)?; + + // Execute the payload + match validated_accounts { + ValidatedAccounts::NativeTransfer { + source_account_info, + source_account_bump, + destination_account_info, + system_program, + } => { + // Transfer SOL + anchor_lang::system_program::transfer( + CpiContext::new_with_signer( + system_program.to_account_info(), + anchor_lang::system_program::Transfer { + from: source_account_info.clone(), + to: destination_account_info.clone(), + }, + &[&[ + SEED_PREFIX, + args.settings_key.as_ref(), + SEED_SMART_ACCOUNT, + &self.source_account_index.to_le_bytes(), + &[source_account_bump], + ]], + ), + payload.amount, + )? + } + ValidatedAccounts::TokenTransfer { + source_account_info, + source_account_bump, + source_token_account_info, + destination_token_account_info, + mint, + token_program, + } => { + // Transfer SPL token + token_interface::transfer_checked( + CpiContext::new_with_signer( + token_program.to_account_info(), + TransferChecked { + from: source_token_account_info.to_account_info(), + mint: mint.to_account_info(), + to: destination_token_account_info.to_account_info(), + authority: source_account_info.clone(), + }, + &[&[ + SEED_PREFIX, + args.settings_key.as_ref(), + SEED_SMART_ACCOUNT, + &self.source_account_index.to_le_bytes(), + &[source_account_bump], + ]], + ), + payload.amount, + payload.decimals, + )?; + } + } + + // Decrement the amount + self.spending_limit.decrement(payload.amount); + + // Invariant check + self.invariant()?; + + Ok(()) + } +} + +// ============================================================================= +// ACCOUNT VALIDATION +// ============================================================================= + +impl SpendingLimitPolicy { + /// Validate the accounts needed for transfer execution + fn validate_accounts<'info>( + &self, + settings_key: &Pubkey, + args: &SpendingLimitPayload, + accounts: &'info [AccountInfo<'info>], + ) -> Result> { + // Derive source account key + let source_account_index_bytes = self.source_account_index.to_le_bytes(); + let source_account_seeds = + get_smart_account_seeds(settings_key, &source_account_index_bytes); + + // Derive source and destination account keys + let (source_account_key, source_account_bump) = + Pubkey::find_program_address(source_account_seeds.as_slice(), &crate::ID); + + // Mint specific logic + match self.spending_limit.mint { + // Native SOL transfer + mint if mint == Pubkey::default() => { + // Parse out the accounts + let (source_account_info, destination_account_info, system_program) = if let [source_account_info, destination_account_info, system_program, _remaining @ ..] = + accounts + { + ( + source_account_info, + destination_account_info, + system_program, + ) + } else { + return err!(SmartAccountError::InvalidNumberOfAccounts); + }; + // Check that the source account is the same as the source account info + require!( + source_account_key == source_account_info.key(), + SmartAccountError::InvalidAccount + ); + // Check that the destination account is the same as the destination account info + require!( + args.destination == destination_account_info.key(), + SmartAccountError::InvalidAccount + ); + + // Check that the source account is not the same as the destination account + require!( + source_account_info.key() != destination_account_info.key(), + SmartAccountError::InvalidAccount + ); + + // Check the system program + require!( + system_program.key() == system_program::ID, + SmartAccountError::InvalidAccount + ); + + // Sanity check for the decimals. Similar to the one in token_interface::transfer_checked. + require!(args.decimals == 9, SmartAccountError::DecimalsMismatch); + + Ok(ValidatedAccounts::NativeTransfer { + source_account_info, + source_account_bump, + destination_account_info, + system_program, + }) + } + // Token transfer + _ => { + // Parse out the accounts + let ( + source_account_info, + source_token_account_info, + destination_token_account_info, + mint, + token_program, + ) = if let [source_account_info, source_token_account_info, destination_token_account_info, mint, token_program, _remaining @ ..] = + accounts + { + ( + source_account_info, + source_token_account_info, + destination_token_account_info, + mint, + token_program, + ) + } else { + return err!(SmartAccountError::InvalidNumberOfAccounts); + }; + + // Check the source account key + require!( + source_account_key == source_account_info.key(), + SmartAccountError::InvalidAccount + ); + + // Deserialize the source and destination token accounts. Either + // T22 or TokenKeg accounts + let source_token_account = + InterfaceAccount::<'info, TokenAccount>::try_from(source_token_account_info)?; + let destination_token_account = + InterfaceAccount::::try_from(destination_token_account_info)?; + + // Check the mint against the policy state + require_eq!(self.spending_limit.mint, mint.key()); + + // Assert the ownership and mint of the token accounts + require!( + source_token_account.owner == source_account_key + && source_token_account.mint == self.spending_limit.mint, + SmartAccountError::InvalidAccount + ); + require!( + destination_token_account.owner == args.destination + && destination_token_account.mint == self.spending_limit.mint, + SmartAccountError::InvalidAccount + ); + // Check the token program + require_eq!(TokenInterface::ids().contains(&token_program.key()), true); + + Ok(ValidatedAccounts::TokenTransfer { + source_account_info, + source_account_bump, + source_token_account_info, + destination_token_account_info, + mint, + token_program, + }) + } + } + } +} diff --git a/programs/squads_smart_account_program/src/state/policies/mod.rs b/programs/squads_smart_account_program/src/state/policies/mod.rs new file mode 100644 index 0000000..d2ef554 --- /dev/null +++ b/programs/squads_smart_account_program/src/state/policies/mod.rs @@ -0,0 +1,7 @@ +pub mod implementations; +pub mod policy_core; +mod utils; + +pub use policy_core::*; + +pub use implementations::*; diff --git a/programs/squads_smart_account_program/src/state/policies/policy_core/mod.rs b/programs/squads_smart_account_program/src/state/policies/policy_core/mod.rs new file mode 100644 index 0000000..6188cfb --- /dev/null +++ b/programs/squads_smart_account_program/src/state/policies/policy_core/mod.rs @@ -0,0 +1,15 @@ +//! Core policy framework +//! +//! This module contains the fundamental policy framework including: +//! - Policy struct and PolicyType enum +//! - PolicyExecutor trait for type-safe execution +//! - PolicyPayload enum for unified payloads +//! - Core consensus integration + +pub mod payloads; +pub mod policy; +pub mod traits; + +pub use payloads::*; +pub use policy::*; +pub use traits::*; diff --git a/programs/squads_smart_account_program/src/state/policies/policy_core/payloads.rs b/programs/squads_smart_account_program/src/state/policies/policy_core/payloads.rs new file mode 100644 index 0000000..1bbce5a --- /dev/null +++ b/programs/squads_smart_account_program/src/state/policies/policy_core/payloads.rs @@ -0,0 +1,42 @@ +use anchor_lang::prelude::*; + +use crate::{ + state::policies::implementations::InternalFundTransferPayload, + InternalFundTransferPolicyCreationPayload, ProgramInteractionPayload, + ProgramInteractionPolicyCreationPayload, SettingsChangePayload, + SettingsChangePolicyCreationPayload, SpendingLimitPayload, SpendingLimitPolicyCreationPayload, +}; + +use super::PolicySizeTrait; + +/// Unified enum for all policy creation payloads +/// These are used in SettingsAction::PolicyCreate to specify which type of policy to create +#[derive(AnchorSerialize, AnchorDeserialize, Clone)] +pub enum PolicyCreationPayload { + InternalFundTransfer(InternalFundTransferPolicyCreationPayload), + SpendingLimit(SpendingLimitPolicyCreationPayload), + SettingsChange(SettingsChangePolicyCreationPayload), + ProgramInteraction(ProgramInteractionPolicyCreationPayload), +} + +impl PolicyCreationPayload { + /// Calculate the size of the resulting policy data after creation + pub fn policy_state_size(&self) -> usize { + // 1 for the Wrapper enum type + 1 + match self { + PolicyCreationPayload::InternalFundTransfer(payload) => payload.policy_state_size(), + PolicyCreationPayload::SpendingLimit(payload) => payload.policy_state_size(), + PolicyCreationPayload::SettingsChange(payload) => payload.policy_state_size(), + PolicyCreationPayload::ProgramInteraction(payload) => payload.policy_state_size(), + } + } +} + +/// Unified enum for all policy execution payloads +#[derive(AnchorSerialize, AnchorDeserialize, Clone)] +pub enum PolicyPayload { + InternalFundTransfer(InternalFundTransferPayload), + ProgramInteraction(ProgramInteractionPayload), + SpendingLimit(SpendingLimitPayload), + SettingsChange(SettingsChangePayload), +} diff --git a/programs/squads_smart_account_program/src/state/policies/policy_core/policy.rs b/programs/squads_smart_account_program/src/state/policies/policy_core/policy.rs new file mode 100644 index 0000000..43cc0b8 --- /dev/null +++ b/programs/squads_smart_account_program/src/state/policies/policy_core/policy.rs @@ -0,0 +1,431 @@ +use anchor_lang::prelude::*; + +use super::{payloads::PolicyPayload, traits::PolicyTrait, PolicyExecutionContext}; +use crate::state::policies::implementations::InternalFundTransferPolicy; +use crate::MAX_TIME_LOCK; +use crate::{ + errors::*, + interface::consensus_trait::{Consensus, ConsensusAccountType}, + InternalFundTransferExecutionArgs, ProgramInteractionExecutionArgs, + ProgramInteractionPolicy, Proposal, Settings, SettingsChangeExecutionArgs, + SettingsChangePolicy, SmartAccountSigner, SpendingLimitExecutionArgs, SpendingLimitPolicy, + Transaction, SEED_POLICY, SEED_PREFIX, +}; + +#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug, PartialEq, Eq, InitSpace)] +pub enum PolicyExpiration { + /// Policy expires at a specific timestamp + Timestamp(i64), + /// Policy expires when the core settings hash mismatches the stored hash. + SettingsState([u8; 32]), +} + +#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug, PartialEq, Eq)] +pub enum PolicyExpirationArgs { + /// Policy expires at a specific timestamp + Timestamp(i64), + /// Policy expires when the core settings hash mismatches the stored hash. + SettingsState, +} + +#[account] +pub struct Policy { + /// The smart account this policy belongs to. + pub settings: Pubkey, + + /// The seed of the policy. + pub seed: u64, + + /// Bump for the policy. + pub bump: u8, + + /// Transaction index for stale transaction protection. + pub transaction_index: u64, + + /// Stale transaction index boundary. + pub stale_transaction_index: u64, + + /// Signers attached to the policy with their permissions. + pub signers: Vec, + + /// Threshold for approvals. + pub threshold: u16, + + /// How many seconds must pass between approval and execution. + pub time_lock: u32, + + /// The state of the policy. + pub policy_state: PolicyState, + + /// Timestamp when the policy becomes active. + pub start: i64, + + /// Policy expiration - either time-based or state-based. + pub expiration: Option, + + /// Rent Collector for the policy for when it gets closed + pub rent_collector: Pubkey +} + +impl Policy { + pub fn size(signers_length: usize, policy_data_length: usize) -> usize { + 8 + // anchor discriminator + 32 + // settings + 8 + // seed + 1 + // bump + 8 + // transaction_index + 8 + // stale_transaction_index + 4 + // signers vector length + signers_length * SmartAccountSigner::INIT_SPACE + // signers + 2 + // threshold + 4 + // time_lock + 1 + policy_data_length + // discriminator + policy_data_length + 8 + // start_timestamp + 1 + PolicyExpiration::INIT_SPACE + // expiration (discriminator + max data size) + 32 // rent_collector + } + + /// Check if the policy account space needs to be reallocated. + pub fn realloc_if_needed<'a>( + policy: AccountInfo<'a>, + signers_length: usize, + policy_data_length: usize, + rent_payer: Option>, + system_program: Option>, + ) -> Result { + let current_account_size = policy.data.borrow().len(); + let required_size = Policy::size(signers_length, policy_data_length); + + if current_account_size >= required_size { + return Ok(false); + } + + crate::utils::realloc(&policy, required_size, rent_payer, system_program)?; + Ok(true) + } + + pub fn invariant(&self) -> Result<()> { + // Max number of signers is u16::MAX. + require!( + self.signers.len() <= usize::from(u16::MAX), + SmartAccountError::TooManySigners + ); + + // There must be no duplicate signers. + let has_duplicates = self.signers.windows(2).any(|win| win[0].key == win[1].key); + require!(!has_duplicates, SmartAccountError::DuplicateSigner); + + // Signers must not have unknown permissions. + require!( + self.signers.iter().all(|s| s.permissions.mask < 8), + SmartAccountError::UnknownPermission + ); + + // There must be at least one signer with Initiate permission. + require!(self.num_proposers() > 0, SmartAccountError::NoProposers); + + // There must be at least one signer with Execute permission. + require!(self.num_executors() > 0, SmartAccountError::NoExecutors); + + // There must be at least one signer with Vote permission. + require!(self.num_voters() > 0, SmartAccountError::NoVoters); + + // Threshold must be greater than 0. + require!(self.threshold > 0, SmartAccountError::InvalidThreshold); + + // Threshold must not exceed the number of voters. + require!( + usize::from(self.threshold) <= self.num_voters(), + SmartAccountError::InvalidThreshold + ); + + // Stale transaction index must be <= transaction index. + require!( + self.stale_transaction_index <= self.transaction_index, + SmartAccountError::InvalidStaleTransactionIndex + ); + + // If policy has expiration, it must be valid + if let Some(expiration) = &self.expiration { + match expiration { + PolicyExpiration::Timestamp(timestamp) => { + require!( + *timestamp > self.start, + SmartAccountError::PolicyInvariantInvalidExpiration + ); + } + _ => {} + } + } + + // Time Lock must not exceed the maximum allowed to prevent bricking the policy. + require!( + self.time_lock <= MAX_TIME_LOCK, + SmartAccountError::TimeLockExceedsMaxAllowed + ); + // Policy state must be valid + self.policy_state.invariant()?; + + Ok(()) + } + + /// Create policy state safely + pub fn create_state( + settings: Pubkey, + seed: u64, + bump: u8, + signers: &Vec, + threshold: u16, + time_lock: u32, + policy_state: PolicyState, + start: i64, + expiration: Option, + rent_collector: Pubkey, + ) -> Result { + let mut sorted_signers = signers.clone(); + sorted_signers.sort_by_key(|s| s.key); + + Ok(Policy { + settings, + seed, + bump, + transaction_index: 0, + stale_transaction_index: 0, + signers: sorted_signers, + threshold, + time_lock, + policy_state, + start, + expiration, + rent_collector, + }) + } + + /// Update policy state safely. Disallows + pub fn update_state( + &mut self, + signers: &Vec, + threshold: u16, + time_lock: u32, + policy_state: PolicyState, + expiration: Option, + ) -> Result<()> { + let mut sorted_signers = signers.clone(); + sorted_signers.sort_by_key(|s| s.key); + + self.signers = sorted_signers; + self.threshold = threshold; + self.time_lock = time_lock; + self.policy_state = policy_state; + self.expiration = expiration; + Ok(()) + } +} + +#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug)] +pub enum PolicyState { + /// Internal fund transfer policy. + InternalFundTransfer(InternalFundTransferPolicy), + /// Spending limit policy + SpendingLimit(SpendingLimitPolicy), + /// Settings change policy + SettingsChange(SettingsChangePolicy), + /// Program interaction policy + ProgramInteraction(ProgramInteractionPolicy), +} + +impl PolicyState { + pub fn invariant(&self) -> Result<()> { + match self { + PolicyState::InternalFundTransfer(policy) => policy.invariant(), + PolicyState::SpendingLimit(policy) => policy.invariant(), + PolicyState::SettingsChange(policy) => policy.invariant(), + PolicyState::ProgramInteraction(policy) => policy.invariant(), + } + } +} + +impl Policy { + /// Validate the payload against the policy. + pub fn validate_payload( + &self, + context: PolicyExecutionContext, + payload: &PolicyPayload, + ) -> Result<()> { + match (&self.policy_state, payload) { + ( + PolicyState::InternalFundTransfer(policy), + PolicyPayload::InternalFundTransfer(payload), + ) => policy.validate_payload(context, payload), + (PolicyState::SpendingLimit(policy), PolicyPayload::SpendingLimit(payload)) => { + policy.validate_payload(context, payload) + } + (PolicyState::SettingsChange(policy), PolicyPayload::SettingsChange(payload)) => { + policy.validate_payload(context, payload) + } + ( + PolicyState::ProgramInteraction(policy), + PolicyPayload::ProgramInteraction(payload), + ) => policy.validate_payload(context, payload), + _ => err!(SmartAccountError::InvalidPolicyPayload), + } + } + /// Dispatch method for policy execution + pub fn execute<'info>( + &mut self, + transaction_account: Option<&Account<'info, Transaction>>, + proposal_account: Option<&Account<'info, Proposal>>, + payload: &PolicyPayload, + accounts: &'info [AccountInfo<'info>], + ) -> Result<()> { + match (&mut self.policy_state, payload) { + ( + PolicyState::InternalFundTransfer(ref mut policy_state), + PolicyPayload::InternalFundTransfer(payload), + ) => { + let args = InternalFundTransferExecutionArgs { + settings_key: self.settings, + }; + policy_state.execute_payload(args, payload, accounts) + } + ( + PolicyState::SpendingLimit(ref mut policy_state), + PolicyPayload::SpendingLimit(payload), + ) => { + let args = SpendingLimitExecutionArgs { + settings_key: self.settings, + }; + policy_state.execute_payload(args, payload, accounts) + } + ( + PolicyState::ProgramInteraction(ref mut policy_state), + PolicyPayload::ProgramInteraction(payload), + ) => { + let args = ProgramInteractionExecutionArgs { + settings_key: self.settings, + // if the transaction account is not provided, use a default + // pubkey (sync transactions) + transaction_key: transaction_account + .map(|t| t.key()) + .unwrap_or(Pubkey::default()), + // if the proposal account is not provided, use a default + // pubkey (sync transactions) + proposal_key: proposal_account + .map(|p| p.key()) + .unwrap_or(Pubkey::default()), + policy_signers: self.signers.clone(), + }; + policy_state.execute_payload(args, payload, accounts) + } + ( + PolicyState::SettingsChange(ref mut policy_state), + PolicyPayload::SettingsChange(payload), + ) => { + let args = SettingsChangeExecutionArgs { + settings_key: self.settings, + }; + policy_state.execute_payload(args, payload, accounts) + } + _ => err!(SmartAccountError::InvalidPolicyPayload), + } + } +} +// Implement Consensus for Policy +impl Consensus for Policy { + /// Checks if a given policy is active based on it's start and expiration + fn is_active(&self, accounts: &[AccountInfo]) -> Result<()> { + // Get the current timestamp + let current_timestamp = Clock::get()?.unix_timestamp; + // Check if the policy has started + require!( + current_timestamp >= self.start, + SmartAccountError::PolicyNotActiveYet + ); + // Check if the policy is expired + match self.expiration { + Some(PolicyExpiration::Timestamp(expiration_timestamp)) => { + // Get current timestamp + let current_timestamp = Clock::get()?.unix_timestamp; + require!( + current_timestamp < expiration_timestamp, + SmartAccountError::PolicyExpirationViolationTimestampExpired + ); + Ok(()) + } + Some(PolicyExpiration::SettingsState(stored_hash)) => { + // Find the settings account in the accounts list + let settings_account_info = &accounts + .get(0) + .ok_or(SmartAccountError::PolicyExpirationViolationSettingsAccountNotPresent)?; + require!( + settings_account_info.key() == self.settings, + SmartAccountError::PolicyExpirationViolationPolicySettingsKeyMismatch + ); + // Deserialize the settings account + let account_data = settings_account_info.try_borrow_data()?; + let settings = Settings::try_deserialize(&mut &**account_data)?; + + // Generate the current core state hash + let current_hash = settings.generate_core_state_hash()?; + + require!( + current_hash == stored_hash, + SmartAccountError::PolicyExpirationViolationHashExpired + ); + Ok(()) + } + // If the policy has no expiration, it is always active + None => Ok(()), + } + } + fn account_type(&self) -> ConsensusAccountType { + ConsensusAccountType::Policy + } + + fn check_derivation(&self, key: Pubkey) -> Result<()> { + // TODO: Since policies can be closed, we need to make the derivation deterministic. + let (address, _bump) = Pubkey::find_program_address( + &[ + SEED_PREFIX, + SEED_POLICY, + self.settings.as_ref(), + self.seed.to_le_bytes().as_ref(), + ], + &crate::ID, + ); + require_keys_eq!(address, key, SmartAccountError::InvalidAccount); + Ok(()) + } + fn signers(&self) -> &[SmartAccountSigner] { + &self.signers + } + + fn threshold(&self) -> u16 { + self.threshold + } + + fn time_lock(&self) -> u32 { + self.time_lock + } + + fn transaction_index(&self) -> u64 { + self.transaction_index + } + + fn set_transaction_index(&mut self, transaction_index: u64) -> Result<()> { + self.transaction_index = transaction_index; + Ok(()) + } + + fn stale_transaction_index(&self) -> u64 { + self.stale_transaction_index + } + + fn invalidate_prior_transactions(&mut self) { + self.stale_transaction_index = self.transaction_index; + } + + fn invariant(&self) -> Result<()> { + self.invariant() + } +} diff --git a/programs/squads_smart_account_program/src/state/policies/policy_core/traits.rs b/programs/squads_smart_account_program/src/state/policies/policy_core/traits.rs new file mode 100644 index 0000000..eafdfaa --- /dev/null +++ b/programs/squads_smart_account_program/src/state/policies/policy_core/traits.rs @@ -0,0 +1,59 @@ +use anchor_lang::prelude::*; + +/// Trait for policy creation payloads that can be converted to policy state +pub trait PolicyPayloadConversionTrait { + type PolicyState; + + /// Convert the creation payload to the actual policy state + fn to_policy_state(self) -> Result; +} + +/// Trait for calculating Borsh serialization sizes of policy-related structs +pub trait PolicySizeTrait { + /// Calculate the size when this payload is Borsh serialized + fn creation_payload_size(&self) -> usize; + + /// Calculate the size of the resulting policy state when Borsh serialized + fn policy_state_size(&self) -> usize; +} + +/// The context in which the policy is being executed +pub enum PolicyExecutionContext { + /// The policy is being executed synchronously + Synchronous, + /// The policy is being executed asynchronously + Asynchronous, +} +/// Core trait for policy execution - implemented by specific policy types +pub trait PolicyTrait { + /// The policy state + type PolicyState; + + /// The creation payload + type CreationPayload: PolicyPayloadConversionTrait + + PolicySizeTrait; + + /// The payload type used when executing this policy + type UsagePayload; + + /// Additional arguments needed for policy execution + type ExecutionArgs; + + /// Validate the policy state + fn invariant(&self) -> Result<()>; + + /// Validate the payload against policy constraints before execution + fn validate_payload( + &self, + context: PolicyExecutionContext, + payload: &Self::UsagePayload, + ) -> Result<()>; + + /// Execute the policy action with the validated payload + fn execute_payload<'info>( + &mut self, + args: Self::ExecutionArgs, + payload: &Self::UsagePayload, + accounts: &'info [AccountInfo<'info>], + ) -> Result<()>; +} diff --git a/programs/squads_smart_account_program/src/state/policies/utils/account_tracking.rs b/programs/squads_smart_account_program/src/state/policies/utils/account_tracking.rs new file mode 100644 index 0000000..34a717f --- /dev/null +++ b/programs/squads_smart_account_program/src/state/policies/utils/account_tracking.rs @@ -0,0 +1,195 @@ +use anchor_lang::{prelude::*, Ids}; +use anchor_spl::token_interface::{TokenAccount, TokenInterface}; + +use crate::{ + errors::SmartAccountError, state::policies::utils::spending_limit_v2::SpendingLimitV2, +}; + +pub struct TrackedTokenAccount<'info> { + pub account: &'info AccountInfo<'info>, + pub balance: u64, + pub delegate: Option<(Pubkey, u64)>, + pub authority: Pubkey, +} + +pub struct TrackedExecutingAccount<'info> { + pub account: &'info AccountInfo<'info>, + pub lamports: u64, +} + +pub struct Balances<'info> { + pub executing_account: TrackedExecutingAccount<'info>, + pub token_accounts: Vec>, +} + +/// Pre-check the balances of the executing account and any token accounts that are owned by it +pub fn check_pre_balances<'info>( + executing_account: Pubkey, + accounts: &'info [AccountInfo<'info>], +) -> Balances<'info> { + let mut tracked_token_accounts = Vec::with_capacity(accounts.len()); + + // Get the executing account info + let executing_account_info = accounts + .iter() + .find(|account| account.key() == executing_account) + .unwrap(); + + // Track the executing account + let tracked_executing_account = TrackedExecutingAccount { + account: executing_account_info, + lamports: executing_account_info.lamports(), + }; + + // Iterate over all accounts and track any given token accounts that are + // owned by the executing account + let token_program_ids = TokenInterface::ids(); + for account in accounts { + // Only track accounts owned by a token program and that are writable + if token_program_ids.contains(&account.owner) && account.is_writable { + // This may fail for accounts that are not token accounts, so skip if it does + let Ok(token_account) = InterfaceAccount::::try_from(account) else { + continue; + }; + // Only track token accounts that are owned by the executing account + if token_account.owner == executing_account { + let balance = token_account.amount; + let delegate = if let Some(delegate_key) = Option::from(token_account.delegate) { + Some((delegate_key, token_account.delegated_amount)) + } else { + None + }; + let authority = token_account.owner; + + // Add the token account to the tracked token accounts + tracked_token_accounts.push(TrackedTokenAccount { + account, + balance, + delegate, + authority, + }); + } + } + } + + Balances { + executing_account: tracked_executing_account, + token_accounts: tracked_token_accounts, + } +} + +impl<'info> Balances<'info> { + /// Evaluate balance changes against the spending limits + pub fn evaluate_balance_changes( + &self, + spending_limits: &mut Vec, + ) -> Result<()> { + // Get the current timestamp + let current_timestamp = Clock::get()?.unix_timestamp; + + // Check the executing accounts lamports + let current_lamports = self.executing_account.account.lamports(); + + // Check the SOL spending limit + // Note: Assumes spending limits have been deduplicated, and no two spending limits can have the same mint + if let Some(spending_limit) = spending_limits.iter_mut().find(|spending_limit| { + spending_limit.mint() == Pubkey::default() + && spending_limit.is_active(current_timestamp).is_ok() + }) { + // Ensure the executing account doesn't have less lamports than the allowed change + let minimum_balance = self + .executing_account + .lamports + .saturating_sub(spending_limit.remaining_in_period()); + require_gte!( + current_lamports, + minimum_balance, + SmartAccountError::ProgramInteractionInsufficientLamportAllowance + ); + // If the executing account has a lower balance than before, decrement the spending limit + if current_lamports < self.executing_account.lamports { + spending_limit.decrement(self.executing_account.lamports - current_lamports); + } + } else { + // Ensure the executing account doesn't have less lamports than before + require_gte!( + current_lamports, + self.executing_account.lamports, + SmartAccountError::ProgramInteractionModifiedIllegalBalance + ); + } + + // Check all of the token accounts + for tracked_token_account in &self.token_accounts { + // Ensure that any tracked token account is not closed + if tracked_token_account.account.data_is_empty() { + return Err( + SmartAccountError::ProgramInteractionIllegalTokenAccountModification.into(), + ); + } + // Re-deserialize the token account + let post_token_account = + InterfaceAccount::::try_from(tracked_token_account.account).unwrap(); + + // Find the spending limit for the token account if it exists and is active + if let Some(spending_limit) = spending_limits.iter_mut().find(|spending_limit| { + spending_limit.mint() == post_token_account.mint + && spending_limit.is_active(current_timestamp).is_ok() + }) { + { + // Saturating subtraction since remaining_amount could be + // higher than the balance + let minimum_balance = tracked_token_account + .balance + .saturating_sub(spending_limit.remaining_in_period()); + + // Ensure the token account has no greater difference than the allowed change + require_gte!( + post_token_account.amount, + minimum_balance, + SmartAccountError::ProgramInteractionInsufficientTokenAllowance + ); + + // If the token account has a lower balance than before, decrement the spending limit + if post_token_account.amount < tracked_token_account.balance { + spending_limit + .decrement(tracked_token_account.balance - post_token_account.amount); + } + } + } else { + // Ensure the token account has the exact or greater balance + // than before + require_gte!( + post_token_account.amount, + tracked_token_account.balance, + SmartAccountError::ProgramInteractionModifiedIllegalBalance + ); + } + + // Ensure the delegate, and authority have not changed. Delegated + // amount may decrease + let post_delegate: Option<(Pubkey, u64)> = + if let Some(delegate_key) = Option::from(post_token_account.delegate) { + Some((delegate_key, post_token_account.delegated_amount)) + } else { + None + }; + match (post_delegate, tracked_token_account.delegate) { + (Some(post_delegate), Some(tracked_delegate)) => { + require_eq!(post_delegate.0, tracked_delegate.0); + require_gte!(post_delegate.1, tracked_delegate.1); + } + (None, None) => {} + _ => { + return Err(SmartAccountError::ProgramInteractionIllegalTokenAccountModification.into()); + } + }; + require_eq!( + post_token_account.owner, + tracked_token_account.authority, + SmartAccountError::ProgramInteractionIllegalTokenAccountModification + ); + } + Ok(()) + } +} diff --git a/programs/squads_smart_account_program/src/state/policies/utils/mod.rs b/programs/squads_smart_account_program/src/state/policies/utils/mod.rs new file mode 100644 index 0000000..b4988ee --- /dev/null +++ b/programs/squads_smart_account_program/src/state/policies/utils/mod.rs @@ -0,0 +1,5 @@ +pub mod account_tracking; +pub mod spending_limit_v2; + +pub use account_tracking::*; +pub use spending_limit_v2::*; \ No newline at end of file diff --git a/programs/squads_smart_account_program/src/state/policies/utils/spending_limit_v2.rs b/programs/squads_smart_account_program/src/state/policies/utils/spending_limit_v2.rs new file mode 100644 index 0000000..aeca0bb --- /dev/null +++ b/programs/squads_smart_account_program/src/state/policies/utils/spending_limit_v2.rs @@ -0,0 +1,409 @@ +use anchor_lang::prelude::*; + +use crate::errors::SmartAccountError; + +#[derive(AnchorSerialize, AnchorDeserialize, Clone, Copy, Debug, PartialEq, Eq, InitSpace)] +pub enum PeriodV2 { + /// The spending limit can only be used once + OneTime, + /// The spending limit is reset every day + Daily, + /// The spending limit is reset every week (7 days) + Weekly, + /// The spending limit is reset every month (30 days) + Monthly, + /// Custom period in seconds + Custom(i64), +} + +impl PeriodV2 { + pub fn to_seconds(&self) -> Option { + match self { + PeriodV2::OneTime => None, + PeriodV2::Daily => Some(24 * 60 * 60), + PeriodV2::Weekly => Some(7 * 24 * 60 * 60), + PeriodV2::Monthly => Some(30 * 24 * 60 * 60), + PeriodV2::Custom(seconds) => Some(*seconds), + } + } +} + +/// Configuration for time-based constraints +#[derive(AnchorSerialize, AnchorDeserialize, Clone, Copy, Debug, PartialEq, Eq, InitSpace)] +pub struct TimeConstraints { + /// Optional start timestamp (0 means immediate) + pub start: i64, + /// Optional expiration timestamp + pub expiration: Option, + /// Reset period for the spending limit + pub period: PeriodV2, + /// Whether unused allowances accumulate across periods + pub accumulate_unused: bool, +} + +/// Quantity constraints for spending limits +#[derive(AnchorSerialize, AnchorDeserialize, Clone, Copy, Debug, PartialEq, Eq, InitSpace)] +pub struct QuantityConstraints { + /// Maximum quantity per period + pub max_per_period: u64, + /// Maximum quantity per individual use (0 means no per-use limit) + pub max_per_use: u64, + /// Whether to enforce exact quantity matching on max per use. + pub enforce_exact_quantity: bool, +} + +/// Usage tracking for resource consumption +#[derive(AnchorSerialize, AnchorDeserialize, Clone, Copy, Debug, PartialEq, Eq, InitSpace)] +pub struct UsageState { + /// Remaining quantity in current period + pub remaining_in_period: u64, + /// Unix timestamp of last reset + pub last_reset: i64, +} + +/// Shared spending limit structure that combines timing, quantity, usage, and mint +#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug, PartialEq, Eq, InitSpace)] +pub struct SpendingLimitV2 { + /// The token mint the spending limit is for. + /// Pubkey::default() means SOL. + /// use NATIVE_MINT for Wrapped SOL. + pub mint: Pubkey, + + /// Timing configuration + pub time_constraints: TimeConstraints, + + /// Amount constraints + pub quantity_constraints: QuantityConstraints, + + /// Current usage tracking + pub usage: UsageState, +} + +impl SpendingLimitV2 { + /// Check if the spending limit is currently active + pub fn is_active(&self, current_timestamp: i64) -> Result<()> { + // Check start time + if current_timestamp < self.time_constraints.start { + return err!(SmartAccountError::SpendingLimitNotActive); + } + + // Check expiration + if let Some(expiration) = self.time_constraints.expiration { + if current_timestamp > expiration { + return err!(SmartAccountError::SpendingLimitExpired); + } + } + + Ok(()) + } + + // Returns the mint of the spending limit + pub fn mint(&self) -> Pubkey { + self.mint + } + + // Returns the remaining amount in the period for the spending limit + pub fn remaining_in_period(&self) -> u64 { + self.usage.remaining_in_period + } + + /// Check that the amount is less than the remaining amount, and if it complies with the quantity constraints + pub fn check_amount(&self, amount: u64) -> Result<()> { + // Remaining amount constraint + if amount > self.usage.remaining_in_period { + return err!(SmartAccountError::SpendingLimitInsufficientRemainingAmount); + } + // Max per use constraint + if self.quantity_constraints.max_per_use > 0 { + require!( + amount <= self.quantity_constraints.max_per_use, + SmartAccountError::SpendingLimitViolatesMaxPerUseConstraint + ); + } + // Exact amount constraint + if self.quantity_constraints.enforce_exact_quantity { + // Exact max per use constraint + require_eq!( + amount, + self.quantity_constraints.max_per_use, + SmartAccountError::SpendingLimitViolatesExactQuantityConstraint + ); + } + + Ok(()) + } + + pub fn decrement(&mut self, amount: u64) { + self.usage.remaining_in_period = + self.usage.remaining_in_period.checked_sub(amount).unwrap(); + } + + /// Reset amounts if period boundary has been crossed + pub fn reset_if_needed(&mut self, current_timestamp: i64) { + // Reset logic for spending limits + if let Some(reset_period) = self.time_constraints.period.to_seconds() { + // Check that the spending limit is active + if self.is_active(current_timestamp).is_err() { + return; + } + + let passed_since_last_reset = current_timestamp + .checked_sub(self.usage.last_reset) + .unwrap(); + + if passed_since_last_reset > reset_period { + let periods_passed = passed_since_last_reset.checked_div(reset_period).unwrap(); + + // Update last_reset: last_reset = last_reset + periods_passed * reset_period + self.usage.last_reset = self + .usage + .last_reset + .checked_add(periods_passed.checked_mul(reset_period).unwrap()) + .unwrap(); + + if self.time_constraints.accumulate_unused { + // For overflow: add missed periods to current amount + // (overflow is only enabled with expiration, so we know it exists) + let additional_amount = self + .quantity_constraints + .max_per_period + .saturating_mul(periods_passed as u64); + self.usage.remaining_in_period = self + .usage + .remaining_in_period + .saturating_add(additional_amount); + } else { + // For non-overflow: reset to full period amount (original behavior) + self.usage.remaining_in_period = self.quantity_constraints.max_per_period; + } + } + } + } + + pub fn invariant(&self) -> Result<()> { + // Amount per period must be non-zero + require_neq!( + self.quantity_constraints.max_per_period, + 0, + SmartAccountError::SpendingLimitInvariantMaxPerPeriodZero + ); + + // If start time is set, it must be positive + require!( + self.time_constraints.start >= 0, + SmartAccountError::SpendingLimitInvariantStartTimePositive + ); + + // If expiration is set, it must be positive + if self.time_constraints.expiration.is_some() { + // Since start is positive, expiration must be greater than start, + // we can skip the check for expiration being positive. + require!( + self.time_constraints.expiration.unwrap() > self.time_constraints.start, + SmartAccountError::SpendingLimitInvariantExpirationSmallerThanStart + ); + } + + // If overflow is enabled, must have expiration. This is to prevent + // footguns + if self.time_constraints.accumulate_unused { + // OneTime period cannot have overflow enabled + require!( + self.time_constraints.period != PeriodV2::OneTime, + SmartAccountError::SpendingLimitInvariantOneTimePeriodCannotHaveOverflowEnabled + ); + require!( + self.time_constraints.expiration.is_some(), + SmartAccountError::SpendingLimitInvariantOverflowEnabledMustHaveExpiration + ); + // Remaining amount must always be less than expiration - start / + // period + 1 * max per period + let total_time = + self.time_constraints.expiration.unwrap() - self.time_constraints.start; + let total_periods = total_time + .checked_div(self.time_constraints.period.to_seconds().unwrap()) + .unwrap() as u64; + // Total amount based on number of periods within start & expiration + let max_amount = match total_time % self.time_constraints.period.to_seconds().unwrap() { + // Start & Expiration are divisible by period, so we can use the + // total number of periods to calculate the max amount. + 0 => total_periods + .checked_mul(self.quantity_constraints.max_per_period) + .unwrap(), + // Start & Expiration are divisible by period with a remainder, so we need to + // add an extra period to the total number of periods. + _ => (total_periods.checked_add(1).unwrap()) + .checked_mul(self.quantity_constraints.max_per_period) + .unwrap(), + }; + // Remaining amount must always be less than max amount + require!( + self.usage.remaining_in_period <= max_amount, + SmartAccountError::SpendingLimitInvariantOverflowRemainingAmountGreaterThanMaxAmount + ); + } else { + // If overflow is disabled, remaining in period must be less than or equal to max per period + require!( + self.usage.remaining_in_period <= self.quantity_constraints.max_per_period, + SmartAccountError::SpendingLimitInvariantRemainingAmountGreaterThanMaxPerPeriod + ); + } + + // If exact amount is enforced, per-use amount must be set and non-zero + if self.quantity_constraints.enforce_exact_quantity { + require!( + self.quantity_constraints.max_per_use > 0, + SmartAccountError::SpendingLimitInvariantExactQuantityMaxPerUseZero + ); + } + + // If per-use amount is set, it cannot exceed per-period amount + if self.quantity_constraints.max_per_use > 0 { + require!( + self.quantity_constraints.max_per_use <= self.quantity_constraints.max_per_period, + SmartAccountError::SpendingLimitInvariantMaxPerUseGreaterThanMaxPerPeriod + ); + } + + // Custom period must have positive duration + if let PeriodV2::Custom(seconds) = self.time_constraints.period { + require!( + seconds > 0, + SmartAccountError::SpendingLimitInvariantCustomPeriodNegative + ); + } + + // Last reset must be between start and expiration + if let Some(expiration) = self.time_constraints.expiration { + require!( + self.usage.last_reset >= self.time_constraints.start + && self.usage.last_reset <= expiration, + SmartAccountError::SpendingLimitInvariantLastResetOutOfBounds + ); + } else { + require!( + self.usage.last_reset >= self.time_constraints.start, + SmartAccountError::SpendingLimitInvariantLastResetSmallerThanStart + ); + } + + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use solana_program::pubkey::Pubkey; + + fn make_time_constraints( + period: PeriodV2, + accumulate_unused: bool, + start: i64, + expiration: Option, + ) -> TimeConstraints { + TimeConstraints { + start, + expiration, + period, + accumulate_unused, + } + } + + fn make_quantity_constraints( + max_per_period: u64, + max_per_use: u64, + enforce_exact_quantity: bool, + ) -> QuantityConstraints { + QuantityConstraints { + max_per_period, + max_per_use, + enforce_exact_quantity, + } + } + + fn make_usage_state(remaining: u64, last_reset: i64) -> UsageState { + UsageState { + remaining_in_period: remaining, + last_reset, + } + } + + #[test] + fn test_reset_amount_non_accumulate_unused() { + // 2.5 days in seconds + let now = 216_000; + let one_and_a_half_days_ago = now - 129_600; + let mut policy = SpendingLimitV2 { + mint: Pubkey::default(), + time_constraints: make_time_constraints(PeriodV2::Daily, false, 0, None), + quantity_constraints: make_quantity_constraints(100, 0, false), + usage: make_usage_state(50, one_and_a_half_days_ago), // last reset was 1 day ago + }; + // Should reset to max_per_period + policy.reset_if_needed(now); + assert_eq!(policy.usage.remaining_in_period, 100); + } + + #[test] + fn test_reset_amount_accumulate_unused() { + // 2.5 days in seconds + let now = 216_000; + let one_and_a_half_days_ago = now - 129_600; + let mut policy = SpendingLimitV2 { + mint: Pubkey::default(), + time_constraints: make_time_constraints(PeriodV2::Daily, true, 0, None), + quantity_constraints: make_quantity_constraints(100, 0, false), + usage: make_usage_state(50, one_and_a_half_days_ago), // last reset was 1.5 days ago + }; + // Should reset to max_per_period + policy.reset_if_needed(now); + assert_eq!(policy.usage.remaining_in_period, 150); + } + + #[test] + fn test_reset_amount_accumulate_unused_2() { + // 2.5 days in seconds + let now = 216_000; + let mut policy = SpendingLimitV2 { + mint: Pubkey::default(), + time_constraints: make_time_constraints(PeriodV2::Daily, true, 0, None), + quantity_constraints: make_quantity_constraints(100, 0, false), + usage: make_usage_state(50, 0), // last reset was 1.5 days ago + }; + // Should reset to max_per_period + policy.reset_if_needed(now); + assert_eq!(policy.usage.remaining_in_period, 250); + } + + #[test] + fn test_decrement_amount() { + let mut policy = SpendingLimitV2 { + mint: Pubkey::default(), + time_constraints: make_time_constraints(PeriodV2::Daily, false, 1_000_000, None), + quantity_constraints: make_quantity_constraints(100, 0, false), + usage: make_usage_state(100, 1_000_000), + }; + policy.decrement(30); + assert_eq!(policy.usage.remaining_in_period, 70); + } + + #[test] + fn test_is_active() { + let now = 1_000_000; + let policy = SpendingLimitV2 { + mint: Pubkey::default(), + time_constraints: make_time_constraints( + PeriodV2::Daily, + false, + now - 10, + Some(now + 100), + ), + quantity_constraints: make_quantity_constraints(100, 0, false), + usage: make_usage_state(100, now - 10), + }; + assert!(policy.is_active(now).is_ok()); + assert!(policy.is_active(now - 100_000).is_err()); // before start + assert!(policy.is_active(now + 200_000).is_err()); // after expiration + } +} diff --git a/programs/squads_smart_account_program/src/state/proposal.rs b/programs/squads_smart_account_program/src/state/proposal.rs index 8c3cee7..69fbe90 100644 --- a/programs/squads_smart_account_program/src/state/proposal.rs +++ b/programs/squads_smart_account_program/src/state/proposal.rs @@ -1,19 +1,22 @@ #![allow(deprecated)] use anchor_lang::prelude::*; +use crate::consensus_trait::ConsensusAccountType; use crate::errors::*; use crate::id; use crate::utils; use crate::utils::realloc; - -use anchor_lang::system_program; +use crate::LogAuthorityInfo; +use crate::ProposalEvent; +use crate::ProposalEventType; +use crate::SmartAccountEvent; /// Stores the data required for tracking the status of a smart account proposal. /// Each `Proposal` has a 1:1 association with a transaction account, e.g. a `Transaction` or a `SettingsTransaction`; /// the latter can be executed only after the `Proposal` has been approved and its time lock is released. #[account] pub struct Proposal { - /// The settings this belongs to. + /// The consensus account (settings or policy) this belongs to. pub settings: Pubkey, /// Index of the smart account transaction this proposal is associated with. pub transaction_index: u64, @@ -165,16 +168,30 @@ impl Proposal { proposal_account: Option, proposal_info: AccountInfo<'info>, proposal_rent_collector: AccountInfo<'info>, + log_authority_info: &LogAuthorityInfo<'info>, + consensus_account_type: ConsensusAccountType, ) -> Result<()> { if let Some(proposal) = proposal_account { require!( proposal_rent_collector.key() == proposal.rent_collector, SmartAccountError::InvalidRentCollector ); + let proposal_key = proposal_info.key(); utils::close( proposal_info, proposal_rent_collector, )?; + let event = ProposalEvent { + event_type: ProposalEventType::Close, + consensus_account: log_authority_info.authority.key(), + consensus_account_type, + proposal_pubkey: proposal_key, + transaction_index: proposal.transaction_index, + signer: None, + memo: None, + proposal: None, + }; + SmartAccountEvent::ProposalEvent(event).log(&log_authority_info)?; } Ok(()) } diff --git a/programs/squads_smart_account_program/src/state/seeds.rs b/programs/squads_smart_account_program/src/state/seeds.rs index ba265b7..e53e8f4 100644 --- a/programs/squads_smart_account_program/src/state/seeds.rs +++ b/programs/squads_smart_account_program/src/state/seeds.rs @@ -1,6 +1,4 @@ -use anchor_lang::AnchorSerialize; - -use super::Settings; +use anchor_lang::prelude::Pubkey; pub const SEED_PREFIX: &[u8] = b"smart_account"; pub const SEED_PROGRAM_CONFIG: &[u8] = b"program_config"; @@ -12,6 +10,31 @@ pub const SEED_SMART_ACCOUNT: &[u8] = b"smart_account"; pub const SEED_EPHEMERAL_SIGNER: &[u8] = b"ephemeral_signer"; pub const SEED_SPENDING_LIMIT: &[u8] = b"spending_limit"; pub const SEED_TRANSACTION_BUFFER: &[u8] = b"transaction_buffer"; +pub const SEED_POLICY: &[u8] = b"policy"; + +#[cfg(not(feature = "testing"))] +// Seed is slightly different, to allow for off curve key without bump +pub const SEED_HOOK_AUTHORITY: &[u8] = b"hook_authority_seeds"; + +#[cfg(feature = "testing")] +// Seed is slightly different, to allow for off curve key without bump, with the +// testng program id +pub const SEED_HOOK_AUTHORITY: &[u8] = b"hook_authority_seeds_test"; + +// Hook authority 2MTRji19YQupkpha1Rki8xvoMtEQUfMn9FB1m93DaHj8. Off curve +// without bump +#[cfg(not(feature = "testing"))] +pub const HOOK_AUTHORITY_PUBKEY: Pubkey = Pubkey::new_from_array([ + 20, 25, 47, 2, 155, 124, 59, 36, 196, 168, 29, 160, 133, 182, 125, 32, 178, 251, 180, 88, 79, + 213, 209, 149, 172, 177, 71, 224, 215, 197, 110, 243, +]); + +#[cfg(feature = "testing")] +// Hook authority 3DBe6CrgCNQ3ydaTRX8j3WenQRdQxkhj87Hqe2MAwwHx +pub const HOOK_AUTHORITY_PUBKEY: Pubkey = Pubkey::new_from_array([ + 32, 214, 95, 168, 10, 233, 119, 125, 45, 249, 95, 236, 95, 70, 192, 202, 150, 140, 8, 162, 126, + 245, 141, 215, 164, 36, 97, 134, 2, 197, 62, 175, +]); pub fn get_settings_signer_seeds(settings_seed: u128) -> Vec> { vec![ @@ -20,3 +43,51 @@ pub fn get_settings_signer_seeds(settings_seed: u128) -> Vec> { settings_seed.to_le_bytes().to_vec(), ] } + +pub fn get_policy_signer_seeds(settings_key: &Pubkey, policy_seed: u64) -> Vec> { + vec![ + SEED_PREFIX.to_vec(), + SEED_POLICY.to_vec(), + settings_key.as_ref().to_vec(), + policy_seed.to_le_bytes().to_vec(), + ] +} + +/// Derives the account seeds for a given smart account based on the settings key and account index +pub fn get_smart_account_seeds<'a>( + settings_key: &'a Pubkey, + account_index_bytes: &'a [u8], +) -> [&'a [u8]; 4] { + [ + SEED_PREFIX, + settings_key.as_ref(), + SEED_SMART_ACCOUNT, + account_index_bytes, + ] +} + +#[cfg(test)] +mod tests { + use std::str::FromStr; + + use anchor_lang::AnchorSerialize; + + use super::*; + + #[test] + fn test_hook_authority_pubkey() { + let address = Pubkey::create_program_address(&[SEED_HOOK_AUTHORITY], &crate::ID).unwrap(); + assert_eq!(address, HOOK_AUTHORITY_PUBKEY); + } + + #[test] + fn test_testing_hook_authority_pubkey() { + let test_program_id = + Pubkey::from_str("GyhGAqjokLwF9UXdQ2dR5Zwiup242j4mX4J1tSMKyAmD").unwrap(); + let address = + Pubkey::create_program_address(&[SEED_HOOK_AUTHORITY], &test_program_id) + .unwrap(); + println!("address: {:?}", address.try_to_vec()); + assert_eq!(address, HOOK_AUTHORITY_PUBKEY); + } +} diff --git a/programs/squads_smart_account_program/src/state/settings.rs b/programs/squads_smart_account_program/src/state/settings.rs index 9b4e761..3f11441 100644 --- a/programs/squads_smart_account_program/src/state/settings.rs +++ b/programs/squads_smart_account_program/src/state/settings.rs @@ -1,7 +1,21 @@ use anchor_lang::prelude::*; use anchor_lang::system_program; - -use crate::{errors::*, id, state::*, utils::*, SettingsAction}; +use solana_program::hash::hash; + +use crate::AddSpendingLimitEvent; +use crate::LogAuthorityInfo; +use crate::PolicyEvent; +use crate::PolicyEventType; +use crate::RemoveSpendingLimitEvent; +use crate::SmartAccountEvent; +use crate::{ + errors::*, + id, + interface::consensus_trait::{Consensus, ConsensusAccountType}, + state::*, + utils::*, + SettingsAction, +}; pub const MAX_TIME_LOCK: u32 = 3 * 30 * 24 * 60 * 60; // 3 months #[account] @@ -47,12 +61,33 @@ pub struct Settings { pub signers: Vec, /// Counter for how many sub accounts are in use (improves off-chain indexing) pub account_utilization: u8, + /// Seed used for deterministic policy creation. + pub policy_seed: Option, // Reserved for future use - pub _reserved1: u8, pub _reserved2: u8, } impl Settings { + /// Generates a hash of the core settings: Signers, threshold, and time_lock + pub fn generate_core_state_hash(&self) -> Result<[u8; 32]> { + let mut data_to_hash = Vec::new(); + + // Signers + for signer in &self.signers { + data_to_hash.extend_from_slice(signer.key.as_ref()); + // Add signer permissions (1 byte) + data_to_hash.push(signer.permissions.mask); + } + // Threshold + data_to_hash.extend_from_slice(&self.threshold.to_le_bytes()); + + // Timelock + data_to_hash.extend_from_slice(&self.time_lock.to_le_bytes()); + + let hash_result = hash(&data_to_hash); + + Ok(hash_result.to_bytes()) + } pub fn find_and_initialize_settings_account<'info>( &self, settings_account_key: Pubkey, @@ -114,31 +149,10 @@ impl Settings { 4 + // signers vector length signers_length * SmartAccountSigner::INIT_SPACE + // signers 1 + // sub_account_utilization - 1 + // _reserved_1 + 1 + 8 + // policy_seed 1 // _reserved_2 } - pub fn num_voters(signers: &[SmartAccountSigner]) -> usize { - signers - .iter() - .filter(|m| m.permissions.has(Permission::Vote)) - .count() - } - - pub fn num_proposers(signers: &[SmartAccountSigner]) -> usize { - signers - .iter() - .filter(|m| m.permissions.has(Permission::Initiate)) - .count() - } - - pub fn num_executors(signers: &[SmartAccountSigner]) -> usize { - signers - .iter() - .filter(|m| m.permissions.has(Permission::Execute)) - .count() - } - /// Check if the settings account space needs to be reallocated to accommodate `signers_length`. /// Returns `true` if the account was reallocated. pub fn realloc_if_needed<'a>( @@ -197,15 +211,15 @@ impl Settings { ); // There must be at least one signer with Initiate permission. - let num_proposers = Self::num_proposers(signers); + let num_proposers = Self::num_proposers(&self); require!(num_proposers > 0, SmartAccountError::NoProposers); // There must be at least one signer with Execute permission. - let num_executors = Self::num_executors(signers); + let num_executors = Self::num_executors(&self); require!(num_executors > 0, SmartAccountError::NoExecutors); // There must be at least one signer with Vote permission. - let num_voters = Self::num_voters(signers); + let num_voters = Self::num_voters(&self); require!(num_voters > 0, SmartAccountError::NoVoters); // Threshold must be greater than 0. @@ -232,38 +246,6 @@ impl Settings { Ok(()) } - /// Makes the transactions created up until this moment stale. - /// Should be called whenever any settings parameter related to the voting consensus is changed. - pub fn invalidate_prior_transactions(&mut self) { - self.stale_transaction_index = self.transaction_index; - } - - /// Returns `Some(index)` if `signer_pubkey` is a signer, with `index` into the `signers` vec. - /// `None` otherwise. - pub fn is_signer(&self, signer_pubkey: Pubkey) -> Option { - self.signers - .binary_search_by_key(&signer_pubkey, |m| m.key) - .ok() - } - - pub fn signer_has_permission(&self, signer_pubkey: Pubkey, permission: Permission) -> bool { - match self.is_signer(signer_pubkey) { - Some(index) => self.signers[index].permissions.has(permission), - _ => false, - } - } - - /// How many "reject" votes are enough to make the transaction "Rejected". - /// The cutoff must be such that it is impossible for the remaining voters to reach the approval threshold. - /// For example: total voters = 7, threshold = 3, cutoff = 5. - pub fn cutoff(&self) -> usize { - Self::num_voters(&self.signers) - .checked_sub(usize::from(self.threshold)) - .unwrap() - .checked_add(1) - .unwrap() - } - /// Add `new_signer` to the settings `signers` vec and sort the vec. pub fn add_signer(&mut self, new_signer: SmartAccountSigner) { self.signers.push(new_signer); @@ -294,6 +276,7 @@ impl Settings { system_program: &Option>, remaining_accounts: &'info [AccountInfo<'info>], program_id: &Pubkey, + log_authority_info: Option<&LogAuthorityInfo<'info>>, ) -> Result<()> { match action { SettingsAction::AddSigner { new_signer } => { @@ -385,6 +368,16 @@ impl Settings { spending_limit.invariant()?; spending_limit .try_serialize(&mut &mut spending_limit_info.data.borrow_mut()[..])?; + + // Log the event + let event = AddSpendingLimitEvent { + settings_pubkey: self_key.to_owned(), + spending_limit_pubkey: spending_limit_key, + spending_limit: spending_limit.clone(), + }; + if let Some(log_authority_info) = log_authority_info { + SmartAccountEvent::AddSpendingLimitEvent(event).log(&log_authority_info)?; + } } SettingsAction::RemoveSpendingLimit { @@ -408,14 +401,320 @@ impl Settings { ); spending_limit.close(rent_payer.to_account_info())?; + + // Log the closing event + let event = RemoveSpendingLimitEvent { + settings_pubkey: self_key.to_owned(), + spending_limit_pubkey: *spending_limit_key, + }; + if let Some(log_authority_info) = log_authority_info { + SmartAccountEvent::RemoveSpendingLimitEvent(event).log(&log_authority_info)?; + } } SettingsAction::SetArchivalAuthority { - new_archival_authority, + new_archival_authority: _, } => { // Marked as NotImplemented until archival feature is implemented. return err!(SmartAccountError::NotImplemented); } + + SettingsAction::PolicyCreate { + seed, + policy_creation_payload, + signers, + threshold, + time_lock, + start_timestamp, + expiration_args, + } => { + // Increment the policy seed if it exists, otherwise set it to + // 1 (First policy is being created) + let next_policy_seed = if let Some(policy_seed) = self.policy_seed { + let next_policy_seed = policy_seed.checked_add(1).unwrap(); + + // Increment the policy seed + self.policy_seed = Some(next_policy_seed); + next_policy_seed + } else { + self.policy_seed = Some(1); + 1 + }; + // Policies get created at a deterministic address based on the + // seed in the settings. + let (policy_pubkey, policy_bump) = Pubkey::find_program_address( + &[ + crate::SEED_PREFIX, + SEED_POLICY, + self_key.as_ref(), + &next_policy_seed.to_le_bytes(), + ], + program_id, + ); + + let policy_info = remaining_accounts + .iter() + .find(|acc| acc.key == &policy_pubkey) + .ok_or(SmartAccountError::MissingAccount)?; + + // Calculate policy data size based on the creation payload + let policy_specific_data_size = policy_creation_payload.policy_state_size(); + + let policy_size = Policy::size(signers.len(), policy_specific_data_size); + + let rent_payer = rent_payer + .as_ref() + .ok_or(SmartAccountError::MissingAccount)?; + let system_program = system_program + .as_ref() + .ok_or(SmartAccountError::MissingAccount)?; + + // Create the policy account (following the pattern from create_spending_limit) + create_account( + &rent_payer.to_account_info(), + &policy_info, + &system_program.to_account_info(), + &id(), + rent, + policy_size, + vec![ + crate::SEED_PREFIX.to_vec(), + SEED_POLICY.to_vec(), + self_key.as_ref().to_vec(), + next_policy_seed.to_le_bytes().to_vec(), + vec![policy_bump], + ], + )?; + + // Convert creation payload to policy type + // TODO: Get rid of this clone + let policy_state = match policy_creation_payload.clone() { + PolicyCreationPayload::InternalFundTransfer(creation_payload) => { + PolicyState::InternalFundTransfer(creation_payload.to_policy_state()?) + } + PolicyCreationPayload::ProgramInteraction(creation_payload) => { + PolicyState::ProgramInteraction(creation_payload.to_policy_state()?) + } + PolicyCreationPayload::SpendingLimit(mut creation_payload) => { + // If accumulate unused is true, and the policy has a + // start date in the past, set it to the current + // timestamp to avoid unintended accumulated usage + let current_timestamp = Clock::get()?.unix_timestamp; + if creation_payload.time_constraints.accumulate_unused + && creation_payload.time_constraints.start < current_timestamp + { + creation_payload.time_constraints.start = current_timestamp; + } + PolicyState::SpendingLimit(creation_payload.to_policy_state()?) + } + PolicyCreationPayload::SettingsChange(creation_payload) => { + PolicyState::SettingsChange(creation_payload.to_policy_state()?) + } + }; + + let expiration: Option = + if let Some(expiration_args) = expiration_args { + match expiration_args { + // Use the provided timestamp + PolicyExpirationArgs::Timestamp(timestamp) => { + Some(PolicyExpiration::Timestamp(*timestamp)) + } + // Generate the core state hash and use it + PolicyExpirationArgs::SettingsState => Some( + PolicyExpiration::SettingsState(self.generate_core_state_hash()?), + ), + } + } else { + None + }; + + // Create and serialize the policy + let policy = Policy::create_state( + *self_key, + next_policy_seed, + policy_bump, + &signers, + *threshold, + *time_lock, + policy_state, + // If no start was submitted, use the current timestamp + start_timestamp.unwrap_or(Clock::get()?.unix_timestamp), + expiration.clone(), + rent_payer.key(), + )?; + + // Check the policy invariant + policy.invariant()?; + policy.try_serialize(&mut &mut policy_info.data.borrow_mut()[..])?; + + // Log the event + let event = PolicyEvent { + event_type: PolicyEventType::Create, + settings_pubkey: self_key.to_owned(), + policy_pubkey: policy_pubkey, + policy: Some(policy), + }; + if let Some(log_authority_info) = log_authority_info { + SmartAccountEvent::PolicyEvent(event).log(&log_authority_info)?; + } + } + + SettingsAction::PolicyUpdate { + policy: policy_key, + signers, + threshold, + time_lock, + policy_update_payload, + expiration_args, + } => { + // Find the policy account + let policy_info = remaining_accounts + .iter() + .find(|acc| acc.key == policy_key) + .ok_or(SmartAccountError::MissingAccount)?; + + // Verify the policy account is writable + require!(policy_info.is_writable, ErrorCode::AccountNotMutable); + + // Deserialize the policy account and verify it belongs to this + // settings account + let mut policy = Account::::try_from(policy_info)?; + + require_keys_eq!( + policy.settings, + self_key.to_owned(), + SmartAccountError::InvalidAccount + ); + + // Calculate policy data size based on the creation payload + let policy_specific_data_size = policy_update_payload.policy_state_size(); + let policy_size = Policy::size(signers.len(), policy_specific_data_size); + + // Get the rent payer and system program + let rent_payer = rent_payer + .as_ref() + .ok_or(SmartAccountError::MissingAccount)?; + let system_program = system_program + .as_ref() + .ok_or(SmartAccountError::MissingAccount)?; + + // Only accept updates to the same policy type + let new_policy_state = match (&policy.policy_state, policy_update_payload.clone()) { + ( + PolicyState::InternalFundTransfer(_), + PolicyCreationPayload::InternalFundTransfer(creation_payload), + ) => PolicyState::InternalFundTransfer(creation_payload.to_policy_state()?), + ( + PolicyState::ProgramInteraction(_), + PolicyCreationPayload::ProgramInteraction(creation_payload), + ) => PolicyState::ProgramInteraction(creation_payload.to_policy_state()?), + ( + PolicyState::SpendingLimit(_), + PolicyCreationPayload::SpendingLimit(creation_payload), + ) => PolicyState::SpendingLimit(creation_payload.to_policy_state()?), + ( + PolicyState::SettingsChange(_), + PolicyCreationPayload::SettingsChange(creation_payload), + ) => PolicyState::SettingsChange(creation_payload.to_policy_state()?), + (_, _) => { + return err!(SmartAccountError::InvalidPolicyPayload); + } + }; + + // Determine the new expiration + let expiration: Option = + if let Some(expiration_args) = expiration_args { + match expiration_args { + // Use the provided timestamp + PolicyExpirationArgs::Timestamp(timestamp) => { + Some(PolicyExpiration::Timestamp(*timestamp)) + } + // Generate the core state hash and use it + PolicyExpirationArgs::SettingsState => Some( + PolicyExpiration::SettingsState(self.generate_core_state_hash()?), + ), + } + } else { + None + }; + + // Update the policy + policy.update_state( + signers, + *threshold, + *time_lock, + new_policy_state, + expiration.clone(), + )?; + + // Invalidate prior transaction due to the update + policy.invalidate_prior_transactions(); + + // Check the policy invariant + policy.invariant()?; + + // Realloc the policy account if needed + Policy::realloc_if_needed( + policy_info.clone(), + signers.len(), + policy_size, + Some(rent_payer.to_account_info()), + Some(system_program.to_account_info()), + )?; + + // Exit the policy account + policy.exit(program_id)?; + + // Log the event + let event = PolicyEvent { + event_type: PolicyEventType::Update, + settings_pubkey: self_key.to_owned(), + policy_pubkey: *policy_key, + policy: Some(policy.clone().into_inner()), + }; + if let Some(log_authority_info) = log_authority_info { + SmartAccountEvent::PolicyEvent(event).log(&log_authority_info)?; + } + } + + SettingsAction::PolicyRemove { policy: policy_key } => { + let policy_info = remaining_accounts + .iter() + .find(|acc| acc.key == policy_key) + .ok_or(SmartAccountError::MissingAccount)?; + + let rent_collector = rent_payer + .as_ref() + .ok_or(SmartAccountError::MissingAccount)?; + + let policy = Account::::try_from(policy_info)?; + + // Verify the policy belongs to this settings account + require_keys_eq!( + policy.settings, + self_key.to_owned(), + SmartAccountError::InvalidAccount + ); + // Verify the policy rent collector matche the account getting reimbursed + require_keys_eq!( + policy.rent_collector, + rent_collector.key(), + SmartAccountError::InvalidRentCollector + ); + + policy.close(rent_collector.to_account_info())?; + + // Log the event + let event = PolicyEvent { + event_type: PolicyEventType::Remove, + settings_pubkey: self_key.to_owned(), + policy_pubkey: *policy_key, + policy: None, + }; + if let Some(log_authority_info) = log_authority_info { + SmartAccountEvent::PolicyEvent(event).log(&log_authority_info)?; + } + } } Ok(()) @@ -460,4 +759,62 @@ impl Permissions { pub fn has(&self, permission: Permission) -> bool { self.mask & (permission as u8) != 0 } + + pub fn all() -> Self { + Self { mask: 0b111 } + } +} + +// Implement Consensus for Settings +impl Consensus for Settings { + fn account_type(&self) -> ConsensusAccountType { + ConsensusAccountType::Settings + } + + fn check_derivation(&self, key: Pubkey) -> Result<()> { + let (address, _bump) = Pubkey::find_program_address( + &[SEED_PREFIX, SEED_SETTINGS, self.seed.to_le_bytes().as_ref()], + &crate::ID, + ); + require_keys_eq!(address, key, SmartAccountError::InvalidAccount); + Ok(()) + } + + /// Settings are always active, and don't have an expiration. + fn is_active(&self, _accounts: &[AccountInfo]) -> Result<()> { + Ok(()) + } + + fn signers(&self) -> &[SmartAccountSigner] { + &self.signers + } + + fn threshold(&self) -> u16 { + self.threshold + } + + fn time_lock(&self) -> u32 { + self.time_lock + } + + fn transaction_index(&self) -> u64 { + self.transaction_index + } + + fn set_transaction_index(&mut self, transaction_index: u64) -> Result<()> { + self.transaction_index = transaction_index; + Ok(()) + } + + fn stale_transaction_index(&self) -> u64 { + self.stale_transaction_index + } + + fn invalidate_prior_transactions(&mut self) { + self.stale_transaction_index = self.transaction_index; + } + + fn invariant(&self) -> Result<()> { + self.invariant() + } } diff --git a/programs/squads_smart_account_program/src/state/settings_transaction.rs b/programs/squads_smart_account_program/src/state/settings_transaction.rs index 6529f8a..e10130f 100644 --- a/programs/squads_smart_account_program/src/state/settings_transaction.rs +++ b/programs/squads_smart_account_program/src/state/settings_transaction.rs @@ -2,6 +2,7 @@ use anchor_lang::prelude::*; use anchor_lang::solana_program::borsh0_10::get_instance_packed_len; use super::*; +use crate::state::policies::policy_core::{PolicyCreationPayload}; /// Stores data required for execution of a settings configuration transaction. /// Settings transactions can perform a predefined set of actions on the Settings PDA, such as adding/removing members, @@ -40,7 +41,7 @@ impl SettingsTransaction { } } -#[derive(AnchorSerialize, AnchorDeserialize, Clone, PartialEq, Eq)] +#[derive(AnchorSerialize, AnchorDeserialize, Clone)] #[non_exhaustive] pub enum SettingsAction { /// Add a new member to the settings. @@ -81,4 +82,41 @@ pub enum SettingsAction { RemoveSpendingLimit { spending_limit: Pubkey }, /// Set the `archival_authority` config parameter of the settings. SetArchivalAuthority { new_archival_authority: Option }, + /// Create a new policy account. + PolicyCreate { + /// Key that is used to seed the Policy PDA. + seed: u64, + /// The policy creation payload containing policy-specific configuration. + policy_creation_payload: PolicyCreationPayload, + /// Signers attached to the policy with their permissions. + signers: Vec, + /// Threshold for approvals on the policy. + threshold: u16, + /// How many seconds must pass between approval and execution. + time_lock: u32, + /// Timestamp when the policy becomes active. + start_timestamp: Option, + /// Policy expiration - either time-based or state-based. + expiration_args: Option, + }, + /// Update a policy account. + PolicyUpdate { + /// The policy account to update. + policy: Pubkey, + /// Signers attached to the policy with their permissions. + signers: Vec, + /// Threshold for approvals on the policy. + threshold: u16, + /// How many seconds must pass between approval and execution. + time_lock: u32, + /// The policy update payload containing policy-specific configuration. + policy_update_payload: PolicyCreationPayload, + /// Policy expiration - either time-based or state-based. + expiration_args: Option, + }, + /// Remove a policy account. + PolicyRemove { + /// The policy account to remove. + policy: Pubkey + }, } diff --git a/programs/squads_smart_account_program/src/state/spending_limit.rs b/programs/squads_smart_account_program/src/state/spending_limit.rs index 1eb5bf2..6e41472 100644 --- a/programs/squads_smart_account_program/src/state/spending_limit.rs +++ b/programs/squads_smart_account_program/src/state/spending_limit.rs @@ -64,7 +64,7 @@ impl SpendingLimit { signers_length * 32 + // signers 4 + // destinations vector length destinations_length * 32 + // destinations - 8 // expiration + 8 // expiration } pub fn invariant(&self) -> Result<()> { diff --git a/programs/squads_smart_account_program/src/state/transaction.rs b/programs/squads_smart_account_program/src/state/transaction.rs index 0976470..3e473f9 100644 --- a/programs/squads_smart_account_program/src/state/transaction.rs +++ b/programs/squads_smart_account_program/src/state/transaction.rs @@ -2,243 +2,112 @@ use anchor_lang::prelude::*; use anchor_lang::solana_program::borsh0_10::get_instance_packed_len; use crate::errors::*; -use crate::instructions::{CompiledInstruction, MessageAddressTableLookup, TransactionMessage}; +use crate::instructions::TransactionMessage; + +use super::{PolicyPayload, SmartAccountTransactionMessage}; /// Stores data required for tracking the voting and execution status of a smart -///account transaction. +/// account transaction or policy action /// Smart Account transaction is a transaction that's executed on behalf of the /// smart account PDA /// and wraps arbitrary Solana instructions, typically calling into other Solana programs. #[account] -#[derive(Default)] pub struct Transaction { - /// The settings this belongs to. - pub settings: Pubkey, + /// The consensus account this belongs to. + pub consensus_account: Pubkey, /// Signer of the Smart Account who submitted the transaction. pub creator: Pubkey, /// The rent collector for the transaction account. pub rent_collector: Pubkey, - /// Index of this transaction within the smart account. + /// Index of this transaction within the consensus account. pub index: u64, - /// bump for the transaction seeds. - pub bump: u8, + /// The payload of the transaction. + pub payload: Payload, +} + +#[derive(AnchorSerialize, AnchorDeserialize, Clone)] +pub enum Payload { + TransactionPayload(TransactionPayloadDetails), + PolicyPayload(PolicyActionPayloadDetails), +} + +impl Payload { + pub fn transaction_payload(&self) -> Result<&TransactionPayloadDetails> { + match self { + Payload::TransactionPayload(payload) => Ok(payload), + _ => err!(SmartAccountError::InvalidPayload), + } + } + + pub fn policy_payload(&self) -> Result<&PolicyActionPayloadDetails> { + match self { + Payload::PolicyPayload(payload) => Ok(payload), + _ => err!(SmartAccountError::InvalidPayload), + } + } +} + +#[derive(AnchorSerialize, AnchorDeserialize, Clone, Eq, PartialEq)] +pub struct TransactionPayloadDetails { /// The account index of the smart account this transaction belongs to. pub account_index: u8, - /// Derivation bump of the smart account PDA this transaction belongs to. - pub account_bump: u8, - /// Derivation bumps for additional signers. - /// Some transactions require multiple signers. Often these additional signers are "ephemeral" keypairs - /// that are generated on the client with a sole purpose of signing the transaction and be discarded immediately after. - /// When wrapping such transactions into smart account ones, we replace these "ephemeral" signing keypairs - /// with PDAs derived from the SmartAccountTransaction's `transaction_index` - /// and controlled by the Smart Account Program; - /// during execution the program includes the seeds of these PDAs into the `invoke_signed` calls, - /// thus "signing" on behalf of these PDAs. + /// The ephemeral signer bumps for the transaction. pub ephemeral_signer_bumps: Vec, - /// data required for executing the transaction. + /// The message of the transaction. pub message: SmartAccountTransactionMessage, } +#[derive(AnchorSerialize, AnchorDeserialize, Clone)] +pub struct PolicyActionPayloadDetails { + pub payload: PolicyPayload, +} + impl Transaction { - pub fn size(ephemeral_signers_length: u8, transaction_message: &[u8]) -> Result { + pub fn size_for_transaction(ephemeral_signers_length: u8, transaction_message: &[u8]) -> Result { let transaction_message: SmartAccountTransactionMessage = TransactionMessage::deserialize(&mut &transaction_message[..])?.try_into()?; - let message_size = get_instance_packed_len(&transaction_message).unwrap_or_default(); + + let payload = Payload::TransactionPayload(TransactionPayloadDetails { + account_index: 0, + ephemeral_signer_bumps: vec![0; usize::from(ephemeral_signers_length)], + message: transaction_message, + }); + + let payload_size = get_instance_packed_len(&payload).unwrap_or_default(); Ok( 8 + // anchor account discriminator - 32 + // settings + 32 + // consensus_account 32 + // creator 32 + // rent_collector 8 + // index - 1 + // bump - 1 + // account_index - 1 + // account_bump - (4 + usize::from(ephemeral_signers_length)) + // ephemeral_signers_bumps vec - message_size, // message + 1 + // account_index + 1 + // account_bump + payload_size, // payload ) } - /// Reduces the Transaction to its default empty value and moves - /// ownership of the data to the caller/return value. - pub fn take(&mut self) -> Transaction { - core::mem::take(self) - } -} - -#[derive(AnchorSerialize, AnchorDeserialize, Clone, Default)] -pub struct SmartAccountTransactionMessage { - /// The number of signer pubkeys in the account_keys vec. - pub num_signers: u8, - /// The number of writable signer pubkeys in the account_keys vec. - pub num_writable_signers: u8, - /// The number of writable non-signer pubkeys in the account_keys vec. - pub num_writable_non_signers: u8, - /// Unique account pubkeys (including program IDs) required for execution of the tx. - /// The signer pubkeys appear at the beginning of the vec, with writable pubkeys first, and read-only pubkeys following. - /// The non-signer pubkeys follow with writable pubkeys first and read-only ones following. - /// Program IDs are also stored at the end of the vec along with other non-signer non-writable pubkeys: - /// - /// ```plaintext - /// [pubkey1, pubkey2, pubkey3, pubkey4, pubkey5, pubkey6, pubkey7, pubkey8] - /// |---writable---| |---readonly---| |---writable---| |---readonly---| - /// |------------signers-------------| |----------non-singers-----------| - /// ``` - pub account_keys: Vec, - /// List of instructions making up the tx. - pub instructions: Vec, - /// List of address table lookups used to load additional accounts - /// for this transaction. - pub address_table_lookups: Vec, -} - -impl SmartAccountTransactionMessage { - /// Returns the number of all the account keys (static + dynamic) in the message. - pub fn num_all_account_keys(&self) -> usize { - let num_account_keys_from_lookups = self - .address_table_lookups - .iter() - .map(|lookup| lookup.writable_indexes.len() + lookup.readonly_indexes.len()) - .sum::(); - - self.account_keys.len() + num_account_keys_from_lookups - } - /// Returns true if the account at the specified index is a part of static `account_keys` and was requested to be writable. - pub fn is_static_writable_index(&self, key_index: usize) -> bool { - let num_account_keys = self.account_keys.len(); - let num_signers = usize::from(self.num_signers); - let num_writable_signers = usize::from(self.num_writable_signers); - let num_writable_non_signers = usize::from(self.num_writable_non_signers); + pub fn size_for_policy(payload: &PolicyPayload) -> Result { + let payload_enum = Payload::PolicyPayload(PolicyActionPayloadDetails { + payload: payload.clone(), + }); - if key_index >= num_account_keys { - // `index` is not a part of static `account_keys`. - return false; - } - - if key_index < num_writable_signers { - // `index` is within the range of writable signer keys. - return true; - } + let payload_size = get_instance_packed_len(&payload_enum).unwrap_or_default(); - if key_index >= num_signers { - // `index` is within the range of non-signer keys. - let index_into_non_signers = key_index.saturating_sub(num_signers); - // Whether `index` is within the range of writable non-signer keys. - return index_into_non_signers < num_writable_non_signers; - } - - false - } - - /// Returns true if the account at the specified index was requested to be a signer. - pub fn is_signer_index(&self, key_index: usize) -> bool { - key_index < usize::from(self.num_signers) - } -} - -impl TryFrom for SmartAccountTransactionMessage { - type Error = Error; - - fn try_from(message: TransactionMessage) -> Result { - let account_keys: Vec = message.account_keys.into(); - let instructions: Vec = message.instructions.into(); - let instructions: Vec = instructions - .into_iter() - .map(SmartAccountCompiledInstruction::from) - .collect(); - let address_table_lookups: Vec = - message.address_table_lookups.into(); - - let num_all_account_keys = account_keys.len() - + address_table_lookups - .iter() - .map(|lookup| lookup.writable_indexes.len() + lookup.readonly_indexes.len()) - .sum::(); - - require!( - usize::from(message.num_signers) <= account_keys.len(), - SmartAccountError::InvalidTransactionMessage - ); - require!( - message.num_writable_signers <= message.num_signers, - SmartAccountError::InvalidTransactionMessage - ); - require!( - usize::from(message.num_writable_non_signers) - <= account_keys - .len() - .saturating_sub(usize::from(message.num_signers)), - SmartAccountError::InvalidTransactionMessage - ); - - // Validate that all program ID indices and account indices are within the bounds of the account keys. - for instruction in &instructions { - require!( - usize::from(instruction.program_id_index) < num_all_account_keys, - SmartAccountError::InvalidTransactionMessage - ); - - for account_index in &instruction.account_indexes { - require!( - usize::from(*account_index) < num_all_account_keys, - SmartAccountError::InvalidTransactionMessage - ); - } - } - - Ok(Self { - num_signers: message.num_signers, - num_writable_signers: message.num_writable_signers, - num_writable_non_signers: message.num_writable_non_signers, - account_keys, - instructions, - address_table_lookups: address_table_lookups - .into_iter() - .map(SmartAccountMessageAddressTableLookup::from) - .collect(), - }) - } -} - -/// Concise serialization schema for instructions that make up a transaction. -/// Closely mimics the Solana transaction wire format. -#[derive(AnchorSerialize, AnchorDeserialize, Clone)] -pub struct SmartAccountCompiledInstruction { - pub program_id_index: u8, - /// Indices into the tx's `account_keys` list indicating which accounts to pass to the instruction. - pub account_indexes: Vec, - /// Instruction data. - pub data: Vec, -} - -impl From for SmartAccountCompiledInstruction { - fn from(compiled_instruction: CompiledInstruction) -> Self { - Self { - program_id_index: compiled_instruction.program_id_index, - account_indexes: compiled_instruction.account_indexes.into(), - data: compiled_instruction.data.into(), - } + Ok( + 8 + // anchor account discriminator + 32 + // consensus_account + 32 + // creator + 32 + // rent_collector + 8 + // index + 1 + // account_index + 1 + // account_bump + payload_size, // payload + ) } -} -/// Address table lookups describe an on-chain address lookup table to use -/// for loading more readonly and writable accounts into a transaction. -#[derive(AnchorSerialize, AnchorDeserialize, Clone)] -pub struct SmartAccountMessageAddressTableLookup { - /// Address lookup table account key. - pub account_key: Pubkey, - /// List of indexes used to load writable accounts. - pub writable_indexes: Vec, - /// List of indexes used to load readonly accounts. - pub readonly_indexes: Vec, -} - -impl From for SmartAccountMessageAddressTableLookup { - fn from(m: MessageAddressTableLookup) -> Self { - Self { - account_key: m.account_key, - writable_indexes: m.writable_indexes.into(), - readonly_indexes: m.readonly_indexes.into(), - } + pub fn size(ephemeral_signers_length: u8, transaction_message: &[u8]) -> Result { + // Backward compatibility - assume transaction payload + Self::size_for_transaction(ephemeral_signers_length, transaction_message) } } diff --git a/programs/squads_smart_account_program/src/state/transaction_buffer.rs b/programs/squads_smart_account_program/src/state/transaction_buffer.rs index 9571d9c..434d4bf 100644 --- a/programs/squads_smart_account_program/src/state/transaction_buffer.rs +++ b/programs/squads_smart_account_program/src/state/transaction_buffer.rs @@ -8,7 +8,7 @@ pub const MAX_BUFFER_SIZE: usize = 4000; #[account] #[derive(Default, Debug)] pub struct TransactionBuffer { - /// The settings this belongs to. + /// The consensus account (settings or policy) this belongs to. pub settings: Pubkey, /// Signer of the smart account who created the TransactionBuffer. pub creator: Pubkey, diff --git a/programs/squads_smart_account_program/src/utils/context_validation.rs b/programs/squads_smart_account_program/src/utils/context_validation.rs index 6af17a2..3b241e4 100644 --- a/programs/squads_smart_account_program/src/utils/context_validation.rs +++ b/programs/squads_smart_account_program/src/utils/context_validation.rs @@ -1,16 +1,20 @@ -use crate::{errors::*, state::*}; +use crate::{consensus::ConsensusAccount, consensus_trait::Consensus, errors::*, state::*}; use anchor_lang::prelude::*; pub fn validate_synchronous_consensus( - settings: &Account, + consensus_account: &ConsensusAccount, num_signers: u8, remaining_accounts: &[AccountInfo], ) -> Result<()> { // Settings must not be time locked - require_eq!(settings.time_lock, 0, SmartAccountError::TimeLockNotZero); + require_eq!( + consensus_account.time_lock(), + 0, + SmartAccountError::TimeLockNotZero + ); // Get signers from remaining accounts using threshold - let required_signer_count = settings.threshold as usize; + let required_signer_count = consensus_account.threshold() as usize; let signer_count = num_signers as usize; require!( signer_count >= required_signer_count, @@ -28,7 +32,7 @@ pub fn validate_synchronous_consensus( // Check permissions for all signers for signer in signers.iter() { - if let Some(member_index) = settings.is_signer(signer.key()) { + if let Some(member_index) = consensus_account.is_signer(signer.key()) { // Check that the signer is indeed a signer if !signer.is_signer { return err!(SmartAccountError::MissingSignature); @@ -39,7 +43,7 @@ pub fn validate_synchronous_consensus( } seen_signers.push(signer.key()); - let signer_permissions = settings.signers[member_index].permissions; + let signer_permissions = consensus_account.signers()[member_index].permissions; // Add to the aggregated permissions mask aggregated_permissions.mask |= signer_permissions.mask; @@ -54,13 +58,13 @@ pub fn validate_synchronous_consensus( // Check if we have all required permissions (Initiate | Vote | Execute = 7) require!( - aggregated_permissions.mask == 7, + aggregated_permissions.mask == Permissions::all().mask, SmartAccountError::InsufficientAggregatePermissions ); // Verify threshold is met across all voting permissions require!( - vote_permission_count >= settings.threshold as usize, + vote_permission_count >= consensus_account.threshold() as usize, SmartAccountError::InsufficientVotePermissions ); diff --git a/programs/squads_smart_account_program/src/utils/executable_transaction_message.rs b/programs/squads_smart_account_program/src/utils/executable_transaction_message.rs index d018a84..8219f3a 100644 --- a/programs/squads_smart_account_program/src/utils/executable_transaction_message.rs +++ b/programs/squads_smart_account_program/src/utils/executable_transaction_message.rs @@ -9,6 +9,7 @@ use anchor_lang::solana_program::program::invoke_signed; use crate::errors::*; use crate::state::*; +use crate::LogEvent; /// Sanitized and validated combination of a `MsTransactionMessage` and `AccountInfo`s it references. pub struct ExecutableTransactionMessage<'a, 'info> { @@ -208,6 +209,7 @@ impl<'a, 'info> ExecutableTransactionMessage<'a, 'info> { SmartAccountError::ProtectedAccount ); } + LogEvent::check_instruction(ix)?; invoke_signed(&ix, &account_infos, &signer_seeds)?; } Ok(()) @@ -255,7 +257,7 @@ impl<'a, 'info> ExecutableTransactionMessage<'a, 'info> { pub fn to_instructions_and_accounts(mut self) -> Vec<(Instruction, Vec>)> { let mut executable_instructions = vec![]; - for sa_compiled_instruction in core::mem::take(&mut self.message.instructions) { + for sa_compiled_instruction in std::mem::take(&mut self.message.instructions) { let ix_accounts: Vec<(AccountInfo<'info>, AccountMeta)> = sa_compiled_instruction .account_indexes .iter() @@ -292,8 +294,11 @@ impl<'a, 'info> ExecutableTransactionMessage<'a, 'info> { let mut account_infos: Vec = ix_accounts .into_iter() - .map(|(account_info, _)| account_info) + .map(|(account_info, _)| (*account_info.key, account_info)) + .collect::>() + .into_values() .collect(); + // Add Program ID account_infos.push(ix_program_account_info.clone()); diff --git a/programs/squads_smart_account_program/src/utils/synchronous_transaction_message.rs b/programs/squads_smart_account_program/src/utils/synchronous_transaction_message.rs index 737e9a2..ffb2de5 100644 --- a/programs/squads_smart_account_program/src/utils/synchronous_transaction_message.rs +++ b/programs/squads_smart_account_program/src/utils/synchronous_transaction_message.rs @@ -4,23 +4,26 @@ use anchor_lang::solana_program::program::invoke_signed; use crate::errors::*; use crate::state::*; +use crate::LogEvent; /// Sanitized and validated combination of transaction instructions and accounts -pub struct SynchronousTransactionMessage<'info> { - pub instructions: Vec, +pub struct SynchronousTransactionMessage<'a, 'info> { + pub instructions: &'a [SmartAccountCompiledInstruction], pub accounts: Vec>, } -impl<'info> SynchronousTransactionMessage<'info> { +impl<'a, 'info> SynchronousTransactionMessage<'a, 'info> { pub fn new_validated( settings_key: &Pubkey, - settings: &Settings, smart_account_pubkey: &Pubkey, - instructions: Vec, + consensus_account_signers: &[SmartAccountSigner], + instructions: &'a [SmartAccountCompiledInstruction], remaining_accounts: &[AccountInfo<'info>], ) -> Result { + // Validate instruction indices first - for instruction in &instructions { + for instruction in instructions { + require!( (instruction.program_id_index as usize) < remaining_accounts.len(), SmartAccountError::InvalidTransactionMessage @@ -36,7 +39,7 @@ impl<'info> SynchronousTransactionMessage<'info> { let mut accounts = Vec::with_capacity(remaining_accounts.len()); // Process accounts and modify signer states - for (i, account) in remaining_accounts.iter().enumerate() { + for (_, account) in remaining_accounts.iter().enumerate() { let mut account_info = account.clone(); // For remaining accounts: @@ -48,7 +51,7 @@ impl<'info> SynchronousTransactionMessage<'info> { } else if account.key == settings_key { // This prevents dangerous re-entrancy account_info.is_writable = false; - } else if settings.is_signer(account.key.to_owned()).is_some() && account.is_signer { + } else if consensus_account_signers.iter().any(|signer| &signer.key == account.key) && account.is_signer { // We may want to remove this so that a signer can be a rent // or feepayer on any of the CPI instructions account_info.is_signer = false; @@ -65,7 +68,7 @@ impl<'info> SynchronousTransactionMessage<'info> { /// Executes all instructions in the message via CPI calls pub fn execute(&self, smart_account_seeds: &[&[u8]]) -> Result<()> { - for instruction in &self.instructions { + for instruction in self.instructions { let program_id = self.accounts[instruction.program_id_index as usize].key; // Build account metas for this instruction @@ -89,6 +92,9 @@ impl<'info> SynchronousTransactionMessage<'info> { data: instruction.data.clone(), }; + // Check that we're not calling our self logging instruction + LogEvent::check_instruction(&ix)?; + let accounts_slice: Vec = instruction .account_indexes .iter() diff --git a/sdk/smart-account/.solitarc.js b/sdk/smart-account/.solitarc.js index e98e2dd..2057415 100644 --- a/sdk/smart-account/.solitarc.js +++ b/sdk/smart-account/.solitarc.js @@ -23,7 +23,15 @@ const ignoredTypes = new Set([ "AddSpendingLimitEvent", "RemoveSpendingLimitEvent", "UseSpendingLimitEvent", + "TransactionEvent", + "ProposalEvent", + "SettingsChangePolicyEvent", "SmartAccountEvent", + "ConsensusAccount", + "SynchronousTransactionEventV2", + "AuthoritySettingsEvent", + "AuthorityChangeEvent", + "TransactionContent" ]); module.exports = { @@ -35,9 +43,32 @@ module.exports = { binaryInstallDir, programDir, idlHook: (idl) => { + // Transform the IDL to replace SmallVec types + const transformType = (obj) => { + if (typeof obj === "string" && obj === "SmallVec") { + return "bytes"; // Replace with bytes type + } + if (typeof obj === "object" && obj !== null) { + if (obj.defined === "SmallVec") { + return "bytes"; // Replace just the type reference + } + if (Array.isArray(obj)) { + return obj.map(transformType); + } + const transformed = {}; + for (const [key, value] of Object.entries(obj)) { + transformed[key] = transformType(value); + } + return transformed; + } + return obj; + }; + + const transformedIdl = transformType(idl); + return { - ...idl, - types: idl.types.filter((type) => { + ...transformedIdl, + types: transformedIdl.types.filter((type) => { return !ignoredTypes.has(type.name); }), }; diff --git a/sdk/smart-account/.yarnrc.yml b/sdk/smart-account/.yarnrc.yml new file mode 100644 index 0000000..3186f3f --- /dev/null +++ b/sdk/smart-account/.yarnrc.yml @@ -0,0 +1 @@ +nodeLinker: node-modules diff --git a/sdk/smart-account/idl/squads_smart_account_program.json b/sdk/smart-account/idl/squads_smart_account_program.json index 8c36e24..3382873 100644 --- a/sdk/smart-account/idl/squads_smart_account_program.json +++ b/sdk/smart-account/idl/squads_smart_account_program.json @@ -65,7 +65,7 @@ { "name": "setProgramConfigSmartAccountCreationFee", "docs": [ - "Set the `multisig_creation_fee` parameter of the program config." + "Set the `smart_account_creation_fee` parameter of the program config." ], "accounts": [ { @@ -167,7 +167,7 @@ { "name": "addSignerAsAuthority", "docs": [ - "Add a new signer to the controlled multisig." + "Add a new signer to the controlled smart account." ], "accounts": [ { @@ -221,7 +221,7 @@ { "name": "removeSignerAsAuthority", "docs": [ - "Remove a signer from the controlled multisig." + "Remove a signer from the controlled smart account." ], "accounts": [ { @@ -275,7 +275,7 @@ { "name": "setTimeLockAsAuthority", "docs": [ - "Set the `time_lock` config parameter for the controlled multisig." + "Set the `time_lock` config parameter for the controlled smart account." ], "accounts": [ { @@ -329,7 +329,7 @@ { "name": "changeThresholdAsAuthority", "docs": [ - "Set the `threshold` config parameter for the controlled multisig." + "Set the `threshold` config parameter for the controlled smart account." ], "accounts": [ { @@ -383,7 +383,7 @@ { "name": "setNewSettingsAuthorityAsAuthority", "docs": [ - "Set the multisig `config_authority`." + "Set the smart account `settings_authority`." ], "accounts": [ { @@ -437,7 +437,7 @@ { "name": "setArchivalAuthorityAsAuthority", "docs": [ - "Set the multisig `archival_authority`." + "Set the smart account `archival_authority`." ], "accounts": [ { @@ -491,7 +491,7 @@ { "name": "addSpendingLimitAsAuthority", "docs": [ - "Create a new spending limit for the controlled multisig." + "Create a new spending limit for the controlled smart account." ], "accounts": [ { @@ -543,7 +543,7 @@ { "name": "removeSpendingLimitAsAuthority", "docs": [ - "Remove the spending limit from the controlled multisig." + "Remove the spending limit from the controlled smart account." ], "accounts": [ { @@ -623,6 +623,11 @@ "name": "systemProgram", "isMut": false, "isSigner": false + }, + { + "name": "program", + "isMut": false, + "isSigner": false } ], "args": [ @@ -692,6 +697,11 @@ "docs": [ "We might need it in case reallocation is needed." ] + }, + { + "name": "program", + "isMut": false, + "isSigner": false } ], "args": [] @@ -703,7 +713,7 @@ ], "accounts": [ { - "name": "settings", + "name": "consensusAccount", "isMut": true, "isSigner": false }, @@ -732,6 +742,11 @@ "name": "systemProgram", "isMut": false, "isSigner": false + }, + { + "name": "program", + "isMut": false, + "isSigner": false } ], "args": [ @@ -750,7 +765,7 @@ ], "accounts": [ { - "name": "settings", + "name": "consensusAccount", "isMut": false, "isSigner": false }, @@ -797,7 +812,7 @@ ], "accounts": [ { - "name": "settings", + "name": "consensusAccount", "isMut": false, "isSigner": false }, @@ -824,7 +839,7 @@ ], "accounts": [ { - "name": "settings", + "name": "consensusAccount", "isMut": false, "isSigner": false }, @@ -862,7 +877,7 @@ "name": "transactionCreate", "accounts": [ { - "name": "settings", + "name": "consensusAccount", "isMut": true, "isSigner": false }, @@ -891,6 +906,11 @@ "name": "systemProgram", "isMut": false, "isSigner": false + }, + { + "name": "program", + "isMut": false, + "isSigner": false } ] }, @@ -922,8 +942,8 @@ ], "accounts": [ { - "name": "settings", - "isMut": false, + "name": "consensusAccount", + "isMut": true, "isSigner": false }, { @@ -946,6 +966,11 @@ "name": "signer", "isMut": false, "isSigner": true + }, + { + "name": "program", + "isMut": false, + "isSigner": false } ], "args": [] @@ -1113,11 +1138,11 @@ { "name": "createProposal", "docs": [ - "Create a new multisig proposal." + "Create a new smart account proposal." ], "accounts": [ { - "name": "settings", + "name": "consensusAccount", "isMut": false, "isSigner": false }, @@ -1146,6 +1171,11 @@ "name": "systemProgram", "isMut": false, "isSigner": false + }, + { + "name": "program", + "isMut": false, + "isSigner": false } ], "args": [ @@ -1160,7 +1190,7 @@ { "name": "activateProposal", "docs": [ - "Update status of a multisig proposal from `Draft` to `Active`." + "Update status of a smart account proposal from `Draft` to `Active`." ], "accounts": [ { @@ -1184,12 +1214,12 @@ { "name": "approveProposal", "docs": [ - "Approve a multisig proposal on behalf of the `member`.", + "Approve a smart account proposal on behalf of the `member`.", "The proposal must be `Active`." ], "accounts": [ { - "name": "settings", + "name": "consensusAccount", "isMut": false, "isSigner": false }, @@ -1208,6 +1238,11 @@ "isMut": false, "isSigner": false, "isOptional": true + }, + { + "name": "program", + "isMut": false, + "isSigner": false } ], "args": [ @@ -1222,12 +1257,12 @@ { "name": "rejectProposal", "docs": [ - "Reject a multisig proposal on behalf of the `member`.", + "Reject a smart account proposal on behalf of the `member`.", "The proposal must be `Active`." ], "accounts": [ { - "name": "settings", + "name": "consensusAccount", "isMut": false, "isSigner": false }, @@ -1246,6 +1281,11 @@ "isMut": false, "isSigner": false, "isOptional": true + }, + { + "name": "program", + "isMut": false, + "isSigner": false } ], "args": [ @@ -1260,12 +1300,12 @@ { "name": "cancelProposal", "docs": [ - "Cancel a multisig proposal on behalf of the `member`.", + "Cancel a smart account proposal on behalf of the `member`.", "The proposal must be `Approved`." ], "accounts": [ { - "name": "settings", + "name": "consensusAccount", "isMut": false, "isSigner": false }, @@ -1284,6 +1324,11 @@ "isMut": false, "isSigner": false, "isOptional": true + }, + { + "name": "program", + "isMut": false, + "isSigner": false } ], "args": [ @@ -1298,7 +1343,7 @@ { "name": "useSpendingLimit", "docs": [ - "Use a spending limit to transfer tokens from a multisig vault to a destination account." + "Use a spending limit to transfer tokens from a smart account vault to a destination account." ], "accounts": [ { @@ -1448,6 +1493,11 @@ "name": "systemProgram", "isMut": false, "isSigner": false + }, + { + "name": "program", + "isMut": false, + "isSigner": false } ], "args": [] @@ -1462,7 +1512,7 @@ ], "accounts": [ { - "name": "settings", + "name": "consensusAccount", "isMut": false, "isSigner": false }, @@ -1502,6 +1552,77 @@ "name": "systemProgram", "isMut": false, "isSigner": false + }, + { + "name": "program", + "isMut": false, + "isSigner": false + } + ], + "args": [] + }, + { + "name": "closeEmptyPolicyTransaction", + "docs": [ + "Closes a `Transaction` and the corresponding `Proposal` for", + "empty/deleted policies." + ], + "accounts": [ + { + "name": "programConfig", + "isMut": true, + "isSigner": false, + "docs": [ + "Global program config account. (Just using this for logging purposes,", + "since we no longer have the consensus account)" + ] + }, + { + "name": "emptyPolicy", + "isMut": false, + "isSigner": false + }, + { + "name": "proposal", + "isMut": true, + "isSigner": false, + "docs": [ + "the logic within `close_empty_policy_transaction` does the rest of the checks." + ] + }, + { + "name": "transaction", + "isMut": true, + "isSigner": false, + "docs": [ + "Transaction corresponding to the `proposal`." + ] + }, + { + "name": "proposalRentCollector", + "isMut": true, + "isSigner": false, + "docs": [ + "The rent collector for the proposal account." + ] + }, + { + "name": "transactionRentCollector", + "isMut": true, + "isSigner": false, + "docs": [ + "The rent collector." + ] + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "program", + "isMut": false, + "isSigner": false } ], "args": [] @@ -1610,6 +1731,11 @@ "name": "systemProgram", "isMut": false, "isSigner": false + }, + { + "name": "program", + "isMut": false, + "isSigner": false } ], "args": [] @@ -1621,9 +1747,35 @@ ], "accounts": [ { - "name": "settings", + "name": "consensusAccount", + "isMut": false, + "isSigner": false + }, + { + "name": "program", "isMut": false, "isSigner": false + } + ], + "args": [ + { + "name": "args", + "type": { + "defined": "LegacySyncTransactionArgs" + } + } + ] + }, + { + "name": "executeTransactionSyncV2", + "docs": [ + "Synchronously execute a policy transaction" + ], + "accounts": [ + { + "name": "consensusAccount", + "isMut": true, + "isSigner": false }, { "name": "program", @@ -1647,7 +1799,7 @@ ], "accounts": [ { - "name": "settings", + "name": "consensusAccount", "isMut": true, "isSigner": false }, @@ -1702,7 +1854,7 @@ { "name": "args", "type": { - "defined": "LogEventArgs" + "defined": "LogEventArgsV2" } } ] @@ -1723,7 +1875,7 @@ { "name": "settings", "docs": [ - "The settings this belongs to." + "The consensus account (settings or policy) this belongs to." ], "type": "publicKey" }, @@ -1835,111 +1987,300 @@ } }, { - "name": "ProgramConfig", + "name": "LegacyTransaction", "docs": [ - "Global program configuration account." + "Stores data required for tracking the voting and execution status of a smart", + "account transaction.", + "Smart Account transaction is a transaction that's executed on behalf of the", + "smart account PDA", + "and wraps arbitrary Solana instructions, typically calling into other Solana programs." ], "type": { "kind": "struct", "fields": [ { - "name": "smartAccountIndex", + "name": "smartAccountSettings", "docs": [ - "Counter for the number of smart accounts created." + "The consensus account this belongs to." ], - "type": "u128" + "type": "publicKey" }, { - "name": "authority", + "name": "creator", "docs": [ - "The authority which can update the config." + "Signer of the Smart Account who submitted the transaction." ], "type": "publicKey" }, { - "name": "smartAccountCreationFee", + "name": "rentCollector", "docs": [ - "The lamports amount charged for creating a new smart account.", - "This fee is sent to the `treasury` account." + "The rent collector for the transaction account." + ], + "type": "publicKey" + }, + { + "name": "index", + "docs": [ + "Index of this transaction within the smart account." ], "type": "u64" }, { - "name": "treasury", + "name": "bump", "docs": [ - "The treasury account to send charged fees to." + "bump for the transaction seeds." ], - "type": "publicKey" + "type": "u8" }, { - "name": "reserved", + "name": "accountIndex", "docs": [ - "Reserved for future use." + "The account index of the smart account this transaction belongs to." + ], + "type": "u8" + }, + { + "name": "accountBump", + "docs": [ + "Derivation bump of the smart account PDA this transaction belongs to." + ], + "type": "u8" + }, + { + "name": "ephemeralSignerBumps", + "docs": [ + "Derivation bumps for additional signers.", + "Some transactions require multiple signers. Often these additional signers are \"ephemeral\" keypairs", + "that are generated on the client with a sole purpose of signing the transaction and be discarded immediately after.", + "When wrapping such transactions into smart account ones, we replace these \"ephemeral\" signing keypairs", + "with PDAs derived from the SmartAccountTransaction's `transaction_index`", + "and controlled by the Smart Account Program;", + "during execution the program includes the seeds of these PDAs into the `invoke_signed` calls,", + "thus \"signing\" on behalf of these PDAs." + ], + "type": "bytes" + }, + { + "name": "message", + "docs": [ + "data required for executing the transaction." ], "type": { - "array": [ - "u8", - 64 - ] + "defined": "SmartAccountTransactionMessage" } } ] } }, { - "name": "Proposal", - "docs": [ - "Stores the data required for tracking the status of a smart account proposal.", - "Each `Proposal` has a 1:1 association with a transaction account, e.g. a `Transaction` or a `SettingsTransaction`;", - "the latter can be executed only after the `Proposal` has been approved and its time lock is released." - ], + "name": "Policy", "type": { "kind": "struct", "fields": [ { "name": "settings", "docs": [ - "The settings this belongs to." + "The smart account this policy belongs to." ], "type": "publicKey" }, { - "name": "transactionIndex", + "name": "seed", "docs": [ - "Index of the smart account transaction this proposal is associated with." + "The seed of the policy." ], "type": "u64" }, { - "name": "rentCollector", + "name": "bump", "docs": [ - "The rent collector for the proposal account." + "Bump for the policy." ], - "type": "publicKey" + "type": "u8" }, { - "name": "status", + "name": "transactionIndex", "docs": [ - "The status of the transaction." + "Transaction index for stale transaction protection." ], - "type": { - "defined": "ProposalStatus" - } + "type": "u64" }, { - "name": "bump", + "name": "staleTransactionIndex", "docs": [ - "PDA bump." + "Stale transaction index boundary." ], - "type": "u8" + "type": "u64" }, { - "name": "approved", + "name": "signers", "docs": [ - "Keys that have approved/signed." + "Signers attached to the policy with their permissions." ], "type": { - "vec": "publicKey" + "vec": { + "defined": "SmartAccountSigner" + } + } + }, + { + "name": "threshold", + "docs": [ + "Threshold for approvals." + ], + "type": "u16" + }, + { + "name": "timeLock", + "docs": [ + "How many seconds must pass between approval and execution." + ], + "type": "u32" + }, + { + "name": "policyState", + "docs": [ + "The state of the policy." + ], + "type": { + "defined": "PolicyState" + } + }, + { + "name": "start", + "docs": [ + "Timestamp when the policy becomes active." + ], + "type": "i64" + }, + { + "name": "expiration", + "docs": [ + "Policy expiration - either time-based or state-based." + ], + "type": { + "option": { + "defined": "PolicyExpiration" + } + } + }, + { + "name": "rentCollector", + "docs": [ + "Rent Collector for the policy for when it gets closed" + ], + "type": "publicKey" + } + ] + } + }, + { + "name": "ProgramConfig", + "docs": [ + "Global program configuration account." + ], + "type": { + "kind": "struct", + "fields": [ + { + "name": "smartAccountIndex", + "docs": [ + "Counter for the number of smart accounts created." + ], + "type": "u128" + }, + { + "name": "authority", + "docs": [ + "The authority which can update the config." + ], + "type": "publicKey" + }, + { + "name": "smartAccountCreationFee", + "docs": [ + "The lamports amount charged for creating a new smart account.", + "This fee is sent to the `treasury` account." + ], + "type": "u64" + }, + { + "name": "treasury", + "docs": [ + "The treasury account to send charged fees to." + ], + "type": "publicKey" + }, + { + "name": "reserved", + "docs": [ + "Reserved for future use." + ], + "type": { + "array": [ + "u8", + 64 + ] + } + } + ] + } + }, + { + "name": "Proposal", + "docs": [ + "Stores the data required for tracking the status of a smart account proposal.", + "Each `Proposal` has a 1:1 association with a transaction account, e.g. a `Transaction` or a `SettingsTransaction`;", + "the latter can be executed only after the `Proposal` has been approved and its time lock is released." + ], + "type": { + "kind": "struct", + "fields": [ + { + "name": "settings", + "docs": [ + "The consensus account (settings or policy) this belongs to." + ], + "type": "publicKey" + }, + { + "name": "transactionIndex", + "docs": [ + "Index of the smart account transaction this proposal is associated with." + ], + "type": "u64" + }, + { + "name": "rentCollector", + "docs": [ + "The rent collector for the proposal account." + ], + "type": "publicKey" + }, + { + "name": "status", + "docs": [ + "The status of the transaction." + ], + "type": { + "defined": "ProposalStatus" + } + }, + { + "name": "bump", + "docs": [ + "PDA bump." + ], + "type": "u8" + }, + { + "name": "approved", + "docs": [ + "Keys that have approved/signed." + ], + "type": { + "vec": "publicKey" } }, { @@ -2130,8 +2471,13 @@ "type": "u8" }, { - "name": "reserved1", - "type": "u8" + "name": "policySeed", + "docs": [ + "Seed used for deterministic policy creation." + ], + "type": { + "option": "u64" + } }, { "name": "reserved2", @@ -2253,7 +2599,7 @@ { "name": "settings", "docs": [ - "The settings this belongs to." + "The consensus account (settings or policy) this belongs to." ], "type": "publicKey" }, @@ -2311,7 +2657,7 @@ "name": "Transaction", "docs": [ "Stores data required for tracking the voting and execution status of a smart", - "account transaction.", + "account transaction or policy action", "Smart Account transaction is a transaction that's executed on behalf of the", "smart account PDA", "and wraps arbitrary Solana instructions, typically calling into other Solana programs." @@ -2320,9 +2666,9 @@ "kind": "struct", "fields": [ { - "name": "settings", + "name": "consensusAccount", "docs": [ - "The settings this belongs to." + "The consensus account this belongs to." ], "type": "publicKey" }, @@ -2343,52 +2689,17 @@ { "name": "index", "docs": [ - "Index of this transaction within the smart account." + "Index of this transaction within the consensus account." ], "type": "u64" }, { - "name": "bump", - "docs": [ - "bump for the transaction seeds." - ], - "type": "u8" - }, - { - "name": "accountIndex", - "docs": [ - "The account index of the smart account this transaction belongs to." - ], - "type": "u8" - }, - { - "name": "accountBump", - "docs": [ - "Derivation bump of the smart account PDA this transaction belongs to." - ], - "type": "u8" - }, - { - "name": "ephemeralSignerBumps", - "docs": [ - "Derivation bumps for additional signers.", - "Some transactions require multiple signers. Often these additional signers are \"ephemeral\" keypairs", - "that are generated on the client with a sole purpose of signing the transaction and be discarded immediately after.", - "When wrapping such transactions into smart account ones, we replace these \"ephemeral\" signing keypairs", - "with PDAs derived from the SmartAccountTransaction's `transaction_index`", - "and controlled by the Smart Account Program;", - "during execution the program includes the seeds of these PDAs into the `invoke_signed` calls,", - "thus \"signing\" on behalf of these PDAs." - ], - "type": "bytes" - }, - { - "name": "message", + "name": "payload", "docs": [ - "data required for executing the transaction." + "The payload of the transaction." ], "type": { - "defined": "SmartAccountTransactionMessage" + "defined": "Payload" } } ] @@ -2690,6 +3001,18 @@ ] } }, + { + "name": "LogEventArgsV2", + "type": { + "kind": "struct", + "fields": [ + { + "name": "event", + "type": "bytes" + } + ] + } + }, { "name": "ProgramConfigSetAuthorityArgs", "type": { @@ -2968,22 +3291,16 @@ } }, { - "name": "CreateTransactionArgs", + "name": "TransactionPayload", "type": { "kind": "struct", "fields": [ { "name": "accountIndex", - "docs": [ - "Index of the smart account this transaction belongs to." - ], "type": "u8" }, { "name": "ephemeralSigners", - "docs": [ - "Number of ephemeral signing PDAs required by the transaction." - ], "type": "u8" }, { @@ -3000,7 +3317,7 @@ } }, { - "name": "SyncTransactionArgs", + "name": "LegacySyncTransactionArgs", "type": { "kind": "struct", "fields": [ @@ -3028,6 +3345,28 @@ ] } }, + { + "name": "SyncTransactionArgs", + "type": { + "kind": "struct", + "fields": [ + { + "name": "accountIndex", + "type": "u8" + }, + { + "name": "numSigners", + "type": "u8" + }, + { + "name": "payload", + "type": { + "defined": "SyncPayload" + } + } + ] + } + }, { "name": "UseSpendingLimitArgs", "type": { @@ -3060,184 +3399,1585 @@ } }, { - "name": "SmartAccountSigner", + "name": "SmartAccountTransactionMessage", "type": { "kind": "struct", "fields": [ { - "name": "key", - "type": "publicKey" + "name": "numSigners", + "docs": [ + "The number of signer pubkeys in the account_keys vec." + ], + "type": "u8" }, { - "name": "permissions", - "type": { - "defined": "Permissions" - } - } - ] - } - }, - { - "name": "Permissions", + "name": "numWritableSigners", + "docs": [ + "The number of writable signer pubkeys in the account_keys vec." + ], + "type": "u8" + }, + { + "name": "numWritableNonSigners", + "docs": [ + "The number of writable non-signer pubkeys in the account_keys vec." + ], + "type": "u8" + }, + { + "name": "accountKeys", + "docs": [ + "Unique account pubkeys (including program IDs) required for execution of the tx.", + "The signer pubkeys appear at the beginning of the vec, with writable pubkeys first, and read-only pubkeys following.", + "The non-signer pubkeys follow with writable pubkeys first and read-only ones following.", + "Program IDs are also stored at the end of the vec along with other non-signer non-writable pubkeys:", + "", + "```plaintext", + "[pubkey1, pubkey2, pubkey3, pubkey4, pubkey5, pubkey6, pubkey7, pubkey8]", + "|---writable---| |---readonly---| |---writable---| |---readonly---|", + "|------------signers-------------| |----------non-singers-----------|", + "```" + ], + "type": { + "vec": "publicKey" + } + }, + { + "name": "instructions", + "docs": [ + "List of instructions making up the tx." + ], + "type": { + "vec": { + "defined": "SmartAccountCompiledInstruction" + } + } + }, + { + "name": "addressTableLookups", + "docs": [ + "List of address table lookups used to load additional accounts", + "for this transaction." + ], + "type": { + "vec": { + "defined": "SmartAccountMessageAddressTableLookup" + } + } + } + ] + } + }, + { + "name": "SmartAccountCompiledInstruction", "docs": [ - "Bitmask for permissions." + "Concise serialization schema for instructions that make up a transaction.", + "Closely mimics the Solana transaction wire format." ], "type": { "kind": "struct", "fields": [ { - "name": "mask", + "name": "programIdIndex", + "type": "u8" + }, + { + "name": "accountIndexes", + "docs": [ + "Indices into the tx's `account_keys` list indicating which accounts to pass to the instruction." + ], + "type": "bytes" + }, + { + "name": "data", + "docs": [ + "Instruction data." + ], + "type": "bytes" + } + ] + } + }, + { + "name": "SmartAccountMessageAddressTableLookup", + "docs": [ + "Address table lookups describe an on-chain address lookup table to use", + "for loading more readonly and writable accounts into a transaction." + ], + "type": { + "kind": "struct", + "fields": [ + { + "name": "accountKey", + "docs": [ + "Address lookup table account key." + ], + "type": "publicKey" + }, + { + "name": "writableIndexes", + "docs": [ + "List of indexes used to load writable accounts." + ], + "type": "bytes" + }, + { + "name": "readonlyIndexes", + "docs": [ + "List of indexes used to load readonly accounts." + ], + "type": "bytes" + } + ] + } + }, + { + "name": "InternalFundTransferPolicy", + "docs": [ + "== InternalFundTransferPolicy ==", + "This policy allows for the transfer of SOL and SPL tokens between", + "a set of source and destination accounts.", + "", + "The policy is defined by a set of source and destination account indices", + "and a set of allowed mints.", + "===============================================", + "" + ], + "type": { + "kind": "struct", + "fields": [ + { + "name": "sourceAccountMask", + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "destinationAccountMask", + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "allowedMints", + "type": { + "vec": "publicKey" + } + } + ] + } + }, + { + "name": "InternalFundTransferPayload", + "type": { + "kind": "struct", + "fields": [ + { + "name": "sourceIndex", + "type": "u8" + }, + { + "name": "destinationIndex", + "type": "u8" + }, + { + "name": "mint", + "type": "publicKey" + }, + { + "name": "decimals", + "type": "u8" + }, + { + "name": "amount", + "type": "u64" + } + ] + } + }, + { + "name": "InternalFundTransferPolicyCreationPayload", + "type": { + "kind": "struct", + "fields": [ + { + "name": "sourceAccountIndices", + "type": "bytes" + }, + { + "name": "destinationAccountIndices", + "type": "bytes" + }, + { + "name": "allowedMints", + "type": { + "vec": "publicKey" + } + } + ] + } + }, + { + "name": "ProgramInteractionPolicy", + "type": { + "kind": "struct", + "fields": [ + { + "name": "accountIndex", + "docs": [ + "The account index of the account that will be used to execute the policy" + ], "type": "u8" + }, + { + "name": "instructionsConstraints", + "docs": [ + "Constraints evaluated as a logical OR" + ], + "type": { + "vec": { + "defined": "InstructionConstraint" + } + } + }, + { + "name": "preHook", + "docs": [ + "Hook invoked before inner instruction execution" + ], + "type": { + "option": { + "defined": "Hook" + } + } + }, + { + "name": "postHook", + "docs": [ + "Hook invoked after inner instruction execution" + ], + "type": { + "option": { + "defined": "Hook" + } + } + }, + { + "name": "spendingLimits", + "docs": [ + "Spending limits applied during policy execution" + ], + "type": { + "vec": { + "defined": "SpendingLimitV2" + } + } + } + ] + } + }, + { + "name": "InstructionConstraint", + "type": { + "kind": "struct", + "fields": [ + { + "name": "programId", + "docs": [ + "The program that this constraint applies to" + ], + "type": "publicKey" + }, + { + "name": "accountConstraints", + "docs": [ + "Account constraints (evaluated as logical AND)" + ], + "type": { + "vec": { + "defined": "AccountConstraint" + } + } + }, + { + "name": "dataConstraints", + "docs": [ + "Data constraints (evaluated as logical AND)" + ], + "type": { + "vec": { + "defined": "DataConstraint" + } + } + } + ] + } + }, + { + "name": "Hook", + "type": { + "kind": "struct", + "fields": [ + { + "name": "numExtraAccounts", + "type": "u8" + }, + { + "name": "accountConstraints", + "type": { + "vec": { + "defined": "AccountConstraint" + } + } + }, + { + "name": "instructionData", + "type": "bytes" + }, + { + "name": "programId", + "type": "publicKey" + }, + { + "name": "passInnerInstructions", + "type": "bool" + } + ] + } + }, + { + "name": "DataConstraint", + "type": { + "kind": "struct", + "fields": [ + { + "name": "dataOffset", + "type": "u64" + }, + { + "name": "dataValue", + "type": { + "defined": "DataValue" + } + }, + { + "name": "operator", + "type": { + "defined": "DataOperator" + } + } + ] + } + }, + { + "name": "AccountConstraint", + "type": { + "kind": "struct", + "fields": [ + { + "name": "accountIndex", + "type": "u8" + }, + { + "name": "accountConstraint", + "type": { + "defined": "AccountConstraintType" + } + }, + { + "name": "owner", + "type": { + "option": "publicKey" + } + } + ] + } + }, + { + "name": "LimitedTimeConstraints", + "docs": [ + "Limited subset of TimeConstraints" + ], + "type": { + "kind": "struct", + "fields": [ + { + "name": "start", + "type": "i64" + }, + { + "name": "expiration", + "type": { + "option": "i64" + } + }, + { + "name": "period", + "type": { + "defined": "PeriodV2" + } + } + ] + } + }, + { + "name": "LimitedQuantityConstraints", + "docs": [ + "Limited subset of QuantityConstraints" + ], + "type": { + "kind": "struct", + "fields": [ + { + "name": "maxPerPeriod", + "type": "u64" + } + ] + } + }, + { + "name": "LimitedSpendingLimit", + "docs": [ + "Limited subset of BalanceConstraint used to create a policy" + ], + "type": { + "kind": "struct", + "fields": [ + { + "name": "mint", + "type": "publicKey" + }, + { + "name": "timeConstraints", + "type": { + "defined": "LimitedTimeConstraints" + } + }, + { + "name": "quantityConstraints", + "type": { + "defined": "LimitedQuantityConstraints" + } + } + ] + } + }, + { + "name": "ProgramInteractionPolicyCreationPayload", + "docs": [ + "Payload used to create a program interaction policy" + ], + "type": { + "kind": "struct", + "fields": [ + { + "name": "accountIndex", + "type": "u8" + }, + { + "name": "instructionsConstraints", + "type": { + "vec": { + "defined": "InstructionConstraint" + } + } + }, + { + "name": "preHook", + "type": { + "option": { + "defined": "Hook" + } + } + }, + { + "name": "postHook", + "type": { + "option": { + "defined": "Hook" + } + } + }, + { + "name": "spendingLimits", + "type": { + "vec": { + "defined": "LimitedSpendingLimit" + } + } + } + ] + } + }, + { + "name": "ProgramInteractionPayload", + "type": { + "kind": "struct", + "fields": [ + { + "name": "instructionConstraintIndices", + "type": { + "option": "bytes" + } + }, + { + "name": "transactionPayload", + "type": { + "defined": "ProgramInteractionTransactionPayload" + } + } + ] + } + }, + { + "name": "SyncTransactionPayloadDetails", + "type": { + "kind": "struct", + "fields": [ + { + "name": "accountIndex", + "type": "u8" + }, + { + "name": "instructions", + "type": "bytes" + } + ] + } + }, + { + "name": "SettingsChangePolicy", + "docs": [ + "== SettingsChangePolicy ==", + "This policy allows for the modification of the settings of a smart account.", + "", + "The policy is defined by a set of allowed settings changes.", + "===============================================" + ], + "type": { + "kind": "struct", + "fields": [ + { + "name": "actions", + "type": { + "vec": { + "defined": "AllowedSettingsChange" + } + } + } + ] + } + }, + { + "name": "SettingsChangePolicyCreationPayload", + "type": { + "kind": "struct", + "fields": [ + { + "name": "actions", + "type": { + "vec": { + "defined": "AllowedSettingsChange" + } + } + } + ] + } + }, + { + "name": "SettingsChangePayload", + "type": { + "kind": "struct", + "fields": [ + { + "name": "actionIndex", + "type": "bytes" + }, + { + "name": "actions", + "type": { + "vec": { + "defined": "LimitedSettingsAction" + } + } + } + ] + } + }, + { + "name": "SpendingLimitPolicy", + "docs": [ + "== SpendingLimitPolicy ==", + "This policy allows for the transfer of SOL and SPL tokens between", + "a source account and a set of destination accounts.", + "", + "The policy is defined by a spending limit configuration and a source account index.", + "The spending limit configuration includes a mint, time constraints, quantity constraints,", + "and usage state.", + "===============================================", + "Main spending limit policy structure" + ], + "type": { + "kind": "struct", + "fields": [ + { + "name": "sourceAccountIndex", + "docs": [ + "The source account index" + ], + "type": "u8" + }, + { + "name": "destinations", + "docs": [ + "The destination addresses the spending limit is allowed to send funds to", + "If empty, funds can be sent to any address" + ], + "type": { + "vec": "publicKey" + } + }, + { + "name": "spendingLimit", + "docs": [ + "Spending limit configuration (timing, constraints, usage, mint)" + ], + "type": { + "defined": "SpendingLimitV2" + } + } + ] + } + }, + { + "name": "SpendingLimitPolicyCreationPayload", + "docs": [ + "Setup parameters for creating a spending limit" + ], + "type": { + "kind": "struct", + "fields": [ + { + "name": "mint", + "type": "publicKey" + }, + { + "name": "sourceAccountIndex", + "type": "u8" + }, + { + "name": "timeConstraints", + "type": { + "defined": "TimeConstraints" + } + }, + { + "name": "quantityConstraints", + "type": { + "defined": "QuantityConstraints" + } + }, + { + "name": "usageState", + "docs": [ + "Optionally this can be submitted to update a spending limit policy", + "Cannot be Some() if accumulate_unused is true, to avoid invariant behavior" + ], + "type": { + "option": { + "defined": "UsageState" + } + } + }, + { + "name": "destinations", + "type": { + "vec": "publicKey" + } + } + ] + } + }, + { + "name": "SpendingLimitPayload", + "docs": [ + "Payload for using a spending limit policy" + ], + "type": { + "kind": "struct", + "fields": [ + { + "name": "amount", + "type": "u64" + }, + { + "name": "destination", + "type": "publicKey" + }, + { + "name": "decimals", + "type": "u8" + } + ] + } + }, + { + "name": "TimeConstraints", + "docs": [ + "Configuration for time-based constraints" + ], + "type": { + "kind": "struct", + "fields": [ + { + "name": "start", + "docs": [ + "Optional start timestamp (0 means immediate)" + ], + "type": "i64" + }, + { + "name": "expiration", + "docs": [ + "Optional expiration timestamp" + ], + "type": { + "option": "i64" + } + }, + { + "name": "period", + "docs": [ + "Reset period for the spending limit" + ], + "type": { + "defined": "PeriodV2" + } + }, + { + "name": "accumulateUnused", + "docs": [ + "Whether unused allowances accumulate across periods" + ], + "type": "bool" + } + ] + } + }, + { + "name": "QuantityConstraints", + "docs": [ + "Quantity constraints for spending limits" + ], + "type": { + "kind": "struct", + "fields": [ + { + "name": "maxPerPeriod", + "docs": [ + "Maximum quantity per period" + ], + "type": "u64" + }, + { + "name": "maxPerUse", + "docs": [ + "Maximum quantity per individual use (0 means no per-use limit)" + ], + "type": "u64" + }, + { + "name": "enforceExactQuantity", + "docs": [ + "Whether to enforce exact quantity matching on max per use." + ], + "type": "bool" + } + ] + } + }, + { + "name": "UsageState", + "docs": [ + "Usage tracking for resource consumption" + ], + "type": { + "kind": "struct", + "fields": [ + { + "name": "remainingInPeriod", + "docs": [ + "Remaining quantity in current period" + ], + "type": "u64" + }, + { + "name": "lastReset", + "docs": [ + "Unix timestamp of last reset" + ], + "type": "i64" + } + ] + } + }, + { + "name": "SpendingLimitV2", + "docs": [ + "Shared spending limit structure that combines timing, quantity, usage, and mint" + ], + "type": { + "kind": "struct", + "fields": [ + { + "name": "mint", + "docs": [ + "The token mint the spending limit is for.", + "Pubkey::default() means SOL.", + "use NATIVE_MINT for Wrapped SOL." + ], + "type": "publicKey" + }, + { + "name": "timeConstraints", + "docs": [ + "Timing configuration" + ], + "type": { + "defined": "TimeConstraints" + } + }, + { + "name": "quantityConstraints", + "docs": [ + "Amount constraints" + ], + "type": { + "defined": "QuantityConstraints" + } + }, + { + "name": "usage", + "docs": [ + "Current usage tracking" + ], + "type": { + "defined": "UsageState" + } + } + ] + } + }, + { + "name": "SmartAccountSigner", + "type": { + "kind": "struct", + "fields": [ + { + "name": "key", + "type": "publicKey" + }, + { + "name": "permissions", + "type": { + "defined": "Permissions" + } + } + ] + } + }, + { + "name": "Permissions", + "docs": [ + "Bitmask for permissions." + ], + "type": { + "kind": "struct", + "fields": [ + { + "name": "mask", + "type": "u8" + } + ] + } + }, + { + "name": "TransactionPayloadDetails", + "type": { + "kind": "struct", + "fields": [ + { + "name": "accountIndex", + "docs": [ + "The account index of the smart account this transaction belongs to." + ], + "type": "u8" + }, + { + "name": "ephemeralSignerBumps", + "docs": [ + "The ephemeral signer bumps for the transaction." + ], + "type": "bytes" + }, + { + "name": "message", + "docs": [ + "The message of the transaction." + ], + "type": { + "defined": "SmartAccountTransactionMessage" + } + } + ] + } + }, + { + "name": "PolicyActionPayloadDetails", + "type": { + "kind": "struct", + "fields": [ + { + "name": "payload", + "type": { + "defined": "PolicyPayload" + } + } + ] + } + }, + { + "name": "SynchronousTransactionEventPayload", + "type": { + "kind": "enum", + "variants": [ + { + "name": "TransactionPayload", + "fields": [ + { + "name": "accountIndex", + "type": "u8" + }, + { + "name": "instructions", + "type": { + "vec": { + "defined": "SmartAccountCompiledInstruction" + } + } + } + ] + }, + { + "name": "PolicyPayload", + "fields": [ + { + "name": "policyPayload", + "type": { + "defined": "PolicyPayload" + } + } + ] + } + ] + } + }, + { + "name": "PolicyEventType", + "type": { + "kind": "enum", + "variants": [ + { + "name": "Create" + }, + { + "name": "Update" + }, + { + "name": "UpdateDuringExecution" + }, + { + "name": "Remove" + } + ] + } + }, + { + "name": "TransactionEventType", + "type": { + "kind": "enum", + "variants": [ + { + "name": "Create" + }, + { + "name": "Execute" + }, + { + "name": "Close" + } + ] + } + }, + { + "name": "ProposalEventType", + "type": { + "kind": "enum", + "variants": [ + { + "name": "Create" + }, + { + "name": "Approve" + }, + { + "name": "Reject" + }, + { + "name": "Cancel" + }, + { + "name": "Execute" + }, + { + "name": "Close" + } + ] + } + }, + { + "name": "Vote", + "type": { + "kind": "enum", + "variants": [ + { + "name": "Approve" + }, + { + "name": "Reject" + }, + { + "name": "Cancel" + } + ] + } + }, + { + "name": "CreateTransactionArgs", + "type": { + "kind": "enum", + "variants": [ + { + "name": "TransactionPayload", + "fields": [ + { + "defined": "TransactionPayload" + } + ] + }, + { + "name": "PolicyPayload", + "fields": [ + { + "name": "payload", + "docs": [ + "The payload of the policy transaction." + ], + "type": { + "defined": "PolicyPayload" + } + } + ] + } + ] + } + }, + { + "name": "SyncPayload", + "type": { + "kind": "enum", + "variants": [ + { + "name": "Transaction", + "fields": [ + "bytes" + ] + }, + { + "name": "Policy", + "fields": [ + { + "defined": "PolicyPayload" + } + ] + } + ] + } + }, + { + "name": "ConsensusAccountType", + "type": { + "kind": "enum", + "variants": [ + { + "name": "Settings" + }, + { + "name": "Policy" + } + ] + } + }, + { + "name": "DataOperator", + "type": { + "kind": "enum", + "variants": [ + { + "name": "Equals" + }, + { + "name": "NotEquals" + }, + { + "name": "GreaterThan" + }, + { + "name": "GreaterThanOrEqualTo" + }, + { + "name": "LessThan" + }, + { + "name": "LessThanOrEqualTo" + } + ] + } + }, + { + "name": "DataValue", + "type": { + "kind": "enum", + "variants": [ + { + "name": "U8", + "fields": [ + "u8" + ] + }, + { + "name": "U16Le", + "fields": [ + "u16" + ] + }, + { + "name": "U32Le", + "fields": [ + "u32" + ] + }, + { + "name": "U64Le", + "fields": [ + "u64" + ] + }, + { + "name": "U128Le", + "fields": [ + "u128" + ] + }, + { + "name": "U8Slice", + "fields": [ + "bytes" + ] + } + ] + } + }, + { + "name": "AccountConstraintType", + "type": { + "kind": "enum", + "variants": [ + { + "name": "Pubkey", + "fields": [ + { + "vec": "publicKey" + } + ] + }, + { + "name": "AccountData", + "fields": [ + { + "vec": { + "defined": "DataConstraint" + } + } + ] + } + ] + } + }, + { + "name": "ProgramInteractionTransactionPayload", + "type": { + "kind": "enum", + "variants": [ + { + "name": "AsyncTransaction", + "fields": [ + { + "defined": "TransactionPayload" + } + ] + }, + { + "name": "SyncTransaction", + "fields": [ + { + "defined": "SyncTransactionPayloadDetails" + } + ] + } + ] + } + }, + { + "name": "AllowedSettingsChange", + "docs": [ + "Defines which settings changes are allowed by the policy" + ], + "type": { + "kind": "enum", + "variants": [ + { + "name": "AddSigner", + "fields": [ + { + "name": "newSigner", + "docs": [ + "Some() - add a specific signer, None - add any signer" + ], + "type": { + "option": "publicKey" + } + }, + { + "name": "newSignerPermissions", + "docs": [ + "Some() - only allow certain permissions, None - allow all permissions" + ], + "type": { + "option": { + "defined": "Permissions" + } + } + } + ] + }, + { + "name": "RemoveSigner", + "fields": [ + { + "name": "oldSigner", + "docs": [ + "Some() - remove a specific signer, None - remove any signer" + ], + "type": { + "option": "publicKey" + } + } + ] + }, + { + "name": "ChangeThreshold" + }, + { + "name": "ChangeTimeLock", + "fields": [ + { + "name": "newTimeLock", + "docs": [ + "Some() - change timelock to a specific value, None - change timelock to any value" + ], + "type": { + "option": "u32" + } + } + ] + } + ] + } + }, + { + "name": "LimitedSettingsAction", + "docs": [ + "Limited subset of settings change actions for execution" + ], + "type": { + "kind": "enum", + "variants": [ + { + "name": "AddSigner", + "fields": [ + { + "name": "newSigner", + "type": { + "defined": "SmartAccountSigner" + } + } + ] + }, + { + "name": "RemoveSigner", + "fields": [ + { + "name": "oldSigner", + "type": "publicKey" + } + ] + }, + { + "name": "ChangeThreshold", + "fields": [ + { + "name": "newThreshold", + "type": "u16" + } + ] + }, + { + "name": "SetTimeLock", + "fields": [ + { + "name": "newTimeLock", + "type": "u32" + } + ] + } + ] + } + }, + { + "name": "PolicyCreationPayload", + "docs": [ + "Unified enum for all policy creation payloads", + "These are used in SettingsAction::PolicyCreate to specify which type of policy to create" + ], + "type": { + "kind": "enum", + "variants": [ + { + "name": "InternalFundTransfer", + "fields": [ + { + "defined": "InternalFundTransferPolicyCreationPayload" + } + ] + }, + { + "name": "SpendingLimit", + "fields": [ + { + "defined": "SpendingLimitPolicyCreationPayload" + } + ] + }, + { + "name": "SettingsChange", + "fields": [ + { + "defined": "SettingsChangePolicyCreationPayload" + } + ] + }, + { + "name": "ProgramInteraction", + "fields": [ + { + "defined": "ProgramInteractionPolicyCreationPayload" + } + ] + } + ] + } + }, + { + "name": "PolicyPayload", + "docs": [ + "Unified enum for all policy execution payloads" + ], + "type": { + "kind": "enum", + "variants": [ + { + "name": "InternalFundTransfer", + "fields": [ + { + "defined": "InternalFundTransferPayload" + } + ] + }, + { + "name": "ProgramInteraction", + "fields": [ + { + "defined": "ProgramInteractionPayload" + } + ] + }, + { + "name": "SpendingLimit", + "fields": [ + { + "defined": "SpendingLimitPayload" + } + ] + }, + { + "name": "SettingsChange", + "fields": [ + { + "defined": "SettingsChangePayload" + } + ] + } + ] + } + }, + { + "name": "PolicyExpiration", + "type": { + "kind": "enum", + "variants": [ + { + "name": "Timestamp", + "fields": [ + "i64" + ] + }, + { + "name": "SettingsState", + "fields": [ + { + "array": [ + "u8", + 32 + ] + } + ] } ] } }, { - "name": "SmartAccountTransactionMessage", + "name": "PolicyExpirationArgs", "type": { - "kind": "struct", - "fields": [ - { - "name": "numSigners", - "docs": [ - "The number of signer pubkeys in the account_keys vec." - ], - "type": "u8" - }, - { - "name": "numWritableSigners", - "docs": [ - "The number of writable signer pubkeys in the account_keys vec." - ], - "type": "u8" - }, - { - "name": "numWritableNonSigners", - "docs": [ - "The number of writable non-signer pubkeys in the account_keys vec." - ], - "type": "u8" - }, - { - "name": "accountKeys", - "docs": [ - "Unique account pubkeys (including program IDs) required for execution of the tx.", - "The signer pubkeys appear at the beginning of the vec, with writable pubkeys first, and read-only pubkeys following.", - "The non-signer pubkeys follow with writable pubkeys first and read-only ones following.", - "Program IDs are also stored at the end of the vec along with other non-signer non-writable pubkeys:", - "", - "```plaintext", - "[pubkey1, pubkey2, pubkey3, pubkey4, pubkey5, pubkey6, pubkey7, pubkey8]", - "|---writable---| |---readonly---| |---writable---| |---readonly---|", - "|------------signers-------------| |----------non-singers-----------|", - "```" - ], - "type": { - "vec": "publicKey" - } - }, + "kind": "enum", + "variants": [ { - "name": "instructions", - "docs": [ - "List of instructions making up the tx." - ], - "type": { - "vec": { - "defined": "SmartAccountCompiledInstruction" - } - } + "name": "Timestamp", + "fields": [ + "i64" + ] }, { - "name": "addressTableLookups", - "docs": [ - "List of address table lookups used to load additional accounts", - "for this transaction." - ], - "type": { - "vec": { - "defined": "SmartAccountMessageAddressTableLookup" - } - } + "name": "SettingsState" } ] } }, { - "name": "SmartAccountCompiledInstruction", - "docs": [ - "Concise serialization schema for instructions that make up a transaction.", - "Closely mimics the Solana transaction wire format." - ], + "name": "PolicyState", "type": { - "kind": "struct", - "fields": [ + "kind": "enum", + "variants": [ { - "name": "programIdIndex", - "type": "u8" + "name": "InternalFundTransfer", + "fields": [ + { + "defined": "InternalFundTransferPolicy" + } + ] }, { - "name": "accountIndexes", - "docs": [ - "Indices into the tx's `account_keys` list indicating which accounts to pass to the instruction." - ], - "type": "bytes" + "name": "SpendingLimit", + "fields": [ + { + "defined": "SpendingLimitPolicy" + } + ] }, { - "name": "data", - "docs": [ - "Instruction data." - ], - "type": "bytes" + "name": "SettingsChange", + "fields": [ + { + "defined": "SettingsChangePolicy" + } + ] + }, + { + "name": "ProgramInteraction", + "fields": [ + { + "defined": "ProgramInteractionPolicy" + } + ] } ] } }, { - "name": "SmartAccountMessageAddressTableLookup", + "name": "PolicyExecutionContext", "docs": [ - "Address table lookups describe an on-chain address lookup table to use", - "for loading more readonly and writable accounts into a transaction." + "The context in which the policy is being executed" ], "type": { - "kind": "struct", - "fields": [ - { - "name": "accountKey", - "docs": [ - "Address lookup table account key." - ], - "type": "publicKey" - }, + "kind": "enum", + "variants": [ { - "name": "writableIndexes", - "docs": [ - "List of indexes used to load writable accounts." - ], - "type": "bytes" + "name": "Synchronous" }, { - "name": "readonlyIndexes", - "docs": [ - "List of indexes used to load readonly accounts." - ], - "type": "bytes" + "name": "Asynchronous" } ] } }, { - "name": "Vote", + "name": "PeriodV2", "type": { "kind": "enum", "variants": [ { - "name": "Approve" + "name": "OneTime" }, { - "name": "Reject" + "name": "Daily" }, { - "name": "Cancel" + "name": "Weekly" + }, + { + "name": "Monthly" + }, + { + "name": "Custom", + "fields": [ + "i64" + ] } ] } @@ -3398,55 +5138,190 @@ } }, { - "name": "signers", + "name": "signers", + "docs": [ + "Members of the settings that can use the spending limit.", + "In case a member is removed from the settings, the spending limit will remain existent", + "(until explicitly deleted), but the removed member will not be able to use it anymore." + ], + "type": { + "vec": "publicKey" + } + }, + { + "name": "destinations", + "docs": [ + "The destination addresses the spending limit is allowed to sent funds to.", + "If empty, funds can be sent to any address." + ], + "type": { + "vec": "publicKey" + } + }, + { + "name": "expiration", + "docs": [ + "The expiration timestamp of the spending limit.", + "Non expiring spending limits are set to `i64::MAX`." + ], + "type": "i64" + } + ] + }, + { + "name": "RemoveSpendingLimit", + "fields": [ + { + "name": "spendingLimit", + "type": "publicKey" + } + ] + }, + { + "name": "SetArchivalAuthority", + "fields": [ + { + "name": "newArchivalAuthority", + "type": { + "option": "publicKey" + } + } + ] + }, + { + "name": "PolicyCreate", + "fields": [ + { + "name": "seed", + "docs": [ + "Key that is used to seed the Policy PDA." + ], + "type": "u64" + }, + { + "name": "policyCreationPayload", + "docs": [ + "The policy creation payload containing policy-specific configuration." + ], + "type": { + "defined": "PolicyCreationPayload" + } + }, + { + "name": "signers", + "docs": [ + "Signers attached to the policy with their permissions." + ], + "type": { + "vec": { + "defined": "SmartAccountSigner" + } + } + }, + { + "name": "threshold", + "docs": [ + "Threshold for approvals on the policy." + ], + "type": "u16" + }, + { + "name": "timeLock", + "docs": [ + "How many seconds must pass between approval and execution." + ], + "type": "u32" + }, + { + "name": "startTimestamp", + "docs": [ + "Timestamp when the policy becomes active." + ], + "type": { + "option": "i64" + } + }, + { + "name": "expirationArgs", + "docs": [ + "Policy expiration - either time-based or state-based." + ], + "type": { + "option": { + "defined": "PolicyExpirationArgs" + } + } + } + ] + }, + { + "name": "PolicyUpdate", + "fields": [ + { + "name": "policy", + "docs": [ + "The policy account to update." + ], + "type": "publicKey" + }, + { + "name": "signers", + "docs": [ + "Signers attached to the policy with their permissions." + ], + "type": { + "vec": { + "defined": "SmartAccountSigner" + } + } + }, + { + "name": "threshold", + "docs": [ + "Threshold for approvals on the policy." + ], + "type": "u16" + }, + { + "name": "timeLock", "docs": [ - "Members of the settings that can use the spending limit.", - "In case a member is removed from the settings, the spending limit will remain existent", - "(until explicitly deleted), but the removed member will not be able to use it anymore." + "How many seconds must pass between approval and execution." ], - "type": { - "vec": "publicKey" - } + "type": "u32" }, { - "name": "destinations", + "name": "policyUpdatePayload", "docs": [ - "The destination addresses the spending limit is allowed to sent funds to.", - "If empty, funds can be sent to any address." + "The policy update payload containing policy-specific configuration." ], "type": { - "vec": "publicKey" + "defined": "PolicyCreationPayload" } }, { - "name": "expiration", + "name": "expirationArgs", "docs": [ - "The expiration timestamp of the spending limit.", - "Non expiring spending limits are set to `i64::MAX`." + "Policy expiration - either time-based or state-based." ], - "type": "i64" + "type": { + "option": { + "defined": "PolicyExpirationArgs" + } + } } ] }, { - "name": "RemoveSpendingLimit", + "name": "PolicyRemove", "fields": [ { - "name": "spendingLimit", + "name": "policy", + "docs": [ + "The policy account to remove." + ], "type": "publicKey" } ] - }, - { - "name": "SetArchivalAuthority", - "fields": [ - { - "name": "newArchivalAuthority", - "type": { - "option": "publicKey" - } - } - ] } ] } @@ -3473,6 +5348,30 @@ } ] } + }, + { + "name": "Payload", + "type": { + "kind": "enum", + "variants": [ + { + "name": "TransactionPayload", + "fields": [ + { + "defined": "TransactionPayloadDetails" + } + ] + }, + { + "name": "PolicyPayload", + "fields": [ + { + "defined": "PolicyActionPayloadDetails" + } + ] + } + ] + } } ], "errors": [ @@ -3623,128 +5522,493 @@ }, { "code": 6029, - "name": "SpendingLimitExpired", - "msg": "Spending limit is expired" - }, - { - "code": 6030, "name": "UnknownPermission", "msg": "Signer has unknown permission" }, { - "code": 6031, + "code": 6030, "name": "ProtectedAccount", "msg": "Account is protected, it cannot be passed into a CPI as writable" }, { - "code": 6032, + "code": 6031, "name": "TimeLockExceedsMaxAllowed", "msg": "Time lock exceeds the maximum allowed (90 days)" }, { - "code": 6033, + "code": 6032, "name": "IllegalAccountOwner", "msg": "Account is not owned by Smart Account program" }, { - "code": 6034, + "code": 6033, "name": "RentReclamationDisabled", "msg": "Rent reclamation is disabled for this smart account" }, { - "code": 6035, + "code": 6034, "name": "InvalidRentCollector", "msg": "Invalid rent collector address" }, { - "code": 6036, + "code": 6035, "name": "ProposalForAnotherSmartAccount", "msg": "Proposal is for another smart account" }, { - "code": 6037, + "code": 6036, "name": "TransactionForAnotherSmartAccount", "msg": "Transaction is for another smart account" }, { - "code": 6038, + "code": 6037, "name": "TransactionNotMatchingProposal", "msg": "Transaction doesn't match proposal" }, { - "code": 6039, + "code": 6038, "name": "TransactionNotLastInBatch", "msg": "Transaction is not last in batch" }, { - "code": 6040, + "code": 6039, "name": "BatchNotEmpty", "msg": "Batch is not empty" }, { - "code": 6041, + "code": 6040, "name": "SpendingLimitInvalidAmount", "msg": "Invalid SpendingLimit amount" }, { - "code": 6042, + "code": 6041, "name": "InvalidInstructionArgs", "msg": "Invalid Instruction Arguments" }, { - "code": 6043, + "code": 6042, "name": "FinalBufferHashMismatch", "msg": "Final message buffer hash doesnt match the expected hash" }, { - "code": 6044, + "code": 6043, "name": "FinalBufferSizeExceeded", "msg": "Final buffer size cannot exceed 4000 bytes" }, { - "code": 6045, + "code": 6044, "name": "FinalBufferSizeMismatch", "msg": "Final buffer size mismatch" }, { - "code": 6046, + "code": 6045, "name": "SmartAccountCreateDeprecated", "msg": "smart_account_create has been deprecated. Use smart_account_create_v2 instead." }, { - "code": 6047, + "code": 6046, "name": "ThresholdNotReached", "msg": "Signers do not reach consensus threshold" }, { - "code": 6048, + "code": 6047, "name": "InvalidSignerCount", "msg": "Invalid number of signer accounts. Must be greater or equal to the threshold" }, { - "code": 6049, + "code": 6048, "name": "MissingSignature", "msg": "Missing signature" }, { - "code": 6050, + "code": 6049, "name": "InsufficientAggregatePermissions", "msg": "Insufficient aggregate permissions across signing members" }, { - "code": 6051, + "code": 6050, "name": "InsufficientVotePermissions", "msg": "Insufficient vote permissions across signing members" }, { - "code": 6052, + "code": 6051, "name": "TimeLockNotZero", "msg": "Smart account must not be time locked" }, { - "code": 6053, + "code": 6052, "name": "NotImplemented", "msg": "Feature not implemented" + }, + { + "code": 6053, + "name": "SpendingLimitInvalidCadenceConfiguration", + "msg": "Invalid cadence configuration" + }, + { + "code": 6054, + "name": "InvalidDataConstraint", + "msg": "Invalid data constraint" + }, + { + "code": 6055, + "name": "InvalidPayload", + "msg": "Invalid payload" + }, + { + "code": 6056, + "name": "ProtectedInstruction", + "msg": "Protected instruction" + }, + { + "code": 6057, + "name": "PlaceholderError", + "msg": "Placeholder error" + }, + { + "code": 6058, + "name": "InvalidPolicyPayload", + "msg": "Invalid policy payload" + }, + { + "code": 6059, + "name": "InvalidEmptyPolicy", + "msg": "Invalid empty policy" + }, + { + "code": 6060, + "name": "TransactionForAnotherPolicy", + "msg": "Transaction is for another policy" + }, + { + "code": 6061, + "name": "ProgramInteractionAsyncPayloadNotAllowedWithSyncTransaction", + "msg": "Program interaction sync payload not allowed with async transaction" + }, + { + "code": 6062, + "name": "ProgramInteractionSyncPayloadNotAllowedWithAsyncTransaction", + "msg": "Program interaction sync payload not allowed with sync transaction" + }, + { + "code": 6063, + "name": "ProgramInteractionDataTooShort", + "msg": "Program interaction data constraint failed: instruction data too short" + }, + { + "code": 6064, + "name": "ProgramInteractionInvalidNumericValue", + "msg": "Program interaction data constraint failed: invalid numeric value" + }, + { + "code": 6065, + "name": "ProgramInteractionInvalidByteSequence", + "msg": "Program interaction data constraint failed: invalid byte sequence" + }, + { + "code": 6066, + "name": "ProgramInteractionUnsupportedSliceOperator", + "msg": "Program interaction data constraint failed: unsupported operator for byte slice" + }, + { + "code": 6067, + "name": "ProgramInteractionDataParsingError", + "msg": "Program interaction constraint failed: instruction data parsing error" + }, + { + "code": 6068, + "name": "ProgramInteractionProgramIdMismatch", + "msg": "Program interaction constraint failed: program ID mismatch" + }, + { + "code": 6069, + "name": "ProgramInteractionAccountConstraintViolated", + "msg": "Program interaction constraint violation: account constraint" + }, + { + "code": 6070, + "name": "ProgramInteractionConstraintIndexOutOfBounds", + "msg": "Program interaction constraint violation: instruction constraint index out of bounds" + }, + { + "code": 6071, + "name": "ProgramInteractionInstructionCountMismatch", + "msg": "Program interaction constraint violation: instruction count mismatch" + }, + { + "code": 6072, + "name": "ProgramInteractionInsufficientLamportAllowance", + "msg": "Program interaction constraint violation: insufficient remaining lamport allowance" + }, + { + "code": 6073, + "name": "ProgramInteractionInsufficientTokenAllowance", + "msg": "Program interaction constraint violation: insufficient remaining token allowance" + }, + { + "code": 6074, + "name": "ProgramInteractionModifiedIllegalBalance", + "msg": "Program interaction constraint violation: modified illegal balance" + }, + { + "code": 6075, + "name": "ProgramInteractionIllegalTokenAccountModification", + "msg": "Program interaction constraint violation: illegal token account modification" + }, + { + "code": 6076, + "name": "ProgramInteractionDuplicateSpendingLimit", + "msg": "Program interaction invariant violation: duplicate spending limit for the same mint" + }, + { + "code": 6077, + "name": "ProgramInteractionTooManyInstructionConstraints", + "msg": "Program interaction constraint violation: too many instruction constraints. Max is 20" + }, + { + "code": 6078, + "name": "ProgramInteractionTooManySpendingLimits", + "msg": "Program interaction constraint violation: too many spending limits. Max is 10" + }, + { + "code": 6079, + "name": "ProgramInteractionTemplateHookError", + "msg": "Program interaction hook violation: template hook error" + }, + { + "code": 6080, + "name": "ProgramInteractionHookAuthorityCannotBePartOfHookAccounts", + "msg": "Program interaction hook violation: hook authority cannot be part of hook accounts" + }, + { + "code": 6081, + "name": "SpendingLimitNotActive", + "msg": "Spending limit is not active" + }, + { + "code": 6082, + "name": "SpendingLimitExpired", + "msg": "Spending limit is expired" + }, + { + "code": 6083, + "name": "SpendingLimitPolicyInvariantAccumulateUnused", + "msg": "Spending limit policy invariant violation: usage state cannot be Some() if accumulate_unused is true" + }, + { + "code": 6084, + "name": "SpendingLimitViolatesExactQuantityConstraint", + "msg": "Amount violates exact quantity constraint" + }, + { + "code": 6085, + "name": "SpendingLimitViolatesMaxPerUseConstraint", + "msg": "Amount violates max per use constraint" + }, + { + "code": 6086, + "name": "SpendingLimitInsufficientRemainingAmount", + "msg": "Spending limit is insufficient" + }, + { + "code": 6087, + "name": "SpendingLimitInvariantMaxPerPeriodZero", + "msg": "Spending limit invariant violation: max per period must be non-zero" + }, + { + "code": 6088, + "name": "SpendingLimitInvariantStartTimePositive", + "msg": "Spending limit invariant violation: start time must be positive" + }, + { + "code": 6089, + "name": "SpendingLimitInvariantExpirationSmallerThanStart", + "msg": "Spending limit invariant violation: expiration must be greater than start" + }, + { + "code": 6090, + "name": "SpendingLimitInvariantOverflowEnabledMustHaveExpiration", + "msg": "Spending limit invariant violation: overflow enabled must have expiration" + }, + { + "code": 6091, + "name": "SpendingLimitInvariantOneTimePeriodCannotHaveOverflowEnabled", + "msg": "Spending limit invariant violation: one time period cannot have overflow enabled" + }, + { + "code": 6092, + "name": "SpendingLimitInvariantOverflowRemainingAmountGreaterThanMaxAmount", + "msg": "Spending limit invariant violation: remaining amount must be less than max amount" + }, + { + "code": 6093, + "name": "SpendingLimitInvariantRemainingAmountGreaterThanMaxPerPeriod", + "msg": "Spending limit invariant violation: remaining amount must be less than or equal to max per period" + }, + { + "code": 6094, + "name": "SpendingLimitInvariantExactQuantityMaxPerUseZero", + "msg": "Spending limit invariant violation: exact quantity must have max per use non-zero" + }, + { + "code": 6095, + "name": "SpendingLimitInvariantMaxPerUseGreaterThanMaxPerPeriod", + "msg": "Spending limit invariant violation: max per use must be less than or equal to max per period" + }, + { + "code": 6096, + "name": "SpendingLimitInvariantCustomPeriodNegative", + "msg": "Spending limit invariant violation: custom period must be positive" + }, + { + "code": 6097, + "name": "SpendingLimitPolicyInvariantDuplicateDestinations", + "msg": "Spending limit policy invariant violation: cannot have duplicate destinations for the same mint" + }, + { + "code": 6098, + "name": "SpendingLimitInvariantLastResetOutOfBounds", + "msg": "Spending limit invariant violation: last reset must be between start and expiration" + }, + { + "code": 6099, + "name": "SpendingLimitInvariantLastResetSmallerThanStart", + "msg": "Spending limit invariant violation: last reset must be greater than start" + }, + { + "code": 6100, + "name": "InternalFundTransferPolicyInvariantSourceAccountIndexNotAllowed", + "msg": "Internal fund transfer policy invariant violation: source account index is not allowed" + }, + { + "code": 6101, + "name": "InternalFundTransferPolicyInvariantDestinationAccountIndexNotAllowed", + "msg": "Internal fund transfer policy invariant violation: destination account index is not allowed" + }, + { + "code": 6102, + "name": "InternalFundTransferPolicyInvariantSourceAndDestinationCannotBeTheSame", + "msg": "Internal fund transfer policy invariant violation: source and destination cannot be the same" + }, + { + "code": 6103, + "name": "InternalFundTransferPolicyInvariantMintNotAllowed", + "msg": "Internal fund transfer policy invariant violation: mint is not allowed" + }, + { + "code": 6104, + "name": "InternalFundTransferPolicyInvariantAmountZero", + "msg": "Internal fund transfer policy invariant violation: amount must be greater than 0" + }, + { + "code": 6105, + "name": "InternalFundTransferPolicyInvariantDuplicateMints", + "msg": "Internal fund transfer policy invariant violation: cannot have duplicate mints" + }, + { + "code": 6106, + "name": "ConsensusAccountNotSettings", + "msg": "Consensus account is not a settings" + }, + { + "code": 6107, + "name": "ConsensusAccountNotPolicy", + "msg": "Consensus account is not a policy" + }, + { + "code": 6108, + "name": "SettingsChangePolicyActionsMustBeNonZero", + "msg": "Settings change policy invariant violation: actions must be non-zero" + }, + { + "code": 6109, + "name": "SettingsChangeInvalidSettingsKey", + "msg": "Settings change policy violation: submitted settings account must match policy settings key" + }, + { + "code": 6110, + "name": "SettingsChangeInvalidSettingsAccount", + "msg": "Settings change policy violation: submitted settings account must be writable" + }, + { + "code": 6111, + "name": "SettingsChangeInvalidRentPayer", + "msg": "Settings change policy violation: rent payer must be writable and signer" + }, + { + "code": 6112, + "name": "SettingsChangeInvalidSystemProgram", + "msg": "Settings change policy violation: system program must be the system program" + }, + { + "code": 6113, + "name": "SettingsChangeAddSignerViolation", + "msg": "Settings change policy violation: signer does not match allowed signer" + }, + { + "code": 6114, + "name": "SettingsChangeAddSignerPermissionsViolation", + "msg": "Settings change policy violation: signer permissions does not match allowed signer permissions" + }, + { + "code": 6115, + "name": "SettingsChangeRemoveSignerViolation", + "msg": "Settings change policy violation: signer removal does not mach allowed signer removal" + }, + { + "code": 6116, + "name": "SettingsChangeChangeTimelockViolation", + "msg": "Settings change policy violation: time lock does not match allowed time lock" + }, + { + "code": 6117, + "name": "SettingsChangeActionMismatch", + "msg": "Settings change policy violation: action does not match allowed action" + }, + { + "code": 6118, + "name": "SettingsChangePolicyInvariantDuplicateActions", + "msg": "Settings change policy invariant violation: cannot have duplicate actions" + }, + { + "code": 6119, + "name": "SettingsChangePolicyInvariantActionIndicesActionsLengthMismatch", + "msg": "Settings change policy invariant violation: action indices must match actions length" + }, + { + "code": 6120, + "name": "SettingsChangePolicyInvariantActionIndexOutOfBounds", + "msg": "Settings change policy invariant violation: action index out of bounds" + }, + { + "code": 6121, + "name": "PolicyNotActiveYet", + "msg": "Policy is not active yet" + }, + { + "code": 6122, + "name": "PolicyInvariantInvalidExpiration", + "msg": "Policy invariant violation: invalid policy expiration" + }, + { + "code": 6123, + "name": "PolicyExpirationViolationPolicySettingsKeyMismatch", + "msg": "Policy expiration violation: submitted settings key does not match policy settings key" + }, + { + "code": 6124, + "name": "PolicyExpirationViolationSettingsAccountNotPresent", + "msg": "Policy expiration violation: state expiration requires the settings to be submitted" + }, + { + "code": 6125, + "name": "PolicyExpirationViolationHashExpired", + "msg": "Policy expiration violation: state hash has expired" + }, + { + "code": 6126, + "name": "PolicyExpirationViolationTimestampExpired", + "msg": "Policy expiration violation: timestamp has expired" } ], "metadata": { diff --git a/sdk/smart-account/package.json b/sdk/smart-account/package.json index a1d7ed2..bbb32e1 100644 --- a/sdk/smart-account/package.json +++ b/sdk/smart-account/package.json @@ -27,7 +27,6 @@ "@metaplex-foundation/cusper": "^0.0.2", "@solana/spl-token": "^0.3.6", "@solana/web3.js": "^1.70.3", - "@types/bn.js": "^5.1.1", "assert": "^2.0.0", "bn.js": "^5.2.1", "buffer": "6.0.3", @@ -36,7 +35,7 @@ "devDependencies": { "@metaplex-foundation/solita": "0.20.0", "@types/invariant": "2.2.35", - "@types/node": "18.11.17", + "@types/node": "24.0.15", "tsup": "^8.0.2", "typedoc": "^0.25.7", "typescript": "*" diff --git a/sdk/smart-account/src/generated/accounts/LegacyTransaction.ts b/sdk/smart-account/src/generated/accounts/LegacyTransaction.ts new file mode 100644 index 0000000..dec35ab --- /dev/null +++ b/sdk/smart-account/src/generated/accounts/LegacyTransaction.ts @@ -0,0 +1,225 @@ +/** + * 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 + */ + +import * as web3 from '@solana/web3.js' +import * as beet from '@metaplex-foundation/beet' +import * as beetSolana from '@metaplex-foundation/beet-solana' +import { + SmartAccountTransactionMessage, + smartAccountTransactionMessageBeet, +} from '../types/SmartAccountTransactionMessage' + +/** + * Arguments used to create {@link LegacyTransaction} + * @category Accounts + * @category generated + */ +export type LegacyTransactionArgs = { + smartAccountSettings: web3.PublicKey + creator: web3.PublicKey + rentCollector: web3.PublicKey + index: beet.bignum + bump: number + accountIndex: number + accountBump: number + ephemeralSignerBumps: Uint8Array + message: SmartAccountTransactionMessage +} + +export const legacyTransactionDiscriminator = [ + 144, 147, 65, 169, 145, 227, 57, 51, +] +/** + * Holds the data for the {@link LegacyTransaction} Account and provides de/serialization + * functionality for that data + * + * @category Accounts + * @category generated + */ +export class LegacyTransaction implements LegacyTransactionArgs { + private constructor( + readonly smartAccountSettings: web3.PublicKey, + readonly creator: web3.PublicKey, + readonly rentCollector: web3.PublicKey, + readonly index: beet.bignum, + readonly bump: number, + readonly accountIndex: number, + readonly accountBump: number, + readonly ephemeralSignerBumps: Uint8Array, + readonly message: SmartAccountTransactionMessage + ) {} + + /** + * Creates a {@link LegacyTransaction} instance from the provided args. + */ + static fromArgs(args: LegacyTransactionArgs) { + return new LegacyTransaction( + args.smartAccountSettings, + args.creator, + args.rentCollector, + args.index, + args.bump, + args.accountIndex, + args.accountBump, + args.ephemeralSignerBumps, + args.message + ) + } + + /** + * Deserializes the {@link LegacyTransaction} from the data of the provided {@link web3.AccountInfo}. + * @returns a tuple of the account data and the offset up to which the buffer was read to obtain it. + */ + static fromAccountInfo( + accountInfo: web3.AccountInfo, + offset = 0 + ): [LegacyTransaction, number] { + return LegacyTransaction.deserialize(accountInfo.data, offset) + } + + /** + * Retrieves the account info from the provided address and deserializes + * the {@link LegacyTransaction} from its data. + * + * @throws Error if no account info is found at the address or if deserialization fails + */ + static async fromAccountAddress( + connection: web3.Connection, + address: web3.PublicKey, + commitmentOrConfig?: web3.Commitment | web3.GetAccountInfoConfig + ): Promise { + const accountInfo = await connection.getAccountInfo( + address, + commitmentOrConfig + ) + if (accountInfo == null) { + throw new Error(`Unable to find LegacyTransaction account at ${address}`) + } + return LegacyTransaction.fromAccountInfo(accountInfo, 0)[0] + } + + /** + * Provides a {@link web3.Connection.getProgramAccounts} config builder, + * to fetch accounts matching filters that can be specified via that builder. + * + * @param programId - the program that owns the accounts we are filtering + */ + static gpaBuilder( + programId: web3.PublicKey = new web3.PublicKey( + 'SMRTzfY6DfH5ik3TKiyLFfXexV8uSG3d2UksSCYdunG' + ) + ) { + return beetSolana.GpaBuilder.fromStruct(programId, legacyTransactionBeet) + } + + /** + * Deserializes the {@link LegacyTransaction} from the provided data Buffer. + * @returns a tuple of the account data and the offset up to which the buffer was read to obtain it. + */ + static deserialize(buf: Buffer, offset = 0): [LegacyTransaction, number] { + return legacyTransactionBeet.deserialize(buf, offset) + } + + /** + * Serializes the {@link LegacyTransaction} into a Buffer. + * @returns a tuple of the created Buffer and the offset up to which the buffer was written to store it. + */ + serialize(): [Buffer, number] { + return legacyTransactionBeet.serialize({ + accountDiscriminator: legacyTransactionDiscriminator, + ...this, + }) + } + + /** + * Returns the byteSize of a {@link Buffer} holding the serialized data of + * {@link LegacyTransaction} for the provided args. + * + * @param args need to be provided since the byte size for this account + * depends on them + */ + static byteSize(args: LegacyTransactionArgs) { + const instance = LegacyTransaction.fromArgs(args) + return legacyTransactionBeet.toFixedFromValue({ + accountDiscriminator: legacyTransactionDiscriminator, + ...instance, + }).byteSize + } + + /** + * Fetches the minimum balance needed to exempt an account holding + * {@link LegacyTransaction} data from rent + * + * @param args need to be provided since the byte size for this account + * depends on them + * @param connection used to retrieve the rent exemption information + */ + static async getMinimumBalanceForRentExemption( + args: LegacyTransactionArgs, + connection: web3.Connection, + commitment?: web3.Commitment + ): Promise { + return connection.getMinimumBalanceForRentExemption( + LegacyTransaction.byteSize(args), + commitment + ) + } + + /** + * Returns a readable version of {@link LegacyTransaction} properties + * and can be used to convert to JSON and/or logging + */ + pretty() { + return { + smartAccountSettings: this.smartAccountSettings.toBase58(), + creator: this.creator.toBase58(), + rentCollector: this.rentCollector.toBase58(), + index: (() => { + const x = <{ toNumber: () => number }>this.index + if (typeof x.toNumber === 'function') { + try { + return x.toNumber() + } catch (_) { + return x + } + } + return x + })(), + bump: this.bump, + accountIndex: this.accountIndex, + accountBump: this.accountBump, + ephemeralSignerBumps: this.ephemeralSignerBumps, + message: this.message, + } + } +} + +/** + * @category Accounts + * @category generated + */ +export const legacyTransactionBeet = new beet.FixableBeetStruct< + LegacyTransaction, + LegacyTransactionArgs & { + accountDiscriminator: number[] /* size: 8 */ + } +>( + [ + ['accountDiscriminator', beet.uniformFixedSizeArray(beet.u8, 8)], + ['smartAccountSettings', beetSolana.publicKey], + ['creator', beetSolana.publicKey], + ['rentCollector', beetSolana.publicKey], + ['index', beet.u64], + ['bump', beet.u8], + ['accountIndex', beet.u8], + ['accountBump', beet.u8], + ['ephemeralSignerBumps', beet.bytes], + ['message', smartAccountTransactionMessageBeet], + ], + LegacyTransaction.fromArgs, + 'LegacyTransaction' +) diff --git a/sdk/smart-account/src/generated/accounts/Policy.ts b/sdk/smart-account/src/generated/accounts/Policy.ts new file mode 100644 index 0000000..e172bcd --- /dev/null +++ b/sdk/smart-account/src/generated/accounts/Policy.ts @@ -0,0 +1,273 @@ +/** + * 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 + */ + +import * as web3 from '@solana/web3.js' +import * as beet from '@metaplex-foundation/beet' +import * as beetSolana from '@metaplex-foundation/beet-solana' +import { + SmartAccountSigner, + smartAccountSignerBeet, +} from '../types/SmartAccountSigner' +import { PolicyState, policyStateBeet } from '../types/PolicyState' +import { + PolicyExpiration, + policyExpirationBeet, +} from '../types/PolicyExpiration' + +/** + * Arguments used to create {@link Policy} + * @category Accounts + * @category generated + */ +export type PolicyArgs = { + settings: web3.PublicKey + seed: beet.bignum + bump: number + transactionIndex: beet.bignum + staleTransactionIndex: beet.bignum + signers: SmartAccountSigner[] + threshold: number + timeLock: number + policyState: PolicyState + start: beet.bignum + expiration: beet.COption + rentCollector: web3.PublicKey +} + +export const policyDiscriminator = [222, 135, 7, 163, 235, 177, 33, 68] +/** + * Holds the data for the {@link Policy} Account and provides de/serialization + * functionality for that data + * + * @category Accounts + * @category generated + */ +export class Policy implements PolicyArgs { + private constructor( + readonly settings: web3.PublicKey, + readonly seed: beet.bignum, + readonly bump: number, + readonly transactionIndex: beet.bignum, + readonly staleTransactionIndex: beet.bignum, + readonly signers: SmartAccountSigner[], + readonly threshold: number, + readonly timeLock: number, + readonly policyState: PolicyState, + readonly start: beet.bignum, + readonly expiration: beet.COption, + readonly rentCollector: web3.PublicKey + ) {} + + /** + * Creates a {@link Policy} instance from the provided args. + */ + static fromArgs(args: PolicyArgs) { + return new Policy( + args.settings, + args.seed, + args.bump, + args.transactionIndex, + args.staleTransactionIndex, + args.signers, + args.threshold, + args.timeLock, + args.policyState, + args.start, + args.expiration, + args.rentCollector + ) + } + + /** + * Deserializes the {@link Policy} from the data of the provided {@link web3.AccountInfo}. + * @returns a tuple of the account data and the offset up to which the buffer was read to obtain it. + */ + static fromAccountInfo( + accountInfo: web3.AccountInfo, + offset = 0 + ): [Policy, number] { + return Policy.deserialize(accountInfo.data, offset) + } + + /** + * Retrieves the account info from the provided address and deserializes + * the {@link Policy} from its data. + * + * @throws Error if no account info is found at the address or if deserialization fails + */ + static async fromAccountAddress( + connection: web3.Connection, + address: web3.PublicKey, + commitmentOrConfig?: web3.Commitment | web3.GetAccountInfoConfig + ): Promise { + const accountInfo = await connection.getAccountInfo( + address, + commitmentOrConfig + ) + if (accountInfo == null) { + throw new Error(`Unable to find Policy account at ${address}`) + } + return Policy.fromAccountInfo(accountInfo, 0)[0] + } + + /** + * Provides a {@link web3.Connection.getProgramAccounts} config builder, + * to fetch accounts matching filters that can be specified via that builder. + * + * @param programId - the program that owns the accounts we are filtering + */ + static gpaBuilder( + programId: web3.PublicKey = new web3.PublicKey( + 'SMRTzfY6DfH5ik3TKiyLFfXexV8uSG3d2UksSCYdunG' + ) + ) { + return beetSolana.GpaBuilder.fromStruct(programId, policyBeet) + } + + /** + * Deserializes the {@link Policy} from the provided data Buffer. + * @returns a tuple of the account data and the offset up to which the buffer was read to obtain it. + */ + static deserialize(buf: Buffer, offset = 0): [Policy, number] { + return policyBeet.deserialize(buf, offset) + } + + /** + * Serializes the {@link Policy} into a Buffer. + * @returns a tuple of the created Buffer and the offset up to which the buffer was written to store it. + */ + serialize(): [Buffer, number] { + return policyBeet.serialize({ + accountDiscriminator: policyDiscriminator, + ...this, + }) + } + + /** + * Returns the byteSize of a {@link Buffer} holding the serialized data of + * {@link Policy} for the provided args. + * + * @param args need to be provided since the byte size for this account + * depends on them + */ + static byteSize(args: PolicyArgs) { + const instance = Policy.fromArgs(args) + return policyBeet.toFixedFromValue({ + accountDiscriminator: policyDiscriminator, + ...instance, + }).byteSize + } + + /** + * Fetches the minimum balance needed to exempt an account holding + * {@link Policy} data from rent + * + * @param args need to be provided since the byte size for this account + * depends on them + * @param connection used to retrieve the rent exemption information + */ + static async getMinimumBalanceForRentExemption( + args: PolicyArgs, + connection: web3.Connection, + commitment?: web3.Commitment + ): Promise { + return connection.getMinimumBalanceForRentExemption( + Policy.byteSize(args), + commitment + ) + } + + /** + * Returns a readable version of {@link Policy} properties + * and can be used to convert to JSON and/or logging + */ + pretty() { + return { + settings: this.settings.toBase58(), + seed: (() => { + const x = <{ toNumber: () => number }>this.seed + if (typeof x.toNumber === 'function') { + try { + return x.toNumber() + } catch (_) { + return x + } + } + return x + })(), + bump: this.bump, + transactionIndex: (() => { + const x = <{ toNumber: () => number }>this.transactionIndex + if (typeof x.toNumber === 'function') { + try { + return x.toNumber() + } catch (_) { + return x + } + } + return x + })(), + staleTransactionIndex: (() => { + const x = <{ toNumber: () => number }>this.staleTransactionIndex + if (typeof x.toNumber === 'function') { + try { + return x.toNumber() + } catch (_) { + return x + } + } + return x + })(), + signers: this.signers, + threshold: this.threshold, + timeLock: this.timeLock, + policyState: this.policyState.__kind, + start: (() => { + const x = <{ toNumber: () => number }>this.start + if (typeof x.toNumber === 'function') { + try { + return x.toNumber() + } catch (_) { + return x + } + } + return x + })(), + expiration: this.expiration, + rentCollector: this.rentCollector.toBase58(), + } + } +} + +/** + * @category Accounts + * @category generated + */ +export const policyBeet = new beet.FixableBeetStruct< + Policy, + PolicyArgs & { + accountDiscriminator: number[] /* size: 8 */ + } +>( + [ + ['accountDiscriminator', beet.uniformFixedSizeArray(beet.u8, 8)], + ['settings', beetSolana.publicKey], + ['seed', beet.u64], + ['bump', beet.u8], + ['transactionIndex', beet.u64], + ['staleTransactionIndex', beet.u64], + ['signers', beet.array(smartAccountSignerBeet)], + ['threshold', beet.u16], + ['timeLock', beet.u32], + ['policyState', policyStateBeet], + ['start', beet.i64], + ['expiration', beet.coption(policyExpirationBeet)], + ['rentCollector', beetSolana.publicKey], + ], + Policy.fromArgs, + 'Policy' +) diff --git a/sdk/smart-account/src/generated/accounts/Settings.ts b/sdk/smart-account/src/generated/accounts/Settings.ts index 0ce21eb..2857add 100644 --- a/sdk/smart-account/src/generated/accounts/Settings.ts +++ b/sdk/smart-account/src/generated/accounts/Settings.ts @@ -30,7 +30,7 @@ export type SettingsArgs = { bump: number signers: SmartAccountSigner[] accountUtilization: number - reserved1: number + policySeed: beet.COption reserved2: number } @@ -55,7 +55,7 @@ export class Settings implements SettingsArgs { readonly bump: number, readonly signers: SmartAccountSigner[], readonly accountUtilization: number, - readonly reserved1: number, + readonly policySeed: beet.COption, readonly reserved2: number ) {} @@ -75,7 +75,7 @@ export class Settings implements SettingsArgs { args.bump, args.signers, args.accountUtilization, - args.reserved1, + args.policySeed, args.reserved2 ) } @@ -236,7 +236,7 @@ export class Settings implements SettingsArgs { bump: this.bump, signers: this.signers, accountUtilization: this.accountUtilization, - reserved1: this.reserved1, + policySeed: this.policySeed, reserved2: this.reserved2, } } @@ -265,7 +265,7 @@ export const settingsBeet = new beet.FixableBeetStruct< ['bump', beet.u8], ['signers', beet.array(smartAccountSignerBeet)], ['accountUtilization', beet.u8], - ['reserved1', beet.u8], + ['policySeed', beet.coption(beet.u64)], ['reserved2', beet.u8], ], Settings.fromArgs, diff --git a/sdk/smart-account/src/generated/accounts/Transaction.ts b/sdk/smart-account/src/generated/accounts/Transaction.ts index f6ccc86..7744ac6 100644 --- a/sdk/smart-account/src/generated/accounts/Transaction.ts +++ b/sdk/smart-account/src/generated/accounts/Transaction.ts @@ -8,10 +8,7 @@ import * as web3 from '@solana/web3.js' import * as beet from '@metaplex-foundation/beet' import * as beetSolana from '@metaplex-foundation/beet-solana' -import { - SmartAccountTransactionMessage, - smartAccountTransactionMessageBeet, -} from '../types/SmartAccountTransactionMessage' +import { Payload, payloadBeet } from '../types/Payload' /** * Arguments used to create {@link Transaction} @@ -19,15 +16,11 @@ import { * @category generated */ export type TransactionArgs = { - settings: web3.PublicKey + consensusAccount: web3.PublicKey creator: web3.PublicKey rentCollector: web3.PublicKey index: beet.bignum - bump: number - accountIndex: number - accountBump: number - ephemeralSignerBumps: Uint8Array - message: SmartAccountTransactionMessage + payload: Payload } export const transactionDiscriminator = [11, 24, 174, 129, 203, 117, 242, 23] @@ -40,15 +33,11 @@ export const transactionDiscriminator = [11, 24, 174, 129, 203, 117, 242, 23] */ export class Transaction implements TransactionArgs { private constructor( - readonly settings: web3.PublicKey, + readonly consensusAccount: web3.PublicKey, readonly creator: web3.PublicKey, readonly rentCollector: web3.PublicKey, readonly index: beet.bignum, - readonly bump: number, - readonly accountIndex: number, - readonly accountBump: number, - readonly ephemeralSignerBumps: Uint8Array, - readonly message: SmartAccountTransactionMessage + readonly payload: Payload ) {} /** @@ -56,15 +45,11 @@ export class Transaction implements TransactionArgs { */ static fromArgs(args: TransactionArgs) { return new Transaction( - args.settings, + args.consensusAccount, args.creator, args.rentCollector, args.index, - args.bump, - args.accountIndex, - args.accountBump, - args.ephemeralSignerBumps, - args.message + args.payload ) } @@ -173,7 +158,7 @@ export class Transaction implements TransactionArgs { */ pretty() { return { - settings: this.settings.toBase58(), + consensusAccount: this.consensusAccount.toBase58(), creator: this.creator.toBase58(), rentCollector: this.rentCollector.toBase58(), index: (() => { @@ -187,11 +172,7 @@ export class Transaction implements TransactionArgs { } return x })(), - bump: this.bump, - accountIndex: this.accountIndex, - accountBump: this.accountBump, - ephemeralSignerBumps: this.ephemeralSignerBumps, - message: this.message, + payload: this.payload.__kind, } } } @@ -208,15 +189,11 @@ export const transactionBeet = new beet.FixableBeetStruct< >( [ ['accountDiscriminator', beet.uniformFixedSizeArray(beet.u8, 8)], - ['settings', beetSolana.publicKey], + ['consensusAccount', beetSolana.publicKey], ['creator', beetSolana.publicKey], ['rentCollector', beetSolana.publicKey], ['index', beet.u64], - ['bump', beet.u8], - ['accountIndex', beet.u8], - ['accountBump', beet.u8], - ['ephemeralSignerBumps', beet.bytes], - ['message', smartAccountTransactionMessageBeet], + ['payload', payloadBeet], ], Transaction.fromArgs, 'Transaction' diff --git a/sdk/smart-account/src/generated/accounts/index.ts b/sdk/smart-account/src/generated/accounts/index.ts index 1189c70..90ebff9 100644 --- a/sdk/smart-account/src/generated/accounts/index.ts +++ b/sdk/smart-account/src/generated/accounts/index.ts @@ -1,5 +1,7 @@ export * from './Batch' export * from './BatchTransaction' +export * from './LegacyTransaction' +export * from './Policy' export * from './ProgramConfig' export * from './Proposal' export * from './Settings' @@ -10,6 +12,8 @@ export * from './TransactionBuffer' import { Batch } from './Batch' import { BatchTransaction } from './BatchTransaction' +import { LegacyTransaction } from './LegacyTransaction' +import { Policy } from './Policy' import { ProgramConfig } from './ProgramConfig' import { Proposal } from './Proposal' import { SettingsTransaction } from './SettingsTransaction' @@ -21,6 +25,8 @@ import { Transaction } from './Transaction' export const accountProviders = { Batch, BatchTransaction, + LegacyTransaction, + Policy, ProgramConfig, Proposal, SettingsTransaction, diff --git a/sdk/smart-account/src/generated/errors/index.ts b/sdk/smart-account/src/generated/errors/index.ts index 5729698..d34f1be 100644 --- a/sdk/smart-account/src/generated/errors/index.ts +++ b/sdk/smart-account/src/generated/errors/index.ts @@ -653,29 +653,6 @@ createErrorFromNameLookup.set( () => new DecimalsMismatchError() ) -/** - * SpendingLimitExpired: 'Spending limit is expired' - * - * @category Errors - * @category generated - */ -export class SpendingLimitExpiredError extends Error { - readonly code: number = 0x178d - readonly name: string = 'SpendingLimitExpired' - constructor() { - super('Spending limit is expired') - if (typeof Error.captureStackTrace === 'function') { - Error.captureStackTrace(this, SpendingLimitExpiredError) - } - } -} - -createErrorFromCodeLookup.set(0x178d, () => new SpendingLimitExpiredError()) -createErrorFromNameLookup.set( - 'SpendingLimitExpired', - () => new SpendingLimitExpiredError() -) - /** * UnknownPermission: 'Signer has unknown permission' * @@ -683,7 +660,7 @@ createErrorFromNameLookup.set( * @category generated */ export class UnknownPermissionError extends Error { - readonly code: number = 0x178e + readonly code: number = 0x178d readonly name: string = 'UnknownPermission' constructor() { super('Signer has unknown permission') @@ -693,7 +670,7 @@ export class UnknownPermissionError extends Error { } } -createErrorFromCodeLookup.set(0x178e, () => new UnknownPermissionError()) +createErrorFromCodeLookup.set(0x178d, () => new UnknownPermissionError()) createErrorFromNameLookup.set( 'UnknownPermission', () => new UnknownPermissionError() @@ -706,7 +683,7 @@ createErrorFromNameLookup.set( * @category generated */ export class ProtectedAccountError extends Error { - readonly code: number = 0x178f + readonly code: number = 0x178e readonly name: string = 'ProtectedAccount' constructor() { super('Account is protected, it cannot be passed into a CPI as writable') @@ -716,7 +693,7 @@ export class ProtectedAccountError extends Error { } } -createErrorFromCodeLookup.set(0x178f, () => new ProtectedAccountError()) +createErrorFromCodeLookup.set(0x178e, () => new ProtectedAccountError()) createErrorFromNameLookup.set( 'ProtectedAccount', () => new ProtectedAccountError() @@ -729,7 +706,7 @@ createErrorFromNameLookup.set( * @category generated */ export class TimeLockExceedsMaxAllowedError extends Error { - readonly code: number = 0x1790 + readonly code: number = 0x178f readonly name: string = 'TimeLockExceedsMaxAllowed' constructor() { super('Time lock exceeds the maximum allowed (90 days)') @@ -740,7 +717,7 @@ export class TimeLockExceedsMaxAllowedError extends Error { } createErrorFromCodeLookup.set( - 0x1790, + 0x178f, () => new TimeLockExceedsMaxAllowedError() ) createErrorFromNameLookup.set( @@ -755,7 +732,7 @@ createErrorFromNameLookup.set( * @category generated */ export class IllegalAccountOwnerError extends Error { - readonly code: number = 0x1791 + readonly code: number = 0x1790 readonly name: string = 'IllegalAccountOwner' constructor() { super('Account is not owned by Smart Account program') @@ -765,7 +742,7 @@ export class IllegalAccountOwnerError extends Error { } } -createErrorFromCodeLookup.set(0x1791, () => new IllegalAccountOwnerError()) +createErrorFromCodeLookup.set(0x1790, () => new IllegalAccountOwnerError()) createErrorFromNameLookup.set( 'IllegalAccountOwner', () => new IllegalAccountOwnerError() @@ -778,7 +755,7 @@ createErrorFromNameLookup.set( * @category generated */ export class RentReclamationDisabledError extends Error { - readonly code: number = 0x1792 + readonly code: number = 0x1791 readonly name: string = 'RentReclamationDisabled' constructor() { super('Rent reclamation is disabled for this smart account') @@ -788,7 +765,7 @@ export class RentReclamationDisabledError extends Error { } } -createErrorFromCodeLookup.set(0x1792, () => new RentReclamationDisabledError()) +createErrorFromCodeLookup.set(0x1791, () => new RentReclamationDisabledError()) createErrorFromNameLookup.set( 'RentReclamationDisabled', () => new RentReclamationDisabledError() @@ -801,7 +778,7 @@ createErrorFromNameLookup.set( * @category generated */ export class InvalidRentCollectorError extends Error { - readonly code: number = 0x1793 + readonly code: number = 0x1792 readonly name: string = 'InvalidRentCollector' constructor() { super('Invalid rent collector address') @@ -811,7 +788,7 @@ export class InvalidRentCollectorError extends Error { } } -createErrorFromCodeLookup.set(0x1793, () => new InvalidRentCollectorError()) +createErrorFromCodeLookup.set(0x1792, () => new InvalidRentCollectorError()) createErrorFromNameLookup.set( 'InvalidRentCollector', () => new InvalidRentCollectorError() @@ -824,7 +801,7 @@ createErrorFromNameLookup.set( * @category generated */ export class ProposalForAnotherSmartAccountError extends Error { - readonly code: number = 0x1794 + readonly code: number = 0x1793 readonly name: string = 'ProposalForAnotherSmartAccount' constructor() { super('Proposal is for another smart account') @@ -835,7 +812,7 @@ export class ProposalForAnotherSmartAccountError extends Error { } createErrorFromCodeLookup.set( - 0x1794, + 0x1793, () => new ProposalForAnotherSmartAccountError() ) createErrorFromNameLookup.set( @@ -850,7 +827,7 @@ createErrorFromNameLookup.set( * @category generated */ export class TransactionForAnotherSmartAccountError extends Error { - readonly code: number = 0x1795 + readonly code: number = 0x1794 readonly name: string = 'TransactionForAnotherSmartAccount' constructor() { super('Transaction is for another smart account') @@ -861,7 +838,7 @@ export class TransactionForAnotherSmartAccountError extends Error { } createErrorFromCodeLookup.set( - 0x1795, + 0x1794, () => new TransactionForAnotherSmartAccountError() ) createErrorFromNameLookup.set( @@ -876,7 +853,7 @@ createErrorFromNameLookup.set( * @category generated */ export class TransactionNotMatchingProposalError extends Error { - readonly code: number = 0x1796 + readonly code: number = 0x1795 readonly name: string = 'TransactionNotMatchingProposal' constructor() { super("Transaction doesn't match proposal") @@ -887,7 +864,7 @@ export class TransactionNotMatchingProposalError extends Error { } createErrorFromCodeLookup.set( - 0x1796, + 0x1795, () => new TransactionNotMatchingProposalError() ) createErrorFromNameLookup.set( @@ -902,7 +879,7 @@ createErrorFromNameLookup.set( * @category generated */ export class TransactionNotLastInBatchError extends Error { - readonly code: number = 0x1797 + readonly code: number = 0x1796 readonly name: string = 'TransactionNotLastInBatch' constructor() { super('Transaction is not last in batch') @@ -913,7 +890,7 @@ export class TransactionNotLastInBatchError extends Error { } createErrorFromCodeLookup.set( - 0x1797, + 0x1796, () => new TransactionNotLastInBatchError() ) createErrorFromNameLookup.set( @@ -928,7 +905,7 @@ createErrorFromNameLookup.set( * @category generated */ export class BatchNotEmptyError extends Error { - readonly code: number = 0x1798 + readonly code: number = 0x1797 readonly name: string = 'BatchNotEmpty' constructor() { super('Batch is not empty') @@ -938,7 +915,7 @@ export class BatchNotEmptyError extends Error { } } -createErrorFromCodeLookup.set(0x1798, () => new BatchNotEmptyError()) +createErrorFromCodeLookup.set(0x1797, () => new BatchNotEmptyError()) createErrorFromNameLookup.set('BatchNotEmpty', () => new BatchNotEmptyError()) /** @@ -948,7 +925,7 @@ createErrorFromNameLookup.set('BatchNotEmpty', () => new BatchNotEmptyError()) * @category generated */ export class SpendingLimitInvalidAmountError extends Error { - readonly code: number = 0x1799 + readonly code: number = 0x1798 readonly name: string = 'SpendingLimitInvalidAmount' constructor() { super('Invalid SpendingLimit amount') @@ -959,7 +936,7 @@ export class SpendingLimitInvalidAmountError extends Error { } createErrorFromCodeLookup.set( - 0x1799, + 0x1798, () => new SpendingLimitInvalidAmountError() ) createErrorFromNameLookup.set( @@ -974,7 +951,7 @@ createErrorFromNameLookup.set( * @category generated */ export class InvalidInstructionArgsError extends Error { - readonly code: number = 0x179a + readonly code: number = 0x1799 readonly name: string = 'InvalidInstructionArgs' constructor() { super('Invalid Instruction Arguments') @@ -984,7 +961,7 @@ export class InvalidInstructionArgsError extends Error { } } -createErrorFromCodeLookup.set(0x179a, () => new InvalidInstructionArgsError()) +createErrorFromCodeLookup.set(0x1799, () => new InvalidInstructionArgsError()) createErrorFromNameLookup.set( 'InvalidInstructionArgs', () => new InvalidInstructionArgsError() @@ -997,7 +974,7 @@ createErrorFromNameLookup.set( * @category generated */ export class FinalBufferHashMismatchError extends Error { - readonly code: number = 0x179b + readonly code: number = 0x179a readonly name: string = 'FinalBufferHashMismatch' constructor() { super('Final message buffer hash doesnt match the expected hash') @@ -1007,7 +984,7 @@ export class FinalBufferHashMismatchError extends Error { } } -createErrorFromCodeLookup.set(0x179b, () => new FinalBufferHashMismatchError()) +createErrorFromCodeLookup.set(0x179a, () => new FinalBufferHashMismatchError()) createErrorFromNameLookup.set( 'FinalBufferHashMismatch', () => new FinalBufferHashMismatchError() @@ -1020,7 +997,7 @@ createErrorFromNameLookup.set( * @category generated */ export class FinalBufferSizeExceededError extends Error { - readonly code: number = 0x179c + readonly code: number = 0x179b readonly name: string = 'FinalBufferSizeExceeded' constructor() { super('Final buffer size cannot exceed 4000 bytes') @@ -1030,7 +1007,7 @@ export class FinalBufferSizeExceededError extends Error { } } -createErrorFromCodeLookup.set(0x179c, () => new FinalBufferSizeExceededError()) +createErrorFromCodeLookup.set(0x179b, () => new FinalBufferSizeExceededError()) createErrorFromNameLookup.set( 'FinalBufferSizeExceeded', () => new FinalBufferSizeExceededError() @@ -1043,7 +1020,7 @@ createErrorFromNameLookup.set( * @category generated */ export class FinalBufferSizeMismatchError extends Error { - readonly code: number = 0x179d + readonly code: number = 0x179c readonly name: string = 'FinalBufferSizeMismatch' constructor() { super('Final buffer size mismatch') @@ -1053,7 +1030,7 @@ export class FinalBufferSizeMismatchError extends Error { } } -createErrorFromCodeLookup.set(0x179d, () => new FinalBufferSizeMismatchError()) +createErrorFromCodeLookup.set(0x179c, () => new FinalBufferSizeMismatchError()) createErrorFromNameLookup.set( 'FinalBufferSizeMismatch', () => new FinalBufferSizeMismatchError() @@ -1066,7 +1043,7 @@ createErrorFromNameLookup.set( * @category generated */ export class SmartAccountCreateDeprecatedError extends Error { - readonly code: number = 0x179e + readonly code: number = 0x179d readonly name: string = 'SmartAccountCreateDeprecated' constructor() { super( @@ -1079,7 +1056,7 @@ export class SmartAccountCreateDeprecatedError extends Error { } createErrorFromCodeLookup.set( - 0x179e, + 0x179d, () => new SmartAccountCreateDeprecatedError() ) createErrorFromNameLookup.set( @@ -1094,7 +1071,7 @@ createErrorFromNameLookup.set( * @category generated */ export class ThresholdNotReachedError extends Error { - readonly code: number = 0x179f + readonly code: number = 0x179e readonly name: string = 'ThresholdNotReached' constructor() { super('Signers do not reach consensus threshold') @@ -1104,7 +1081,7 @@ export class ThresholdNotReachedError extends Error { } } -createErrorFromCodeLookup.set(0x179f, () => new ThresholdNotReachedError()) +createErrorFromCodeLookup.set(0x179e, () => new ThresholdNotReachedError()) createErrorFromNameLookup.set( 'ThresholdNotReached', () => new ThresholdNotReachedError() @@ -1117,7 +1094,7 @@ createErrorFromNameLookup.set( * @category generated */ export class InvalidSignerCountError extends Error { - readonly code: number = 0x17a0 + readonly code: number = 0x179f readonly name: string = 'InvalidSignerCount' constructor() { super( @@ -1129,7 +1106,7 @@ export class InvalidSignerCountError extends Error { } } -createErrorFromCodeLookup.set(0x17a0, () => new InvalidSignerCountError()) +createErrorFromCodeLookup.set(0x179f, () => new InvalidSignerCountError()) createErrorFromNameLookup.set( 'InvalidSignerCount', () => new InvalidSignerCountError() @@ -1142,7 +1119,7 @@ createErrorFromNameLookup.set( * @category generated */ export class MissingSignatureError extends Error { - readonly code: number = 0x17a1 + readonly code: number = 0x17a0 readonly name: string = 'MissingSignature' constructor() { super('Missing signature') @@ -1152,7 +1129,7 @@ export class MissingSignatureError extends Error { } } -createErrorFromCodeLookup.set(0x17a1, () => new MissingSignatureError()) +createErrorFromCodeLookup.set(0x17a0, () => new MissingSignatureError()) createErrorFromNameLookup.set( 'MissingSignature', () => new MissingSignatureError() @@ -1165,7 +1142,7 @@ createErrorFromNameLookup.set( * @category generated */ export class InsufficientAggregatePermissionsError extends Error { - readonly code: number = 0x17a2 + readonly code: number = 0x17a1 readonly name: string = 'InsufficientAggregatePermissions' constructor() { super('Insufficient aggregate permissions across signing members') @@ -1176,7 +1153,7 @@ export class InsufficientAggregatePermissionsError extends Error { } createErrorFromCodeLookup.set( - 0x17a2, + 0x17a1, () => new InsufficientAggregatePermissionsError() ) createErrorFromNameLookup.set( @@ -1191,7 +1168,7 @@ createErrorFromNameLookup.set( * @category generated */ export class InsufficientVotePermissionsError extends Error { - readonly code: number = 0x17a3 + readonly code: number = 0x17a2 readonly name: string = 'InsufficientVotePermissions' constructor() { super('Insufficient vote permissions across signing members') @@ -1202,7 +1179,7 @@ export class InsufficientVotePermissionsError extends Error { } createErrorFromCodeLookup.set( - 0x17a3, + 0x17a2, () => new InsufficientVotePermissionsError() ) createErrorFromNameLookup.set( @@ -1217,7 +1194,7 @@ createErrorFromNameLookup.set( * @category generated */ export class TimeLockNotZeroError extends Error { - readonly code: number = 0x17a4 + readonly code: number = 0x17a3 readonly name: string = 'TimeLockNotZero' constructor() { super('Smart account must not be time locked') @@ -1227,7 +1204,7 @@ export class TimeLockNotZeroError extends Error { } } -createErrorFromCodeLookup.set(0x17a4, () => new TimeLockNotZeroError()) +createErrorFromCodeLookup.set(0x17a3, () => new TimeLockNotZeroError()) createErrorFromNameLookup.set( 'TimeLockNotZero', () => new TimeLockNotZeroError() @@ -1240,7 +1217,7 @@ createErrorFromNameLookup.set( * @category generated */ export class NotImplementedError extends Error { - readonly code: number = 0x17a5 + readonly code: number = 0x17a4 readonly name: string = 'NotImplemented' constructor() { super('Feature not implemented') @@ -1250,9 +1227,2148 @@ export class NotImplementedError extends Error { } } -createErrorFromCodeLookup.set(0x17a5, () => new NotImplementedError()) +createErrorFromCodeLookup.set(0x17a4, () => new NotImplementedError()) createErrorFromNameLookup.set('NotImplemented', () => new NotImplementedError()) +/** + * SpendingLimitInvalidCadenceConfiguration: 'Invalid cadence configuration' + * + * @category Errors + * @category generated + */ +export class SpendingLimitInvalidCadenceConfigurationError extends Error { + readonly code: number = 0x17a5 + readonly name: string = 'SpendingLimitInvalidCadenceConfiguration' + constructor() { + super('Invalid cadence configuration') + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + SpendingLimitInvalidCadenceConfigurationError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17a5, + () => new SpendingLimitInvalidCadenceConfigurationError() +) +createErrorFromNameLookup.set( + 'SpendingLimitInvalidCadenceConfiguration', + () => new SpendingLimitInvalidCadenceConfigurationError() +) + +/** + * InvalidDataConstraint: 'Invalid data constraint' + * + * @category Errors + * @category generated + */ +export class InvalidDataConstraintError extends Error { + readonly code: number = 0x17a6 + readonly name: string = 'InvalidDataConstraint' + constructor() { + super('Invalid data constraint') + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace(this, InvalidDataConstraintError) + } + } +} + +createErrorFromCodeLookup.set(0x17a6, () => new InvalidDataConstraintError()) +createErrorFromNameLookup.set( + 'InvalidDataConstraint', + () => new InvalidDataConstraintError() +) + +/** + * InvalidPayload: 'Invalid payload' + * + * @category Errors + * @category generated + */ +export class InvalidPayloadError extends Error { + readonly code: number = 0x17a7 + readonly name: string = 'InvalidPayload' + constructor() { + super('Invalid payload') + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace(this, InvalidPayloadError) + } + } +} + +createErrorFromCodeLookup.set(0x17a7, () => new InvalidPayloadError()) +createErrorFromNameLookup.set('InvalidPayload', () => new InvalidPayloadError()) + +/** + * ProtectedInstruction: 'Protected instruction' + * + * @category Errors + * @category generated + */ +export class ProtectedInstructionError extends Error { + readonly code: number = 0x17a8 + readonly name: string = 'ProtectedInstruction' + constructor() { + super('Protected instruction') + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace(this, ProtectedInstructionError) + } + } +} + +createErrorFromCodeLookup.set(0x17a8, () => new ProtectedInstructionError()) +createErrorFromNameLookup.set( + 'ProtectedInstruction', + () => new ProtectedInstructionError() +) + +/** + * PlaceholderError: 'Placeholder error' + * + * @category Errors + * @category generated + */ +export class PlaceholderErrorError extends Error { + readonly code: number = 0x17a9 + readonly name: string = 'PlaceholderError' + constructor() { + super('Placeholder error') + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace(this, PlaceholderErrorError) + } + } +} + +createErrorFromCodeLookup.set(0x17a9, () => new PlaceholderErrorError()) +createErrorFromNameLookup.set( + 'PlaceholderError', + () => new PlaceholderErrorError() +) + +/** + * InvalidPolicyPayload: 'Invalid policy payload' + * + * @category Errors + * @category generated + */ +export class InvalidPolicyPayloadError extends Error { + readonly code: number = 0x17aa + readonly name: string = 'InvalidPolicyPayload' + constructor() { + super('Invalid policy payload') + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace(this, InvalidPolicyPayloadError) + } + } +} + +createErrorFromCodeLookup.set(0x17aa, () => new InvalidPolicyPayloadError()) +createErrorFromNameLookup.set( + 'InvalidPolicyPayload', + () => new InvalidPolicyPayloadError() +) + +/** + * InvalidEmptyPolicy: 'Invalid empty policy' + * + * @category Errors + * @category generated + */ +export class InvalidEmptyPolicyError extends Error { + readonly code: number = 0x17ab + readonly name: string = 'InvalidEmptyPolicy' + constructor() { + super('Invalid empty policy') + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace(this, InvalidEmptyPolicyError) + } + } +} + +createErrorFromCodeLookup.set(0x17ab, () => new InvalidEmptyPolicyError()) +createErrorFromNameLookup.set( + 'InvalidEmptyPolicy', + () => new InvalidEmptyPolicyError() +) + +/** + * TransactionForAnotherPolicy: 'Transaction is for another policy' + * + * @category Errors + * @category generated + */ +export class TransactionForAnotherPolicyError extends Error { + readonly code: number = 0x17ac + readonly name: string = 'TransactionForAnotherPolicy' + constructor() { + super('Transaction is for another policy') + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace(this, TransactionForAnotherPolicyError) + } + } +} + +createErrorFromCodeLookup.set( + 0x17ac, + () => new TransactionForAnotherPolicyError() +) +createErrorFromNameLookup.set( + 'TransactionForAnotherPolicy', + () => new TransactionForAnotherPolicyError() +) + +/** + * ProgramInteractionAsyncPayloadNotAllowedWithSyncTransaction: 'Program interaction sync payload not allowed with async transaction' + * + * @category Errors + * @category generated + */ +export class ProgramInteractionAsyncPayloadNotAllowedWithSyncTransactionError extends Error { + readonly code: number = 0x17ad + readonly name: string = + 'ProgramInteractionAsyncPayloadNotAllowedWithSyncTransaction' + constructor() { + super('Program interaction sync payload not allowed with async transaction') + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + ProgramInteractionAsyncPayloadNotAllowedWithSyncTransactionError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17ad, + () => new ProgramInteractionAsyncPayloadNotAllowedWithSyncTransactionError() +) +createErrorFromNameLookup.set( + 'ProgramInteractionAsyncPayloadNotAllowedWithSyncTransaction', + () => new ProgramInteractionAsyncPayloadNotAllowedWithSyncTransactionError() +) + +/** + * ProgramInteractionSyncPayloadNotAllowedWithAsyncTransaction: 'Program interaction sync payload not allowed with sync transaction' + * + * @category Errors + * @category generated + */ +export class ProgramInteractionSyncPayloadNotAllowedWithAsyncTransactionError extends Error { + readonly code: number = 0x17ae + readonly name: string = + 'ProgramInteractionSyncPayloadNotAllowedWithAsyncTransaction' + constructor() { + super('Program interaction sync payload not allowed with sync transaction') + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + ProgramInteractionSyncPayloadNotAllowedWithAsyncTransactionError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17ae, + () => new ProgramInteractionSyncPayloadNotAllowedWithAsyncTransactionError() +) +createErrorFromNameLookup.set( + 'ProgramInteractionSyncPayloadNotAllowedWithAsyncTransaction', + () => new ProgramInteractionSyncPayloadNotAllowedWithAsyncTransactionError() +) + +/** + * ProgramInteractionDataTooShort: 'Program interaction data constraint failed: instruction data too short' + * + * @category Errors + * @category generated + */ +export class ProgramInteractionDataTooShortError extends Error { + readonly code: number = 0x17af + readonly name: string = 'ProgramInteractionDataTooShort' + constructor() { + super( + 'Program interaction data constraint failed: instruction data too short' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace(this, ProgramInteractionDataTooShortError) + } + } +} + +createErrorFromCodeLookup.set( + 0x17af, + () => new ProgramInteractionDataTooShortError() +) +createErrorFromNameLookup.set( + 'ProgramInteractionDataTooShort', + () => new ProgramInteractionDataTooShortError() +) + +/** + * ProgramInteractionInvalidNumericValue: 'Program interaction data constraint failed: invalid numeric value' + * + * @category Errors + * @category generated + */ +export class ProgramInteractionInvalidNumericValueError extends Error { + readonly code: number = 0x17b0 + readonly name: string = 'ProgramInteractionInvalidNumericValue' + constructor() { + super('Program interaction data constraint failed: invalid numeric value') + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace(this, ProgramInteractionInvalidNumericValueError) + } + } +} + +createErrorFromCodeLookup.set( + 0x17b0, + () => new ProgramInteractionInvalidNumericValueError() +) +createErrorFromNameLookup.set( + 'ProgramInteractionInvalidNumericValue', + () => new ProgramInteractionInvalidNumericValueError() +) + +/** + * ProgramInteractionInvalidByteSequence: 'Program interaction data constraint failed: invalid byte sequence' + * + * @category Errors + * @category generated + */ +export class ProgramInteractionInvalidByteSequenceError extends Error { + readonly code: number = 0x17b1 + readonly name: string = 'ProgramInteractionInvalidByteSequence' + constructor() { + super('Program interaction data constraint failed: invalid byte sequence') + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace(this, ProgramInteractionInvalidByteSequenceError) + } + } +} + +createErrorFromCodeLookup.set( + 0x17b1, + () => new ProgramInteractionInvalidByteSequenceError() +) +createErrorFromNameLookup.set( + 'ProgramInteractionInvalidByteSequence', + () => new ProgramInteractionInvalidByteSequenceError() +) + +/** + * ProgramInteractionUnsupportedSliceOperator: 'Program interaction data constraint failed: unsupported operator for byte slice' + * + * @category Errors + * @category generated + */ +export class ProgramInteractionUnsupportedSliceOperatorError extends Error { + readonly code: number = 0x17b2 + readonly name: string = 'ProgramInteractionUnsupportedSliceOperator' + constructor() { + super( + 'Program interaction data constraint failed: unsupported operator for byte slice' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + ProgramInteractionUnsupportedSliceOperatorError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17b2, + () => new ProgramInteractionUnsupportedSliceOperatorError() +) +createErrorFromNameLookup.set( + 'ProgramInteractionUnsupportedSliceOperator', + () => new ProgramInteractionUnsupportedSliceOperatorError() +) + +/** + * ProgramInteractionDataParsingError: 'Program interaction constraint failed: instruction data parsing error' + * + * @category Errors + * @category generated + */ +export class ProgramInteractionDataParsingErrorError extends Error { + readonly code: number = 0x17b3 + readonly name: string = 'ProgramInteractionDataParsingError' + constructor() { + super( + 'Program interaction constraint failed: instruction data parsing error' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace(this, ProgramInteractionDataParsingErrorError) + } + } +} + +createErrorFromCodeLookup.set( + 0x17b3, + () => new ProgramInteractionDataParsingErrorError() +) +createErrorFromNameLookup.set( + 'ProgramInteractionDataParsingError', + () => new ProgramInteractionDataParsingErrorError() +) + +/** + * ProgramInteractionProgramIdMismatch: 'Program interaction constraint failed: program ID mismatch' + * + * @category Errors + * @category generated + */ +export class ProgramInteractionProgramIdMismatchError extends Error { + readonly code: number = 0x17b4 + readonly name: string = 'ProgramInteractionProgramIdMismatch' + constructor() { + super('Program interaction constraint failed: program ID mismatch') + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace(this, ProgramInteractionProgramIdMismatchError) + } + } +} + +createErrorFromCodeLookup.set( + 0x17b4, + () => new ProgramInteractionProgramIdMismatchError() +) +createErrorFromNameLookup.set( + 'ProgramInteractionProgramIdMismatch', + () => new ProgramInteractionProgramIdMismatchError() +) + +/** + * ProgramInteractionAccountConstraintViolated: 'Program interaction constraint violation: account constraint' + * + * @category Errors + * @category generated + */ +export class ProgramInteractionAccountConstraintViolatedError extends Error { + readonly code: number = 0x17b5 + readonly name: string = 'ProgramInteractionAccountConstraintViolated' + constructor() { + super('Program interaction constraint violation: account constraint') + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + ProgramInteractionAccountConstraintViolatedError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17b5, + () => new ProgramInteractionAccountConstraintViolatedError() +) +createErrorFromNameLookup.set( + 'ProgramInteractionAccountConstraintViolated', + () => new ProgramInteractionAccountConstraintViolatedError() +) + +/** + * ProgramInteractionConstraintIndexOutOfBounds: 'Program interaction constraint violation: instruction constraint index out of bounds' + * + * @category Errors + * @category generated + */ +export class ProgramInteractionConstraintIndexOutOfBoundsError extends Error { + readonly code: number = 0x17b6 + readonly name: string = 'ProgramInteractionConstraintIndexOutOfBounds' + constructor() { + super( + 'Program interaction constraint violation: instruction constraint index out of bounds' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + ProgramInteractionConstraintIndexOutOfBoundsError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17b6, + () => new ProgramInteractionConstraintIndexOutOfBoundsError() +) +createErrorFromNameLookup.set( + 'ProgramInteractionConstraintIndexOutOfBounds', + () => new ProgramInteractionConstraintIndexOutOfBoundsError() +) + +/** + * ProgramInteractionInstructionCountMismatch: 'Program interaction constraint violation: instruction count mismatch' + * + * @category Errors + * @category generated + */ +export class ProgramInteractionInstructionCountMismatchError extends Error { + readonly code: number = 0x17b7 + readonly name: string = 'ProgramInteractionInstructionCountMismatch' + constructor() { + super( + 'Program interaction constraint violation: instruction count mismatch' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + ProgramInteractionInstructionCountMismatchError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17b7, + () => new ProgramInteractionInstructionCountMismatchError() +) +createErrorFromNameLookup.set( + 'ProgramInteractionInstructionCountMismatch', + () => new ProgramInteractionInstructionCountMismatchError() +) + +/** + * ProgramInteractionInsufficientLamportAllowance: 'Program interaction constraint violation: insufficient remaining lamport allowance' + * + * @category Errors + * @category generated + */ +export class ProgramInteractionInsufficientLamportAllowanceError extends Error { + readonly code: number = 0x17b8 + readonly name: string = 'ProgramInteractionInsufficientLamportAllowance' + constructor() { + super( + 'Program interaction constraint violation: insufficient remaining lamport allowance' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + ProgramInteractionInsufficientLamportAllowanceError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17b8, + () => new ProgramInteractionInsufficientLamportAllowanceError() +) +createErrorFromNameLookup.set( + 'ProgramInteractionInsufficientLamportAllowance', + () => new ProgramInteractionInsufficientLamportAllowanceError() +) + +/** + * ProgramInteractionInsufficientTokenAllowance: 'Program interaction constraint violation: insufficient remaining token allowance' + * + * @category Errors + * @category generated + */ +export class ProgramInteractionInsufficientTokenAllowanceError extends Error { + readonly code: number = 0x17b9 + readonly name: string = 'ProgramInteractionInsufficientTokenAllowance' + constructor() { + super( + 'Program interaction constraint violation: insufficient remaining token allowance' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + ProgramInteractionInsufficientTokenAllowanceError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17b9, + () => new ProgramInteractionInsufficientTokenAllowanceError() +) +createErrorFromNameLookup.set( + 'ProgramInteractionInsufficientTokenAllowance', + () => new ProgramInteractionInsufficientTokenAllowanceError() +) + +/** + * ProgramInteractionModifiedIllegalBalance: 'Program interaction constraint violation: modified illegal balance' + * + * @category Errors + * @category generated + */ +export class ProgramInteractionModifiedIllegalBalanceError extends Error { + readonly code: number = 0x17ba + readonly name: string = 'ProgramInteractionModifiedIllegalBalance' + constructor() { + super('Program interaction constraint violation: modified illegal balance') + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + ProgramInteractionModifiedIllegalBalanceError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17ba, + () => new ProgramInteractionModifiedIllegalBalanceError() +) +createErrorFromNameLookup.set( + 'ProgramInteractionModifiedIllegalBalance', + () => new ProgramInteractionModifiedIllegalBalanceError() +) + +/** + * ProgramInteractionIllegalTokenAccountModification: 'Program interaction constraint violation: illegal token account modification' + * + * @category Errors + * @category generated + */ +export class ProgramInteractionIllegalTokenAccountModificationError extends Error { + readonly code: number = 0x17bb + readonly name: string = 'ProgramInteractionIllegalTokenAccountModification' + constructor() { + super( + 'Program interaction constraint violation: illegal token account modification' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + ProgramInteractionIllegalTokenAccountModificationError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17bb, + () => new ProgramInteractionIllegalTokenAccountModificationError() +) +createErrorFromNameLookup.set( + 'ProgramInteractionIllegalTokenAccountModification', + () => new ProgramInteractionIllegalTokenAccountModificationError() +) + +/** + * ProgramInteractionDuplicateSpendingLimit: 'Program interaction invariant violation: duplicate spending limit for the same mint' + * + * @category Errors + * @category generated + */ +export class ProgramInteractionDuplicateSpendingLimitError extends Error { + readonly code: number = 0x17bc + readonly name: string = 'ProgramInteractionDuplicateSpendingLimit' + constructor() { + super( + 'Program interaction invariant violation: duplicate spending limit for the same mint' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + ProgramInteractionDuplicateSpendingLimitError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17bc, + () => new ProgramInteractionDuplicateSpendingLimitError() +) +createErrorFromNameLookup.set( + 'ProgramInteractionDuplicateSpendingLimit', + () => new ProgramInteractionDuplicateSpendingLimitError() +) + +/** + * ProgramInteractionTooManyInstructionConstraints: 'Program interaction constraint violation: too many instruction constraints. Max is 20' + * + * @category Errors + * @category generated + */ +export class ProgramInteractionTooManyInstructionConstraintsError extends Error { + readonly code: number = 0x17bd + readonly name: string = 'ProgramInteractionTooManyInstructionConstraints' + constructor() { + super( + 'Program interaction constraint violation: too many instruction constraints. Max is 20' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + ProgramInteractionTooManyInstructionConstraintsError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17bd, + () => new ProgramInteractionTooManyInstructionConstraintsError() +) +createErrorFromNameLookup.set( + 'ProgramInteractionTooManyInstructionConstraints', + () => new ProgramInteractionTooManyInstructionConstraintsError() +) + +/** + * ProgramInteractionTooManySpendingLimits: 'Program interaction constraint violation: too many spending limits. Max is 10' + * + * @category Errors + * @category generated + */ +export class ProgramInteractionTooManySpendingLimitsError extends Error { + readonly code: number = 0x17be + readonly name: string = 'ProgramInteractionTooManySpendingLimits' + constructor() { + super( + 'Program interaction constraint violation: too many spending limits. Max is 10' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + ProgramInteractionTooManySpendingLimitsError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17be, + () => new ProgramInteractionTooManySpendingLimitsError() +) +createErrorFromNameLookup.set( + 'ProgramInteractionTooManySpendingLimits', + () => new ProgramInteractionTooManySpendingLimitsError() +) + +/** + * ProgramInteractionTemplateHookError: 'Program interaction hook violation: template hook error' + * + * @category Errors + * @category generated + */ +export class ProgramInteractionTemplateHookErrorError extends Error { + readonly code: number = 0x17bf + readonly name: string = 'ProgramInteractionTemplateHookError' + constructor() { + super('Program interaction hook violation: template hook error') + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace(this, ProgramInteractionTemplateHookErrorError) + } + } +} + +createErrorFromCodeLookup.set( + 0x17bf, + () => new ProgramInteractionTemplateHookErrorError() +) +createErrorFromNameLookup.set( + 'ProgramInteractionTemplateHookError', + () => new ProgramInteractionTemplateHookErrorError() +) + +/** + * ProgramInteractionHookAuthorityCannotBePartOfHookAccounts: 'Program interaction hook violation: hook authority cannot be part of hook accounts' + * + * @category Errors + * @category generated + */ +export class ProgramInteractionHookAuthorityCannotBePartOfHookAccountsError extends Error { + readonly code: number = 0x17c0 + readonly name: string = + 'ProgramInteractionHookAuthorityCannotBePartOfHookAccounts' + constructor() { + super( + 'Program interaction hook violation: hook authority cannot be part of hook accounts' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + ProgramInteractionHookAuthorityCannotBePartOfHookAccountsError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17c0, + () => new ProgramInteractionHookAuthorityCannotBePartOfHookAccountsError() +) +createErrorFromNameLookup.set( + 'ProgramInteractionHookAuthorityCannotBePartOfHookAccounts', + () => new ProgramInteractionHookAuthorityCannotBePartOfHookAccountsError() +) + +/** + * SpendingLimitNotActive: 'Spending limit is not active' + * + * @category Errors + * @category generated + */ +export class SpendingLimitNotActiveError extends Error { + readonly code: number = 0x17c1 + readonly name: string = 'SpendingLimitNotActive' + constructor() { + super('Spending limit is not active') + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace(this, SpendingLimitNotActiveError) + } + } +} + +createErrorFromCodeLookup.set(0x17c1, () => new SpendingLimitNotActiveError()) +createErrorFromNameLookup.set( + 'SpendingLimitNotActive', + () => new SpendingLimitNotActiveError() +) + +/** + * SpendingLimitExpired: 'Spending limit is expired' + * + * @category Errors + * @category generated + */ +export class SpendingLimitExpiredError extends Error { + readonly code: number = 0x17c2 + readonly name: string = 'SpendingLimitExpired' + constructor() { + super('Spending limit is expired') + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace(this, SpendingLimitExpiredError) + } + } +} + +createErrorFromCodeLookup.set(0x17c2, () => new SpendingLimitExpiredError()) +createErrorFromNameLookup.set( + 'SpendingLimitExpired', + () => new SpendingLimitExpiredError() +) + +/** + * SpendingLimitPolicyInvariantAccumulateUnused: 'Spending limit policy invariant violation: usage state cannot be Some() if accumulate_unused is true' + * + * @category Errors + * @category generated + */ +export class SpendingLimitPolicyInvariantAccumulateUnusedError extends Error { + readonly code: number = 0x17c3 + readonly name: string = 'SpendingLimitPolicyInvariantAccumulateUnused' + constructor() { + super( + 'Spending limit policy invariant violation: usage state cannot be Some() if accumulate_unused is true' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + SpendingLimitPolicyInvariantAccumulateUnusedError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17c3, + () => new SpendingLimitPolicyInvariantAccumulateUnusedError() +) +createErrorFromNameLookup.set( + 'SpendingLimitPolicyInvariantAccumulateUnused', + () => new SpendingLimitPolicyInvariantAccumulateUnusedError() +) + +/** + * SpendingLimitViolatesExactQuantityConstraint: 'Amount violates exact quantity constraint' + * + * @category Errors + * @category generated + */ +export class SpendingLimitViolatesExactQuantityConstraintError extends Error { + readonly code: number = 0x17c4 + readonly name: string = 'SpendingLimitViolatesExactQuantityConstraint' + constructor() { + super('Amount violates exact quantity constraint') + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + SpendingLimitViolatesExactQuantityConstraintError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17c4, + () => new SpendingLimitViolatesExactQuantityConstraintError() +) +createErrorFromNameLookup.set( + 'SpendingLimitViolatesExactQuantityConstraint', + () => new SpendingLimitViolatesExactQuantityConstraintError() +) + +/** + * SpendingLimitViolatesMaxPerUseConstraint: 'Amount violates max per use constraint' + * + * @category Errors + * @category generated + */ +export class SpendingLimitViolatesMaxPerUseConstraintError extends Error { + readonly code: number = 0x17c5 + readonly name: string = 'SpendingLimitViolatesMaxPerUseConstraint' + constructor() { + super('Amount violates max per use constraint') + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + SpendingLimitViolatesMaxPerUseConstraintError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17c5, + () => new SpendingLimitViolatesMaxPerUseConstraintError() +) +createErrorFromNameLookup.set( + 'SpendingLimitViolatesMaxPerUseConstraint', + () => new SpendingLimitViolatesMaxPerUseConstraintError() +) + +/** + * SpendingLimitInsufficientRemainingAmount: 'Spending limit is insufficient' + * + * @category Errors + * @category generated + */ +export class SpendingLimitInsufficientRemainingAmountError extends Error { + readonly code: number = 0x17c6 + readonly name: string = 'SpendingLimitInsufficientRemainingAmount' + constructor() { + super('Spending limit is insufficient') + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + SpendingLimitInsufficientRemainingAmountError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17c6, + () => new SpendingLimitInsufficientRemainingAmountError() +) +createErrorFromNameLookup.set( + 'SpendingLimitInsufficientRemainingAmount', + () => new SpendingLimitInsufficientRemainingAmountError() +) + +/** + * SpendingLimitInvariantMaxPerPeriodZero: 'Spending limit invariant violation: max per period must be non-zero' + * + * @category Errors + * @category generated + */ +export class SpendingLimitInvariantMaxPerPeriodZeroError extends Error { + readonly code: number = 0x17c7 + readonly name: string = 'SpendingLimitInvariantMaxPerPeriodZero' + constructor() { + super('Spending limit invariant violation: max per period must be non-zero') + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace(this, SpendingLimitInvariantMaxPerPeriodZeroError) + } + } +} + +createErrorFromCodeLookup.set( + 0x17c7, + () => new SpendingLimitInvariantMaxPerPeriodZeroError() +) +createErrorFromNameLookup.set( + 'SpendingLimitInvariantMaxPerPeriodZero', + () => new SpendingLimitInvariantMaxPerPeriodZeroError() +) + +/** + * SpendingLimitInvariantStartTimePositive: 'Spending limit invariant violation: start time must be positive' + * + * @category Errors + * @category generated + */ +export class SpendingLimitInvariantStartTimePositiveError extends Error { + readonly code: number = 0x17c8 + readonly name: string = 'SpendingLimitInvariantStartTimePositive' + constructor() { + super('Spending limit invariant violation: start time must be positive') + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + SpendingLimitInvariantStartTimePositiveError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17c8, + () => new SpendingLimitInvariantStartTimePositiveError() +) +createErrorFromNameLookup.set( + 'SpendingLimitInvariantStartTimePositive', + () => new SpendingLimitInvariantStartTimePositiveError() +) + +/** + * SpendingLimitInvariantExpirationSmallerThanStart: 'Spending limit invariant violation: expiration must be greater than start' + * + * @category Errors + * @category generated + */ +export class SpendingLimitInvariantExpirationSmallerThanStartError extends Error { + readonly code: number = 0x17c9 + readonly name: string = 'SpendingLimitInvariantExpirationSmallerThanStart' + constructor() { + super( + 'Spending limit invariant violation: expiration must be greater than start' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + SpendingLimitInvariantExpirationSmallerThanStartError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17c9, + () => new SpendingLimitInvariantExpirationSmallerThanStartError() +) +createErrorFromNameLookup.set( + 'SpendingLimitInvariantExpirationSmallerThanStart', + () => new SpendingLimitInvariantExpirationSmallerThanStartError() +) + +/** + * SpendingLimitInvariantOverflowEnabledMustHaveExpiration: 'Spending limit invariant violation: overflow enabled must have expiration' + * + * @category Errors + * @category generated + */ +export class SpendingLimitInvariantOverflowEnabledMustHaveExpirationError extends Error { + readonly code: number = 0x17ca + readonly name: string = + 'SpendingLimitInvariantOverflowEnabledMustHaveExpiration' + constructor() { + super( + 'Spending limit invariant violation: overflow enabled must have expiration' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + SpendingLimitInvariantOverflowEnabledMustHaveExpirationError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17ca, + () => new SpendingLimitInvariantOverflowEnabledMustHaveExpirationError() +) +createErrorFromNameLookup.set( + 'SpendingLimitInvariantOverflowEnabledMustHaveExpiration', + () => new SpendingLimitInvariantOverflowEnabledMustHaveExpirationError() +) + +/** + * SpendingLimitInvariantOneTimePeriodCannotHaveOverflowEnabled: 'Spending limit invariant violation: one time period cannot have overflow enabled' + * + * @category Errors + * @category generated + */ +export class SpendingLimitInvariantOneTimePeriodCannotHaveOverflowEnabledError extends Error { + readonly code: number = 0x17cb + readonly name: string = + 'SpendingLimitInvariantOneTimePeriodCannotHaveOverflowEnabled' + constructor() { + super( + 'Spending limit invariant violation: one time period cannot have overflow enabled' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + SpendingLimitInvariantOneTimePeriodCannotHaveOverflowEnabledError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17cb, + () => new SpendingLimitInvariantOneTimePeriodCannotHaveOverflowEnabledError() +) +createErrorFromNameLookup.set( + 'SpendingLimitInvariantOneTimePeriodCannotHaveOverflowEnabled', + () => new SpendingLimitInvariantOneTimePeriodCannotHaveOverflowEnabledError() +) + +/** + * SpendingLimitInvariantOverflowRemainingAmountGreaterThanMaxAmount: 'Spending limit invariant violation: remaining amount must be less than max amount' + * + * @category Errors + * @category generated + */ +export class SpendingLimitInvariantOverflowRemainingAmountGreaterThanMaxAmountError extends Error { + readonly code: number = 0x17cc + readonly name: string = + 'SpendingLimitInvariantOverflowRemainingAmountGreaterThanMaxAmount' + constructor() { + super( + 'Spending limit invariant violation: remaining amount must be less than max amount' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + SpendingLimitInvariantOverflowRemainingAmountGreaterThanMaxAmountError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17cc, + () => + new SpendingLimitInvariantOverflowRemainingAmountGreaterThanMaxAmountError() +) +createErrorFromNameLookup.set( + 'SpendingLimitInvariantOverflowRemainingAmountGreaterThanMaxAmount', + () => + new SpendingLimitInvariantOverflowRemainingAmountGreaterThanMaxAmountError() +) + +/** + * SpendingLimitInvariantRemainingAmountGreaterThanMaxPerPeriod: 'Spending limit invariant violation: remaining amount must be less than or equal to max per period' + * + * @category Errors + * @category generated + */ +export class SpendingLimitInvariantRemainingAmountGreaterThanMaxPerPeriodError extends Error { + readonly code: number = 0x17cd + readonly name: string = + 'SpendingLimitInvariantRemainingAmountGreaterThanMaxPerPeriod' + constructor() { + super( + 'Spending limit invariant violation: remaining amount must be less than or equal to max per period' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + SpendingLimitInvariantRemainingAmountGreaterThanMaxPerPeriodError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17cd, + () => new SpendingLimitInvariantRemainingAmountGreaterThanMaxPerPeriodError() +) +createErrorFromNameLookup.set( + 'SpendingLimitInvariantRemainingAmountGreaterThanMaxPerPeriod', + () => new SpendingLimitInvariantRemainingAmountGreaterThanMaxPerPeriodError() +) + +/** + * SpendingLimitInvariantExactQuantityMaxPerUseZero: 'Spending limit invariant violation: exact quantity must have max per use non-zero' + * + * @category Errors + * @category generated + */ +export class SpendingLimitInvariantExactQuantityMaxPerUseZeroError extends Error { + readonly code: number = 0x17ce + readonly name: string = 'SpendingLimitInvariantExactQuantityMaxPerUseZero' + constructor() { + super( + 'Spending limit invariant violation: exact quantity must have max per use non-zero' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + SpendingLimitInvariantExactQuantityMaxPerUseZeroError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17ce, + () => new SpendingLimitInvariantExactQuantityMaxPerUseZeroError() +) +createErrorFromNameLookup.set( + 'SpendingLimitInvariantExactQuantityMaxPerUseZero', + () => new SpendingLimitInvariantExactQuantityMaxPerUseZeroError() +) + +/** + * SpendingLimitInvariantMaxPerUseGreaterThanMaxPerPeriod: 'Spending limit invariant violation: max per use must be less than or equal to max per period' + * + * @category Errors + * @category generated + */ +export class SpendingLimitInvariantMaxPerUseGreaterThanMaxPerPeriodError extends Error { + readonly code: number = 0x17cf + readonly name: string = + 'SpendingLimitInvariantMaxPerUseGreaterThanMaxPerPeriod' + constructor() { + super( + 'Spending limit invariant violation: max per use must be less than or equal to max per period' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + SpendingLimitInvariantMaxPerUseGreaterThanMaxPerPeriodError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17cf, + () => new SpendingLimitInvariantMaxPerUseGreaterThanMaxPerPeriodError() +) +createErrorFromNameLookup.set( + 'SpendingLimitInvariantMaxPerUseGreaterThanMaxPerPeriod', + () => new SpendingLimitInvariantMaxPerUseGreaterThanMaxPerPeriodError() +) + +/** + * SpendingLimitInvariantCustomPeriodNegative: 'Spending limit invariant violation: custom period must be positive' + * + * @category Errors + * @category generated + */ +export class SpendingLimitInvariantCustomPeriodNegativeError extends Error { + readonly code: number = 0x17d0 + readonly name: string = 'SpendingLimitInvariantCustomPeriodNegative' + constructor() { + super('Spending limit invariant violation: custom period must be positive') + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + SpendingLimitInvariantCustomPeriodNegativeError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17d0, + () => new SpendingLimitInvariantCustomPeriodNegativeError() +) +createErrorFromNameLookup.set( + 'SpendingLimitInvariantCustomPeriodNegative', + () => new SpendingLimitInvariantCustomPeriodNegativeError() +) + +/** + * SpendingLimitPolicyInvariantDuplicateDestinations: 'Spending limit policy invariant violation: cannot have duplicate destinations for the same mint' + * + * @category Errors + * @category generated + */ +export class SpendingLimitPolicyInvariantDuplicateDestinationsError extends Error { + readonly code: number = 0x17d1 + readonly name: string = 'SpendingLimitPolicyInvariantDuplicateDestinations' + constructor() { + super( + 'Spending limit policy invariant violation: cannot have duplicate destinations for the same mint' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + SpendingLimitPolicyInvariantDuplicateDestinationsError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17d1, + () => new SpendingLimitPolicyInvariantDuplicateDestinationsError() +) +createErrorFromNameLookup.set( + 'SpendingLimitPolicyInvariantDuplicateDestinations', + () => new SpendingLimitPolicyInvariantDuplicateDestinationsError() +) + +/** + * SpendingLimitInvariantLastResetOutOfBounds: 'Spending limit invariant violation: last reset must be between start and expiration' + * + * @category Errors + * @category generated + */ +export class SpendingLimitInvariantLastResetOutOfBoundsError extends Error { + readonly code: number = 0x17d2 + readonly name: string = 'SpendingLimitInvariantLastResetOutOfBounds' + constructor() { + super( + 'Spending limit invariant violation: last reset must be between start and expiration' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + SpendingLimitInvariantLastResetOutOfBoundsError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17d2, + () => new SpendingLimitInvariantLastResetOutOfBoundsError() +) +createErrorFromNameLookup.set( + 'SpendingLimitInvariantLastResetOutOfBounds', + () => new SpendingLimitInvariantLastResetOutOfBoundsError() +) + +/** + * SpendingLimitInvariantLastResetSmallerThanStart: 'Spending limit invariant violation: last reset must be greater than start' + * + * @category Errors + * @category generated + */ +export class SpendingLimitInvariantLastResetSmallerThanStartError extends Error { + readonly code: number = 0x17d3 + readonly name: string = 'SpendingLimitInvariantLastResetSmallerThanStart' + constructor() { + super( + 'Spending limit invariant violation: last reset must be greater than start' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + SpendingLimitInvariantLastResetSmallerThanStartError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17d3, + () => new SpendingLimitInvariantLastResetSmallerThanStartError() +) +createErrorFromNameLookup.set( + 'SpendingLimitInvariantLastResetSmallerThanStart', + () => new SpendingLimitInvariantLastResetSmallerThanStartError() +) + +/** + * InternalFundTransferPolicyInvariantSourceAccountIndexNotAllowed: 'Internal fund transfer policy invariant violation: source account index is not allowed' + * + * @category Errors + * @category generated + */ +export class InternalFundTransferPolicyInvariantSourceAccountIndexNotAllowedError extends Error { + readonly code: number = 0x17d4 + readonly name: string = + 'InternalFundTransferPolicyInvariantSourceAccountIndexNotAllowed' + constructor() { + super( + 'Internal fund transfer policy invariant violation: source account index is not allowed' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + InternalFundTransferPolicyInvariantSourceAccountIndexNotAllowedError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17d4, + () => + new InternalFundTransferPolicyInvariantSourceAccountIndexNotAllowedError() +) +createErrorFromNameLookup.set( + 'InternalFundTransferPolicyInvariantSourceAccountIndexNotAllowed', + () => + new InternalFundTransferPolicyInvariantSourceAccountIndexNotAllowedError() +) + +/** + * InternalFundTransferPolicyInvariantDestinationAccountIndexNotAllowed: 'Internal fund transfer policy invariant violation: destination account index is not allowed' + * + * @category Errors + * @category generated + */ +export class InternalFundTransferPolicyInvariantDestinationAccountIndexNotAllowedError extends Error { + readonly code: number = 0x17d5 + readonly name: string = + 'InternalFundTransferPolicyInvariantDestinationAccountIndexNotAllowed' + constructor() { + super( + 'Internal fund transfer policy invariant violation: destination account index is not allowed' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + InternalFundTransferPolicyInvariantDestinationAccountIndexNotAllowedError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17d5, + () => + new InternalFundTransferPolicyInvariantDestinationAccountIndexNotAllowedError() +) +createErrorFromNameLookup.set( + 'InternalFundTransferPolicyInvariantDestinationAccountIndexNotAllowed', + () => + new InternalFundTransferPolicyInvariantDestinationAccountIndexNotAllowedError() +) + +/** + * InternalFundTransferPolicyInvariantSourceAndDestinationCannotBeTheSame: 'Internal fund transfer policy invariant violation: source and destination cannot be the same' + * + * @category Errors + * @category generated + */ +export class InternalFundTransferPolicyInvariantSourceAndDestinationCannotBeTheSameError extends Error { + readonly code: number = 0x17d6 + readonly name: string = + 'InternalFundTransferPolicyInvariantSourceAndDestinationCannotBeTheSame' + constructor() { + super( + 'Internal fund transfer policy invariant violation: source and destination cannot be the same' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + InternalFundTransferPolicyInvariantSourceAndDestinationCannotBeTheSameError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17d6, + () => + new InternalFundTransferPolicyInvariantSourceAndDestinationCannotBeTheSameError() +) +createErrorFromNameLookup.set( + 'InternalFundTransferPolicyInvariantSourceAndDestinationCannotBeTheSame', + () => + new InternalFundTransferPolicyInvariantSourceAndDestinationCannotBeTheSameError() +) + +/** + * InternalFundTransferPolicyInvariantMintNotAllowed: 'Internal fund transfer policy invariant violation: mint is not allowed' + * + * @category Errors + * @category generated + */ +export class InternalFundTransferPolicyInvariantMintNotAllowedError extends Error { + readonly code: number = 0x17d7 + readonly name: string = 'InternalFundTransferPolicyInvariantMintNotAllowed' + constructor() { + super( + 'Internal fund transfer policy invariant violation: mint is not allowed' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + InternalFundTransferPolicyInvariantMintNotAllowedError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17d7, + () => new InternalFundTransferPolicyInvariantMintNotAllowedError() +) +createErrorFromNameLookup.set( + 'InternalFundTransferPolicyInvariantMintNotAllowed', + () => new InternalFundTransferPolicyInvariantMintNotAllowedError() +) + +/** + * InternalFundTransferPolicyInvariantAmountZero: 'Internal fund transfer policy invariant violation: amount must be greater than 0' + * + * @category Errors + * @category generated + */ +export class InternalFundTransferPolicyInvariantAmountZeroError extends Error { + readonly code: number = 0x17d8 + readonly name: string = 'InternalFundTransferPolicyInvariantAmountZero' + constructor() { + super( + 'Internal fund transfer policy invariant violation: amount must be greater than 0' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + InternalFundTransferPolicyInvariantAmountZeroError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17d8, + () => new InternalFundTransferPolicyInvariantAmountZeroError() +) +createErrorFromNameLookup.set( + 'InternalFundTransferPolicyInvariantAmountZero', + () => new InternalFundTransferPolicyInvariantAmountZeroError() +) + +/** + * InternalFundTransferPolicyInvariantDuplicateMints: 'Internal fund transfer policy invariant violation: cannot have duplicate mints' + * + * @category Errors + * @category generated + */ +export class InternalFundTransferPolicyInvariantDuplicateMintsError extends Error { + readonly code: number = 0x17d9 + readonly name: string = 'InternalFundTransferPolicyInvariantDuplicateMints' + constructor() { + super( + 'Internal fund transfer policy invariant violation: cannot have duplicate mints' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + InternalFundTransferPolicyInvariantDuplicateMintsError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17d9, + () => new InternalFundTransferPolicyInvariantDuplicateMintsError() +) +createErrorFromNameLookup.set( + 'InternalFundTransferPolicyInvariantDuplicateMints', + () => new InternalFundTransferPolicyInvariantDuplicateMintsError() +) + +/** + * ConsensusAccountNotSettings: 'Consensus account is not a settings' + * + * @category Errors + * @category generated + */ +export class ConsensusAccountNotSettingsError extends Error { + readonly code: number = 0x17da + readonly name: string = 'ConsensusAccountNotSettings' + constructor() { + super('Consensus account is not a settings') + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace(this, ConsensusAccountNotSettingsError) + } + } +} + +createErrorFromCodeLookup.set( + 0x17da, + () => new ConsensusAccountNotSettingsError() +) +createErrorFromNameLookup.set( + 'ConsensusAccountNotSettings', + () => new ConsensusAccountNotSettingsError() +) + +/** + * ConsensusAccountNotPolicy: 'Consensus account is not a policy' + * + * @category Errors + * @category generated + */ +export class ConsensusAccountNotPolicyError extends Error { + readonly code: number = 0x17db + readonly name: string = 'ConsensusAccountNotPolicy' + constructor() { + super('Consensus account is not a policy') + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace(this, ConsensusAccountNotPolicyError) + } + } +} + +createErrorFromCodeLookup.set( + 0x17db, + () => new ConsensusAccountNotPolicyError() +) +createErrorFromNameLookup.set( + 'ConsensusAccountNotPolicy', + () => new ConsensusAccountNotPolicyError() +) + +/** + * SettingsChangePolicyActionsMustBeNonZero: 'Settings change policy invariant violation: actions must be non-zero' + * + * @category Errors + * @category generated + */ +export class SettingsChangePolicyActionsMustBeNonZeroError extends Error { + readonly code: number = 0x17dc + readonly name: string = 'SettingsChangePolicyActionsMustBeNonZero' + constructor() { + super( + 'Settings change policy invariant violation: actions must be non-zero' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + SettingsChangePolicyActionsMustBeNonZeroError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17dc, + () => new SettingsChangePolicyActionsMustBeNonZeroError() +) +createErrorFromNameLookup.set( + 'SettingsChangePolicyActionsMustBeNonZero', + () => new SettingsChangePolicyActionsMustBeNonZeroError() +) + +/** + * SettingsChangeInvalidSettingsKey: 'Settings change policy violation: submitted settings account must match policy settings key' + * + * @category Errors + * @category generated + */ +export class SettingsChangeInvalidSettingsKeyError extends Error { + readonly code: number = 0x17dd + readonly name: string = 'SettingsChangeInvalidSettingsKey' + constructor() { + super( + 'Settings change policy violation: submitted settings account must match policy settings key' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace(this, SettingsChangeInvalidSettingsKeyError) + } + } +} + +createErrorFromCodeLookup.set( + 0x17dd, + () => new SettingsChangeInvalidSettingsKeyError() +) +createErrorFromNameLookup.set( + 'SettingsChangeInvalidSettingsKey', + () => new SettingsChangeInvalidSettingsKeyError() +) + +/** + * SettingsChangeInvalidSettingsAccount: 'Settings change policy violation: submitted settings account must be writable' + * + * @category Errors + * @category generated + */ +export class SettingsChangeInvalidSettingsAccountError extends Error { + readonly code: number = 0x17de + readonly name: string = 'SettingsChangeInvalidSettingsAccount' + constructor() { + super( + 'Settings change policy violation: submitted settings account must be writable' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace(this, SettingsChangeInvalidSettingsAccountError) + } + } +} + +createErrorFromCodeLookup.set( + 0x17de, + () => new SettingsChangeInvalidSettingsAccountError() +) +createErrorFromNameLookup.set( + 'SettingsChangeInvalidSettingsAccount', + () => new SettingsChangeInvalidSettingsAccountError() +) + +/** + * SettingsChangeInvalidRentPayer: 'Settings change policy violation: rent payer must be writable and signer' + * + * @category Errors + * @category generated + */ +export class SettingsChangeInvalidRentPayerError extends Error { + readonly code: number = 0x17df + readonly name: string = 'SettingsChangeInvalidRentPayer' + constructor() { + super( + 'Settings change policy violation: rent payer must be writable and signer' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace(this, SettingsChangeInvalidRentPayerError) + } + } +} + +createErrorFromCodeLookup.set( + 0x17df, + () => new SettingsChangeInvalidRentPayerError() +) +createErrorFromNameLookup.set( + 'SettingsChangeInvalidRentPayer', + () => new SettingsChangeInvalidRentPayerError() +) + +/** + * SettingsChangeInvalidSystemProgram: 'Settings change policy violation: system program must be the system program' + * + * @category Errors + * @category generated + */ +export class SettingsChangeInvalidSystemProgramError extends Error { + readonly code: number = 0x17e0 + readonly name: string = 'SettingsChangeInvalidSystemProgram' + constructor() { + super( + 'Settings change policy violation: system program must be the system program' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace(this, SettingsChangeInvalidSystemProgramError) + } + } +} + +createErrorFromCodeLookup.set( + 0x17e0, + () => new SettingsChangeInvalidSystemProgramError() +) +createErrorFromNameLookup.set( + 'SettingsChangeInvalidSystemProgram', + () => new SettingsChangeInvalidSystemProgramError() +) + +/** + * SettingsChangeAddSignerViolation: 'Settings change policy violation: signer does not match allowed signer' + * + * @category Errors + * @category generated + */ +export class SettingsChangeAddSignerViolationError extends Error { + readonly code: number = 0x17e1 + readonly name: string = 'SettingsChangeAddSignerViolation' + constructor() { + super( + 'Settings change policy violation: signer does not match allowed signer' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace(this, SettingsChangeAddSignerViolationError) + } + } +} + +createErrorFromCodeLookup.set( + 0x17e1, + () => new SettingsChangeAddSignerViolationError() +) +createErrorFromNameLookup.set( + 'SettingsChangeAddSignerViolation', + () => new SettingsChangeAddSignerViolationError() +) + +/** + * SettingsChangeAddSignerPermissionsViolation: 'Settings change policy violation: signer permissions does not match allowed signer permissions' + * + * @category Errors + * @category generated + */ +export class SettingsChangeAddSignerPermissionsViolationError extends Error { + readonly code: number = 0x17e2 + readonly name: string = 'SettingsChangeAddSignerPermissionsViolation' + constructor() { + super( + 'Settings change policy violation: signer permissions does not match allowed signer permissions' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + SettingsChangeAddSignerPermissionsViolationError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17e2, + () => new SettingsChangeAddSignerPermissionsViolationError() +) +createErrorFromNameLookup.set( + 'SettingsChangeAddSignerPermissionsViolation', + () => new SettingsChangeAddSignerPermissionsViolationError() +) + +/** + * SettingsChangeRemoveSignerViolation: 'Settings change policy violation: signer removal does not mach allowed signer removal' + * + * @category Errors + * @category generated + */ +export class SettingsChangeRemoveSignerViolationError extends Error { + readonly code: number = 0x17e3 + readonly name: string = 'SettingsChangeRemoveSignerViolation' + constructor() { + super( + 'Settings change policy violation: signer removal does not mach allowed signer removal' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace(this, SettingsChangeRemoveSignerViolationError) + } + } +} + +createErrorFromCodeLookup.set( + 0x17e3, + () => new SettingsChangeRemoveSignerViolationError() +) +createErrorFromNameLookup.set( + 'SettingsChangeRemoveSignerViolation', + () => new SettingsChangeRemoveSignerViolationError() +) + +/** + * SettingsChangeChangeTimelockViolation: 'Settings change policy violation: time lock does not match allowed time lock' + * + * @category Errors + * @category generated + */ +export class SettingsChangeChangeTimelockViolationError extends Error { + readonly code: number = 0x17e4 + readonly name: string = 'SettingsChangeChangeTimelockViolation' + constructor() { + super( + 'Settings change policy violation: time lock does not match allowed time lock' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace(this, SettingsChangeChangeTimelockViolationError) + } + } +} + +createErrorFromCodeLookup.set( + 0x17e4, + () => new SettingsChangeChangeTimelockViolationError() +) +createErrorFromNameLookup.set( + 'SettingsChangeChangeTimelockViolation', + () => new SettingsChangeChangeTimelockViolationError() +) + +/** + * SettingsChangeActionMismatch: 'Settings change policy violation: action does not match allowed action' + * + * @category Errors + * @category generated + */ +export class SettingsChangeActionMismatchError extends Error { + readonly code: number = 0x17e5 + readonly name: string = 'SettingsChangeActionMismatch' + constructor() { + super( + 'Settings change policy violation: action does not match allowed action' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace(this, SettingsChangeActionMismatchError) + } + } +} + +createErrorFromCodeLookup.set( + 0x17e5, + () => new SettingsChangeActionMismatchError() +) +createErrorFromNameLookup.set( + 'SettingsChangeActionMismatch', + () => new SettingsChangeActionMismatchError() +) + +/** + * SettingsChangePolicyInvariantDuplicateActions: 'Settings change policy invariant violation: cannot have duplicate actions' + * + * @category Errors + * @category generated + */ +export class SettingsChangePolicyInvariantDuplicateActionsError extends Error { + readonly code: number = 0x17e6 + readonly name: string = 'SettingsChangePolicyInvariantDuplicateActions' + constructor() { + super( + 'Settings change policy invariant violation: cannot have duplicate actions' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + SettingsChangePolicyInvariantDuplicateActionsError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17e6, + () => new SettingsChangePolicyInvariantDuplicateActionsError() +) +createErrorFromNameLookup.set( + 'SettingsChangePolicyInvariantDuplicateActions', + () => new SettingsChangePolicyInvariantDuplicateActionsError() +) + +/** + * SettingsChangePolicyInvariantActionIndicesActionsLengthMismatch: 'Settings change policy invariant violation: action indices must match actions length' + * + * @category Errors + * @category generated + */ +export class SettingsChangePolicyInvariantActionIndicesActionsLengthMismatchError extends Error { + readonly code: number = 0x17e7 + readonly name: string = + 'SettingsChangePolicyInvariantActionIndicesActionsLengthMismatch' + constructor() { + super( + 'Settings change policy invariant violation: action indices must match actions length' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + SettingsChangePolicyInvariantActionIndicesActionsLengthMismatchError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17e7, + () => + new SettingsChangePolicyInvariantActionIndicesActionsLengthMismatchError() +) +createErrorFromNameLookup.set( + 'SettingsChangePolicyInvariantActionIndicesActionsLengthMismatch', + () => + new SettingsChangePolicyInvariantActionIndicesActionsLengthMismatchError() +) + +/** + * SettingsChangePolicyInvariantActionIndexOutOfBounds: 'Settings change policy invariant violation: action index out of bounds' + * + * @category Errors + * @category generated + */ +export class SettingsChangePolicyInvariantActionIndexOutOfBoundsError extends Error { + readonly code: number = 0x17e8 + readonly name: string = 'SettingsChangePolicyInvariantActionIndexOutOfBounds' + constructor() { + super( + 'Settings change policy invariant violation: action index out of bounds' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + SettingsChangePolicyInvariantActionIndexOutOfBoundsError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17e8, + () => new SettingsChangePolicyInvariantActionIndexOutOfBoundsError() +) +createErrorFromNameLookup.set( + 'SettingsChangePolicyInvariantActionIndexOutOfBounds', + () => new SettingsChangePolicyInvariantActionIndexOutOfBoundsError() +) + +/** + * PolicyNotActiveYet: 'Policy is not active yet' + * + * @category Errors + * @category generated + */ +export class PolicyNotActiveYetError extends Error { + readonly code: number = 0x17e9 + readonly name: string = 'PolicyNotActiveYet' + constructor() { + super('Policy is not active yet') + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace(this, PolicyNotActiveYetError) + } + } +} + +createErrorFromCodeLookup.set(0x17e9, () => new PolicyNotActiveYetError()) +createErrorFromNameLookup.set( + 'PolicyNotActiveYet', + () => new PolicyNotActiveYetError() +) + +/** + * PolicyInvariantInvalidExpiration: 'Policy invariant violation: invalid policy expiration' + * + * @category Errors + * @category generated + */ +export class PolicyInvariantInvalidExpirationError extends Error { + readonly code: number = 0x17ea + readonly name: string = 'PolicyInvariantInvalidExpiration' + constructor() { + super('Policy invariant violation: invalid policy expiration') + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace(this, PolicyInvariantInvalidExpirationError) + } + } +} + +createErrorFromCodeLookup.set( + 0x17ea, + () => new PolicyInvariantInvalidExpirationError() +) +createErrorFromNameLookup.set( + 'PolicyInvariantInvalidExpiration', + () => new PolicyInvariantInvalidExpirationError() +) + +/** + * PolicyExpirationViolationPolicySettingsKeyMismatch: 'Policy expiration violation: submitted settings key does not match policy settings key' + * + * @category Errors + * @category generated + */ +export class PolicyExpirationViolationPolicySettingsKeyMismatchError extends Error { + readonly code: number = 0x17eb + readonly name: string = 'PolicyExpirationViolationPolicySettingsKeyMismatch' + constructor() { + super( + 'Policy expiration violation: submitted settings key does not match policy settings key' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + PolicyExpirationViolationPolicySettingsKeyMismatchError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17eb, + () => new PolicyExpirationViolationPolicySettingsKeyMismatchError() +) +createErrorFromNameLookup.set( + 'PolicyExpirationViolationPolicySettingsKeyMismatch', + () => new PolicyExpirationViolationPolicySettingsKeyMismatchError() +) + +/** + * PolicyExpirationViolationSettingsAccountNotPresent: 'Policy expiration violation: state expiration requires the settings to be submitted' + * + * @category Errors + * @category generated + */ +export class PolicyExpirationViolationSettingsAccountNotPresentError extends Error { + readonly code: number = 0x17ec + readonly name: string = 'PolicyExpirationViolationSettingsAccountNotPresent' + constructor() { + super( + 'Policy expiration violation: state expiration requires the settings to be submitted' + ) + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + PolicyExpirationViolationSettingsAccountNotPresentError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17ec, + () => new PolicyExpirationViolationSettingsAccountNotPresentError() +) +createErrorFromNameLookup.set( + 'PolicyExpirationViolationSettingsAccountNotPresent', + () => new PolicyExpirationViolationSettingsAccountNotPresentError() +) + +/** + * PolicyExpirationViolationHashExpired: 'Policy expiration violation: state hash has expired' + * + * @category Errors + * @category generated + */ +export class PolicyExpirationViolationHashExpiredError extends Error { + readonly code: number = 0x17ed + readonly name: string = 'PolicyExpirationViolationHashExpired' + constructor() { + super('Policy expiration violation: state hash has expired') + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace(this, PolicyExpirationViolationHashExpiredError) + } + } +} + +createErrorFromCodeLookup.set( + 0x17ed, + () => new PolicyExpirationViolationHashExpiredError() +) +createErrorFromNameLookup.set( + 'PolicyExpirationViolationHashExpired', + () => new PolicyExpirationViolationHashExpiredError() +) + +/** + * PolicyExpirationViolationTimestampExpired: 'Policy expiration violation: timestamp has expired' + * + * @category Errors + * @category generated + */ +export class PolicyExpirationViolationTimestampExpiredError extends Error { + readonly code: number = 0x17ee + readonly name: string = 'PolicyExpirationViolationTimestampExpired' + constructor() { + super('Policy expiration violation: timestamp has expired') + if (typeof Error.captureStackTrace === 'function') { + Error.captureStackTrace( + this, + PolicyExpirationViolationTimestampExpiredError + ) + } + } +} + +createErrorFromCodeLookup.set( + 0x17ee, + () => new PolicyExpirationViolationTimestampExpiredError() +) +createErrorFromNameLookup.set( + 'PolicyExpirationViolationTimestampExpired', + () => new PolicyExpirationViolationTimestampExpiredError() +) + /** * Attempts to resolve a custom program error from the provided error code. * @category Errors diff --git a/sdk/smart-account/src/generated/instructions/approveProposal.ts b/sdk/smart-account/src/generated/instructions/approveProposal.ts index e932130..6f0f63d 100644 --- a/sdk/smart-account/src/generated/instructions/approveProposal.ts +++ b/sdk/smart-account/src/generated/instructions/approveProposal.ts @@ -39,18 +39,20 @@ export const approveProposalStruct = new beet.FixableBeetArgsStruct< /** * Accounts required by the _approveProposal_ instruction * - * @property [] settings + * @property [] consensusAccount * @property [_writable_, **signer**] signer * @property [_writable_] proposal + * @property [] program * @category Instructions * @category ApproveProposal * @category generated */ export type ApproveProposalInstructionAccounts = { - settings: web3.PublicKey + consensusAccount: web3.PublicKey signer: web3.PublicKey proposal: web3.PublicKey systemProgram?: web3.PublicKey + program: web3.PublicKey anchorRemainingAccounts?: web3.AccountMeta[] } @@ -82,7 +84,7 @@ export function createApproveProposalInstruction( }) const keys: web3.AccountMeta[] = [ { - pubkey: accounts.settings, + pubkey: accounts.consensusAccount, isWritable: false, isSigner: false, }, @@ -101,6 +103,11 @@ export function createApproveProposalInstruction( isWritable: false, isSigner: false, }, + { + pubkey: accounts.program, + isWritable: false, + isSigner: false, + }, ] if (accounts.anchorRemainingAccounts != null) { diff --git a/sdk/smart-account/src/generated/instructions/cancelProposal.ts b/sdk/smart-account/src/generated/instructions/cancelProposal.ts index 5fbf6bc..d63345b 100644 --- a/sdk/smart-account/src/generated/instructions/cancelProposal.ts +++ b/sdk/smart-account/src/generated/instructions/cancelProposal.ts @@ -39,18 +39,20 @@ export const cancelProposalStruct = new beet.FixableBeetArgsStruct< /** * Accounts required by the _cancelProposal_ instruction * - * @property [] settings + * @property [] consensusAccount * @property [_writable_, **signer**] signer * @property [_writable_] proposal + * @property [] program * @category Instructions * @category CancelProposal * @category generated */ export type CancelProposalInstructionAccounts = { - settings: web3.PublicKey + consensusAccount: web3.PublicKey signer: web3.PublicKey proposal: web3.PublicKey systemProgram?: web3.PublicKey + program: web3.PublicKey anchorRemainingAccounts?: web3.AccountMeta[] } @@ -82,7 +84,7 @@ export function createCancelProposalInstruction( }) const keys: web3.AccountMeta[] = [ { - pubkey: accounts.settings, + pubkey: accounts.consensusAccount, isWritable: false, isSigner: false, }, @@ -101,6 +103,11 @@ export function createCancelProposalInstruction( isWritable: false, isSigner: false, }, + { + pubkey: accounts.program, + isWritable: false, + isSigner: false, + }, ] if (accounts.anchorRemainingAccounts != null) { diff --git a/sdk/smart-account/src/generated/instructions/closeBatch.ts b/sdk/smart-account/src/generated/instructions/closeBatch.ts index 2def11e..bd94631 100644 --- a/sdk/smart-account/src/generated/instructions/closeBatch.ts +++ b/sdk/smart-account/src/generated/instructions/closeBatch.ts @@ -27,6 +27,7 @@ export const closeBatchStruct = new beet.BeetArgsStruct<{ * @property [_writable_] batch * @property [_writable_] proposalRentCollector * @property [_writable_] batchRentCollector + * @property [] program * @category Instructions * @category CloseBatch * @category generated @@ -38,6 +39,7 @@ export type CloseBatchInstructionAccounts = { proposalRentCollector: web3.PublicKey batchRentCollector: web3.PublicKey systemProgram?: web3.PublicKey + program: web3.PublicKey anchorRemainingAccounts?: web3.AccountMeta[] } @@ -91,6 +93,11 @@ export function createCloseBatchInstruction( isWritable: false, isSigner: false, }, + { + pubkey: accounts.program, + isWritable: false, + isSigner: false, + }, ] if (accounts.anchorRemainingAccounts != null) { diff --git a/sdk/smart-account/src/generated/instructions/closeEmptyPolicyTransaction.ts b/sdk/smart-account/src/generated/instructions/closeEmptyPolicyTransaction.ts new file mode 100644 index 0000000..e6005a5 --- /dev/null +++ b/sdk/smart-account/src/generated/instructions/closeEmptyPolicyTransaction.ts @@ -0,0 +1,123 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +import * as web3 from '@solana/web3.js' + +/** + * @category Instructions + * @category CloseEmptyPolicyTransaction + * @category generated + */ +export const closeEmptyPolicyTransactionStruct = new beet.BeetArgsStruct<{ + instructionDiscriminator: number[] /* size: 8 */ +}>( + [['instructionDiscriminator', beet.uniformFixedSizeArray(beet.u8, 8)]], + 'CloseEmptyPolicyTransactionInstructionArgs' +) +/** + * Accounts required by the _closeEmptyPolicyTransaction_ instruction + * + * @property [_writable_] programConfig + * @property [] emptyPolicy + * @property [_writable_] proposal + * @property [_writable_] transaction + * @property [_writable_] proposalRentCollector + * @property [_writable_] transactionRentCollector + * @property [] program + * @category Instructions + * @category CloseEmptyPolicyTransaction + * @category generated + */ +export type CloseEmptyPolicyTransactionInstructionAccounts = { + programConfig: web3.PublicKey + emptyPolicy: web3.PublicKey + proposal: web3.PublicKey + transaction: web3.PublicKey + proposalRentCollector: web3.PublicKey + transactionRentCollector: web3.PublicKey + systemProgram?: web3.PublicKey + program: web3.PublicKey + anchorRemainingAccounts?: web3.AccountMeta[] +} + +export const closeEmptyPolicyTransactionInstructionDiscriminator = [ + 183, 66, 199, 226, 42, 87, 146, 77, +] + +/** + * Creates a _CloseEmptyPolicyTransaction_ instruction. + * + * @param accounts that will be accessed while the instruction is processed + * @category Instructions + * @category CloseEmptyPolicyTransaction + * @category generated + */ +export function createCloseEmptyPolicyTransactionInstruction( + accounts: CloseEmptyPolicyTransactionInstructionAccounts, + programId = new web3.PublicKey('SMRTzfY6DfH5ik3TKiyLFfXexV8uSG3d2UksSCYdunG') +) { + const [data] = closeEmptyPolicyTransactionStruct.serialize({ + instructionDiscriminator: + closeEmptyPolicyTransactionInstructionDiscriminator, + }) + const keys: web3.AccountMeta[] = [ + { + pubkey: accounts.programConfig, + isWritable: true, + isSigner: false, + }, + { + pubkey: accounts.emptyPolicy, + isWritable: false, + isSigner: false, + }, + { + pubkey: accounts.proposal, + isWritable: true, + isSigner: false, + }, + { + pubkey: accounts.transaction, + isWritable: true, + isSigner: false, + }, + { + pubkey: accounts.proposalRentCollector, + isWritable: true, + isSigner: false, + }, + { + pubkey: accounts.transactionRentCollector, + isWritable: true, + isSigner: false, + }, + { + pubkey: accounts.systemProgram ?? web3.SystemProgram.programId, + isWritable: false, + isSigner: false, + }, + { + pubkey: accounts.program, + isWritable: false, + isSigner: false, + }, + ] + + if (accounts.anchorRemainingAccounts != null) { + for (const acc of accounts.anchorRemainingAccounts) { + keys.push(acc) + } + } + + const ix = new web3.TransactionInstruction({ + programId, + keys, + data, + }) + return ix +} diff --git a/sdk/smart-account/src/generated/instructions/closeSettingsTransaction.ts b/sdk/smart-account/src/generated/instructions/closeSettingsTransaction.ts index 01b0d97..9141fc1 100644 --- a/sdk/smart-account/src/generated/instructions/closeSettingsTransaction.ts +++ b/sdk/smart-account/src/generated/instructions/closeSettingsTransaction.ts @@ -27,6 +27,7 @@ export const closeSettingsTransactionStruct = new beet.BeetArgsStruct<{ * @property [_writable_] transaction * @property [_writable_] proposalRentCollector * @property [_writable_] transactionRentCollector + * @property [] program * @category Instructions * @category CloseSettingsTransaction * @category generated @@ -38,6 +39,7 @@ export type CloseSettingsTransactionInstructionAccounts = { proposalRentCollector: web3.PublicKey transactionRentCollector: web3.PublicKey systemProgram?: web3.PublicKey + program: web3.PublicKey anchorRemainingAccounts?: web3.AccountMeta[] } @@ -91,6 +93,11 @@ export function createCloseSettingsTransactionInstruction( isWritable: false, isSigner: false, }, + { + pubkey: accounts.program, + isWritable: false, + isSigner: false, + }, ] if (accounts.anchorRemainingAccounts != null) { diff --git a/sdk/smart-account/src/generated/instructions/closeTransaction.ts b/sdk/smart-account/src/generated/instructions/closeTransaction.ts index 20f00ab..6665a38 100644 --- a/sdk/smart-account/src/generated/instructions/closeTransaction.ts +++ b/sdk/smart-account/src/generated/instructions/closeTransaction.ts @@ -22,22 +22,24 @@ export const closeTransactionStruct = new beet.BeetArgsStruct<{ /** * Accounts required by the _closeTransaction_ instruction * - * @property [] settings + * @property [] consensusAccount * @property [_writable_] proposal * @property [_writable_] transaction * @property [_writable_] proposalRentCollector * @property [_writable_] transactionRentCollector + * @property [] program * @category Instructions * @category CloseTransaction * @category generated */ export type CloseTransactionInstructionAccounts = { - settings: web3.PublicKey + consensusAccount: web3.PublicKey proposal: web3.PublicKey transaction: web3.PublicKey proposalRentCollector: web3.PublicKey transactionRentCollector: web3.PublicKey systemProgram?: web3.PublicKey + program: web3.PublicKey anchorRemainingAccounts?: web3.AccountMeta[] } @@ -62,7 +64,7 @@ export function createCloseTransactionInstruction( }) const keys: web3.AccountMeta[] = [ { - pubkey: accounts.settings, + pubkey: accounts.consensusAccount, isWritable: false, isSigner: false, }, @@ -91,6 +93,11 @@ export function createCloseTransactionInstruction( isWritable: false, isSigner: false, }, + { + pubkey: accounts.program, + isWritable: false, + isSigner: false, + }, ] if (accounts.anchorRemainingAccounts != null) { diff --git a/sdk/smart-account/src/generated/instructions/closeTransactionBuffer.ts b/sdk/smart-account/src/generated/instructions/closeTransactionBuffer.ts index e488ef9..9f489d7 100644 --- a/sdk/smart-account/src/generated/instructions/closeTransactionBuffer.ts +++ b/sdk/smart-account/src/generated/instructions/closeTransactionBuffer.ts @@ -22,7 +22,7 @@ export const closeTransactionBufferStruct = new beet.BeetArgsStruct<{ /** * Accounts required by the _closeTransactionBuffer_ instruction * - * @property [] settings + * @property [] consensusAccount * @property [_writable_] transactionBuffer * @property [**signer**] creator * @category Instructions @@ -30,7 +30,7 @@ export const closeTransactionBufferStruct = new beet.BeetArgsStruct<{ * @category generated */ export type CloseTransactionBufferInstructionAccounts = { - settings: web3.PublicKey + consensusAccount: web3.PublicKey transactionBuffer: web3.PublicKey creator: web3.PublicKey anchorRemainingAccounts?: web3.AccountMeta[] @@ -57,7 +57,7 @@ export function createCloseTransactionBufferInstruction( }) const keys: web3.AccountMeta[] = [ { - pubkey: accounts.settings, + pubkey: accounts.consensusAccount, isWritable: false, isSigner: false, }, diff --git a/sdk/smart-account/src/generated/instructions/createProposal.ts b/sdk/smart-account/src/generated/instructions/createProposal.ts index 35e0efd..7115b57 100644 --- a/sdk/smart-account/src/generated/instructions/createProposal.ts +++ b/sdk/smart-account/src/generated/instructions/createProposal.ts @@ -39,20 +39,22 @@ export const createProposalStruct = new beet.BeetArgsStruct< /** * Accounts required by the _createProposal_ instruction * - * @property [] settings + * @property [] consensusAccount * @property [_writable_] proposal * @property [**signer**] creator * @property [_writable_, **signer**] rentPayer + * @property [] program * @category Instructions * @category CreateProposal * @category generated */ export type CreateProposalInstructionAccounts = { - settings: web3.PublicKey + consensusAccount: web3.PublicKey proposal: web3.PublicKey creator: web3.PublicKey rentPayer: web3.PublicKey systemProgram?: web3.PublicKey + program: web3.PublicKey anchorRemainingAccounts?: web3.AccountMeta[] } @@ -81,7 +83,7 @@ export function createCreateProposalInstruction( }) const keys: web3.AccountMeta[] = [ { - pubkey: accounts.settings, + pubkey: accounts.consensusAccount, isWritable: false, isSigner: false, }, @@ -105,6 +107,11 @@ export function createCreateProposalInstruction( isWritable: false, isSigner: false, }, + { + pubkey: accounts.program, + isWritable: false, + isSigner: false, + }, ] if (accounts.anchorRemainingAccounts != null) { diff --git a/sdk/smart-account/src/generated/instructions/createSettingsTransaction.ts b/sdk/smart-account/src/generated/instructions/createSettingsTransaction.ts index 6ef7bb1..26cfaf7 100644 --- a/sdk/smart-account/src/generated/instructions/createSettingsTransaction.ts +++ b/sdk/smart-account/src/generated/instructions/createSettingsTransaction.ts @@ -43,6 +43,7 @@ export const createSettingsTransactionStruct = new beet.FixableBeetArgsStruct< * @property [_writable_] transaction * @property [**signer**] creator * @property [_writable_, **signer**] rentPayer + * @property [] program * @category Instructions * @category CreateSettingsTransaction * @category generated @@ -53,6 +54,7 @@ export type CreateSettingsTransactionInstructionAccounts = { creator: web3.PublicKey rentPayer: web3.PublicKey systemProgram?: web3.PublicKey + program: web3.PublicKey anchorRemainingAccounts?: web3.AccountMeta[] } @@ -105,6 +107,11 @@ export function createCreateSettingsTransactionInstruction( isWritable: false, isSigner: false, }, + { + pubkey: accounts.program, + isWritable: false, + isSigner: false, + }, ] if (accounts.anchorRemainingAccounts != null) { diff --git a/sdk/smart-account/src/generated/instructions/createTransaction.ts b/sdk/smart-account/src/generated/instructions/createTransaction.ts index da6200c..2d678ba 100644 --- a/sdk/smart-account/src/generated/instructions/createTransaction.ts +++ b/sdk/smart-account/src/generated/instructions/createTransaction.ts @@ -39,20 +39,22 @@ export const createTransactionStruct = new beet.FixableBeetArgsStruct< /** * Accounts required by the _createTransaction_ instruction * - * @property [_writable_] settings + * @property [_writable_] consensusAccount * @property [_writable_] transaction * @property [**signer**] creator * @property [_writable_, **signer**] rentPayer + * @property [] program * @category Instructions * @category CreateTransaction * @category generated */ export type CreateTransactionInstructionAccounts = { - settings: web3.PublicKey + consensusAccount: web3.PublicKey transaction: web3.PublicKey creator: web3.PublicKey rentPayer: web3.PublicKey systemProgram?: web3.PublicKey + program: web3.PublicKey anchorRemainingAccounts?: web3.AccountMeta[] } @@ -81,7 +83,7 @@ export function createCreateTransactionInstruction( }) const keys: web3.AccountMeta[] = [ { - pubkey: accounts.settings, + pubkey: accounts.consensusAccount, isWritable: true, isSigner: false, }, @@ -105,6 +107,11 @@ export function createCreateTransactionInstruction( isWritable: false, isSigner: false, }, + { + pubkey: accounts.program, + isWritable: false, + isSigner: false, + }, ] if (accounts.anchorRemainingAccounts != null) { diff --git a/sdk/smart-account/src/generated/instructions/createTransactionBuffer.ts b/sdk/smart-account/src/generated/instructions/createTransactionBuffer.ts index c9e2f04..569ff1d 100644 --- a/sdk/smart-account/src/generated/instructions/createTransactionBuffer.ts +++ b/sdk/smart-account/src/generated/instructions/createTransactionBuffer.ts @@ -39,7 +39,7 @@ export const createTransactionBufferStruct = new beet.FixableBeetArgsStruct< /** * Accounts required by the _createTransactionBuffer_ instruction * - * @property [] settings + * @property [] consensusAccount * @property [_writable_] transactionBuffer * @property [**signer**] creator * @property [_writable_, **signer**] rentPayer @@ -48,7 +48,7 @@ export const createTransactionBufferStruct = new beet.FixableBeetArgsStruct< * @category generated */ export type CreateTransactionBufferInstructionAccounts = { - settings: web3.PublicKey + consensusAccount: web3.PublicKey transactionBuffer: web3.PublicKey creator: web3.PublicKey rentPayer: web3.PublicKey @@ -81,7 +81,7 @@ export function createCreateTransactionBufferInstruction( }) const keys: web3.AccountMeta[] = [ { - pubkey: accounts.settings, + pubkey: accounts.consensusAccount, isWritable: false, isSigner: false, }, diff --git a/sdk/smart-account/src/generated/instructions/createTransactionFromBuffer.ts b/sdk/smart-account/src/generated/instructions/createTransactionFromBuffer.ts index b05e9b6..fa49bee 100644 --- a/sdk/smart-account/src/generated/instructions/createTransactionFromBuffer.ts +++ b/sdk/smart-account/src/generated/instructions/createTransactionFromBuffer.ts @@ -39,11 +39,12 @@ export const createTransactionFromBufferStruct = new beet.FixableBeetArgsStruct< /** * Accounts required by the _createTransactionFromBuffer_ instruction * - * @property [_writable_] transactionCreateItemSettings + * @property [_writable_] transactionCreateItemConsensusAccount * @property [_writable_] transactionCreateItemTransaction * @property [**signer**] transactionCreateItemCreator * @property [_writable_, **signer**] transactionCreateItemRentPayer * @property [] transactionCreateItemSystemProgram + * @property [] transactionCreateItemProgram * @property [_writable_] transactionBuffer * @property [_writable_, **signer**] creator * @category Instructions @@ -51,11 +52,12 @@ export const createTransactionFromBufferStruct = new beet.FixableBeetArgsStruct< * @category generated */ export type CreateTransactionFromBufferInstructionAccounts = { - transactionCreateItemSettings: web3.PublicKey + transactionCreateItemConsensusAccount: web3.PublicKey transactionCreateItemTransaction: web3.PublicKey transactionCreateItemCreator: web3.PublicKey transactionCreateItemRentPayer: web3.PublicKey transactionCreateItemSystemProgram: web3.PublicKey + transactionCreateItemProgram: web3.PublicKey transactionBuffer: web3.PublicKey creator: web3.PublicKey anchorRemainingAccounts?: web3.AccountMeta[] @@ -87,7 +89,7 @@ export function createCreateTransactionFromBufferInstruction( }) const keys: web3.AccountMeta[] = [ { - pubkey: accounts.transactionCreateItemSettings, + pubkey: accounts.transactionCreateItemConsensusAccount, isWritable: true, isSigner: false, }, @@ -111,6 +113,11 @@ export function createCreateTransactionFromBufferInstruction( isWritable: false, isSigner: false, }, + { + pubkey: accounts.transactionCreateItemProgram, + isWritable: false, + isSigner: false, + }, { pubkey: accounts.transactionBuffer, isWritable: true, diff --git a/sdk/smart-account/src/generated/instructions/executeSettingsTransaction.ts b/sdk/smart-account/src/generated/instructions/executeSettingsTransaction.ts index 3d2704e..51f2b26 100644 --- a/sdk/smart-account/src/generated/instructions/executeSettingsTransaction.ts +++ b/sdk/smart-account/src/generated/instructions/executeSettingsTransaction.ts @@ -27,6 +27,7 @@ export const executeSettingsTransactionStruct = new beet.BeetArgsStruct<{ * @property [_writable_] proposal * @property [] transaction * @property [_writable_, **signer**] rentPayer (optional) + * @property [] program * @category Instructions * @category ExecuteSettingsTransaction * @category generated @@ -38,6 +39,7 @@ export type ExecuteSettingsTransactionInstructionAccounts = { transaction: web3.PublicKey rentPayer?: web3.PublicKey systemProgram?: web3.PublicKey + program: web3.PublicKey anchorRemainingAccounts?: web3.AccountMeta[] } @@ -95,6 +97,11 @@ export function createExecuteSettingsTransactionInstruction( isWritable: false, isSigner: false, }, + { + pubkey: accounts.program, + isWritable: false, + isSigner: false, + }, ] if (accounts.anchorRemainingAccounts != null) { diff --git a/sdk/smart-account/src/generated/instructions/executeSettingsTransactionSync.ts b/sdk/smart-account/src/generated/instructions/executeSettingsTransactionSync.ts index 6bda341..c9cf0e7 100644 --- a/sdk/smart-account/src/generated/instructions/executeSettingsTransactionSync.ts +++ b/sdk/smart-account/src/generated/instructions/executeSettingsTransactionSync.ts @@ -40,7 +40,7 @@ export const executeSettingsTransactionSyncStruct = /** * Accounts required by the _executeSettingsTransactionSync_ instruction * - * @property [_writable_] settings + * @property [_writable_] consensusAccount * @property [_writable_, **signer**] rentPayer (optional) * @property [] program * @category Instructions @@ -48,7 +48,7 @@ export const executeSettingsTransactionSyncStruct = * @category generated */ export type ExecuteSettingsTransactionSyncInstructionAccounts = { - settings: web3.PublicKey + consensusAccount: web3.PublicKey rentPayer?: web3.PublicKey systemProgram?: web3.PublicKey program: web3.PublicKey @@ -84,7 +84,7 @@ export function createExecuteSettingsTransactionSyncInstruction( }) const keys: web3.AccountMeta[] = [ { - pubkey: accounts.settings, + pubkey: accounts.consensusAccount, isWritable: true, isSigner: false, }, diff --git a/sdk/smart-account/src/generated/instructions/executeTransaction.ts b/sdk/smart-account/src/generated/instructions/executeTransaction.ts index 6c3040e..de09be1 100644 --- a/sdk/smart-account/src/generated/instructions/executeTransaction.ts +++ b/sdk/smart-account/src/generated/instructions/executeTransaction.ts @@ -22,19 +22,21 @@ export const executeTransactionStruct = new beet.BeetArgsStruct<{ /** * Accounts required by the _executeTransaction_ instruction * - * @property [] settings + * @property [_writable_] consensusAccount * @property [_writable_] proposal * @property [] transaction * @property [**signer**] signer + * @property [] program * @category Instructions * @category ExecuteTransaction * @category generated */ export type ExecuteTransactionInstructionAccounts = { - settings: web3.PublicKey + consensusAccount: web3.PublicKey proposal: web3.PublicKey transaction: web3.PublicKey signer: web3.PublicKey + program: web3.PublicKey anchorRemainingAccounts?: web3.AccountMeta[] } @@ -59,8 +61,8 @@ export function createExecuteTransactionInstruction( }) const keys: web3.AccountMeta[] = [ { - pubkey: accounts.settings, - isWritable: false, + pubkey: accounts.consensusAccount, + isWritable: true, isSigner: false, }, { @@ -78,6 +80,11 @@ export function createExecuteTransactionInstruction( isWritable: false, isSigner: true, }, + { + pubkey: accounts.program, + isWritable: false, + isSigner: false, + }, ] if (accounts.anchorRemainingAccounts != null) { diff --git a/sdk/smart-account/src/generated/instructions/executeTransactionSync.ts b/sdk/smart-account/src/generated/instructions/executeTransactionSync.ts index 6633cf3..78631fa 100644 --- a/sdk/smart-account/src/generated/instructions/executeTransactionSync.ts +++ b/sdk/smart-account/src/generated/instructions/executeTransactionSync.ts @@ -8,9 +8,9 @@ import * as beet from '@metaplex-foundation/beet' import * as web3 from '@solana/web3.js' import { - SyncTransactionArgs, - syncTransactionArgsBeet, -} from '../types/SyncTransactionArgs' + LegacySyncTransactionArgs, + legacySyncTransactionArgsBeet, +} from '../types/LegacySyncTransactionArgs' /** * @category Instructions @@ -18,7 +18,7 @@ import { * @category generated */ export type ExecuteTransactionSyncInstructionArgs = { - args: SyncTransactionArgs + args: LegacySyncTransactionArgs } /** * @category Instructions @@ -32,21 +32,21 @@ export const executeTransactionSyncStruct = new beet.FixableBeetArgsStruct< >( [ ['instructionDiscriminator', beet.uniformFixedSizeArray(beet.u8, 8)], - ['args', syncTransactionArgsBeet], + ['args', legacySyncTransactionArgsBeet], ], 'ExecuteTransactionSyncInstructionArgs' ) /** * Accounts required by the _executeTransactionSync_ instruction * - * @property [] settings + * @property [] consensusAccount * @property [] program * @category Instructions * @category ExecuteTransactionSync * @category generated */ export type ExecuteTransactionSyncInstructionAccounts = { - settings: web3.PublicKey + consensusAccount: web3.PublicKey program: web3.PublicKey anchorRemainingAccounts?: web3.AccountMeta[] } @@ -76,7 +76,7 @@ export function createExecuteTransactionSyncInstruction( }) const keys: web3.AccountMeta[] = [ { - pubkey: accounts.settings, + pubkey: accounts.consensusAccount, isWritable: false, isSigner: false, }, diff --git a/sdk/smart-account/src/generated/instructions/executeTransactionSyncV2.ts b/sdk/smart-account/src/generated/instructions/executeTransactionSyncV2.ts new file mode 100644 index 0000000..ab7195d --- /dev/null +++ b/sdk/smart-account/src/generated/instructions/executeTransactionSyncV2.ts @@ -0,0 +1,102 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +import * as web3 from '@solana/web3.js' +import { + SyncTransactionArgs, + syncTransactionArgsBeet, +} from '../types/SyncTransactionArgs' + +/** + * @category Instructions + * @category ExecuteTransactionSyncV2 + * @category generated + */ +export type ExecuteTransactionSyncV2InstructionArgs = { + args: SyncTransactionArgs +} +/** + * @category Instructions + * @category ExecuteTransactionSyncV2 + * @category generated + */ +export const executeTransactionSyncV2Struct = new beet.FixableBeetArgsStruct< + ExecuteTransactionSyncV2InstructionArgs & { + instructionDiscriminator: number[] /* size: 8 */ + } +>( + [ + ['instructionDiscriminator', beet.uniformFixedSizeArray(beet.u8, 8)], + ['args', syncTransactionArgsBeet], + ], + 'ExecuteTransactionSyncV2InstructionArgs' +) +/** + * Accounts required by the _executeTransactionSyncV2_ instruction + * + * @property [_writable_] consensusAccount + * @property [] program + * @category Instructions + * @category ExecuteTransactionSyncV2 + * @category generated + */ +export type ExecuteTransactionSyncV2InstructionAccounts = { + consensusAccount: web3.PublicKey + program: web3.PublicKey + anchorRemainingAccounts?: web3.AccountMeta[] +} + +export const executeTransactionSyncV2InstructionDiscriminator = [ + 90, 81, 187, 81, 39, 70, 128, 78, +] + +/** + * Creates a _ExecuteTransactionSyncV2_ instruction. + * + * @param accounts that will be accessed while the instruction is processed + * @param args to provide as instruction data to the program + * + * @category Instructions + * @category ExecuteTransactionSyncV2 + * @category generated + */ +export function createExecuteTransactionSyncV2Instruction( + accounts: ExecuteTransactionSyncV2InstructionAccounts, + args: ExecuteTransactionSyncV2InstructionArgs, + programId = new web3.PublicKey('SMRTzfY6DfH5ik3TKiyLFfXexV8uSG3d2UksSCYdunG') +) { + const [data] = executeTransactionSyncV2Struct.serialize({ + instructionDiscriminator: executeTransactionSyncV2InstructionDiscriminator, + ...args, + }) + const keys: web3.AccountMeta[] = [ + { + pubkey: accounts.consensusAccount, + isWritable: true, + isSigner: false, + }, + { + pubkey: accounts.program, + isWritable: false, + isSigner: false, + }, + ] + + if (accounts.anchorRemainingAccounts != null) { + for (const acc of accounts.anchorRemainingAccounts) { + keys.push(acc) + } + } + + const ix = new web3.TransactionInstruction({ + programId, + keys, + data, + }) + return ix +} diff --git a/sdk/smart-account/src/generated/instructions/extendTransactionBuffer.ts b/sdk/smart-account/src/generated/instructions/extendTransactionBuffer.ts index ec5be37..854d31e 100644 --- a/sdk/smart-account/src/generated/instructions/extendTransactionBuffer.ts +++ b/sdk/smart-account/src/generated/instructions/extendTransactionBuffer.ts @@ -39,7 +39,7 @@ export const extendTransactionBufferStruct = new beet.FixableBeetArgsStruct< /** * Accounts required by the _extendTransactionBuffer_ instruction * - * @property [] settings + * @property [] consensusAccount * @property [_writable_] transactionBuffer * @property [**signer**] creator * @category Instructions @@ -47,7 +47,7 @@ export const extendTransactionBufferStruct = new beet.FixableBeetArgsStruct< * @category generated */ export type ExtendTransactionBufferInstructionAccounts = { - settings: web3.PublicKey + consensusAccount: web3.PublicKey transactionBuffer: web3.PublicKey creator: web3.PublicKey anchorRemainingAccounts?: web3.AccountMeta[] @@ -78,7 +78,7 @@ export function createExtendTransactionBufferInstruction( }) const keys: web3.AccountMeta[] = [ { - pubkey: accounts.settings, + pubkey: accounts.consensusAccount, isWritable: false, isSigner: false, }, diff --git a/sdk/smart-account/src/generated/instructions/index.ts b/sdk/smart-account/src/generated/instructions/index.ts index 820b8f5..f7c85e5 100644 --- a/sdk/smart-account/src/generated/instructions/index.ts +++ b/sdk/smart-account/src/generated/instructions/index.ts @@ -7,6 +7,7 @@ export * from './cancelProposal' export * from './changeThresholdAsAuthority' export * from './closeBatch' export * from './closeBatchTransaction' +export * from './closeEmptyPolicyTransaction' export * from './closeSettingsTransaction' export * from './closeTransaction' export * from './closeTransactionBuffer' @@ -22,6 +23,7 @@ export * from './executeSettingsTransaction' export * from './executeSettingsTransactionSync' export * from './executeTransaction' export * from './executeTransactionSync' +export * from './executeTransactionSyncV2' export * from './extendTransactionBuffer' export * from './initializeProgramConfig' export * from './logEvent' diff --git a/sdk/smart-account/src/generated/instructions/logEvent.ts b/sdk/smart-account/src/generated/instructions/logEvent.ts index b93308f..268a976 100644 --- a/sdk/smart-account/src/generated/instructions/logEvent.ts +++ b/sdk/smart-account/src/generated/instructions/logEvent.ts @@ -7,7 +7,7 @@ import * as beet from '@metaplex-foundation/beet' import * as web3 from '@solana/web3.js' -import { LogEventArgs, logEventArgsBeet } from '../types/LogEventArgs' +import { LogEventArgsV2, logEventArgsV2Beet } from '../types/LogEventArgsV2' /** * @category Instructions @@ -15,7 +15,7 @@ import { LogEventArgs, logEventArgsBeet } from '../types/LogEventArgs' * @category generated */ export type LogEventInstructionArgs = { - args: LogEventArgs + args: LogEventArgsV2 } /** * @category Instructions @@ -29,7 +29,7 @@ export const logEventStruct = new beet.FixableBeetArgsStruct< >( [ ['instructionDiscriminator', beet.uniformFixedSizeArray(beet.u8, 8)], - ['args', logEventArgsBeet], + ['args', logEventArgsV2Beet], ], 'LogEventInstructionArgs' ) diff --git a/sdk/smart-account/src/generated/instructions/rejectProposal.ts b/sdk/smart-account/src/generated/instructions/rejectProposal.ts index 43d64c8..1697c2c 100644 --- a/sdk/smart-account/src/generated/instructions/rejectProposal.ts +++ b/sdk/smart-account/src/generated/instructions/rejectProposal.ts @@ -39,18 +39,20 @@ export const rejectProposalStruct = new beet.FixableBeetArgsStruct< /** * Accounts required by the _rejectProposal_ instruction * - * @property [] settings + * @property [] consensusAccount * @property [_writable_, **signer**] signer * @property [_writable_] proposal + * @property [] program * @category Instructions * @category RejectProposal * @category generated */ export type RejectProposalInstructionAccounts = { - settings: web3.PublicKey + consensusAccount: web3.PublicKey signer: web3.PublicKey proposal: web3.PublicKey systemProgram?: web3.PublicKey + program: web3.PublicKey anchorRemainingAccounts?: web3.AccountMeta[] } @@ -82,7 +84,7 @@ export function createRejectProposalInstruction( }) const keys: web3.AccountMeta[] = [ { - pubkey: accounts.settings, + pubkey: accounts.consensusAccount, isWritable: false, isSigner: false, }, @@ -101,6 +103,11 @@ export function createRejectProposalInstruction( isWritable: false, isSigner: false, }, + { + pubkey: accounts.program, + isWritable: false, + isSigner: false, + }, ] if (accounts.anchorRemainingAccounts != null) { diff --git a/sdk/smart-account/src/generated/types/AccountConstraint.ts b/sdk/smart-account/src/generated/types/AccountConstraint.ts new file mode 100644 index 0000000..13b10f6 --- /dev/null +++ b/sdk/smart-account/src/generated/types/AccountConstraint.ts @@ -0,0 +1,33 @@ +/** + * 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 + */ + +import * as web3 from '@solana/web3.js' +import * as beet from '@metaplex-foundation/beet' +import * as beetSolana from '@metaplex-foundation/beet-solana' +import { + AccountConstraintType, + accountConstraintTypeBeet, +} from './AccountConstraintType' +export type AccountConstraint = { + accountIndex: number + accountConstraint: AccountConstraintType + owner: beet.COption +} + +/** + * @category userTypes + * @category generated + */ +export const accountConstraintBeet = + new beet.FixableBeetArgsStruct( + [ + ['accountIndex', beet.u8], + ['accountConstraint', accountConstraintTypeBeet], + ['owner', beet.coption(beetSolana.publicKey)], + ], + 'AccountConstraint' + ) diff --git a/sdk/smart-account/src/generated/types/AccountConstraintType.ts b/sdk/smart-account/src/generated/types/AccountConstraintType.ts new file mode 100644 index 0000000..de3a53c --- /dev/null +++ b/sdk/smart-account/src/generated/types/AccountConstraintType.ts @@ -0,0 +1,70 @@ +/** + * 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 + */ + +import * as web3 from '@solana/web3.js' +import * as beet from '@metaplex-foundation/beet' +import * as beetSolana from '@metaplex-foundation/beet-solana' +import { DataConstraint, dataConstraintBeet } from './DataConstraint' +/** + * This type is used to derive the {@link AccountConstraintType} type as well as the de/serializer. + * However don't refer to it in your code but use the {@link AccountConstraintType} type instead. + * + * @category userTypes + * @category enums + * @category generated + * @private + */ +export type AccountConstraintTypeRecord = { + Pubkey: { fields: [web3.PublicKey[]] } + AccountData: { fields: [DataConstraint[]] } +} + +/** + * Union type respresenting the AccountConstraintType data enum defined in Rust. + * + * NOTE: that it includes a `__kind` property which allows to narrow types in + * switch/if statements. + * Additionally `isAccountConstraintType*` type guards are exposed below to narrow to a specific variant. + * + * @category userTypes + * @category enums + * @category generated + */ +export type AccountConstraintType = + beet.DataEnumKeyAsKind + +export const isAccountConstraintTypePubkey = ( + x: AccountConstraintType +): x is AccountConstraintType & { __kind: 'Pubkey' } => x.__kind === 'Pubkey' +export const isAccountConstraintTypeAccountData = ( + x: AccountConstraintType +): x is AccountConstraintType & { __kind: 'AccountData' } => + x.__kind === 'AccountData' + +/** + * @category userTypes + * @category generated + */ +export const accountConstraintTypeBeet = + beet.dataEnum([ + [ + 'Pubkey', + new beet.FixableBeetArgsStruct( + [['fields', beet.tuple([beet.array(beetSolana.publicKey)])]], + 'AccountConstraintTypeRecord["Pubkey"]' + ), + ], + [ + 'AccountData', + new beet.FixableBeetArgsStruct< + AccountConstraintTypeRecord['AccountData'] + >( + [['fields', beet.tuple([beet.array(dataConstraintBeet)])]], + 'AccountConstraintTypeRecord["AccountData"]' + ), + ], + ]) as beet.FixableBeet diff --git a/sdk/smart-account/src/generated/types/AllowedSettingsChange.ts b/sdk/smart-account/src/generated/types/AllowedSettingsChange.ts new file mode 100644 index 0000000..9f48510 --- /dev/null +++ b/sdk/smart-account/src/generated/types/AllowedSettingsChange.ts @@ -0,0 +1,99 @@ +/** + * 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 + */ + +import * as web3 from '@solana/web3.js' +import * as beet from '@metaplex-foundation/beet' +import * as beetSolana from '@metaplex-foundation/beet-solana' +import { Permissions, permissionsBeet } from './Permissions' +/** + * This type is used to derive the {@link AllowedSettingsChange} type as well as the de/serializer. + * However don't refer to it in your code but use the {@link AllowedSettingsChange} type instead. + * + * @category userTypes + * @category enums + * @category generated + * @private + */ +export type AllowedSettingsChangeRecord = { + AddSigner: { + newSigner: beet.COption + newSignerPermissions: beet.COption + } + RemoveSigner: { oldSigner: beet.COption } + ChangeThreshold: void /* scalar variant */ + ChangeTimeLock: { newTimeLock: beet.COption } +} + +/** + * Union type respresenting the AllowedSettingsChange data enum defined in Rust. + * + * NOTE: that it includes a `__kind` property which allows to narrow types in + * switch/if statements. + * Additionally `isAllowedSettingsChange*` type guards are exposed below to narrow to a specific variant. + * + * @category userTypes + * @category enums + * @category generated + */ +export type AllowedSettingsChange = + beet.DataEnumKeyAsKind + +export const isAllowedSettingsChangeAddSigner = ( + x: AllowedSettingsChange +): x is AllowedSettingsChange & { __kind: 'AddSigner' } => + x.__kind === 'AddSigner' +export const isAllowedSettingsChangeRemoveSigner = ( + x: AllowedSettingsChange +): x is AllowedSettingsChange & { __kind: 'RemoveSigner' } => + x.__kind === 'RemoveSigner' +export const isAllowedSettingsChangeChangeThreshold = ( + x: AllowedSettingsChange +): x is AllowedSettingsChange & { __kind: 'ChangeThreshold' } => + x.__kind === 'ChangeThreshold' +export const isAllowedSettingsChangeChangeTimeLock = ( + x: AllowedSettingsChange +): x is AllowedSettingsChange & { __kind: 'ChangeTimeLock' } => + x.__kind === 'ChangeTimeLock' + +/** + * @category userTypes + * @category generated + */ +export const allowedSettingsChangeBeet = + beet.dataEnum([ + [ + 'AddSigner', + new beet.FixableBeetArgsStruct( + [ + ['newSigner', beet.coption(beetSolana.publicKey)], + ['newSignerPermissions', beet.coption(permissionsBeet)], + ], + 'AllowedSettingsChangeRecord["AddSigner"]' + ), + ], + + [ + 'RemoveSigner', + new beet.FixableBeetArgsStruct< + AllowedSettingsChangeRecord['RemoveSigner'] + >( + [['oldSigner', beet.coption(beetSolana.publicKey)]], + 'AllowedSettingsChangeRecord["RemoveSigner"]' + ), + ], + ['ChangeThreshold', beet.unit], + + [ + 'ChangeTimeLock', + new beet.FixableBeetArgsStruct< + AllowedSettingsChangeRecord['ChangeTimeLock'] + >( + [['newTimeLock', beet.coption(beet.u32)]], + 'AllowedSettingsChangeRecord["ChangeTimeLock"]' + ), + ], + ]) as beet.FixableBeet diff --git a/sdk/smart-account/src/generated/types/ConsensusAccountType.ts b/sdk/smart-account/src/generated/types/ConsensusAccountType.ts new file mode 100644 index 0000000..f79f3f2 --- /dev/null +++ b/sdk/smart-account/src/generated/types/ConsensusAccountType.ts @@ -0,0 +1,24 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +/** + * @category enums + * @category generated + */ +export enum ConsensusAccountType { + Settings, + Policy, +} + +/** + * @category userTypes + * @category generated + */ +export const consensusAccountTypeBeet = beet.fixedScalarEnum( + ConsensusAccountType +) as beet.FixedSizeBeet diff --git a/sdk/smart-account/src/generated/types/CreateTransactionArgs.ts b/sdk/smart-account/src/generated/types/CreateTransactionArgs.ts index 17a35ca..e13dc56 100644 --- a/sdk/smart-account/src/generated/types/CreateTransactionArgs.ts +++ b/sdk/smart-account/src/generated/types/CreateTransactionArgs.ts @@ -6,24 +6,71 @@ */ import * as beet from '@metaplex-foundation/beet' -export type CreateTransactionArgs = { - accountIndex: number - ephemeralSigners: number - transactionMessage: Uint8Array - memo: beet.COption +import { + TransactionPayload, + transactionPayloadBeet, +} from './TransactionPayload' +import { PolicyPayload, policyPayloadBeet } from './PolicyPayload' +/** + * This type is used to derive the {@link CreateTransactionArgs} type as well as the de/serializer. + * However don't refer to it in your code but use the {@link CreateTransactionArgs} type instead. + * + * @category userTypes + * @category enums + * @category generated + * @private + */ +export type CreateTransactionArgsRecord = { + TransactionPayload: { fields: [TransactionPayload] } + PolicyPayload: { payload: PolicyPayload } } +/** + * Union type respresenting the CreateTransactionArgs data enum defined in Rust. + * + * NOTE: that it includes a `__kind` property which allows to narrow types in + * switch/if statements. + * Additionally `isCreateTransactionArgs*` type guards are exposed below to narrow to a specific variant. + * + * @category userTypes + * @category enums + * @category generated + */ +export type CreateTransactionArgs = + beet.DataEnumKeyAsKind + +export const isCreateTransactionArgsTransactionPayload = ( + x: CreateTransactionArgs +): x is CreateTransactionArgs & { __kind: 'TransactionPayload' } => + x.__kind === 'TransactionPayload' +export const isCreateTransactionArgsPolicyPayload = ( + x: CreateTransactionArgs +): x is CreateTransactionArgs & { __kind: 'PolicyPayload' } => + x.__kind === 'PolicyPayload' + /** * @category userTypes * @category generated */ export const createTransactionArgsBeet = - new beet.FixableBeetArgsStruct( + beet.dataEnum([ + [ + 'TransactionPayload', + new beet.FixableBeetArgsStruct< + CreateTransactionArgsRecord['TransactionPayload'] + >( + [['fields', beet.tuple([transactionPayloadBeet])]], + 'CreateTransactionArgsRecord["TransactionPayload"]' + ), + ], + [ - ['accountIndex', beet.u8], - ['ephemeralSigners', beet.u8], - ['transactionMessage', beet.bytes], - ['memo', beet.coption(beet.utf8String)], + 'PolicyPayload', + new beet.FixableBeetArgsStruct< + CreateTransactionArgsRecord['PolicyPayload'] + >( + [['payload', policyPayloadBeet]], + 'CreateTransactionArgsRecord["PolicyPayload"]' + ), ], - 'CreateTransactionArgs' - ) + ]) as beet.FixableBeet diff --git a/sdk/smart-account/src/generated/types/DataConstraint.ts b/sdk/smart-account/src/generated/types/DataConstraint.ts new file mode 100644 index 0000000..1fb7c38 --- /dev/null +++ b/sdk/smart-account/src/generated/types/DataConstraint.ts @@ -0,0 +1,29 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +import { DataValue, dataValueBeet } from './DataValue' +import { DataOperator, dataOperatorBeet } from './DataOperator' +export type DataConstraint = { + dataOffset: beet.bignum + dataValue: DataValue + operator: DataOperator +} + +/** + * @category userTypes + * @category generated + */ +export const dataConstraintBeet = + new beet.FixableBeetArgsStruct( + [ + ['dataOffset', beet.u64], + ['dataValue', dataValueBeet], + ['operator', dataOperatorBeet], + ], + 'DataConstraint' + ) diff --git a/sdk/smart-account/src/generated/types/DataOperator.ts b/sdk/smart-account/src/generated/types/DataOperator.ts new file mode 100644 index 0000000..a920625 --- /dev/null +++ b/sdk/smart-account/src/generated/types/DataOperator.ts @@ -0,0 +1,28 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +/** + * @category enums + * @category generated + */ +export enum DataOperator { + Equals, + NotEquals, + GreaterThan, + GreaterThanOrEqualTo, + LessThan, + LessThanOrEqualTo, +} + +/** + * @category userTypes + * @category generated + */ +export const dataOperatorBeet = beet.fixedScalarEnum( + DataOperator +) as beet.FixedSizeBeet diff --git a/sdk/smart-account/src/generated/types/DataValue.ts b/sdk/smart-account/src/generated/types/DataValue.ts new file mode 100644 index 0000000..dee7fcb --- /dev/null +++ b/sdk/smart-account/src/generated/types/DataValue.ts @@ -0,0 +1,106 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +/** + * This type is used to derive the {@link DataValue} type as well as the de/serializer. + * However don't refer to it in your code but use the {@link DataValue} type instead. + * + * @category userTypes + * @category enums + * @category generated + * @private + */ +export type DataValueRecord = { + U8: { fields: [number] } + U16Le: { fields: [number] } + U32Le: { fields: [number] } + U64Le: { fields: [beet.bignum] } + U128Le: { fields: [beet.bignum] } + U8Slice: { fields: [Uint8Array] } +} + +/** + * Union type respresenting the DataValue data enum defined in Rust. + * + * NOTE: that it includes a `__kind` property which allows to narrow types in + * switch/if statements. + * Additionally `isDataValue*` type guards are exposed below to narrow to a specific variant. + * + * @category userTypes + * @category enums + * @category generated + */ +export type DataValue = beet.DataEnumKeyAsKind + +export const isDataValueU8 = ( + x: DataValue +): x is DataValue & { __kind: 'U8' } => x.__kind === 'U8' +export const isDataValueU16Le = ( + x: DataValue +): x is DataValue & { __kind: 'U16Le' } => x.__kind === 'U16Le' +export const isDataValueU32Le = ( + x: DataValue +): x is DataValue & { __kind: 'U32Le' } => x.__kind === 'U32Le' +export const isDataValueU64Le = ( + x: DataValue +): x is DataValue & { __kind: 'U64Le' } => x.__kind === 'U64Le' +export const isDataValueU128Le = ( + x: DataValue +): x is DataValue & { __kind: 'U128Le' } => x.__kind === 'U128Le' +export const isDataValueU8Slice = ( + x: DataValue +): x is DataValue & { __kind: 'U8Slice' } => x.__kind === 'U8Slice' + +/** + * @category userTypes + * @category generated + */ +export const dataValueBeet = beet.dataEnum([ + [ + 'U8', + new beet.BeetArgsStruct( + [['fields', beet.fixedSizeTuple([beet.u8])]], + 'DataValueRecord["U8"]' + ), + ], + [ + 'U16Le', + new beet.BeetArgsStruct( + [['fields', beet.fixedSizeTuple([beet.u16])]], + 'DataValueRecord["U16Le"]' + ), + ], + [ + 'U32Le', + new beet.BeetArgsStruct( + [['fields', beet.fixedSizeTuple([beet.u32])]], + 'DataValueRecord["U32Le"]' + ), + ], + [ + 'U64Le', + new beet.BeetArgsStruct( + [['fields', beet.fixedSizeTuple([beet.u64])]], + 'DataValueRecord["U64Le"]' + ), + ], + [ + 'U128Le', + new beet.BeetArgsStruct( + [['fields', beet.fixedSizeTuple([beet.u128])]], + 'DataValueRecord["U128Le"]' + ), + ], + [ + 'U8Slice', + new beet.FixableBeetArgsStruct( + [['fields', beet.tuple([beet.bytes])]], + 'DataValueRecord["U8Slice"]' + ), + ], +]) as beet.FixableBeet diff --git a/sdk/smart-account/src/generated/types/Hook.ts b/sdk/smart-account/src/generated/types/Hook.ts new file mode 100644 index 0000000..57a5558 --- /dev/null +++ b/sdk/smart-account/src/generated/types/Hook.ts @@ -0,0 +1,33 @@ +/** + * 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 + */ + +import * as web3 from '@solana/web3.js' +import * as beet from '@metaplex-foundation/beet' +import * as beetSolana from '@metaplex-foundation/beet-solana' +import { AccountConstraint, accountConstraintBeet } from './AccountConstraint' +export type Hook = { + numExtraAccounts: number + accountConstraints: AccountConstraint[] + instructionData: Uint8Array + programId: web3.PublicKey + passInnerInstructions: boolean +} + +/** + * @category userTypes + * @category generated + */ +export const hookBeet = new beet.FixableBeetArgsStruct( + [ + ['numExtraAccounts', beet.u8], + ['accountConstraints', beet.array(accountConstraintBeet)], + ['instructionData', beet.bytes], + ['programId', beetSolana.publicKey], + ['passInnerInstructions', beet.bool], + ], + 'Hook' +) diff --git a/sdk/smart-account/src/generated/types/InstructionConstraint.ts b/sdk/smart-account/src/generated/types/InstructionConstraint.ts new file mode 100644 index 0000000..e7d3f5b --- /dev/null +++ b/sdk/smart-account/src/generated/types/InstructionConstraint.ts @@ -0,0 +1,31 @@ +/** + * 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 + */ + +import * as web3 from '@solana/web3.js' +import * as beetSolana from '@metaplex-foundation/beet-solana' +import * as beet from '@metaplex-foundation/beet' +import { AccountConstraint, accountConstraintBeet } from './AccountConstraint' +import { DataConstraint, dataConstraintBeet } from './DataConstraint' +export type InstructionConstraint = { + programId: web3.PublicKey + accountConstraints: AccountConstraint[] + dataConstraints: DataConstraint[] +} + +/** + * @category userTypes + * @category generated + */ +export const instructionConstraintBeet = + new beet.FixableBeetArgsStruct( + [ + ['programId', beetSolana.publicKey], + ['accountConstraints', beet.array(accountConstraintBeet)], + ['dataConstraints', beet.array(dataConstraintBeet)], + ], + 'InstructionConstraint' + ) diff --git a/sdk/smart-account/src/generated/types/InternalFundTransferPayload.ts b/sdk/smart-account/src/generated/types/InternalFundTransferPayload.ts new file mode 100644 index 0000000..55d4a1a --- /dev/null +++ b/sdk/smart-account/src/generated/types/InternalFundTransferPayload.ts @@ -0,0 +1,33 @@ +/** + * 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 + */ + +import * as web3 from '@solana/web3.js' +import * as beet from '@metaplex-foundation/beet' +import * as beetSolana from '@metaplex-foundation/beet-solana' +export type InternalFundTransferPayload = { + sourceIndex: number + destinationIndex: number + mint: web3.PublicKey + decimals: number + amount: beet.bignum +} + +/** + * @category userTypes + * @category generated + */ +export const internalFundTransferPayloadBeet = + new beet.BeetArgsStruct( + [ + ['sourceIndex', beet.u8], + ['destinationIndex', beet.u8], + ['mint', beetSolana.publicKey], + ['decimals', beet.u8], + ['amount', beet.u64], + ], + 'InternalFundTransferPayload' + ) diff --git a/sdk/smart-account/src/generated/types/InternalFundTransferPolicy.ts b/sdk/smart-account/src/generated/types/InternalFundTransferPolicy.ts new file mode 100644 index 0000000..1fc32a6 --- /dev/null +++ b/sdk/smart-account/src/generated/types/InternalFundTransferPolicy.ts @@ -0,0 +1,29 @@ +/** + * 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 + */ + +import * as web3 from '@solana/web3.js' +import * as beet from '@metaplex-foundation/beet' +import * as beetSolana from '@metaplex-foundation/beet-solana' +export type InternalFundTransferPolicy = { + sourceAccountMask: number[] /* size: 32 */ + destinationAccountMask: number[] /* size: 32 */ + allowedMints: web3.PublicKey[] +} + +/** + * @category userTypes + * @category generated + */ +export const internalFundTransferPolicyBeet = + new beet.FixableBeetArgsStruct( + [ + ['sourceAccountMask', beet.uniformFixedSizeArray(beet.u8, 32)], + ['destinationAccountMask', beet.uniformFixedSizeArray(beet.u8, 32)], + ['allowedMints', beet.array(beetSolana.publicKey)], + ], + 'InternalFundTransferPolicy' + ) diff --git a/sdk/smart-account/src/generated/types/InternalFundTransferPolicyCreationPayload.ts b/sdk/smart-account/src/generated/types/InternalFundTransferPolicyCreationPayload.ts new file mode 100644 index 0000000..8c1ad1a --- /dev/null +++ b/sdk/smart-account/src/generated/types/InternalFundTransferPolicyCreationPayload.ts @@ -0,0 +1,29 @@ +/** + * 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 + */ + +import * as web3 from '@solana/web3.js' +import * as beet from '@metaplex-foundation/beet' +import * as beetSolana from '@metaplex-foundation/beet-solana' +export type InternalFundTransferPolicyCreationPayload = { + sourceAccountIndices: Uint8Array + destinationAccountIndices: Uint8Array + allowedMints: web3.PublicKey[] +} + +/** + * @category userTypes + * @category generated + */ +export const internalFundTransferPolicyCreationPayloadBeet = + new beet.FixableBeetArgsStruct( + [ + ['sourceAccountIndices', beet.bytes], + ['destinationAccountIndices', beet.bytes], + ['allowedMints', beet.array(beetSolana.publicKey)], + ], + 'InternalFundTransferPolicyCreationPayload' + ) diff --git a/sdk/smart-account/src/generated/types/LegacySyncTransactionArgs.ts b/sdk/smart-account/src/generated/types/LegacySyncTransactionArgs.ts new file mode 100644 index 0000000..6f91880 --- /dev/null +++ b/sdk/smart-account/src/generated/types/LegacySyncTransactionArgs.ts @@ -0,0 +1,27 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +export type LegacySyncTransactionArgs = { + accountIndex: number + numSigners: number + instructions: Uint8Array +} + +/** + * @category userTypes + * @category generated + */ +export const legacySyncTransactionArgsBeet = + new beet.FixableBeetArgsStruct( + [ + ['accountIndex', beet.u8], + ['numSigners', beet.u8], + ['instructions', beet.bytes], + ], + 'LegacySyncTransactionArgs' + ) diff --git a/sdk/smart-account/src/generated/types/LimitedQuantityConstraints.ts b/sdk/smart-account/src/generated/types/LimitedQuantityConstraints.ts new file mode 100644 index 0000000..5e38ddf --- /dev/null +++ b/sdk/smart-account/src/generated/types/LimitedQuantityConstraints.ts @@ -0,0 +1,21 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +export type LimitedQuantityConstraints = { + maxPerPeriod: beet.bignum +} + +/** + * @category userTypes + * @category generated + */ +export const limitedQuantityConstraintsBeet = + new beet.BeetArgsStruct( + [['maxPerPeriod', beet.u64]], + 'LimitedQuantityConstraints' + ) diff --git a/sdk/smart-account/src/generated/types/LimitedSettingsAction.ts b/sdk/smart-account/src/generated/types/LimitedSettingsAction.ts new file mode 100644 index 0000000..3312b42 --- /dev/null +++ b/sdk/smart-account/src/generated/types/LimitedSettingsAction.ts @@ -0,0 +1,99 @@ +/** + * 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 + */ + +import * as web3 from '@solana/web3.js' +import * as beetSolana from '@metaplex-foundation/beet-solana' +import * as beet from '@metaplex-foundation/beet' +import { + SmartAccountSigner, + smartAccountSignerBeet, +} from './SmartAccountSigner' +/** + * This type is used to derive the {@link LimitedSettingsAction} type as well as the de/serializer. + * However don't refer to it in your code but use the {@link LimitedSettingsAction} type instead. + * + * @category userTypes + * @category enums + * @category generated + * @private + */ +export type LimitedSettingsActionRecord = { + AddSigner: { newSigner: SmartAccountSigner } + RemoveSigner: { oldSigner: web3.PublicKey } + ChangeThreshold: { newThreshold: number } + SetTimeLock: { newTimeLock: number } +} + +/** + * Union type respresenting the LimitedSettingsAction data enum defined in Rust. + * + * NOTE: that it includes a `__kind` property which allows to narrow types in + * switch/if statements. + * Additionally `isLimitedSettingsAction*` type guards are exposed below to narrow to a specific variant. + * + * @category userTypes + * @category enums + * @category generated + */ +export type LimitedSettingsAction = + beet.DataEnumKeyAsKind + +export const isLimitedSettingsActionAddSigner = ( + x: LimitedSettingsAction +): x is LimitedSettingsAction & { __kind: 'AddSigner' } => + x.__kind === 'AddSigner' +export const isLimitedSettingsActionRemoveSigner = ( + x: LimitedSettingsAction +): x is LimitedSettingsAction & { __kind: 'RemoveSigner' } => + x.__kind === 'RemoveSigner' +export const isLimitedSettingsActionChangeThreshold = ( + x: LimitedSettingsAction +): x is LimitedSettingsAction & { __kind: 'ChangeThreshold' } => + x.__kind === 'ChangeThreshold' +export const isLimitedSettingsActionSetTimeLock = ( + x: LimitedSettingsAction +): x is LimitedSettingsAction & { __kind: 'SetTimeLock' } => + x.__kind === 'SetTimeLock' + +/** + * @category userTypes + * @category generated + */ +export const limitedSettingsActionBeet = + beet.dataEnum([ + [ + 'AddSigner', + new beet.BeetArgsStruct( + [['newSigner', smartAccountSignerBeet]], + 'LimitedSettingsActionRecord["AddSigner"]' + ), + ], + + [ + 'RemoveSigner', + new beet.BeetArgsStruct( + [['oldSigner', beetSolana.publicKey]], + 'LimitedSettingsActionRecord["RemoveSigner"]' + ), + ], + + [ + 'ChangeThreshold', + new beet.BeetArgsStruct( + [['newThreshold', beet.u16]], + 'LimitedSettingsActionRecord["ChangeThreshold"]' + ), + ], + + [ + 'SetTimeLock', + new beet.BeetArgsStruct( + [['newTimeLock', beet.u32]], + 'LimitedSettingsActionRecord["SetTimeLock"]' + ), + ], + ]) as beet.FixableBeet diff --git a/sdk/smart-account/src/generated/types/LimitedSpendingLimit.ts b/sdk/smart-account/src/generated/types/LimitedSpendingLimit.ts new file mode 100644 index 0000000..1eabefb --- /dev/null +++ b/sdk/smart-account/src/generated/types/LimitedSpendingLimit.ts @@ -0,0 +1,37 @@ +/** + * 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 + */ + +import * as web3 from '@solana/web3.js' +import * as beetSolana from '@metaplex-foundation/beet-solana' +import * as beet from '@metaplex-foundation/beet' +import { + LimitedTimeConstraints, + limitedTimeConstraintsBeet, +} from './LimitedTimeConstraints' +import { + LimitedQuantityConstraints, + limitedQuantityConstraintsBeet, +} from './LimitedQuantityConstraints' +export type LimitedSpendingLimit = { + mint: web3.PublicKey + timeConstraints: LimitedTimeConstraints + quantityConstraints: LimitedQuantityConstraints +} + +/** + * @category userTypes + * @category generated + */ +export const limitedSpendingLimitBeet = + new beet.FixableBeetArgsStruct( + [ + ['mint', beetSolana.publicKey], + ['timeConstraints', limitedTimeConstraintsBeet], + ['quantityConstraints', limitedQuantityConstraintsBeet], + ], + 'LimitedSpendingLimit' + ) diff --git a/sdk/smart-account/src/generated/types/LimitedTimeConstraints.ts b/sdk/smart-account/src/generated/types/LimitedTimeConstraints.ts new file mode 100644 index 0000000..e6b7234 --- /dev/null +++ b/sdk/smart-account/src/generated/types/LimitedTimeConstraints.ts @@ -0,0 +1,28 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +import { PeriodV2, periodV2Beet } from './PeriodV2' +export type LimitedTimeConstraints = { + start: beet.bignum + expiration: beet.COption + period: PeriodV2 +} + +/** + * @category userTypes + * @category generated + */ +export const limitedTimeConstraintsBeet = + new beet.FixableBeetArgsStruct( + [ + ['start', beet.i64], + ['expiration', beet.coption(beet.i64)], + ['period', periodV2Beet], + ], + 'LimitedTimeConstraints' + ) diff --git a/sdk/smart-account/src/generated/types/LogEventArgsV2.ts b/sdk/smart-account/src/generated/types/LogEventArgsV2.ts new file mode 100644 index 0000000..4011e1d --- /dev/null +++ b/sdk/smart-account/src/generated/types/LogEventArgsV2.ts @@ -0,0 +1,21 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +export type LogEventArgsV2 = { + event: Uint8Array +} + +/** + * @category userTypes + * @category generated + */ +export const logEventArgsV2Beet = + new beet.FixableBeetArgsStruct( + [['event', beet.bytes]], + 'LogEventArgsV2' + ) diff --git a/sdk/smart-account/src/generated/types/Payload.ts b/sdk/smart-account/src/generated/types/Payload.ts new file mode 100644 index 0000000..a63d1f1 --- /dev/null +++ b/sdk/smart-account/src/generated/types/Payload.ts @@ -0,0 +1,71 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +import { + TransactionPayloadDetails, + transactionPayloadDetailsBeet, +} from './TransactionPayloadDetails' +import { + PolicyActionPayloadDetails, + policyActionPayloadDetailsBeet, +} from './PolicyActionPayloadDetails' +/** + * This type is used to derive the {@link Payload} type as well as the de/serializer. + * However don't refer to it in your code but use the {@link Payload} type instead. + * + * @category userTypes + * @category enums + * @category generated + * @private + */ +export type PayloadRecord = { + TransactionPayload: { fields: [TransactionPayloadDetails] } + PolicyPayload: { fields: [PolicyActionPayloadDetails] } +} + +/** + * Union type respresenting the Payload data enum defined in Rust. + * + * NOTE: that it includes a `__kind` property which allows to narrow types in + * switch/if statements. + * Additionally `isPayload*` type guards are exposed below to narrow to a specific variant. + * + * @category userTypes + * @category enums + * @category generated + */ +export type Payload = beet.DataEnumKeyAsKind + +export const isPayloadTransactionPayload = ( + x: Payload +): x is Payload & { __kind: 'TransactionPayload' } => + x.__kind === 'TransactionPayload' +export const isPayloadPolicyPayload = ( + x: Payload +): x is Payload & { __kind: 'PolicyPayload' } => x.__kind === 'PolicyPayload' + +/** + * @category userTypes + * @category generated + */ +export const payloadBeet = beet.dataEnum([ + [ + 'TransactionPayload', + new beet.FixableBeetArgsStruct( + [['fields', beet.tuple([transactionPayloadDetailsBeet])]], + 'PayloadRecord["TransactionPayload"]' + ), + ], + [ + 'PolicyPayload', + new beet.FixableBeetArgsStruct( + [['fields', beet.tuple([policyActionPayloadDetailsBeet])]], + 'PayloadRecord["PolicyPayload"]' + ), + ], +]) as beet.FixableBeet diff --git a/sdk/smart-account/src/generated/types/PeriodV2.ts b/sdk/smart-account/src/generated/types/PeriodV2.ts new file mode 100644 index 0000000..e58c5c7 --- /dev/null +++ b/sdk/smart-account/src/generated/types/PeriodV2.ts @@ -0,0 +1,71 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +/** + * This type is used to derive the {@link PeriodV2} type as well as the de/serializer. + * However don't refer to it in your code but use the {@link PeriodV2} type instead. + * + * @category userTypes + * @category enums + * @category generated + * @private + */ +export type PeriodV2Record = { + OneTime: void /* scalar variant */ + Daily: void /* scalar variant */ + Weekly: void /* scalar variant */ + Monthly: void /* scalar variant */ + Custom: { fields: [beet.bignum] } +} + +/** + * Union type respresenting the PeriodV2 data enum defined in Rust. + * + * NOTE: that it includes a `__kind` property which allows to narrow types in + * switch/if statements. + * Additionally `isPeriodV2*` type guards are exposed below to narrow to a specific variant. + * + * @category userTypes + * @category enums + * @category generated + */ +export type PeriodV2 = beet.DataEnumKeyAsKind + +export const isPeriodV2OneTime = ( + x: PeriodV2 +): x is PeriodV2 & { __kind: 'OneTime' } => x.__kind === 'OneTime' +export const isPeriodV2Daily = ( + x: PeriodV2 +): x is PeriodV2 & { __kind: 'Daily' } => x.__kind === 'Daily' +export const isPeriodV2Weekly = ( + x: PeriodV2 +): x is PeriodV2 & { __kind: 'Weekly' } => x.__kind === 'Weekly' +export const isPeriodV2Monthly = ( + x: PeriodV2 +): x is PeriodV2 & { __kind: 'Monthly' } => x.__kind === 'Monthly' +export const isPeriodV2Custom = ( + x: PeriodV2 +): x is PeriodV2 & { __kind: 'Custom' } => x.__kind === 'Custom' + +/** + * @category userTypes + * @category generated + */ +export const periodV2Beet = beet.dataEnum([ + ['OneTime', beet.unit], + ['Daily', beet.unit], + ['Weekly', beet.unit], + ['Monthly', beet.unit], + [ + 'Custom', + new beet.BeetArgsStruct( + [['fields', beet.fixedSizeTuple([beet.i64])]], + 'PeriodV2Record["Custom"]' + ), + ], +]) as beet.FixableBeet diff --git a/sdk/smart-account/src/generated/types/PolicyActionPayloadDetails.ts b/sdk/smart-account/src/generated/types/PolicyActionPayloadDetails.ts new file mode 100644 index 0000000..d00412a --- /dev/null +++ b/sdk/smart-account/src/generated/types/PolicyActionPayloadDetails.ts @@ -0,0 +1,22 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +import { PolicyPayload, policyPayloadBeet } from './PolicyPayload' +export type PolicyActionPayloadDetails = { + payload: PolicyPayload +} + +/** + * @category userTypes + * @category generated + */ +export const policyActionPayloadDetailsBeet = + new beet.FixableBeetArgsStruct( + [['payload', policyPayloadBeet]], + 'PolicyActionPayloadDetails' + ) diff --git a/sdk/smart-account/src/generated/types/PolicyCreationPayload.ts b/sdk/smart-account/src/generated/types/PolicyCreationPayload.ts new file mode 100644 index 0000000..6f0e9b9 --- /dev/null +++ b/sdk/smart-account/src/generated/types/PolicyCreationPayload.ts @@ -0,0 +1,119 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +import { + InternalFundTransferPolicyCreationPayload, + internalFundTransferPolicyCreationPayloadBeet, +} from './InternalFundTransferPolicyCreationPayload' +import { + SpendingLimitPolicyCreationPayload, + spendingLimitPolicyCreationPayloadBeet, +} from './SpendingLimitPolicyCreationPayload' +import { + SettingsChangePolicyCreationPayload, + settingsChangePolicyCreationPayloadBeet, +} from './SettingsChangePolicyCreationPayload' +import { + ProgramInteractionPolicyCreationPayload, + programInteractionPolicyCreationPayloadBeet, +} from './ProgramInteractionPolicyCreationPayload' +/** + * This type is used to derive the {@link PolicyCreationPayload} type as well as the de/serializer. + * However don't refer to it in your code but use the {@link PolicyCreationPayload} type instead. + * + * @category userTypes + * @category enums + * @category generated + * @private + */ +export type PolicyCreationPayloadRecord = { + InternalFundTransfer: { fields: [InternalFundTransferPolicyCreationPayload] } + SpendingLimit: { fields: [SpendingLimitPolicyCreationPayload] } + SettingsChange: { fields: [SettingsChangePolicyCreationPayload] } + ProgramInteraction: { fields: [ProgramInteractionPolicyCreationPayload] } +} + +/** + * Union type respresenting the PolicyCreationPayload data enum defined in Rust. + * + * NOTE: that it includes a `__kind` property which allows to narrow types in + * switch/if statements. + * Additionally `isPolicyCreationPayload*` type guards are exposed below to narrow to a specific variant. + * + * @category userTypes + * @category enums + * @category generated + */ +export type PolicyCreationPayload = + beet.DataEnumKeyAsKind + +export const isPolicyCreationPayloadInternalFundTransfer = ( + x: PolicyCreationPayload +): x is PolicyCreationPayload & { __kind: 'InternalFundTransfer' } => + x.__kind === 'InternalFundTransfer' +export const isPolicyCreationPayloadSpendingLimit = ( + x: PolicyCreationPayload +): x is PolicyCreationPayload & { __kind: 'SpendingLimit' } => + x.__kind === 'SpendingLimit' +export const isPolicyCreationPayloadSettingsChange = ( + x: PolicyCreationPayload +): x is PolicyCreationPayload & { __kind: 'SettingsChange' } => + x.__kind === 'SettingsChange' +export const isPolicyCreationPayloadProgramInteraction = ( + x: PolicyCreationPayload +): x is PolicyCreationPayload & { __kind: 'ProgramInteraction' } => + x.__kind === 'ProgramInteraction' + +/** + * @category userTypes + * @category generated + */ +export const policyCreationPayloadBeet = + beet.dataEnum([ + [ + 'InternalFundTransfer', + new beet.FixableBeetArgsStruct< + PolicyCreationPayloadRecord['InternalFundTransfer'] + >( + [ + [ + 'fields', + beet.tuple([internalFundTransferPolicyCreationPayloadBeet]), + ], + ], + 'PolicyCreationPayloadRecord["InternalFundTransfer"]' + ), + ], + [ + 'SpendingLimit', + new beet.FixableBeetArgsStruct< + PolicyCreationPayloadRecord['SpendingLimit'] + >( + [['fields', beet.tuple([spendingLimitPolicyCreationPayloadBeet])]], + 'PolicyCreationPayloadRecord["SpendingLimit"]' + ), + ], + [ + 'SettingsChange', + new beet.FixableBeetArgsStruct< + PolicyCreationPayloadRecord['SettingsChange'] + >( + [['fields', beet.tuple([settingsChangePolicyCreationPayloadBeet])]], + 'PolicyCreationPayloadRecord["SettingsChange"]' + ), + ], + [ + 'ProgramInteraction', + new beet.FixableBeetArgsStruct< + PolicyCreationPayloadRecord['ProgramInteraction'] + >( + [['fields', beet.tuple([programInteractionPolicyCreationPayloadBeet])]], + 'PolicyCreationPayloadRecord["ProgramInteraction"]' + ), + ], + ]) as beet.FixableBeet diff --git a/sdk/smart-account/src/generated/types/PolicyEventType.ts b/sdk/smart-account/src/generated/types/PolicyEventType.ts new file mode 100644 index 0000000..c87188b --- /dev/null +++ b/sdk/smart-account/src/generated/types/PolicyEventType.ts @@ -0,0 +1,26 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +/** + * @category enums + * @category generated + */ +export enum PolicyEventType { + Create, + Update, + UpdateDuringExecution, + Remove, +} + +/** + * @category userTypes + * @category generated + */ +export const policyEventTypeBeet = beet.fixedScalarEnum( + PolicyEventType +) as beet.FixedSizeBeet diff --git a/sdk/smart-account/src/generated/types/PolicyExecutionContext.ts b/sdk/smart-account/src/generated/types/PolicyExecutionContext.ts new file mode 100644 index 0000000..1c96fb7 --- /dev/null +++ b/sdk/smart-account/src/generated/types/PolicyExecutionContext.ts @@ -0,0 +1,24 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +/** + * @category enums + * @category generated + */ +export enum PolicyExecutionContext { + Synchronous, + Asynchronous, +} + +/** + * @category userTypes + * @category generated + */ +export const policyExecutionContextBeet = beet.fixedScalarEnum( + PolicyExecutionContext +) as beet.FixedSizeBeet diff --git a/sdk/smart-account/src/generated/types/PolicyExpiration.ts b/sdk/smart-account/src/generated/types/PolicyExpiration.ts new file mode 100644 index 0000000..6c029fe --- /dev/null +++ b/sdk/smart-account/src/generated/types/PolicyExpiration.ts @@ -0,0 +1,68 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +/** + * This type is used to derive the {@link PolicyExpiration} type as well as the de/serializer. + * However don't refer to it in your code but use the {@link PolicyExpiration} type instead. + * + * @category userTypes + * @category enums + * @category generated + * @private + */ +export type PolicyExpirationRecord = { + Timestamp: { fields: [beet.bignum] } + SettingsState: { fields: [number[] /* size: 32 */] } +} + +/** + * Union type respresenting the PolicyExpiration data enum defined in Rust. + * + * NOTE: that it includes a `__kind` property which allows to narrow types in + * switch/if statements. + * Additionally `isPolicyExpiration*` type guards are exposed below to narrow to a specific variant. + * + * @category userTypes + * @category enums + * @category generated + */ +export type PolicyExpiration = beet.DataEnumKeyAsKind + +export const isPolicyExpirationTimestamp = ( + x: PolicyExpiration +): x is PolicyExpiration & { __kind: 'Timestamp' } => x.__kind === 'Timestamp' +export const isPolicyExpirationSettingsState = ( + x: PolicyExpiration +): x is PolicyExpiration & { __kind: 'SettingsState' } => + x.__kind === 'SettingsState' + +/** + * @category userTypes + * @category generated + */ +export const policyExpirationBeet = beet.dataEnum([ + [ + 'Timestamp', + new beet.BeetArgsStruct( + [['fields', beet.fixedSizeTuple([beet.i64])]], + 'PolicyExpirationRecord["Timestamp"]' + ), + ], + [ + 'SettingsState', + new beet.BeetArgsStruct( + [ + [ + 'fields', + beet.fixedSizeTuple([beet.uniformFixedSizeArray(beet.u8, 32)]), + ], + ], + 'PolicyExpirationRecord["SettingsState"]' + ), + ], +]) as beet.FixableBeet diff --git a/sdk/smart-account/src/generated/types/PolicyExpirationArgs.ts b/sdk/smart-account/src/generated/types/PolicyExpirationArgs.ts new file mode 100644 index 0000000..ba2a7f6 --- /dev/null +++ b/sdk/smart-account/src/generated/types/PolicyExpirationArgs.ts @@ -0,0 +1,60 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +/** + * This type is used to derive the {@link PolicyExpirationArgs} type as well as the de/serializer. + * However don't refer to it in your code but use the {@link PolicyExpirationArgs} type instead. + * + * @category userTypes + * @category enums + * @category generated + * @private + */ +export type PolicyExpirationArgsRecord = { + Timestamp: { fields: [beet.bignum] } + SettingsState: void /* scalar variant */ +} + +/** + * Union type respresenting the PolicyExpirationArgs data enum defined in Rust. + * + * NOTE: that it includes a `__kind` property which allows to narrow types in + * switch/if statements. + * Additionally `isPolicyExpirationArgs*` type guards are exposed below to narrow to a specific variant. + * + * @category userTypes + * @category enums + * @category generated + */ +export type PolicyExpirationArgs = + beet.DataEnumKeyAsKind + +export const isPolicyExpirationArgsTimestamp = ( + x: PolicyExpirationArgs +): x is PolicyExpirationArgs & { __kind: 'Timestamp' } => + x.__kind === 'Timestamp' +export const isPolicyExpirationArgsSettingsState = ( + x: PolicyExpirationArgs +): x is PolicyExpirationArgs & { __kind: 'SettingsState' } => + x.__kind === 'SettingsState' + +/** + * @category userTypes + * @category generated + */ +export const policyExpirationArgsBeet = + beet.dataEnum([ + [ + 'Timestamp', + new beet.BeetArgsStruct( + [['fields', beet.fixedSizeTuple([beet.i64])]], + 'PolicyExpirationArgsRecord["Timestamp"]' + ), + ], + ['SettingsState', beet.unit], + ]) as beet.FixableBeet diff --git a/sdk/smart-account/src/generated/types/PolicyPayload.ts b/sdk/smart-account/src/generated/types/PolicyPayload.ts new file mode 100644 index 0000000..14b627a --- /dev/null +++ b/sdk/smart-account/src/generated/types/PolicyPayload.ts @@ -0,0 +1,104 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +import { + InternalFundTransferPayload, + internalFundTransferPayloadBeet, +} from './InternalFundTransferPayload' +import { + ProgramInteractionPayload, + programInteractionPayloadBeet, +} from './ProgramInteractionPayload' +import { + SpendingLimitPayload, + spendingLimitPayloadBeet, +} from './SpendingLimitPayload' +import { + SettingsChangePayload, + settingsChangePayloadBeet, +} from './SettingsChangePayload' +/** + * This type is used to derive the {@link PolicyPayload} type as well as the de/serializer. + * However don't refer to it in your code but use the {@link PolicyPayload} type instead. + * + * @category userTypes + * @category enums + * @category generated + * @private + */ +export type PolicyPayloadRecord = { + InternalFundTransfer: { fields: [InternalFundTransferPayload] } + ProgramInteraction: { fields: [ProgramInteractionPayload] } + SpendingLimit: { fields: [SpendingLimitPayload] } + SettingsChange: { fields: [SettingsChangePayload] } +} + +/** + * Union type respresenting the PolicyPayload data enum defined in Rust. + * + * NOTE: that it includes a `__kind` property which allows to narrow types in + * switch/if statements. + * Additionally `isPolicyPayload*` type guards are exposed below to narrow to a specific variant. + * + * @category userTypes + * @category enums + * @category generated + */ +export type PolicyPayload = beet.DataEnumKeyAsKind + +export const isPolicyPayloadInternalFundTransfer = ( + x: PolicyPayload +): x is PolicyPayload & { __kind: 'InternalFundTransfer' } => + x.__kind === 'InternalFundTransfer' +export const isPolicyPayloadProgramInteraction = ( + x: PolicyPayload +): x is PolicyPayload & { __kind: 'ProgramInteraction' } => + x.__kind === 'ProgramInteraction' +export const isPolicyPayloadSpendingLimit = ( + x: PolicyPayload +): x is PolicyPayload & { __kind: 'SpendingLimit' } => + x.__kind === 'SpendingLimit' +export const isPolicyPayloadSettingsChange = ( + x: PolicyPayload +): x is PolicyPayload & { __kind: 'SettingsChange' } => + x.__kind === 'SettingsChange' + +/** + * @category userTypes + * @category generated + */ +export const policyPayloadBeet = beet.dataEnum([ + [ + 'InternalFundTransfer', + new beet.BeetArgsStruct( + [['fields', beet.fixedSizeTuple([internalFundTransferPayloadBeet])]], + 'PolicyPayloadRecord["InternalFundTransfer"]' + ), + ], + [ + 'ProgramInteraction', + new beet.FixableBeetArgsStruct( + [['fields', beet.tuple([programInteractionPayloadBeet])]], + 'PolicyPayloadRecord["ProgramInteraction"]' + ), + ], + [ + 'SpendingLimit', + new beet.BeetArgsStruct( + [['fields', beet.fixedSizeTuple([spendingLimitPayloadBeet])]], + 'PolicyPayloadRecord["SpendingLimit"]' + ), + ], + [ + 'SettingsChange', + new beet.FixableBeetArgsStruct( + [['fields', beet.tuple([settingsChangePayloadBeet])]], + 'PolicyPayloadRecord["SettingsChange"]' + ), + ], +]) as beet.FixableBeet diff --git a/sdk/smart-account/src/generated/types/PolicyState.ts b/sdk/smart-account/src/generated/types/PolicyState.ts new file mode 100644 index 0000000..45166c9 --- /dev/null +++ b/sdk/smart-account/src/generated/types/PolicyState.ts @@ -0,0 +1,104 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +import { + InternalFundTransferPolicy, + internalFundTransferPolicyBeet, +} from './InternalFundTransferPolicy' +import { + SpendingLimitPolicy, + spendingLimitPolicyBeet, +} from './SpendingLimitPolicy' +import { + SettingsChangePolicy, + settingsChangePolicyBeet, +} from './SettingsChangePolicy' +import { + ProgramInteractionPolicy, + programInteractionPolicyBeet, +} from './ProgramInteractionPolicy' +/** + * This type is used to derive the {@link PolicyState} type as well as the de/serializer. + * However don't refer to it in your code but use the {@link PolicyState} type instead. + * + * @category userTypes + * @category enums + * @category generated + * @private + */ +export type PolicyStateRecord = { + InternalFundTransfer: { fields: [InternalFundTransferPolicy] } + SpendingLimit: { fields: [SpendingLimitPolicy] } + SettingsChange: { fields: [SettingsChangePolicy] } + ProgramInteraction: { fields: [ProgramInteractionPolicy] } +} + +/** + * Union type respresenting the PolicyState data enum defined in Rust. + * + * NOTE: that it includes a `__kind` property which allows to narrow types in + * switch/if statements. + * Additionally `isPolicyState*` type guards are exposed below to narrow to a specific variant. + * + * @category userTypes + * @category enums + * @category generated + */ +export type PolicyState = beet.DataEnumKeyAsKind + +export const isPolicyStateInternalFundTransfer = ( + x: PolicyState +): x is PolicyState & { __kind: 'InternalFundTransfer' } => + x.__kind === 'InternalFundTransfer' +export const isPolicyStateSpendingLimit = ( + x: PolicyState +): x is PolicyState & { __kind: 'SpendingLimit' } => + x.__kind === 'SpendingLimit' +export const isPolicyStateSettingsChange = ( + x: PolicyState +): x is PolicyState & { __kind: 'SettingsChange' } => + x.__kind === 'SettingsChange' +export const isPolicyStateProgramInteraction = ( + x: PolicyState +): x is PolicyState & { __kind: 'ProgramInteraction' } => + x.__kind === 'ProgramInteraction' + +/** + * @category userTypes + * @category generated + */ +export const policyStateBeet = beet.dataEnum([ + [ + 'InternalFundTransfer', + new beet.FixableBeetArgsStruct( + [['fields', beet.tuple([internalFundTransferPolicyBeet])]], + 'PolicyStateRecord["InternalFundTransfer"]' + ), + ], + [ + 'SpendingLimit', + new beet.FixableBeetArgsStruct( + [['fields', beet.tuple([spendingLimitPolicyBeet])]], + 'PolicyStateRecord["SpendingLimit"]' + ), + ], + [ + 'SettingsChange', + new beet.FixableBeetArgsStruct( + [['fields', beet.tuple([settingsChangePolicyBeet])]], + 'PolicyStateRecord["SettingsChange"]' + ), + ], + [ + 'ProgramInteraction', + new beet.FixableBeetArgsStruct( + [['fields', beet.tuple([programInteractionPolicyBeet])]], + 'PolicyStateRecord["ProgramInteraction"]' + ), + ], +]) as beet.FixableBeet diff --git a/sdk/smart-account/src/generated/types/ProgramInteractionPayload.ts b/sdk/smart-account/src/generated/types/ProgramInteractionPayload.ts new file mode 100644 index 0000000..aa0d4be --- /dev/null +++ b/sdk/smart-account/src/generated/types/ProgramInteractionPayload.ts @@ -0,0 +1,29 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +import { + ProgramInteractionTransactionPayload, + programInteractionTransactionPayloadBeet, +} from './ProgramInteractionTransactionPayload' +export type ProgramInteractionPayload = { + instructionConstraintIndices: beet.COption + transactionPayload: ProgramInteractionTransactionPayload +} + +/** + * @category userTypes + * @category generated + */ +export const programInteractionPayloadBeet = + new beet.FixableBeetArgsStruct( + [ + ['instructionConstraintIndices', beet.coption(beet.bytes)], + ['transactionPayload', programInteractionTransactionPayloadBeet], + ], + 'ProgramInteractionPayload' + ) diff --git a/sdk/smart-account/src/generated/types/ProgramInteractionPolicy.ts b/sdk/smart-account/src/generated/types/ProgramInteractionPolicy.ts new file mode 100644 index 0000000..62814bc --- /dev/null +++ b/sdk/smart-account/src/generated/types/ProgramInteractionPolicy.ts @@ -0,0 +1,37 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +import { + InstructionConstraint, + instructionConstraintBeet, +} from './InstructionConstraint' +import { Hook, hookBeet } from './Hook' +import { SpendingLimitV2, spendingLimitV2Beet } from './SpendingLimitV2' +export type ProgramInteractionPolicy = { + accountIndex: number + instructionsConstraints: InstructionConstraint[] + preHook: beet.COption + postHook: beet.COption + spendingLimits: SpendingLimitV2[] +} + +/** + * @category userTypes + * @category generated + */ +export const programInteractionPolicyBeet = + new beet.FixableBeetArgsStruct( + [ + ['accountIndex', beet.u8], + ['instructionsConstraints', beet.array(instructionConstraintBeet)], + ['preHook', beet.coption(hookBeet)], + ['postHook', beet.coption(hookBeet)], + ['spendingLimits', beet.array(spendingLimitV2Beet)], + ], + 'ProgramInteractionPolicy' + ) diff --git a/sdk/smart-account/src/generated/types/ProgramInteractionPolicyCreationPayload.ts b/sdk/smart-account/src/generated/types/ProgramInteractionPolicyCreationPayload.ts new file mode 100644 index 0000000..0056f36 --- /dev/null +++ b/sdk/smart-account/src/generated/types/ProgramInteractionPolicyCreationPayload.ts @@ -0,0 +1,40 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +import { + InstructionConstraint, + instructionConstraintBeet, +} from './InstructionConstraint' +import { Hook, hookBeet } from './Hook' +import { + LimitedSpendingLimit, + limitedSpendingLimitBeet, +} from './LimitedSpendingLimit' +export type ProgramInteractionPolicyCreationPayload = { + accountIndex: number + instructionsConstraints: InstructionConstraint[] + preHook: beet.COption + postHook: beet.COption + spendingLimits: LimitedSpendingLimit[] +} + +/** + * @category userTypes + * @category generated + */ +export const programInteractionPolicyCreationPayloadBeet = + new beet.FixableBeetArgsStruct( + [ + ['accountIndex', beet.u8], + ['instructionsConstraints', beet.array(instructionConstraintBeet)], + ['preHook', beet.coption(hookBeet)], + ['postHook', beet.coption(hookBeet)], + ['spendingLimits', beet.array(limitedSpendingLimitBeet)], + ], + 'ProgramInteractionPolicyCreationPayload' + ) diff --git a/sdk/smart-account/src/generated/types/ProgramInteractionTransactionPayload.ts b/sdk/smart-account/src/generated/types/ProgramInteractionTransactionPayload.ts new file mode 100644 index 0000000..42d8e96 --- /dev/null +++ b/sdk/smart-account/src/generated/types/ProgramInteractionTransactionPayload.ts @@ -0,0 +1,81 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +import { + TransactionPayload, + transactionPayloadBeet, +} from './TransactionPayload' +import { + SyncTransactionPayloadDetails, + syncTransactionPayloadDetailsBeet, +} from './SyncTransactionPayloadDetails' +/** + * This type is used to derive the {@link ProgramInteractionTransactionPayload} type as well as the de/serializer. + * However don't refer to it in your code but use the {@link ProgramInteractionTransactionPayload} type instead. + * + * @category userTypes + * @category enums + * @category generated + * @private + */ +export type ProgramInteractionTransactionPayloadRecord = { + AsyncTransaction: { fields: [TransactionPayload] } + SyncTransaction: { fields: [SyncTransactionPayloadDetails] } +} + +/** + * Union type respresenting the ProgramInteractionTransactionPayload data enum defined in Rust. + * + * NOTE: that it includes a `__kind` property which allows to narrow types in + * switch/if statements. + * Additionally `isProgramInteractionTransactionPayload*` type guards are exposed below to narrow to a specific variant. + * + * @category userTypes + * @category enums + * @category generated + */ +export type ProgramInteractionTransactionPayload = + beet.DataEnumKeyAsKind + +export const isProgramInteractionTransactionPayloadAsyncTransaction = ( + x: ProgramInteractionTransactionPayload +): x is ProgramInteractionTransactionPayload & { __kind: 'AsyncTransaction' } => + x.__kind === 'AsyncTransaction' +export const isProgramInteractionTransactionPayloadSyncTransaction = ( + x: ProgramInteractionTransactionPayload +): x is ProgramInteractionTransactionPayload & { __kind: 'SyncTransaction' } => + x.__kind === 'SyncTransaction' + +/** + * @category userTypes + * @category generated + */ +export const programInteractionTransactionPayloadBeet = + beet.dataEnum([ + [ + 'AsyncTransaction', + new beet.FixableBeetArgsStruct< + ProgramInteractionTransactionPayloadRecord['AsyncTransaction'] + >( + [['fields', beet.tuple([transactionPayloadBeet])]], + 'ProgramInteractionTransactionPayloadRecord["AsyncTransaction"]' + ), + ], + [ + 'SyncTransaction', + new beet.FixableBeetArgsStruct< + ProgramInteractionTransactionPayloadRecord['SyncTransaction'] + >( + [['fields', beet.tuple([syncTransactionPayloadDetailsBeet])]], + 'ProgramInteractionTransactionPayloadRecord["SyncTransaction"]' + ), + ], + ]) as beet.FixableBeet< + ProgramInteractionTransactionPayload, + ProgramInteractionTransactionPayload + > diff --git a/sdk/smart-account/src/generated/types/ProposalEventType.ts b/sdk/smart-account/src/generated/types/ProposalEventType.ts new file mode 100644 index 0000000..51ac464 --- /dev/null +++ b/sdk/smart-account/src/generated/types/ProposalEventType.ts @@ -0,0 +1,28 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +/** + * @category enums + * @category generated + */ +export enum ProposalEventType { + Create, + Approve, + Reject, + Cancel, + Execute, + Close, +} + +/** + * @category userTypes + * @category generated + */ +export const proposalEventTypeBeet = beet.fixedScalarEnum( + ProposalEventType +) as beet.FixedSizeBeet diff --git a/sdk/smart-account/src/generated/types/QuantityConstraints.ts b/sdk/smart-account/src/generated/types/QuantityConstraints.ts new file mode 100644 index 0000000..0ef464d --- /dev/null +++ b/sdk/smart-account/src/generated/types/QuantityConstraints.ts @@ -0,0 +1,27 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +export type QuantityConstraints = { + maxPerPeriod: beet.bignum + maxPerUse: beet.bignum + enforceExactQuantity: boolean +} + +/** + * @category userTypes + * @category generated + */ +export const quantityConstraintsBeet = + new beet.BeetArgsStruct( + [ + ['maxPerPeriod', beet.u64], + ['maxPerUse', beet.u64], + ['enforceExactQuantity', beet.bool], + ], + 'QuantityConstraints' + ) diff --git a/sdk/smart-account/src/generated/types/SettingsAction.ts b/sdk/smart-account/src/generated/types/SettingsAction.ts index ef8f478..90b956d 100644 --- a/sdk/smart-account/src/generated/types/SettingsAction.ts +++ b/sdk/smart-account/src/generated/types/SettingsAction.ts @@ -13,6 +13,14 @@ import { smartAccountSignerBeet, } from './SmartAccountSigner' import { Period, periodBeet } from './Period' +import { + PolicyCreationPayload, + policyCreationPayloadBeet, +} from './PolicyCreationPayload' +import { + PolicyExpirationArgs, + policyExpirationArgsBeet, +} from './PolicyExpirationArgs' /** * This type is used to derive the {@link SettingsAction} type as well as the de/serializer. * However don't refer to it in your code but use the {@link SettingsAction} type instead. @@ -39,6 +47,24 @@ export type SettingsActionRecord = { } RemoveSpendingLimit: { spendingLimit: web3.PublicKey } SetArchivalAuthority: { newArchivalAuthority: beet.COption } + PolicyCreate: { + seed: beet.bignum + policyCreationPayload: PolicyCreationPayload + signers: SmartAccountSigner[] + threshold: number + timeLock: number + startTimestamp: beet.COption + expirationArgs: beet.COption + } + PolicyUpdate: { + policy: web3.PublicKey + signers: SmartAccountSigner[] + threshold: number + timeLock: number + policyUpdatePayload: PolicyCreationPayload + expirationArgs: beet.COption + } + PolicyRemove: { policy: web3.PublicKey } } /** @@ -80,6 +106,18 @@ export const isSettingsActionSetArchivalAuthority = ( x: SettingsAction ): x is SettingsAction & { __kind: 'SetArchivalAuthority' } => x.__kind === 'SetArchivalAuthority' +export const isSettingsActionPolicyCreate = ( + x: SettingsAction +): x is SettingsAction & { __kind: 'PolicyCreate' } => + x.__kind === 'PolicyCreate' +export const isSettingsActionPolicyUpdate = ( + x: SettingsAction +): x is SettingsAction & { __kind: 'PolicyUpdate' } => + x.__kind === 'PolicyUpdate' +export const isSettingsActionPolicyRemove = ( + x: SettingsAction +): x is SettingsAction & { __kind: 'PolicyRemove' } => + x.__kind === 'PolicyRemove' /** * @category userTypes @@ -152,4 +190,43 @@ export const settingsActionBeet = beet.dataEnum([ 'SettingsActionRecord["SetArchivalAuthority"]' ), ], + + [ + 'PolicyCreate', + new beet.FixableBeetArgsStruct( + [ + ['seed', beet.u64], + ['policyCreationPayload', policyCreationPayloadBeet], + ['signers', beet.array(smartAccountSignerBeet)], + ['threshold', beet.u16], + ['timeLock', beet.u32], + ['startTimestamp', beet.coption(beet.i64)], + ['expirationArgs', beet.coption(policyExpirationArgsBeet)], + ], + 'SettingsActionRecord["PolicyCreate"]' + ), + ], + + [ + 'PolicyUpdate', + new beet.FixableBeetArgsStruct( + [ + ['policy', beetSolana.publicKey], + ['signers', beet.array(smartAccountSignerBeet)], + ['threshold', beet.u16], + ['timeLock', beet.u32], + ['policyUpdatePayload', policyCreationPayloadBeet], + ['expirationArgs', beet.coption(policyExpirationArgsBeet)], + ], + 'SettingsActionRecord["PolicyUpdate"]' + ), + ], + + [ + 'PolicyRemove', + new beet.BeetArgsStruct( + [['policy', beetSolana.publicKey]], + 'SettingsActionRecord["PolicyRemove"]' + ), + ], ]) as beet.FixableBeet diff --git a/sdk/smart-account/src/generated/types/SettingsChangePayload.ts b/sdk/smart-account/src/generated/types/SettingsChangePayload.ts new file mode 100644 index 0000000..164cbb4 --- /dev/null +++ b/sdk/smart-account/src/generated/types/SettingsChangePayload.ts @@ -0,0 +1,29 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +import { + LimitedSettingsAction, + limitedSettingsActionBeet, +} from './LimitedSettingsAction' +export type SettingsChangePayload = { + actionIndex: Uint8Array + actions: LimitedSettingsAction[] +} + +/** + * @category userTypes + * @category generated + */ +export const settingsChangePayloadBeet = + new beet.FixableBeetArgsStruct( + [ + ['actionIndex', beet.bytes], + ['actions', beet.array(limitedSettingsActionBeet)], + ], + 'SettingsChangePayload' + ) diff --git a/sdk/smart-account/src/generated/types/SettingsChangePolicy.ts b/sdk/smart-account/src/generated/types/SettingsChangePolicy.ts new file mode 100644 index 0000000..439a384 --- /dev/null +++ b/sdk/smart-account/src/generated/types/SettingsChangePolicy.ts @@ -0,0 +1,25 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +import { + AllowedSettingsChange, + allowedSettingsChangeBeet, +} from './AllowedSettingsChange' +export type SettingsChangePolicy = { + actions: AllowedSettingsChange[] +} + +/** + * @category userTypes + * @category generated + */ +export const settingsChangePolicyBeet = + new beet.FixableBeetArgsStruct( + [['actions', beet.array(allowedSettingsChangeBeet)]], + 'SettingsChangePolicy' + ) diff --git a/sdk/smart-account/src/generated/types/SettingsChangePolicyCreationPayload.ts b/sdk/smart-account/src/generated/types/SettingsChangePolicyCreationPayload.ts new file mode 100644 index 0000000..326d433 --- /dev/null +++ b/sdk/smart-account/src/generated/types/SettingsChangePolicyCreationPayload.ts @@ -0,0 +1,25 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +import { + AllowedSettingsChange, + allowedSettingsChangeBeet, +} from './AllowedSettingsChange' +export type SettingsChangePolicyCreationPayload = { + actions: AllowedSettingsChange[] +} + +/** + * @category userTypes + * @category generated + */ +export const settingsChangePolicyCreationPayloadBeet = + new beet.FixableBeetArgsStruct( + [['actions', beet.array(allowedSettingsChangeBeet)]], + 'SettingsChangePolicyCreationPayload' + ) diff --git a/sdk/smart-account/src/generated/types/SpendingLimitPayload.ts b/sdk/smart-account/src/generated/types/SpendingLimitPayload.ts new file mode 100644 index 0000000..ea18758 --- /dev/null +++ b/sdk/smart-account/src/generated/types/SpendingLimitPayload.ts @@ -0,0 +1,29 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +import * as web3 from '@solana/web3.js' +import * as beetSolana from '@metaplex-foundation/beet-solana' +export type SpendingLimitPayload = { + amount: beet.bignum + destination: web3.PublicKey + decimals: number +} + +/** + * @category userTypes + * @category generated + */ +export const spendingLimitPayloadBeet = + new beet.BeetArgsStruct( + [ + ['amount', beet.u64], + ['destination', beetSolana.publicKey], + ['decimals', beet.u8], + ], + 'SpendingLimitPayload' + ) diff --git a/sdk/smart-account/src/generated/types/SpendingLimitPolicy.ts b/sdk/smart-account/src/generated/types/SpendingLimitPolicy.ts new file mode 100644 index 0000000..34a9ec9 --- /dev/null +++ b/sdk/smart-account/src/generated/types/SpendingLimitPolicy.ts @@ -0,0 +1,30 @@ +/** + * 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 + */ + +import * as web3 from '@solana/web3.js' +import * as beet from '@metaplex-foundation/beet' +import * as beetSolana from '@metaplex-foundation/beet-solana' +import { SpendingLimitV2, spendingLimitV2Beet } from './SpendingLimitV2' +export type SpendingLimitPolicy = { + sourceAccountIndex: number + destinations: web3.PublicKey[] + spendingLimit: SpendingLimitV2 +} + +/** + * @category userTypes + * @category generated + */ +export const spendingLimitPolicyBeet = + new beet.FixableBeetArgsStruct( + [ + ['sourceAccountIndex', beet.u8], + ['destinations', beet.array(beetSolana.publicKey)], + ['spendingLimit', spendingLimitV2Beet], + ], + 'SpendingLimitPolicy' + ) diff --git a/sdk/smart-account/src/generated/types/SpendingLimitPolicyCreationPayload.ts b/sdk/smart-account/src/generated/types/SpendingLimitPolicyCreationPayload.ts new file mode 100644 index 0000000..e9594dc --- /dev/null +++ b/sdk/smart-account/src/generated/types/SpendingLimitPolicyCreationPayload.ts @@ -0,0 +1,41 @@ +/** + * 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 + */ + +import * as web3 from '@solana/web3.js' +import * as beet from '@metaplex-foundation/beet' +import * as beetSolana from '@metaplex-foundation/beet-solana' +import { TimeConstraints, timeConstraintsBeet } from './TimeConstraints' +import { + QuantityConstraints, + quantityConstraintsBeet, +} from './QuantityConstraints' +import { UsageState, usageStateBeet } from './UsageState' +export type SpendingLimitPolicyCreationPayload = { + mint: web3.PublicKey + sourceAccountIndex: number + timeConstraints: TimeConstraints + quantityConstraints: QuantityConstraints + usageState: beet.COption + destinations: web3.PublicKey[] +} + +/** + * @category userTypes + * @category generated + */ +export const spendingLimitPolicyCreationPayloadBeet = + new beet.FixableBeetArgsStruct( + [ + ['mint', beetSolana.publicKey], + ['sourceAccountIndex', beet.u8], + ['timeConstraints', timeConstraintsBeet], + ['quantityConstraints', quantityConstraintsBeet], + ['usageState', beet.coption(usageStateBeet)], + ['destinations', beet.array(beetSolana.publicKey)], + ], + 'SpendingLimitPolicyCreationPayload' + ) diff --git a/sdk/smart-account/src/generated/types/SpendingLimitV2.ts b/sdk/smart-account/src/generated/types/SpendingLimitV2.ts new file mode 100644 index 0000000..5990565 --- /dev/null +++ b/sdk/smart-account/src/generated/types/SpendingLimitV2.ts @@ -0,0 +1,37 @@ +/** + * 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 + */ + +import * as web3 from '@solana/web3.js' +import * as beetSolana from '@metaplex-foundation/beet-solana' +import * as beet from '@metaplex-foundation/beet' +import { TimeConstraints, timeConstraintsBeet } from './TimeConstraints' +import { + QuantityConstraints, + quantityConstraintsBeet, +} from './QuantityConstraints' +import { UsageState, usageStateBeet } from './UsageState' +export type SpendingLimitV2 = { + mint: web3.PublicKey + timeConstraints: TimeConstraints + quantityConstraints: QuantityConstraints + usage: UsageState +} + +/** + * @category userTypes + * @category generated + */ +export const spendingLimitV2Beet = + new beet.FixableBeetArgsStruct( + [ + ['mint', beetSolana.publicKey], + ['timeConstraints', timeConstraintsBeet], + ['quantityConstraints', quantityConstraintsBeet], + ['usage', usageStateBeet], + ], + 'SpendingLimitV2' + ) diff --git a/sdk/smart-account/src/generated/types/SyncPayload.ts b/sdk/smart-account/src/generated/types/SyncPayload.ts new file mode 100644 index 0000000..f7ab739 --- /dev/null +++ b/sdk/smart-account/src/generated/types/SyncPayload.ts @@ -0,0 +1,63 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +import { PolicyPayload, policyPayloadBeet } from './PolicyPayload' +/** + * This type is used to derive the {@link SyncPayload} type as well as the de/serializer. + * However don't refer to it in your code but use the {@link SyncPayload} type instead. + * + * @category userTypes + * @category enums + * @category generated + * @private + */ +export type SyncPayloadRecord = { + Transaction: { fields: [Uint8Array] } + Policy: { fields: [PolicyPayload] } +} + +/** + * Union type respresenting the SyncPayload data enum defined in Rust. + * + * NOTE: that it includes a `__kind` property which allows to narrow types in + * switch/if statements. + * Additionally `isSyncPayload*` type guards are exposed below to narrow to a specific variant. + * + * @category userTypes + * @category enums + * @category generated + */ +export type SyncPayload = beet.DataEnumKeyAsKind + +export const isSyncPayloadTransaction = ( + x: SyncPayload +): x is SyncPayload & { __kind: 'Transaction' } => x.__kind === 'Transaction' +export const isSyncPayloadPolicy = ( + x: SyncPayload +): x is SyncPayload & { __kind: 'Policy' } => x.__kind === 'Policy' + +/** + * @category userTypes + * @category generated + */ +export const syncPayloadBeet = beet.dataEnum([ + [ + 'Transaction', + new beet.FixableBeetArgsStruct( + [['fields', beet.tuple([beet.bytes])]], + 'SyncPayloadRecord["Transaction"]' + ), + ], + [ + 'Policy', + new beet.FixableBeetArgsStruct( + [['fields', beet.tuple([policyPayloadBeet])]], + 'SyncPayloadRecord["Policy"]' + ), + ], +]) as beet.FixableBeet diff --git a/sdk/smart-account/src/generated/types/SyncTransactionArgs.ts b/sdk/smart-account/src/generated/types/SyncTransactionArgs.ts index d4969fc..32a0612 100644 --- a/sdk/smart-account/src/generated/types/SyncTransactionArgs.ts +++ b/sdk/smart-account/src/generated/types/SyncTransactionArgs.ts @@ -6,10 +6,11 @@ */ import * as beet from '@metaplex-foundation/beet' +import { SyncPayload, syncPayloadBeet } from './SyncPayload' export type SyncTransactionArgs = { accountIndex: number numSigners: number - instructions: Uint8Array + payload: SyncPayload } /** @@ -21,7 +22,7 @@ export const syncTransactionArgsBeet = [ ['accountIndex', beet.u8], ['numSigners', beet.u8], - ['instructions', beet.bytes], + ['payload', syncPayloadBeet], ], 'SyncTransactionArgs' ) diff --git a/sdk/smart-account/src/generated/types/SyncTransactionPayloadDetails.ts b/sdk/smart-account/src/generated/types/SyncTransactionPayloadDetails.ts new file mode 100644 index 0000000..46e09b3 --- /dev/null +++ b/sdk/smart-account/src/generated/types/SyncTransactionPayloadDetails.ts @@ -0,0 +1,25 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +export type SyncTransactionPayloadDetails = { + accountIndex: number + instructions: Uint8Array +} + +/** + * @category userTypes + * @category generated + */ +export const syncTransactionPayloadDetailsBeet = + new beet.FixableBeetArgsStruct( + [ + ['accountIndex', beet.u8], + ['instructions', beet.bytes], + ], + 'SyncTransactionPayloadDetails' + ) diff --git a/sdk/smart-account/src/generated/types/SynchronousTransactionEventPayload.ts b/sdk/smart-account/src/generated/types/SynchronousTransactionEventPayload.ts new file mode 100644 index 0000000..9c5c836 --- /dev/null +++ b/sdk/smart-account/src/generated/types/SynchronousTransactionEventPayload.ts @@ -0,0 +1,85 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +import { + SmartAccountCompiledInstruction, + smartAccountCompiledInstructionBeet, +} from './SmartAccountCompiledInstruction' +import { PolicyPayload, policyPayloadBeet } from './PolicyPayload' +/** + * This type is used to derive the {@link SynchronousTransactionEventPayload} type as well as the de/serializer. + * However don't refer to it in your code but use the {@link SynchronousTransactionEventPayload} type instead. + * + * @category userTypes + * @category enums + * @category generated + * @private + */ +export type SynchronousTransactionEventPayloadRecord = { + TransactionPayload: { + accountIndex: number + instructions: SmartAccountCompiledInstruction[] + } + PolicyPayload: { policyPayload: PolicyPayload } +} + +/** + * Union type respresenting the SynchronousTransactionEventPayload data enum defined in Rust. + * + * NOTE: that it includes a `__kind` property which allows to narrow types in + * switch/if statements. + * Additionally `isSynchronousTransactionEventPayload*` type guards are exposed below to narrow to a specific variant. + * + * @category userTypes + * @category enums + * @category generated + */ +export type SynchronousTransactionEventPayload = + beet.DataEnumKeyAsKind + +export const isSynchronousTransactionEventPayloadTransactionPayload = ( + x: SynchronousTransactionEventPayload +): x is SynchronousTransactionEventPayload & { __kind: 'TransactionPayload' } => + x.__kind === 'TransactionPayload' +export const isSynchronousTransactionEventPayloadPolicyPayload = ( + x: SynchronousTransactionEventPayload +): x is SynchronousTransactionEventPayload & { __kind: 'PolicyPayload' } => + x.__kind === 'PolicyPayload' + +/** + * @category userTypes + * @category generated + */ +export const synchronousTransactionEventPayloadBeet = + beet.dataEnum([ + [ + 'TransactionPayload', + new beet.FixableBeetArgsStruct< + SynchronousTransactionEventPayloadRecord['TransactionPayload'] + >( + [ + ['accountIndex', beet.u8], + ['instructions', beet.array(smartAccountCompiledInstructionBeet)], + ], + 'SynchronousTransactionEventPayloadRecord["TransactionPayload"]' + ), + ], + + [ + 'PolicyPayload', + new beet.FixableBeetArgsStruct< + SynchronousTransactionEventPayloadRecord['PolicyPayload'] + >( + [['policyPayload', policyPayloadBeet]], + 'SynchronousTransactionEventPayloadRecord["PolicyPayload"]' + ), + ], + ]) as beet.FixableBeet< + SynchronousTransactionEventPayload, + SynchronousTransactionEventPayload + > diff --git a/sdk/smart-account/src/generated/types/TimeConstraints.ts b/sdk/smart-account/src/generated/types/TimeConstraints.ts new file mode 100644 index 0000000..790c0c7 --- /dev/null +++ b/sdk/smart-account/src/generated/types/TimeConstraints.ts @@ -0,0 +1,30 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +import { PeriodV2, periodV2Beet } from './PeriodV2' +export type TimeConstraints = { + start: beet.bignum + expiration: beet.COption + period: PeriodV2 + accumulateUnused: boolean +} + +/** + * @category userTypes + * @category generated + */ +export const timeConstraintsBeet = + new beet.FixableBeetArgsStruct( + [ + ['start', beet.i64], + ['expiration', beet.coption(beet.i64)], + ['period', periodV2Beet], + ['accumulateUnused', beet.bool], + ], + 'TimeConstraints' + ) diff --git a/sdk/smart-account/src/generated/types/TransactionEventType.ts b/sdk/smart-account/src/generated/types/TransactionEventType.ts new file mode 100644 index 0000000..46f553e --- /dev/null +++ b/sdk/smart-account/src/generated/types/TransactionEventType.ts @@ -0,0 +1,25 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +/** + * @category enums + * @category generated + */ +export enum TransactionEventType { + Create, + Execute, + Close, +} + +/** + * @category userTypes + * @category generated + */ +export const transactionEventTypeBeet = beet.fixedScalarEnum( + TransactionEventType +) as beet.FixedSizeBeet diff --git a/sdk/smart-account/src/generated/types/TransactionPayload.ts b/sdk/smart-account/src/generated/types/TransactionPayload.ts new file mode 100644 index 0000000..e15452a --- /dev/null +++ b/sdk/smart-account/src/generated/types/TransactionPayload.ts @@ -0,0 +1,29 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +export type TransactionPayload = { + accountIndex: number + ephemeralSigners: number + transactionMessage: Uint8Array + memo: beet.COption +} + +/** + * @category userTypes + * @category generated + */ +export const transactionPayloadBeet = + new beet.FixableBeetArgsStruct( + [ + ['accountIndex', beet.u8], + ['ephemeralSigners', beet.u8], + ['transactionMessage', beet.bytes], + ['memo', beet.coption(beet.utf8String)], + ], + 'TransactionPayload' + ) diff --git a/sdk/smart-account/src/generated/types/TransactionPayloadDetails.ts b/sdk/smart-account/src/generated/types/TransactionPayloadDetails.ts new file mode 100644 index 0000000..f419c7d --- /dev/null +++ b/sdk/smart-account/src/generated/types/TransactionPayloadDetails.ts @@ -0,0 +1,31 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +import { + SmartAccountTransactionMessage, + smartAccountTransactionMessageBeet, +} from './SmartAccountTransactionMessage' +export type TransactionPayloadDetails = { + accountIndex: number + ephemeralSignerBumps: Uint8Array + message: SmartAccountTransactionMessage +} + +/** + * @category userTypes + * @category generated + */ +export const transactionPayloadDetailsBeet = + new beet.FixableBeetArgsStruct( + [ + ['accountIndex', beet.u8], + ['ephemeralSignerBumps', beet.bytes], + ['message', smartAccountTransactionMessageBeet], + ], + 'TransactionPayloadDetails' + ) diff --git a/sdk/smart-account/src/generated/types/UsageState.ts b/sdk/smart-account/src/generated/types/UsageState.ts new file mode 100644 index 0000000..d4b99ba --- /dev/null +++ b/sdk/smart-account/src/generated/types/UsageState.ts @@ -0,0 +1,24 @@ +/** + * 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 + */ + +import * as beet from '@metaplex-foundation/beet' +export type UsageState = { + remainingInPeriod: beet.bignum + lastReset: beet.bignum +} + +/** + * @category userTypes + * @category generated + */ +export const usageStateBeet = new beet.BeetArgsStruct( + [ + ['remainingInPeriod', beet.u64], + ['lastReset', beet.i64], + ], + 'UsageState' +) diff --git a/sdk/smart-account/src/generated/types/index.ts b/sdk/smart-account/src/generated/types/index.ts index a72eda0..0580c4d 100644 --- a/sdk/smart-account/src/generated/types/index.ts +++ b/sdk/smart-account/src/generated/types/index.ts @@ -1,34 +1,83 @@ +export * from './AccountConstraint' +export * from './AccountConstraintType' export * from './AddSignerArgs' export * from './AddSpendingLimitArgs' export * from './AddTransactionToBatchArgs' +export * from './AllowedSettingsChange' export * from './ChangeThresholdArgs' +export * from './ConsensusAccountType' export * from './CreateBatchArgs' export * from './CreateProposalArgs' export * from './CreateSettingsTransactionArgs' export * from './CreateSmartAccountArgs' export * from './CreateTransactionArgs' export * from './CreateTransactionBufferArgs' +export * from './DataConstraint' +export * from './DataOperator' +export * from './DataValue' export * from './ExtendTransactionBufferArgs' +export * from './Hook' export * from './InitProgramConfigArgs' +export * from './InstructionConstraint' +export * from './InternalFundTransferPayload' +export * from './InternalFundTransferPolicy' +export * from './InternalFundTransferPolicyCreationPayload' +export * from './LegacySyncTransactionArgs' +export * from './LimitedQuantityConstraints' +export * from './LimitedSettingsAction' +export * from './LimitedSpendingLimit' +export * from './LimitedTimeConstraints' export * from './LogEventArgs' +export * from './LogEventArgsV2' +export * from './Payload' export * from './Period' +export * from './PeriodV2' export * from './Permissions' +export * from './PolicyActionPayloadDetails' +export * from './PolicyCreationPayload' +export * from './PolicyEventType' +export * from './PolicyExecutionContext' +export * from './PolicyExpiration' +export * from './PolicyExpirationArgs' +export * from './PolicyPayload' +export * from './PolicyState' export * from './ProgramConfigSetAuthorityArgs' export * from './ProgramConfigSetSmartAccountCreationFeeArgs' export * from './ProgramConfigSetTreasuryArgs' +export * from './ProgramInteractionPayload' +export * from './ProgramInteractionPolicy' +export * from './ProgramInteractionPolicyCreationPayload' +export * from './ProgramInteractionTransactionPayload' +export * from './ProposalEventType' export * from './ProposalStatus' +export * from './QuantityConstraints' export * from './RemoveSignerArgs' export * from './RemoveSpendingLimitArgs' export * from './SetArchivalAuthorityArgs' export * from './SetNewSettingsAuthorityArgs' export * from './SetTimeLockArgs' export * from './SettingsAction' +export * from './SettingsChangePayload' +export * from './SettingsChangePolicy' +export * from './SettingsChangePolicyCreationPayload' export * from './SmartAccountCompiledInstruction' export * from './SmartAccountMessageAddressTableLookup' export * from './SmartAccountSigner' export * from './SmartAccountTransactionMessage' +export * from './SpendingLimitPayload' +export * from './SpendingLimitPolicy' +export * from './SpendingLimitPolicyCreationPayload' +export * from './SpendingLimitV2' +export * from './SyncPayload' export * from './SyncSettingsTransactionArgs' export * from './SyncTransactionArgs' +export * from './SyncTransactionPayloadDetails' +export * from './SynchronousTransactionEventPayload' +export * from './TimeConstraints' +export * from './TransactionEventType' +export * from './TransactionPayload' +export * from './TransactionPayloadDetails' +export * from './UsageState' export * from './UseSpendingLimitArgs' export * from './Vote' export * from './VoteOnProposalArgs' diff --git a/sdk/smart-account/src/instructions/addTransactionToBatch.ts b/sdk/smart-account/src/instructions/addTransactionToBatch.ts index 56f7e19..5ce234c 100644 --- a/sdk/smart-account/src/instructions/addTransactionToBatch.ts +++ b/sdk/smart-account/src/instructions/addTransactionToBatch.ts @@ -62,7 +62,7 @@ export function addTransactionToBatch({ programId, }); - const transactionMessageBytes = + const { transactionMessageBytes, compiledMessage } = transactionMessageToMultisigTransactionMessageBytes({ message: transactionMessage, addressLookupTableAccounts, diff --git a/sdk/smart-account/src/instructions/approveProposal.ts b/sdk/smart-account/src/instructions/approveProposal.ts index fb3a7e7..9fbc4f3 100644 --- a/sdk/smart-account/src/instructions/approveProposal.ts +++ b/sdk/smart-account/src/instructions/approveProposal.ts @@ -1,5 +1,5 @@ import { getProposalPda } from "../pda"; -import { createApproveProposalInstruction } from "../generated"; +import { createApproveProposalInstruction, PROGRAM_ID } from "../generated"; import { PublicKey } from "@solana/web3.js"; export function approveProposal({ @@ -7,7 +7,7 @@ export function approveProposal({ transactionIndex, signer, memo, - programId, + programId = PROGRAM_ID, }: { settingsPda: PublicKey; transactionIndex: bigint; @@ -22,7 +22,7 @@ export function approveProposal({ }); return createApproveProposalInstruction( - { settings: settingsPda, proposal: proposalPda, signer }, + { consensusAccount: settingsPda, proposal: proposalPda, signer, program: programId }, { args: { memo: memo ?? null } }, programId ); diff --git a/sdk/smart-account/src/instructions/cancelProposal.ts b/sdk/smart-account/src/instructions/cancelProposal.ts index ad01c40..389cfc5 100644 --- a/sdk/smart-account/src/instructions/cancelProposal.ts +++ b/sdk/smart-account/src/instructions/cancelProposal.ts @@ -22,7 +22,7 @@ export function cancelProposal({ }); return createCancelProposalInstruction( - { settings: settingsPda, proposal: proposalPda, signer, systemProgram: SystemProgram.programId }, + { consensusAccount: settingsPda, proposal: proposalPda, signer, systemProgram: SystemProgram.programId, program: programId }, { args: { memo: memo ?? null } }, programId ); diff --git a/sdk/smart-account/src/instructions/closeBatch.ts b/sdk/smart-account/src/instructions/closeBatch.ts index 22827a1..2f7a23a 100644 --- a/sdk/smart-account/src/instructions/closeBatch.ts +++ b/sdk/smart-account/src/instructions/closeBatch.ts @@ -40,6 +40,7 @@ export function closeBatch({ proposalRentCollector, proposal: proposalPda, batch: batchPda, + program: programId, }, programId ); diff --git a/sdk/smart-account/src/instructions/closeEmptyPolicyTransaction.ts b/sdk/smart-account/src/instructions/closeEmptyPolicyTransaction.ts new file mode 100644 index 0000000..c47ffac --- /dev/null +++ b/sdk/smart-account/src/instructions/closeEmptyPolicyTransaction.ts @@ -0,0 +1,48 @@ +import { PublicKey } from "@solana/web3.js"; +import { + createCloseEmptyPolicyTransactionInstruction, + createCloseTransactionInstruction, + PROGRAM_ID, +} from "../generated"; +import { getProgramConfigPda, getProposalPda, getTransactionPda } from "../pda"; + +export function closeEmptyPolicyTransaction({ + emptyPolicy, + transactionRentCollector, + transactionIndex, + programId = PROGRAM_ID, +}: { + emptyPolicy: PublicKey; + transactionRentCollector: PublicKey; + transactionIndex: bigint; + programId?: PublicKey; + proposalRentCollector?: PublicKey; +}) { + const [proposalPda] = getProposalPda({ + settingsPda: emptyPolicy, + transactionIndex, + programId, + }); + const [transactionPda] = getTransactionPda({ + settingsPda: emptyPolicy, + transactionIndex: transactionIndex, + programId, + }); + + const [programConfigPda] = getProgramConfigPda({ + programId, + }); + + return createCloseEmptyPolicyTransactionInstruction( + { + emptyPolicy, + proposal: proposalPda, + proposalRentCollector: transactionRentCollector, + transaction: transactionPda, + transactionRentCollector, + programConfig: programConfigPda, + program: programId, + }, + programId + ); +} diff --git a/sdk/smart-account/src/instructions/closeSettingsTransaction.ts b/sdk/smart-account/src/instructions/closeSettingsTransaction.ts index 938e7f9..84b515c 100644 --- a/sdk/smart-account/src/instructions/closeSettingsTransaction.ts +++ b/sdk/smart-account/src/instructions/closeSettingsTransaction.ts @@ -36,6 +36,7 @@ export function closeSettingsTransaction({ proposal: proposalPda, proposalRentCollector, transaction: transactionPda, + program: programId, }, programId ); diff --git a/sdk/smart-account/src/instructions/closeTransaction.ts b/sdk/smart-account/src/instructions/closeTransaction.ts index 96c2588..a762f11 100644 --- a/sdk/smart-account/src/instructions/closeTransaction.ts +++ b/sdk/smart-account/src/instructions/closeTransaction.ts @@ -31,12 +31,12 @@ export function closeTransaction({ return createCloseTransactionInstruction( { - settings: settingsPda, - + consensusAccount: settingsPda, proposal: proposalPda, proposalRentCollector, transaction: transactionPda, transactionRentCollector, + program: programId, }, programId ); diff --git a/sdk/smart-account/src/instructions/createPolicyTransaction.ts b/sdk/smart-account/src/instructions/createPolicyTransaction.ts new file mode 100644 index 0000000..f04bcf9 --- /dev/null +++ b/sdk/smart-account/src/instructions/createPolicyTransaction.ts @@ -0,0 +1,53 @@ +import { + createCreateTransactionInstruction, + PolicyPayload, + PROGRAM_ID, +} from "../generated"; +import { + AddressLookupTableAccount, + PublicKey, + TransactionMessage, +} from "@solana/web3.js"; +import { getTransactionPda, getSmartAccountPda, getPolicyPda } from "../pda"; +import { transactionMessageToMultisigTransactionMessageBytes } from "../utils"; + +export function createPolicyTransaction({ + policy, + transactionIndex, + creator, + rentPayer, + accountIndex, + policyPayload, + programId = PROGRAM_ID, +}: { + policy: PublicKey; + transactionIndex: bigint; + creator: PublicKey; + rentPayer?: PublicKey; + accountIndex: number; + policyPayload: PolicyPayload; + programId?: PublicKey; +}) { + const [transactionPda] = getTransactionPda({ + settingsPda: policy, + transactionIndex, + programId, + }); + + return createCreateTransactionInstruction( + { + consensusAccount: policy, + transaction: transactionPda, + creator, + rentPayer: rentPayer ?? creator, + program: programId, + }, + { + args: { + __kind: "PolicyPayload", + payload: policyPayload, + }, + }, + programId + ); +} diff --git a/sdk/smart-account/src/instructions/createProposal.ts b/sdk/smart-account/src/instructions/createProposal.ts index 45ba30f..5fd4c55 100644 --- a/sdk/smart-account/src/instructions/createProposal.ts +++ b/sdk/smart-account/src/instructions/createProposal.ts @@ -33,8 +33,9 @@ export function createProposal({ { creator, rentPayer: rentPayer ?? creator, - settings: settingsPda, + consensusAccount: settingsPda, proposal: proposalPda, + program: programId, }, { args: { transactionIndex: Number(transactionIndex), draft: isDraft } }, programId diff --git a/sdk/smart-account/src/instructions/createSettingsTransaction.ts b/sdk/smart-account/src/instructions/createSettingsTransaction.ts index 20eb625..b0dc109 100644 --- a/sdk/smart-account/src/instructions/createSettingsTransaction.ts +++ b/sdk/smart-account/src/instructions/createSettingsTransaction.ts @@ -1,4 +1,4 @@ -import { PublicKey } from "@solana/web3.js"; +import { AccountMeta, PublicKey } from "@solana/web3.js"; import { SettingsAction, createCreateSettingsTransactionInstruction, @@ -13,6 +13,7 @@ export function createSettingsTransaction({ rentPayer, actions, memo, + remainingAccounts, programId = PROGRAM_ID, }: { settingsPda: PublicKey; @@ -23,6 +24,7 @@ export function createSettingsTransaction({ transactionIndex: bigint; actions: SettingsAction[]; memo?: string; + remainingAccounts?: AccountMeta[]; programId?: PublicKey; }) { const [transactionPda] = getTransactionPda({ @@ -37,6 +39,8 @@ export function createSettingsTransaction({ transaction: transactionPda, creator, rentPayer: rentPayer ?? creator, + anchorRemainingAccounts: remainingAccounts, + program: programId, }, { args: { actions, memo: memo ?? null } }, programId diff --git a/sdk/smart-account/src/instructions/createTransaction.ts b/sdk/smart-account/src/instructions/createTransaction.ts index 4285009..bcde921 100644 --- a/sdk/smart-account/src/instructions/createTransaction.ts +++ b/sdk/smart-account/src/instructions/createTransaction.ts @@ -1,7 +1,4 @@ -import { - createCreateTransactionInstruction, - PROGRAM_ID, -} from "../generated"; +import { createCreateTransactionInstruction, PROGRAM_ID } from "../generated"; import { AddressLookupTableAccount, PublicKey, @@ -48,7 +45,7 @@ export function createTransaction({ programId, }); - const transactionMessageBytes = + const { transactionMessageBytes, compiledMessage } = transactionMessageToMultisigTransactionMessageBytes({ message: transactionMessage, addressLookupTableAccounts, @@ -57,17 +54,23 @@ export function createTransaction({ return createCreateTransactionInstruction( { - settings: settingsPda, + consensusAccount: settingsPda, transaction: transactionPda, creator, rentPayer: rentPayer ?? creator, + program: programId, }, { args: { - accountIndex, - ephemeralSigners, - transactionMessage: transactionMessageBytes, - memo: memo ?? null, + __kind: "TransactionPayload", + fields: [ + { + accountIndex, + ephemeralSigners, + transactionMessage: transactionMessageBytes, + memo: memo ?? null, + }, + ], }, }, programId diff --git a/sdk/smart-account/src/instructions/executePolicyPayloadSync.ts b/sdk/smart-account/src/instructions/executePolicyPayloadSync.ts new file mode 100644 index 0000000..b672a3f --- /dev/null +++ b/sdk/smart-account/src/instructions/executePolicyPayloadSync.ts @@ -0,0 +1,46 @@ +import { PublicKey } from "@solana/web3.js"; +import { + createExecuteTransactionSyncV2Instruction, + PROGRAM_ID, + PolicyPayload, +} from "../generated"; + +export function executePolicyPayloadSync({ + policy, + accountIndex, + numSigners, + policyPayload, + instruction_accounts, + programId = PROGRAM_ID, +}: { + policy: PublicKey; + accountIndex: number; + numSigners: number; + policyPayload: PolicyPayload; + instruction_accounts: { + pubkey: PublicKey; + isWritable: boolean; + isSigner: boolean; + }[]; + programId?: PublicKey; +}) { + const ix = createExecuteTransactionSyncV2Instruction( + { + consensusAccount: policy, + program: programId, + anchorRemainingAccounts: instruction_accounts, + }, + { + args: { + accountIndex, + numSigners, + payload: { + __kind: "Policy", + fields: [policyPayload], + }, + }, + }, + programId + ); + return ix; +} \ No newline at end of file diff --git a/sdk/smart-account/src/instructions/executePolicyTransaction.ts b/sdk/smart-account/src/instructions/executePolicyTransaction.ts new file mode 100644 index 0000000..ffdb698 --- /dev/null +++ b/sdk/smart-account/src/instructions/executePolicyTransaction.ts @@ -0,0 +1,47 @@ +import { + PublicKey, + TransactionInstruction, + AccountMeta, +} from "@solana/web3.js"; +import { + createExecuteTransactionInstruction, + PROGRAM_ID, +} from "../generated"; +import { getProposalPda, getTransactionPda } from "../pda"; + +export function executePolicyTransaction({ + policy, + transactionIndex, + signer, + anchorRemainingAccounts, + programId = PROGRAM_ID, +}: { + policy: PublicKey; + transactionIndex: bigint; + signer: PublicKey; + anchorRemainingAccounts: AccountMeta[]; + programId?: PublicKey; +}): TransactionInstruction { + const [proposalPda] = getProposalPda({ + settingsPda: policy, + transactionIndex, + programId, + }); + const [transactionPda] = getTransactionPda({ + settingsPda: policy, + transactionIndex, + programId, + }); + + return createExecuteTransactionInstruction( + { + consensusAccount: policy, + signer, + proposal: proposalPda, + transaction: transactionPda, + anchorRemainingAccounts, + program: programId, + }, + programId + ); +} \ No newline at end of file diff --git a/sdk/smart-account/src/instructions/executeSettingsTransaction.ts b/sdk/smart-account/src/instructions/executeSettingsTransaction.ts index 315ae37..4dd7fb1 100644 --- a/sdk/smart-account/src/instructions/executeSettingsTransaction.ts +++ b/sdk/smart-account/src/instructions/executeSettingsTransaction.ts @@ -1,4 +1,4 @@ -import { PublicKey, SystemProgram } from "@solana/web3.js"; +import { AccountMeta, PublicKey, SystemProgram } from "@solana/web3.js"; import { createExecuteSettingsTransactionInstruction, PROGRAM_ID, @@ -11,6 +11,7 @@ export function executeSettingsTransaction({ signer, rentPayer, spendingLimits, + policies, programId = PROGRAM_ID, }: { settingsPda: PublicKey; @@ -19,6 +20,7 @@ export function executeSettingsTransaction({ rentPayer?: PublicKey; /** In case the transaction adds or removes SpendingLimits, pass the array of their Pubkeys here. */ spendingLimits?: PublicKey[]; + policies?: PublicKey[]; programId?: PublicKey; }) { const [proposalPda] = getProposalPda({ @@ -32,6 +34,21 @@ export function executeSettingsTransaction({ programId, }); + let remainingAccounts: AccountMeta[] = []; + if (spendingLimits) { + remainingAccounts = spendingLimits.map((spendingLimit) => ({ + pubkey: spendingLimit, + isWritable: true, + isSigner: false, + })); + } + if (policies) { + remainingAccounts = policies.map((policy) => ({ + pubkey: policy, + isWritable: true, + isSigner: false, + })); + } return createExecuteSettingsTransactionInstruction( { settings: settingsPda, @@ -40,11 +57,8 @@ export function executeSettingsTransaction({ transaction: transactionPda, rentPayer: rentPayer ?? signer, systemProgram: SystemProgram.programId, - anchorRemainingAccounts: spendingLimits?.map((spendingLimit) => ({ - pubkey: spendingLimit, - isWritable: true, - isSigner: false, - })), + anchorRemainingAccounts: remainingAccounts, + program: programId, }, programId ); diff --git a/sdk/smart-account/src/instructions/executeSettingsTransactionSync.ts b/sdk/smart-account/src/instructions/executeSettingsTransactionSync.ts index 5fc7756..a17a72f 100644 --- a/sdk/smart-account/src/instructions/executeSettingsTransactionSync.ts +++ b/sdk/smart-account/src/instructions/executeSettingsTransactionSync.ts @@ -1,4 +1,4 @@ -import { PublicKey, SystemProgram } from "@solana/web3.js"; +import { AccountMeta, PublicKey, SystemProgram } from "@solana/web3.js"; import { SettingsAction, createExecuteSettingsTransactionSyncInstruction, PROGRAM_ID } from "../generated"; export function executeSettingsTransactionSync({ @@ -7,18 +7,20 @@ export function executeSettingsTransactionSync({ actions, feePayer, memo, + remainingAccounts, programId = PROGRAM_ID, }: { settingsPda: PublicKey; signers: PublicKey[]; actions: SettingsAction[]; feePayer: PublicKey; + remainingAccounts?: AccountMeta[]; memo?: string; programId?: PublicKey; }) { const ix = createExecuteSettingsTransactionSyncInstruction( { - settings: settingsPda, + consensusAccount: settingsPda, rentPayer: feePayer ?? undefined, systemProgram: SystemProgram.programId, program: programId, @@ -39,5 +41,8 @@ export function executeSettingsTransactionSync({ isSigner: true, isWritable: false, }))); + if (remainingAccounts) { + ix.keys.push(...remainingAccounts); + } return ix; } diff --git a/sdk/smart-account/src/instructions/executeTransaction.ts b/sdk/smart-account/src/instructions/executeTransaction.ts index fb472e4..36b4f2c 100644 --- a/sdk/smart-account/src/instructions/executeTransaction.ts +++ b/sdk/smart-account/src/instructions/executeTransaction.ts @@ -8,6 +8,7 @@ import { createExecuteTransactionInstruction, PROGRAM_ID, Transaction, + TransactionPayloadDetails, } from "../generated"; import { getProposalPda, getSmartAccountPda, getTransactionPda } from "../pda"; import { accountsForTransactionExecute } from "../utils"; @@ -42,18 +43,25 @@ export async function executeTransaction({ connection, transactionPda ); + const transactionPayload = transactionAccount.payload + let transactionDetails: TransactionPayloadDetails + if (transactionPayload.__kind === "TransactionPayload") { + transactionDetails = transactionPayload.fields[0] + } else { + throw new Error("Invalid transaction payload") + } const [smartAccountPda] = getSmartAccountPda({ settingsPda, - accountIndex: transactionAccount.accountIndex, + accountIndex: transactionDetails.accountIndex, programId, }); const { accountMetas, lookupTableAccounts } = await accountsForTransactionExecute({ connection, - message: transactionAccount.message, - ephemeralSignerBumps: [...transactionAccount.ephemeralSignerBumps], + message: transactionDetails.message, + ephemeralSignerBumps: [...transactionDetails.ephemeralSignerBumps], smartAccountPda, transactionPda, programId, @@ -62,10 +70,11 @@ export async function executeTransaction({ return { instruction: createExecuteTransactionInstruction( { - settings: settingsPda, + consensusAccount: settingsPda, signer, proposal: proposalPda, transaction: transactionPda, + program: programId, anchorRemainingAccounts: accountMetas, }, programId diff --git a/sdk/smart-account/src/instructions/executeTransactionSync.ts b/sdk/smart-account/src/instructions/executeTransactionSync.ts index 16161d6..9fc24fb 100644 --- a/sdk/smart-account/src/instructions/executeTransactionSync.ts +++ b/sdk/smart-account/src/instructions/executeTransactionSync.ts @@ -25,7 +25,7 @@ export function executeTransactionSync({ }) { const ix = createExecuteTransactionSyncInstruction( { - settings: settingsPda, + consensusAccount: settingsPda, program: programId, anchorRemainingAccounts: instruction_accounts, }, diff --git a/sdk/smart-account/src/instructions/executeTransactionSyncV2.ts b/sdk/smart-account/src/instructions/executeTransactionSyncV2.ts new file mode 100644 index 0000000..1fd2028 --- /dev/null +++ b/sdk/smart-account/src/instructions/executeTransactionSyncV2.ts @@ -0,0 +1,45 @@ +import { PublicKey } from "@solana/web3.js"; +import { + createExecuteTransactionSyncV2Instruction, + PROGRAM_ID, +} from "../generated"; + +export function executeTransactionSyncV2({ + settingsPda, + accountIndex, + numSigners, + instructions, + instruction_accounts, + programId = PROGRAM_ID, +}: { + settingsPda: PublicKey; + accountIndex: number; + numSigners: number; + instructions: Uint8Array; + instruction_accounts: { + pubkey: PublicKey; + isWritable: boolean; + isSigner: boolean; + }[]; + programId?: PublicKey; +}) { + const ix = createExecuteTransactionSyncV2Instruction( + { + consensusAccount: settingsPda, + program: programId, + anchorRemainingAccounts: instruction_accounts, + }, + { + args: { + accountIndex, + numSigners, + payload: { + __kind: "Transaction", + fields: [instructions], + }, + }, + }, + programId + ); + return ix; +} diff --git a/sdk/smart-account/src/instructions/index.ts b/sdk/smart-account/src/instructions/index.ts index ebbad3c..b6faa5e 100644 --- a/sdk/smart-account/src/instructions/index.ts +++ b/sdk/smart-account/src/instructions/index.ts @@ -26,3 +26,8 @@ export * from "./closeTransaction.js"; export * from "./createTransaction.js"; export * from "./executeTransaction.js"; export * from "./executeTransactionSync.js"; +export * from "./createPolicyTransaction.js"; +export * from "./executePolicyTransaction.js"; +export * from "./executeTransactionSyncV2.js"; +export * from "./executePolicyPayloadSync.js"; +export * from "./closeEmptyPolicyTransaction.js"; \ No newline at end of file diff --git a/sdk/smart-account/src/instructions/rejectProposal.ts b/sdk/smart-account/src/instructions/rejectProposal.ts index a7ac708..70eb018 100644 --- a/sdk/smart-account/src/instructions/rejectProposal.ts +++ b/sdk/smart-account/src/instructions/rejectProposal.ts @@ -22,7 +22,12 @@ export function rejectProposal({ }); return createRejectProposalInstruction( - { settings: settingsPda, proposal: proposalPda, signer }, + { + consensusAccount: settingsPda, + proposal: proposalPda, + signer, + program: programId, + }, { args: { memo: memo ?? null } }, programId ); diff --git a/sdk/smart-account/src/pda.ts b/sdk/smart-account/src/pda.ts index 7471710..232aae3 100644 --- a/sdk/smart-account/src/pda.ts +++ b/sdk/smart-account/src/pda.ts @@ -1,7 +1,13 @@ import { PublicKey } from "@solana/web3.js"; import invariant from "invariant"; import { PROGRAM_ID } from "./generated"; -import { toU128Bytes, toU32Bytes, toU64Bytes, toU8Bytes, toUtfBytes } from "./utils"; +import { + toU128Bytes, + toU32Bytes, + toU64Bytes, + toU8Bytes, + toUtfBytes, +} from "./utils"; const SEED_PREFIX = toUtfBytes("smart_account"); const SEED_PROGRAM_CONFIG = toUtfBytes("program_config"); @@ -12,6 +18,7 @@ const SEED_PROPOSAL = toUtfBytes("proposal"); const SEED_BATCH_TRANSACTION = toUtfBytes("batch_transaction"); const SEED_EPHEMERAL_SIGNER = toUtfBytes("ephemeral_signer"); const SEED_SPENDING_LIMIT = toUtfBytes("spending_limit"); +const SEED_POLICY = toUtfBytes("policy"); export function getProgramConfigPda({ programId = PROGRAM_ID, @@ -155,13 +162,28 @@ export function getSpendingLimitPda({ settingsPda: PublicKey; seed: PublicKey; programId?: PublicKey; +}): [PublicKey, number] { + return PublicKey.findProgramAddressSync( + [SEED_PREFIX, settingsPda.toBytes(), SEED_SPENDING_LIMIT, seed.toBytes()], + programId + ); +} + +export function getPolicyPda({ + settingsPda, + policySeed, + programId = PROGRAM_ID, +}: { + settingsPda: PublicKey; + policySeed: number; + programId?: PublicKey; }): [PublicKey, number] { return PublicKey.findProgramAddressSync( [ SEED_PREFIX, + SEED_POLICY, settingsPda.toBytes(), - SEED_SPENDING_LIMIT, - seed.toBytes(), + toU64Bytes(BigInt(policySeed)), ], programId ); diff --git a/sdk/smart-account/src/rpc/closeEmptyPolicyTransaction.ts b/sdk/smart-account/src/rpc/closeEmptyPolicyTransaction.ts new file mode 100644 index 0000000..7bd7f5b --- /dev/null +++ b/sdk/smart-account/src/rpc/closeEmptyPolicyTransaction.ts @@ -0,0 +1,53 @@ +import { + Connection, + PublicKey, + SendOptions, + Signer, + TransactionSignature, +} from "@solana/web3.js"; +import { translateAndThrowAnchorError } from "../errors.js"; +import * as transactions from "../transactions/index.js"; + +/** + * Close the Proposal and ConfigTransaction accounts associated with a + * empty/deleted policy. + */ +export async function closeEmptyPolicyTransaction({ + connection, + feePayer, + emptyPolicy, + transactionRentCollector, + transactionIndex, + sendOptions, + programId, + proposalRentCollector, +}: { + connection: Connection; + feePayer: Signer; + emptyPolicy: PublicKey; + transactionRentCollector: PublicKey; + transactionIndex: bigint; + sendOptions?: SendOptions; + programId?: PublicKey; + proposalRentCollector?: PublicKey; +}): Promise { + const blockhash = (await connection.getLatestBlockhash()).blockhash; + + const tx = transactions.closeEmptyPolicyTransaction({ + blockhash, + feePayer: feePayer.publicKey, + emptyPolicy, + transactionRentCollector, + transactionIndex, + programId, + proposalRentCollector, + }); + + tx.sign([feePayer]); + + try { + return await connection.sendTransaction(tx, sendOptions); + } catch (err) { + translateAndThrowAnchorError(err); + } +} diff --git a/sdk/smart-account/src/rpc/createPolicyTransaction.ts b/sdk/smart-account/src/rpc/createPolicyTransaction.ts new file mode 100644 index 0000000..822c4cb --- /dev/null +++ b/sdk/smart-account/src/rpc/createPolicyTransaction.ts @@ -0,0 +1,63 @@ +import { + AddressLookupTableAccount, + Connection, + PublicKey, + SendOptions, + Signer, + TransactionMessage, + TransactionSignature, +} from "@solana/web3.js"; +import * as transactions from "../transactions"; +import { translateAndThrowAnchorError } from "../errors"; +import { PolicyPayload } from "../generated"; + +/** Create a new vault transaction. */ +export async function createPolicyTransaction({ + connection, + feePayer, + policy, + transactionIndex, + creator, + rentPayer, + accountIndex, + policyPayload, + signers, + sendOptions, + programId, +}: { + connection: Connection; + feePayer: Signer; + policy: PublicKey; + transactionIndex: bigint; + /** Member of the multisig that is creating the transaction. */ + creator: PublicKey; + /** Payer for the transaction account rent. If not provided, `creator` is used. */ + rentPayer?: PublicKey; + accountIndex: number; + policyPayload: PolicyPayload; + signers?: Signer[]; + sendOptions?: SendOptions; + programId?: PublicKey; +}): Promise { + const blockhash = (await connection.getLatestBlockhash()).blockhash; + + const tx = transactions.createPolicyTransaction({ + blockhash, + feePayer: feePayer.publicKey, + policy, + transactionIndex, + creator, + rentPayer, + accountIndex, + policyPayload, + programId, + }); + + tx.sign([feePayer, ...(signers ?? [])]); + + try { + return await connection.sendRawTransaction(tx.serialize(), sendOptions); + } catch (err) { + translateAndThrowAnchorError(err); + } +} diff --git a/sdk/smart-account/src/rpc/createSettingsTransaction.ts b/sdk/smart-account/src/rpc/createSettingsTransaction.ts index 34b25af..6a05c5e 100644 --- a/sdk/smart-account/src/rpc/createSettingsTransaction.ts +++ b/sdk/smart-account/src/rpc/createSettingsTransaction.ts @@ -1,4 +1,5 @@ import { + AccountMeta, Connection, PublicKey, SendOptions, @@ -21,6 +22,7 @@ export async function createSettingsTransaction({ memo, signers, sendOptions, + remainingAccounts, programId, }: { connection: Connection; @@ -35,6 +37,7 @@ export async function createSettingsTransaction({ memo?: string; signers?: Signer[]; sendOptions?: SendOptions; + remainingAccounts?: AccountMeta[]; programId?: PublicKey; }): Promise { const blockhash = (await connection.getLatestBlockhash()).blockhash; @@ -48,6 +51,7 @@ export async function createSettingsTransaction({ rentPayer, actions, memo, + remainingAccounts, programId, }); diff --git a/sdk/smart-account/src/rpc/executePolicyPayloadSync.ts b/sdk/smart-account/src/rpc/executePolicyPayloadSync.ts new file mode 100644 index 0000000..7ff0325 --- /dev/null +++ b/sdk/smart-account/src/rpc/executePolicyPayloadSync.ts @@ -0,0 +1,62 @@ +import { + Connection, + PublicKey, + SendOptions, + Signer, + TransactionSignature, +} from "@solana/web3.js"; +import * as transactions from "../transactions"; +import { translateAndThrowAnchorError } from "../errors"; +import { PolicyPayload } from "../generated"; + +/** + * Execute a policy payload synchronously with V2 instruction. + * All required signers must be provided. + */ +export async function executePolicyPayloadSync({ + connection, + feePayer, + policy, + accountIndex, + numSigners, + policyPayload, + instruction_accounts, + signers, + sendOptions, + programId, +}: { + connection: Connection; + feePayer: Signer; + policy: PublicKey; + accountIndex: number; + numSigners: number; + policyPayload: PolicyPayload; + instruction_accounts: { + pubkey: PublicKey; + isWritable: boolean; + isSigner: boolean; + }[]; + signers?: Signer[]; + sendOptions?: SendOptions; + programId?: PublicKey; +}): Promise { + const blockhash = (await connection.getLatestBlockhash()).blockhash; + const tx = transactions.executePolicyPayloadSync({ + blockhash, + feePayer: feePayer.publicKey, + policy, + accountIndex, + numSigners, + policyPayload, + instruction_accounts, + programId, + }); + + tx.sign([feePayer, ...(signers ?? [])]); + + try { + return await connection.sendRawTransaction(tx.serialize(), sendOptions); + } catch (err) { + translateAndThrowAnchorError(err); + } +} diff --git a/sdk/smart-account/src/rpc/executePolicyTransaction.ts b/sdk/smart-account/src/rpc/executePolicyTransaction.ts new file mode 100644 index 0000000..979e98c --- /dev/null +++ b/sdk/smart-account/src/rpc/executePolicyTransaction.ts @@ -0,0 +1,56 @@ +import { + Connection, + PublicKey, + SendOptions, + Signer, + TransactionSignature, + AccountMeta, +} from "@solana/web3.js"; +import * as transactions from "../transactions"; +import { translateAndThrowAnchorError } from "../errors"; + +/** + * Execute the policy transaction. + * The transaction must be `ExecuteReady`. + */ +export async function executePolicyTransaction({ + connection, + feePayer, + policy, + transactionIndex, + signer, + anchorRemainingAccounts, + signers, + sendOptions, + programId, +}: { + connection: Connection; + feePayer: Signer; + policy: PublicKey; + transactionIndex: bigint; + signer: PublicKey; + anchorRemainingAccounts: AccountMeta[]; + signers?: Signer[]; + sendOptions?: SendOptions; + programId?: PublicKey; +}): Promise { + const blockhash = (await connection.getLatestBlockhash()).blockhash; + + const tx = transactions.executePolicyTransaction({ + blockhash, + feePayer: feePayer.publicKey, + policy, + transactionIndex, + signer, + anchorRemainingAccounts, + programId, + }); + + tx.sign([feePayer, ...(signers ?? [])]); + + try { + return await connection.sendRawTransaction(tx.serialize(), sendOptions); + } catch (err) { + translateAndThrowAnchorError(err); + } +} diff --git a/sdk/smart-account/src/rpc/executeSettingsTransaction.ts b/sdk/smart-account/src/rpc/executeSettingsTransaction.ts index 5345bbc..6d0cc52 100644 --- a/sdk/smart-account/src/rpc/executeSettingsTransaction.ts +++ b/sdk/smart-account/src/rpc/executeSettingsTransaction.ts @@ -17,6 +17,7 @@ export async function executeSettingsTransaction({ signer, rentPayer, spendingLimits, + policies, signers, sendOptions, programId, @@ -29,6 +30,8 @@ export async function executeSettingsTransaction({ rentPayer: Signer; /** In case the transaction adds or removes SpendingLimits, pass the array of their Pubkeys here. */ spendingLimits?: PublicKey[]; + /** In case the transaction adds or removes Policies, pass the array of their Pubkeys here. */ + policies?: PublicKey[]; signers?: Signer[]; sendOptions?: SendOptions; programId?: PublicKey; @@ -43,13 +46,14 @@ export async function executeSettingsTransaction({ signer: signer.publicKey, rentPayer: rentPayer.publicKey, spendingLimits, + policies, programId, }); tx.sign([feePayer, signer, rentPayer, ...(signers ?? [])]); try { - return await connection.sendTransaction(tx, sendOptions); + return await connection.sendRawTransaction(tx.serialize(), sendOptions); } catch (err) { translateAndThrowAnchorError(err); } diff --git a/sdk/smart-account/src/rpc/executeSettingsTransactionSync.ts b/sdk/smart-account/src/rpc/executeSettingsTransactionSync.ts index 5178922..038de18 100644 --- a/sdk/smart-account/src/rpc/executeSettingsTransactionSync.ts +++ b/sdk/smart-account/src/rpc/executeSettingsTransactionSync.ts @@ -1,4 +1,5 @@ import { + AccountMeta, Connection, PublicKey, SendOptions, @@ -19,6 +20,7 @@ export async function executeSettingsTransactionSync({ actions, memo, signers, + remainingAccounts, sendOptions, programId, }: { @@ -27,6 +29,7 @@ export async function executeSettingsTransactionSync({ settingsPda: PublicKey; actions: SettingsAction[]; signers: Signer[]; + remainingAccounts?: AccountMeta[]; memo?: string; sendOptions?: SendOptions; programId?: PublicKey; @@ -37,13 +40,14 @@ export async function executeSettingsTransactionSync({ blockhash, feePayer: feePayer.publicKey, settingsPda, - signers: signers.map(signer => signer.publicKey), + signers: signers.map((signer) => signer.publicKey), settingsActions: actions, memo, + remainingAccounts, programId, }); - tx.sign([feePayer, ...(signers)]); + tx.sign([feePayer, ...signers]); try { return await connection.sendTransaction(tx, sendOptions); diff --git a/sdk/smart-account/src/rpc/executeTransactionSyncV2.ts b/sdk/smart-account/src/rpc/executeTransactionSyncV2.ts new file mode 100644 index 0000000..5bf1f3b --- /dev/null +++ b/sdk/smart-account/src/rpc/executeTransactionSyncV2.ts @@ -0,0 +1,62 @@ +import { + Connection, + PublicKey, + SendOptions, + Signer, + TransactionSignature, +} from "@solana/web3.js"; +import * as transactions from "../transactions"; +import { translateAndThrowAnchorError } from "../errors"; + +/** + * Execute a transaction synchronously with V2 instruction. + * All required signers must be provided. + */ +export async function executeTransactionSyncV2({ + connection, + feePayer, + settingsPda, + accountIndex, + numSigners, + instructions, + instruction_accounts, + signers, + sendOptions, + programId, +}: { + connection: Connection; + feePayer: Signer; + settingsPda: PublicKey; + accountIndex: number; + numSigners: number; + instructions: Uint8Array; + instruction_accounts: { + pubkey: PublicKey; + isWritable: boolean; + isSigner: boolean; + }[]; + signers?: Signer[]; + sendOptions?: SendOptions; + programId?: PublicKey; +}): Promise { + const blockhash = (await connection.getLatestBlockhash()).blockhash; + + const tx = transactions.executeTransactionSyncV2({ + blockhash, + feePayer: feePayer.publicKey, + settingsPda, + accountIndex, + numSigners, + instructions, + instruction_accounts, + programId, + }); + + tx.sign([feePayer, ...(signers ?? [])]); + + try { + return await connection.sendRawTransaction(tx.serialize(), sendOptions); + } catch (err) { + translateAndThrowAnchorError(err); + } +} \ No newline at end of file diff --git a/sdk/smart-account/src/rpc/index.ts b/sdk/smart-account/src/rpc/index.ts index c61a6ba..a93ea25 100644 --- a/sdk/smart-account/src/rpc/index.ts +++ b/sdk/smart-account/src/rpc/index.ts @@ -24,3 +24,8 @@ export * from "./setArchivalAuthorityAsAuthority.js"; export * from "./setTimeLockAsAuthority.js"; export * from "./useSpendingLimit.js"; export * from "./activateProposal.js"; +export * from "./createPolicyTransaction.js"; +export * from "./executePolicyTransaction.js"; +export * from "./executeTransactionSyncV2.js"; +export * from "./executePolicyPayloadSync.js"; +export * from "./closeEmptyPolicyTransaction.js"; diff --git a/sdk/smart-account/src/transactions/closeEmptyPolicyTransaction.ts b/sdk/smart-account/src/transactions/closeEmptyPolicyTransaction.ts new file mode 100644 index 0000000..2324e32 --- /dev/null +++ b/sdk/smart-account/src/transactions/closeEmptyPolicyTransaction.ts @@ -0,0 +1,40 @@ +import { + PublicKey, + TransactionMessage, + VersionedTransaction, +} from "@solana/web3.js"; +import * as instructions from "../instructions/index.js"; + +export function closeEmptyPolicyTransaction({ + blockhash, + feePayer, + emptyPolicy, + transactionRentCollector, + transactionIndex, + programId, + proposalRentCollector = transactionRentCollector, +}: { + blockhash: string; + feePayer: PublicKey; + emptyPolicy: PublicKey; + transactionRentCollector: PublicKey; + transactionIndex: bigint; + programId?: PublicKey; + proposalRentCollector?: PublicKey; +}): VersionedTransaction { + const message = new TransactionMessage({ + payerKey: feePayer, + recentBlockhash: blockhash, + instructions: [ + instructions.closeEmptyPolicyTransaction({ + emptyPolicy, + transactionRentCollector, + transactionIndex, + programId, + proposalRentCollector, + }), + ], + }).compileToV0Message(); + + return new VersionedTransaction(message); +} diff --git a/sdk/smart-account/src/transactions/createPolicyTransaction.ts b/sdk/smart-account/src/transactions/createPolicyTransaction.ts new file mode 100644 index 0000000..957c4e2 --- /dev/null +++ b/sdk/smart-account/src/transactions/createPolicyTransaction.ts @@ -0,0 +1,54 @@ +import { + AddressLookupTableAccount, + PublicKey, + TransactionMessage, + VersionedTransaction, +} from "@solana/web3.js"; +import * as instructions from "../instructions/index"; +import { PolicyPayload } from "../generated"; + +/** + * Returns unsigned `VersionedTransaction` that needs to be + * signed by `creator`, `rentPayer` and `feePayer` before sending it. + */ +export function createPolicyTransaction({ + blockhash, + feePayer, + policy, + transactionIndex, + creator, + rentPayer, + accountIndex, + policyPayload, + programId, +}: { + blockhash: string; + feePayer: PublicKey; + policy: PublicKey; + transactionIndex: bigint; + /** Member of the multisig that is creating the transaction. */ + creator: PublicKey; + /** Payer for the transaction account rent. If not provided, `creator` is used. */ + rentPayer?: PublicKey; + accountIndex: number; + policyPayload: PolicyPayload; + programId?: PublicKey; +}): VersionedTransaction { + const message = new TransactionMessage({ + payerKey: feePayer, + recentBlockhash: blockhash, + instructions: [ + instructions.createPolicyTransaction({ + policy, + transactionIndex, + creator, + rentPayer, + accountIndex, + policyPayload, + programId, + }), + ], + }).compileToV0Message(); + + return new VersionedTransaction(message); +} diff --git a/sdk/smart-account/src/transactions/createSettingsTransaction.ts b/sdk/smart-account/src/transactions/createSettingsTransaction.ts index 450a16d..e6368cb 100644 --- a/sdk/smart-account/src/transactions/createSettingsTransaction.ts +++ b/sdk/smart-account/src/transactions/createSettingsTransaction.ts @@ -1,4 +1,5 @@ import { + AccountMeta, PublicKey, TransactionMessage, VersionedTransaction, @@ -19,6 +20,7 @@ export function createSettingsTransaction({ transactionIndex, actions, memo, + remainingAccounts, programId, }: { blockhash: string; @@ -31,6 +33,7 @@ export function createSettingsTransaction({ transactionIndex: bigint; actions: SettingsAction[]; memo?: string; + remainingAccounts?: AccountMeta[]; programId?: PublicKey; }): VersionedTransaction { const message = new TransactionMessage({ @@ -44,6 +47,7 @@ export function createSettingsTransaction({ transactionIndex, actions, memo, + remainingAccounts, programId, }), ], diff --git a/sdk/smart-account/src/transactions/executePolicyPayloadSync.ts b/sdk/smart-account/src/transactions/executePolicyPayloadSync.ts new file mode 100644 index 0000000..cd2dfa9 --- /dev/null +++ b/sdk/smart-account/src/transactions/executePolicyPayloadSync.ts @@ -0,0 +1,54 @@ +import { + PublicKey, + TransactionMessage, + VersionedTransaction, +} from "@solana/web3.js"; +import * as instructions from "../instructions"; +import { PolicyPayload } from "../generated"; + +/** + * Returns unsigned `VersionedTransaction` that needs to be + * signed by required signers and `feePayer` before sending it. + */ +export function executePolicyPayloadSync({ + blockhash, + feePayer, + policy, + accountIndex, + numSigners, + policyPayload, + instruction_accounts, + programId, +}: { + blockhash: string; + feePayer: PublicKey; + policy: PublicKey; + accountIndex: number; + numSigners: number; + policyPayload: PolicyPayload; + instruction_accounts: { + pubkey: PublicKey; + isWritable: boolean; + isSigner: boolean; + }[]; + programId?: PublicKey; +}): VersionedTransaction { + const instruction = instructions.executePolicyPayloadSync({ + policy, + accountIndex, + numSigners, + policyPayload, + instruction_accounts, + programId, + }); + + const message = new TransactionMessage({ + payerKey: feePayer, + recentBlockhash: blockhash, + instructions: [instruction], + }).compileToV0Message(); + + + + return new VersionedTransaction(message); +} \ No newline at end of file diff --git a/sdk/smart-account/src/transactions/executePolicyTransaction.ts b/sdk/smart-account/src/transactions/executePolicyTransaction.ts new file mode 100644 index 0000000..25c1d7f --- /dev/null +++ b/sdk/smart-account/src/transactions/executePolicyTransaction.ts @@ -0,0 +1,45 @@ +import { + PublicKey, + TransactionMessage, + VersionedTransaction, + AccountMeta, +} from "@solana/web3.js"; +import * as instructions from "../instructions"; + +/** + * Returns unsigned `VersionedTransaction` that needs to be + * signed by `member` and `feePayer` before sending it. + */ +export function executePolicyTransaction({ + blockhash, + feePayer, + policy, + transactionIndex, + signer, + anchorRemainingAccounts, + programId, +}: { + blockhash: string; + feePayer: PublicKey; + policy: PublicKey; + transactionIndex: bigint; + signer: PublicKey; + anchorRemainingAccounts: AccountMeta[]; + programId?: PublicKey; +}): VersionedTransaction { + const instruction = instructions.executePolicyTransaction({ + policy, + signer, + transactionIndex, + anchorRemainingAccounts, + programId, + }); + + const message = new TransactionMessage({ + payerKey: feePayer, + recentBlockhash: blockhash, + instructions: [instruction], + }).compileToV0Message(); + + return new VersionedTransaction(message); +} \ No newline at end of file diff --git a/sdk/smart-account/src/transactions/executeSettingsTransaction.ts b/sdk/smart-account/src/transactions/executeSettingsTransaction.ts index ad2e090..1609f6d 100644 --- a/sdk/smart-account/src/transactions/executeSettingsTransaction.ts +++ b/sdk/smart-account/src/transactions/executeSettingsTransaction.ts @@ -1,4 +1,5 @@ import { + AccountMeta, PublicKey, TransactionMessage, VersionedTransaction, @@ -17,6 +18,7 @@ export function executeSettingsTransaction({ rentPayer, transactionIndex, spendingLimits, + policies, programId, }: { blockhash: string; @@ -27,6 +29,8 @@ export function executeSettingsTransaction({ rentPayer: PublicKey; /** In case the transaction adds or removes SpendingLimits, pass the array of their Pubkeys here. */ spendingLimits?: PublicKey[]; + /** In case the transaction adds or removes Policies, pass the array of their Pubkeys here. */ + policies?: PublicKey[]; programId?: PublicKey; }): VersionedTransaction { const message = new TransactionMessage({ @@ -39,6 +43,7 @@ export function executeSettingsTransaction({ signer, rentPayer, spendingLimits, + policies, programId, }), ], diff --git a/sdk/smart-account/src/transactions/executeSettingsTransactionSync.ts b/sdk/smart-account/src/transactions/executeSettingsTransactionSync.ts index 76eb98c..52cc303 100644 --- a/sdk/smart-account/src/transactions/executeSettingsTransactionSync.ts +++ b/sdk/smart-account/src/transactions/executeSettingsTransactionSync.ts @@ -1,4 +1,5 @@ import { + AccountMeta, PublicKey, TransactionMessage, VersionedTransaction, @@ -17,6 +18,7 @@ export function executeSettingsTransactionSync({ signers, settingsActions, memo, + remainingAccounts, programId, }: { blockhash: string; @@ -24,6 +26,7 @@ export function executeSettingsTransactionSync({ settingsPda: PublicKey; signers: PublicKey[]; settingsActions: SettingsAction[]; + remainingAccounts?: AccountMeta[]; memo?: string; programId?: PublicKey; }): VersionedTransaction { @@ -37,6 +40,7 @@ export function executeSettingsTransactionSync({ signers, actions: settingsActions, memo, + remainingAccounts, programId, }), ], diff --git a/sdk/smart-account/src/transactions/executeTransactionSyncV2.ts b/sdk/smart-account/src/transactions/executeTransactionSyncV2.ts new file mode 100644 index 0000000..f0307b5 --- /dev/null +++ b/sdk/smart-account/src/transactions/executeTransactionSyncV2.ts @@ -0,0 +1,51 @@ +import { + PublicKey, + TransactionMessage, + VersionedTransaction, +} from "@solana/web3.js"; +import * as instructions from "../instructions"; + +/** + * Returns unsigned `VersionedTransaction` that needs to be + * signed by required signers and `feePayer` before sending it. + */ +export function executeTransactionSyncV2({ + blockhash, + feePayer, + settingsPda, + accountIndex, + numSigners, + instructions: instructionBytes, + instruction_accounts, + programId, +}: { + blockhash: string; + feePayer: PublicKey; + settingsPda: PublicKey; + accountIndex: number; + numSigners: number; + instructions: Uint8Array; + instruction_accounts: { + pubkey: PublicKey; + isWritable: boolean; + isSigner: boolean; + }[]; + programId?: PublicKey; +}): VersionedTransaction { + const instruction = instructions.executeTransactionSyncV2({ + settingsPda, + accountIndex, + numSigners, + instructions: instructionBytes, + instruction_accounts, + programId, + }); + + const message = new TransactionMessage({ + payerKey: feePayer, + recentBlockhash: blockhash, + instructions: [instruction], + }).compileToV0Message(); + + return new VersionedTransaction(message); +} \ No newline at end of file diff --git a/sdk/smart-account/src/transactions/index.ts b/sdk/smart-account/src/transactions/index.ts index 9f00175..70aecdf 100644 --- a/sdk/smart-account/src/transactions/index.ts +++ b/sdk/smart-account/src/transactions/index.ts @@ -26,3 +26,8 @@ export * from "./createTransaction.js"; export * from "./executeTransaction.js"; export * from "./executeTransactionSync.js"; export * from "./executeSettingsTransactionSync.js"; +export * from "./createPolicyTransaction.js"; +export * from "./executePolicyTransaction.js"; +export * from "./executeTransactionSyncV2.js"; +export * from "./executePolicyPayloadSync.js"; +export * from "./closeEmptyPolicyTransaction.js"; \ No newline at end of file diff --git a/sdk/smart-account/src/utils.ts b/sdk/smart-account/src/utils.ts index 72a9013..99efad8 100644 --- a/sdk/smart-account/src/utils.ts +++ b/sdk/smart-account/src/utils.ts @@ -3,6 +3,7 @@ import { AccountMeta, AddressLookupTableAccount, Connection, + MessageV0, PublicKey, TransactionInstruction, TransactionMessage, @@ -15,6 +16,10 @@ import { getEphemeralSignerPda } from "./pda"; import { transactionMessageBeet } from "./types"; import { compileToSynchronousMessageAndAccounts } from "./utils/compileToSynchronousMessage"; import { compileToWrappedMessageV0 } from "./utils/compileToWrappedMessageV0"; +import { + compileToSynchronousMessageAndAccountsV2, + compileToSynchronousMessageAndAccountsV2WithHooks, +} from "./utils/compileToSynchronousMessageV2"; export function toUtfBytes(str: string): Uint8Array { return new TextEncoder().encode(str); @@ -107,7 +112,10 @@ export function transactionMessageToMultisigTransactionMessageBytes({ message: TransactionMessage; addressLookupTableAccounts?: AddressLookupTableAccount[]; smartAccountPda: PublicKey; -}): Uint8Array { +}): { + transactionMessageBytes: Uint8Array; + compiledMessage: MessageV0; +} { // // Make sure authority is marked as non-signer in all instructions, // // otherwise the message will be serialized in incorrect format. // message.instructions.forEach((instruction) => { @@ -151,7 +159,10 @@ export function transactionMessageToMultisigTransactionMessageBytes({ addressTableLookups: compiledMessage.addressTableLookups, }); - return transactionMessageBytes; + return { + transactionMessageBytes, + compiledMessage, + }; } export function instructionsToSynchronousTransactionDetails({ @@ -178,6 +189,60 @@ export function instructionsToSynchronousTransactionDetails({ }; } +export function instructionsToSynchronousTransactionDetailsV2({ + vaultPda, + members, + transaction_instructions, +}: { + vaultPda: PublicKey; + members: PublicKey[]; + transaction_instructions: TransactionInstruction[]; +}): { + instructions: Uint8Array; + accounts: AccountMeta[]; +} { + const { instructions, accounts } = compileToSynchronousMessageAndAccountsV2({ + vaultPda, + members, + instructions: transaction_instructions, + }); + + return { + instructions, + accounts, + }; +} + +export function instructionsToSynchronousTransactionDetailsV2WithHooks({ + vaultPda, + members, + preHookAccounts, + postHookAccounts, + transaction_instructions, +}: { + vaultPda: PublicKey; + members: PublicKey[]; + preHookAccounts: AccountMeta[]; + postHookAccounts: AccountMeta[]; + transaction_instructions: TransactionInstruction[]; +}): { + instructions: Uint8Array; + accounts: AccountMeta[]; +} { + const { instructions, accounts } = + compileToSynchronousMessageAndAccountsV2WithHooks({ + vaultPda, + members, + preHookAccounts, + postHookAccounts, + instructions: transaction_instructions, + }); + + return { + instructions, + accounts, + }; +} /** Populate remaining accounts required for execution of the transaction. */ export async function accountsForTransactionExecute({ connection, diff --git a/sdk/smart-account/src/utils/compileToSynchronousMessage.ts b/sdk/smart-account/src/utils/compileToSynchronousMessage.ts index 4f40b9a..7626b86 100644 --- a/sdk/smart-account/src/utils/compileToSynchronousMessage.ts +++ b/sdk/smart-account/src/utils/compileToSynchronousMessage.ts @@ -1,125 +1,132 @@ import { - AccountMeta, - PublicKey, - TransactionInstruction + AccountMeta, + PublicKey, + TransactionInstruction, } from "@solana/web3.js"; import { CompiledKeys } from "./compiled-keys"; - export function compileToSynchronousMessageAndAccounts({ - vaultPda, - members, - instructions, + vaultPda, + members, + instructions, }: { - vaultPda: PublicKey, - members: PublicKey[], - instructions: TransactionInstruction[]; + vaultPda: PublicKey; + members: PublicKey[]; + instructions: TransactionInstruction[]; }): { - instructions: Uint8Array; - accounts: AccountMeta[]; + instructions: Uint8Array; + accounts: AccountMeta[]; } { + // Compile instructions to get account mapping + const compiledKeys = CompiledKeys.compileWithoutPayer(instructions); + + // Get message components + const [header, staticAccountKeys] = compiledKeys.getMessageComponents(); + + // Mark the vault as non-signer if it exists + // Create remaining accounts array starting with vault + const remainingAccounts: AccountMeta[] = []; + // Add the members as signers + members.forEach((member) => { + remainingAccounts.unshift({ + pubkey: member, + isSigner: true, + isWritable: false, + }); + }); + + // Add all other accounts + staticAccountKeys.forEach((key, index) => { + remainingAccounts.push({ + pubkey: key, + isSigner: index < header.numRequiredSignatures, + isWritable: + index < + header.numRequiredSignatures - header.numReadonlySignedAccounts || + (index >= header.numRequiredSignatures && + index < + staticAccountKeys.length - header.numReadonlyUnsignedAccounts), + }); + }); + + // Mark the vault as non-signer if it exists + if (remainingAccounts.find((acc) => acc.pubkey.equals(vaultPda))) { + remainingAccounts.find((acc) => acc.pubkey.equals(vaultPda))!.isSigner = + false; + } + // Compile instructions with updated indices + let args_buffer = Buffer.alloc(0); + + // Insert instruction length as u8 as first byte + args_buffer = Buffer.concat([Buffer.from([instructions.length])]); + + // Serialize each instruction + instructions.forEach((ix) => { + const accounts = ix.keys.map((key) => { + const index = remainingAccounts.findIndex((acc) => + acc.pubkey.equals(key.pubkey) + ); + if (index === -1) { + throw new Error( + `Account ${key.pubkey.toBase58()} not found in remaining accounts` + ); + } + return index; + }); - // Compile instructions to get account mapping - const compiledKeys = CompiledKeys.compileWithoutPayer( - instructions + const programIdIndex = remainingAccounts.findIndex((id) => + id.pubkey.equals(ix.programId) ); + if (programIdIndex === -1) { + throw new Error( + `ProgramId ${ix.programId.toBase58()} not found in remaining accounts` + ); + } - // Get message components - const [header, staticAccountKeys] = compiledKeys.getMessageComponents(); - - // Mark the vault as non-signer if it exists - // Create remaining accounts array starting with vault - const remainingAccounts: AccountMeta[] = [ - ...members.map((member, index) => ({ - pubkey: member, - isSigner: true, - isWritable: false, - })), - ]; - - // Add all other accounts - staticAccountKeys.forEach((key, index) => { - remainingAccounts.push({ - pubkey: key, - isSigner: index < header.numRequiredSignatures, - isWritable: index < (header.numRequiredSignatures - header.numReadonlySignedAccounts) || - (index >= header.numRequiredSignatures && - index < (staticAccountKeys.length - header.numReadonlyUnsignedAccounts)) - }); + const serialized_ix = serializeCompiledInstruction({ + programIdIndex, + accountIndexes: accounts, + data: ix.data, }); - // Mark the vault as non-signer if it exists - if (remainingAccounts.find(acc => acc.pubkey.equals(vaultPda))) { - remainingAccounts.find(acc => acc.pubkey.equals(vaultPda))!.isSigner = false; - } - // Compile instructions with updated indices - let args_buffer = Buffer.alloc(0); - - // Insert instruction length as u8 as first byte - args_buffer = Buffer.concat([ - Buffer.from([instructions.length]) - ]); - - // Serialize each instruction - instructions.forEach(ix => { - const accounts = ix.keys.map(key => { - const index = remainingAccounts.findIndex(acc => acc.pubkey.equals(key.pubkey)); - if (index === -1) { - throw new Error(`Account ${key.pubkey.toBase58()} not found in remaining accounts`); - } - return index; - }); - - const programIdIndex = remainingAccounts.findIndex(id => id.pubkey.equals(ix.programId)); - if (programIdIndex === -1) { - throw new Error(`ProgramId ${ix.programId.toBase58()} not found in remaining accounts`); - } - - const serialized_ix = serializeCompiledInstruction({ - programIdIndex, - accountIndexes: accounts, - data: ix.data, - }); - - // Concatenate the serialized instruction to the buffer - args_buffer = Buffer.concat([args_buffer, serialized_ix]); - }); + // Concatenate the serialized instruction to the buffer + args_buffer = Buffer.concat([args_buffer, serialized_ix]); + }); - return { - instructions: args_buffer, - accounts: remainingAccounts, - }; + return { + instructions: args_buffer, + accounts: remainingAccounts, + }; } - function serializeCompiledInstruction(ix: { - programIdIndex: number, - accountIndexes: number[], - data: Buffer | Uint8Array, + programIdIndex: number; + accountIndexes: number[]; + data: Buffer | Uint8Array; }) { - // Create a buffer to hold the serialized instruction - let buffer = Buffer.alloc(0); - - // Add program id index (u8) - buffer = Buffer.concat([buffer, Buffer.from([ix.programIdIndex])]); - - // SmallVec for account indexes - buffer = Buffer.concat([ - buffer, - // Length prefix as u8 - Buffer.from([ix.accountIndexes.length]), - // The account indexes - Buffer.from(ix.accountIndexes) - ]); - - // SmallVec for data - buffer = Buffer.concat([ - buffer, - // Length prefix as u16 (little endian) - Buffer.from(new Uint16Array([ix.data.length]).buffer), - // The actual data bytes - ix.data - ]); - - return Uint8Array.from(buffer); -} \ No newline at end of file + // Create a buffer to hold the serialized instruction + let buffer = Buffer.alloc(0); + + // Add program id index (u8) + buffer = Buffer.concat([buffer, Buffer.from([ix.programIdIndex])]); + + // SmallVec for account indexes + buffer = Buffer.concat([ + buffer, + // Length prefix as u8 + Buffer.from([ix.accountIndexes.length]), + // The account indexes + Buffer.from(ix.accountIndexes), + ]); + + // SmallVec for data + buffer = Buffer.concat([ + buffer, + // Length prefix as u16 (little endian) + Buffer.from(new Uint16Array([ix.data.length]).buffer), + // The actual data bytes + ix.data, + ]); + + return Uint8Array.from(buffer); +} diff --git a/sdk/smart-account/src/utils/compileToSynchronousMessageV2.ts b/sdk/smart-account/src/utils/compileToSynchronousMessageV2.ts new file mode 100644 index 0000000..9f844ed --- /dev/null +++ b/sdk/smart-account/src/utils/compileToSynchronousMessageV2.ts @@ -0,0 +1,240 @@ +import { + AccountMeta, + PublicKey, + TransactionInstruction, +} from "@solana/web3.js"; +import { CompiledKeys } from "./compiled-keys"; + +export function compileToSynchronousMessageAndAccountsV2({ + vaultPda, + members, + instructions, +}: { + vaultPda: PublicKey; + members: PublicKey[]; + instructions: TransactionInstruction[]; +}): { + instructions: Uint8Array; + accounts: AccountMeta[]; +} { + // Compile instructions to get account mapping + const compiledKeys = CompiledKeys.compileWithoutPayer(instructions); + + // Get message components + const [header, staticAccountKeys] = compiledKeys.getMessageComponents(); + + // Mark the vault as non-signer if it exists + // Create remaining accounts array starting with vault + const remainingAccounts: AccountMeta[] = []; + + // Add all other accounts + staticAccountKeys.forEach((key, index) => { + remainingAccounts.push({ + pubkey: key, + isSigner: index < header.numRequiredSignatures, + isWritable: + index < + header.numRequiredSignatures - header.numReadonlySignedAccounts || + (index >= header.numRequiredSignatures && + index < + staticAccountKeys.length - header.numReadonlyUnsignedAccounts), + }); + }); + + // Mark the vault as non-signer if it exists + if (remainingAccounts.find((acc) => acc.pubkey.equals(vaultPda))) { + remainingAccounts.find((acc) => acc.pubkey.equals(vaultPda))!.isSigner = + false; + } + // Compile instructions with updated indices + let args_buffer = Buffer.alloc(0); + + // Insert instruction length as u8 as first byte + args_buffer = Buffer.concat([Buffer.from([instructions.length])]); + + // Serialize each instruction + instructions.forEach((ix) => { + const accounts = ix.keys.map((key) => { + const index = remainingAccounts.findIndex((acc) => + acc.pubkey.equals(key.pubkey) + ); + if (index === -1) { + throw new Error( + `Account ${key.pubkey.toBase58()} not found in remaining accounts` + ); + } + return index; + }); + + const programIdIndex = remainingAccounts.findIndex((id) => + id.pubkey.equals(ix.programId) + ); + if (programIdIndex === -1) { + throw new Error( + `ProgramId ${ix.programId.toBase58()} not found in remaining accounts` + ); + } + + const serialized_ix = serializeCompiledInstruction({ + programIdIndex, + accountIndexes: accounts, + data: ix.data, + }); + + // Concatenate the serialized instruction to the buffer + args_buffer = Buffer.concat([args_buffer, serialized_ix]); + + // Add the members as signers + members.forEach((member) => { + remainingAccounts.unshift({ + pubkey: member, + isSigner: true, + isWritable: false, + }); + }); + }); + + return { + instructions: args_buffer, + accounts: remainingAccounts, + }; +} + +export function compileToSynchronousMessageAndAccountsV2WithHooks({ + vaultPda, + members, + preHookAccounts, + postHookAccounts, + instructions, +}: { + vaultPda: PublicKey; + members: PublicKey[]; + preHookAccounts: AccountMeta[]; + postHookAccounts: AccountMeta[]; + instructions: TransactionInstruction[]; +}): { + instructions: Uint8Array; + accounts: AccountMeta[]; +} { + // Compile instructions to get account mapping + const compiledKeys = CompiledKeys.compileWithoutPayer(instructions); + + // Get message components + const [header, staticAccountKeys] = compiledKeys.getMessageComponents(); + + // Mark the vault as non-signer if it exists + // Create remaining accounts array starting with vault + const remainingAccounts: AccountMeta[] = []; + + // Add all other accounts + staticAccountKeys.forEach((key, index) => { + remainingAccounts.push({ + pubkey: key, + isSigner: index < header.numRequiredSignatures, + isWritable: + index < + header.numRequiredSignatures - header.numReadonlySignedAccounts || + (index >= header.numRequiredSignatures && + index < + staticAccountKeys.length - header.numReadonlyUnsignedAccounts), + }); + }); + + // Mark the vault as non-signer if it exists + if (remainingAccounts.find((acc) => acc.pubkey.equals(vaultPda))) { + remainingAccounts.find((acc) => acc.pubkey.equals(vaultPda))!.isSigner = + false; + } + // Compile instructions with updated indices + let args_buffer = Buffer.alloc(0); + + // Insert instruction length as u8 as first byte + args_buffer = Buffer.concat([Buffer.from([instructions.length])]); + + // Serialize each instruction + instructions.forEach((ix) => { + const accounts = ix.keys.map((key) => { + const index = remainingAccounts.findIndex((acc) => + acc.pubkey.equals(key.pubkey) + ); + if (index === -1) { + throw new Error( + `Account ${key.pubkey.toBase58()} not found in remaining accounts` + ); + } + return index; + }); + + const programIdIndex = remainingAccounts.findIndex((id) => + id.pubkey.equals(ix.programId) + ); + if (programIdIndex === -1) { + throw new Error( + `ProgramId ${ix.programId.toBase58()} not found in remaining accounts` + ); + } + + const serialized_ix = serializeCompiledInstruction({ + programIdIndex, + accountIndexes: accounts, + data: ix.data, + }); + + // Concatenate the serialized instruction to the buffer + args_buffer = Buffer.concat([args_buffer, serialized_ix]); + + // Add the members as signers + members.forEach((member) => { + remainingAccounts.unshift({ + pubkey: member, + isSigner: true, + isWritable: false, + }); + }); + // Add the pre hook accounts after the members + remainingAccounts.splice(members.length, 0, ...preHookAccounts); + // Add the post hook accounts after the pre hook accounts + remainingAccounts.splice( + members.length + preHookAccounts.length, + 0, + ...postHookAccounts + ); + }); + + return { + instructions: args_buffer, + accounts: remainingAccounts, + }; +} + +function serializeCompiledInstruction(ix: { + programIdIndex: number; + accountIndexes: number[]; + data: Buffer | Uint8Array; +}) { + // Create a buffer to hold the serialized instruction + let buffer = Buffer.alloc(0); + + // Add program id index (u8) + buffer = Buffer.concat([buffer, Buffer.from([ix.programIdIndex])]); + + // SmallVec for account indexes + buffer = Buffer.concat([ + buffer, + // Length prefix as u8 + Buffer.from([ix.accountIndexes.length]), + // The account indexes + Buffer.from(ix.accountIndexes), + ]); + + // SmallVec for data + buffer = Buffer.concat([ + buffer, + // Length prefix as u16 (little endian) + Buffer.from(new Uint16Array([ix.data.length]).buffer), + // The actual data bytes + ix.data, + ]); + + return Uint8Array.from(buffer); +} diff --git a/sdk/smart-account/yarn.lock b/sdk/smart-account/yarn.lock index d616fed..9cc5b1d 100644 --- a/sdk/smart-account/yarn.lock +++ b/sdk/smart-account/yarn.lock @@ -1,540 +1,3397 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@babel/runtime@^7.12.5", "@babel/runtime@^7.17.2": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.7.tgz#fcb41a5a70550e04a7b708037c7c32f7f356d8fd" - integrity sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ== - dependencies: - regenerator-runtime "^0.13.11" - -"@metaplex-foundation/beet-solana@^0.3.1": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@metaplex-foundation/beet-solana/-/beet-solana-0.3.1.tgz#4b37cda5c7f32ffd2bdd8b3164edc05c6463ab35" - integrity sha512-tgyEl6dvtLln8XX81JyBvWjIiEcjTkUwZbrM5dIobTmoqMuGewSyk9CClno8qsMsFdB5T3jC91Rjeqmu/6xk2g== - dependencies: - "@metaplex-foundation/beet" ">=0.1.0" - "@solana/web3.js" "^1.56.2" - bs58 "^5.0.0" - debug "^4.3.4" - -"@metaplex-foundation/beet-solana@^0.4.0": - version "0.4.0" - resolved "https://registry.yarnpkg.com/@metaplex-foundation/beet-solana/-/beet-solana-0.4.0.tgz#52891e78674aaa54e0031f1bca5bfbc40de12e8d" - integrity sha512-B1L94N3ZGMo53b0uOSoznbuM5GBNJ8LwSeznxBxJ+OThvfHQ4B5oMUqb+0zdLRfkKGS7Q6tpHK9P+QK0j3w2cQ== - dependencies: - "@metaplex-foundation/beet" ">=0.1.0" - "@solana/web3.js" "^1.56.2" - bs58 "^5.0.0" - debug "^4.3.4" - -"@metaplex-foundation/beet@>=0.1.0", "@metaplex-foundation/beet@^0.7.1": - version "0.7.1" - resolved "https://registry.yarnpkg.com/@metaplex-foundation/beet/-/beet-0.7.1.tgz#0975314211643f87b5f6f3e584fa31abcf4c612c" - integrity sha512-hNCEnS2WyCiYyko82rwuISsBY3KYpe828ubsd2ckeqZr7tl0WVLivGkoyA/qdiaaHEBGdGl71OpfWa2rqL3DiA== - dependencies: - ansicolors "^0.3.2" - bn.js "^5.2.0" - debug "^4.3.3" - -"@metaplex-foundation/rustbin@^0.3.0": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@metaplex-foundation/rustbin/-/rustbin-0.3.1.tgz#bbcd61e8699b73c0b062728c6f5e8d52e8145042" - integrity sha512-hWd2JPrnt2/nJzkBpZD3Y6ZfCUlJujv2K7qUfsxdS0jSwLrSrOvYwmNWFw6mc3lbULj6VP4WDyuy9W5/CHU/lQ== - dependencies: - debug "^4.3.3" - semver "^7.3.7" - text-table "^0.2.0" - toml "^3.0.0" - -"@metaplex-foundation/solita@^0.19.3": - version "0.19.3" - resolved "https://registry.yarnpkg.com/@metaplex-foundation/solita/-/solita-0.19.3.tgz#dbb7659f6af513cdae93201ab079f28b162b0199" - integrity sha512-VnCqW05opw8UueP9IsH3ax6Dk7J+8QuqTs/ceSeMhJquOpoLv3M4crrzFqX+GXr5GH0j/Fk32UlRD7iEp6sEnQ== - dependencies: - "@metaplex-foundation/beet" "^0.7.1" - "@metaplex-foundation/beet-solana" "^0.3.1" - "@metaplex-foundation/rustbin" "^0.3.0" - "@solana/web3.js" "^1.56.2" - ansi-colors "^4.1.3" - camelcase "^6.2.1" - debug "^4.3.3" - js-sha256 "^0.9.0" - prettier "^2.5.1" - snake-case "^3.0.4" - spok "^1.4.3" - -"@noble/ed25519@^1.7.0": - version "1.7.1" - resolved "https://registry.yarnpkg.com/@noble/ed25519/-/ed25519-1.7.1.tgz#6899660f6fbb97798a6fbd227227c4589a454724" - integrity sha512-Rk4SkJFaXZiznFyC/t77Q0NKS4FL7TLJJsVG2V2oiEq3kJVeTdxysEe/yRWSpnWMe808XRDJ+VFh5pt/FN5plw== - -"@noble/hashes@^1.1.2": - version "1.1.5" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.5.tgz#1a0377f3b9020efe2fae03290bd2a12140c95c11" - integrity sha512-LTMZiiLc+V4v1Yi16TD6aX2gmtKszNye0pQgbaLqkvhIqP7nVsSaJsWloGQjJfJ8offaoP5GtX3yY5swbcJxxQ== - -"@noble/secp256k1@^1.6.3": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.0.tgz#d15357f7c227e751d90aa06b05a0e5cf993ba8c1" - integrity sha512-kbacwGSsH/CTout0ZnZWxnW1B+jH/7r/WAAKLBtrRJ/+CUH7lgmQzl3GTrQua3SGKWNSDsS6lmjnDpIJ5Dxyaw== - -"@solana/buffer-layout@^4.0.0": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@solana/buffer-layout/-/buffer-layout-4.0.1.tgz#b996235eaec15b1e0b5092a8ed6028df77fa6c15" - integrity sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA== - dependencies: - buffer "~6.0.3" - -"@solana/web3.js@^1.56.2", "@solana/web3.js@^1.70.3": - version "1.70.3" - resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.70.3.tgz#44040a78d1f86ee6a0a9dbe391b5f891bb404265" - integrity sha512-9JAFXAWB3yhUHnoahzemTz4TcsGqmITPArNlm9795e+LA/DYkIEJIXIosV4ImzDMfqolymZeRgG3O8ewNgYTTA== - dependencies: - "@babel/runtime" "^7.12.5" - "@noble/ed25519" "^1.7.0" - "@noble/hashes" "^1.1.2" - "@noble/secp256k1" "^1.6.3" - "@solana/buffer-layout" "^4.0.0" - agentkeepalive "^4.2.1" - bigint-buffer "^1.1.5" - bn.js "^5.0.0" - borsh "^0.7.0" - bs58 "^4.0.1" - buffer "6.0.1" - fast-stable-stringify "^1.0.0" - jayson "^3.4.4" - node-fetch "2" - rpc-websockets "^7.5.0" - superstruct "^0.14.2" - -"@types/connect@^3.4.33": - version "3.4.35" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" - integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== - dependencies: - "@types/node" "*" - -"@types/node@*", "@types/node@^18.11.17": - version "18.11.17" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.17.tgz#5c009e1d9c38f4a2a9d45c0b0c493fe6cdb4bcb5" - integrity sha512-HJSUJmni4BeDHhfzn6nF0sVmd1SMezP7/4F0Lq+aXzmp2xm9O7WXrUtHW/CHlYVtZUbByEvWidHqRtcJXGF2Ng== - -"@types/node@^12.12.54": - version "12.20.55" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240" - integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ== - -"@types/ws@^7.4.4": - version "7.4.7" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" - integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== - dependencies: - "@types/node" "*" - -JSONStream@^1.3.5: - version "1.3.5" - resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" - integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== - dependencies: - jsonparse "^1.2.0" - through ">=2.2.7 <3" - -agentkeepalive@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.2.1.tgz#a7975cbb9f83b367f06c90cc51ff28fe7d499717" - integrity sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA== - dependencies: - debug "^4.1.0" - depd "^1.1.2" - humanize-ms "^1.2.1" - -ansi-colors@^4.1.3: - version "4.1.3" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" - integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== - -ansicolors@^0.3.2, ansicolors@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979" - integrity sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg== - -base-x@^3.0.2: - version "3.0.9" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" - integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== - dependencies: - safe-buffer "^5.0.1" - -base-x@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-4.0.0.tgz#d0e3b7753450c73f8ad2389b5c018a4af7b2224a" - integrity sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw== - -base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - -bigint-buffer@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/bigint-buffer/-/bigint-buffer-1.1.5.tgz#d038f31c8e4534c1f8d0015209bf34b4fa6dd442" - integrity sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA== - dependencies: - bindings "^1.3.0" - -bindings@^1.3.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" - integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== - dependencies: - file-uri-to-path "1.0.0" - -bn.js@^5.0.0, bn.js@^5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" - integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== - -borsh@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/borsh/-/borsh-0.7.0.tgz#6e9560d719d86d90dc589bca60ffc8a6c51fec2a" - integrity sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA== - dependencies: - bn.js "^5.2.0" - bs58 "^4.0.0" - text-encoding-utf-8 "^1.0.2" - -bs58@^4.0.0, bs58@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" - integrity sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw== - dependencies: - base-x "^3.0.2" - -bs58@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/bs58/-/bs58-5.0.0.tgz#865575b4d13c09ea2a84622df6c8cbeb54ffc279" - integrity sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ== - dependencies: - base-x "^4.0.0" - -buffer@6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.1.tgz#3cbea8c1463e5a0779e30b66d4c88c6ffa182ac2" - integrity sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.2.1" - -buffer@~6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" - integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.2.1" - -bufferutil@^4.0.1: - version "4.0.7" - resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.7.tgz#60c0d19ba2c992dd8273d3f73772ffc894c153ad" - integrity sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw== - dependencies: - node-gyp-build "^4.3.0" - -camelcase@^6.2.1: - version "6.3.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" - integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== - -commander@^2.20.3: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -debug@^4.1.0, debug@^4.3.3, debug@^4.3.4: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - -delay@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/delay/-/delay-5.0.0.tgz#137045ef1b96e5071060dd5be60bf9334436bd1d" - integrity sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw== - -depd@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== - -dot-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" - integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== - dependencies: - no-case "^3.0.4" - tslib "^2.0.3" - -es6-promise@^4.0.3: - version "4.2.8" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" - integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== - -es6-promisify@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" - integrity sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ== - dependencies: - es6-promise "^4.0.3" - -eventemitter3@^4.0.7: - version "4.0.7" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" - integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== - -eyes@^0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" - integrity sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ== - -fast-stable-stringify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz#5c5543462b22aeeefd36d05b34e51c78cb86d313" - integrity sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag== - -file-uri-to-path@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" - integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== - -humanize-ms@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" - integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== - dependencies: - ms "^2.0.0" - -ieee754@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - -isomorphic-ws@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" - integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== - -jayson@^3.4.4: - version "3.7.0" - resolved "https://registry.yarnpkg.com/jayson/-/jayson-3.7.0.tgz#b735b12d06d348639ae8230d7a1e2916cb078f25" - integrity sha512-tfy39KJMrrXJ+mFcMpxwBvFDetS8LAID93+rycFglIQM4kl3uNR3W4lBLE/FFhsoUCEox5Dt2adVpDm/XtebbQ== - dependencies: - "@types/connect" "^3.4.33" - "@types/node" "^12.12.54" - "@types/ws" "^7.4.4" - JSONStream "^1.3.5" - commander "^2.20.3" - delay "^5.0.0" - es6-promisify "^5.0.0" - eyes "^0.1.8" - isomorphic-ws "^4.0.1" - json-stringify-safe "^5.0.1" - lodash "^4.17.20" - uuid "^8.3.2" - ws "^7.4.5" - -js-sha256@^0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/js-sha256/-/js-sha256-0.9.0.tgz#0b89ac166583e91ef9123644bd3c5334ce9d0966" - integrity sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA== - -json-stringify-safe@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== - -jsonparse@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" - integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== - -lodash@^4.17.20: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -lower-case@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" - integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== - dependencies: - tslib "^2.0.3" - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@^2.0.0: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -no-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" - integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== - dependencies: - lower-case "^2.0.2" - tslib "^2.0.3" - -node-fetch@2: - version "2.6.7" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" - integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== - dependencies: - whatwg-url "^5.0.0" - -node-gyp-build@^4.3.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.5.0.tgz#7a64eefa0b21112f89f58379da128ac177f20e40" - integrity sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg== - -prettier@^2.5.1: - version "2.8.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.1.tgz#4e1fd11c34e2421bc1da9aea9bd8127cd0a35efc" - integrity sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg== - -regenerator-runtime@^0.13.11: - version "0.13.11" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" - integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== - -rpc-websockets@^7.5.0: - version "7.5.0" - resolved "https://registry.yarnpkg.com/rpc-websockets/-/rpc-websockets-7.5.0.tgz#bbeb87572e66703ff151e50af1658f98098e2748" - integrity sha512-9tIRi1uZGy7YmDjErf1Ax3wtqdSSLIlnmL5OtOzgd5eqPKbsPpwDP5whUDO2LQay3Xp0CcHlcNSGzacNRluBaQ== - dependencies: - "@babel/runtime" "^7.17.2" - eventemitter3 "^4.0.7" - uuid "^8.3.2" - ws "^8.5.0" - optionalDependencies: - bufferutil "^4.0.1" - utf-8-validate "^5.0.2" - -safe-buffer@^5.0.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -semver@^7.3.7: - version "7.3.8" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" - integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== - dependencies: - lru-cache "^6.0.0" - -snake-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-3.0.4.tgz#4f2bbd568e9935abdfd593f34c691dadb49c452c" - integrity sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg== - dependencies: - dot-case "^3.0.4" - tslib "^2.0.3" - -spok@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/spok/-/spok-1.4.3.tgz#8516234e6bd8caf0e10567bd675e15fd03b5ceb8" - integrity sha512-5wFGctwrk638aDs+44u99kohxFNByUq2wo0uShQ9yqxSmsxqx7zKbMo1Busy4s7stZQXU+PhJ/BlVf2XWFEGIw== - dependencies: - ansicolors "~0.3.2" - -superstruct@^0.14.2: - version "0.14.2" - resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-0.14.2.tgz#0dbcdf3d83676588828f1cf5ed35cda02f59025b" - integrity sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ== - -text-encoding-utf-8@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz#585b62197b0ae437e3c7b5d0af27ac1021e10d13" - integrity sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg== - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== - -"through@>=2.2.7 <3": - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== - -toml@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/toml/-/toml-3.0.0.tgz#342160f1af1904ec9d204d03a5d61222d762c5ee" - integrity sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w== - -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== - -tslib@^2.0.3: - version "2.4.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" - integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA== - -typescript@^4.9.4: - version "4.9.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.4.tgz#a2a3d2756c079abda241d75f149df9d561091e78" - integrity sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg== - -utf-8-validate@^5.0.2: - version "5.0.10" - resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz#d7d10ea39318171ca982718b6b96a8d2442571a2" - integrity sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ== - dependencies: - node-gyp-build "^4.3.0" - -uuid@^8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" - integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== - -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - -ws@^7.4.5: - version "7.5.9" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" - integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== - -ws@^8.5.0: - version "8.11.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.11.0.tgz#6a0d36b8edfd9f96d8b25683db2f8d7de6e8e143" - integrity sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== +# This file is generated by running "yarn install" inside your project. +# Manual changes might be lost - proceed with caution! + +__metadata: + version: 6 + cacheKey: 8 + +"@babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.17.2": + version: 7.20.7 + resolution: "@babel/runtime@npm:7.20.7" + dependencies: + regenerator-runtime: ^0.13.11 + checksum: 4629ce5c46f06cca9cfb9b7fc00d48003335a809888e2b91ec2069a2dcfbfef738480cff32ba81e0b7c290f8918e5c22ddcf2b710001464ee84ba62c7e32a3a3 + languageName: node + linkType: hard + +"@babel/runtime@npm:^7.25.0": + version: 7.27.6 + resolution: "@babel/runtime@npm:7.27.6" + checksum: 3f7b879df1823c0926bd5dbc941c62f5d60faa790c1aab9758c04799e1f04ee8d93553be9ec059d4e5882f19fe03cbe8933ee4f46212dced0f6d8205992c9c9a + languageName: node + linkType: hard + +"@esbuild/aix-ppc64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/aix-ppc64@npm:0.25.8" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/android-arm64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/android-arm64@npm:0.25.8" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/android-arm@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/android-arm@npm:0.25.8" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@esbuild/android-x64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/android-x64@npm:0.25.8" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/darwin-arm64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/darwin-arm64@npm:0.25.8" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/darwin-x64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/darwin-x64@npm:0.25.8" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/freebsd-arm64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/freebsd-arm64@npm:0.25.8" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/freebsd-x64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/freebsd-x64@npm:0.25.8" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/linux-arm64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/linux-arm64@npm:0.25.8" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/linux-arm@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/linux-arm@npm:0.25.8" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@esbuild/linux-ia32@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/linux-ia32@npm:0.25.8" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/linux-loong64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/linux-loong64@npm:0.25.8" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + +"@esbuild/linux-mips64el@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/linux-mips64el@npm:0.25.8" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + +"@esbuild/linux-ppc64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/linux-ppc64@npm:0.25.8" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/linux-riscv64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/linux-riscv64@npm:0.25.8" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + +"@esbuild/linux-s390x@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/linux-s390x@npm:0.25.8" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + +"@esbuild/linux-x64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/linux-x64@npm:0.25.8" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/netbsd-arm64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/netbsd-arm64@npm:0.25.8" + conditions: os=netbsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/netbsd-x64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/netbsd-x64@npm:0.25.8" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openbsd-arm64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/openbsd-arm64@npm:0.25.8" + conditions: os=openbsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/openbsd-x64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/openbsd-x64@npm:0.25.8" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openharmony-arm64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/openharmony-arm64@npm:0.25.8" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/sunos-x64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/sunos-x64@npm:0.25.8" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/win32-arm64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/win32-arm64@npm:0.25.8" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/win32-ia32@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/win32-ia32@npm:0.25.8" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/win32-x64@npm:0.25.8": + version: 0.25.8 + resolution: "@esbuild/win32-x64@npm:0.25.8" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@isaacs/cliui@npm:^8.0.2": + version: 8.0.2 + resolution: "@isaacs/cliui@npm:8.0.2" + dependencies: + string-width: ^5.1.2 + string-width-cjs: "npm:string-width@^4.2.0" + strip-ansi: ^7.0.1 + strip-ansi-cjs: "npm:strip-ansi@^6.0.1" + wrap-ansi: ^8.1.0 + wrap-ansi-cjs: "npm:wrap-ansi@^7.0.0" + checksum: 4a473b9b32a7d4d3cfb7a614226e555091ff0c5a29a1734c28c72a182c2f6699b26fc6b5c2131dfd841e86b185aea714c72201d7c98c2fba5f17709333a67aeb + languageName: node + linkType: hard + +"@isaacs/fs-minipass@npm:^4.0.0": + version: 4.0.1 + resolution: "@isaacs/fs-minipass@npm:4.0.1" + dependencies: + minipass: ^7.0.4 + checksum: 5d36d289960e886484362d9eb6a51d1ea28baed5f5d0140bbe62b99bac52eaf06cc01c2bc0d3575977962f84f6b2c4387b043ee632216643d4787b0999465bf2 + languageName: node + linkType: hard + +"@jridgewell/gen-mapping@npm:^0.3.2": + version: 0.3.12 + resolution: "@jridgewell/gen-mapping@npm:0.3.12" + dependencies: + "@jridgewell/sourcemap-codec": ^1.5.0 + "@jridgewell/trace-mapping": ^0.3.24 + checksum: 56ee1631945084897f274e65348afbaca7970ce92e3c23b3a23b2fe5d0d2f0c67614f0df0f2bb070e585e944bbaaf0c11cee3a36318ab8a36af46f2fd566bc40 + languageName: node + linkType: hard + +"@jridgewell/resolve-uri@npm:^3.1.0": + version: 3.1.2 + resolution: "@jridgewell/resolve-uri@npm:3.1.2" + checksum: 83b85f72c59d1c080b4cbec0fef84528963a1b5db34e4370fa4bd1e3ff64a0d80e0cee7369d11d73c704e0286fb2865b530acac7a871088fbe92b5edf1000870 + languageName: node + linkType: hard + +"@jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.5.0": + version: 1.5.4 + resolution: "@jridgewell/sourcemap-codec@npm:1.5.4" + checksum: 959093724bfbc7c1c9aadc08066154f5c1f2acc647b45bd59beec46922cbfc6a9eda4a2114656de5bc00bb3600e420ea9a4cb05e68dcf388619f573b77bd9f0c + languageName: node + linkType: hard + +"@jridgewell/trace-mapping@npm:^0.3.24": + version: 0.3.29 + resolution: "@jridgewell/trace-mapping@npm:0.3.29" + dependencies: + "@jridgewell/resolve-uri": ^3.1.0 + "@jridgewell/sourcemap-codec": ^1.4.14 + checksum: 5e92eeafa5131a4f6b7122063833d657f885cb581c812da54f705d7a599ff36a75a4a093a83b0f6c7e95642f5772dd94753f696915e8afea082237abf7423ca3 + languageName: node + linkType: hard + +"@metaplex-foundation/beet-solana@npm:0.4.0": + version: 0.4.0 + resolution: "@metaplex-foundation/beet-solana@npm:0.4.0" + dependencies: + "@metaplex-foundation/beet": ">=0.1.0" + "@solana/web3.js": ^1.56.2 + bs58: ^5.0.0 + debug: ^4.3.4 + checksum: ee746c2d15f985c31d133d4ee29efbda445877473cc32aafa4b684ce3fa9a916ddff30d0e3cfef7654ff5725adff59a62a635c76bc781a6e1362c5b5d3137ed0 + languageName: node + linkType: hard + +"@metaplex-foundation/beet-solana@npm:^0.3.1": + version: 0.3.1 + resolution: "@metaplex-foundation/beet-solana@npm:0.3.1" + dependencies: + "@metaplex-foundation/beet": ">=0.1.0" + "@solana/web3.js": ^1.56.2 + bs58: ^5.0.0 + debug: ^4.3.4 + checksum: 5405ec57c8cdb2dce016bf96f1cbd96ae185d6c764b8bdd1aaa68028e1970ad4815e7eb026a61703f57c33ddac261e47874e013bb03d84fa74ad78fce4b6e7cd + languageName: node + linkType: hard + +"@metaplex-foundation/beet@npm:0.7.1, @metaplex-foundation/beet@npm:>=0.1.0, @metaplex-foundation/beet@npm:^0.7.1": + version: 0.7.1 + resolution: "@metaplex-foundation/beet@npm:0.7.1" + dependencies: + ansicolors: ^0.3.2 + bn.js: ^5.2.0 + debug: ^4.3.3 + checksum: f8a330073ab1a0976478e9847c0e63e32f7bee67ea6306e1f89784e8275e30daaecba7cbc5f3424e5d96c411aa3bfbc2b638c105a90067a985acdfbd33a1a287 + languageName: node + linkType: hard + +"@metaplex-foundation/cusper@npm:^0.0.2": + version: 0.0.2 + resolution: "@metaplex-foundation/cusper@npm:0.0.2" + checksum: d157953baf42a2a012cdeb809c1785f29a44d80a3b5a3841c930baeb12ac6ddcf37f1a15eded4dce20d66f7bc8f23bedb87e905758df721e274bfcd816e70ba1 + languageName: node + linkType: hard + +"@metaplex-foundation/rustbin@npm:^0.3.0": + version: 0.3.1 + resolution: "@metaplex-foundation/rustbin@npm:0.3.1" + dependencies: + debug: ^4.3.3 + semver: ^7.3.7 + text-table: ^0.2.0 + toml: ^3.0.0 + checksum: 042eb8cb729e886477efa885693dadcf31722c071f8adc5a49509483d846d4d359999b9f2beff9406f4dc9fa0a0f0bdb37be4b0c68426864f9f9f60b456cc74b + languageName: node + linkType: hard + +"@metaplex-foundation/solita@npm:0.20.0": + version: 0.20.0 + resolution: "@metaplex-foundation/solita@npm:0.20.0" + dependencies: + "@metaplex-foundation/beet": ^0.7.1 + "@metaplex-foundation/beet-solana": ^0.3.1 + "@metaplex-foundation/rustbin": ^0.3.0 + "@solana/web3.js": ^1.56.2 + ansi-colors: ^4.1.3 + camelcase: ^6.2.1 + debug: ^4.3.3 + js-sha256: ^0.9.0 + prettier: ^2.5.1 + snake-case: ^3.0.4 + spok: ^1.4.3 + bin: + solita: dist/src/cli/solita.js + checksum: 9596a80063398193af85b808fc704328916f5d76f3e30bc01d6e3af39fa4004815eb64a63d0b7e59d0e83835f7f83edf569914016b97eef8378d93b68081dcc2 + languageName: node + linkType: hard + +"@noble/curves@npm:^1.4.2": + version: 1.9.4 + resolution: "@noble/curves@npm:1.9.4" + dependencies: + "@noble/hashes": 1.8.0 + checksum: 464813a81982ad670d2ae38452eea389066cf3b8d976ec2992dfa7c47b809a3703e7cf4f0915c559792fff97284563176e2ac5d06c353434292789404cbfc3dd + languageName: node + linkType: hard + +"@noble/ed25519@npm:^1.7.0": + version: 1.7.1 + resolution: "@noble/ed25519@npm:1.7.1" + checksum: b8e50306ac70f5cecc349111997e72e897b47a28d406b96cf95d0ebe7cbdefb8380d26117d7847d94102281db200aa3a494e520f9fc12e2f292e0762cb0fa333 + languageName: node + linkType: hard + +"@noble/hashes@npm:1.8.0, @noble/hashes@npm:^1.4.0": + version: 1.8.0 + resolution: "@noble/hashes@npm:1.8.0" + checksum: c94e98b941963676feaba62475b1ccfa8341e3f572adbb3b684ee38b658df44100187fa0ef4220da580b13f8d27e87d5492623c8a02ecc61f23fb9960c7918f5 + languageName: node + linkType: hard + +"@noble/hashes@npm:^1.1.2": + version: 1.1.5 + resolution: "@noble/hashes@npm:1.1.5" + checksum: de3f095a7ac1cbf5b4b3d09f193288d4f2eec35fbadf2ed9fd7e47d8a3042fef410052ba62dc0296a185f994c11192f5357fdb1bd9178c905efd82e946c53b00 + languageName: node + linkType: hard + +"@noble/secp256k1@npm:^1.6.3": + version: 1.7.0 + resolution: "@noble/secp256k1@npm:1.7.0" + checksum: 540a2b8e527ee1e5522af1c430e54945ad373883cac983b115136cd0950efa1f2c473ee6a36d8e69b6809b3ee586276de62f5fa705c77a9425721e81bada8116 + languageName: node + linkType: hard + +"@npmcli/agent@npm:^3.0.0": + version: 3.0.0 + resolution: "@npmcli/agent@npm:3.0.0" + dependencies: + agent-base: ^7.1.0 + http-proxy-agent: ^7.0.0 + https-proxy-agent: ^7.0.1 + lru-cache: ^10.0.1 + socks-proxy-agent: ^8.0.3 + checksum: e8fc25d536250ed3e669813b36e8c6d805628b472353c57afd8c4fde0fcfcf3dda4ffe22f7af8c9070812ec2e7a03fb41d7151547cef3508efe661a5a3add20f + languageName: node + linkType: hard + +"@npmcli/fs@npm:^4.0.0": + version: 4.0.0 + resolution: "@npmcli/fs@npm:4.0.0" + dependencies: + semver: ^7.3.5 + checksum: 68951c589e9a4328698a35fd82fe71909a257d6f2ede0434d236fa55634f0fbcad9bb8755553ce5849bd25ee6f019f4d435921ac715c853582c4a7f5983c8d4a + languageName: node + linkType: hard + +"@pkgjs/parseargs@npm:^0.11.0": + version: 0.11.0 + resolution: "@pkgjs/parseargs@npm:0.11.0" + checksum: 6ad6a00fc4f2f2cfc6bff76fb1d88b8ee20bc0601e18ebb01b6d4be583733a860239a521a7fbca73b612e66705078809483549d2b18f370eb346c5155c8e4a0f + languageName: node + linkType: hard + +"@rollup/rollup-android-arm-eabi@npm:4.45.1": + version: 4.45.1 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.45.1" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@rollup/rollup-android-arm64@npm:4.45.1": + version: 4.45.1 + resolution: "@rollup/rollup-android-arm64@npm:4.45.1" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-darwin-arm64@npm:4.45.1": + version: 4.45.1 + resolution: "@rollup/rollup-darwin-arm64@npm:4.45.1" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-darwin-x64@npm:4.45.1": + version: 4.45.1 + resolution: "@rollup/rollup-darwin-x64@npm:4.45.1" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@rollup/rollup-freebsd-arm64@npm:4.45.1": + version: 4.45.1 + resolution: "@rollup/rollup-freebsd-arm64@npm:4.45.1" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-freebsd-x64@npm:4.45.1": + version: 4.45.1 + resolution: "@rollup/rollup-freebsd-x64@npm:4.45.1" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm-gnueabihf@npm:4.45.1": + version: 4.45.1 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.45.1" + conditions: os=linux & cpu=arm & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm-musleabihf@npm:4.45.1": + version: 4.45.1 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.45.1" + conditions: os=linux & cpu=arm & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm64-gnu@npm:4.45.1": + version: 4.45.1 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.45.1" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm64-musl@npm:4.45.1": + version: 4.45.1 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.45.1" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-loongarch64-gnu@npm:4.45.1": + version: 4.45.1 + resolution: "@rollup/rollup-linux-loongarch64-gnu@npm:4.45.1" + conditions: os=linux & cpu=loong64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-powerpc64le-gnu@npm:4.45.1": + version: 4.45.1 + resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.45.1" + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-riscv64-gnu@npm:4.45.1": + version: 4.45.1 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.45.1" + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-riscv64-musl@npm:4.45.1": + version: 4.45.1 + resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.45.1" + conditions: os=linux & cpu=riscv64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-s390x-gnu@npm:4.45.1": + version: 4.45.1 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.45.1" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-x64-gnu@npm:4.45.1": + version: 4.45.1 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.45.1" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-x64-musl@npm:4.45.1": + version: 4.45.1 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.45.1" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-win32-arm64-msvc@npm:4.45.1": + version: 4.45.1 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.45.1" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-win32-ia32-msvc@npm:4.45.1": + version: 4.45.1 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.45.1" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@rollup/rollup-win32-x64-msvc@npm:4.45.1": + version: 4.45.1 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.45.1" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@solana/buffer-layout-utils@npm:^0.2.0": + version: 0.2.0 + resolution: "@solana/buffer-layout-utils@npm:0.2.0" + dependencies: + "@solana/buffer-layout": ^4.0.0 + "@solana/web3.js": ^1.32.0 + bigint-buffer: ^1.1.5 + bignumber.js: ^9.0.1 + checksum: 9284242245b18b49577195ba7548263850be865a4a2d183944fa01bb76382039db589aab8473698e9bb734b515ada9b4d70db0a72e341c5d567c59b83d6d0840 + languageName: node + linkType: hard + +"@solana/buffer-layout@npm:^4.0.0, @solana/buffer-layout@npm:^4.0.1": + version: 4.0.1 + resolution: "@solana/buffer-layout@npm:4.0.1" + dependencies: + buffer: ~6.0.3 + checksum: bf846888e813187243d4008a7a9f58b49d16cbd995b9d7f1b72898aa510ed77b1ce5e8468e7b2fd26dd81e557a4e74a666e21fccb95f123c1f740d41138bbacd + languageName: node + linkType: hard + +"@solana/codecs-core@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/codecs-core@npm:2.0.0-rc.1" + dependencies: + "@solana/errors": 2.0.0-rc.1 + peerDependencies: + typescript: ">=5" + checksum: e3a138cbdc2b87c6296c449384b684ca2f90cf212cee1cf0a1f30385c3acc72c9a3dc2e60e3152723b9fa5640635bcf69ce06581d83113986ede05d41139f0ba + languageName: node + linkType: hard + +"@solana/codecs-core@npm:2.3.0": + version: 2.3.0 + resolution: "@solana/codecs-core@npm:2.3.0" + dependencies: + "@solana/errors": 2.3.0 + peerDependencies: + typescript: ">=5.3.3" + checksum: 037f4d40ab89bf9db9139a3aedfc4a39f8b044d2093216c0e8a7306edfaf93fbc0d5c49e6011fb3caeb2b69e97601f3c339a3201109b64e005993aa203814810 + languageName: node + linkType: hard + +"@solana/codecs-data-structures@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/codecs-data-structures@npm:2.0.0-rc.1" + dependencies: + "@solana/codecs-core": 2.0.0-rc.1 + "@solana/codecs-numbers": 2.0.0-rc.1 + "@solana/errors": 2.0.0-rc.1 + peerDependencies: + typescript: ">=5" + checksum: 7c24700be7c935fc066dc70e1a02c32d9f17393d3898074e6dcff2c2083012dc8c5583fff5ee04f8ce4578c57bb708688f5e52aad301aa5543aab293640a0b21 + languageName: node + linkType: hard + +"@solana/codecs-numbers@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/codecs-numbers@npm:2.0.0-rc.1" + dependencies: + "@solana/codecs-core": 2.0.0-rc.1 + "@solana/errors": 2.0.0-rc.1 + peerDependencies: + typescript: ">=5" + checksum: 370c1f94970e969b1f523d47714ddd751b68f622967455e2376590af0f230e027dce365bd54a9017fbc064ed21447f795c775c46285222c42a11b8ed46a41570 + languageName: node + linkType: hard + +"@solana/codecs-numbers@npm:^2.1.0": + version: 2.3.0 + resolution: "@solana/codecs-numbers@npm:2.3.0" + dependencies: + "@solana/codecs-core": 2.3.0 + "@solana/errors": 2.3.0 + peerDependencies: + typescript: ">=5.3.3" + checksum: 8b8f88eeeec0eb8e7622c82d3ac580672c28d84ff243eddf40cfa1da4645d34b1c8d3dfd7364fa7f76a3cc0e05ffbb69fcb46d35880184e8eca465a9836bb5ee + languageName: node + linkType: hard + +"@solana/codecs-strings@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/codecs-strings@npm:2.0.0-rc.1" + dependencies: + "@solana/codecs-core": 2.0.0-rc.1 + "@solana/codecs-numbers": 2.0.0-rc.1 + "@solana/errors": 2.0.0-rc.1 + peerDependencies: + fastestsmallesttextencoderdecoder: ^1.0.22 + typescript: ">=5" + checksum: 0706605311508b02f7dc4bfde6f93237337ecde051c83f172a121b52676e2a21af90f916624f57c0e80bbe420412ed98c1e7ae90a583761b028cc6a883fa4a0e + languageName: node + linkType: hard + +"@solana/codecs@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/codecs@npm:2.0.0-rc.1" + dependencies: + "@solana/codecs-core": 2.0.0-rc.1 + "@solana/codecs-data-structures": 2.0.0-rc.1 + "@solana/codecs-numbers": 2.0.0-rc.1 + "@solana/codecs-strings": 2.0.0-rc.1 + "@solana/options": 2.0.0-rc.1 + peerDependencies: + typescript: ">=5" + checksum: 8586abfd1e2792008a447c29efc22e0bfefd7d97a8025090dd49ec07c8c860e51c44355ab74faf43e23336f3dd2e1353238fa4b009d3fe60ff3f02b46a96aa04 + languageName: node + linkType: hard + +"@solana/errors@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/errors@npm:2.0.0-rc.1" + dependencies: + chalk: ^5.3.0 + commander: ^12.1.0 + peerDependencies: + typescript: ">=5" + bin: + errors: bin/cli.mjs + checksum: 906892a892d250c2236449b875b174e0e19ade788146d0e63da23c83d89b98a762770c276341fae8f73959efc57d01090e0e979d111b12ac0e451f2402a8d092 + languageName: node + linkType: hard + +"@solana/errors@npm:2.3.0": + version: 2.3.0 + resolution: "@solana/errors@npm:2.3.0" + dependencies: + chalk: ^5.4.1 + commander: ^14.0.0 + peerDependencies: + typescript: ">=5.3.3" + bin: + errors: bin/cli.mjs + checksum: 7ddb4113de064f693bde01daffc31f880125b4e89d16ee22e1e5c82bb5505fe8445ecf32451538d201fd36ff999bce7bb53e541104cc353c8f32cec6430331b5 + languageName: node + linkType: hard + +"@solana/options@npm:2.0.0-rc.1": + version: 2.0.0-rc.1 + resolution: "@solana/options@npm:2.0.0-rc.1" + dependencies: + "@solana/codecs-core": 2.0.0-rc.1 + "@solana/codecs-data-structures": 2.0.0-rc.1 + "@solana/codecs-numbers": 2.0.0-rc.1 + "@solana/codecs-strings": 2.0.0-rc.1 + "@solana/errors": 2.0.0-rc.1 + peerDependencies: + typescript: ">=5" + checksum: 63f3ed04e56ca232023fcf35ddab8f01a1ba7aae932990908657dec833ff4133ad0af279417d4bce291367903dbd3b962287796a22dd0aaa1d3e3290613a442e + languageName: node + linkType: hard + +"@solana/spl-token-metadata@npm:^0.1.2": + version: 0.1.6 + resolution: "@solana/spl-token-metadata@npm:0.1.6" + dependencies: + "@solana/codecs": 2.0.0-rc.1 + peerDependencies: + "@solana/web3.js": ^1.95.3 + checksum: a19d7d659c3fca375312e86cf4b0a2077327b220462b46a8627f0cc1892c97ce34cfbe9c3645620496d7b1177d56628b16a7357cd61314e079c1d9c73c944d98 + languageName: node + linkType: hard + +"@solana/spl-token@npm:^0.3.6": + version: 0.3.11 + resolution: "@solana/spl-token@npm:0.3.11" + dependencies: + "@solana/buffer-layout": ^4.0.0 + "@solana/buffer-layout-utils": ^0.2.0 + "@solana/spl-token-metadata": ^0.1.2 + buffer: ^6.0.3 + peerDependencies: + "@solana/web3.js": ^1.88.0 + checksum: 84faef5e8ed798e21870728817f650d572a0d0b8c8ac6591f75325d7e89831df396f48384083a65f8b79c30ea4cbfabd0ccb4fbc7a4f20953d133b746ed8b99d + languageName: node + linkType: hard + +"@solana/web3.js@npm:^1.32.0": + version: 1.98.2 + resolution: "@solana/web3.js@npm:1.98.2" + dependencies: + "@babel/runtime": ^7.25.0 + "@noble/curves": ^1.4.2 + "@noble/hashes": ^1.4.0 + "@solana/buffer-layout": ^4.0.1 + "@solana/codecs-numbers": ^2.1.0 + agentkeepalive: ^4.5.0 + bn.js: ^5.2.1 + borsh: ^0.7.0 + bs58: ^4.0.1 + buffer: 6.0.3 + fast-stable-stringify: ^1.0.0 + jayson: ^4.1.1 + node-fetch: ^2.7.0 + rpc-websockets: ^9.0.2 + superstruct: ^2.0.2 + checksum: 23b8165cf603aeba4dd9f521eada10d1ed992ffad709298c5c7ffba6c17020e29c363e95664ecdb9a374d635060ee436c71761bee4b665308d231ab5524b2df8 + languageName: node + linkType: hard + +"@solana/web3.js@npm:^1.56.2, @solana/web3.js@npm:^1.70.3": + version: 1.70.3 + resolution: "@solana/web3.js@npm:1.70.3" + dependencies: + "@babel/runtime": ^7.12.5 + "@noble/ed25519": ^1.7.0 + "@noble/hashes": ^1.1.2 + "@noble/secp256k1": ^1.6.3 + "@solana/buffer-layout": ^4.0.0 + agentkeepalive: ^4.2.1 + bigint-buffer: ^1.1.5 + bn.js: ^5.0.0 + borsh: ^0.7.0 + bs58: ^4.0.1 + buffer: 6.0.1 + fast-stable-stringify: ^1.0.0 + jayson: ^3.4.4 + node-fetch: 2 + rpc-websockets: ^7.5.0 + superstruct: ^0.14.2 + checksum: 3a2809fed6ca994930f3b5ac263a1c7ab2e67b0b9d3343bdf43208f53031918327eb23c4b5eecd701d25418aa35f45e46f03245e0eaa05129d88c385725d316d + languageName: node + linkType: hard + +"@sqds/smart-account@workspace:.": + version: 0.0.0-use.local + resolution: "@sqds/smart-account@workspace:." + dependencies: + "@metaplex-foundation/beet": 0.7.1 + "@metaplex-foundation/beet-solana": 0.4.0 + "@metaplex-foundation/cusper": ^0.0.2 + "@metaplex-foundation/solita": 0.20.0 + "@solana/spl-token": ^0.3.6 + "@solana/web3.js": ^1.70.3 + "@types/invariant": 2.2.35 + "@types/node": 24.0.15 + assert: ^2.0.0 + bn.js: ^5.2.1 + buffer: 6.0.3 + invariant: 2.2.4 + tsup: ^8.0.2 + typedoc: ^0.25.7 + typescript: "*" + languageName: unknown + linkType: soft + +"@swc/helpers@npm:^0.5.11": + version: 0.5.17 + resolution: "@swc/helpers@npm:0.5.17" + dependencies: + tslib: ^2.8.0 + checksum: 085e13b536323945dfc3a270debf270bda6dfc80a1c68fd2ed08f7cbdfcbdaeead402650b5b10722e54e4a24193afc8a3c6f63d3d6d719974e7470557fb415bd + languageName: node + linkType: hard + +"@types/connect@npm:^3.4.33": + version: 3.4.35 + resolution: "@types/connect@npm:3.4.35" + dependencies: + "@types/node": "*" + checksum: fe81351470f2d3165e8b12ce33542eef89ea893e36dd62e8f7d72566dfb7e448376ae962f9f3ea888547ce8b55a40020ca0e01d637fab5d99567673084542641 + languageName: node + linkType: hard + +"@types/estree@npm:1.0.8": + version: 1.0.8 + resolution: "@types/estree@npm:1.0.8" + checksum: bd93e2e415b6f182ec4da1074e1f36c480f1d26add3e696d54fb30c09bc470897e41361c8fd957bf0985024f8fbf1e6e2aff977d79352ef7eb93a5c6dcff6c11 + languageName: node + linkType: hard + +"@types/invariant@npm:2.2.35": + version: 2.2.35 + resolution: "@types/invariant@npm:2.2.35" + checksum: af1b624057c89789ed0917838fea3d42bb0c101cc22b829a24d8777c678be3bc79d6ae05992a13bdf607b94731262467a2e62a809602ea1f7eea5e8c2242660d + languageName: node + linkType: hard + +"@types/node@npm:*": + version: 18.11.17 + resolution: "@types/node@npm:18.11.17" + checksum: 1933afd068d5c75c068c6c4df6d10edb3b0b2bb6503d544e2f0496ac007c90596e6a5e284a8ef032451bc16f871b7e46719d7d2bea60e9b25d13a77d52161cac + languageName: node + linkType: hard + +"@types/node@npm:24.0.15": + version: 24.0.15 + resolution: "@types/node@npm:24.0.15" + dependencies: + undici-types: ~7.8.0 + checksum: 27f31e6976587efdfd13c0024703d7e11e6a27a6af48d488c6e5662733c9e8d47ac059e38cd9d491425f68f0c5e8e2bc060859b0b66afe79af0697acb0c25e4d + languageName: node + linkType: hard + +"@types/node@npm:^12.12.54": + version: 12.20.55 + resolution: "@types/node@npm:12.20.55" + checksum: e4f86785f4092706e0d3b0edff8dca5a13b45627e4b36700acd8dfe6ad53db71928c8dee914d4276c7fd3b6ccd829aa919811c9eb708a2c8e4c6eb3701178c37 + languageName: node + linkType: hard + +"@types/uuid@npm:^8.3.4": + version: 8.3.4 + resolution: "@types/uuid@npm:8.3.4" + checksum: 6f11f3ff70f30210edaa8071422d405e9c1d4e53abbe50fdce365150d3c698fe7bbff65c1e71ae080cbfb8fded860dbb5e174da96fdbbdfcaa3fb3daa474d20f + languageName: node + linkType: hard + +"@types/ws@npm:^7.4.4": + version: 7.4.7 + resolution: "@types/ws@npm:7.4.7" + dependencies: + "@types/node": "*" + checksum: b4c9b8ad209620c9b21e78314ce4ff07515c0cadab9af101c1651e7bfb992d7fd933bd8b9c99d110738fd6db523ed15f82f29f50b45510288da72e964dedb1a3 + languageName: node + linkType: hard + +"@types/ws@npm:^8.2.2": + version: 8.18.1 + resolution: "@types/ws@npm:8.18.1" + dependencies: + "@types/node": "*" + checksum: 0331b14cde388e2805af66cad3e3f51857db8e68ed91e5b99750915e96fe7572e58296dc99999331bbcf08f0ff00a227a0bb214e991f53c2a5aca7b0e71173fa + languageName: node + linkType: hard + +"JSONStream@npm:^1.3.5": + version: 1.3.5 + resolution: "JSONStream@npm:1.3.5" + dependencies: + jsonparse: ^1.2.0 + through: ">=2.2.7 <3" + bin: + JSONStream: ./bin.js + checksum: 2605fa124260c61bad38bb65eba30d2f72216a78e94d0ab19b11b4e0327d572b8d530c0c9cc3b0764f727ad26d39e00bf7ebad57781ca6368394d73169c59e46 + languageName: node + linkType: hard + +"abbrev@npm:^3.0.0": + version: 3.0.1 + resolution: "abbrev@npm:3.0.1" + checksum: e70b209f5f408dd3a3bbd0eec4b10a2ffd64704a4a3821d0969d84928cc490a8eb60f85b78a95622c1841113edac10161c62e52f5e7d0027aa26786a8136e02e + languageName: node + linkType: hard + +"acorn@npm:^8.14.0": + version: 8.15.0 + resolution: "acorn@npm:8.15.0" + bin: + acorn: bin/acorn + checksum: 309c6b49aedf1a2e34aaf266de06de04aab6eb097c02375c66fdeb0f64556a6a823540409914fb364d9a11bc30d79d485a2eba29af47992d3490e9886c4391c3 + languageName: node + linkType: hard + +"agent-base@npm:^7.1.0, agent-base@npm:^7.1.2": + version: 7.1.4 + resolution: "agent-base@npm:7.1.4" + checksum: 86a7f542af277cfbd77dd61e7df8422f90bac512953709003a1c530171a9d019d072e2400eab2b59f84b49ab9dd237be44315ca663ac73e82b3922d10ea5eafa + languageName: node + linkType: hard + +"agentkeepalive@npm:^4.2.1": + version: 4.2.1 + resolution: "agentkeepalive@npm:4.2.1" + dependencies: + debug: ^4.1.0 + depd: ^1.1.2 + humanize-ms: ^1.2.1 + checksum: 39cb49ed8cf217fd6da058a92828a0a84e0b74c35550f82ee0a10e1ee403c4b78ade7948be2279b188b7a7303f5d396ea2738b134731e464bf28de00a4f72a18 + languageName: node + linkType: hard + +"agentkeepalive@npm:^4.5.0": + version: 4.6.0 + resolution: "agentkeepalive@npm:4.6.0" + dependencies: + humanize-ms: ^1.2.1 + checksum: b3cdd10efca04876defda3c7671163523fcbce20e8ef7a8f9f30919a242e32b846791c0f1a8a0269718a585805a2cdcd031779ff7b9927a1a8dd8586f8c2e8c5 + languageName: node + linkType: hard + +"ansi-colors@npm:^4.1.3": + version: 4.1.3 + resolution: "ansi-colors@npm:4.1.3" + checksum: a9c2ec842038a1fabc7db9ece7d3177e2fe1c5dc6f0c51ecfbf5f39911427b89c00b5dc6b8bd95f82a26e9b16aaae2e83d45f060e98070ce4d1333038edceb0e + languageName: node + linkType: hard + +"ansi-regex@npm:^5.0.1": + version: 5.0.1 + resolution: "ansi-regex@npm:5.0.1" + checksum: 2aa4bb54caf2d622f1afdad09441695af2a83aa3fe8b8afa581d205e57ed4261c183c4d3877cee25794443fde5876417d859c108078ab788d6af7e4fe52eb66b + languageName: node + linkType: hard + +"ansi-regex@npm:^6.0.1": + version: 6.1.0 + resolution: "ansi-regex@npm:6.1.0" + checksum: 495834a53b0856c02acd40446f7130cb0f8284f4a39afdab20d5dc42b2e198b1196119fe887beed8f9055c4ff2055e3b2f6d4641d0be018cdfb64fedf6fc1aac + languageName: node + linkType: hard + +"ansi-sequence-parser@npm:^1.1.0": + version: 1.1.3 + resolution: "ansi-sequence-parser@npm:1.1.3" + checksum: 98e516176fa9177d501a49a12b96dd26359eaa1c6cee9d6261ebd36540cd4d33a9acd5a8cf43ed3e4508f1cf8b28fcc17643abd49bdf017471e840d98d1c036d + languageName: node + linkType: hard + +"ansi-styles@npm:^4.0.0": + version: 4.3.0 + resolution: "ansi-styles@npm:4.3.0" + dependencies: + color-convert: ^2.0.1 + checksum: 513b44c3b2105dd14cc42a19271e80f386466c4be574bccf60b627432f9198571ebf4ab1e4c3ba17347658f4ee1711c163d574248c0c1cdc2d5917a0ad582ec4 + languageName: node + linkType: hard + +"ansi-styles@npm:^6.1.0": + version: 6.2.1 + resolution: "ansi-styles@npm:6.2.1" + checksum: ef940f2f0ced1a6347398da88a91da7930c33ecac3c77b72c5905f8b8fe402c52e6fde304ff5347f616e27a742da3f1dc76de98f6866c69251ad0b07a66776d9 + languageName: node + linkType: hard + +"ansicolors@npm:^0.3.2, ansicolors@npm:~0.3.2": + version: 0.3.2 + resolution: "ansicolors@npm:0.3.2" + checksum: e84fae7ebc27ac96d9dbb57f35f078cd6dde1b7046b0f03f73dcefc9fbb1f2e82e3685d083466aded8faf038f9fa9ebb408d215282bcd7aaa301d5ac3c486815 + languageName: node + linkType: hard + +"any-promise@npm:^1.0.0": + version: 1.3.0 + resolution: "any-promise@npm:1.3.0" + checksum: 0ee8a9bdbe882c90464d75d1f55cf027f5458650c4bd1f0467e65aec38ccccda07ca5844969ee77ed46d04e7dded3eaceb027e8d32f385688523fe305fa7e1de + languageName: node + linkType: hard + +"assert@npm:^2.0.0": + version: 2.1.0 + resolution: "assert@npm:2.1.0" + dependencies: + call-bind: ^1.0.2 + is-nan: ^1.3.2 + object-is: ^1.1.5 + object.assign: ^4.1.4 + util: ^0.12.5 + checksum: 1ed1cabba9abe55f4109b3f7292b4e4f3cf2953aad8dc148c0b3c3bd676675c31b1abb32ef563b7d5a19d1715bf90d1e5f09fad2a4ee655199468902da80f7c2 + languageName: node + linkType: hard + +"available-typed-arrays@npm:^1.0.7": + version: 1.0.7 + resolution: "available-typed-arrays@npm:1.0.7" + dependencies: + possible-typed-array-names: ^1.0.0 + checksum: 1aa3ffbfe6578276996de660848b6e95669d9a95ad149e3dd0c0cda77db6ee1dbd9d1dd723b65b6d277b882dd0c4b91a654ae9d3cf9e1254b7e93e4908d78fd3 + languageName: node + linkType: hard + +"balanced-match@npm:^1.0.0": + version: 1.0.2 + resolution: "balanced-match@npm:1.0.2" + checksum: 9706c088a283058a8a99e0bf91b0a2f75497f185980d9ffa8b304de1d9e58ebda7c72c07ebf01dadedaac5b2907b2c6f566f660d62bd336c3468e960403b9d65 + languageName: node + linkType: hard + +"base-x@npm:^3.0.2": + version: 3.0.9 + resolution: "base-x@npm:3.0.9" + dependencies: + safe-buffer: ^5.0.1 + checksum: 957101d6fd09e1903e846fd8f69fd7e5e3e50254383e61ab667c725866bec54e5ece5ba49ce385128ae48f9ec93a26567d1d5ebb91f4d56ef4a9cc0d5a5481e8 + languageName: node + linkType: hard + +"base-x@npm:^4.0.0": + version: 4.0.0 + resolution: "base-x@npm:4.0.0" + checksum: b25db9e07eb1998472a20557c7f00c797dc0595f79df95155ab74274e7fa98b9f2659b3ee547ac8773666b7f69540656793aeb97ad2b1ceccdb6fa5faaf69ac0 + languageName: node + linkType: hard + +"base64-js@npm:^1.3.1": + version: 1.5.1 + resolution: "base64-js@npm:1.5.1" + checksum: 669632eb3745404c2f822a18fc3a0122d2f9a7a13f7fb8b5823ee19d1d2ff9ee5b52c53367176ea4ad093c332fd5ab4bd0ebae5a8e27917a4105a4cfc86b1005 + languageName: node + linkType: hard + +"bigint-buffer@npm:^1.1.5": + version: 1.1.5 + resolution: "bigint-buffer@npm:1.1.5" + dependencies: + bindings: ^1.3.0 + node-gyp: latest + checksum: d010c9f57758bcdaccb435d88b483ffcc95fe8bbc6e7fb3a44fb5221f29c894ffaf4a3c5a4a530e0e7d6608203c2cde9b79ee4f2386cd6d4462d1070bc8c9f4e + languageName: node + linkType: hard + +"bignumber.js@npm:^9.0.1": + version: 9.3.1 + resolution: "bignumber.js@npm:9.3.1" + checksum: 6ab100271a23a75bb8b99a4b1a34a1a94967ac0b9a52a198147607bd91064e72c6f356380d7a09cd687bf50d81ad2ed1a0a8edfaa90369c9003ed8bb2440d7f0 + languageName: node + linkType: hard + +"bindings@npm:^1.3.0": + version: 1.5.0 + resolution: "bindings@npm:1.5.0" + dependencies: + file-uri-to-path: 1.0.0 + checksum: 65b6b48095717c2e6105a021a7da4ea435aa8d3d3cd085cb9e85bcb6e5773cf318c4745c3f7c504412855940b585bdf9b918236612a1c7a7942491de176f1ae7 + languageName: node + linkType: hard + +"bn.js@npm:^5.0.0, bn.js@npm:^5.2.0": + version: 5.2.1 + resolution: "bn.js@npm:5.2.1" + checksum: 3dd8c8d38055fedfa95c1d5fc3c99f8dd547b36287b37768db0abab3c239711f88ff58d18d155dd8ad902b0b0cee973747b7ae20ea12a09473272b0201c9edd3 + languageName: node + linkType: hard + +"bn.js@npm:^5.2.1": + version: 5.2.2 + resolution: "bn.js@npm:5.2.2" + checksum: 4384d35fef785c757eb050bc1f13d60dd8e37662ca72392ae6678b35cfa2a2ae8f0494291086294683a7d977609c7878ac3cff08ecca7f74c3ca73f3acbadbe8 + languageName: node + linkType: hard + +"borsh@npm:^0.7.0": + version: 0.7.0 + resolution: "borsh@npm:0.7.0" + dependencies: + bn.js: ^5.2.0 + bs58: ^4.0.0 + text-encoding-utf-8: ^1.0.2 + checksum: e98bfb5f7cfb820819c2870b884dac58dd4b4ce6a86c286c8fbf5c9ca582e73a8c6094df67e81a28c418ff07a309c6b118b2e27fdfea83fd92b8100c741da0b5 + languageName: node + linkType: hard + +"brace-expansion@npm:^2.0.1": + version: 2.0.2 + resolution: "brace-expansion@npm:2.0.2" + dependencies: + balanced-match: ^1.0.0 + checksum: 01dff195e3646bc4b0d27b63d9bab84d2ebc06121ff5013ad6e5356daa5a9d6b60fa26cf73c74797f2dc3fbec112af13578d51f75228c1112b26c790a87b0488 + languageName: node + linkType: hard + +"bs58@npm:^4.0.0, bs58@npm:^4.0.1": + version: 4.0.1 + resolution: "bs58@npm:4.0.1" + dependencies: + base-x: ^3.0.2 + checksum: b3c5365bb9e0c561e1a82f1a2d809a1a692059fae016be233a6127ad2f50a6b986467c3a50669ce4c18929dcccb297c5909314dd347a25a68c21b68eb3e95ac2 + languageName: node + linkType: hard + +"bs58@npm:^5.0.0": + version: 5.0.0 + resolution: "bs58@npm:5.0.0" + dependencies: + base-x: ^4.0.0 + checksum: 2475cb0684e07077521aac718e604a13e0f891d58cff923d437a2f7e9e28703ab39fce9f84c7c703ab369815a675f11e3bd394d38643bfe8969fbe42e6833d45 + languageName: node + linkType: hard + +"buffer@npm:6.0.1": + version: 6.0.1 + resolution: "buffer@npm:6.0.1" + dependencies: + base64-js: ^1.3.1 + ieee754: ^1.2.1 + checksum: 0274c2c6c5c5d9e9e1fd48116c26a3e3f824fe262ff379f630771f590c2e4e7d1fa2604a58684bfc4471a3f9cc40c6317be26b50f15c4cca126249bfc84c4f8b + languageName: node + linkType: hard + +"buffer@npm:6.0.3, buffer@npm:^6.0.3, buffer@npm:~6.0.3": + version: 6.0.3 + resolution: "buffer@npm:6.0.3" + dependencies: + base64-js: ^1.3.1 + ieee754: ^1.2.1 + checksum: 5ad23293d9a731e4318e420025800b42bf0d264004c0286c8cc010af7a270c7a0f6522e84f54b9ad65cbd6db20b8badbfd8d2ebf4f80fa03dab093b89e68c3f9 + languageName: node + linkType: hard + +"bufferutil@npm:^4.0.1": + version: 4.0.7 + resolution: "bufferutil@npm:4.0.7" + dependencies: + node-gyp: latest + node-gyp-build: ^4.3.0 + checksum: f75aa87e3d1b99b87a95f60a855e63f70af07b57fb8443e75a2ddfef2e47788d130fdd46e3a78fd7e0c10176082b26dfbed970c5b8632e1cc299cafa0e93ce45 + languageName: node + linkType: hard + +"bundle-require@npm:^5.1.0": + version: 5.1.0 + resolution: "bundle-require@npm:5.1.0" + dependencies: + load-tsconfig: ^0.2.3 + peerDependencies: + esbuild: ">=0.18" + checksum: 78a972b2d83b212f8bf3919bf806cc0846db4fb2182eb85770d4caec459f3b78053477acffb7396c6c15ceb7e132f22b18c1b430388d0f1b335a3b73b5012a1c + languageName: node + linkType: hard + +"cac@npm:^6.7.14": + version: 6.7.14 + resolution: "cac@npm:6.7.14" + checksum: 45a2496a9443abbe7f52a49b22fbe51b1905eff46e03fd5e6c98e3f85077be3f8949685a1849b1a9cd2bc3e5567dfebcf64f01ce01847baf918f1b37c839791a + languageName: node + linkType: hard + +"cacache@npm:^19.0.1": + version: 19.0.1 + resolution: "cacache@npm:19.0.1" + dependencies: + "@npmcli/fs": ^4.0.0 + fs-minipass: ^3.0.0 + glob: ^10.2.2 + lru-cache: ^10.0.1 + minipass: ^7.0.3 + minipass-collect: ^2.0.1 + minipass-flush: ^1.0.5 + minipass-pipeline: ^1.2.4 + p-map: ^7.0.2 + ssri: ^12.0.0 + tar: ^7.4.3 + unique-filename: ^4.0.0 + checksum: e95684717de6881b4cdaa949fa7574e3171946421cd8291769dd3d2417dbf7abf4aa557d1f968cca83dcbc95bed2a281072b09abfc977c942413146ef7ed4525 + languageName: node + linkType: hard + +"call-bind-apply-helpers@npm:^1.0.0, call-bind-apply-helpers@npm:^1.0.1, call-bind-apply-helpers@npm:^1.0.2": + version: 1.0.2 + resolution: "call-bind-apply-helpers@npm:1.0.2" + dependencies: + es-errors: ^1.3.0 + function-bind: ^1.1.2 + checksum: b2863d74fcf2a6948221f65d95b91b4b2d90cfe8927650b506141e669f7d5de65cea191bf788838bc40d13846b7886c5bc5c84ab96c3adbcf88ad69a72fcdc6b + languageName: node + linkType: hard + +"call-bind@npm:^1.0.0, call-bind@npm:^1.0.2, call-bind@npm:^1.0.7, call-bind@npm:^1.0.8": + version: 1.0.8 + resolution: "call-bind@npm:1.0.8" + dependencies: + call-bind-apply-helpers: ^1.0.0 + es-define-property: ^1.0.0 + get-intrinsic: ^1.2.4 + set-function-length: ^1.2.2 + checksum: aa2899bce917a5392fd73bd32e71799c37c0b7ab454e0ed13af7f6727549091182aade8bbb7b55f304a5bc436d543241c14090fb8a3137e9875e23f444f4f5a9 + languageName: node + linkType: hard + +"call-bound@npm:^1.0.2, call-bound@npm:^1.0.3, call-bound@npm:^1.0.4": + version: 1.0.4 + resolution: "call-bound@npm:1.0.4" + dependencies: + call-bind-apply-helpers: ^1.0.2 + get-intrinsic: ^1.3.0 + checksum: 2f6399488d1c272f56306ca60ff696575e2b7f31daf23bc11574798c84d9f2759dceb0cb1f471a85b77f28962a7ac6411f51d283ea2e45319009a19b6ccab3b2 + languageName: node + linkType: hard + +"camelcase@npm:^6.2.1": + version: 6.3.0 + resolution: "camelcase@npm:6.3.0" + checksum: 8c96818a9076434998511251dcb2761a94817ea17dbdc37f47ac080bd088fc62c7369429a19e2178b993497132c8cbcf5cc1f44ba963e76782ba469c0474938d + languageName: node + linkType: hard + +"chalk@npm:^5.3.0, chalk@npm:^5.4.1": + version: 5.4.1 + resolution: "chalk@npm:5.4.1" + checksum: 0c656f30b782fed4d99198825c0860158901f449a6b12b818b0aabad27ec970389e7e8767d0e00762175b23620c812e70c4fd92c0210e55fc2d993638b74e86e + languageName: node + linkType: hard + +"chokidar@npm:^4.0.3": + version: 4.0.3 + resolution: "chokidar@npm:4.0.3" + dependencies: + readdirp: ^4.0.1 + checksum: a8765e452bbafd04f3f2fad79f04222dd65f43161488bb6014a41099e6ca18d166af613d59a90771908c1c823efa3f46ba36b86ac50b701c20c1b9908c5fe36e + languageName: node + linkType: hard + +"chownr@npm:^3.0.0": + version: 3.0.0 + resolution: "chownr@npm:3.0.0" + checksum: fd73a4bab48b79e66903fe1cafbdc208956f41ea4f856df883d0c7277b7ab29fd33ee65f93b2ec9192fc0169238f2f8307b7735d27c155821d886b84aa97aa8d + languageName: node + linkType: hard + +"color-convert@npm:^2.0.1": + version: 2.0.1 + resolution: "color-convert@npm:2.0.1" + dependencies: + color-name: ~1.1.4 + checksum: 79e6bdb9fd479a205c71d89574fccfb22bd9053bd98c6c4d870d65c132e5e904e6034978e55b43d69fcaa7433af2016ee203ce76eeba9cfa554b373e7f7db336 + languageName: node + linkType: hard + +"color-name@npm:~1.1.4": + version: 1.1.4 + resolution: "color-name@npm:1.1.4" + checksum: b0445859521eb4021cd0fb0cc1a75cecf67fceecae89b63f62b201cca8d345baf8b952c966862a9d9a2632987d4f6581f0ec8d957dfacece86f0a7919316f610 + languageName: node + linkType: hard + +"commander@npm:^12.1.0": + version: 12.1.0 + resolution: "commander@npm:12.1.0" + checksum: 68e9818b00fc1ed9cdab9eb16905551c2b768a317ae69a5e3c43924c2b20ac9bb65b27e1cab36aeda7b6496376d4da908996ba2c0b5d79463e0fb1e77935d514 + languageName: node + linkType: hard + +"commander@npm:^14.0.0": + version: 14.0.0 + resolution: "commander@npm:14.0.0" + checksum: 6e9bdaf2e8e4f512855ffc10579eeae2e84c4a7697a91b1a5f62aab3c9849182207855268dd7c3952ae7a2334312a7138f58e929e4b428aef5bf8af862685c9b + languageName: node + linkType: hard + +"commander@npm:^2.20.3": + version: 2.20.3 + resolution: "commander@npm:2.20.3" + checksum: ab8c07884e42c3a8dbc5dd9592c606176c7eb5c1ca5ff274bcf907039b2c41de3626f684ea75ccf4d361ba004bbaff1f577d5384c155f3871e456bdf27becf9e + languageName: node + linkType: hard + +"commander@npm:^4.0.0": + version: 4.1.1 + resolution: "commander@npm:4.1.1" + checksum: d7b9913ff92cae20cb577a4ac6fcc121bd6223319e54a40f51a14740a681ad5c574fd29a57da478a5f234a6fa6c52cbf0b7c641353e03c648b1ae85ba670b977 + languageName: node + linkType: hard + +"confbox@npm:^0.1.8": + version: 0.1.8 + resolution: "confbox@npm:0.1.8" + checksum: 5c7718ab22cf9e35a31c21ef124156076ae8c9dc65e6463d54961caf5a1d529284485a0fdf83fd23b27329f3b75b0c8c07d2e36c699f5151a2efe903343f976a + languageName: node + linkType: hard + +"consola@npm:^3.4.0": + version: 3.4.2 + resolution: "consola@npm:3.4.2" + checksum: 32d1339e0505842f033ca34cb4572a841281caa367f438b785d3b284ab2a06134f009e605908480402c5f57f56c1e3210090c37e6417923416f76ce730d39361 + languageName: node + linkType: hard + +"cross-spawn@npm:^7.0.6": + version: 7.0.6 + resolution: "cross-spawn@npm:7.0.6" + dependencies: + path-key: ^3.1.0 + shebang-command: ^2.0.0 + which: ^2.0.1 + checksum: 8d306efacaf6f3f60e0224c287664093fa9185680b2d195852ba9a863f85d02dcc737094c6e512175f8ee0161f9b87c73c6826034c2422e39de7d6569cf4503b + languageName: node + linkType: hard + +"debug@npm:4, debug@npm:^4.4.0": + version: 4.4.1 + resolution: "debug@npm:4.4.1" + dependencies: + ms: ^2.1.3 + peerDependenciesMeta: + supports-color: + optional: true + checksum: a43826a01cda685ee4cec00fb2d3322eaa90ccadbef60d9287debc2a886be3e835d9199c80070ede75a409ee57828c4c6cd80e4b154f2843f0dc95a570dc0729 + languageName: node + linkType: hard + +"debug@npm:^4.1.0, debug@npm:^4.3.3, debug@npm:^4.3.4": + version: 4.3.4 + resolution: "debug@npm:4.3.4" + dependencies: + ms: 2.1.2 + peerDependenciesMeta: + supports-color: + optional: true + checksum: 3dbad3f94ea64f34431a9cbf0bafb61853eda57bff2880036153438f50fb5a84f27683ba0d8e5426bf41a8c6ff03879488120cf5b3a761e77953169c0600a708 + languageName: node + linkType: hard + +"define-data-property@npm:^1.0.1, define-data-property@npm:^1.1.4": + version: 1.1.4 + resolution: "define-data-property@npm:1.1.4" + dependencies: + es-define-property: ^1.0.0 + es-errors: ^1.3.0 + gopd: ^1.0.1 + checksum: 8068ee6cab694d409ac25936eb861eea704b7763f7f342adbdfe337fc27c78d7ae0eff2364b2917b58c508d723c7a074326d068eef2e45c4edcd85cf94d0313b + languageName: node + linkType: hard + +"define-properties@npm:^1.1.3, define-properties@npm:^1.2.1": + version: 1.2.1 + resolution: "define-properties@npm:1.2.1" + dependencies: + define-data-property: ^1.0.1 + has-property-descriptors: ^1.0.0 + object-keys: ^1.1.1 + checksum: b4ccd00597dd46cb2d4a379398f5b19fca84a16f3374e2249201992f36b30f6835949a9429669ee6b41b6e837205a163eadd745e472069e70dfc10f03e5fcc12 + languageName: node + linkType: hard + +"delay@npm:^5.0.0": + version: 5.0.0 + resolution: "delay@npm:5.0.0" + checksum: 62f151151ecfde0d9afbb8a6be37a6d103c4cb24f35a20ef3fe56f920b0d0d0bb02bc9c0a3084d0179ef669ca332b91155f2ee4d9854622cd2cdba5fc95285f9 + languageName: node + linkType: hard + +"depd@npm:^1.1.2": + version: 1.1.2 + resolution: "depd@npm:1.1.2" + checksum: 6b406620d269619852885ce15965272b829df6f409724415e0002c8632ab6a8c0a08ec1f0bd2add05dc7bd7507606f7e2cc034fa24224ab829580040b835ecd9 + languageName: node + linkType: hard + +"dot-case@npm:^3.0.4": + version: 3.0.4 + resolution: "dot-case@npm:3.0.4" + dependencies: + no-case: ^3.0.4 + tslib: ^2.0.3 + checksum: a65e3519414856df0228b9f645332f974f2bf5433370f544a681122eab59e66038fc3349b4be1cdc47152779dac71a5864f1ccda2f745e767c46e9c6543b1169 + languageName: node + linkType: hard + +"dunder-proto@npm:^1.0.1": + version: 1.0.1 + resolution: "dunder-proto@npm:1.0.1" + dependencies: + call-bind-apply-helpers: ^1.0.1 + es-errors: ^1.3.0 + gopd: ^1.2.0 + checksum: 149207e36f07bd4941921b0ca929e3a28f1da7bd6b6ff8ff7f4e2f2e460675af4576eeba359c635723dc189b64cdd4787e0255897d5b135ccc5d15cb8685fc90 + languageName: node + linkType: hard + +"eastasianwidth@npm:^0.2.0": + version: 0.2.0 + resolution: "eastasianwidth@npm:0.2.0" + checksum: 7d00d7cd8e49b9afa762a813faac332dee781932d6f2c848dc348939c4253f1d4564341b7af1d041853bc3f32c2ef141b58e0a4d9862c17a7f08f68df1e0f1ed + languageName: node + linkType: hard + +"emoji-regex@npm:^8.0.0": + version: 8.0.0 + resolution: "emoji-regex@npm:8.0.0" + checksum: d4c5c39d5a9868b5fa152f00cada8a936868fd3367f33f71be515ecee4c803132d11b31a6222b2571b1e5f7e13890156a94880345594d0ce7e3c9895f560f192 + languageName: node + linkType: hard + +"emoji-regex@npm:^9.2.2": + version: 9.2.2 + resolution: "emoji-regex@npm:9.2.2" + checksum: 8487182da74aabd810ac6d6f1994111dfc0e331b01271ae01ec1eb0ad7b5ecc2bbbbd2f053c05cb55a1ac30449527d819bbfbf0e3de1023db308cbcb47f86601 + languageName: node + linkType: hard + +"encoding@npm:^0.1.13": + version: 0.1.13 + resolution: "encoding@npm:0.1.13" + dependencies: + iconv-lite: ^0.6.2 + checksum: bb98632f8ffa823996e508ce6a58ffcf5856330fde839ae42c9e1f436cc3b5cc651d4aeae72222916545428e54fd0f6aa8862fd8d25bdbcc4589f1e3f3715e7f + languageName: node + linkType: hard + +"env-paths@npm:^2.2.0": + version: 2.2.1 + resolution: "env-paths@npm:2.2.1" + checksum: 65b5df55a8bab92229ab2b40dad3b387fad24613263d103a97f91c9fe43ceb21965cd3392b1ccb5d77088021e525c4e0481adb309625d0cb94ade1d1fb8dc17e + languageName: node + linkType: hard + +"err-code@npm:^2.0.2": + version: 2.0.3 + resolution: "err-code@npm:2.0.3" + checksum: 8b7b1be20d2de12d2255c0bc2ca638b7af5171142693299416e6a9339bd7d88fc8d7707d913d78e0993176005405a236b066b45666b27b797252c771156ace54 + languageName: node + linkType: hard + +"es-define-property@npm:^1.0.0, es-define-property@npm:^1.0.1": + version: 1.0.1 + resolution: "es-define-property@npm:1.0.1" + checksum: 0512f4e5d564021c9e3a644437b0155af2679d10d80f21adaf868e64d30efdfbd321631956f20f42d655fedb2e3a027da479fad3fa6048f768eb453a80a5f80a + languageName: node + linkType: hard + +"es-errors@npm:^1.3.0": + version: 1.3.0 + resolution: "es-errors@npm:1.3.0" + checksum: ec1414527a0ccacd7f15f4a3bc66e215f04f595ba23ca75cdae0927af099b5ec865f9f4d33e9d7e86f512f252876ac77d4281a7871531a50678132429b1271b5 + languageName: node + linkType: hard + +"es-object-atoms@npm:^1.0.0, es-object-atoms@npm:^1.1.1": + version: 1.1.1 + resolution: "es-object-atoms@npm:1.1.1" + dependencies: + es-errors: ^1.3.0 + checksum: 214d3767287b12f36d3d7267ef342bbbe1e89f899cfd67040309fc65032372a8e60201410a99a1645f2f90c1912c8c49c8668066f6bdd954bcd614dda2e3da97 + languageName: node + linkType: hard + +"es6-promise@npm:^4.0.3": + version: 4.2.8 + resolution: "es6-promise@npm:4.2.8" + checksum: 95614a88873611cb9165a85d36afa7268af5c03a378b35ca7bda9508e1d4f1f6f19a788d4bc755b3fd37c8ebba40782018e02034564ff24c9d6fa37e959ad57d + languageName: node + linkType: hard + +"es6-promisify@npm:^5.0.0": + version: 5.0.0 + resolution: "es6-promisify@npm:5.0.0" + dependencies: + es6-promise: ^4.0.3 + checksum: fbed9d791598831413be84a5374eca8c24800ec71a16c1c528c43a98e2dadfb99331483d83ae6094ddb9b87e6f799a15d1553cebf756047e0865c753bc346b92 + languageName: node + linkType: hard + +"esbuild@npm:^0.25.0": + version: 0.25.8 + resolution: "esbuild@npm:0.25.8" + dependencies: + "@esbuild/aix-ppc64": 0.25.8 + "@esbuild/android-arm": 0.25.8 + "@esbuild/android-arm64": 0.25.8 + "@esbuild/android-x64": 0.25.8 + "@esbuild/darwin-arm64": 0.25.8 + "@esbuild/darwin-x64": 0.25.8 + "@esbuild/freebsd-arm64": 0.25.8 + "@esbuild/freebsd-x64": 0.25.8 + "@esbuild/linux-arm": 0.25.8 + "@esbuild/linux-arm64": 0.25.8 + "@esbuild/linux-ia32": 0.25.8 + "@esbuild/linux-loong64": 0.25.8 + "@esbuild/linux-mips64el": 0.25.8 + "@esbuild/linux-ppc64": 0.25.8 + "@esbuild/linux-riscv64": 0.25.8 + "@esbuild/linux-s390x": 0.25.8 + "@esbuild/linux-x64": 0.25.8 + "@esbuild/netbsd-arm64": 0.25.8 + "@esbuild/netbsd-x64": 0.25.8 + "@esbuild/openbsd-arm64": 0.25.8 + "@esbuild/openbsd-x64": 0.25.8 + "@esbuild/openharmony-arm64": 0.25.8 + "@esbuild/sunos-x64": 0.25.8 + "@esbuild/win32-arm64": 0.25.8 + "@esbuild/win32-ia32": 0.25.8 + "@esbuild/win32-x64": 0.25.8 + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-arm64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-arm64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/openharmony-arm64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 018e7b151c86df559f30e9b4da95cd5f6c76715818ee1c584ea3a4d19400be75f705f6d57486af2884ad7c1654b791e28419d34c0755186b194d3411745d074c + languageName: node + linkType: hard + +"eventemitter3@npm:^4.0.7": + version: 4.0.7 + resolution: "eventemitter3@npm:4.0.7" + checksum: 1875311c42fcfe9c707b2712c32664a245629b42bb0a5a84439762dd0fd637fc54d078155ea83c2af9e0323c9ac13687e03cfba79b03af9f40c89b4960099374 + languageName: node + linkType: hard + +"eventemitter3@npm:^5.0.1": + version: 5.0.1 + resolution: "eventemitter3@npm:5.0.1" + checksum: 543d6c858ab699303c3c32e0f0f47fc64d360bf73c3daf0ac0b5079710e340d6fe9f15487f94e66c629f5f82cd1a8678d692f3dbb6f6fcd1190e1b97fcad36f8 + languageName: node + linkType: hard + +"exponential-backoff@npm:^3.1.1": + version: 3.1.2 + resolution: "exponential-backoff@npm:3.1.2" + checksum: 7e191e3dd6edd8c56c88f2c8037c98fbb8034fe48778be53ed8cb30ccef371a061a4e999a469aab939b92f8f12698f3b426d52f4f76b7a20da5f9f98c3cbc862 + languageName: node + linkType: hard + +"eyes@npm:^0.1.8": + version: 0.1.8 + resolution: "eyes@npm:0.1.8" + checksum: c31703a92bf36ba75ee8d379ee7985c24ee6149f3a6175f44cec7a05b178c38bce9836d3ca48c9acb0329a960ac2c4b2ead4e60cdd4fe6e8c92cad7cd6913687 + languageName: node + linkType: hard + +"fast-stable-stringify@npm:^1.0.0": + version: 1.0.0 + resolution: "fast-stable-stringify@npm:1.0.0" + checksum: ef1203d246a7e8ac15e2bfbda0a89fa375947bccf9f7910be0ea759856dbe8ea5024a0d8cc2cceabe18a9cb67e95927b78bb6173a3ae37ec55a518cf36e5244b + languageName: node + linkType: hard + +"fdir@npm:^6.4.4": + version: 6.4.6 + resolution: "fdir@npm:6.4.6" + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + checksum: fe9f3014901d023cf631831dcb9eae5447f4d7f69218001dd01ecf007eccc40f6c129a04411b5cc273a5f93c14e02e971e17270afc9022041c80be924091eb6f + languageName: node + linkType: hard + +"file-uri-to-path@npm:1.0.0": + version: 1.0.0 + resolution: "file-uri-to-path@npm:1.0.0" + checksum: b648580bdd893a008c92c7ecc96c3ee57a5e7b6c4c18a9a09b44fb5d36d79146f8e442578bc0e173dc027adf3987e254ba1dfd6e3ec998b7c282873010502144 + languageName: node + linkType: hard + +"fix-dts-default-cjs-exports@npm:^1.0.0": + version: 1.0.1 + resolution: "fix-dts-default-cjs-exports@npm:1.0.1" + dependencies: + magic-string: ^0.30.17 + mlly: ^1.7.4 + rollup: ^4.34.8 + checksum: 3324418bb63c93b6b22a808e242d220caba804860c24218b2912abc4525525334fcdcb62d22be6472a8d84ee2ad4165bc79554140c3369eb11d23220cdd986ce + languageName: node + linkType: hard + +"for-each@npm:^0.3.5": + version: 0.3.5 + resolution: "for-each@npm:0.3.5" + dependencies: + is-callable: ^1.2.7 + checksum: 3c986d7e11f4381237cc98baa0a2f87eabe74719eee65ed7bed275163082b940ede19268c61d04c6260e0215983b12f8d885e3c8f9aa8c2113bf07c37051745c + languageName: node + linkType: hard + +"foreground-child@npm:^3.1.0": + version: 3.3.1 + resolution: "foreground-child@npm:3.3.1" + dependencies: + cross-spawn: ^7.0.6 + signal-exit: ^4.0.1 + checksum: b2c1a6fc0bf0233d645d9fefdfa999abf37db1b33e5dab172b3cbfb0662b88bfbd2c9e7ab853533d199050ec6b65c03fcf078fc212d26e4990220e98c6930eef + languageName: node + linkType: hard + +"fs-minipass@npm:^3.0.0": + version: 3.0.3 + resolution: "fs-minipass@npm:3.0.3" + dependencies: + minipass: ^7.0.3 + checksum: 8722a41109130851d979222d3ec88aabaceeaaf8f57b2a8f744ef8bd2d1ce95453b04a61daa0078822bc5cd21e008814f06fe6586f56fef511e71b8d2394d802 + languageName: node + linkType: hard + +"fsevents@npm:~2.3.2": + version: 2.3.3 + resolution: "fsevents@npm:2.3.3" + dependencies: + node-gyp: latest + checksum: 11e6ea6fea15e42461fc55b4b0e4a0a3c654faa567f1877dbd353f39156f69def97a69936d1746619d656c4b93de2238bf731f6085a03a50cabf287c9d024317 + conditions: os=darwin + languageName: node + linkType: hard + +"fsevents@patch:fsevents@~2.3.2#~builtin": + version: 2.3.3 + resolution: "fsevents@patch:fsevents@npm%3A2.3.3#~builtin::version=2.3.3&hash=df0bf1" + dependencies: + node-gyp: latest + conditions: os=darwin + languageName: node + linkType: hard + +"function-bind@npm:^1.1.2": + version: 1.1.2 + resolution: "function-bind@npm:1.1.2" + checksum: 2b0ff4ce708d99715ad14a6d1f894e2a83242e4a52ccfcefaee5e40050562e5f6dafc1adbb4ce2d4ab47279a45dc736ab91ea5042d843c3c092820dfe032efb1 + languageName: node + linkType: hard + +"get-intrinsic@npm:^1.2.4, get-intrinsic@npm:^1.3.0": + version: 1.3.0 + resolution: "get-intrinsic@npm:1.3.0" + dependencies: + call-bind-apply-helpers: ^1.0.2 + es-define-property: ^1.0.1 + es-errors: ^1.3.0 + es-object-atoms: ^1.1.1 + function-bind: ^1.1.2 + get-proto: ^1.0.1 + gopd: ^1.2.0 + has-symbols: ^1.1.0 + hasown: ^2.0.2 + math-intrinsics: ^1.1.0 + checksum: 301008e4482bb9a9cb49e132b88fee093bff373b4e6def8ba219b1e96b60158a6084f273ef5cafe832e42cd93462f4accb46a618d35fe59a2b507f2388c5b79d + languageName: node + linkType: hard + +"get-proto@npm:^1.0.0, get-proto@npm:^1.0.1": + version: 1.0.1 + resolution: "get-proto@npm:1.0.1" + dependencies: + dunder-proto: ^1.0.1 + es-object-atoms: ^1.0.0 + checksum: 4fc96afdb58ced9a67558698b91433e6b037aaa6f1493af77498d7c85b141382cf223c0e5946f334fb328ee85dfe6edd06d218eaf09556f4bc4ec6005d7f5f7b + languageName: node + linkType: hard + +"glob@npm:^10.2.2, glob@npm:^10.3.10": + version: 10.4.5 + resolution: "glob@npm:10.4.5" + dependencies: + foreground-child: ^3.1.0 + jackspeak: ^3.1.2 + minimatch: ^9.0.4 + minipass: ^7.1.2 + package-json-from-dist: ^1.0.0 + path-scurry: ^1.11.1 + bin: + glob: dist/esm/bin.mjs + checksum: 0bc725de5e4862f9f387fd0f2b274baf16850dcd2714502ccf471ee401803997983e2c05590cb65f9675a3c6f2a58e7a53f9e365704108c6ad3cbf1d60934c4a + languageName: node + linkType: hard + +"gopd@npm:^1.0.1, gopd@npm:^1.2.0": + version: 1.2.0 + resolution: "gopd@npm:1.2.0" + checksum: cc6d8e655e360955bdccaca51a12a474268f95bb793fc3e1f2bdadb075f28bfd1fd988dab872daf77a61d78cbaf13744bc8727a17cfb1d150d76047d805375f3 + languageName: node + linkType: hard + +"graceful-fs@npm:^4.2.6": + version: 4.2.11 + resolution: "graceful-fs@npm:4.2.11" + checksum: ac85f94da92d8eb6b7f5a8b20ce65e43d66761c55ce85ac96df6865308390da45a8d3f0296dd3a663de65d30ba497bd46c696cc1e248c72b13d6d567138a4fc7 + languageName: node + linkType: hard + +"has-property-descriptors@npm:^1.0.0, has-property-descriptors@npm:^1.0.2": + version: 1.0.2 + resolution: "has-property-descriptors@npm:1.0.2" + dependencies: + es-define-property: ^1.0.0 + checksum: fcbb246ea2838058be39887935231c6d5788babed499d0e9d0cc5737494c48aba4fe17ba1449e0d0fbbb1e36175442faa37f9c427ae357d6ccb1d895fbcd3de3 + languageName: node + linkType: hard + +"has-symbols@npm:^1.0.3, has-symbols@npm:^1.1.0": + version: 1.1.0 + resolution: "has-symbols@npm:1.1.0" + checksum: b2316c7302a0e8ba3aaba215f834e96c22c86f192e7310bdf689dd0e6999510c89b00fbc5742571507cebf25764d68c988b3a0da217369a73596191ac0ce694b + languageName: node + linkType: hard + +"has-tostringtag@npm:^1.0.2": + version: 1.0.2 + resolution: "has-tostringtag@npm:1.0.2" + dependencies: + has-symbols: ^1.0.3 + checksum: 999d60bb753ad714356b2c6c87b7fb74f32463b8426e159397da4bde5bca7e598ab1073f4d8d4deafac297f2eb311484cd177af242776bf05f0d11565680468d + languageName: node + linkType: hard + +"hasown@npm:^2.0.2": + version: 2.0.2 + resolution: "hasown@npm:2.0.2" + dependencies: + function-bind: ^1.1.2 + checksum: e8516f776a15149ca6c6ed2ae3110c417a00b62260e222590e54aa367cbcd6ed99122020b37b7fbdf05748df57b265e70095d7bf35a47660587619b15ffb93db + languageName: node + linkType: hard + +"http-cache-semantics@npm:^4.1.1": + version: 4.2.0 + resolution: "http-cache-semantics@npm:4.2.0" + checksum: 7a7246ddfce629f96832791176fd643589d954e6f3b49548dadb4290451961237fab8fcea41cd2008fe819d95b41c1e8b97f47d088afc0a1c81705287b4ddbcc + languageName: node + linkType: hard + +"http-proxy-agent@npm:^7.0.0": + version: 7.0.2 + resolution: "http-proxy-agent@npm:7.0.2" + dependencies: + agent-base: ^7.1.0 + debug: ^4.3.4 + checksum: 670858c8f8f3146db5889e1fa117630910101db601fff7d5a8aa637da0abedf68c899f03d3451cac2f83bcc4c3d2dabf339b3aa00ff8080571cceb02c3ce02f3 + languageName: node + linkType: hard + +"https-proxy-agent@npm:^7.0.1": + version: 7.0.6 + resolution: "https-proxy-agent@npm:7.0.6" + dependencies: + agent-base: ^7.1.2 + debug: 4 + checksum: b882377a120aa0544846172e5db021fa8afbf83fea2a897d397bd2ddd8095ab268c24bc462f40a15f2a8c600bf4aa05ce52927f70038d4014e68aefecfa94e8d + languageName: node + linkType: hard + +"humanize-ms@npm:^1.2.1": + version: 1.2.1 + resolution: "humanize-ms@npm:1.2.1" + dependencies: + ms: ^2.0.0 + checksum: 9c7a74a2827f9294c009266c82031030eae811ca87b0da3dceb8d6071b9bde22c9f3daef0469c3c533cc67a97d8a167cd9fc0389350e5f415f61a79b171ded16 + languageName: node + linkType: hard + +"iconv-lite@npm:^0.6.2": + version: 0.6.3 + resolution: "iconv-lite@npm:0.6.3" + dependencies: + safer-buffer: ">= 2.1.2 < 3.0.0" + checksum: 3f60d47a5c8fc3313317edfd29a00a692cc87a19cac0159e2ce711d0ebc9019064108323b5e493625e25594f11c6236647d8e256fbe7a58f4a3b33b89e6d30bf + languageName: node + linkType: hard + +"ieee754@npm:^1.2.1": + version: 1.2.1 + resolution: "ieee754@npm:1.2.1" + checksum: 5144c0c9815e54ada181d80a0b810221a253562422e7c6c3a60b1901154184f49326ec239d618c416c1c5945a2e197107aee8d986a3dd836b53dffefd99b5e7e + languageName: node + linkType: hard + +"imurmurhash@npm:^0.1.4": + version: 0.1.4 + resolution: "imurmurhash@npm:0.1.4" + checksum: 7cae75c8cd9a50f57dadd77482359f659eaebac0319dd9368bcd1714f55e65badd6929ca58569da2b6494ef13fdd5598cd700b1eba23f8b79c5f19d195a3ecf7 + languageName: node + linkType: hard + +"inherits@npm:^2.0.3": + version: 2.0.4 + resolution: "inherits@npm:2.0.4" + checksum: 4a48a733847879d6cf6691860a6b1e3f0f4754176e4d71494c41f3475553768b10f84b5ce1d40fbd0e34e6bfbb864ee35858ad4dd2cf31e02fc4a154b724d7f1 + languageName: node + linkType: hard + +"invariant@npm:2.2.4": + version: 2.2.4 + resolution: "invariant@npm:2.2.4" + dependencies: + loose-envify: ^1.0.0 + checksum: cc3182d793aad82a8d1f0af697b462939cb46066ec48bbf1707c150ad5fad6406137e91a262022c269702e01621f35ef60269f6c0d7fd178487959809acdfb14 + languageName: node + linkType: hard + +"ip-address@npm:^9.0.5": + version: 9.0.5 + resolution: "ip-address@npm:9.0.5" + dependencies: + jsbn: 1.1.0 + sprintf-js: ^1.1.3 + checksum: aa15f12cfd0ef5e38349744e3654bae649a34c3b10c77a674a167e99925d1549486c5b14730eebce9fea26f6db9d5e42097b00aa4f9f612e68c79121c71652dc + languageName: node + linkType: hard + +"is-arguments@npm:^1.0.4": + version: 1.2.0 + resolution: "is-arguments@npm:1.2.0" + dependencies: + call-bound: ^1.0.2 + has-tostringtag: ^1.0.2 + checksum: aae9307fedfe2e5be14aebd0f48a9eeedf6b8c8f5a0b66257b965146d1e94abdc3f08e3dce3b1d908e1fa23c70039a88810ee1d753905758b9b6eebbab0bafeb + languageName: node + linkType: hard + +"is-callable@npm:^1.2.7": + version: 1.2.7 + resolution: "is-callable@npm:1.2.7" + checksum: 61fd57d03b0d984e2ed3720fb1c7a897827ea174bd44402878e059542ea8c4aeedee0ea0985998aa5cc2736b2fa6e271c08587addb5b3959ac52cf665173d1ac + languageName: node + linkType: hard + +"is-fullwidth-code-point@npm:^3.0.0": + version: 3.0.0 + resolution: "is-fullwidth-code-point@npm:3.0.0" + checksum: 44a30c29457c7fb8f00297bce733f0a64cd22eca270f83e58c105e0d015e45c019491a4ab2faef91ab51d4738c670daff901c799f6a700e27f7314029e99e348 + languageName: node + linkType: hard + +"is-generator-function@npm:^1.0.7": + version: 1.1.0 + resolution: "is-generator-function@npm:1.1.0" + dependencies: + call-bound: ^1.0.3 + get-proto: ^1.0.0 + has-tostringtag: ^1.0.2 + safe-regex-test: ^1.1.0 + checksum: f7f7276131bdf7e28169b86ac55a5b080012a597f9d85a0cbef6fe202a7133fa450a3b453e394870e3cb3685c5a764c64a9f12f614684b46969b1e6f297bed6b + languageName: node + linkType: hard + +"is-nan@npm:^1.3.2": + version: 1.3.2 + resolution: "is-nan@npm:1.3.2" + dependencies: + call-bind: ^1.0.0 + define-properties: ^1.1.3 + checksum: 5dfadcef6ad12d3029d43643d9800adbba21cf3ce2ec849f734b0e14ee8da4070d82b15fdb35138716d02587c6578225b9a22779cab34888a139cc43e4e3610a + languageName: node + linkType: hard + +"is-regex@npm:^1.2.1": + version: 1.2.1 + resolution: "is-regex@npm:1.2.1" + dependencies: + call-bound: ^1.0.2 + gopd: ^1.2.0 + has-tostringtag: ^1.0.2 + hasown: ^2.0.2 + checksum: 99ee0b6d30ef1bb61fa4b22fae7056c6c9b3c693803c0c284ff7a8570f83075a7d38cda53b06b7996d441215c27895ea5d1af62124562e13d91b3dbec41a5e13 + languageName: node + linkType: hard + +"is-typed-array@npm:^1.1.3": + version: 1.1.15 + resolution: "is-typed-array@npm:1.1.15" + dependencies: + which-typed-array: ^1.1.16 + checksum: ea7cfc46c282f805d19a9ab2084fd4542fed99219ee9dbfbc26284728bd713a51eac66daa74eca00ae0a43b61322920ba334793607dc39907465913e921e0892 + languageName: node + linkType: hard + +"isexe@npm:^2.0.0": + version: 2.0.0 + resolution: "isexe@npm:2.0.0" + checksum: 26bf6c5480dda5161c820c5b5c751ae1e766c587b1f951ea3fcfc973bafb7831ae5b54a31a69bd670220e42e99ec154475025a468eae58ea262f813fdc8d1c62 + languageName: node + linkType: hard + +"isexe@npm:^3.1.1": + version: 3.1.1 + resolution: "isexe@npm:3.1.1" + checksum: 7fe1931ee4e88eb5aa524cd3ceb8c882537bc3a81b02e438b240e47012eef49c86904d0f0e593ea7c3a9996d18d0f1f3be8d3eaa92333977b0c3a9d353d5563e + languageName: node + linkType: hard + +"isomorphic-ws@npm:^4.0.1": + version: 4.0.1 + resolution: "isomorphic-ws@npm:4.0.1" + peerDependencies: + ws: "*" + checksum: d7190eadefdc28bdb93d67b5f0c603385aaf87724fa2974abb382ac1ec9756ed2cfb27065cbe76122879c2d452e2982bc4314317f3d6c737ddda6c047328771a + languageName: node + linkType: hard + +"jackspeak@npm:^3.1.2": + version: 3.4.3 + resolution: "jackspeak@npm:3.4.3" + dependencies: + "@isaacs/cliui": ^8.0.2 + "@pkgjs/parseargs": ^0.11.0 + dependenciesMeta: + "@pkgjs/parseargs": + optional: true + checksum: be31027fc72e7cc726206b9f560395604b82e0fddb46c4cbf9f97d049bcef607491a5afc0699612eaa4213ca5be8fd3e1e7cd187b3040988b65c9489838a7c00 + languageName: node + linkType: hard + +"jayson@npm:^3.4.4": + version: 3.7.0 + resolution: "jayson@npm:3.7.0" + dependencies: + "@types/connect": ^3.4.33 + "@types/node": ^12.12.54 + "@types/ws": ^7.4.4 + JSONStream: ^1.3.5 + commander: ^2.20.3 + delay: ^5.0.0 + es6-promisify: ^5.0.0 + eyes: ^0.1.8 + isomorphic-ws: ^4.0.1 + json-stringify-safe: ^5.0.1 + lodash: ^4.17.20 + uuid: ^8.3.2 + ws: ^7.4.5 + bin: + jayson: bin/jayson.js + checksum: 4218a4829168a4927e657bde953ff9699f02af561ec72edcc7464446772b50a0c5c7e9f11d4ee5976e4794d0f1040c0f351a0fee51c542bf8492743d30b7a971 + languageName: node + linkType: hard + +"jayson@npm:^4.1.1": + version: 4.2.0 + resolution: "jayson@npm:4.2.0" + dependencies: + "@types/connect": ^3.4.33 + "@types/node": ^12.12.54 + "@types/ws": ^7.4.4 + commander: ^2.20.3 + delay: ^5.0.0 + es6-promisify: ^5.0.0 + eyes: ^0.1.8 + isomorphic-ws: ^4.0.1 + json-stringify-safe: ^5.0.1 + stream-json: ^1.9.1 + uuid: ^8.3.2 + ws: ^7.5.10 + bin: + jayson: bin/jayson.js + checksum: 674a86dd23559477f53c6ea2302209c28b48d54fbca564e22a790ec533b0519de86d95796deb828d6a52061a8ccc2670c47a28f44b7b6dfaea02f44fd1cf9ab0 + languageName: node + linkType: hard + +"joycon@npm:^3.1.1": + version: 3.1.1 + resolution: "joycon@npm:3.1.1" + checksum: 8003c9c3fc79c5c7602b1c7e9f7a2df2e9916f046b0dbad862aa589be78c15734d11beb9fe846f5e06138df22cb2ad29961b6a986ba81c4920ce2b15a7f11067 + languageName: node + linkType: hard + +"js-sha256@npm:^0.9.0": + version: 0.9.0 + resolution: "js-sha256@npm:0.9.0" + checksum: ffad54b3373f81581e245866abfda50a62c483803a28176dd5c28fd2d313e0bdf830e77dac7ff8afd193c53031618920f3d98daf21cbbe80082753ab639c0365 + languageName: node + linkType: hard + +"js-tokens@npm:^3.0.0 || ^4.0.0": + version: 4.0.0 + resolution: "js-tokens@npm:4.0.0" + checksum: 8a95213a5a77deb6cbe94d86340e8d9ace2b93bc367790b260101d2f36a2eaf4e4e22d9fa9cf459b38af3a32fb4190e638024cf82ec95ef708680e405ea7cc78 + languageName: node + linkType: hard + +"jsbn@npm:1.1.0": + version: 1.1.0 + resolution: "jsbn@npm:1.1.0" + checksum: 944f924f2bd67ad533b3850eee47603eed0f6ae425fd1ee8c760f477e8c34a05f144c1bd4f5a5dd1963141dc79a2c55f89ccc5ab77d039e7077f3ad196b64965 + languageName: node + linkType: hard + +"json-stringify-safe@npm:^5.0.1": + version: 5.0.1 + resolution: "json-stringify-safe@npm:5.0.1" + checksum: 48ec0adad5280b8a96bb93f4563aa1667fd7a36334f79149abd42446d0989f2ddc58274b479f4819f1f00617957e6344c886c55d05a4e15ebb4ab931e4a6a8ee + languageName: node + linkType: hard + +"jsonc-parser@npm:^3.2.0": + version: 3.3.1 + resolution: "jsonc-parser@npm:3.3.1" + checksum: 81ef19d98d9c6bd6e4a37a95e2753c51c21705cbeffd895e177f4b542cca9cda5fda12fb942a71a2e824a9132cf119dc2e642e9286386055e1365b5478f49a47 + languageName: node + linkType: hard + +"jsonparse@npm:^1.2.0": + version: 1.3.1 + resolution: "jsonparse@npm:1.3.1" + checksum: 6514a7be4674ebf407afca0eda3ba284b69b07f9958a8d3113ef1005f7ec610860c312be067e450c569aab8b89635e332cee3696789c750692bb60daba627f4d + languageName: node + linkType: hard + +"lilconfig@npm:^3.1.1": + version: 3.1.3 + resolution: "lilconfig@npm:3.1.3" + checksum: 644eb10830350f9cdc88610f71a921f510574ed02424b57b0b3abb66ea725d7a082559552524a842f4e0272c196b88dfe1ff7d35ffcc6f45736777185cd67c9a + languageName: node + linkType: hard + +"lines-and-columns@npm:^1.1.6": + version: 1.2.4 + resolution: "lines-and-columns@npm:1.2.4" + checksum: 0c37f9f7fa212b38912b7145e1cd16a5f3cd34d782441c3e6ca653485d326f58b3caccda66efce1c5812bde4961bbde3374fae4b0d11bf1226152337f3894aa5 + languageName: node + linkType: hard + +"load-tsconfig@npm:^0.2.3": + version: 0.2.5 + resolution: "load-tsconfig@npm:0.2.5" + checksum: 631740833c4a7157bb7b6eeae6e1afb6a6fac7416b7ba91bd0944d5c5198270af2d68bf8347af3cc2ba821adc4d83ef98f66278bd263bc284c863a09ec441503 + languageName: node + linkType: hard + +"lodash.sortby@npm:^4.7.0": + version: 4.7.0 + resolution: "lodash.sortby@npm:4.7.0" + checksum: db170c9396d29d11fe9a9f25668c4993e0c1331bcb941ddbd48fb76f492e732add7f2a47cfdf8e9d740fa59ac41bbfaf931d268bc72aab3ab49e9f89354d718c + languageName: node + linkType: hard + +"lodash@npm:^4.17.20": + version: 4.17.21 + resolution: "lodash@npm:4.17.21" + checksum: eb835a2e51d381e561e508ce932ea50a8e5a68f4ebdd771ea240d3048244a8d13658acbd502cd4829768c56f2e16bdd4340b9ea141297d472517b83868e677f7 + languageName: node + linkType: hard + +"loose-envify@npm:^1.0.0": + version: 1.4.0 + resolution: "loose-envify@npm:1.4.0" + dependencies: + js-tokens: ^3.0.0 || ^4.0.0 + bin: + loose-envify: cli.js + checksum: 6517e24e0cad87ec9888f500c5b5947032cdfe6ef65e1c1936a0c48a524b81e65542c9c3edc91c97d5bddc806ee2a985dbc79be89215d613b1de5db6d1cfe6f4 + languageName: node + linkType: hard + +"lower-case@npm:^2.0.2": + version: 2.0.2 + resolution: "lower-case@npm:2.0.2" + dependencies: + tslib: ^2.0.3 + checksum: 83a0a5f159ad7614bee8bf976b96275f3954335a84fad2696927f609ddae902802c4f3312d86668722e668bef41400254807e1d3a7f2e8c3eede79691aa1f010 + languageName: node + linkType: hard + +"lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0": + version: 10.4.3 + resolution: "lru-cache@npm:10.4.3" + checksum: 6476138d2125387a6d20f100608c2583d415a4f64a0fecf30c9e2dda976614f09cad4baa0842447bd37dd459a7bd27f57d9d8f8ce558805abd487c583f3d774a + languageName: node + linkType: hard + +"lru-cache@npm:^6.0.0": + version: 6.0.0 + resolution: "lru-cache@npm:6.0.0" + dependencies: + yallist: ^4.0.0 + checksum: f97f499f898f23e4585742138a22f22526254fdba6d75d41a1c2526b3b6cc5747ef59c5612ba7375f42aca4f8461950e925ba08c991ead0651b4918b7c978297 + languageName: node + linkType: hard + +"lunr@npm:^2.3.9": + version: 2.3.9 + resolution: "lunr@npm:2.3.9" + checksum: 176719e24fcce7d3cf1baccce9dd5633cd8bdc1f41ebe6a180112e5ee99d80373fe2454f5d4624d437e5a8319698ca6837b9950566e15d2cae5f2a543a3db4b8 + languageName: node + linkType: hard + +"magic-string@npm:^0.30.17": + version: 0.30.17 + resolution: "magic-string@npm:0.30.17" + dependencies: + "@jridgewell/sourcemap-codec": ^1.5.0 + checksum: f4b4ed17c5ada64f77fc98491847302ebad64894a905c417c943840c0384662118c9b37f9f68bb86add159fa4749ff6f118c4627d69a470121b46731f8debc6d + languageName: node + linkType: hard + +"make-fetch-happen@npm:^14.0.3": + version: 14.0.3 + resolution: "make-fetch-happen@npm:14.0.3" + dependencies: + "@npmcli/agent": ^3.0.0 + cacache: ^19.0.1 + http-cache-semantics: ^4.1.1 + minipass: ^7.0.2 + minipass-fetch: ^4.0.0 + minipass-flush: ^1.0.5 + minipass-pipeline: ^1.2.4 + negotiator: ^1.0.0 + proc-log: ^5.0.0 + promise-retry: ^2.0.1 + ssri: ^12.0.0 + checksum: 6fb2fee6da3d98f1953b03d315826b5c5a4ea1f908481afc113782d8027e19f080c85ae998454de4e5f27a681d3ec58d57278f0868d4e0b736f51d396b661691 + languageName: node + linkType: hard + +"marked@npm:^4.3.0": + version: 4.3.0 + resolution: "marked@npm:4.3.0" + bin: + marked: bin/marked.js + checksum: 0db6817893952c3ec710eb9ceafb8468bf5ae38cb0f92b7b083baa13d70b19774674be04db5b817681fa7c5c6a088f61300815e4dd75a59696f4716ad69f6260 + languageName: node + linkType: hard + +"math-intrinsics@npm:^1.1.0": + version: 1.1.0 + resolution: "math-intrinsics@npm:1.1.0" + checksum: 0e513b29d120f478c85a70f49da0b8b19bc638975eca466f2eeae0071f3ad00454c621bf66e16dd435896c208e719fc91ad79bbfba4e400fe0b372e7c1c9c9a2 + languageName: node + linkType: hard + +"minimatch@npm:^9.0.3, minimatch@npm:^9.0.4": + version: 9.0.5 + resolution: "minimatch@npm:9.0.5" + dependencies: + brace-expansion: ^2.0.1 + checksum: 2c035575eda1e50623c731ec6c14f65a85296268f749b9337005210bb2b34e2705f8ef1a358b188f69892286ab99dc42c8fb98a57bde55c8d81b3023c19cea28 + languageName: node + linkType: hard + +"minipass-collect@npm:^2.0.1": + version: 2.0.1 + resolution: "minipass-collect@npm:2.0.1" + dependencies: + minipass: ^7.0.3 + checksum: b251bceea62090f67a6cced7a446a36f4cd61ee2d5cea9aee7fff79ba8030e416327a1c5aa2908dc22629d06214b46d88fdab8c51ac76bacbf5703851b5ad342 + languageName: node + linkType: hard + +"minipass-fetch@npm:^4.0.0": + version: 4.0.1 + resolution: "minipass-fetch@npm:4.0.1" + dependencies: + encoding: ^0.1.13 + minipass: ^7.0.3 + minipass-sized: ^1.0.3 + minizlib: ^3.0.1 + dependenciesMeta: + encoding: + optional: true + checksum: 3dfca705ce887ca9ff14d73e8d8593996dea1a1ecd8101fdbb9c10549d1f9670bc8fb66ad0192769ead4c2dc01b4f9ca1cf567ded365adff17827a303b948140 + languageName: node + linkType: hard + +"minipass-flush@npm:^1.0.5": + version: 1.0.5 + resolution: "minipass-flush@npm:1.0.5" + dependencies: + minipass: ^3.0.0 + checksum: 56269a0b22bad756a08a94b1ffc36b7c9c5de0735a4dd1ab2b06c066d795cfd1f0ac44a0fcae13eece5589b908ecddc867f04c745c7009be0b566421ea0944cf + languageName: node + linkType: hard + +"minipass-pipeline@npm:^1.2.4": + version: 1.2.4 + resolution: "minipass-pipeline@npm:1.2.4" + dependencies: + minipass: ^3.0.0 + checksum: b14240dac0d29823c3d5911c286069e36d0b81173d7bdf07a7e4a91ecdef92cdff4baaf31ea3746f1c61e0957f652e641223970870e2353593f382112257971b + languageName: node + linkType: hard + +"minipass-sized@npm:^1.0.3": + version: 1.0.3 + resolution: "minipass-sized@npm:1.0.3" + dependencies: + minipass: ^3.0.0 + checksum: 79076749fcacf21b5d16dd596d32c3b6bf4d6e62abb43868fac21674078505c8b15eaca4e47ed844985a4514854f917d78f588fcd029693709417d8f98b2bd60 + languageName: node + linkType: hard + +"minipass@npm:^3.0.0": + version: 3.3.6 + resolution: "minipass@npm:3.3.6" + dependencies: + yallist: ^4.0.0 + checksum: a30d083c8054cee83cdcdc97f97e4641a3f58ae743970457b1489ce38ee1167b3aaf7d815cd39ec7a99b9c40397fd4f686e83750e73e652b21cb516f6d845e48 + languageName: node + linkType: hard + +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.0.4, minipass@npm:^7.1.2": + version: 7.1.2 + resolution: "minipass@npm:7.1.2" + checksum: 2bfd325b95c555f2b4d2814d49325691c7bee937d753814861b0b49d5edcda55cbbf22b6b6a60bb91eddac8668771f03c5ff647dcd9d0f798e9548b9cdc46ee3 + languageName: node + linkType: hard + +"minizlib@npm:^3.0.1": + version: 3.0.2 + resolution: "minizlib@npm:3.0.2" + dependencies: + minipass: ^7.1.2 + checksum: 493bed14dcb6118da7f8af356a8947cf1473289c09658e5aabd69a737800a8c3b1736fb7d7931b722268a9c9bc038a6d53c049b6a6af24b34a121823bb709996 + languageName: node + linkType: hard + +"mkdirp@npm:^3.0.1": + version: 3.0.1 + resolution: "mkdirp@npm:3.0.1" + bin: + mkdirp: dist/cjs/src/bin.js + checksum: 972deb188e8fb55547f1e58d66bd6b4a3623bf0c7137802582602d73e6480c1c2268dcbafbfb1be466e00cc7e56ac514d7fd9334b7cf33e3e2ab547c16f83a8d + languageName: node + linkType: hard + +"mlly@npm:^1.7.4": + version: 1.7.4 + resolution: "mlly@npm:1.7.4" + dependencies: + acorn: ^8.14.0 + pathe: ^2.0.1 + pkg-types: ^1.3.0 + ufo: ^1.5.4 + checksum: a290da940d208f9d77ceed7ed1db3397e37ff083d28bf75e3c92097a8e58967a2b2e2bea33fdcdc63005e2987854cd081dd0621461d89eee4b61c977b5fa020c + languageName: node + linkType: hard + +"ms@npm:2.1.2": + version: 2.1.2 + resolution: "ms@npm:2.1.2" + checksum: 673cdb2c3133eb050c745908d8ce632ed2c02d85640e2edb3ace856a2266a813b30c613569bf3354fdf4ea7d1a1494add3bfa95e2713baa27d0c2c71fc44f58f + languageName: node + linkType: hard + +"ms@npm:^2.0.0, ms@npm:^2.1.3": + version: 2.1.3 + resolution: "ms@npm:2.1.3" + checksum: aa92de608021b242401676e35cfa5aa42dd70cbdc082b916da7fb925c542173e36bce97ea3e804923fe92c0ad991434e4a38327e15a1b5b5f945d66df615ae6d + languageName: node + linkType: hard + +"mz@npm:^2.7.0": + version: 2.7.0 + resolution: "mz@npm:2.7.0" + dependencies: + any-promise: ^1.0.0 + object-assign: ^4.0.1 + thenify-all: ^1.0.0 + checksum: 8427de0ece99a07e9faed3c0c6778820d7543e3776f9a84d22cf0ec0a8eb65f6e9aee9c9d353ff9a105ff62d33a9463c6ca638974cc652ee8140cd1e35951c87 + languageName: node + linkType: hard + +"negotiator@npm:^1.0.0": + version: 1.0.0 + resolution: "negotiator@npm:1.0.0" + checksum: 20ebfe79b2d2e7cf9cbc8239a72662b584f71164096e6e8896c8325055497c96f6b80cd22c258e8a2f2aa382a787795ec3ee8b37b422a302c7d4381b0d5ecfbb + languageName: node + linkType: hard + +"no-case@npm:^3.0.4": + version: 3.0.4 + resolution: "no-case@npm:3.0.4" + dependencies: + lower-case: ^2.0.2 + tslib: ^2.0.3 + checksum: 0b2ebc113dfcf737d48dde49cfebf3ad2d82a8c3188e7100c6f375e30eafbef9e9124aadc3becef237b042fd5eb0aad2fd78669c20972d045bbe7fea8ba0be5c + languageName: node + linkType: hard + +"node-fetch@npm:2": + version: 2.6.7 + resolution: "node-fetch@npm:2.6.7" + dependencies: + whatwg-url: ^5.0.0 + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + checksum: 8d816ffd1ee22cab8301c7756ef04f3437f18dace86a1dae22cf81db8ef29c0bf6655f3215cb0cdb22b420b6fe141e64b26905e7f33f9377a7fa59135ea3e10b + languageName: node + linkType: hard + +"node-fetch@npm:^2.7.0": + version: 2.7.0 + resolution: "node-fetch@npm:2.7.0" + dependencies: + whatwg-url: ^5.0.0 + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + checksum: d76d2f5edb451a3f05b15115ec89fc6be39de37c6089f1b6368df03b91e1633fd379a7e01b7ab05089a25034b2023d959b47e59759cb38d88341b2459e89d6e5 + languageName: node + linkType: hard + +"node-gyp-build@npm:^4.3.0": + version: 4.5.0 + resolution: "node-gyp-build@npm:4.5.0" + bin: + node-gyp-build: bin.js + node-gyp-build-optional: optional.js + node-gyp-build-test: build-test.js + checksum: d888bae0fb88335f69af1b57a2294a931c5042f36e413d8d364c992c9ebfa0b96ffe773179a5a2c8f04b73856e8634e09cce108dbb9804396d3cc8c5455ff2db + languageName: node + linkType: hard + +"node-gyp@npm:latest": + version: 11.2.0 + resolution: "node-gyp@npm:11.2.0" + dependencies: + env-paths: ^2.2.0 + exponential-backoff: ^3.1.1 + graceful-fs: ^4.2.6 + make-fetch-happen: ^14.0.3 + nopt: ^8.0.0 + proc-log: ^5.0.0 + semver: ^7.3.5 + tar: ^7.4.3 + tinyglobby: ^0.2.12 + which: ^5.0.0 + bin: + node-gyp: bin/node-gyp.js + checksum: 2536282ba81f8a94b29482d3622b6ab298611440619e46de4512a6f32396a68b5530357c474b859787069d84a4c537d99e0c71078cce5b9f808bf84eeb78e8fb + languageName: node + linkType: hard + +"nopt@npm:^8.0.0": + version: 8.1.0 + resolution: "nopt@npm:8.1.0" + dependencies: + abbrev: ^3.0.0 + bin: + nopt: bin/nopt.js + checksum: 49cfd3eb6f565e292bf61f2ff1373a457238804d5a5a63a8d786c923007498cba89f3648e3b952bc10203e3e7285752abf5b14eaf012edb821e84f24e881a92a + languageName: node + linkType: hard + +"object-assign@npm:^4.0.1": + version: 4.1.1 + resolution: "object-assign@npm:4.1.1" + checksum: fcc6e4ea8c7fe48abfbb552578b1c53e0d194086e2e6bbbf59e0a536381a292f39943c6e9628af05b5528aa5e3318bb30d6b2e53cadaf5b8fe9e12c4b69af23f + languageName: node + linkType: hard + +"object-is@npm:^1.1.5": + version: 1.1.6 + resolution: "object-is@npm:1.1.6" + dependencies: + call-bind: ^1.0.7 + define-properties: ^1.2.1 + checksum: 3ea22759967e6f2380a2cbbd0f737b42dc9ddb2dfefdb159a1b927fea57335e1b058b564bfa94417db8ad58cddab33621a035de6f5e5ad56d89f2dd03e66c6a1 + languageName: node + linkType: hard + +"object-keys@npm:^1.1.1": + version: 1.1.1 + resolution: "object-keys@npm:1.1.1" + checksum: b363c5e7644b1e1b04aa507e88dcb8e3a2f52b6ffd0ea801e4c7a62d5aa559affe21c55a07fd4b1fd55fc03a33c610d73426664b20032405d7b92a1414c34d6a + languageName: node + linkType: hard + +"object.assign@npm:^4.1.4": + version: 4.1.7 + resolution: "object.assign@npm:4.1.7" + dependencies: + call-bind: ^1.0.8 + call-bound: ^1.0.3 + define-properties: ^1.2.1 + es-object-atoms: ^1.0.0 + has-symbols: ^1.1.0 + object-keys: ^1.1.1 + checksum: 60e07d2651cf4f5528c485f1aa4dbded9b384c47d80e8187cefd11320abb1aebebf78df5483451dfa549059f8281c21f7b4bf7d19e9e5e97d8d617df0df298de + languageName: node + linkType: hard + +"p-map@npm:^7.0.2": + version: 7.0.3 + resolution: "p-map@npm:7.0.3" + checksum: 8c92d533acf82f0d12f7e196edccff773f384098bbb048acdd55a08778ce4fc8889d8f1bde72969487bd96f9c63212698d79744c20bedfce36c5b00b46d369f8 + languageName: node + linkType: hard + +"package-json-from-dist@npm:^1.0.0": + version: 1.0.1 + resolution: "package-json-from-dist@npm:1.0.1" + checksum: 58ee9538f2f762988433da00e26acc788036914d57c71c246bf0be1b60cdbd77dd60b6a3e1a30465f0b248aeb80079e0b34cb6050b1dfa18c06953bb1cbc7602 + languageName: node + linkType: hard + +"path-key@npm:^3.1.0": + version: 3.1.1 + resolution: "path-key@npm:3.1.1" + checksum: 55cd7a9dd4b343412a8386a743f9c746ef196e57c823d90ca3ab917f90ab9f13dd0ded27252ba49dbdfcab2b091d998bc446f6220cd3cea65db407502a740020 + languageName: node + linkType: hard + +"path-scurry@npm:^1.11.1": + version: 1.11.1 + resolution: "path-scurry@npm:1.11.1" + dependencies: + lru-cache: ^10.2.0 + minipass: ^5.0.0 || ^6.0.2 || ^7.0.0 + checksum: 890d5abcd593a7912dcce7cf7c6bf7a0b5648e3dee6caf0712c126ca0a65c7f3d7b9d769072a4d1baf370f61ce493ab5b038d59988688e0c5f3f646ee3c69023 + languageName: node + linkType: hard + +"pathe@npm:^2.0.1": + version: 2.0.3 + resolution: "pathe@npm:2.0.3" + checksum: 0602bdd4acb54d91044e0c56f1fb63467ae7d44ab3afea1f797947b0eb2b4d1d91cf0d58d065fdb0a8ab0c4acbbd8d3a5b424983eaf10dd5285d37a16f6e3ee9 + languageName: node + linkType: hard + +"picocolors@npm:^1.1.1": + version: 1.1.1 + resolution: "picocolors@npm:1.1.1" + checksum: e1cf46bf84886c79055fdfa9dcb3e4711ad259949e3565154b004b260cd356c5d54b31a1437ce9782624bf766272fe6b0154f5f0c744fb7af5d454d2b60db045 + languageName: node + linkType: hard + +"picomatch@npm:^4.0.2": + version: 4.0.3 + resolution: "picomatch@npm:4.0.3" + checksum: 6817fb74eb745a71445debe1029768de55fd59a42b75606f478ee1d0dc1aa6e78b711d041a7c9d5550e042642029b7f373dc1a43b224c4b7f12d23436735dba0 + languageName: node + linkType: hard + +"pirates@npm:^4.0.1": + version: 4.0.7 + resolution: "pirates@npm:4.0.7" + checksum: 3dcbaff13c8b5bc158416feb6dc9e49e3c6be5fddc1ea078a05a73ef6b85d79324bbb1ef59b954cdeff000dbf000c1d39f32dc69310c7b78fbada5171b583e40 + languageName: node + linkType: hard + +"pkg-types@npm:^1.3.0": + version: 1.3.1 + resolution: "pkg-types@npm:1.3.1" + dependencies: + confbox: ^0.1.8 + mlly: ^1.7.4 + pathe: ^2.0.1 + checksum: 4fa4edb2bb845646cdbd04c5c6bc43cdbc8f02ed4d1c28bfcafb6e65928aece789bcf1335e4cac5f65dfdc376e4bd7435bd509a35e9ec73ef2c076a1b88e289c + languageName: node + linkType: hard + +"possible-typed-array-names@npm:^1.0.0": + version: 1.1.0 + resolution: "possible-typed-array-names@npm:1.1.0" + checksum: cfcd4f05264eee8fd184cd4897a17890561d1d473434b43ab66ad3673d9c9128981ec01e0cb1d65a52cd6b1eebfb2eae1e53e39b2e0eca86afc823ede7a4f41b + languageName: node + linkType: hard + +"postcss-load-config@npm:^6.0.1": + version: 6.0.1 + resolution: "postcss-load-config@npm:6.0.1" + dependencies: + lilconfig: ^3.1.1 + peerDependencies: + jiti: ">=1.21.0" + postcss: ">=8.0.9" + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + checksum: 701061264cce7646e53e4cecd14aa95432a9bd508f30520a31dfa4c86fe9252d5d8d0204fdbfbddc1559c9b8791556e9c4b92c56070f5fca0a6c60e5ee9ad0fd + languageName: node + linkType: hard + +"prettier@npm:^2.5.1": + version: 2.8.1 + resolution: "prettier@npm:2.8.1" + bin: + prettier: bin-prettier.js + checksum: 4f21a0f1269f76fb36f54e9a8a1ea4c11e27478958bf860661fb4b6d7ac69aac1581f8724fa98ea3585e56d42a2ea317a17ff6e3324f40cb11ff9e20b73785cc + languageName: node + linkType: hard + +"proc-log@npm:^5.0.0": + version: 5.0.0 + resolution: "proc-log@npm:5.0.0" + checksum: c78b26ecef6d5cce4a7489a1e9923d7b4b1679028c8654aef0463b27f4a90b0946cd598f55799da602895c52feb085ec76381d007ab8dcceebd40b89c2f9dfe0 + languageName: node + linkType: hard + +"promise-retry@npm:^2.0.1": + version: 2.0.1 + resolution: "promise-retry@npm:2.0.1" + dependencies: + err-code: ^2.0.2 + retry: ^0.12.0 + checksum: f96a3f6d90b92b568a26f71e966cbbc0f63ab85ea6ff6c81284dc869b41510e6cdef99b6b65f9030f0db422bf7c96652a3fff9f2e8fb4a0f069d8f4430359429 + languageName: node + linkType: hard + +"punycode@npm:^2.1.0": + version: 2.3.1 + resolution: "punycode@npm:2.3.1" + checksum: bb0a0ceedca4c3c57a9b981b90601579058903c62be23c5e8e843d2c2d4148a3ecf029d5133486fb0e1822b098ba8bba09e89d6b21742d02fa26bda6441a6fb2 + languageName: node + linkType: hard + +"readdirp@npm:^4.0.1": + version: 4.1.2 + resolution: "readdirp@npm:4.1.2" + checksum: 3242ee125422cb7c0e12d51452e993f507e6ed3d8c490bc8bf3366c5cdd09167562224e429b13e9cb2b98d4b8b2b11dc100d3c73883aa92d657ade5a21ded004 + languageName: node + linkType: hard + +"regenerator-runtime@npm:^0.13.11": + version: 0.13.11 + resolution: "regenerator-runtime@npm:0.13.11" + checksum: 27481628d22a1c4e3ff551096a683b424242a216fee44685467307f14d58020af1e19660bf2e26064de946bad7eff28950eae9f8209d55723e2d9351e632bbb4 + languageName: node + linkType: hard + +"resolve-from@npm:^5.0.0": + version: 5.0.0 + resolution: "resolve-from@npm:5.0.0" + checksum: 4ceeb9113e1b1372d0cd969f3468fa042daa1dd9527b1b6bb88acb6ab55d8b9cd65dbf18819f9f9ddf0db804990901dcdaade80a215e7b2c23daae38e64f5bdf + languageName: node + linkType: hard + +"retry@npm:^0.12.0": + version: 0.12.0 + resolution: "retry@npm:0.12.0" + checksum: 623bd7d2e5119467ba66202d733ec3c2e2e26568074923bc0585b6b99db14f357e79bdedb63cab56cec47491c4a0da7e6021a7465ca6dc4f481d3898fdd3158c + languageName: node + linkType: hard + +"rollup@npm:^4.34.8": + version: 4.45.1 + resolution: "rollup@npm:4.45.1" + dependencies: + "@rollup/rollup-android-arm-eabi": 4.45.1 + "@rollup/rollup-android-arm64": 4.45.1 + "@rollup/rollup-darwin-arm64": 4.45.1 + "@rollup/rollup-darwin-x64": 4.45.1 + "@rollup/rollup-freebsd-arm64": 4.45.1 + "@rollup/rollup-freebsd-x64": 4.45.1 + "@rollup/rollup-linux-arm-gnueabihf": 4.45.1 + "@rollup/rollup-linux-arm-musleabihf": 4.45.1 + "@rollup/rollup-linux-arm64-gnu": 4.45.1 + "@rollup/rollup-linux-arm64-musl": 4.45.1 + "@rollup/rollup-linux-loongarch64-gnu": 4.45.1 + "@rollup/rollup-linux-powerpc64le-gnu": 4.45.1 + "@rollup/rollup-linux-riscv64-gnu": 4.45.1 + "@rollup/rollup-linux-riscv64-musl": 4.45.1 + "@rollup/rollup-linux-s390x-gnu": 4.45.1 + "@rollup/rollup-linux-x64-gnu": 4.45.1 + "@rollup/rollup-linux-x64-musl": 4.45.1 + "@rollup/rollup-win32-arm64-msvc": 4.45.1 + "@rollup/rollup-win32-ia32-msvc": 4.45.1 + "@rollup/rollup-win32-x64-msvc": 4.45.1 + "@types/estree": 1.0.8 + fsevents: ~2.3.2 + dependenciesMeta: + "@rollup/rollup-android-arm-eabi": + optional: true + "@rollup/rollup-android-arm64": + optional: true + "@rollup/rollup-darwin-arm64": + optional: true + "@rollup/rollup-darwin-x64": + optional: true + "@rollup/rollup-freebsd-arm64": + optional: true + "@rollup/rollup-freebsd-x64": + optional: true + "@rollup/rollup-linux-arm-gnueabihf": + optional: true + "@rollup/rollup-linux-arm-musleabihf": + optional: true + "@rollup/rollup-linux-arm64-gnu": + optional: true + "@rollup/rollup-linux-arm64-musl": + optional: true + "@rollup/rollup-linux-loongarch64-gnu": + optional: true + "@rollup/rollup-linux-powerpc64le-gnu": + optional: true + "@rollup/rollup-linux-riscv64-gnu": + optional: true + "@rollup/rollup-linux-riscv64-musl": + optional: true + "@rollup/rollup-linux-s390x-gnu": + optional: true + "@rollup/rollup-linux-x64-gnu": + optional: true + "@rollup/rollup-linux-x64-musl": + optional: true + "@rollup/rollup-win32-arm64-msvc": + optional: true + "@rollup/rollup-win32-ia32-msvc": + optional: true + "@rollup/rollup-win32-x64-msvc": + optional: true + fsevents: + optional: true + bin: + rollup: dist/bin/rollup + checksum: 3a84cad560ed0f7a15bc6b8408a52a103c624c1748ef47bbbb845a0dc352a294717754cd6158bdbcade9c1aa82f527a5d28e3640ac6f1458e3f7590fd1f31a4e + languageName: node + linkType: hard + +"rpc-websockets@npm:^7.5.0": + version: 7.5.0 + resolution: "rpc-websockets@npm:7.5.0" + dependencies: + "@babel/runtime": ^7.17.2 + bufferutil: ^4.0.1 + eventemitter3: ^4.0.7 + utf-8-validate: ^5.0.2 + uuid: ^8.3.2 + ws: ^8.5.0 + dependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: cd4c999e54161f9f40e162f57d7f3313edf086ff5facefbdc0629d52066e9843ace987681dbff8b4329db225deb69f58c528d7818a9c7e89f0100969b7789c2d + languageName: node + linkType: hard + +"rpc-websockets@npm:^9.0.2": + version: 9.1.1 + resolution: "rpc-websockets@npm:9.1.1" + dependencies: + "@swc/helpers": ^0.5.11 + "@types/uuid": ^8.3.4 + "@types/ws": ^8.2.2 + buffer: ^6.0.3 + bufferutil: ^4.0.1 + eventemitter3: ^5.0.1 + utf-8-validate: ^5.0.2 + uuid: ^8.3.2 + ws: ^8.5.0 + dependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 3b0db5c93ea572240db07c41c8645b1d9f2cdd3b932f87e415300d775afdcf4443159abfa1400630aadc26a5ea5ae79e4ff9f6f5f124b3ca0698cf2eac5ba68b + languageName: node + linkType: hard + +"safe-buffer@npm:^5.0.1": + version: 5.2.1 + resolution: "safe-buffer@npm:5.2.1" + checksum: b99c4b41fdd67a6aaf280fcd05e9ffb0813654894223afb78a31f14a19ad220bba8aba1cb14eddce1fcfb037155fe6de4e861784eb434f7d11ed58d1e70dd491 + languageName: node + linkType: hard + +"safe-regex-test@npm:^1.1.0": + version: 1.1.0 + resolution: "safe-regex-test@npm:1.1.0" + dependencies: + call-bound: ^1.0.2 + es-errors: ^1.3.0 + is-regex: ^1.2.1 + checksum: 3c809abeb81977c9ed6c869c83aca6873ea0f3ab0f806b8edbba5582d51713f8a6e9757d24d2b4b088f563801475ea946c8e77e7713e8c65cdd02305b6caedab + languageName: node + linkType: hard + +"safer-buffer@npm:>= 2.1.2 < 3.0.0": + version: 2.1.2 + resolution: "safer-buffer@npm:2.1.2" + checksum: cab8f25ae6f1434abee8d80023d7e72b598cf1327164ddab31003c51215526801e40b66c5e65d658a0af1e9d6478cadcb4c745f4bd6751f97d8644786c0978b0 + languageName: node + linkType: hard + +"semver@npm:^7.3.5": + version: 7.7.2 + resolution: "semver@npm:7.7.2" + bin: + semver: bin/semver.js + checksum: dd94ba8f1cbc903d8eeb4dd8bf19f46b3deb14262b6717d0de3c804b594058ae785ef2e4b46c5c3b58733c99c83339068203002f9e37cfe44f7e2cc5e3d2f621 + languageName: node + linkType: hard + +"semver@npm:^7.3.7": + version: 7.3.8 + resolution: "semver@npm:7.3.8" + dependencies: + lru-cache: ^6.0.0 + bin: + semver: bin/semver.js + checksum: ba9c7cbbf2b7884696523450a61fee1a09930d888b7a8d7579025ad93d459b2d1949ee5bbfeb188b2be5f4ac163544c5e98491ad6152df34154feebc2cc337c1 + languageName: node + linkType: hard + +"set-function-length@npm:^1.2.2": + version: 1.2.2 + resolution: "set-function-length@npm:1.2.2" + dependencies: + define-data-property: ^1.1.4 + es-errors: ^1.3.0 + function-bind: ^1.1.2 + get-intrinsic: ^1.2.4 + gopd: ^1.0.1 + has-property-descriptors: ^1.0.2 + checksum: a8248bdacdf84cb0fab4637774d9fb3c7a8e6089866d04c817583ff48e14149c87044ce683d7f50759a8c50fb87c7a7e173535b06169c87ef76f5fb276dfff72 + languageName: node + linkType: hard + +"shebang-command@npm:^2.0.0": + version: 2.0.0 + resolution: "shebang-command@npm:2.0.0" + dependencies: + shebang-regex: ^3.0.0 + checksum: 6b52fe87271c12968f6a054e60f6bde5f0f3d2db483a1e5c3e12d657c488a15474121a1d55cd958f6df026a54374ec38a4a963988c213b7570e1d51575cea7fa + languageName: node + linkType: hard + +"shebang-regex@npm:^3.0.0": + version: 3.0.0 + resolution: "shebang-regex@npm:3.0.0" + checksum: 1a2bcae50de99034fcd92ad4212d8e01eedf52c7ec7830eedcf886622804fe36884278f2be8be0ea5fde3fd1c23911643a4e0f726c8685b61871c8908af01222 + languageName: node + linkType: hard + +"shiki@npm:^0.14.7": + version: 0.14.7 + resolution: "shiki@npm:0.14.7" + dependencies: + ansi-sequence-parser: ^1.1.0 + jsonc-parser: ^3.2.0 + vscode-oniguruma: ^1.7.0 + vscode-textmate: ^8.0.0 + checksum: 2aec3b3519df977c4391df9e1825cb496e9a4d7e11395f05a0da77e4fa2f7c3d9d6e6ee94029ac699533017f2b25637ee68f6d39f05f311535c2704d0329b520 + languageName: node + linkType: hard + +"signal-exit@npm:^4.0.1": + version: 4.1.0 + resolution: "signal-exit@npm:4.1.0" + checksum: 64c757b498cb8629ffa5f75485340594d2f8189e9b08700e69199069c8e3070fb3e255f7ab873c05dc0b3cec412aea7402e10a5990cb6a050bd33ba062a6c549 + languageName: node + linkType: hard + +"smart-buffer@npm:^4.2.0": + version: 4.2.0 + resolution: "smart-buffer@npm:4.2.0" + checksum: b5167a7142c1da704c0e3af85c402002b597081dd9575031a90b4f229ca5678e9a36e8a374f1814c8156a725d17008ae3bde63b92f9cfd132526379e580bec8b + languageName: node + linkType: hard + +"snake-case@npm:^3.0.4": + version: 3.0.4 + resolution: "snake-case@npm:3.0.4" + dependencies: + dot-case: ^3.0.4 + tslib: ^2.0.3 + checksum: 0a7a79900bbb36f8aaa922cf111702a3647ac6165736d5dc96d3ef367efc50465cac70c53cd172c382b022dac72ec91710608e5393de71f76d7142e6fd80e8a3 + languageName: node + linkType: hard + +"socks-proxy-agent@npm:^8.0.3": + version: 8.0.5 + resolution: "socks-proxy-agent@npm:8.0.5" + dependencies: + agent-base: ^7.1.2 + debug: ^4.3.4 + socks: ^2.8.3 + checksum: b4fbcdb7ad2d6eec445926e255a1fb95c975db0020543fbac8dfa6c47aecc6b3b619b7fb9c60a3f82c9b2969912a5e7e174a056ae4d98cb5322f3524d6036e1d + languageName: node + linkType: hard + +"socks@npm:^2.8.3": + version: 2.8.6 + resolution: "socks@npm:2.8.6" + dependencies: + ip-address: ^9.0.5 + smart-buffer: ^4.2.0 + checksum: 3d2a696d42d94b05b2a7e797b9291483d6768b23300b015353f34f8046cce35f23fe59300a38a77a9f0dee4274dd6c333afbdef628cf48f3df171bfb86c2d21c + languageName: node + linkType: hard + +"source-map@npm:0.8.0-beta.0": + version: 0.8.0-beta.0 + resolution: "source-map@npm:0.8.0-beta.0" + dependencies: + whatwg-url: ^7.0.0 + checksum: e94169be6461ab0ac0913313ad1719a14c60d402bd22b0ad96f4a6cffd79130d91ab5df0a5336a326b04d2df131c1409f563c9dc0d21a6ca6239a44b6c8dbd92 + languageName: node + linkType: hard + +"spok@npm:^1.4.3": + version: 1.4.3 + resolution: "spok@npm:1.4.3" + dependencies: + ansicolors: ~0.3.2 + checksum: 22fc0ab37ad6314069700d0dae7f878f981fa51d29c478aa1de30aa74f6bdfbb5dee9fe24bfcf59dc234c4240a344139c486ee6e06134a4dd396ab2df75ca18a + languageName: node + linkType: hard + +"sprintf-js@npm:^1.1.3": + version: 1.1.3 + resolution: "sprintf-js@npm:1.1.3" + checksum: a3fdac7b49643875b70864a9d9b469d87a40dfeaf5d34d9d0c5b1cda5fd7d065531fcb43c76357d62254c57184a7b151954156563a4d6a747015cfb41021cad0 + languageName: node + linkType: hard + +"ssri@npm:^12.0.0": + version: 12.0.0 + resolution: "ssri@npm:12.0.0" + dependencies: + minipass: ^7.0.3 + checksum: ef4b6b0ae47b4a69896f5f1c4375f953b9435388c053c36d27998bc3d73e046969ccde61ab659e679142971a0b08e50478a1228f62edb994105b280f17900c98 + languageName: node + linkType: hard + +"stream-chain@npm:^2.2.5": + version: 2.2.5 + resolution: "stream-chain@npm:2.2.5" + checksum: c83cbf504bd11e2bcbe761a92801295b3decac7ffa4092ceffca2eb1b5d0763bcc511fa22cd8044e8a18c21ca66794fd10c8d9cd1292a3e6c0d83a4194c6b8ed + languageName: node + linkType: hard + +"stream-json@npm:^1.9.1": + version: 1.9.1 + resolution: "stream-json@npm:1.9.1" + dependencies: + stream-chain: ^2.2.5 + checksum: 2ebf0648f9ed82ee79727a9a47805231a70d5032e0c21cee3e05cd3c449d3ce49c72b371555447eeef55904bae22ac64be8ae6086fc6cce0b83b3aa617736b64 + languageName: node + linkType: hard + +"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0": + version: 4.2.3 + resolution: "string-width@npm:4.2.3" + dependencies: + emoji-regex: ^8.0.0 + is-fullwidth-code-point: ^3.0.0 + strip-ansi: ^6.0.1 + checksum: e52c10dc3fbfcd6c3a15f159f54a90024241d0f149cf8aed2982a2d801d2e64df0bf1dc351cf8e95c3319323f9f220c16e740b06faecd53e2462df1d2b5443fb + languageName: node + linkType: hard + +"string-width@npm:^5.0.1, string-width@npm:^5.1.2": + version: 5.1.2 + resolution: "string-width@npm:5.1.2" + dependencies: + eastasianwidth: ^0.2.0 + emoji-regex: ^9.2.2 + strip-ansi: ^7.0.1 + checksum: 7369deaa29f21dda9a438686154b62c2c5f661f8dda60449088f9f980196f7908fc39fdd1803e3e01541970287cf5deae336798337e9319a7055af89dafa7193 + languageName: node + linkType: hard + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": + version: 6.0.1 + resolution: "strip-ansi@npm:6.0.1" + dependencies: + ansi-regex: ^5.0.1 + checksum: f3cd25890aef3ba6e1a74e20896c21a46f482e93df4a06567cebf2b57edabb15133f1f94e57434e0a958d61186087b1008e89c94875d019910a213181a14fc8c + languageName: node + linkType: hard + +"strip-ansi@npm:^7.0.1": + version: 7.1.0 + resolution: "strip-ansi@npm:7.1.0" + dependencies: + ansi-regex: ^6.0.1 + checksum: 859c73fcf27869c22a4e4d8c6acfe690064659e84bef9458aa6d13719d09ca88dcfd40cbf31fd0be63518ea1a643fe070b4827d353e09533a5b0b9fd4553d64d + languageName: node + linkType: hard + +"sucrase@npm:^3.35.0": + version: 3.35.0 + resolution: "sucrase@npm:3.35.0" + dependencies: + "@jridgewell/gen-mapping": ^0.3.2 + commander: ^4.0.0 + glob: ^10.3.10 + lines-and-columns: ^1.1.6 + mz: ^2.7.0 + pirates: ^4.0.1 + ts-interface-checker: ^0.1.9 + bin: + sucrase: bin/sucrase + sucrase-node: bin/sucrase-node + checksum: 9fc5792a9ab8a14dcf9c47dcb704431d35c1cdff1d17d55d382a31c2e8e3063870ad32ce120a80915498486246d612e30cda44f1624d9d9a10423e1a43487ad1 + languageName: node + linkType: hard + +"superstruct@npm:^0.14.2": + version: 0.14.2 + resolution: "superstruct@npm:0.14.2" + checksum: c5c4840f432da82125b923ec45faca5113217e83ae416e314d80eae012b8bb603d2e745025d173450758d116348820bc7028157f8c9a72b6beae879f94b837c0 + languageName: node + linkType: hard + +"superstruct@npm:^2.0.2": + version: 2.0.2 + resolution: "superstruct@npm:2.0.2" + checksum: a5f75b72cb8b14b86f4f7f750dae8c5ab0e4e1d92414b55e7625bae07bbcafad81c92486e7e32ccacd6ae1f553caff2b92a50ff42ad5093fd35b9cb7f4e5ec86 + languageName: node + linkType: hard + +"tar@npm:^7.4.3": + version: 7.4.3 + resolution: "tar@npm:7.4.3" + dependencies: + "@isaacs/fs-minipass": ^4.0.0 + chownr: ^3.0.0 + minipass: ^7.1.2 + minizlib: ^3.0.1 + mkdirp: ^3.0.1 + yallist: ^5.0.0 + checksum: 8485350c0688331c94493031f417df069b778aadb25598abdad51862e007c39d1dd5310702c7be4a6784731a174799d8885d2fde0484269aea205b724d7b2ffa + languageName: node + linkType: hard + +"text-encoding-utf-8@npm:^1.0.2": + version: 1.0.2 + resolution: "text-encoding-utf-8@npm:1.0.2" + checksum: ec4c15d50e738c5dba7327ad432ebf0725ec75d4d69c0bd55609254c5a3bc5341272d7003691084a0a73d60d981c8eb0e87603676fdb6f3fed60f4c9192309f9 + languageName: node + linkType: hard + +"text-table@npm:^0.2.0": + version: 0.2.0 + resolution: "text-table@npm:0.2.0" + checksum: b6937a38c80c7f84d9c11dd75e49d5c44f71d95e810a3250bd1f1797fc7117c57698204adf676b71497acc205d769d65c16ae8fa10afad832ae1322630aef10a + languageName: node + linkType: hard + +"thenify-all@npm:^1.0.0": + version: 1.6.0 + resolution: "thenify-all@npm:1.6.0" + dependencies: + thenify: ">= 3.1.0 < 4" + checksum: dba7cc8a23a154cdcb6acb7f51d61511c37a6b077ec5ab5da6e8b874272015937788402fd271fdfc5f187f8cb0948e38d0a42dcc89d554d731652ab458f5343e + languageName: node + linkType: hard + +"thenify@npm:>= 3.1.0 < 4": + version: 3.3.1 + resolution: "thenify@npm:3.3.1" + dependencies: + any-promise: ^1.0.0 + checksum: 84e1b804bfec49f3531215f17b4a6e50fd4397b5f7c1bccc427b9c656e1ecfb13ea79d899930184f78bc2f57285c54d9a50a590c8868f4f0cef5c1d9f898b05e + languageName: node + linkType: hard + +"through@npm:>=2.2.7 <3": + version: 2.3.8 + resolution: "through@npm:2.3.8" + checksum: a38c3e059853c494af95d50c072b83f8b676a9ba2818dcc5b108ef252230735c54e0185437618596c790bbba8fcdaef5b290405981ffa09dce67b1f1bf190cbd + languageName: node + linkType: hard + +"tinyexec@npm:^0.3.2": + version: 0.3.2 + resolution: "tinyexec@npm:0.3.2" + checksum: bd491923020610bdeadb0d8cf5d70e7cbad5a3201620fd01048c9bf3b31ffaa75c33254e1540e13b993ce4e8187852b0b5a93057bb598e7a57afa2ca2048a35c + languageName: node + linkType: hard + +"tinyglobby@npm:^0.2.11, tinyglobby@npm:^0.2.12": + version: 0.2.14 + resolution: "tinyglobby@npm:0.2.14" + dependencies: + fdir: ^6.4.4 + picomatch: ^4.0.2 + checksum: 261e986e3f2062dec3a582303bad2ce31b4634b9348648b46828c000d464b012cf474e38f503312367d4117c3f2f18611992738fca684040758bba44c24de522 + languageName: node + linkType: hard + +"toml@npm:^3.0.0": + version: 3.0.0 + resolution: "toml@npm:3.0.0" + checksum: 5d7f1d8413ad7780e9bdecce8ea4c3f5130dd53b0a4f2e90b93340979a137739879d7b9ce2ce05c938b8cc828897fe9e95085197342a1377dd8850bf5125f15f + languageName: node + linkType: hard + +"tr46@npm:^1.0.1": + version: 1.0.1 + resolution: "tr46@npm:1.0.1" + dependencies: + punycode: ^2.1.0 + checksum: 96d4ed46bc161db75dbf9247a236ea0bfcaf5758baae6749e92afab0bc5a09cb59af21788ede7e55080f2bf02dce3e4a8f2a484cc45164e29f4b5e68f7cbcc1a + languageName: node + linkType: hard + +"tr46@npm:~0.0.3": + version: 0.0.3 + resolution: "tr46@npm:0.0.3" + checksum: 726321c5eaf41b5002e17ffbd1fb7245999a073e8979085dacd47c4b4e8068ff5777142fc6726d6ca1fd2ff16921b48788b87225cbc57c72636f6efa8efbffe3 + languageName: node + linkType: hard + +"tree-kill@npm:^1.2.2": + version: 1.2.2 + resolution: "tree-kill@npm:1.2.2" + bin: + tree-kill: cli.js + checksum: 49117f5f410d19c84b0464d29afb9642c863bc5ba40fcb9a245d474c6d5cc64d1b177a6e6713129eb346b40aebb9d4631d967517f9fbe8251c35b21b13cd96c7 + languageName: node + linkType: hard + +"ts-interface-checker@npm:^0.1.9": + version: 0.1.13 + resolution: "ts-interface-checker@npm:0.1.13" + checksum: 20c29189c2dd6067a8775e07823ddf8d59a33e2ffc47a1bd59a5cb28bb0121a2969a816d5e77eda2ed85b18171aa5d1c4005a6b88ae8499ec7cc49f78571cb5e + languageName: node + linkType: hard + +"tslib@npm:^2.0.3": + version: 2.4.1 + resolution: "tslib@npm:2.4.1" + checksum: 19480d6e0313292bd6505d4efe096a6b31c70e21cf08b5febf4da62e95c265c8f571f7b36fcc3d1a17e068032f59c269fab3459d6cd3ed6949eafecf64315fca + languageName: node + linkType: hard + +"tslib@npm:^2.8.0": + version: 2.8.1 + resolution: "tslib@npm:2.8.1" + checksum: e4aba30e632b8c8902b47587fd13345e2827fa639e7c3121074d5ee0880723282411a8838f830b55100cbe4517672f84a2472667d355b81e8af165a55dc6203a + languageName: node + linkType: hard + +"tsup@npm:^8.0.2": + version: 8.5.0 + resolution: "tsup@npm:8.5.0" + dependencies: + bundle-require: ^5.1.0 + cac: ^6.7.14 + chokidar: ^4.0.3 + consola: ^3.4.0 + debug: ^4.4.0 + esbuild: ^0.25.0 + fix-dts-default-cjs-exports: ^1.0.0 + joycon: ^3.1.1 + picocolors: ^1.1.1 + postcss-load-config: ^6.0.1 + resolve-from: ^5.0.0 + rollup: ^4.34.8 + source-map: 0.8.0-beta.0 + sucrase: ^3.35.0 + tinyexec: ^0.3.2 + tinyglobby: ^0.2.11 + tree-kill: ^1.2.2 + peerDependencies: + "@microsoft/api-extractor": ^7.36.0 + "@swc/core": ^1 + postcss: ^8.4.12 + typescript: ">=4.5.0" + peerDependenciesMeta: + "@microsoft/api-extractor": + optional: true + "@swc/core": + optional: true + postcss: + optional: true + typescript: + optional: true + bin: + tsup: dist/cli-default.js + tsup-node: dist/cli-node.js + checksum: 5d7083f777fc480fd085ab9060e4223e753f261cbfc87ee284b151f5ccc540b9de8e7792654982e8962d8c5f82c6486cd066754e78984cc761e027c560b81d73 + languageName: node + linkType: hard + +"typedoc@npm:^0.25.7": + version: 0.25.13 + resolution: "typedoc@npm:0.25.13" + dependencies: + lunr: ^2.3.9 + marked: ^4.3.0 + minimatch: ^9.0.3 + shiki: ^0.14.7 + peerDependencies: + typescript: 4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x + bin: + typedoc: bin/typedoc + checksum: 703d1f48137300b0ef3df1998a25ae745db3ca0b126f8dd1f7262918f11243a94d24dfc916cdba2baeb5a7d85d5a94faac811caf7f4fa6b7d07144dc02f7639f + languageName: node + linkType: hard + +"typescript@npm:*": + version: 5.8.3 + resolution: "typescript@npm:5.8.3" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: cb1d081c889a288b962d3c8ae18d337ad6ee88a8e81ae0103fa1fecbe923737f3ba1dbdb3e6d8b776c72bc73bfa6d8d850c0306eed1a51377d2fccdfd75d92c4 + languageName: node + linkType: hard + +"typescript@patch:typescript@*#~builtin": + version: 5.8.3 + resolution: "typescript@patch:typescript@npm%3A5.8.3#~builtin::version=5.8.3&hash=85af82" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 1b503525a88ff0ff5952e95870971c4fb2118c17364d60302c21935dedcd6c37e6a0a692f350892bafcef6f4a16d09073fe461158547978d2f16fbe4cb18581c + languageName: node + linkType: hard + +"ufo@npm:^1.5.4": + version: 1.6.1 + resolution: "ufo@npm:1.6.1" + checksum: 2c401dd45bd98ad00806e044aa8571aa2aa1762fffeae5e78c353192b257ef2c638159789f119e5d8d5e5200e34228cd1bbde871a8f7805de25daa8576fb1633 + languageName: node + linkType: hard + +"undici-types@npm:~7.8.0": + version: 7.8.0 + resolution: "undici-types@npm:7.8.0" + checksum: 59521a5b9b50e72cb838a29466b3557b4eacbc191a83f4df5a2f7b156bc8263072b145dc4bb8ec41da7d56a7e9b178892458da02af769243d57f801a50ac5751 + languageName: node + linkType: hard + +"unique-filename@npm:^4.0.0": + version: 4.0.0 + resolution: "unique-filename@npm:4.0.0" + dependencies: + unique-slug: ^5.0.0 + checksum: 6a62094fcac286b9ec39edbd1f8f64ff92383baa430af303dfed1ffda5e47a08a6b316408554abfddd9730c78b6106bef4ca4d02c1231a735ddd56ced77573df + languageName: node + linkType: hard + +"unique-slug@npm:^5.0.0": + version: 5.0.0 + resolution: "unique-slug@npm:5.0.0" + dependencies: + imurmurhash: ^0.1.4 + checksum: 222d0322bc7bbf6e45c08967863212398313ef73423f4125e075f893a02405a5ffdbaaf150f7dd1e99f8861348a486dd079186d27c5f2c60e465b7dcbb1d3e5b + languageName: node + linkType: hard + +"utf-8-validate@npm:^5.0.2": + version: 5.0.10 + resolution: "utf-8-validate@npm:5.0.10" + dependencies: + node-gyp: latest + node-gyp-build: ^4.3.0 + checksum: 5579350a023c66a2326752b6c8804cc7b39dcd251bb088241da38db994b8d78352e388dcc24ad398ab98385ba3c5ffcadb6b5b14b2637e43f767869055e46ba6 + languageName: node + linkType: hard + +"util@npm:^0.12.5": + version: 0.12.5 + resolution: "util@npm:0.12.5" + dependencies: + inherits: ^2.0.3 + is-arguments: ^1.0.4 + is-generator-function: ^1.0.7 + is-typed-array: ^1.1.3 + which-typed-array: ^1.1.2 + checksum: 705e51f0de5b446f4edec10739752ac25856541e0254ea1e7e45e5b9f9b0cb105bc4bd415736a6210edc68245a7f903bf085ffb08dd7deb8a0e847f60538a38a + languageName: node + linkType: hard + +"uuid@npm:^8.3.2": + version: 8.3.2 + resolution: "uuid@npm:8.3.2" + bin: + uuid: dist/bin/uuid + checksum: 5575a8a75c13120e2f10e6ddc801b2c7ed7d8f3c8ac22c7ed0c7b2ba6383ec0abda88c905085d630e251719e0777045ae3236f04c812184b7c765f63a70e58df + languageName: node + linkType: hard + +"vscode-oniguruma@npm:^1.7.0": + version: 1.7.0 + resolution: "vscode-oniguruma@npm:1.7.0" + checksum: 53519d91d90593e6fb080260892e87d447e9b200c4964d766772b5053f5699066539d92100f77f1302c91e8fc5d9c772fbe40fe4c90f3d411a96d5a9b1e63f42 + languageName: node + linkType: hard + +"vscode-textmate@npm:^8.0.0": + version: 8.0.0 + resolution: "vscode-textmate@npm:8.0.0" + checksum: 127780dfea89559d70b8326df6ec344cfd701312dd7f3f591a718693812b7852c30b6715e3cfc8b3200a4e2515b4c96f0843c0eacc0a3020969b5de262c2a4bb + languageName: node + linkType: hard + +"webidl-conversions@npm:^3.0.0": + version: 3.0.1 + resolution: "webidl-conversions@npm:3.0.1" + checksum: c92a0a6ab95314bde9c32e1d0a6dfac83b578f8fa5f21e675bc2706ed6981bc26b7eb7e6a1fab158e5ce4adf9caa4a0aee49a52505d4d13c7be545f15021b17c + languageName: node + linkType: hard + +"webidl-conversions@npm:^4.0.2": + version: 4.0.2 + resolution: "webidl-conversions@npm:4.0.2" + checksum: c93d8dfe908a0140a4ae9c0ebc87a33805b416a33ee638a605b551523eec94a9632165e54632f6d57a39c5f948c4bab10e0e066525e9a4b87a79f0d04fbca374 + languageName: node + linkType: hard + +"whatwg-url@npm:^5.0.0": + version: 5.0.0 + resolution: "whatwg-url@npm:5.0.0" + dependencies: + tr46: ~0.0.3 + webidl-conversions: ^3.0.0 + checksum: b8daed4ad3356cc4899048a15b2c143a9aed0dfae1f611ebd55073310c7b910f522ad75d727346ad64203d7e6c79ef25eafd465f4d12775ca44b90fa82ed9e2c + languageName: node + linkType: hard + +"whatwg-url@npm:^7.0.0": + version: 7.1.0 + resolution: "whatwg-url@npm:7.1.0" + dependencies: + lodash.sortby: ^4.7.0 + tr46: ^1.0.1 + webidl-conversions: ^4.0.2 + checksum: fecb07c87290b47d2ec2fb6d6ca26daad3c9e211e0e531dd7566e7ff95b5b3525a57d4f32640ad4adf057717e0c215731db842ad761e61d947e81010e05cf5fd + languageName: node + linkType: hard + +"which-typed-array@npm:^1.1.16, which-typed-array@npm:^1.1.2": + version: 1.1.19 + resolution: "which-typed-array@npm:1.1.19" + dependencies: + available-typed-arrays: ^1.0.7 + call-bind: ^1.0.8 + call-bound: ^1.0.4 + for-each: ^0.3.5 + get-proto: ^1.0.1 + gopd: ^1.2.0 + has-tostringtag: ^1.0.2 + checksum: 162d2a07f68ea323f88ed9419861487ce5d02cb876f2cf9dd1e428d04a63133f93a54f89308f337b27cabd312ee3d027cae4a79002b2f0a85b79b9ef4c190670 + languageName: node + linkType: hard + +"which@npm:^2.0.1": + version: 2.0.2 + resolution: "which@npm:2.0.2" + dependencies: + isexe: ^2.0.0 + bin: + node-which: ./bin/node-which + checksum: 1a5c563d3c1b52d5f893c8b61afe11abc3bab4afac492e8da5bde69d550de701cf9806235f20a47b5c8fa8a1d6a9135841de2596535e998027a54589000e66d1 + languageName: node + linkType: hard + +"which@npm:^5.0.0": + version: 5.0.0 + resolution: "which@npm:5.0.0" + dependencies: + isexe: ^3.1.1 + bin: + node-which: bin/which.js + checksum: 6ec99e89ba32c7e748b8a3144e64bfc74aa63e2b2eacbb61a0060ad0b961eb1a632b08fb1de067ed59b002cec3e21de18299216ebf2325ef0f78e0f121e14e90 + languageName: node + linkType: hard + +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version: 7.0.0 + resolution: "wrap-ansi@npm:7.0.0" + dependencies: + ansi-styles: ^4.0.0 + string-width: ^4.1.0 + strip-ansi: ^6.0.0 + checksum: a790b846fd4505de962ba728a21aaeda189b8ee1c7568ca5e817d85930e06ef8d1689d49dbf0e881e8ef84436af3a88bc49115c2e2788d841ff1b8b5b51a608b + languageName: node + linkType: hard + +"wrap-ansi@npm:^8.1.0": + version: 8.1.0 + resolution: "wrap-ansi@npm:8.1.0" + dependencies: + ansi-styles: ^6.1.0 + string-width: ^5.0.1 + strip-ansi: ^7.0.1 + checksum: 371733296dc2d616900ce15a0049dca0ef67597d6394c57347ba334393599e800bab03c41d4d45221b6bc967b8c453ec3ae4749eff3894202d16800fdfe0e238 + languageName: node + linkType: hard + +"ws@npm:^7.4.5": + version: 7.5.9 + resolution: "ws@npm:7.5.9" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: c3c100a181b731f40b7f2fddf004aa023f79d64f489706a28bc23ff88e87f6a64b3c6651fbec3a84a53960b75159574d7a7385709847a62ddb7ad6af76f49138 + languageName: node + linkType: hard + +"ws@npm:^7.5.10": + version: 7.5.10 + resolution: "ws@npm:7.5.10" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: f9bb062abf54cc8f02d94ca86dcd349c3945d63851f5d07a3a61c2fcb755b15a88e943a63cf580cbdb5b74436d67ef6b67f745b8f7c0814e411379138e1863cb + languageName: node + linkType: hard + +"ws@npm:^8.5.0": + version: 8.11.0 + resolution: "ws@npm:8.11.0" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 316b33aba32f317cd217df66dbfc5b281a2f09ff36815de222bc859e3424d83766d9eb2bd4d667de658b6ab7be151f258318fb1da812416b30be13103e5b5c67 + languageName: node + linkType: hard + +"yallist@npm:^4.0.0": + version: 4.0.0 + resolution: "yallist@npm:4.0.0" + checksum: 343617202af32df2a15a3be36a5a8c0c8545208f3d3dfbc6bb7c3e3b7e8c6f8e7485432e4f3b88da3031a6e20afa7c711eded32ddfb122896ac5d914e75848d5 + languageName: node + linkType: hard + +"yallist@npm:^5.0.0": + version: 5.0.0 + resolution: "yallist@npm:5.0.0" + checksum: eba51182400b9f35b017daa7f419f434424410691bbc5de4f4240cc830fdef906b504424992700dc047f16b4d99100a6f8b8b11175c193f38008e9c96322b6a5 + languageName: node + linkType: hard diff --git a/summary.md b/summary.md new file mode 100644 index 0000000..1a2bfdc --- /dev/null +++ b/summary.md @@ -0,0 +1,204 @@ +# Policy Account Architecture Design Problem + +## Context + +The Squads Smart Account Program is implementing a unified policy framework where different types of policies (spending limits, program interactions, internal fund transfers, etc.) can be executed through a common consensus mechanism. The goal is to make policy execution as idiomatic and extensible as possible. + +## Current Architecture + +### Existing Structure +The current implementation uses a single `Policy` account with an enum-based approach: + +```rust +#[account] +pub struct Policy { + // Common consensus fields (90% shared across all policy types) + pub settings: Pubkey, + pub transaction_index: u64, + pub stale_transaction_index: u64, + pub signers: Vec, + pub threshold: u16, + pub time_lock: u32, + pub vault_scopes: Vec, + + // Policy type identification + pub policy_type: PolicyType, +} + +#[derive(AnchorSerialize, AnchorDeserialize, Clone)] +pub enum PolicyType { + InternalFundTransfer(InternalFundTransferPolicy), + SpendingLimit(SpendingLimitPolicy), + // Future policy types... +} +``` + +### Current Execution Flow +1. **Transaction Creation**: `CreateTransactionArgs` enum handles both `TransactionPayload` (for settings) and `PolicyPayload` (for policies) +2. **Transaction Execution**: Pattern matching on `transaction.payload` type in `transaction_execute.rs` +3. **Policy Dispatch**: Manual pattern matching on policy type with incomplete execution logic + +### ConsensusAccount Trait +All consensus accounts (Settings and Policies) implement a unified `Consensus` trait that provides: +- Signer management (`signers()`, `is_signer()`, `signer_has_permission()`) +- Transaction indexing (`transaction_index()`, `set_transaction_index()`) +- Threshold and timelock management +- Stale transaction protection + +Instructions use `InterfaceAccount<'info, ConsensusAccount>` to work with any consensus account type uniformly. + +## The Problem + +### Current Issues +1. **Inconsistent Execution Pattern**: Each policy type requires manual pattern matching in execution logic +2. **Unused Abstractions**: `PolicyExecution` trait exists but isn't properly utilized +3. **Ad-hoc Dispatch**: `PolicyPayload::execute()` manually dispatches to policy implementations +4. **Maintenance Burden**: Adding new policy types requires changes to multiple match statements +5. **State Management Complexity**: Policy-specific data is embedded in enums, making field access verbose + +### Core Dilemma +The fundamental tension is between: +- **Type Safety & Performance**: Direct field access (`policy.field = value`) with compile-time guarantees +- **Unified Interface**: Single account type that works with `InterfaceAccount<'info, ConsensusAccount>` +- **Code Reuse**: Avoiding duplication of the 90% shared consensus fields across policy types + +## Explored Solutions + +### Option 1: Composition with Serialized Data +```rust +#[account] +pub struct Policy { + // Common consensus fields + pub settings: Pubkey, + pub transaction_index: u64, + // ... other consensus fields + + pub policy_discriminator: u8, + pub policy_data: Vec, // Serialized policy-specific data +} +``` + +**Pros**: Zero duplication, unified interface +**Cons**: Serialization overhead for every state change, loss of type safety + +### Option 2: Macro-Generated Separate Types +```rust +macro_rules! policy_account { + ($name:ident { $(pub $field:ident: $type:ty,)* }) => { + #[account] + pub struct $name { + // Auto-generated consensus fields + pub settings: Pubkey, + pub transaction_index: u64, + // ... + + // Policy-specific fields + $(pub $field: $type,)* + } + }; +} +``` + +**Pros**: Zero runtime overhead, full type safety, direct field access +**Cons**: Breaks `InterfaceAccount<'info, ConsensusAccount>` - multiple distinct types can't be treated uniformly + +### Option 3: Composition with Embedded Struct +```rust +#[derive(AnchorSerialize, AnchorDeserialize)] +pub struct PolicyConsensus { + pub settings: Pubkey, + pub transaction_index: u64, + // ... consensus fields +} + +#[account] +pub struct InternalFundTransferPolicy { + pub consensus: PolicyConsensus, + pub source_account_indices: Vec, + // ... policy-specific fields +} +``` + +**Pros**: Direct field access, type safety, minimal duplication +**Cons**: Still breaks unified interface, requires trait delegation boilerplate + +### Option 4: Enum for Interface with Separate Types +```rust +pub enum ConsensusAccountData { + Settings(Settings), + InternalFundTransferPolicy(InternalFundTransferPolicy), + SpendingLimitPolicy(SpendingLimitPolicy), +} + +impl ConsensusAccount for ConsensusAccountData { + fn signers(&self) -> &[PolicySigner] { + match self { + ConsensusAccountData::Settings(s) => &s.signers, + ConsensusAccountData::InternalFundTransferPolicy(p) => &p.consensus.signers, + // ... pattern match for each type + } + } +} +``` + +**Pros**: Maintains unified interface, type-safe field access +**Cons**: Method delegation boilerplate for every consensus method on every policy type + +## Core Architectural Constraints + +### Anchor Framework Limitations +- `InterfaceAccount<'info, T>` requires a single trait object type +- Account types must be known at compile time for space allocation +- Serialization format is fixed per account type + +### Performance Requirements +- State changes should be direct field assignments, not serialize/deserialize cycles +- Consensus operations (voting, execution) happen frequently and must be efficient + +### Extensibility Goals +- Adding new policy types should require minimal changes to existing code +- Policy execution should be pluggable and uniform +- Each policy should own its specific logic and data + +## Key Questions for Resolution + +1. **Interface vs Type Safety**: Is it acceptable to break the unified `InterfaceAccount` interface to gain type safety and performance? + +2. **Code Generation**: Are macros an acceptable solution for eliminating boilerplate, or do they introduce too much complexity? + +3. **Runtime Dispatch**: Is the performance cost of serialization/deserialization acceptable for the benefits of a unified interface? + +4. **Trait Delegation**: Is repetitive trait implementation across policy types an acceptable trade-off for direct field access? + +5. **Alternative Architectures**: Are there Rust/Anchor patterns we haven't considered that could solve this trilemma? + +## Success Criteria + +The ideal solution should provide: +- **Ergonomic state management**: `policy.field = value` level simplicity +- **Type safety**: Compile-time guarantees for policy-specific fields +- **Unified interface**: Works with existing consensus trait and instruction patterns +- **Zero/minimal duplication**: Don't repeat the 90% shared consensus logic +- **Extensibility**: Adding new policies requires only implementing policy-specific logic +- **Performance**: No unnecessary serialization overhead for state changes + +## Policy Types Context + +### Current Policy Types +- **InternalFundTransfer**: Transfer funds between smart account vaults +- **SpendingLimit**: Token spending limits with time constraints and usage tracking +- **ProgramInteraction**: Constrained program calls with instruction/data validation + +### Policy Execution Pattern +All policies follow the pattern: +1. Receive a policy-specific payload (execution parameters) +2. Validate the payload against policy constraints +3. Execute the action using provided `remaining_accounts` +4. Update policy state (usage tracking, etc.) + +### Consensus Integration +Policies implement the same consensus mechanism as Settings: +- Multi-signature approval with configurable thresholds +- Time locks between approval and execution +- Stale transaction protection when policy parameters change +- Permission-based access control (Initiate, Vote, Execute) \ No newline at end of file diff --git a/tests/fixtures/noop.so b/tests/fixtures/noop.so new file mode 100644 index 0000000..e250fa0 Binary files /dev/null and b/tests/fixtures/noop.so differ diff --git a/tests/index.ts b/tests/index.ts index 3f2a2f6..406bcc7 100644 --- a/tests/index.ts +++ b/tests/index.ts @@ -1,25 +1,34 @@ // The order of imports is the order the test suite will run in. import "./suites/program-config-init"; -import "./suites/examples/batch-sol-transfer"; -import "./suites/examples/create-mint"; -import "./suites/examples/immediate-execution"; -import "./suites/examples/spending-limits"; -import "./suites/examples/transaction-buffer"; -import "./suites/instructions/batchAccountsClose"; -import "./suites/instructions/cancelRealloc"; -import "./suites/instructions/settingsTransactionAccountsClose"; -import "./suites/instructions/settingsTransactionExecute"; -import "./suites/instructions/settingsTransactionSynchronous"; -import "./suites/instructions/smartAccountCreate"; -import "./suites/instructions/smartAccountSetArchivalAuthority"; -import "./suites/instructions/transactionBufferClose"; -import "./suites/instructions/transactionBufferCreate"; -import "./suites/instructions/transactionBufferExtend"; -import "./suites/instructions/batchTransactionAccountClose"; -import "./suites/instructions/transactionAccountsClose"; -import "./suites/instructions/transactionCreateFromBuffer"; -import "./suites/instructions/transactionSynchronous"; -import "./suites/smart-account-sdk"; +// import "./suites/examples/batch-sol-transfer"; +// import "./suites/examples/create-mint"; +// import "./suites/examples/immediate-execution"; +// import "./suites/examples/spending-limits"; +// import "./suites/examples/transaction-buffer"; +// import "./suites/instructions/batchAccountsClose"; +// import "./suites/instructions/cancelRealloc"; +// import "./suites/instructions/settingsTransactionAccountsClose"; +// import "./suites/instructions/settingsTransactionExecute"; +// import "./suites/instructions/settingsTransactionSynchronous"; +// import "./suites/instructions/smartAccountCreate"; +// import "./suites/instructions/smartAccountSetArchivalAuthority"; +// import "./suites/instructions/transactionBufferClose"; +// import "./suites/instructions/transactionBufferCreate"; +// import "./suites/instructions/transactionBufferExtend"; +// import "./suites/instructions/batchTransactionAccountClose"; +// import "./suites/instructions/transactionAccountsClose"; +// import "./suites/instructions/transactionCreateFromBuffer"; +// import "./suites/instructions/transactionSynchronous"; +// import "./suites/instructions/logEvent"; +// import "./suites/instructions/policyCreation"; +// import "./suites/instructions/policyUpdate"; +// import "./suites/instructions/removePolicy"; +// import "./suites/instructions/policyExpiration"; +// import "./suites/instructions/settingsChangePolicy"; +import "./suites/instructions/programInteractionPolicy"; +// import "./suites/instructions/spendingLimitPolicy"; +// import "./suites/instructions/internalFundTransferPolicy"; +// import "./suites/smart-account-sdk"; // // // Uncomment to enable the heapTest instruction testing // // //import "./suites/instructions/heapTest"; // // import "./suites/examples/custom-heap"; diff --git a/tests/suites/examples/custom-heap.ts b/tests/suites/examples/custom-heap.ts deleted file mode 100644 index 68ed342..0000000 --- a/tests/suites/examples/custom-heap.ts +++ /dev/null @@ -1,324 +0,0 @@ -import { - ComputeBudgetProgram, - Keypair, - LAMPORTS_PER_SOL, - PublicKey, - SystemProgram, - Transaction, - TransactionMessage, - VersionedTransaction, -} from "@solana/web3.js"; -import * as smartAccount from "@sqds/smart-account"; -import { - CreateTransactionArgs, - CreateTransactionBufferArgs, - CreateTransactionBufferInstructionArgs, - CreateTransactionFromBufferInstructionArgs, -} from "@sqds/smart-account/lib/generated"; -import assert from "assert"; -import { BN } from "bn.js"; -import * as crypto from "crypto"; -import { - TestMembers, - createAutonomousSmartAccountV2, - createLocalhostConnection, - createTestTransferInstruction, - generateSmartAccountSigners, - getTestProgramId, - processBufferInChunks, -} from "../../utils"; - -const programId = getTestProgramId(); -const connection = createLocalhostConnection(); - -describe("Examples / Custom Heap Usage", () => { - let members: TestMembers; - - const createKey = Keypair.generate(); - - let settingsPda: PublicKey; - let vaultPda: PublicKey; - - // Set up a smart account with some transactions. - before(async () => { - members = await generateSmartAccountSigners(connection); - - // Create new autonomous smart account with rentCollector set to its default vault. - await createAutonomousSmartAccountV2({ - connection, - members, - threshold: 1, - timeLock: 0, - rentCollector: vaultPda, - programId, - }); - - // Airdrop some SOL to the vault - let signature = await connection.requestAirdrop( - vaultPda, - 10 * LAMPORTS_PER_SOL - ); - await connection.confirmTransaction(signature); - }); - - // We expect this to succeed when requesting extra heap. - it("execute large transaction (custom heap)", async () => { - const transactionIndex = 1n; - - const testIx = await createTestTransferInstruction(vaultPda, vaultPda, 1); - - let instructions = []; - - // Add 64 transfer instructions to the message. - for (let i = 0; i <= 59; i++) { - instructions.push(testIx); - } - - const testTransferMessage = new TransactionMessage({ - payerKey: vaultPda, - recentBlockhash: (await connection.getLatestBlockhash()).blockhash, - instructions: instructions, - }); - - //region Create & Upload Buffer - // Serialize the message. Must be done with this util function - const messageBuffer = - smartAccount.utils.transactionMessageToMultisigTransactionMessageBytes({ - message: testTransferMessage, - addressLookupTableAccounts: [], - smartAccountPda: vaultPda, - }); - - const [transactionBuffer, _] = PublicKey.findProgramAddressSync( - [ - Buffer.from("smart_account"), - settingsPda.toBuffer(), - Buffer.from("transaction_buffer"), - new BN(Number(transactionIndex)).toBuffer("le", 8), - ], - programId - ); - - const messageHash = crypto - .createHash("sha256") - .update(messageBuffer) - .digest(); - - // Slice the message buffer into two parts. - const firstSlice = messageBuffer.slice(0, 700); - const bufferLength = messageBuffer.length; - - const ix = smartAccount.generated.createCreateTransactionBufferInstruction( - { - settings: settingsPda, - transactionBuffer, - creator: members.proposer.publicKey, - rentPayer: members.proposer.publicKey, - systemProgram: SystemProgram.programId, - }, - { - args: { - accountIndex: 0, - // Must be a SHA256 hash of the message buffer. - finalBufferHash: Array.from(messageHash), - finalBufferSize: bufferLength, - buffer: firstSlice, - } as CreateTransactionBufferArgs, - } as CreateTransactionBufferInstructionArgs, - programId - ); - - const message = new TransactionMessage({ - payerKey: members.proposer.publicKey, - recentBlockhash: (await connection.getLatestBlockhash()).blockhash, - instructions: [ix], - }).compileToV0Message(); - - const tx = new VersionedTransaction(message); - tx.sign([members.proposer]); - - // Send first transaction. - const signature1 = await connection.sendRawTransaction(tx.serialize(), { - skipPreflight: true, - }); - await connection.confirmTransaction(signature1); - - const transactionBufferAccount = await connection.getAccountInfo( - transactionBuffer - ); - - const [txBufferDeser1] = - smartAccount.generated.TransactionBuffer.fromAccountInfo( - transactionBufferAccount! - ); - - // Check buffer account exists. - assert.notEqual(transactionBufferAccount, null); - assert.ok(transactionBufferAccount?.data.length! > 0); - - // First chunk uploaded. Check that length is as expected. - assert.equal(txBufferDeser1.buffer.length, 700); - - // Process the buffer in <=700 byte chunks. - await processBufferInChunks( - members.proposer as Keypair, - settingsPda, - transactionBuffer, - messageBuffer, - connection, - programId, - 700, - 700 - ); - - // Get account info and deserialize to run checks. - const transactionBufferInfo2 = await connection.getAccountInfo( - transactionBuffer - ); - const [txBufferDeser2] = - smartAccount.generated.TransactionBuffer.fromAccountInfo( - transactionBufferInfo2! - ); - - // Final chunk uploaded. Check that length is as expected. - assert.equal(txBufferDeser2.buffer.length, messageBuffer.byteLength); - - // Derive transaction PDA. - const [transactionPda] = smartAccount.getTransactionPda({ - settingsPda, - transactionIndex: transactionIndex, - programId, - }); - //endregion - - //region Create Transaction From Buffer - // Create final instruction. - const thirdIx = - smartAccount.generated.createCreateTransactionFromBufferInstruction( - { - transactionCreateItemSettings: settingsPda, - transactionCreateItemTransaction: transactionPda, - transactionCreateItemCreator: members.proposer.publicKey, - transactionCreateItemRentPayer: members.proposer.publicKey, - transactionCreateItemSystemProgram: SystemProgram.programId, - transactionBuffer, - creator: members.proposer.publicKey, - }, - { - args: { - ephemeralSigners: 0, - memo: null, - } as CreateTransactionArgs, - } as CreateTransactionFromBufferInstructionArgs, - programId - ); - - // Request heap memory - const prelimHeap = ComputeBudgetProgram.requestHeapFrame({ - bytes: 8 * 32 * 1024, - }); - - const prelimHeapCU = ComputeBudgetProgram.setComputeUnitLimit({ - units: 1_400_000, - }); - - const bufferConvertMessage = new TransactionMessage({ - payerKey: members.proposer.publicKey, - recentBlockhash: (await connection.getLatestBlockhash()).blockhash, - instructions: [prelimHeap, prelimHeapCU, thirdIx], - }).compileToV0Message(); - - const bufferConvertTx = new VersionedTransaction(bufferConvertMessage); - - bufferConvertTx.sign([members.proposer]); - - // Send buffer conversion transaction. - const signature3 = await connection.sendRawTransaction( - bufferConvertTx.serialize(), - { - skipPreflight: true, - } - ); - await connection.confirmTransaction(signature3); - - const transactionInfo = - await smartAccount.accounts.Transaction.fromAccountAddress( - connection, - transactionPda - ); - - // Ensure final transaction has 60 instructions - assert.equal(transactionInfo.message.instructions.length, 60); - //endregion - - //region Create, Vote, and Execute - // Create a proposal for the newly uploaded transaction. - const signature4 = await smartAccount.rpc.createProposal({ - connection, - feePayer: members.almighty, - settingsPda, - transactionIndex: 1n, - creator: members.almighty, - isDraft: false, - programId, - }); - await connection.confirmTransaction(signature4); - - // Approve the proposal. - const signature5 = await smartAccount.rpc.approveProposal({ - connection, - feePayer: members.almighty, - settingsPda, - transactionIndex: 1n, - signer: members.almighty, - programId, - }); - await connection.confirmTransaction(signature5); - - // Execute the transaction. - const executeIx = await smartAccount.instructions.executeTransaction({ - connection, - settingsPda, - transactionIndex: 1n, - signer: members.almighty.publicKey, - programId, - }); - - // Request heap for execution (it's very much needed here). - const computeBudgetIx = ComputeBudgetProgram.requestHeapFrame({ - bytes: 8 * 32 * 1024, - }); - - const computeBudgetCUIx = ComputeBudgetProgram.setComputeUnitLimit({ - units: 1_400_000, - }); - - const executeTx = new Transaction().add( - computeBudgetIx, - computeBudgetCUIx, - executeIx.instruction - ); - const signature6 = await connection.sendTransaction( - executeTx, - [members.almighty], - { skipPreflight: true } - ); - - await connection.confirmTransaction(signature6); - - const proposal = await smartAccount.getProposalPda({ - settingsPda, - transactionIndex: 1n, - programId, - })[0]; - - const proposalInfo = - await smartAccount.accounts.Proposal.fromAccountAddress( - connection, - proposal - ); - - assert.equal(proposalInfo.status.__kind, "Executed"); - //endregion - }); -}); diff --git a/tests/suites/examples/transaction-buffer.ts b/tests/suites/examples/transaction-buffer.ts index 99eebb8..95dcdfd 100644 --- a/tests/suites/examples/transaction-buffer.ts +++ b/tests/suites/examples/transaction-buffer.ts @@ -1,5 +1,6 @@ import { AccountMeta, + ComputeBudgetProgram, Keypair, LAMPORTS_PER_SOL, PublicKey, @@ -16,6 +17,7 @@ import { CreateTransactionFromBufferInstructionArgs, ExtendTransactionBufferArgs, ExtendTransactionBufferInstructionArgs, + TransactionPayloadDetails, } from "@sqds/smart-account/lib/generated"; import assert from "assert"; import * as crypto from "crypto"; @@ -24,6 +26,7 @@ import { createAutonomousSmartAccountV2, createLocalhostConnection, createTestTransferInstruction, + extractTransactionPayloadDetails, generateSmartAccountSigners, getNextAccountIndex, getTestProgramId, @@ -106,26 +109,27 @@ describe("Examples / Transaction Buffers", () => { const messageHash = crypto .createHash("sha256") - .update(messageBuffer) + .update(messageBuffer.transactionMessageBytes) .digest(); // Slice the message buffer into two parts. - const firstSlice = messageBuffer.slice(0, 400); + const firstSlice = messageBuffer.transactionMessageBytes.slice(0, 400); const ix = smartAccount.generated.createCreateTransactionBufferInstruction( { - settings: settingsPda, + consensusAccount: settingsPda, transactionBuffer, creator: members.almighty.publicKey, rentPayer: members.almighty.publicKey, }, { args: { + __kind: "TransactionPayload", accountIndex: 0, bufferIndex: 0, // Must be a SHA256 hash of the message buffer. finalBufferHash: Array.from(messageHash), - finalBufferSize: messageBuffer.length, + finalBufferSize: messageBuffer.transactionMessageBytes.byteLength, buffer: firstSlice, } as CreateTransactionBufferArgs, } as CreateTransactionBufferInstructionArgs, @@ -168,13 +172,16 @@ describe("Examples / Transaction Buffers", () => { // First chunk uploaded. Check that length is as expected. assert.equal(txBufferDeser1.buffer.length, 400); - const secondSlice = messageBuffer.slice(400, messageBuffer.byteLength); + const secondSlice = messageBuffer.transactionMessageBytes.slice( + 400, + messageBuffer.transactionMessageBytes.byteLength + ); // Extned the buffer. const secondIx = smartAccount.generated.createExtendTransactionBufferInstruction( { - settings: settingsPda, + consensusAccount: settingsPda, transactionBuffer, creator: members.almighty.publicKey, }, @@ -213,7 +220,10 @@ describe("Examples / Transaction Buffers", () => { ); // Full buffer uploaded. Check that length is as expected. - assert.equal(txBufferDeser2.buffer.length, messageBuffer.byteLength); + assert.equal( + txBufferDeser2.buffer.length, + messageBuffer.transactionMessageBytes.byteLength + ); // Derive transaction PDA. const [transactionPda] = smartAccount.getTransactionPda({ @@ -231,20 +241,26 @@ describe("Examples / Transaction Buffers", () => { const thirdIx = smartAccount.generated.createCreateTransactionFromBufferInstruction( { - transactionCreateItemSettings: settingsPda, + transactionCreateItemConsensusAccount: settingsPda, transactionCreateItemTransaction: transactionPda, transactionCreateItemCreator: members.almighty.publicKey, transactionCreateItemRentPayer: members.almighty.publicKey, transactionCreateItemSystemProgram: SystemProgram.programId, transactionBuffer: transactionBuffer, creator: members.almighty.publicKey, + transactionCreateItemProgram: programId, }, { args: { - accountIndex: 0, - transactionMessage: new Uint8Array(6).fill(0), - ephemeralSigners: 0, - memo: null, + __kind: "TransactionPayload", + fields: [ + { + accountIndex: 0, + transactionMessage: new Uint8Array(6).fill(0), + ephemeralSigners: 0, + memo: null, + }, + ], } as CreateTransactionArgs, } as CreateTransactionFromBufferInstructionArgs, programId @@ -275,7 +291,10 @@ describe("Examples / Transaction Buffers", () => { ); // Ensure final transaction has 23 instructions - assert.equal(transactionInfo.message.instructions.length, 23); + let transactionPayloadDetails = extractTransactionPayloadDetails( + transactionInfo.payload + ); + assert.equal(transactionPayloadDetails.message.instructions.length, 23); }); it("create proposal, approve, execute from buffer derived transaction", async () => { @@ -295,7 +314,10 @@ describe("Examples / Transaction Buffers", () => { ); // Check that we're dealing with the same account from last test. - assert.equal(transactionInfo.message.instructions.length, 23); + let transactionPayloadDetails = extractTransactionPayloadDetails( + transactionInfo.payload + ); + assert.equal(transactionPayloadDetails.message.instructions.length, 23); const [proposalPda] = smartAccount.getProposalPda({ settingsPda, @@ -339,7 +361,11 @@ describe("Examples / Transaction Buffers", () => { programId, }); - const tx = new Transaction().add(ix.instruction); + let heapFrameIx = ComputeBudgetProgram.requestHeapFrame({ + bytes: 256_000, + }); + + const tx = new Transaction().add(heapFrameIx).add(ix.instruction); const signature4 = await connection.sendTransaction( tx, [members.almighty], diff --git a/tests/suites/instructions/batchAccountsClose.ts b/tests/suites/instructions/batchAccountsClose.ts index 5fdb4a4..e6f2d72 100644 --- a/tests/suites/instructions/batchAccountsClose.ts +++ b/tests/suites/instructions/batchAccountsClose.ts @@ -284,6 +284,7 @@ describe("Instructions / batch_accounts_close", () => { transactionIndex: 1n, programId, })[0], + program: programId, }, programId ); diff --git a/tests/suites/instructions/heapTest.ts b/tests/suites/instructions/heapTest.ts deleted file mode 100644 index ec76d52..0000000 --- a/tests/suites/instructions/heapTest.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { - ComputeBudgetProgram, - Keypair, - LAMPORTS_PER_SOL, - TransactionMessage, - VersionedTransaction, -} from "@solana/web3.js"; -import * as smartAccount from "@sqds/smart-account"; -import { HeapTestInstructionArgs } from "@sqds/smart account/lib/generated"; -import { createLocalhostConnection, getTestProgramId } from "../../utils"; - -const programId = getTestProgramId(); -const connection = createLocalhostConnection(); - -describe("Instructions / transaction_buffer_close", () => { - it("heap test", async () => { - let keypair = Keypair.generate(); - // Request airdrop - let signature = await connection.requestAirdrop( - keypair.publicKey, - 10 * LAMPORTS_PER_SOL - ); - await connection.confirmTransaction(signature); - const createArgs: HeapTestInstructionArgs = { - length: 25000, - }; - const heapTestIx = smartAccount.generated.createHeapTestInstruction( - { - authority: keypair.publicKey, - }, - createArgs, - programId - ); - const computeBudgetIx = ComputeBudgetProgram.requestHeapFrame({ - bytes: 8 * 32 * 1024, - }); - const computeBudgetCUIx = ComputeBudgetProgram.setComputeUnitLimit({ - units: 1_400_000, - }); - // const heapTestMessage = new TransactionMessage({ - // payerKey: keypair.publicKey, - // recentBlockhash: (await connection.getLatestBlockhash()).blockhash, - // instructions: [computeBudgetIx, computeBudgetCUIx, heapTestIx], - // }).compileToV0Message(); - const heapTestMessage = new TransactionMessage({ - payerKey: keypair.publicKey, - recentBlockhash: (await connection.getLatestBlockhash()).blockhash, - instructions: [computeBudgetCUIx, heapTestIx], - }).compileToV0Message(); - const heapTestTx = new VersionedTransaction(heapTestMessage); - heapTestTx.sign([keypair]); - const heapTestSig = await connection.sendRawTransaction( - heapTestTx.serialize(), - { skipPreflight: true } - ); - console.log(heapTestSig); - await connection.confirmTransaction(heapTestSig); - }); -}); diff --git a/tests/suites/instructions/internalFundTransferPolicy.ts b/tests/suites/instructions/internalFundTransferPolicy.ts new file mode 100644 index 0000000..6a8b842 --- /dev/null +++ b/tests/suites/instructions/internalFundTransferPolicy.ts @@ -0,0 +1,524 @@ +import * as smartAccount from "@sqds/smart-account"; +import * as web3 from "@solana/web3.js"; +import assert from "assert"; +import { + createAutonomousMultisig, + createLocalhostConnection, + createMintAndTransferTo, + generateSmartAccountSigners, + getTestProgramId, + TestMembers, +} from "../../utils"; +import { AccountMeta } from "@solana/web3.js"; +import { getSmartAccountPda } from "@sqds/smart-account"; +import { + createAssociatedTokenAccount, + getAssociatedTokenAddressSync, + getOrCreateAssociatedTokenAccount, + TOKEN_PROGRAM_ID, +} from "@solana/spl-token"; +const { Settings, Proposal, Policy } = smartAccount.accounts; +const programId = getTestProgramId(); +const connection = createLocalhostConnection(); + +describe("Flow / InternalFundTransferPolicy", () => { + let members: TestMembers; + + before(async () => { + members = await generateSmartAccountSigners(connection); + }); + + it("create policy: InternalFundTransfer + SOL Transfer", async () => { + // Create new autonomous smart account with 1/1 threshold for easy testing + const settingsPda = ( + await createAutonomousMultisig({ + connection, + members, + threshold: 1, + timeLock: 0, + programId, + }) + )[0]; + + // Use seed 1 for the first policy on this smart account + const policySeed = 1; + + // Create policy creation payload + const policyCreationPayload: smartAccount.generated.PolicyCreationPayload = + { + __kind: "InternalFundTransfer", + fields: [ + { + sourceAccountIndices: new Uint8Array([0]), // Allow transfers from account indices 0 and 1 + destinationAccountIndices: new Uint8Array([1, 3]), // Allow transfers to account indices 2 and 3 + allowedMints: [web3.PublicKey.default], // Allow native SOL transfers + }, + ], + }; + + const transactionIndex = BigInt(1); + + const [policyPda] = smartAccount.getPolicyPda({ + settingsPda, + policySeed, + programId, + }); + // Create settings transaction with PolicyCreate action + let signature = await smartAccount.rpc.createSettingsTransaction({ + connection, + feePayer: members.proposer, + settingsPda, + transactionIndex, + creator: members.proposer.publicKey, + actions: [ + { + __kind: "PolicyCreate", + seed: policySeed, + policyCreationPayload, + signers: [ + { + key: members.voter.publicKey, + permissions: { mask: 7 }, + }, + ], + threshold: 1, + timeLock: 0, + startTimestamp: null, + expirationArgs: null, + }, + ], + programId, + }); + await connection.confirmTransaction(signature); + + // Create proposal for the transaction + signature = await smartAccount.rpc.createProposal({ + connection, + feePayer: members.proposer, + settingsPda, + transactionIndex, + creator: members.proposer, + programId, + }); + await connection.confirmTransaction(signature); + + // Approve the proposal (1/1 threshold) + signature = await smartAccount.rpc.approveProposal({ + connection, + feePayer: members.voter, + settingsPda, + transactionIndex, + signer: members.voter, + programId, + }); + await connection.confirmTransaction(signature); + + // Execute the settings transaction + signature = await smartAccount.rpc.executeSettingsTransaction({ + connection, + feePayer: members.almighty, + settingsPda, + transactionIndex, + signer: members.almighty, + rentPayer: members.almighty, + policies: [policyPda], + programId, + }); + await connection.confirmTransaction(signature); + + const policyAccount = await Policy.fromAccountAddress( + connection, + policyPda + ); + assert.strictEqual( + policyAccount.settings.toString(), + settingsPda.toString() + ); + assert.strictEqual(policyAccount.threshold, 1); + assert.strictEqual(policyAccount.timeLock, 0); + + // Try transfer SOL via creating a transaction and proposal + const policyTransactionIndex = BigInt(1); + + const policyPayload: smartAccount.generated.PolicyPayload = { + __kind: "InternalFundTransfer", + fields: [ + { + sourceIndex: 0, + destinationIndex: 1, + mint: web3.PublicKey.default, + decimals: 9, + // 1 SOL + amount: 1_000_000_000, + }, + ], + }; + // Create a transaction + signature = await smartAccount.rpc.createPolicyTransaction({ + connection, + feePayer: members.voter, + policy: policyPda, + accountIndex: 0, + transactionIndex: policyTransactionIndex, + creator: members.voter.publicKey, + policyPayload, + sendOptions: { + skipPreflight: true, + }, + programId, + }); + await connection.confirmTransaction(signature); + // Create proposal for the transaction + signature = await smartAccount.rpc.createProposal({ + connection, + feePayer: members.voter, + settingsPda: policyPda, + transactionIndex: policyTransactionIndex, + creator: members.voter, + programId, + }); + await connection.confirmTransaction(signature); + + // Approve the proposal (1/1 threshold) + signature = await smartAccount.rpc.approveProposal({ + connection, + feePayer: members.voter, + settingsPda: policyPda, + transactionIndex: policyTransactionIndex, + signer: members.voter, + programId, + }); + await connection.confirmTransaction(signature); + + let remainingAccounts: AccountMeta[] = []; + let [sourceSmartAccountPda] = await getSmartAccountPda({ + settingsPda, + accountIndex: 0, + programId, + }); + let [destinationSmartAccountPda] = await getSmartAccountPda({ + settingsPda, + accountIndex: 1, + programId, + }); + remainingAccounts.push({ + pubkey: sourceSmartAccountPda, + isWritable: true, + isSigner: false, + }); + remainingAccounts.push({ + pubkey: destinationSmartAccountPda, + isWritable: true, + isSigner: false, + }); + remainingAccounts.push({ + pubkey: web3.SystemProgram.programId, + isWritable: false, + isSigner: false, + }); + // Airdrop SOL to the source smart account + let airdropSignature = await connection.requestAirdrop( + sourceSmartAccountPda, + 2_000_000_000 + ); + await connection.confirmTransaction(airdropSignature); + + // Execute the transaction + signature = await smartAccount.rpc.executePolicyTransaction({ + connection, + feePayer: members.voter, + policy: policyPda, + transactionIndex: policyTransactionIndex, + signer: members.voter.publicKey, + anchorRemainingAccounts: remainingAccounts, + sendOptions: { + skipPreflight: true, + }, + programId, + }); + await connection.confirmTransaction(signature); + + // Check the balances + let sourceBalance = await connection.getBalance(sourceSmartAccountPda); + let destinationBalance = await connection.getBalance( + destinationSmartAccountPda + ); + assert.strictEqual(sourceBalance, 1_000_000_000); + assert.strictEqual(destinationBalance, 1_000_000_000); + + // Sync instruction expects the voter to be a part of the remaining accounts + let syncRemainingAccounts = remainingAccounts; + syncRemainingAccounts.unshift({ + pubkey: members.voter.publicKey, + isWritable: false, + isSigner: true, + }); + // Attempt to do the same with a synchronous instruction + signature = await smartAccount.rpc.executePolicyPayloadSync({ + connection, + feePayer: members.voter, + policy: policyPda, + accountIndex: 0, + numSigners: 1, + policyPayload: policyPayload, + instruction_accounts: syncRemainingAccounts, + signers: [members.voter], + programId, + }); + await connection.confirmTransaction(signature); + + // Check the balances + sourceBalance = await connection.getBalance(sourceSmartAccountPda); + destinationBalance = await connection.getBalance( + destinationSmartAccountPda + ); + assert.strictEqual(sourceBalance, 0); + assert.strictEqual(destinationBalance, 2_000_000_000); + + let invalidPayload: smartAccount.generated.PolicyPayload = { + __kind: "InternalFundTransfer", + fields: [ + { + // Invalid source index + sourceIndex: 1, + destinationIndex: 1, + mint: web3.PublicKey.default, + decimals: 9, + amount: 1_000_000_000, + }, + ], + }; + assert.rejects( + smartAccount.rpc.executePolicyPayloadSync({ + connection, + feePayer: members.voter, + policy: policyPda, + accountIndex: 0, + numSigners: 1, + policyPayload: invalidPayload, + instruction_accounts: syncRemainingAccounts, + signers: [members.voter], + programId, + }) + ); + }); + + it("InternalFundTransfer + SPL Token Transfer", async () => { + // Create new autonomous smart account with 1/1 threshold for easy testing + const settingsPda = ( + await createAutonomousMultisig({ + connection, + members, + threshold: 1, + timeLock: 0, + programId, + }) + )[0]; + + // Use seed 1 for the first policy on this smart account + const policySeed = 1; + + // Create a mint and transfer tokens to the source smart account + let [sourceSmartAccountPda] = getSmartAccountPda({ + settingsPda, + accountIndex: 0, + programId, + }); + let [destinationSmartAccountPda] = getSmartAccountPda({ + settingsPda, + accountIndex: 1, + programId, + }); + const [mint, mintDecimals] = await createMintAndTransferTo( + connection, + members.voter, + sourceSmartAccountPda, + 1_000_000_000 + ); + + // Create policy creation payload + const policyCreationPayload: smartAccount.generated.PolicyCreationPayload = + { + __kind: "InternalFundTransfer", + fields: [ + { + sourceAccountIndices: new Uint8Array([0]), // Allow transfers from account indices 0 and 1 + destinationAccountIndices: new Uint8Array([1, 3]), // Allow transfers to account indices 2 and 3 + allowedMints: [mint], // Allow native SOL transfers + }, + ], + }; + + const transactionIndex = BigInt(1); + + const [policyPda] = smartAccount.getPolicyPda({ + settingsPda, + policySeed, + programId, + }); + + // Create settings transaction with PolicyCreate action + let signature = await smartAccount.rpc.createSettingsTransaction({ + connection, + feePayer: members.proposer, + settingsPda, + transactionIndex, + creator: members.proposer.publicKey, + actions: [ + { + __kind: "PolicyCreate", + seed: policySeed, + policyCreationPayload, + signers: [ + { + key: members.voter.publicKey, + permissions: { mask: 7 }, + }, + ], + threshold: 1, + timeLock: 0, + startTimestamp: null, + expirationArgs: null, + }, + ], + programId, + }); + await connection.confirmTransaction(signature); + + // Create proposal for the transaction + signature = await smartAccount.rpc.createProposal({ + connection, + feePayer: members.proposer, + settingsPda, + transactionIndex, + creator: members.proposer, + programId, + }); + await connection.confirmTransaction(signature); + + // Approve the proposal (1/1 threshold) + signature = await smartAccount.rpc.approveProposal({ + connection, + feePayer: members.voter, + settingsPda, + transactionIndex, + signer: members.voter, + programId, + }); + await connection.confirmTransaction(signature); + + // Execute the settings transaction + signature = await smartAccount.rpc.executeSettingsTransaction({ + connection, + feePayer: members.almighty, + settingsPda, + transactionIndex, + signer: members.almighty, + rentPayer: members.almighty, + policies: [policyPda], + programId, + }); + await connection.confirmTransaction(signature); + + const policyAccount = await Policy.fromAccountAddress( + connection, + policyPda + ); + assert.strictEqual( + policyAccount.settings.toString(), + settingsPda.toString() + ); + assert.strictEqual(policyAccount.threshold, 1); + assert.strictEqual(policyAccount.timeLock, 0); + + const policyPayload: smartAccount.generated.PolicyPayload = { + __kind: "InternalFundTransfer", + fields: [ + { + sourceIndex: 0, + destinationIndex: 1, + mint: mint, + decimals: mintDecimals, + amount: 500_000_000, + }, + ], + }; + let sourceTokenAccount = await getAssociatedTokenAddressSync( + mint, + sourceSmartAccountPda, + true + ); + let destinationTokenAccount = getAssociatedTokenAddressSync( + mint, + destinationSmartAccountPda, + true + ); + await getOrCreateAssociatedTokenAccount( + connection, + members.voter, + mint, + destinationSmartAccountPda, + true + ); + + let remainingAccounts: AccountMeta[] = []; + + remainingAccounts.push({ + pubkey: members.voter.publicKey, + isWritable: false, + isSigner: true, + }); + remainingAccounts.push({ + pubkey: sourceSmartAccountPda, + isWritable: false, + isSigner: false, + }); + remainingAccounts.push({ + pubkey: sourceTokenAccount, + isWritable: true, + isSigner: false, + }); + remainingAccounts.push({ + pubkey: destinationTokenAccount, + isWritable: true, + isSigner: false, + }); + remainingAccounts.push({ + pubkey: mint, + isWritable: false, + isSigner: false, + }); + remainingAccounts.push({ + pubkey: TOKEN_PROGRAM_ID, + isWritable: false, + isSigner: false, + }); + + // Attempt to do the same with a synchronous instruction + signature = await smartAccount.rpc.executePolicyPayloadSync({ + connection, + feePayer: members.voter, + policy: policyPda, + accountIndex: 0, + numSigners: 1, + policyPayload: policyPayload, + instruction_accounts: remainingAccounts, + sendOptions: { + skipPreflight: true, + }, + signers: [members.voter], + programId, + }); + await connection.confirmTransaction(signature); + + // Check the balances + let sourceBalance = await connection.getTokenAccountBalance( + sourceTokenAccount + ); + let destinationBalance = await connection.getTokenAccountBalance( + destinationTokenAccount + ); + assert.strictEqual(sourceBalance.value.amount, "500000000"); + assert.strictEqual(destinationBalance.value.amount, "500000000"); + }); +}); diff --git a/tests/suites/instructions/logEvent.ts b/tests/suites/instructions/logEvent.ts new file mode 100644 index 0000000..9c4611c --- /dev/null +++ b/tests/suites/instructions/logEvent.ts @@ -0,0 +1,75 @@ +import * as web3 from "@solana/web3.js"; +import * as smartAccount from "@sqds/smart-account"; +import { createLocalhostConnection, getTestProgramId } from "../../utils"; +import assert from "assert"; + +const programId = getTestProgramId(); + +describe("Instructions / Log Event", () => { + it("Calling log event after using assign", async () => { + const connection = createLocalhostConnection(); + const feePayer = web3.Keypair.generate(); + + let airdropSignature = await connection.requestAirdrop( + feePayer.publicKey, + 1_000_000_000 + ); + await connection.confirmTransaction(airdropSignature); + + const keyPair = web3.Keypair.generate(); + + let transferIx = web3.SystemProgram.transfer({ + fromPubkey: feePayer.publicKey, + toPubkey: keyPair.publicKey, + lamports: 1586880, + }); + + let allocateIx = web3.SystemProgram.allocate({ + accountPubkey: keyPair.publicKey, + space: 100, + }); + + let ix = web3.SystemProgram.assign({ + accountPubkey: keyPair.publicKey, + programId, + }); + + let logEventIx = smartAccount.generated.createLogEventInstruction( + { + logAuthority: keyPair.publicKey, + }, + { + args: { + event: Buffer.from("test"), + }, + }, + programId + ); + + let tx = new web3.Transaction().add(transferIx, allocateIx, ix); + tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash; + tx.feePayer = feePayer.publicKey; + tx.partialSign(feePayer); + tx.partialSign(keyPair); + + let signature = await connection.sendRawTransaction(tx.serialize(), { + skipPreflight: true, + }); + await connection.confirmTransaction(signature); + + let logEventTx = new web3.Transaction().add(logEventIx); + logEventTx.recentBlockhash = ( + await connection.getLatestBlockhash() + ).blockhash; + logEventTx.feePayer = feePayer.publicKey; + logEventTx.partialSign(feePayer); + logEventTx.partialSign(keyPair); + + assert.rejects( + connection.sendRawTransaction(logEventTx.serialize()), + (error: any) => { + return true; + } + ); + }); +}); diff --git a/tests/suites/instructions/policyCreation.ts b/tests/suites/instructions/policyCreation.ts new file mode 100644 index 0000000..19a30ac --- /dev/null +++ b/tests/suites/instructions/policyCreation.ts @@ -0,0 +1,512 @@ +import * as smartAccount from "@sqds/smart-account"; +import * as web3 from "@solana/web3.js"; +import assert from "assert"; +import { + createAutonomousMultisig, + createLocalhostConnection, + generateSmartAccountSigners, + getTestProgramId, + TestMembers, +} from "../../utils"; +const { Settings, Proposal, Policy } = smartAccount.accounts; +const programId = getTestProgramId(); +const connection = createLocalhostConnection(); + +describe("Flows / Policy Creation", () => { + let members: TestMembers; + + before(async () => { + members = await generateSmartAccountSigners(connection); + }); + + it("create policy: InternalFundTransfer", async () => { + // Create new autonomous smart account with 1/1 threshold for easy testing + const settingsPda = ( + await createAutonomousMultisig({ + connection, + members, + threshold: 1, + timeLock: 0, + programId, + }) + )[0]; + + // Use seed 1 for the first policy on this smart account + const policySeed = 1; + + // Create policy creation payload + const policyCreationPayload: smartAccount.generated.PolicyCreationPayload = + { + __kind: "InternalFundTransfer", + fields: [ + { + sourceAccountIndices: new Uint8Array([0, 1]), // Allow transfers from account indices 0 and 1 + destinationAccountIndices: new Uint8Array([2, 3]), // Allow transfers to account indices 2 and 3 + allowedMints: [web3.PublicKey.default], // Allow native SOL transfers + }, + ], + }; + + const transactionIndex = BigInt(1); + + const [policyPda] = smartAccount.getPolicyPda({ + settingsPda, + policySeed, + programId, + }); + // Create settings transaction with PolicyCreate action + let signature = await smartAccount.rpc.createSettingsTransaction({ + connection, + feePayer: members.proposer, + settingsPda, + transactionIndex, + creator: members.proposer.publicKey, + actions: [ + { + __kind: "PolicyCreate", + seed: policySeed, + policyCreationPayload, + signers: [ + { + key: members.voter.publicKey, + permissions: { mask: 7 }, + }, + ], + threshold: 1, + timeLock: 0, + startTimestamp: null, + expirationArgs: null, + }, + ], + programId, + }); + await connection.confirmTransaction(signature); + + // Create proposal for the transaction + signature = await smartAccount.rpc.createProposal({ + connection, + feePayer: members.proposer, + settingsPda, + transactionIndex, + creator: members.proposer, + programId, + }); + await connection.confirmTransaction(signature); + + // Approve the proposal (1/1 threshold) + signature = await smartAccount.rpc.approveProposal({ + connection, + feePayer: members.voter, + settingsPda, + transactionIndex, + signer: members.voter, + programId, + }); + await connection.confirmTransaction(signature); + + // Execute the settings transaction + signature = await smartAccount.rpc.executeSettingsTransaction({ + connection, + feePayer: members.almighty, + settingsPda, + transactionIndex, + signer: members.almighty, + rentPayer: members.almighty, + policies: [policyPda], + programId, + }); + await connection.confirmTransaction(signature); + // Check settings counter incremented + const settingsAccount = await Settings.fromAccountAddress( + connection, + settingsPda + ); + assert.strictEqual(settingsAccount.policySeed?.toString(), "1"); + + const policyAccount = await Policy.fromAccountAddress( + connection, + policyPda + ); + assert.strictEqual( + policyAccount.settings.toString(), + settingsPda.toString() + ); + assert.strictEqual(policyAccount.threshold, 1); + assert.strictEqual(policyAccount.timeLock, 0); + }); + + it("create policy: ProgramInteraction", async () => { + // Create new autonomous smart account with 1/1 threshold + const settingsPda = ( + await createAutonomousMultisig({ + connection, + members, + threshold: 1, + timeLock: 0, + programId, + }) + )[0]; + + const policySeed = 1; + + const policyCreationPayload: smartAccount.generated.PolicyCreationPayload = + { + __kind: "ProgramInteraction", + fields: [ + { + accountIndex: 0, // Apply to account index 0 + preHook: { + numExtraAccounts: 4, + accountConstraints: [ + { + accountIndex: 0, + accountConstraint: { + __kind: "Pubkey", + fields: [[members.proposer.publicKey]], + }, + owner: null, + }, + ], + instructionData: new Uint8Array([1, 2, 3]), + programId: web3.PublicKey.default, + passInnerInstructions: false, + }, + postHook: null, + instructionsConstraints: [ + { + programId: web3.PublicKey.default, // Allow system program interactions + dataConstraints: [], + accountConstraints: [], + }, + ], + spendingLimits: [], // No balance constraints + }, + ], + }; + + const transactionIndex = BigInt(1); + + const [policyPda] = smartAccount.getPolicyPda({ + settingsPda, + policySeed, + programId, + }); + + let signature = await smartAccount.rpc.createSettingsTransaction({ + connection, + feePayer: members.proposer, + settingsPda, + transactionIndex, + creator: members.proposer.publicKey, + actions: [ + { + __kind: "PolicyCreate", + seed: policySeed, + policyCreationPayload, + signers: [ + { + key: members.voter.publicKey, + permissions: { mask: 7 }, + }, + ], + threshold: 1, + timeLock: 0, + startTimestamp: Date.now(), + expirationArgs: null, + }, + ], + programId, + }); + await connection.confirmTransaction(signature); + + // Create and approve proposal + signature = await smartAccount.rpc.createProposal({ + connection, + feePayer: members.proposer, + settingsPda, + transactionIndex, + creator: members.proposer, + programId, + }); + await connection.confirmTransaction(signature); + + signature = await smartAccount.rpc.approveProposal({ + connection, + feePayer: members.voter, + settingsPda, + transactionIndex, + signer: members.voter, + programId, + }); + await connection.confirmTransaction(signature); + + // Execute settings transaction + signature = await smartAccount.rpc.executeSettingsTransaction({ + connection, + feePayer: members.almighty, + settingsPda, + transactionIndex, + signer: members.almighty, + rentPayer: members.almighty, + policies: [policyPda], + sendOptions: { skipPreflight: true }, + programId, + }); + await connection.confirmTransaction(signature); + + // Check settings counter incremented + const settingsAccount = await Settings.fromAccountAddress( + connection, + settingsPda + ); + assert.strictEqual(settingsAccount.policySeed?.toString(), "1"); + + const policyAccount = await Policy.fromAccountAddress( + connection, + policyPda + ); + assert.strictEqual( + policyAccount.settings.toString(), + settingsPda.toString() + ); + assert.strictEqual(policyAccount.threshold, 1); + }); + + it("create policy: SpendingLimit", async () => { + // Create new autonomous smart account with 1/1 threshold + const settingsPda = ( + await createAutonomousMultisig({ + connection, + members, + threshold: 1, + timeLock: 0, + programId, + }) + )[0]; + + const policySeed = 1; + + const policyCreationPayload: smartAccount.generated.PolicyCreationPayload = + { + __kind: "SpendingLimit", + fields: [ + { + mint: web3.PublicKey.default, // Native SOL + sourceAccountIndex: 0, + timeConstraints: { + period: { __kind: "Daily" }, + start: Date.now(), + expiration: null, + accumulateUnused: false, + }, + quantityConstraints: { + maxPerPeriod: 1000000000, // 1 SOL in lamports + maxPerUse: 100000000, // 0.1 SOL in lamports + enforceExactQuantity: false, + }, + destinations: [], // Empty array means any destination allowed + usageState: null, + }, + ], + }; + + const transactionIndex = BigInt(1); + + const [policyPda] = smartAccount.getPolicyPda({ + settingsPda, + policySeed, + programId, + }); + + let signature = await smartAccount.rpc.createSettingsTransaction({ + connection, + feePayer: members.proposer, + settingsPda, + transactionIndex, + creator: members.proposer.publicKey, + actions: [ + { + __kind: "PolicyCreate", + seed: policySeed, + policyCreationPayload, + signers: [ + { + key: members.voter.publicKey, + permissions: { mask: 7 }, + }, + ], + threshold: 1, + timeLock: 0, + startTimestamp: Date.now(), + expirationArgs: null, + }, + ], + programId, + }); + await connection.confirmTransaction(signature); + + // Create and approve proposal + signature = await smartAccount.rpc.createProposal({ + connection, + feePayer: members.proposer, + settingsPda, + transactionIndex, + creator: members.proposer, + programId, + }); + await connection.confirmTransaction(signature); + + signature = await smartAccount.rpc.approveProposal({ + connection, + feePayer: members.voter, + settingsPda, + transactionIndex, + signer: members.voter, + programId, + }); + await connection.confirmTransaction(signature); + + // Execute settings transaction + signature = await smartAccount.rpc.executeSettingsTransaction({ + connection, + feePayer: members.almighty, + settingsPda, + transactionIndex, + signer: members.almighty, + rentPayer: members.almighty, + policies: [policyPda], + sendOptions: { skipPreflight: true }, + programId, + }); + await connection.confirmTransaction(signature); + + // Check settings counter incremented + const settingsAccount = await Settings.fromAccountAddress( + connection, + settingsPda + ); + assert.strictEqual(settingsAccount.policySeed?.toString(), "1"); + + const policyAccount = await Policy.fromAccountAddress( + connection, + policyPda + ); + assert.strictEqual( + policyAccount.settings.toString(), + settingsPda.toString() + ); + assert.strictEqual(policyAccount.threshold, 1); + }); + + it("create policy: SettingsChange", async () => { + // Create new autonomous smart account with 1/1 threshold + const settingsPda = ( + await createAutonomousMultisig({ + connection, + members, + threshold: 1, + timeLock: 0, + programId, + }) + )[0]; + + const policySeed = 1; + + const policyCreationPayload: smartAccount.generated.PolicyCreationPayload = + { + __kind: "SettingsChange", + fields: [ + { + actions: [{ __kind: "ChangeThreshold" }], // Allow threshold changes + }, + ], + }; + + const transactionIndex = BigInt(1); + + const [policyPda] = smartAccount.getPolicyPda({ + settingsPda, + policySeed, + programId, + }); + + let signature = await smartAccount.rpc.createSettingsTransaction({ + connection, + feePayer: members.proposer, + settingsPda, + transactionIndex, + creator: members.proposer.publicKey, + actions: [ + { + __kind: "PolicyCreate", + seed: policySeed, + policyCreationPayload, + signers: [ + { + key: members.voter.publicKey, + permissions: { mask: 7 }, + }, + ], + threshold: 1, + timeLock: 0, + startTimestamp: Date.now(), + expirationArgs: null, + }, + ], + programId, + }); + await connection.confirmTransaction(signature); + + // Create and approve proposal + signature = await smartAccount.rpc.createProposal({ + connection, + feePayer: members.proposer, + settingsPda, + transactionIndex, + creator: members.proposer, + programId, + }); + await connection.confirmTransaction(signature); + + signature = await smartAccount.rpc.approveProposal({ + connection, + feePayer: members.voter, + settingsPda, + transactionIndex, + signer: members.voter, + programId, + }); + await connection.confirmTransaction(signature); + + // Execute settings transaction + signature = await smartAccount.rpc.executeSettingsTransaction({ + connection, + feePayer: members.almighty, + settingsPda, + transactionIndex, + signer: members.almighty, + rentPayer: members.almighty, + policies: [policyPda], + sendOptions: { skipPreflight: true }, + programId, + }); + await connection.confirmTransaction(signature); + + // Check settings counter incremented + const settingsAccount = await Settings.fromAccountAddress( + connection, + settingsPda + ); + assert.strictEqual(settingsAccount.policySeed?.toString(), "1"); + + const policyAccount = await Policy.fromAccountAddress( + connection, + policyPda + ); + assert.strictEqual( + policyAccount.settings.toString(), + settingsPda.toString() + ); + assert.strictEqual(policyAccount.threshold, 1); + }); +}); diff --git a/tests/suites/instructions/policyExpiration.ts b/tests/suites/instructions/policyExpiration.ts new file mode 100644 index 0000000..a7be9d7 --- /dev/null +++ b/tests/suites/instructions/policyExpiration.ts @@ -0,0 +1,356 @@ +import * as smartAccount from "@sqds/smart-account"; +import * as web3 from "@solana/web3.js"; +import assert from "assert"; +import { + createAutonomousMultisig, + createLocalhostConnection, + generateSmartAccountSigners, + getTestProgramId, + TestMembers, +} from "../../utils"; +const { Settings, Proposal, Policy } = smartAccount.accounts; +const programId = getTestProgramId(); +const connection = createLocalhostConnection(); + +describe("Flows / Policy Expiration", () => { + let members: TestMembers; + + before(async () => { + members = await generateSmartAccountSigners(connection); + }); + + it("Test: Policy State Expiry", async () => { + // Create new autonomous smart account with 1/1 threshold for easy testing + const settingsPda = ( + await createAutonomousMultisig({ + connection, + members, + threshold: 1, + timeLock: 0, + programId, + }) + )[0]; + + // Use seed 1 for the first policy on this smart account + const policySeed = 1; + + // Create policy creation payload + const policyCreationPayload: smartAccount.generated.PolicyCreationPayload = + { + __kind: "InternalFundTransfer", + fields: [ + { + sourceAccountIndices: new Uint8Array([0, 1]), // Allow transfers from account indices 0 and 1 + destinationAccountIndices: new Uint8Array([2, 3]), // Allow transfers to account indices 2 and 3 + allowedMints: [web3.PublicKey.default], // Allow native SOL transfers + }, + ], + }; + + const transactionIndex = BigInt(1); + + const [policyPda] = smartAccount.getPolicyPda({ + settingsPda, + policySeed, + programId, + }); + // Create settings transaction with PolicyCreate action + let signature = await smartAccount.rpc.createSettingsTransaction({ + connection, + feePayer: members.proposer, + settingsPda, + transactionIndex, + creator: members.proposer.publicKey, + actions: [ + { + __kind: "PolicyCreate", + seed: policySeed, + policyCreationPayload, + signers: [ + { + key: members.voter.publicKey, + permissions: { mask: 7 }, + }, + ], + threshold: 1, + timeLock: 0, + startTimestamp: null, + expirationArgs: { + __kind: "SettingsState", + }, + }, + ], + programId, + }); + await connection.confirmTransaction(signature); + + // Create proposal for the transaction + signature = await smartAccount.rpc.createProposal({ + connection, + feePayer: members.proposer, + settingsPda, + transactionIndex, + creator: members.proposer, + programId, + }); + await connection.confirmTransaction(signature); + + // Approve the proposal (1/1 threshold) + signature = await smartAccount.rpc.approveProposal({ + connection, + feePayer: members.voter, + settingsPda, + transactionIndex, + signer: members.voter, + programId, + }); + await connection.confirmTransaction(signature); + + // Execute the settings transaction + signature = await smartAccount.rpc.executeSettingsTransaction({ + connection, + feePayer: members.almighty, + settingsPda, + transactionIndex, + signer: members.almighty, + rentPayer: members.almighty, + policies: [policyPda], + programId, + sendOptions: { + skipPreflight: true, + }, + }); + await connection.confirmTransaction(signature); + // Check settings counter incremented + const settingsAccount = await Settings.fromAccountAddress( + connection, + settingsPda + ); + assert.strictEqual(settingsAccount.policySeed?.toString(), "1"); + + // Add a member to the smart account settings + signature = await smartAccount.rpc.executeSettingsTransactionSync({ + connection, + feePayer: members.proposer, + settingsPda, + actions: [ + { + __kind: "AddSigner", + newSigner: { + key: web3.PublicKey.unique(), + permissions: { mask: 7 }, + }, + }, + ], + signers: [members.almighty], + programId, + }); + await connection.confirmTransaction(signature); + + // Assert the policy is expired due to settings state changing + const policyPayload: smartAccount.generated.PolicyPayload = { + __kind: "InternalFundTransfer", + fields: [ + { + sourceIndex: 0, + destinationIndex: 2, + mint: web3.PublicKey.default, + decimals: 9, + // 1 SOL + amount: 1_000_000_000, + }, + ], + }; + + // Reject due to lack of settings account submission + assert.rejects( + async () => { + await smartAccount.rpc.executePolicyPayloadSync({ + connection, + feePayer: members.voter, + policy: policyPda, + accountIndex: 0, + policyPayload, + numSigners: 1, + // Not submitting the settings account is a violation + instruction_accounts: [], + signers: [members.voter], + programId, + }); + }, + (err: any) => { + assert.ok( + err + .toString() + .includes("PolicyExpirationViolationSettingsAccountNotPresent") + ); + return true; + } + ); + + // Reject due to mismatching settings account submission + assert.rejects( + async () => { + await smartAccount.rpc.executePolicyPayloadSync({ + connection, + feePayer: members.voter, + policy: policyPda, + accountIndex: 0, + policyPayload, + numSigners: 1, + // Not submitting the settings account is a violation + instruction_accounts: [ + // Passing a random account as remaining account 0 + { + pubkey: members.proposer.publicKey, + isWritable: true, + isSigner: false, + }, + ], + signers: [members.voter], + programId, + }); + }, + (err: any) => { + assert.ok( + err + .toString() + .includes("PolicyExpirationViolationPolicySettingsKeyMismatch") + ); + return true; + } + ); + + // Reject due to settings hash expiration + assert.rejects( + async () => { + await smartAccount.rpc.executePolicyPayloadSync({ + connection, + feePayer: members.voter, + policy: policyPda, + accountIndex: 0, + policyPayload, + numSigners: 1, + // Not submitting the settings account is a violation + instruction_accounts: [ + // Passing a random account as remaining account 0 + { + pubkey: settingsPda, + isWritable: false, + isSigner: false, + }, + ], + signers: [members.voter], + programId, + }); + }, + (err: any) => { + assert.ok( + err.toString().includes("PolicyExpirationViolationHashExpired") + ); + return true; + } + ); + + // Update the policy to use the new settings hash + signature = await smartAccount.rpc.executeSettingsTransactionSync({ + connection, + feePayer: members.almighty, + settingsPda, + actions: [ + { + __kind: "PolicyUpdate", + policy: policyPda, + signers: [ + { + key: members.voter.publicKey, + permissions: { mask: 7 }, + }, + ], + threshold: 1, + timeLock: 0, + policyUpdatePayload: policyCreationPayload, + expirationArgs: { + __kind: "SettingsState", + }, + }, + ], + remainingAccounts: [ + { + pubkey: policyPda, + isWritable: true, + isSigner: false, + }, + ], + signers: [members.almighty], + programId, + }); + await connection.confirmTransaction(signature); + + // Get the destination and source accounts + let [destinationAccount] = await smartAccount.getSmartAccountPda({ + settingsPda, + accountIndex: 2, + programId, + }); + let [sourceAccount] = await smartAccount.getSmartAccountPda({ + settingsPda, + accountIndex: 0, + programId, + }); + + // Airdrop SOL to the source account + let airdropSignature = await connection.requestAirdrop( + sourceAccount, + 1_000_000_000 + ); + await connection.confirmTransaction(airdropSignature); + + // Execute the policy payload + signature = await smartAccount.rpc.executePolicyPayloadSync({ + connection, + feePayer: members.voter, + policy: policyPda, + accountIndex: 0, + policyPayload, + numSigners: 1, + instruction_accounts: [ + { + pubkey: members.voter.publicKey, + isWritable: false, + isSigner: true, + }, + { + pubkey: settingsPda, + isWritable: false, + isSigner: false, + }, + { + pubkey: sourceAccount, + isWritable: true, + isSigner: false, + }, + { + pubkey: destinationAccount, + isWritable: true, + isSigner: false, + }, + { + pubkey: web3.SystemProgram.programId, + isWritable: false, + isSigner: false, + }, + ], + signers: [members.voter], + sendOptions: { + skipPreflight: true, + }, + programId, + }); + await connection.confirmTransaction(signature); + + // Check the balances + let destinationBalance = await connection.getBalance(destinationAccount); + assert.strictEqual(destinationBalance, 1_000_000_000); + }); +}); diff --git a/tests/suites/instructions/policyUpdate.ts b/tests/suites/instructions/policyUpdate.ts new file mode 100644 index 0000000..a25d69c --- /dev/null +++ b/tests/suites/instructions/policyUpdate.ts @@ -0,0 +1,221 @@ +import * as smartAccount from "@sqds/smart-account"; +import * as web3 from "@solana/web3.js"; +import assert from "assert"; +import { + createAutonomousMultisig, + createLocalhostConnection, + generateSmartAccountSigners, + getTestProgramId, + TestMembers, +} from "../../utils"; +import { AccountMeta } from "@solana/web3.js"; +const { Settings, Proposal, Policy } = smartAccount.accounts; +const programId = getTestProgramId(); +const connection = createLocalhostConnection(); + +describe("Flows / Policy Update", () => { + let members: TestMembers; + + before(async () => { + members = await generateSmartAccountSigners(connection); + }); + + it("update policy: InternalFundTransfer", async () => { + // Create new autonomous smart account with 1/1 threshold for easy testing + const settingsPda = ( + await createAutonomousMultisig({ + connection, + members, + threshold: 1, + timeLock: 0, + programId, + }) + )[0]; + + // Use seed 1 for the first policy on this smart account + const policySeed = 1; + + // Create policy creation payload + const policyCreationPayload: smartAccount.generated.PolicyCreationPayload = + { + __kind: "InternalFundTransfer", + fields: [ + { + sourceAccountIndices: new Uint8Array([0, 1]), // Allow transfers from account indices 0 and 1 + destinationAccountIndices: new Uint8Array([2, 3]), // Allow transfers to account indices 2 and 3 + allowedMints: [web3.PublicKey.default], // Allow native SOL transfers + }, + ], + }; + + const transactionIndex = BigInt(1); + + const [policyPda] = smartAccount.getPolicyPda({ + settingsPda, + policySeed, + programId, + }); + // Create settings transaction with PolicyCreate action + let signature = await smartAccount.rpc.createSettingsTransaction({ + connection, + feePayer: members.proposer, + settingsPda, + transactionIndex, + creator: members.proposer.publicKey, + actions: [ + { + __kind: "PolicyCreate", + seed: policySeed, + policyCreationPayload, + signers: [ + { + key: members.voter.publicKey, + permissions: { mask: 7 }, + }, + ], + threshold: 1, + timeLock: 0, + startTimestamp: null, + expirationArgs: null, + }, + ], + programId, + }); + await connection.confirmTransaction(signature); + + // Create proposal for the transaction + signature = await smartAccount.rpc.createProposal({ + connection, + feePayer: members.proposer, + settingsPda, + transactionIndex, + creator: members.proposer, + programId, + }); + await connection.confirmTransaction(signature); + + // Approve the proposal (1/1 threshold) + signature = await smartAccount.rpc.approveProposal({ + connection, + feePayer: members.voter, + settingsPda, + transactionIndex, + signer: members.voter, + programId, + }); + await connection.confirmTransaction(signature); + + // Execute the settings transaction + signature = await smartAccount.rpc.executeSettingsTransaction({ + connection, + feePayer: members.almighty, + settingsPda, + transactionIndex, + signer: members.almighty, + rentPayer: members.almighty, + policies: [policyPda], + programId, + }); + await connection.confirmTransaction(signature); + // Check settings counter incremented + const settingsAccount = await Settings.fromAccountAddress( + connection, + settingsPda + ); + assert.strictEqual(settingsAccount.policySeed?.toString(), "1"); + + // Create a proposal for the policy + const policyPayload: smartAccount.generated.PolicyPayload = { + __kind: "InternalFundTransfer", + fields: [ + { + sourceIndex: 0, + destinationIndex: 2, + mint: web3.PublicKey.default, + decimals: 9, + // 1 SOL + amount: 1_000_000_000, + }, + ], + }; + // Create a transaction + signature = await smartAccount.rpc.createPolicyTransaction({ + connection, + feePayer: members.voter, + policy: policyPda, + accountIndex: 0, + transactionIndex: BigInt(1), + creator: members.voter.publicKey, + policyPayload, + sendOptions: { + skipPreflight: true, + }, + programId, + }); + await connection.confirmTransaction(signature); + // Assert the policies tx index increased + let policyAccount = await Policy.fromAccountAddress(connection, policyPda); + assert.strictEqual(policyAccount.transactionIndex.toString(), "1"); + assert.strictEqual(policyAccount.staleTransactionIndex?.toString(), "0"); + + // Update the policy + let remainingAccounts: AccountMeta[] = []; + remainingAccounts.push({ + pubkey: policyPda, + isWritable: true, + isSigner: false, + }); + + let updateSignature = await smartAccount.rpc.executeSettingsTransactionSync( + { + connection, + feePayer: members.almighty, + settingsPda, + actions: [ + { + __kind: "PolicyUpdate", + policy: policyPda, + signers: [ + { + key: members.voter.publicKey, + permissions: { mask: 7 }, + }, + ], + threshold: 1, + timeLock: 0, + policyUpdatePayload: { + __kind: "InternalFundTransfer", + fields: [ + { + sourceAccountIndices: new Uint8Array([0, 1]), // Allow transfers from account indices 0 and 1 + destinationAccountIndices: new Uint8Array([2, 3]), // Allow transfers to account indices 2 and 3 + allowedMints: [members.voter.publicKey], // Change the mint + }, + ], + }, + expirationArgs: null, + }, + ], + signers: [members.almighty], + remainingAccounts, + programId, + } + ); + await connection.confirmTransaction(updateSignature); + + // Check the policy stale tx index increased + policyAccount = await Policy.fromAccountAddress(connection, policyPda); + assert.strictEqual(policyAccount.transactionIndex.toString(), "1"); + assert.strictEqual(policyAccount.staleTransactionIndex?.toString(), "1"); + + // Check the policy state updated + let policyState = policyAccount.policyState; + let programInteractionPolicy = policyState + .fields[0] as smartAccount.generated.InternalFundTransferPolicy; + let allowedMints = programInteractionPolicy.allowedMints; + assert.equal( + allowedMints[0].toString(), + members.voter.publicKey.toString() + ); + }); +}); diff --git a/tests/suites/instructions/programInteractionPolicy.ts b/tests/suites/instructions/programInteractionPolicy.ts new file mode 100644 index 0000000..3e8dab8 --- /dev/null +++ b/tests/suites/instructions/programInteractionPolicy.ts @@ -0,0 +1,1168 @@ +import * as smartAccount from "@sqds/smart-account"; +import * as web3 from "@solana/web3.js"; +import assert from "assert"; +import { + createAutonomousMultisig, + createLocalhostConnection, + createMintAndTransferTo, + generateSmartAccountSigners, + getTestProgramId, + TestMembers, +} from "../../utils"; +import { AccountMeta } from "@solana/web3.js"; +import { getSmartAccountPda, generated, utils } from "@sqds/smart-account"; +import { + createAssociatedTokenAccount, + createTransferInstruction, + getAssociatedTokenAddressSync, + getOrCreateAssociatedTokenAccount, + TOKEN_PROGRAM_ID, + transfer, +} from "@solana/spl-token"; + +const { Settings, Proposal, Policy } = smartAccount.accounts; +const programId = getTestProgramId(); +const connection = createLocalhostConnection(); + +describe("Flow / ProgramInteractionPolicy", () => { + let members: TestMembers; + + before(async () => { + members = await generateSmartAccountSigners(connection); + }); + + // it("Program Interaction Policy", async () => { + // // Create new autonomous smart account with 1/1 threshold for easy testing + // const settingsPda = ( + // await createAutonomousMultisig({ + // connection, + // members, + // threshold: 1, + // timeLock: 0, + // programId, + // }) + // )[0]; + + // // Use seed 1 for the first policy on this smart account + // const policySeed = 1; + + // let [sourceSmartAccountPda] = await getSmartAccountPda({ + // settingsPda, + // accountIndex: 0, + // programId, + // }); + + // let [destinationSmartAccountPda] = await getSmartAccountPda({ + // settingsPda, + // accountIndex: 1, + // programId, + // }); + + // let [mint, mintDecimals] = await createMintAndTransferTo( + // connection, + // members.voter, + // sourceSmartAccountPda, + // 1_500_000_000 + // ); + + // let sourceTokenAccount = await getAssociatedTokenAddressSync( + // mint, + // sourceSmartAccountPda, + // true + // ); + // let destinationTokenAccount = getAssociatedTokenAddressSync( + // mint, + // destinationSmartAccountPda, + // true + // ); + + // await getOrCreateAssociatedTokenAccount( + // connection, + // members.voter, + // mint, + // destinationSmartAccountPda, + // true + // ); + + // // Create policy creation payload + // const policyCreationPayload: smartAccount.generated.PolicyCreationPayload = + // { + // __kind: "ProgramInteraction", + // fields: [ + // { + // accountIndex: 0, + // preHook: null, + // postHook: null, + // instructionsConstraints: [ + // { + // programId: TOKEN_PROGRAM_ID, + // dataConstraints: [ + // { + // dataOffset: 0, + // // Only allow TokenProgram.Transfer + // dataValue: { __kind: "U8", fields: [3] }, + // // Only allow TokenProgram.Transfer + // operator: generated.DataOperator.Equals, + // }, + // ], + // accountConstraints: [ + // { + // // Destination of the transfer + // accountIndex: 1, + // accountConstraint: { + // __kind: "Pubkey", + // fields: [[destinationTokenAccount]], + // }, + // owner: null, + // }, + // ], + // }, + // ], + // spendingLimits: [ + // { + // mint, + // timeConstraints: { + // start: 0, + // expiration: null, + // // 10 Second spending limit + // period: { __kind: "Custom", fields: [5] }, + // }, + // quantityConstraints: { + // maxPerPeriod: 1_000_000_000, + // }, + // }, + // ], + // }, + // ], + // }; + + // const transactionIndex = BigInt(1); + + // const [policyPda] = smartAccount.getPolicyPda({ + // settingsPda, + // policySeed, + // programId, + // }); + // // Create settings transaction with PolicyCreate action + // let signature = await smartAccount.rpc.createSettingsTransaction({ + // connection, + // feePayer: members.proposer, + // settingsPda, + // transactionIndex, + // creator: members.proposer.publicKey, + // actions: [ + // { + // __kind: "PolicyCreate", + // seed: policySeed, + // policyCreationPayload, + // signers: [ + // { + // key: members.voter.publicKey, + // permissions: { mask: 7 }, + // }, + // ], + // threshold: 1, + // timeLock: 0, + // startTimestamp: null, + // expirationArgs: null, + // }, + // ], + // programId, + // }); + // await connection.confirmTransaction(signature); + + // // Create proposal for the transaction + // signature = await smartAccount.rpc.createProposal({ + // connection, + // feePayer: members.proposer, + // settingsPda, + // transactionIndex, + // creator: members.proposer, + // programId, + // }); + // await connection.confirmTransaction(signature); + + // // Approve the proposal (1/1 threshold) + // signature = await smartAccount.rpc.approveProposal({ + // connection, + // feePayer: members.voter, + // settingsPda, + // transactionIndex, + // signer: members.voter, + // programId, + // }); + // await connection.confirmTransaction(signature); + + // // Execute the settings transaction + // signature = await smartAccount.rpc.executeSettingsTransaction({ + // connection, + // feePayer: members.almighty, + // settingsPda, + // transactionIndex, + // signer: members.almighty, + // rentPayer: members.almighty, + // policies: [policyPda], + // sendOptions: { + // skipPreflight: true, + // }, + // programId, + // }); + // await connection.confirmTransaction(signature); + + // // Check the policy state + // const policyAccount = await Policy.fromAccountAddress( + // connection, + // policyPda + // ); + // let policyState = policyAccount.policyState; + // let programInteractionPolicy = policyState + // .fields[0] as smartAccount.generated.ProgramInteractionPolicy; + // let spendingLimit = programInteractionPolicy.spendingLimits[0]; + // assert.equal( + // spendingLimit.usage.remainingInPeriod.toString(), + // "1000000000" + // ); + // let lastReset = spendingLimit.usage.lastReset.toString(); + + // assert.strictEqual( + // policyAccount.settings.toString(), + // settingsPda.toString() + // ); + // assert.strictEqual(policyAccount.threshold, 1); + // assert.strictEqual(policyAccount.timeLock, 0); + + // // Try transfer SOL via creating a transaction and proposal + // const policyTransactionIndex = BigInt(1); + + // // Create SPL token transfer instruction + // const tokenTransferIxn = createTransferInstruction( + // sourceTokenAccount, // source token account + // destinationTokenAccount, // destination token account + // sourceSmartAccountPda, // authority + // 500_000_000n // amount + // ); + + // // Create transaction message + // const message = new web3.TransactionMessage({ + // payerKey: sourceSmartAccountPda, + // recentBlockhash: (await connection.getLatestBlockhash()).blockhash, + // instructions: [tokenTransferIxn], + // }); + + // let { transactionMessageBytes, compiledMessage } = + // utils.transactionMessageToMultisigTransactionMessageBytes({ + // message, + // addressLookupTableAccounts: [], + // smartAccountPda: sourceSmartAccountPda, + // }); + + // const policyPayload: smartAccount.generated.PolicyPayload = { + // __kind: "ProgramInteraction", + // fields: [ + // { + // instructionConstraintIndices: new Uint8Array([0]), + // transactionPayload: { + // __kind: "AsyncTransaction", + // fields: [ + // { + // accountIndex: 0, + // ephemeralSigners: 0, + // transactionMessage: transactionMessageBytes, + // memo: null, + // }, + // ], + // }, + // }, + // ], + // }; + + // // Create a transaction + // signature = await smartAccount.rpc.createPolicyTransaction({ + // connection, + // feePayer: members.voter, + // policy: policyPda, + // accountIndex: 0, + // transactionIndex: policyTransactionIndex, + // creator: members.voter.publicKey, + // policyPayload, + // sendOptions: { + // skipPreflight: true, + // }, + // programId, + // }); + // await connection.confirmTransaction(signature); + + // // Create proposal for the transaction + // signature = await smartAccount.rpc.createProposal({ + // connection, + // feePayer: members.voter, + // settingsPda: policyPda, + // transactionIndex: policyTransactionIndex, + // creator: members.voter, + // programId, + // }); + // await connection.confirmTransaction(signature); + + // // Approve the proposal (1/1 threshold) + // signature = await smartAccount.rpc.approveProposal({ + // connection, + // feePayer: members.voter, + // settingsPda: policyPda, + // transactionIndex: policyTransactionIndex, + // signer: members.voter, + // programId, + // }); + // await connection.confirmTransaction(signature); + + // let remainingAccounts: AccountMeta[] = []; + + // for (const [ + // index, + // accountKey, + // ] of compiledMessage.staticAccountKeys.entries()) { + // if (accountKey.equals(sourceSmartAccountPda)) { + // remainingAccounts.push({ + // pubkey: accountKey, + // isWritable: compiledMessage.isAccountWritable(index), + // isSigner: false, + // }); + // } else { + // remainingAccounts.push({ + // pubkey: accountKey, + // isWritable: compiledMessage.isAccountWritable(index), + // isSigner: false, + // }); + // } + // } + // // Airdrop SOL to the source smart account + // let airdropSignature = await connection.requestAirdrop( + // sourceSmartAccountPda, + // 2_000_000_000 + // ); + // await connection.confirmTransaction(airdropSignature); + + // // Execute the transaction + // signature = await smartAccount.rpc.executePolicyTransaction({ + // connection, + // feePayer: members.voter, + // policy: policyPda, + // transactionIndex: policyTransactionIndex, + // signer: members.voter.publicKey, + // anchorRemainingAccounts: remainingAccounts, + // sendOptions: { + // skipPreflight: true, + // }, + // programId, + // }); + // await connection.confirmTransaction(signature); + + // // Check the balances & policy state + // let sourceBalance = await connection.getTokenAccountBalance( + // sourceTokenAccount + // ); + // let destinationBalance = await connection.getTokenAccountBalance( + // destinationTokenAccount + // ); + // assert.strictEqual(sourceBalance.value.amount, "1000000000"); + // assert.strictEqual(destinationBalance.value.amount, "500000000"); + + // // Policy state + // let policyData = await Policy.fromAccountAddress(connection, policyPda, { + // commitment: "processed", + // }); + // policyState = policyData.policyState; + // programInteractionPolicy = policyState + // .fields[0] as smartAccount.generated.ProgramInteractionPolicy; + // spendingLimit = programInteractionPolicy.spendingLimits[0]; + // assert.equal(spendingLimit.usage.remainingInPeriod.toString(), "500000000"); + + // let modifiedTokenTransfer = tokenTransferIxn; + // modifiedTokenTransfer.keys[2].isWritable = true; + + // let synchronousPayload = + // utils.instructionsToSynchronousTransactionDetailsV2({ + // vaultPda: sourceSmartAccountPda, + // members: [members.voter.publicKey], + // transaction_instructions: [tokenTransferIxn], + // }); + + // let syncPolicyPayload: smartAccount.generated.PolicyPayload = { + // __kind: "ProgramInteraction", + // fields: [ + // { + // instructionConstraintIndices: new Uint8Array([0]), + // transactionPayload: { + // __kind: "SyncTransaction", + // fields: [ + // { + // accountIndex: 0, + // instructions: synchronousPayload.instructions, + // }, + // ], + // }, + // }, + // ], + // }; + + // // Attempt to do the same with a synchronous instruction + // signature = await smartAccount.rpc.executePolicyPayloadSync({ + // connection, + // feePayer: members.voter, + // policy: policyPda, + // accountIndex: 0, + // numSigners: 1, + // policyPayload: syncPolicyPayload, + // instruction_accounts: synchronousPayload.accounts, + // signers: [members.voter], + // programId, + // }); + // await connection.confirmTransaction(signature); + + // // Check the balances & policy state + // sourceBalance = await connection.getTokenAccountBalance(sourceTokenAccount); + // destinationBalance = await connection.getTokenAccountBalance( + // destinationTokenAccount + // ); + // assert.strictEqual(sourceBalance.value.amount, "500000000"); + // assert.strictEqual(destinationBalance.value.amount, "1000000000"); + + // // Check the policy state + // policyData = await Policy.fromAccountAddress(connection, policyPda, { + // commitment: "processed", + // }); + // policyState = policyData.policyState; + // assert.strictEqual(policyState.__kind, "ProgramInteraction"); + // programInteractionPolicy = policyState + // .fields[0] as smartAccount.generated.ProgramInteractionPolicy; + // spendingLimit = programInteractionPolicy.spendingLimits[0]; + // assert.equal(spendingLimit.usage.remainingInPeriod.toString(), "0"); + // assert.equal(spendingLimit.usage.lastReset.toString(), lastReset); + + // // Try to transfer more than the policy allows + // await assert.rejects( + // smartAccount.rpc.executePolicyPayloadSync({ + // connection, + // feePayer: members.voter, + // policy: policyPda, + // accountIndex: 0, + // numSigners: 1, + // policyPayload: syncPolicyPayload, + // instruction_accounts: synchronousPayload.accounts, + // signers: [members.voter], + // programId, + // }), + // (err: any) => { + // assert.ok( + // err + // .toString() + // .includes("ProgramInteractionInsufficientTokenAllowance") + // ); + // return true; + // } + // ); + // // Wait 6 seconds and retry to get the spending limit to reset + // await new Promise((resolve) => setTimeout(resolve, 5000)); + + // let signatureAfter = await smartAccount.rpc.executePolicyPayloadSync({ + // connection, + // feePayer: members.voter, + // policy: policyPda, + // accountIndex: 0, + // numSigners: 1, + // policyPayload: syncPolicyPayload, + // instruction_accounts: synchronousPayload.accounts, + // signers: [members.voter], + // sendOptions: { + // skipPreflight: true, + // }, + // programId, + // }); + // await connection.confirmTransaction(signatureAfter); + + // // Check the balances & policy state + // sourceBalance = await connection.getTokenAccountBalance(sourceTokenAccount); + // destinationBalance = await connection.getTokenAccountBalance( + // destinationTokenAccount + // ); + // assert.strictEqual(sourceBalance.value.amount, "0"); + // assert.strictEqual(destinationBalance.value.amount, "1500000000"); + + // // Policy state + // policyData = await Policy.fromAccountAddress(connection, policyPda, { + // commitment: "processed", + // }); + // policyState = policyData.policyState; + // programInteractionPolicy = policyState + // .fields[0] as smartAccount.generated.ProgramInteractionPolicy; + // spendingLimit = programInteractionPolicy.spendingLimits[0]; + // // Should have reset + // assert.equal(spendingLimit.usage.remainingInPeriod.toString(), "500000000"); + // }); + + // it("Program Interaction Policy - Account Data Constraints", async () => { + // // Create new autonomous smart account with 1/1 threshold for easy testing + // const settingsPda = ( + // await createAutonomousMultisig({ + // connection, + // members, + // threshold: 1, + // timeLock: 0, + // programId, + // }) + // )[0]; + + // // Use seed 1 for the first policy on this smart account + // const policySeed = 1; + // let randomAccountPublicKey = web3.Keypair.generate().publicKey; + + // let [sourceSmartAccountPda] = await getSmartAccountPda({ + // settingsPda, + // accountIndex: 0, + // programId, + // }); + + // let [destinationSmartAccountPda] = await getSmartAccountPda({ + // settingsPda, + // accountIndex: 1, + // programId, + // }); + + // let [mint, mintDecimals] = await createMintAndTransferTo( + // connection, + // members.voter, + // sourceSmartAccountPda, + // 1_500_000_000 + // ); + + // let sourceTokenAccount = await getAssociatedTokenAddressSync( + // mint, + // sourceSmartAccountPda, + // true + // ); + + // let destinationTokenAccount = getAssociatedTokenAddressSync( + // mint, + // destinationSmartAccountPda, + // true + // ); + // let randomDestinationTokenAccount = getAssociatedTokenAddressSync( + // mint, + // randomAccountPublicKey, + // true + // ); + + // await getOrCreateAssociatedTokenAccount( + // connection, + // members.voter, + // mint, + // destinationSmartAccountPda, + // true + // ); + // await getOrCreateAssociatedTokenAccount( + // connection, + // members.voter, + // mint, + // randomAccountPublicKey, + // true + // ); + + // // Create policy creation payload + // const policyCreationPayload: smartAccount.generated.PolicyCreationPayload = + // { + // __kind: "ProgramInteraction", + // fields: [ + // { + // accountIndex: 0, + // preHook: null, + // postHook: null, + // instructionsConstraints: [ + // { + // programId: TOKEN_PROGRAM_ID, + // dataConstraints: [ + // { + // dataOffset: 0, + // // Only allow TokenProgram.Transfer + // dataValue: { __kind: "U8", fields: [3] }, + // // Only allow TokenProgram.Transfer + // operator: generated.DataOperator.Equals, + // }, + // ], + // accountConstraints: [ + // { + // // Destination of the transfer + // accountIndex: 1, + // accountConstraint: { + // __kind: "AccountData", + // fields: [ + // [ + // // Owner of the destination token account must be the destination smart account + // { + // dataOffset: 32, + // dataValue: { + // __kind: "U8Slice", + // fields: [destinationSmartAccountPda.toBuffer()], + // }, + // operator: generated.DataOperator.Equals, + // }, + // ], + // ], + // }, + // owner: TOKEN_PROGRAM_ID, + // }, + // ], + // }, + // ], + // spendingLimits: [], + // }, + // ], + // }; + + // const transactionIndex = BigInt(1); + + // const [policyPda] = smartAccount.getPolicyPda({ + // settingsPda, + // policySeed, + // programId, + // }); + // // Create settings transaction with PolicyCreate action + // let signature = await smartAccount.rpc.createSettingsTransaction({ + // connection, + // feePayer: members.proposer, + // settingsPda, + // transactionIndex, + // creator: members.proposer.publicKey, + // actions: [ + // { + // __kind: "PolicyCreate", + // seed: policySeed, + // policyCreationPayload, + // signers: [ + // { + // key: members.voter.publicKey, + // permissions: { mask: 7 }, + // }, + // ], + // threshold: 1, + // timeLock: 0, + // startTimestamp: null, + // expirationArgs: null, + // }, + // ], + // programId, + // }); + // await connection.confirmTransaction(signature); + + // // Create proposal for the transaction + // signature = await smartAccount.rpc.createProposal({ + // connection, + // feePayer: members.proposer, + // settingsPda, + // transactionIndex, + // creator: members.proposer, + // programId, + // }); + // await connection.confirmTransaction(signature); + + // // Approve the proposal (1/1 threshold) + // signature = await smartAccount.rpc.approveProposal({ + // connection, + // feePayer: members.voter, + // settingsPda, + // transactionIndex, + // signer: members.voter, + // programId, + // }); + // await connection.confirmTransaction(signature); + + // // Execute the settings transaction + // signature = await smartAccount.rpc.executeSettingsTransaction({ + // connection, + // feePayer: members.almighty, + // settingsPda, + // transactionIndex, + // signer: members.almighty, + // rentPayer: members.almighty, + // policies: [policyPda], + // sendOptions: { + // skipPreflight: true, + // }, + // programId, + // }); + // await connection.confirmTransaction(signature); + + // // Check the policy state + // const policyAccount = await Policy.fromAccountAddress( + // connection, + // policyPda + // ); + // let policyState = policyAccount.policyState; + // let programInteractionPolicy = policyState + // .fields[0] as smartAccount.generated.ProgramInteractionPolicy; + // let instructionConstraint = + // programInteractionPolicy.instructionsConstraints[0]; + // let accountConstraint = instructionConstraint.accountConstraints[0]; + // let dataConstraint = instructionConstraint.dataConstraints[0]; + + // assert.strictEqual(accountConstraint.accountIndex, 1); + // assert.strictEqual( + // accountConstraint.accountConstraint.__kind, + // "AccountData" + // ); + + // assert.strictEqual( + // policyAccount.settings.toString(), + // settingsPda.toString() + // ); + // assert.strictEqual(policyAccount.threshold, 1); + // assert.strictEqual(policyAccount.timeLock, 0); + + // // Create SPL token transfer instruction + // const tokenTransferIxn = createTransferInstruction( + // sourceTokenAccount, // source token account + // destinationTokenAccount, // destination token account + // sourceSmartAccountPda, // authority + // 500_000_000n // amount + // ); + // // Make the authority writable to make it compatible with the util function + // tokenTransferIxn.keys[2].isWritable = true; + + // // Create transaction message + // const message = new web3.TransactionMessage({ + // payerKey: sourceSmartAccountPda, + // recentBlockhash: (await connection.getLatestBlockhash()).blockhash, + // instructions: [tokenTransferIxn], + // }); + + // let syncPayload = utils.instructionsToSynchronousTransactionDetailsV2({ + // vaultPda: sourceSmartAccountPda, + // members: [members.voter.publicKey], + // transaction_instructions: [tokenTransferIxn], + // }); + + // const policyPayload: smartAccount.generated.PolicyPayload = { + // __kind: "ProgramInteraction", + // fields: [ + // { + // instructionConstraintIndices: new Uint8Array([0]), + // transactionPayload: { + // __kind: "SyncTransaction", + // fields: [ + // { + // accountIndex: 0, + // instructions: syncPayload.instructions, + // }, + // ], + // }, + // }, + // ], + // }; + + // // Attempt to do the same with a synchronous instruction + // signature = await smartAccount.rpc.executePolicyPayloadSync({ + // connection, + // feePayer: members.voter, + // policy: policyPda, + // accountIndex: 0, + // numSigners: 1, + // policyPayload: policyPayload, + // instruction_accounts: syncPayload.accounts, + // signers: [members.voter], + // programId, + // sendOptions: { + // skipPreflight: true, + // }, + // }); + // await connection.confirmTransaction(signature); + + // // + // // Airdrop SOL to the source smart account + // let airdropAmount = 2_000_000_000; + // let airdropSignature = await connection.requestAirdrop( + // sourceSmartAccountPda, + // 2_000_000_000 + // ); + // await connection.confirmTransaction(airdropSignature); + + // // Check the balances & policy state + // let sourceBalance = await connection.getTokenAccountBalance( + // sourceTokenAccount + // ); + // let destinationBalance = await connection.getTokenAccountBalance( + // destinationTokenAccount + // ); + // assert.strictEqual(sourceBalance.value.amount, "1000000000"); + // assert.strictEqual(destinationBalance.value.amount, "500000000"); + + // // Policy state + // let policyData = await Policy.fromAccountAddress(connection, policyPda, { + // commitment: "processed", + // }); + // policyState = policyData.policyState; + // programInteractionPolicy = policyState + // .fields[0] as smartAccount.generated.ProgramInteractionPolicy; + + // let modifiedTokenTransfer = tokenTransferIxn; + // modifiedTokenTransfer.keys[2].isWritable = true; + + // let synchronousPayload = + // utils.instructionsToSynchronousTransactionDetailsV2({ + // vaultPda: sourceSmartAccountPda, + // members: [members.voter.publicKey], + // transaction_instructions: [tokenTransferIxn], + // }); + + // let syncPolicyPayload: smartAccount.generated.PolicyPayload = { + // __kind: "ProgramInteraction", + // fields: [ + // { + // instructionConstraintIndices: new Uint8Array([0]), + // transactionPayload: { + // __kind: "SyncTransaction", + // fields: [ + // { + // accountIndex: 0, + // instructions: synchronousPayload.instructions, + // }, + // ], + // }, + // }, + // ], + // }; + + // // Attempt to do the same with a synchronous instruction + // signature = await smartAccount.rpc.executePolicyPayloadSync({ + // connection, + // feePayer: members.voter, + // policy: policyPda, + // accountIndex: 0, + // numSigners: 1, + // policyPayload: syncPolicyPayload, + // instruction_accounts: synchronousPayload.accounts, + // signers: [members.voter], + // programId, + // }); + // await connection.confirmTransaction(signature); + + // // Check the balances & policy state + // sourceBalance = await connection.getTokenAccountBalance(sourceTokenAccount); + // destinationBalance = await connection.getTokenAccountBalance( + // destinationTokenAccount + // ); + // assert.strictEqual(sourceBalance.value.amount, "500000000"); + // assert.strictEqual(destinationBalance.value.amount, "1000000000"); + + // let invalidTokenTransferIxn = createTransferInstruction( + // sourceTokenAccount, // source token account + // randomDestinationTokenAccount, // destination token account + // sourceSmartAccountPda, // authority + // 500_000_000n // amount + // ); + // // Make the authority writable to make it compatible with the util function + // invalidTokenTransferIxn.keys[2].isWritable = true; + + // let invalidSynchronousPayload = + // utils.instructionsToSynchronousTransactionDetailsV2({ + // vaultPda: sourceSmartAccountPda, + // members: [members.voter.publicKey], + // transaction_instructions: [invalidTokenTransferIxn], + // }); + + // let invalidSyncPolicyPayload: smartAccount.generated.PolicyPayload = { + // __kind: "ProgramInteraction", + // fields: [ + // { + // instructionConstraintIndices: new Uint8Array([0]), + // transactionPayload: { + // __kind: "SyncTransaction", + // fields: [ + // { + // accountIndex: 0, + // instructions: invalidSynchronousPayload.instructions, + // }, + // ], + // }, + // }, + // ], + // }; + + // // Try to transfer more than the policy allows; should fail + // await assert.rejects( + // smartAccount.rpc.executePolicyPayloadSync({ + // connection, + // feePayer: members.voter, + // policy: policyPda, + // accountIndex: 0, + // numSigners: 1, + // policyPayload: invalidSyncPolicyPayload, + // instruction_accounts: invalidSynchronousPayload.accounts, + // signers: [members.voter], + // programId, + // }), + // /ProgramInteractionInvalidNumericValue/i // This is the error from @file_context_0 + // ); + // }); + + it("Program Interaction Policy with pre/post hooks", async () => { + // Create new autonomous smart account with 1/1 threshold for easy testing + const settingsPda = ( + await createAutonomousMultisig({ + connection, + members, + threshold: 1, + timeLock: 0, + programId, + }) + )[0]; + + let [sourceSmartAccountPda] = await getSmartAccountPda({ + settingsPda, + accountIndex: 0, + programId, + }); + + let [destinationSmartAccountPda] = await getSmartAccountPda({ + settingsPda, + accountIndex: 1, + programId, + }); + + let [mint, _mintDecimals] = await createMintAndTransferTo( + connection, + members.voter, + sourceSmartAccountPda, + 1_500_000_000 + ); + + let sourceTokenAccount = await getAssociatedTokenAddressSync( + mint, + sourceSmartAccountPda, + true + ); + + let destinationTokenAccount = getAssociatedTokenAddressSync( + mint, + destinationSmartAccountPda, + true + ); + + await getOrCreateAssociatedTokenAccount( + connection, + members.voter, + mint, + destinationSmartAccountPda, + true + ); + + // Transaction index + const transactionIndex = BigInt(1); + + // Use seed 1 for the first policy on this smart account + const policySeed = 1; + + // Create policy creation payload + const policyCreationPayload: smartAccount.generated.PolicyCreationPayload = + { + __kind: "ProgramInteraction", + fields: [ + { + accountIndex: 0, + preHook: { + numExtraAccounts: 0, + accountConstraints: [], + instructionData: new Uint8Array([1, 2, 3]), + programId: new web3.PublicKey( + "noopb9bkMVfRPU8AsbpTUg8AQkHtKwMYZiFUjNRtMmV" + ), + passInnerInstructions: false, + }, + postHook: { + numExtraAccounts: 1, + accountConstraints: [], + instructionData: new Uint8Array([3, 4, 5]), + programId: new web3.PublicKey( + "noopb9bkMVfRPU8AsbpTUg8AQkHtKwMYZiFUjNRtMmV" + ), + passInnerInstructions: true, + }, + instructionsConstraints: [ + { + programId: TOKEN_PROGRAM_ID, + dataConstraints: [ + { + dataOffset: 0, + // Only allow TokenProgram.Transfer + dataValue: { __kind: "U8", fields: [3] }, + // Only allow TokenProgram.Transfer + operator: generated.DataOperator.Equals, + }, + ], + accountConstraints: [], + }, + ], + spendingLimits: [], + }, + ], + }; + + // Create settings transaction with PolicyCreate action + let signature = await smartAccount.rpc.createSettingsTransaction({ + connection, + feePayer: members.proposer, + settingsPda, + transactionIndex, + creator: members.proposer.publicKey, + actions: [ + { + __kind: "PolicyCreate", + seed: policySeed, + policyCreationPayload, + signers: [ + { + key: members.voter.publicKey, + permissions: { mask: 7 }, + }, + ], + threshold: 1, + timeLock: 0, + startTimestamp: null, + expirationArgs: null, + }, + ], + programId, + }); + await connection.confirmTransaction(signature); + + // Create proposal for the transaction + signature = await smartAccount.rpc.createProposal({ + connection, + feePayer: members.proposer, + settingsPda, + transactionIndex, + creator: members.proposer, + programId, + }); + await connection.confirmTransaction(signature); + + // Approve the proposal (1/1 threshold) + signature = await smartAccount.rpc.approveProposal({ + connection, + feePayer: members.voter, + settingsPda, + transactionIndex, + signer: members.voter, + programId, + }); + await connection.confirmTransaction(signature); + + // Get the policy PDA + const [policyPda] = smartAccount.getPolicyPda({ + settingsPda, + policySeed, + programId, + }); + // Execute the settings transaction + signature = await smartAccount.rpc.executeSettingsTransaction({ + connection, + feePayer: members.almighty, + settingsPda, + transactionIndex, + signer: members.almighty, + rentPayer: members.almighty, + policies: [policyPda], + sendOptions: { + skipPreflight: true, + }, + programId, + }); + await connection.confirmTransaction(signature); + + // Create SPL token transfer instruction + const tokenTransferIxn = createTransferInstruction( + sourceTokenAccount, // source token account + destinationTokenAccount, // destination token account + sourceSmartAccountPda, // authority + 500_000_000n // amount + ); + // Make the authority writable to make it compatible with the util function + tokenTransferIxn.keys[2].isWritable = true; + + // Pre hook accounts + const postHookAccounts = [ + { + pubkey: new web3.PublicKey( + "3DBe6CrgCNQ3ydaTRX8j3WenQRdQxkhj87Hqe2MAwwHx" + ), + isWritable: true, + isSigner: false, + }, + { + pubkey: new web3.PublicKey( + "noopb9bkMVfRPU8AsbpTUg8AQkHtKwMYZiFUjNRtMmV" + ), + isWritable: false, + isSigner: false, + }, + ]; + let preHookAccounts = [ + { + pubkey: new web3.PublicKey( + "noopb9bkMVfRPU8AsbpTUg8AQkHtKwMYZiFUjNRtMmV" + ), + isWritable: false, + isSigner: false, + }, + ]; + let syncPayload = + utils.instructionsToSynchronousTransactionDetailsV2WithHooks({ + vaultPda: sourceSmartAccountPda, + members: [members.voter.publicKey], + preHookAccounts: preHookAccounts, + postHookAccounts: postHookAccounts, + transaction_instructions: [tokenTransferIxn], + }); + + let syncPolicyPayload: smartAccount.generated.PolicyPayload = { + __kind: "ProgramInteraction", + fields: [ + { + instructionConstraintIndices: new Uint8Array([0]), + transactionPayload: { + __kind: "SyncTransaction", + fields: [ + { + accountIndex: 0, + instructions: syncPayload.instructions, + }, + ], + }, + }, + ], + }; + + // Execute the policy payload + signature = await smartAccount.rpc.executePolicyPayloadSync({ + connection, + feePayer: members.voter, + policy: policyPda, + accountIndex: 0, + numSigners: 1, + policyPayload: syncPolicyPayload, + instruction_accounts: syncPayload.accounts, + signers: [members.voter], + programId, + }); + await connection.confirmTransaction(signature); + + // Check the balances & policy state + let sourceBalance = await connection.getTokenAccountBalance( + sourceTokenAccount + ); + let destinationBalance = await connection.getTokenAccountBalance( + destinationTokenAccount + ); + assert.strictEqual(sourceBalance.value.amount, "1000000000"); + assert.strictEqual(destinationBalance.value.amount, "500000000"); + // Log signature + console.log("signature", signature); + }); +}); diff --git a/tests/suites/instructions/removePolicy.ts b/tests/suites/instructions/removePolicy.ts new file mode 100644 index 0000000..b6687c7 --- /dev/null +++ b/tests/suites/instructions/removePolicy.ts @@ -0,0 +1,215 @@ +import * as smartAccount from "@sqds/smart-account"; +import * as web3 from "@solana/web3.js"; +import assert from "assert"; +import { + createAutonomousMultisig, + createLocalhostConnection, + generateSmartAccountSigners, + getTestProgramId, + TestMembers, +} from "../../utils"; +import { AccountMeta } from "@solana/web3.js"; +const { Settings, Proposal, Policy } = smartAccount.accounts; +const programId = getTestProgramId(); +const connection = createLocalhostConnection(); + +describe("Flows / Remove Policy", () => { + let members: TestMembers; + + before(async () => { + members = await generateSmartAccountSigners(connection); + }); + + it("remove policy: InternalFundTransfer", async () => { + // Create new autonomous smart account with 1/1 threshold for easy testing + const settingsPda = ( + await createAutonomousMultisig({ + connection, + members, + threshold: 1, + timeLock: 0, + programId, + }) + )[0]; + + // Use seed 1 for the first policy on this smart account + const policySeed = 1; + + // Create policy creation payload + const policyCreationPayload: smartAccount.generated.PolicyCreationPayload = + { + __kind: "InternalFundTransfer", + fields: [ + { + sourceAccountIndices: new Uint8Array([0, 1]), // Allow transfers from account indices 0 and 1 + destinationAccountIndices: new Uint8Array([2, 3]), // Allow transfers to account indices 2 and 3 + allowedMints: [web3.PublicKey.default], // Allow native SOL transfers + }, + ], + }; + + const transactionIndex = BigInt(1); + + const [policyPda] = smartAccount.getPolicyPda({ + settingsPda, + policySeed, + programId, + }); + // Create settings transaction with PolicyCreate action + let signature = await smartAccount.rpc.createSettingsTransaction({ + connection, + feePayer: members.proposer, + settingsPda, + transactionIndex, + creator: members.proposer.publicKey, + actions: [ + { + __kind: "PolicyCreate", + seed: policySeed, + policyCreationPayload, + signers: [ + { + key: members.voter.publicKey, + permissions: { mask: 7 }, + }, + ], + threshold: 1, + timeLock: 0, + startTimestamp: null, + expirationArgs: null, + }, + ], + programId, + }); + await connection.confirmTransaction(signature); + + // Create proposal for the transaction + signature = await smartAccount.rpc.createProposal({ + connection, + feePayer: members.proposer, + settingsPda, + transactionIndex, + creator: members.proposer, + programId, + }); + await connection.confirmTransaction(signature); + + // Approve the proposal (1/1 threshold) + signature = await smartAccount.rpc.approveProposal({ + connection, + feePayer: members.voter, + settingsPda, + transactionIndex, + signer: members.voter, + programId, + }); + await connection.confirmTransaction(signature); + + // Execute the settings transaction + signature = await smartAccount.rpc.executeSettingsTransaction({ + connection, + feePayer: members.almighty, + settingsPda, + transactionIndex, + signer: members.almighty, + rentPayer: members.almighty, + policies: [policyPda], + programId, + }); + await connection.confirmTransaction(signature); + // Check settings counter incremented + const settingsAccount = await Settings.fromAccountAddress( + connection, + settingsPda + ); + assert.strictEqual(settingsAccount.policySeed?.toString(), "1"); + + // Create a proposal for the policy + const policyPayload: smartAccount.generated.PolicyPayload = { + __kind: "InternalFundTransfer", + fields: [ + { + sourceIndex: 0, + destinationIndex: 2, + mint: web3.PublicKey.default, + decimals: 9, + // 1 SOL + amount: 1_000_000_000, + }, + ], + }; + // Create a transaction + signature = await smartAccount.rpc.createPolicyTransaction({ + connection, + feePayer: members.voter, + policy: policyPda, + accountIndex: 0, + transactionIndex: BigInt(1), + creator: members.voter.publicKey, + policyPayload, + sendOptions: { + skipPreflight: true, + }, + programId, + }); + await connection.confirmTransaction(signature); + // Assert the policies tx index increased + let policyAccount = await Policy.fromAccountAddress(connection, policyPda); + assert.strictEqual(policyAccount.transactionIndex.toString(), "1"); + assert.strictEqual(policyAccount.staleTransactionIndex?.toString(), "0"); + + // Remove the policy + let remainingAccounts: AccountMeta[] = []; + remainingAccounts.push({ + pubkey: policyPda, + isWritable: true, + isSigner: false, + }); + + let removeSignature = await smartAccount.rpc.executeSettingsTransactionSync( + { + connection, + feePayer: members.almighty, + settingsPda, + actions: [ + { + __kind: "PolicyRemove", + policy: policyPda, + }, + ], + signers: [members.almighty], + remainingAccounts, + programId, + } + ); + await connection.confirmTransaction(removeSignature); + // Check the policy is closed + let transactionPda = smartAccount.getTransactionPda({ + settingsPda: policyPda, + transactionIndex: BigInt(1), + programId, + })[0]; + let transactionAccount = await connection.getAccountInfo(transactionPda); + assert.strictEqual( + transactionAccount?.owner.toString(), + programId.toString() + ); + + let closeSignature = await smartAccount.rpc.closeEmptyPolicyTransaction({ + connection, + feePayer: members.almighty, + emptyPolicy: policyPda, + transactionRentCollector: members.voter.publicKey, + transactionIndex: BigInt(1), + programId, + }); + await connection.confirmTransaction(closeSignature); + + transactionAccount = await connection.getAccountInfo(transactionPda); + assert.strictEqual( + transactionAccount, + null, + "Transaction account should be closed" + ); + }); +}); diff --git a/tests/suites/instructions/settingsChangePolicy.ts b/tests/suites/instructions/settingsChangePolicy.ts new file mode 100644 index 0000000..431530a --- /dev/null +++ b/tests/suites/instructions/settingsChangePolicy.ts @@ -0,0 +1,277 @@ +import * as smartAccount from "@sqds/smart-account"; +import * as web3 from "@solana/web3.js"; +import assert from "assert"; +import { + createAutonomousMultisig, + createLocalhostConnection, + generateSmartAccountSigners, + getTestProgramId, + TestMembers, +} from "../../utils"; +const { Settings, Proposal, Policy } = smartAccount.accounts; +const programId = getTestProgramId(); +const connection = createLocalhostConnection(); + +describe("Flow / SettingsChangePolicy", () => { + let members: TestMembers; + + before(async () => { + members = await generateSmartAccountSigners(connection); + }); + + it("create policy: SettingsChange", async () => { + // Create new autonomous smart account with 1/1 threshold + const settingsPda = ( + await createAutonomousMultisig({ + connection, + members, + threshold: 1, + timeLock: 0, + programId, + }) + )[0]; + + const policySeed = 1; + + let allowedKeypair = web3.Keypair.generate(); + const policyCreationPayload: smartAccount.generated.PolicyCreationPayload = + { + __kind: "SettingsChange", + fields: [ + { + actions: [ + { + __kind: "AddSigner", + newSigner: allowedKeypair.publicKey, + newSignerPermissions: { + mask: 1, // Allow only voting + }, + }, + { __kind: "ChangeThreshold" }, + ], // Allow threshold changes + }, + ], + }; + + const transactionIndex = BigInt(1); + + const [policyPda] = smartAccount.getPolicyPda({ + settingsPda, + policySeed, + programId, + }); + + let signature = await smartAccount.rpc.createSettingsTransaction({ + connection, + feePayer: members.proposer, + settingsPda, + transactionIndex, + creator: members.proposer.publicKey, + actions: [ + { + __kind: "PolicyCreate", + seed: policySeed, + policyCreationPayload, + signers: [ + { + key: members.voter.publicKey, + permissions: { mask: 7 }, + }, + ], + threshold: 1, + timeLock: 0, + startTimestamp: Date.now() / 1000, + expirationArgs: null, + }, + ], + programId, + }); + await connection.confirmTransaction(signature); + + // Create and approve proposal + signature = await smartAccount.rpc.createProposal({ + connection, + feePayer: members.proposer, + settingsPda, + transactionIndex, + creator: members.proposer, + programId, + }); + await connection.confirmTransaction(signature); + + signature = await smartAccount.rpc.approveProposal({ + connection, + feePayer: members.voter, + settingsPda, + transactionIndex, + signer: members.voter, + programId, + }); + await connection.confirmTransaction(signature); + + // Execute settings transaction + signature = await smartAccount.rpc.executeSettingsTransaction({ + connection, + feePayer: members.almighty, + settingsPda, + transactionIndex, + signer: members.almighty, + rentPayer: members.almighty, + policies: [policyPda], + sendOptions: { skipPreflight: true }, + programId, + }); + await connection.confirmTransaction(signature); + + // Check settings counter incremented + const settingsAccount = await Settings.fromAccountAddress( + connection, + settingsPda + ); + assert.strictEqual(settingsAccount.policySeed?.toString(), "1"); + + const policyAccount = await Policy.fromAccountAddress( + connection, + policyPda + ); + assert.strictEqual( + policyAccount.settings.toString(), + settingsPda.toString() + ); + assert.strictEqual(policyAccount.threshold, 1); + + const instructionAccounts = [ + { + pubkey: members.voter.publicKey, + isWritable: false, + isSigner: true, + }, + { + pubkey: settingsPda, + isWritable: true, + isSigner: false, + }, + // Rent payer + { + pubkey: members.voter.publicKey, + isWritable: true, + isSigner: true, + }, + + // System program + { + pubkey: web3.SystemProgram.programId, + isWritable: false, + isSigner: false, + }, + // Program + { + pubkey: programId, + isWritable: false, + isSigner: false, + }, + ]; + // Try to add the new signer to the policy + signature = await smartAccount.rpc.executePolicyPayloadSync({ + connection, + feePayer: members.almighty, + policy: policyPda, + accountIndex: 0, + numSigners: 1, + signers: [members.voter], + programId, + policyPayload: { + __kind: "SettingsChange", + fields: [ + { + actionIndex: new Uint8Array([0]), + actions: [ + { + __kind: "AddSigner", + newSigner: { + key: allowedKeypair.publicKey, + permissions: { mask: 1 }, + }, + }, + ], + }, + ], + }, + instruction_accounts: instructionAccounts, + }); + + // Wrong action index + await assert.rejects( + smartAccount.rpc.executePolicyPayloadSync({ + connection, + feePayer: members.almighty, + policy: policyPda, + accountIndex: 0, + numSigners: 1, + signers: [members.voter], + programId, + policyPayload: { + __kind: "SettingsChange", + fields: [ + { + // Change threshold + actionIndex: new Uint8Array([1]), + actions: [ + { + __kind: "AddSigner", + newSigner: { + key: allowedKeypair.publicKey, + permissions: { mask: 1 }, + }, + }, + ], + }, + ], + }, + instruction_accounts: instructionAccounts, + }), + (error: any) => { + error.toString().includes("SettingsChangeActionMismatch"); + return true; + } + ); + + // Wrong action index + await assert.rejects( + smartAccount.rpc.executePolicyPayloadSync({ + connection, + feePayer: members.almighty, + policy: policyPda, + accountIndex: 0, + numSigners: 1, + signers: [members.voter], + programId, + policyPayload: { + __kind: "SettingsChange", + fields: [ + { + // Change threshold + actionIndex: new Uint8Array([0]), + actions: [ + { + __kind: "AddSigner", + newSigner: { + key: allowedKeypair.publicKey, + permissions: { mask: 7 }, + }, + }, + ], + }, + ], + }, + instruction_accounts: instructionAccounts, + }), + (error: any) => { + error + .toString() + .includes("SettingsChangeAddSignerPermissionsViolation"); + return true; + } + ); + }); +}); diff --git a/tests/suites/instructions/settingsTransactionAccountsClose.ts b/tests/suites/instructions/settingsTransactionAccountsClose.ts index 7aed791..920dcdc 100644 --- a/tests/suites/instructions/settingsTransactionAccountsClose.ts +++ b/tests/suites/instructions/settingsTransactionAccountsClose.ts @@ -538,6 +538,7 @@ describe("Instructions / settings_transaction_accounts_close", () => { transactionIndex: 1n, programId, })[0], + program: programId, }, programId ); @@ -666,6 +667,7 @@ describe("Instructions / settings_transaction_accounts_close", () => { transactionIndex: 1n, programId, })[0], + program: programId, }, programId ); @@ -713,6 +715,7 @@ describe("Instructions / settings_transaction_accounts_close", () => { transactionIndex: approvedTransactionIndex, programId, })[0], + program: programId, }, programId ); diff --git a/tests/suites/instructions/smartAccountCreate.ts b/tests/suites/instructions/smartAccountCreate.ts index 81444d2..c7fa32a 100644 --- a/tests/suites/instructions/smartAccountCreate.ts +++ b/tests/suites/instructions/smartAccountCreate.ts @@ -534,7 +534,7 @@ describe("Instructions / smart_account_create", () => { await connection.confirmTransaction(signature); const creatorBalancePost = await connection.getBalance(creator.publicKey); - const rentAndNetworkFee = 2698520; + const rentAndNetworkFee = 2754200; assert.strictEqual( creatorBalancePost, diff --git a/tests/suites/instructions/spendingLimitPolicy.ts b/tests/suites/instructions/spendingLimitPolicy.ts new file mode 100644 index 0000000..38dc090 --- /dev/null +++ b/tests/suites/instructions/spendingLimitPolicy.ts @@ -0,0 +1,366 @@ +import * as smartAccount from "@sqds/smart-account"; +import * as web3 from "@solana/web3.js"; +import assert from "assert"; +import { + createAutonomousMultisig, + createLocalhostConnection, + createMintAndTransferTo, + generateSmartAccountSigners, + getTestProgramId, + TestMembers, +} from "../../utils"; +import { AccountMeta } from "@solana/web3.js"; +import { getSmartAccountPda, generated, utils } from "@sqds/smart-account"; +import { + createAssociatedTokenAccount, + createTransferInstruction, + getAssociatedTokenAddressSync, + getOrCreateAssociatedTokenAccount, + TOKEN_PROGRAM_ID, + transfer, +} from "@solana/spl-token"; + +const { Settings, Proposal, Policy } = smartAccount.accounts; +const programId = getTestProgramId(); +const connection = createLocalhostConnection(); + +describe("Flow / SpendingLimitPolicy", () => { + let members: TestMembers; + + before(async () => { + members = await generateSmartAccountSigners(connection); + }); + + it("Spending Limit Policy", async () => { + // Create new autonomous smart account with 1/1 threshold for easy testing + const settingsPda = ( + await createAutonomousMultisig({ + connection, + members, + threshold: 1, + timeLock: 0, + programId, + }) + )[0]; + + // Use seed 1 for the first policy on this smart account + const policySeed = 1; + + let [sourceSmartAccountPda] = await getSmartAccountPda({ + settingsPda, + accountIndex: 0, + programId, + }); + + let [destinationSmartAccountPda] = await getSmartAccountPda({ + settingsPda, + accountIndex: 1, + programId, + }); + + let [mint, mintDecimals] = await createMintAndTransferTo( + connection, + members.voter, + sourceSmartAccountPda, + 1_000_000_000 + ); + + let sourceTokenAccount = await getAssociatedTokenAddressSync( + mint, + sourceSmartAccountPda, + true + ); + let destinationTokenAccount = getAssociatedTokenAddressSync( + mint, + destinationSmartAccountPda, + true + ); + + await getOrCreateAssociatedTokenAccount( + connection, + members.voter, + mint, + destinationSmartAccountPda, + true + ); + + // Create policy creation payload + const policyCreationPayload: smartAccount.generated.PolicyCreationPayload = + { + __kind: "SpendingLimit", + fields: [ + { + mint, + sourceAccountIndex: 0, + destinations: [destinationSmartAccountPda], + timeConstraints: { + start: 0, + expiration: null, + period: { __kind: "Daily" }, + accumulateUnused: false, + }, + quantityConstraints: { + maxPerPeriod: 1_000_000_000, + maxPerUse: 250_000_000, + enforceExactQuantity: true, + }, + usageState: null, + }, + ], + }; + + const transactionIndex = BigInt(1); + + const [policyPda] = smartAccount.getPolicyPda({ + settingsPda, + policySeed, + programId, + }); + // Create settings transaction with PolicyCreate action + let signature = await smartAccount.rpc.createSettingsTransaction({ + connection, + feePayer: members.proposer, + settingsPda, + transactionIndex, + creator: members.proposer.publicKey, + actions: [ + { + __kind: "PolicyCreate", + seed: policySeed, + policyCreationPayload, + signers: [ + { + key: members.voter.publicKey, + permissions: { mask: 7 }, + }, + ], + threshold: 1, + timeLock: 0, + startTimestamp: null, + expirationArgs: null, + }, + ], + programId, + }); + await connection.confirmTransaction(signature); + + // Create proposal for the transaction + signature = await smartAccount.rpc.createProposal({ + connection, + feePayer: members.proposer, + settingsPda, + transactionIndex, + creator: members.proposer, + programId, + }); + await connection.confirmTransaction(signature); + + // Approve the proposal (1/1 threshold) + signature = await smartAccount.rpc.approveProposal({ + connection, + feePayer: members.voter, + settingsPda, + transactionIndex, + signer: members.voter, + programId, + }); + await connection.confirmTransaction(signature); + + // Execute the settings transaction + signature = await smartAccount.rpc.executeSettingsTransaction({ + connection, + feePayer: members.almighty, + settingsPda, + transactionIndex, + signer: members.almighty, + rentPayer: members.almighty, + policies: [policyPda], + sendOptions: { + skipPreflight: true, + }, + programId, + }); + await connection.confirmTransaction(signature); + + const policyAccount = await Policy.fromAccountAddress( + connection, + policyPda + ); + assert.strictEqual( + policyAccount.settings.toString(), + settingsPda.toString() + ); + assert.strictEqual(policyAccount.threshold, 1); + assert.strictEqual(policyAccount.timeLock, 0); + + // Try transfer SOL via creating a transaction and proposal + const policyTransactionIndex = BigInt(1); + + const policyPayload: smartAccount.generated.PolicyPayload = { + __kind: "SpendingLimit", + fields: [ + { + amount: 250_000_000, + destination: destinationSmartAccountPda, + decimals: mintDecimals, + }, + ], + }; + + // Create a transaction + signature = await smartAccount.rpc.createPolicyTransaction({ + connection, + feePayer: members.voter, + policy: policyPda, + accountIndex: 0, + transactionIndex: policyTransactionIndex, + creator: members.voter.publicKey, + policyPayload, + sendOptions: { + skipPreflight: true, + }, + programId, + }); + await connection.confirmTransaction(signature); + + // Create proposal for the transaction + signature = await smartAccount.rpc.createProposal({ + connection, + feePayer: members.voter, + settingsPda: policyPda, + transactionIndex: policyTransactionIndex, + creator: members.voter, + programId, + }); + await connection.confirmTransaction(signature); + + // Approve the proposal (1/1 threshold) + signature = await smartAccount.rpc.approveProposal({ + connection, + feePayer: members.voter, + settingsPda: policyPda, + transactionIndex: policyTransactionIndex, + signer: members.voter, + programId, + }); + await connection.confirmTransaction(signature); + + let remainingAccounts: AccountMeta[] = []; + + remainingAccounts.push({ + pubkey: sourceSmartAccountPda, + isWritable: false, + isSigner: false, + }); + remainingAccounts.push({ + pubkey: sourceTokenAccount, + isWritable: true, + isSigner: false, + }); + remainingAccounts.push({ + pubkey: destinationTokenAccount, + isWritable: true, + isSigner: false, + }); + remainingAccounts.push({ + pubkey: mint, + isWritable: false, + isSigner: false, + }); + remainingAccounts.push({ + pubkey: TOKEN_PROGRAM_ID, + isWritable: false, + isSigner: false, + }); + + // Execute the transaction + signature = await smartAccount.rpc.executePolicyTransaction({ + connection, + feePayer: members.voter, + policy: policyPda, + transactionIndex: policyTransactionIndex, + signer: members.voter.publicKey, + anchorRemainingAccounts: remainingAccounts, + programId, + }); + await connection.confirmTransaction(signature); + + // Check the balances + let sourceBalance = await connection.getTokenAccountBalance( + sourceTokenAccount + ); + let destinationBalance = await connection.getTokenAccountBalance( + destinationTokenAccount + ); + assert.strictEqual(sourceBalance.value.amount, "750000000"); + assert.strictEqual(destinationBalance.value.amount, "250000000"); + + let syncPolicyPayload: smartAccount.generated.PolicyPayload = { + __kind: "SpendingLimit", + fields: [ + { + amount: 250_000_000, + destination: destinationSmartAccountPda, + decimals: mintDecimals, + }, + ], + }; + + // Attempt to do the same with a synchronous instruction + let syncRemainingAccounts = remainingAccounts; + // Sync instruction expects the voter to be a part of the remaining accounts + syncRemainingAccounts.unshift({ + pubkey: members.voter.publicKey, + isWritable: false, + isSigner: true, + }); + signature = await smartAccount.rpc.executePolicyPayloadSync({ + connection, + feePayer: members.voter, + policy: policyPda, + accountIndex: 0, + numSigners: 1, + policyPayload: syncPolicyPayload, + instruction_accounts: syncRemainingAccounts, + signers: [members.voter], + programId, + }); + await connection.confirmTransaction(signature); + + // Check the balances + sourceBalance = await connection.getTokenAccountBalance(sourceTokenAccount); + destinationBalance = await connection.getTokenAccountBalance( + destinationTokenAccount + ); + assert.strictEqual(sourceBalance.value.amount, "500000000"); + assert.strictEqual(destinationBalance.value.amount, "500000000"); + + let invalidPayload: smartAccount.generated.PolicyPayload = { + __kind: "SpendingLimit", + fields: [ + { + amount: 250_000_001, + destination: destinationSmartAccountPda, + decimals: mintDecimals, + }, + ], + }; + // Attempt to use non-exact amount + assert.rejects( + smartAccount.rpc.executePolicyPayloadSync({ + connection, + feePayer: members.voter, + policy: policyPda, + accountIndex: 0, + numSigners: 1, + policyPayload: invalidPayload, + instruction_accounts: syncRemainingAccounts, + signers: [members.voter], + programId, + }), + (error: any) => { + error.toString().includes("SpendingLimitViolatesMaxPerUseConstraint"); + } + ); + }); +}); diff --git a/tests/suites/instructions/transactionAccountsClose.ts b/tests/suites/instructions/transactionAccountsClose.ts index f3bd4b6..a9b9b47 100644 --- a/tests/suites/instructions/transactionAccountsClose.ts +++ b/tests/suites/instructions/transactionAccountsClose.ts @@ -711,7 +711,7 @@ describe("Instructions / transaction_accounts_close", () => { // Manually construct an instruction that uses the proposal account from the other smartAccount. const ix = smartAccount.generated.createCloseTransactionInstruction( { - settings: settingsPda, + consensusAccount: settingsPda, transactionRentCollector: members.proposer.publicKey, proposalRentCollector: members.proposer.publicKey, proposal: smartAccount.getProposalPda({ @@ -724,6 +724,7 @@ describe("Instructions / transaction_accounts_close", () => { transactionIndex: 1n, programId, })[0], + program: programId, }, programId ); @@ -880,7 +881,7 @@ describe("Instructions / transaction_accounts_close", () => { // Manually construct an instruction that uses transaction that doesn't match proposal. const ix = smartAccount.generated.createCloseTransactionInstruction( { - settings: settingsPda, + consensusAccount: settingsPda, transactionRentCollector: members.proposer.publicKey, proposalRentCollector: members.proposer.publicKey, proposal: smartAccount.getProposalPda({ @@ -893,6 +894,7 @@ describe("Instructions / transaction_accounts_close", () => { transactionIndex: 1n, programId, })[0], + program: programId, }, programId ); @@ -926,7 +928,7 @@ describe("Instructions / transaction_accounts_close", () => { // Manually construct an instruction that uses transaction that doesn't match proposal. const ix = smartAccount.generated.createCloseTransactionInstruction( { - settings: settingsPda, + consensusAccount: settingsPda, transactionRentCollector: members.proposer.publicKey, proposalRentCollector: members.proposer.publicKey, proposal: smartAccount.getProposalPda({ @@ -940,6 +942,7 @@ describe("Instructions / transaction_accounts_close", () => { transactionIndex: approvedTransactionIndex, programId, })[0], + program: programId, }, programId ); diff --git a/tests/suites/instructions/transactionBufferClose.ts b/tests/suites/instructions/transactionBufferClose.ts index d43a47a..8fbd29f 100644 --- a/tests/suites/instructions/transactionBufferClose.ts +++ b/tests/suites/instructions/transactionBufferClose.ts @@ -91,13 +91,13 @@ describe("Instructions / transaction_buffer_close", () => { ); const messageHash = crypto .createHash("sha256") - .update(messageBuffer) + .update(messageBuffer.transactionMessageBytes) .digest(); const createIx = smartAccount.generated.createCreateTransactionBufferInstruction( { - settings: settingsPda, + consensusAccount: settingsPda, transactionBuffer, creator: members.proposer.publicKey, rentPayer: members.proposer.publicKey, @@ -108,9 +108,9 @@ describe("Instructions / transaction_buffer_close", () => { accountIndex: 0, bufferIndex: Number(bufferIndex), finalBufferHash: Array.from(messageHash), - finalBufferSize: messageBuffer.length, - buffer: messageBuffer, - } as CreateTransactionBufferArgs, + finalBufferSize: messageBuffer.transactionMessageBytes.byteLength, + buffer: messageBuffer.transactionMessageBytes, + }, } as CreateTransactionBufferInstructionArgs, programId ); @@ -135,7 +135,7 @@ describe("Instructions / transaction_buffer_close", () => { const closeIx = smartAccount.generated.createCloseTransactionBufferInstruction( { - settings: settingsPda, + consensusAccount: settingsPda, transactionBuffer, creator: members.voter.publicKey, }, @@ -164,7 +164,7 @@ describe("Instructions / transaction_buffer_close", () => { const closeIx = smartAccount.generated.createCloseTransactionBufferInstruction( { - settings: settingsPda, + consensusAccount: settingsPda, transactionBuffer, creator: members.proposer.publicKey, }, diff --git a/tests/suites/instructions/transactionBufferCreate.ts b/tests/suites/instructions/transactionBufferCreate.ts index 1d1dad6..8683bd9 100644 --- a/tests/suites/instructions/transactionBufferCreate.ts +++ b/tests/suites/instructions/transactionBufferCreate.ts @@ -101,12 +101,12 @@ describe("Instructions / transaction_buffer_create", () => { // Convert to a SHA256 hash. const messageHash = crypto .createHash("sha256") - .update(messageBuffer) + .update(messageBuffer.transactionMessageBytes) .digest(); const ix = smartAccount.generated.createCreateTransactionBufferInstruction( { - settings: settingsPda, + consensusAccount: settingsPda, transactionBuffer, creator: members.proposer.publicKey, rentPayer: members.proposer.publicKey, @@ -119,8 +119,8 @@ describe("Instructions / transaction_buffer_create", () => { createKey: Keypair.generate(), // Must be a SHA256 hash of the message buffer. finalBufferHash: Array.from(messageHash), - finalBufferSize: messageBuffer.length, - buffer: messageBuffer, + finalBufferSize: messageBuffer.transactionMessageBytes.byteLength, + buffer: messageBuffer.transactionMessageBytes, } as CreateTransactionBufferArgs, } as CreateTransactionBufferInstructionArgs, programId @@ -167,7 +167,7 @@ describe("Instructions / transaction_buffer_create", () => { const ix = smartAccount.generated.createCloseTransactionBufferInstruction( { - settings: settingsPda, + consensusAccount: settingsPda, transactionBuffer, creator: members.proposer.publicKey, }, @@ -237,12 +237,12 @@ describe("Instructions / transaction_buffer_create", () => { // Convert to a SHA256 hash. const messageHash = crypto .createHash("sha256") - .update(messageBuffer) + .update(messageBuffer.transactionMessageBytes) .digest(); const ix = smartAccount.generated.createCreateTransactionBufferInstruction( { - settings: settingsPda, + consensusAccount: settingsPda, transactionBuffer, creator: members.proposer.publicKey, rentPayer: members.proposer.publicKey, @@ -255,8 +255,8 @@ describe("Instructions / transaction_buffer_create", () => { createKey: Keypair.generate(), // Must be a SHA256 hash of the message buffer. finalBufferHash: Array.from(messageHash), - finalBufferSize: messageBuffer.length, - buffer: messageBuffer, + finalBufferSize: messageBuffer.transactionMessageBytes.byteLength, + buffer: messageBuffer.transactionMessageBytes, } as CreateTransactionBufferArgs, } as CreateTransactionBufferInstructionArgs, programId @@ -288,7 +288,7 @@ describe("Instructions / transaction_buffer_create", () => { const ix2 = smartAccount.generated.createCloseTransactionBufferInstruction( { - settings: settingsPda, + consensusAccount: settingsPda, transactionBuffer, creator: members.proposer.publicKey, }, @@ -369,13 +369,13 @@ describe("Instructions / transaction_buffer_create", () => { // Create a hash of the message buffer const messageHash = crypto .createHash("sha256") - .update(messageBuffer) + .update(messageBuffer.transactionMessageBytes) .digest(); // Create the instruction to create a transaction buffer const ix = smartAccount.generated.createCreateTransactionBufferInstruction( { - settings: settingsPda, + consensusAccount: settingsPda, transactionBuffer, creator: nonMember.publicKey, rentPayer: nonMember.publicKey, @@ -386,8 +386,8 @@ describe("Instructions / transaction_buffer_create", () => { bufferIndex: bufferIndex, accountIndex: 0, finalBufferHash: Array.from(messageHash), - finalBufferSize: messageBuffer.length, - buffer: messageBuffer, + finalBufferSize: messageBuffer.transactionMessageBytes.byteLength, + buffer: messageBuffer.transactionMessageBytes, } as CreateTransactionBufferArgs, } as CreateTransactionBufferInstructionArgs, programId @@ -457,13 +457,13 @@ describe("Instructions / transaction_buffer_create", () => { // Create a hash of the message buffer const messageHash = crypto .createHash("sha256") - .update(messageBuffer) + .update(messageBuffer.transactionMessageBytes) .digest(); // Create the instruction to create a transaction buffer const ix = smartAccount.generated.createCreateTransactionBufferInstruction( { - settings: settingsPda, + consensusAccount: settingsPda, transactionBuffer, creator: memberWithoutInitiatePermissions.publicKey, rentPayer: memberWithoutInitiatePermissions.publicKey, @@ -474,8 +474,8 @@ describe("Instructions / transaction_buffer_create", () => { bufferIndex: bufferIndex, accountIndex: 0, finalBufferHash: Array.from(messageHash), - finalBufferSize: messageBuffer.length, - buffer: messageBuffer, + finalBufferSize: messageBuffer.transactionMessageBytes.byteLength, + buffer: messageBuffer.transactionMessageBytes, } as CreateTransactionBufferArgs, } as CreateTransactionBufferInstructionArgs, programId @@ -544,13 +544,13 @@ describe("Instructions / transaction_buffer_create", () => { // Create a hash of the message buffer const messageHash = crypto .createHash("sha256") - .update(messageBuffer) + .update(messageBuffer.transactionMessageBytes) .digest(); // Create the instruction to create a transaction buffer const ix = smartAccount.generated.createCreateTransactionBufferInstruction( { - settings: settingsPda, + consensusAccount: settingsPda, transactionBuffer, creator: members.proposer.publicKey, rentPayer: members.proposer.publicKey, @@ -561,8 +561,8 @@ describe("Instructions / transaction_buffer_create", () => { bufferIndex: 0, accountIndex: 0, finalBufferHash: Array.from(messageHash), - finalBufferSize: messageBuffer.length, - buffer: messageBuffer, + finalBufferSize: messageBuffer.transactionMessageBytes.byteLength, + buffer: messageBuffer.transactionMessageBytes, } as CreateTransactionBufferArgs, } as CreateTransactionBufferInstructionArgs, programId @@ -616,7 +616,7 @@ describe("Instructions / transaction_buffer_create", () => { // Create the instruction to create a transaction buffer const ix = smartAccount.generated.createCreateTransactionBufferInstruction( { - settings: settingsPda, + consensusAccount: settingsPda, transactionBuffer, creator: members.proposer.publicKey, rentPayer: members.proposer.publicKey, diff --git a/tests/suites/instructions/transactionBufferExtend.ts b/tests/suites/instructions/transactionBufferExtend.ts index be05ef5..60b60be 100644 --- a/tests/suites/instructions/transactionBufferExtend.ts +++ b/tests/suites/instructions/transactionBufferExtend.ts @@ -104,13 +104,13 @@ describe("Instructions / transaction_buffer_extend", () => { const messageHash = crypto .createHash("sha256") - .update(messageBuffer) + .update(messageBuffer.transactionMessageBytes) .digest(); const createIx = smartAccount.generated.createCreateTransactionBufferInstruction( { - settings: settingsPda, + consensusAccount: settingsPda, transactionBuffer, creator: creator.publicKey, rentPayer: creator.publicKey, @@ -121,8 +121,8 @@ describe("Instructions / transaction_buffer_extend", () => { bufferIndex: Number(transactionIndex), accountIndex: 0, finalBufferHash: Array.from(messageHash), - finalBufferSize: messageBuffer.length, - buffer: messageBuffer.slice(0, 750), + finalBufferSize: messageBuffer.transactionMessageBytes.byteLength, + buffer: messageBuffer.transactionMessageBytes.slice(0, 750), } as CreateTransactionBufferArgs, } as CreateTransactionBufferInstructionArgs, programId @@ -153,7 +153,7 @@ describe("Instructions / transaction_buffer_extend", () => { const closeIx = smartAccount.generated.createCloseTransactionBufferInstruction( { - settings: settingsPda, + consensusAccount: settingsPda, transactionBuffer, creator: creator.publicKey, }, @@ -220,15 +220,15 @@ describe("Instructions / transaction_buffer_extend", () => { // Convert message buffer to a SHA256 hash. const messageHash = crypto .createHash("sha256") - .update(messageBuffer) + .update(messageBuffer.transactionMessageBytes) .digest(); // Slice the first 750 bytes of the message buffer. - const firstHalf = messageBuffer.slice(0, 750); + const firstHalf = messageBuffer.transactionMessageBytes.slice(0, 750); const ix = smartAccount.generated.createCreateTransactionBufferInstruction( { - settings: settingsPda, + consensusAccount: settingsPda, transactionBuffer, creator: members.proposer.publicKey, rentPayer: members.proposer.publicKey, @@ -240,7 +240,7 @@ describe("Instructions / transaction_buffer_extend", () => { accountIndex: 0, // Must be a SHA256 hash of the message buffer. finalBufferHash: Array.from(messageHash), - finalBufferSize: messageBuffer.length, + finalBufferSize: messageBuffer.transactionMessageBytes.byteLength, buffer: firstHalf, } as CreateTransactionBufferArgs, } as CreateTransactionBufferInstructionArgs, @@ -285,12 +285,15 @@ describe("Instructions / transaction_buffer_extend", () => { assert.equal(txBufferDeser1.buffer.length, 750); // Slice that last bytes of the message buffer. - const secondHalf = messageBuffer.slice(750, messageBuffer.byteLength); + const secondHalf = messageBuffer.transactionMessageBytes.slice( + 750, + messageBuffer.transactionMessageBytes.byteLength + ); const secondIx = smartAccount.generated.createExtendTransactionBufferInstruction( { - settings: settingsPda, + consensusAccount: settingsPda, transactionBuffer, creator: members.proposer.publicKey, }, @@ -329,7 +332,10 @@ describe("Instructions / transaction_buffer_extend", () => { ); // Buffer fully uploaded. Check that length is as expected. - assert.equal(txBufferDeser2.buffer.length, messageBuffer.byteLength); + assert.equal( + txBufferDeser2.buffer.length, + messageBuffer.transactionMessageBytes.byteLength + ); // Close the transaction buffer account. await closeTransactionBuffer(members.proposer, transactionBuffer); @@ -355,7 +361,7 @@ describe("Instructions / transaction_buffer_extend", () => { const dummyData = Buffer.alloc(100, 1); const ix = smartAccount.generated.createExtendTransactionBufferInstruction( { - settings: settingsPda, + consensusAccount: settingsPda, transactionBuffer, creator: nonMember.publicKey, }, @@ -399,7 +405,7 @@ describe("Instructions / transaction_buffer_extend", () => { const largeData = Buffer.alloc(500, 1); const ix = smartAccount.generated.createExtendTransactionBufferInstruction( { - settings: settingsPda, + consensusAccount: settingsPda, transactionBuffer, creator: members.almighty.publicKey, }, @@ -444,7 +450,7 @@ describe("Instructions / transaction_buffer_extend", () => { const extendIx = smartAccount.generated.createExtendTransactionBufferInstruction( { - settings: settingsPda, + consensusAccount: settingsPda, transactionBuffer, creator: members.almighty.publicKey, }, diff --git a/tests/suites/instructions/transactionCreateFromBuffer.ts b/tests/suites/instructions/transactionCreateFromBuffer.ts index e218d81..052f204 100644 --- a/tests/suites/instructions/transactionCreateFromBuffer.ts +++ b/tests/suites/instructions/transactionCreateFromBuffer.ts @@ -24,6 +24,7 @@ import { createAutonomousSmartAccountV2, createLocalhostConnection, createTestTransferInstruction, + extractTransactionPayloadDetails, generateSmartAccountSigners, getLogs, getNextAccountIndex, @@ -112,15 +113,15 @@ describe("Instructions / transaction_create_from_buffer", () => { const messageHash = crypto .createHash("sha256") - .update(messageBuffer) + .update(messageBuffer.transactionMessageBytes) .digest(); // Slice the message buffer into two parts. - const firstSlice = messageBuffer.slice(0, 700); + const firstSlice = messageBuffer.transactionMessageBytes.slice(0, 700); const ix = smartAccount.generated.createCreateTransactionBufferInstruction( { - settings: settingsPda, + consensusAccount: settingsPda, transactionBuffer, creator: members.proposer.publicKey, rentPayer: members.proposer.publicKey, @@ -128,11 +129,12 @@ describe("Instructions / transaction_create_from_buffer", () => { }, { args: { + __kind: "TransactionPayload", bufferIndex: bufferIndex, accountIndex: 0, // Must be a SHA256 hash of the message buffer. finalBufferHash: Array.from(messageHash), - finalBufferSize: messageBuffer.length, + finalBufferSize: messageBuffer.transactionMessageBytes.byteLength, buffer: firstSlice, } as CreateTransactionBufferArgs, } as CreateTransactionBufferInstructionArgs, @@ -175,13 +177,16 @@ describe("Instructions / transaction_create_from_buffer", () => { // First chunk uploaded. Check that length is as expected. assert.equal(txBufferDeser1.buffer.length, 700); - const secondSlice = messageBuffer.slice(700, messageBuffer.byteLength); + const secondSlice = messageBuffer.transactionMessageBytes.slice( + 700, + messageBuffer.transactionMessageBytes.byteLength + ); // Extned the buffer. const secondIx = smartAccount.generated.createExtendTransactionBufferInstruction( { - settings: settingsPda, + consensusAccount: settingsPda, transactionBuffer, creator: members.proposer.publicKey, }, @@ -221,7 +226,10 @@ describe("Instructions / transaction_create_from_buffer", () => { // Final chunk uploaded. Check that length is as expected. - assert.equal(txBufferDeser2.buffer.length, messageBuffer.byteLength); + assert.equal( + txBufferDeser2.buffer.length, + messageBuffer.transactionMessageBytes.byteLength + ); // Derive transaction PDA. const [transactionPda] = smartAccount.getTransactionPda({ @@ -249,20 +257,26 @@ describe("Instructions / transaction_create_from_buffer", () => { const thirdIx = smartAccount.generated.createCreateTransactionFromBufferInstruction( { - transactionCreateItemSettings: settingsPda, + transactionCreateItemConsensusAccount: settingsPda, transactionCreateItemTransaction: transactionPda, transactionCreateItemCreator: members.proposer.publicKey, transactionCreateItemRentPayer: members.proposer.publicKey, transactionCreateItemSystemProgram: SystemProgram.programId, transactionBuffer: transactionBuffer, creator: members.proposer.publicKey, + transactionCreateItemProgram: programId, }, { args: { - accountIndex: 0, - ephemeralSigners: 0, - transactionMessage: new Uint8Array(6).fill(0), - memo: null, + __kind: "TransactionPayload", + fields: [ + { + accountIndex: 0, + ephemeralSigners: 0, + transactionMessage: new Uint8Array(6).fill(0), + memo: null, + }, + ], } as CreateTransactionArgs, } as CreateTransactionInstructionArgs, programId @@ -305,7 +319,10 @@ describe("Instructions / transaction_create_from_buffer", () => { ); // Ensure final transaction has 43 instructions - assert.equal(transactionInfo.message.instructions.length, 43); + let transactionPayloadDetails = extractTransactionPayloadDetails( + transactionInfo.payload + ); + assert.equal(transactionPayloadDetails.message.instructions.length, 43); }); it("error: create from buffer with mismatched hash", async () => { @@ -349,7 +366,7 @@ describe("Instructions / transaction_create_from_buffer", () => { const createIx = smartAccount.generated.createCreateTransactionBufferInstruction( { - settings: settingsPda, + consensusAccount: settingsPda, transactionBuffer, creator: members.proposer.publicKey, rentPayer: members.proposer.publicKey, @@ -357,11 +374,12 @@ describe("Instructions / transaction_create_from_buffer", () => { }, { args: { + __kind: "TransactionPayload", bufferIndex, accountIndex: 0, finalBufferHash: Array.from(dummyHash), - finalBufferSize: messageBuffer.length, - buffer: messageBuffer, + finalBufferSize: messageBuffer.transactionMessageBytes.byteLength, + buffer: messageBuffer.transactionMessageBytes, } as CreateTransactionBufferArgs, } as CreateTransactionBufferInstructionArgs, programId @@ -395,21 +413,26 @@ describe("Instructions / transaction_create_from_buffer", () => { const createFromBufferIx = smartAccount.generated.createCreateTransactionFromBufferInstruction( { - transactionCreateItemSettings: settingsPda, + transactionCreateItemConsensusAccount: settingsPda, transactionCreateItemTransaction: transactionPda, transactionCreateItemCreator: members.proposer.publicKey, transactionCreateItemRentPayer: members.proposer.publicKey, transactionCreateItemSystemProgram: SystemProgram.programId, creator: members.proposer.publicKey, transactionBuffer: transactionBuffer, + transactionCreateItemProgram: programId, }, { args: { - accountIndex: 0, - ephemeralSigners: 0, - transactionMessage: new Uint8Array(6).fill(0), - memo: null, - anchorRemainingAccounts: [transactionBufferMeta], + __kind: "TransactionPayload", + fields: [ + { + accountIndex: 0, + ephemeralSigners: 0, + transactionMessage: new Uint8Array(6).fill(0), + memo: null, + }, + ], } as CreateTransactionArgs, } as CreateTransactionInstructionArgs, programId @@ -450,7 +473,10 @@ describe("Instructions / transaction_create_from_buffer", () => { ); // Check that we're dealing with the same account from first test. - assert.equal(transactionInfo.message.instructions.length, 43); + let transactionPayloadDetails = extractTransactionPayloadDetails( + transactionInfo.payload + ); + assert.equal(transactionPayloadDetails.message.instructions.length, 43); const fourthSignature = await smartAccount.rpc.createProposal({ connection, diff --git a/tests/suites/program-config-init.ts b/tests/suites/program-config-init.ts index df6a7a7..ba487db 100644 --- a/tests/suites/program-config-init.ts +++ b/tests/suites/program-config-init.ts @@ -224,7 +224,7 @@ describe("Initialize Global ProgramConfig", () => { assert.ok(smartAccount.errors.isErrorWithLogs(err)); assert.ok( - err.logs.find((line) => { + err.logs.find((line: string) => { return line.includes("already in use"); }) ); diff --git a/tests/suites/smart-account-sdk.ts b/tests/suites/smart-account-sdk.ts index 06a64e3..b8ec57e 100644 --- a/tests/suites/smart-account-sdk.ts +++ b/tests/suites/smart-account-sdk.ts @@ -13,6 +13,7 @@ import { createControlledSmartAccount, createLocalhostConnection, createTestTransferInstruction, + extractTransactionPayloadDetails, fundKeypair, generateFundedKeypair, generateSmartAccountSigners, @@ -1332,8 +1333,11 @@ describe("Smart Account SDK", () => { connection, transactionPda ); + let transactionPayloadDetails = extractTransactionPayloadDetails( + transactionAccount.payload + ); assert.strictEqual( - transactionAccount.settings.toBase58(), + transactionAccount.consensusAccount.toBase58(), settingsPda.toBase58() ); assert.strictEqual( @@ -1344,14 +1348,14 @@ describe("Smart Account SDK", () => { transactionAccount.index.toString(), transactionIndex.toString() ); - assert.strictEqual(transactionAccount.accountBump, vaultBump); + assert.deepEqual( - transactionAccount.ephemeralSignerBumps, + transactionPayloadDetails.ephemeralSignerBumps, new Uint8Array() ); - assert.strictEqual(transactionAccount.bump, transactionBump); + assert.deepEqual(transactionPayloadDetails.accountIndex, 0); // TODO: verify the transaction message data. - assert.ok(transactionAccount.message); + assert.ok(transactionPayloadDetails.message); }); }); @@ -2321,10 +2325,12 @@ describe("Smart Account SDK", () => { transactionIndex, programId, }); - + let transactionPayloadDetails = extractTransactionPayloadDetails( + transactionAccount.payload + ); const [vaultPda] = smartAccount.getSmartAccountPda({ settingsPda, - accountIndex: transactionAccount.accountIndex, + accountIndex: transactionPayloadDetails.accountIndex, programId, }); const preVaultBalance = await connection.getBalance(vaultPda); diff --git a/tests/utils.ts b/tests/utils.ts index 8e9ec3c..1b5837a 100644 --- a/tests/utils.ts +++ b/tests/utils.ts @@ -10,6 +10,8 @@ import { VersionedTransaction, } from "@solana/web3.js"; import * as smartAccount from "@sqds/smart-account"; +import { Payload } from "@sqds/smart-account/lib/generated"; +import { TransactionPayloadDetails } from "@sqds/smart-account/src/generated/types"; import assert from "assert"; import { readFileSync } from "fs"; import path from "path"; @@ -1255,7 +1257,7 @@ export async function processBufferInChunks( const ix = smartAccount.generated.createExtendTransactionBufferInstruction( { - settings: settingsPda, + consensusAccount: settingsPda, transactionBuffer: bufferAccount, creator: signer.publicKey, }, @@ -1305,3 +1307,102 @@ export async function getNextAccountIndex( const nextAccountIndex = accountIndex + 1n; return nextAccountIndex; } + +/** + * Extracts the TransactionPayloadDetails from a Payload. + * @param transactionPayload - The Payload to extract the TransactionPayloadDetails from. + * @returns The TransactionPayloadDetails. + */ +export function extractTransactionPayloadDetails( + transactionPayload: Payload +): TransactionPayloadDetails { + if (transactionPayload.__kind === "TransactionPayload") { + return transactionPayload.fields[0] as TransactionPayloadDetails; + } else { + throw new Error("Invalid transaction payload"); + } +} + +/** + * Creates a mint and transfers tokens to the recipient. + * @param connection - The connection to use. + * @param payer - The keypair to use as the mint authority. + * @param recipient - The recipient of the tokens. + * @param amount - The amount of tokens to transfer. + * @returns The mint address. + */ +export async function createMintAndTransferTo( + connection: Connection, + payer: Keypair, + recipient: PublicKey, + amount: number +): Promise<[PublicKey, number]> { + // Import SPL token functions + const { + createMint, + getOrCreateAssociatedTokenAccount, + getAssociatedTokenAddressSync, + TOKEN_PROGRAM_ID, + } = await import("@solana/spl-token"); + + let mintDecimals = 9; + // Create a new mint with 9 decimals + const mint = await createMint( + connection, + payer, + payer.publicKey, // mint authority + null, // freeze authority (you can set this to null if you don't want a freeze authority) + mintDecimals, // decimals + undefined, // keypair (will generate a new one) + undefined, // options + TOKEN_PROGRAM_ID + ); + + // Get the associated token account address for the recipient + const associatedTokenAccount = getAssociatedTokenAddressSync( + mint, + recipient, + true, // allowOwnerOffCurve + TOKEN_PROGRAM_ID + ); + + // Create the associated token account for the recipient + await getOrCreateAssociatedTokenAccount( + connection, + payer, + mint, + recipient, + true + ); + + // Mint tokens to the recipient + const { createMintToInstruction } = await import("@solana/spl-token"); + const mintToIx = createMintToInstruction( + mint, + associatedTokenAccount, + payer.publicKey, + amount, + [], + TOKEN_PROGRAM_ID + ); + + // Create and send the transaction + const { TransactionMessage, VersionedTransaction } = await import( + "@solana/web3.js" + ); + const message = new TransactionMessage({ + payerKey: payer.publicKey, + recentBlockhash: (await connection.getLatestBlockhash()).blockhash, + instructions: [mintToIx], + }).compileToV0Message(); + + const transaction = new VersionedTransaction(message); + transaction.sign([payer]); + + const sig = await connection.sendRawTransaction(transaction.serialize(), { + skipPreflight: true, + }); + await connection.confirmTransaction(sig); + + return [mint, mintDecimals]; +} diff --git a/yarn.lock b/yarn.lock index 5d87c8a..e0d1c14 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1,2552 +1,3974 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@babel/runtime@^7.12.5", "@babel/runtime@^7.17.2": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.7.tgz#fcb41a5a70550e04a7b708037c7c32f7f356d8fd" - integrity sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ== - dependencies: - regenerator-runtime "^0.13.11" - -"@babel/runtime@^7.25.0": - version "7.26.0" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.0.tgz#8600c2f595f277c60815256418b85356a65173c1" - integrity sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw== - dependencies: - regenerator-runtime "^0.14.0" - -"@cspotcode/source-map-support@^0.8.0": - version "0.8.1" - resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" - integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== - dependencies: - "@jridgewell/trace-mapping" "0.3.9" - -"@esbuild/aix-ppc64@0.24.2": - version "0.24.2" - resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz#38848d3e25afe842a7943643cbcd387cc6e13461" - integrity sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA== - -"@esbuild/android-arm64@0.24.2": - version "0.24.2" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz#f592957ae8b5643129fa889c79e69cd8669bb894" - integrity sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg== - -"@esbuild/android-arm@0.24.2": - version "0.24.2" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.24.2.tgz#72d8a2063aa630308af486a7e5cbcd1e134335b3" - integrity sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q== - -"@esbuild/android-x64@0.24.2": - version "0.24.2" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.24.2.tgz#9a7713504d5f04792f33be9c197a882b2d88febb" - integrity sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw== - -"@esbuild/darwin-arm64@0.24.2": - version "0.24.2" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz#02ae04ad8ebffd6e2ea096181b3366816b2b5936" - integrity sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA== - -"@esbuild/darwin-x64@0.24.2": - version "0.24.2" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz#9ec312bc29c60e1b6cecadc82bd504d8adaa19e9" - integrity sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA== - -"@esbuild/freebsd-arm64@0.24.2": - version "0.24.2" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz#5e82f44cb4906d6aebf24497d6a068cfc152fa00" - integrity sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg== - -"@esbuild/freebsd-x64@0.24.2": - version "0.24.2" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz#3fb1ce92f276168b75074b4e51aa0d8141ecce7f" - integrity sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q== - -"@esbuild/linux-arm64@0.24.2": - version "0.24.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz#856b632d79eb80aec0864381efd29de8fd0b1f43" - integrity sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg== - -"@esbuild/linux-arm@0.24.2": - version "0.24.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz#c846b4694dc5a75d1444f52257ccc5659021b736" - integrity sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA== - -"@esbuild/linux-ia32@0.24.2": - version "0.24.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz#f8a16615a78826ccbb6566fab9a9606cfd4a37d5" - integrity sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw== - -"@esbuild/linux-loong64@0.24.2": - version "0.24.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz#1c451538c765bf14913512c76ed8a351e18b09fc" - integrity sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ== - -"@esbuild/linux-mips64el@0.24.2": - version "0.24.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz#0846edeefbc3d8d50645c51869cc64401d9239cb" - integrity sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw== - -"@esbuild/linux-ppc64@0.24.2": - version "0.24.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz#8e3fc54505671d193337a36dfd4c1a23b8a41412" - integrity sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw== - -"@esbuild/linux-riscv64@0.24.2": - version "0.24.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz#6a1e92096d5e68f7bb10a0d64bb5b6d1daf9a694" - integrity sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q== - -"@esbuild/linux-s390x@0.24.2": - version "0.24.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz#ab18e56e66f7a3c49cb97d337cd0a6fea28a8577" - integrity sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw== - -"@esbuild/linux-x64@0.24.2": - version "0.24.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz#8140c9b40da634d380b0b29c837a0b4267aff38f" - integrity sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q== - -"@esbuild/netbsd-arm64@0.24.2": - version "0.24.2" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz#65f19161432bafb3981f5f20a7ff45abb2e708e6" - integrity sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw== - -"@esbuild/netbsd-x64@0.24.2": - version "0.24.2" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz#7a3a97d77abfd11765a72f1c6f9b18f5396bcc40" - integrity sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw== - -"@esbuild/openbsd-arm64@0.24.2": - version "0.24.2" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz#58b00238dd8f123bfff68d3acc53a6ee369af89f" - integrity sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A== - -"@esbuild/openbsd-x64@0.24.2": - version "0.24.2" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz#0ac843fda0feb85a93e288842936c21a00a8a205" - integrity sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA== - -"@esbuild/sunos-x64@0.24.2": - version "0.24.2" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz#8b7aa895e07828d36c422a4404cc2ecf27fb15c6" - integrity sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig== - -"@esbuild/win32-arm64@0.24.2": - version "0.24.2" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz#c023afb647cabf0c3ed13f0eddfc4f1d61c66a85" - integrity sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ== - -"@esbuild/win32-ia32@0.24.2": - version "0.24.2" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz#96c356132d2dda990098c8b8b951209c3cd743c2" - integrity sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA== - -"@esbuild/win32-x64@0.24.2": - version "0.24.2" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz#34aa0b52d0fbb1a654b596acfa595f0c7b77a77b" - integrity sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg== - -"@isaacs/cliui@^8.0.2": - version "8.0.2" - resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" - integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== - dependencies: - string-width "^5.1.2" - string-width-cjs "npm:string-width@^4.2.0" - strip-ansi "^7.0.1" - strip-ansi-cjs "npm:strip-ansi@^6.0.1" - wrap-ansi "^8.1.0" - wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" - -"@jridgewell/gen-mapping@^0.3.2": - version "0.3.8" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz#4f0e06362e01362f823d348f1872b08f666d8142" - integrity sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA== - dependencies: - "@jridgewell/set-array" "^1.2.1" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/trace-mapping" "^0.3.24" - -"@jridgewell/resolve-uri@^3.0.3": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" - integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== - -"@jridgewell/resolve-uri@^3.1.0": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" - integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== - -"@jridgewell/set-array@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280" - integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== - -"@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.14" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" - integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== - -"@jridgewell/sourcemap-codec@^1.4.14": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" - integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== - -"@jridgewell/trace-mapping@0.3.9": - version "0.3.9" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" - integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== - dependencies: - "@jridgewell/resolve-uri" "^3.0.3" - "@jridgewell/sourcemap-codec" "^1.4.10" - -"@jridgewell/trace-mapping@^0.3.24": - version "0.3.25" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" - integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== - dependencies: - "@jridgewell/resolve-uri" "^3.1.0" - "@jridgewell/sourcemap-codec" "^1.4.14" - -"@metaplex-foundation/beet-solana@0.4.0": - version "0.4.0" - resolved "https://registry.yarnpkg.com/@metaplex-foundation/beet-solana/-/beet-solana-0.4.0.tgz#52891e78674aaa54e0031f1bca5bfbc40de12e8d" - integrity sha512-B1L94N3ZGMo53b0uOSoznbuM5GBNJ8LwSeznxBxJ+OThvfHQ4B5oMUqb+0zdLRfkKGS7Q6tpHK9P+QK0j3w2cQ== - dependencies: - "@metaplex-foundation/beet" ">=0.1.0" - "@solana/web3.js" "^1.56.2" - bs58 "^5.0.0" - debug "^4.3.4" - -"@metaplex-foundation/beet-solana@^0.3.1": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@metaplex-foundation/beet-solana/-/beet-solana-0.3.1.tgz#4b37cda5c7f32ffd2bdd8b3164edc05c6463ab35" - integrity sha512-tgyEl6dvtLln8XX81JyBvWjIiEcjTkUwZbrM5dIobTmoqMuGewSyk9CClno8qsMsFdB5T3jC91Rjeqmu/6xk2g== - dependencies: - "@metaplex-foundation/beet" ">=0.1.0" - "@solana/web3.js" "^1.56.2" - bs58 "^5.0.0" - debug "^4.3.4" - -"@metaplex-foundation/beet@0.7.1", "@metaplex-foundation/beet@>=0.1.0": - version "0.7.1" - resolved "https://registry.yarnpkg.com/@metaplex-foundation/beet/-/beet-0.7.1.tgz#0975314211643f87b5f6f3e584fa31abcf4c612c" - integrity sha512-hNCEnS2WyCiYyko82rwuISsBY3KYpe828ubsd2ckeqZr7tl0WVLivGkoyA/qdiaaHEBGdGl71OpfWa2rqL3DiA== - dependencies: - ansicolors "^0.3.2" - bn.js "^5.2.0" - debug "^4.3.3" - -"@metaplex-foundation/beet@^0.7.1": - version "0.7.2" - resolved "https://registry.yarnpkg.com/@metaplex-foundation/beet/-/beet-0.7.2.tgz#fa4726e4cfd4fb6fed6cddc9b5213c1c2a2d0b77" - integrity sha512-K+g3WhyFxKPc0xIvcIjNyV1eaTVJTiuaHZpig7Xx0MuYRMoJLLvhLTnUXhFdR5Tu2l2QSyKwfyXDgZlzhULqFg== - dependencies: - ansicolors "^0.3.2" - assert "^2.1.0" - bn.js "^5.2.0" - debug "^4.3.3" - -"@metaplex-foundation/cusper@^0.0.2": - version "0.0.2" - resolved "https://registry.yarnpkg.com/@metaplex-foundation/cusper/-/cusper-0.0.2.tgz#dc2032a452d6c269e25f016aa4dd63600e2af975" - integrity sha512-S9RulC2fFCFOQraz61bij+5YCHhSO9llJegK8c8Y6731fSi6snUSQJdCUqYS8AIgR0TKbQvdvgSyIIdbDFZbBA== - -"@metaplex-foundation/rustbin@^0.3.0": - version "0.3.5" - resolved "https://registry.yarnpkg.com/@metaplex-foundation/rustbin/-/rustbin-0.3.5.tgz#56d028afd96c2b56ad3bbea22ff454adde900e8c" - integrity sha512-m0wkRBEQB/8krwMwKBvFugufZtYwMXiGHud2cTDAv+aGXK4M90y0Hx67/wpu+AqqoQfdV8VM9YezUOHKD+Z5kA== - dependencies: - debug "^4.3.3" - semver "^7.3.7" - text-table "^0.2.0" - toml "^3.0.0" - -"@metaplex-foundation/solita@0.20.0": - version "0.20.0" - resolved "https://registry.yarnpkg.com/@metaplex-foundation/solita/-/solita-0.20.0.tgz#7efc7bf0f32ce0bddfe2cd45779f0ce7fb7bdfa8" - integrity sha512-pNm8UVJJW9yItGC5CKSSzfreCWuEHLaYpK1oFL6RCEq9J+JjpGp6p9Ro1H6WMmBBcAaN23LRZ9/kMfh79GkFAQ== - dependencies: - "@metaplex-foundation/beet" "^0.7.1" - "@metaplex-foundation/beet-solana" "^0.3.1" - "@metaplex-foundation/rustbin" "^0.3.0" - "@solana/web3.js" "^1.56.2" - ansi-colors "^4.1.3" - camelcase "^6.2.1" - debug "^4.3.3" - js-sha256 "^0.9.0" - prettier "^2.5.1" - snake-case "^3.0.4" - spok "^1.4.3" - -"@noble/curves@^1.4.2": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.7.0.tgz#0512360622439256df892f21d25b388f52505e45" - integrity sha512-UTMhXK9SeDhFJVrHeUJ5uZlI6ajXg10O6Ddocf9S6GjbSBVZsJo88HzKwXznNfGpMTRDyJkqMjNDPYgf0qFWnw== - dependencies: - "@noble/hashes" "1.6.0" - -"@noble/ed25519@^1.7.0": - version "1.7.1" - resolved "https://registry.yarnpkg.com/@noble/ed25519/-/ed25519-1.7.1.tgz#6899660f6fbb97798a6fbd227227c4589a454724" - integrity sha512-Rk4SkJFaXZiznFyC/t77Q0NKS4FL7TLJJsVG2V2oiEq3kJVeTdxysEe/yRWSpnWMe808XRDJ+VFh5pt/FN5plw== - -"@noble/hashes@1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.6.0.tgz#d4bfb516ad6e7b5111c216a5cc7075f4cf19e6c5" - integrity sha512-YUULf0Uk4/mAA89w+k3+yUYh6NrEvxZa5T6SY3wlMvE2chHkxFUUIDI8/XW1QSC357iA5pSnqt7XEhvFOqmDyQ== - -"@noble/hashes@^1.1.2": - version "1.1.5" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.5.tgz#1a0377f3b9020efe2fae03290bd2a12140c95c11" - integrity sha512-LTMZiiLc+V4v1Yi16TD6aX2gmtKszNye0pQgbaLqkvhIqP7nVsSaJsWloGQjJfJ8offaoP5GtX3yY5swbcJxxQ== - -"@noble/hashes@^1.4.0": - version "1.6.1" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.6.1.tgz#df6e5943edcea504bac61395926d6fd67869a0d5" - integrity sha512-pq5D8h10hHBjyqX+cfBm0i8JUXJ0UhczFc4r74zbuT9XgewFo2E3J1cOaGtdZynILNmQ685YWGzGE1Zv6io50w== - -"@noble/secp256k1@^1.6.3": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.0.tgz#d15357f7c227e751d90aa06b05a0e5cf993ba8c1" - integrity sha512-kbacwGSsH/CTout0ZnZWxnW1B+jH/7r/WAAKLBtrRJ/+CUH7lgmQzl3GTrQua3SGKWNSDsS6lmjnDpIJ5Dxyaw== - -"@pkgjs/parseargs@^0.11.0": - version "0.11.0" - resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" - integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== - -"@rollup/rollup-android-arm-eabi@4.34.8": - version "4.34.8" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.8.tgz#731df27dfdb77189547bcef96ada7bf166bbb2fb" - integrity sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw== - -"@rollup/rollup-android-arm64@4.34.8": - version "4.34.8" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.8.tgz#4bea6db78e1f6927405df7fe0faf2f5095e01343" - integrity sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q== - -"@rollup/rollup-darwin-arm64@4.34.8": - version "4.34.8" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.8.tgz#a7aab77d44be3c44a20f946e10160f84e5450e7f" - integrity sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q== - -"@rollup/rollup-darwin-x64@4.34.8": - version "4.34.8" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.8.tgz#c572c024b57ee8ddd1b0851703ace9eb6cc0dd82" - integrity sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw== - -"@rollup/rollup-freebsd-arm64@4.34.8": - version "4.34.8" - resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.8.tgz#cf74f8113b5a83098a5c026c165742277cbfb88b" - integrity sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA== - -"@rollup/rollup-freebsd-x64@4.34.8": - version "4.34.8" - resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.8.tgz#39561f3a2f201a4ad6a01425b1ff5928154ecd7c" - integrity sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q== - -"@rollup/rollup-linux-arm-gnueabihf@4.34.8": - version "4.34.8" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.8.tgz#980d6061e373bfdaeb67925c46d2f8f9b3de537f" - integrity sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g== - -"@rollup/rollup-linux-arm-musleabihf@4.34.8": - version "4.34.8" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.8.tgz#f91a90f30dc00d5a64ac2d9bbedc829cd3cfaa78" - integrity sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA== - -"@rollup/rollup-linux-arm64-gnu@4.34.8": - version "4.34.8" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.8.tgz#fac700fa5c38bc13a0d5d34463133093da4c92a0" - integrity sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A== - -"@rollup/rollup-linux-arm64-musl@4.34.8": - version "4.34.8" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.8.tgz#f50ecccf8c78841ff6df1706bc4782d7f62bf9c3" - integrity sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q== - -"@rollup/rollup-linux-loongarch64-gnu@4.34.8": - version "4.34.8" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.8.tgz#5869dc0b28242da6553e2b52af41374f4038cd6e" - integrity sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ== - -"@rollup/rollup-linux-powerpc64le-gnu@4.34.8": - version "4.34.8" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.8.tgz#5cdd9f851ce1bea33d6844a69f9574de335f20b1" - integrity sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw== - -"@rollup/rollup-linux-riscv64-gnu@4.34.8": - version "4.34.8" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.8.tgz#ef5dc37f4388f5253f0def43e1440ec012af204d" - integrity sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw== - -"@rollup/rollup-linux-s390x-gnu@4.34.8": - version "4.34.8" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.8.tgz#7dbc3ccbcbcfb3e65be74538dfb6e8dd16178fde" - integrity sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA== - -"@rollup/rollup-linux-x64-gnu@4.34.8": - version "4.34.8" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.8.tgz#5783fc0adcab7dc069692056e8ca8d83709855ce" - integrity sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA== - -"@rollup/rollup-linux-x64-musl@4.34.8": - version "4.34.8" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.8.tgz#00b6c29b298197a384e3c659910b47943003a678" - integrity sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ== - -"@rollup/rollup-win32-arm64-msvc@4.34.8": - version "4.34.8" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.8.tgz#cbfee01f1fe73791c35191a05397838520ca3cdd" - integrity sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ== - -"@rollup/rollup-win32-ia32-msvc@4.34.8": - version "4.34.8" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.8.tgz#95cdbdff48fe6c948abcf6a1d500b2bd5ce33f62" - integrity sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w== - -"@rollup/rollup-win32-x64-msvc@4.34.8": - version "4.34.8" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.8.tgz#4cdb2cfae69cdb7b1a3cc58778e820408075e928" - integrity sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g== - -"@solana/buffer-layout-utils@^0.2.0": - version "0.2.0" - resolved "https://registry.yarnpkg.com/@solana/buffer-layout-utils/-/buffer-layout-utils-0.2.0.tgz#b45a6cab3293a2eb7597cceb474f229889d875ca" - integrity sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g== - dependencies: - "@solana/buffer-layout" "^4.0.0" - "@solana/web3.js" "^1.32.0" - bigint-buffer "^1.1.5" - bignumber.js "^9.0.1" - -"@solana/buffer-layout@^4.0.0", "@solana/buffer-layout@^4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@solana/buffer-layout/-/buffer-layout-4.0.1.tgz#b996235eaec15b1e0b5092a8ed6028df77fa6c15" - integrity sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA== - dependencies: - buffer "~6.0.3" - -"@solana/spl-memo@^0.2.3": - version "0.2.3" - resolved "https://registry.yarnpkg.com/@solana/spl-memo/-/spl-memo-0.2.3.tgz#594a28c37b40c0e22143f38f71b4f56d1f5b24fd" - integrity sha512-CNsKSsl85ebuVoeGq1LDYi5M/PMs1Pxv2/UsyTgS6b30qrYqZOXha5ouZzgGKtJtZ3C3dxfOAEw6caJPN1N63w== - dependencies: - buffer "^6.0.3" - -"@solana/spl-token@*", "@solana/spl-token@0.3.6", "@solana/spl-token@^0.3.6": - version "0.3.6" - resolved "https://registry.yarnpkg.com/@solana/spl-token/-/spl-token-0.3.6.tgz#35473ad2ed71fe91e5754a2ac72901e1b8b26a42" - integrity sha512-P9pTXjDIRvVbjr3J0mCnSamYqLnICeds7IoH1/Ro2R9OBuOHdp5pqKZoscfZ3UYrgnCWUc1bc9M2m/YPHjw+1g== - dependencies: - "@solana/buffer-layout" "^4.0.0" - "@solana/buffer-layout-utils" "^0.2.0" - buffer "^6.0.3" - -"@solana/web3.js@1.70.3", "@solana/web3.js@^1.32.0", "@solana/web3.js@^1.56.2", "@solana/web3.js@^1.70.3", "@solana/web3.js@^1.95.5": - version "1.70.3" - resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.70.3.tgz#44040a78d1f86ee6a0a9dbe391b5f891bb404265" - integrity sha512-9JAFXAWB3yhUHnoahzemTz4TcsGqmITPArNlm9795e+LA/DYkIEJIXIosV4ImzDMfqolymZeRgG3O8ewNgYTTA== - dependencies: - "@babel/runtime" "^7.12.5" - "@noble/ed25519" "^1.7.0" - "@noble/hashes" "^1.1.2" - "@noble/secp256k1" "^1.6.3" - "@solana/buffer-layout" "^4.0.0" - agentkeepalive "^4.2.1" - bigint-buffer "^1.1.5" - bn.js "^5.0.0" - borsh "^0.7.0" - bs58 "^4.0.1" - buffer "6.0.1" - fast-stable-stringify "^1.0.0" - jayson "^3.4.4" - node-fetch "2" - rpc-websockets "^7.5.0" - superstruct "^0.14.2" - -"@swc/helpers@^0.5.11": - version "0.5.15" - resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.15.tgz#79efab344c5819ecf83a43f3f9f811fc84b516d7" - integrity sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g== - dependencies: - tslib "^2.8.0" - -"@tsconfig/node10@^1.0.7": - version "1.0.9" - resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" - integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== - -"@tsconfig/node12@^1.0.7": - version "1.0.11" - resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" - integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== - -"@tsconfig/node14@^1.0.0": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" - integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== - -"@tsconfig/node16@^1.0.2": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e" - integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ== - -"@types/bn.js@5.1.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.0.tgz#32c5d271503a12653c62cf4d2b45e6eab8cebc68" - integrity sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA== - dependencies: - "@types/node" "*" - -"@types/bn.js@^5.1.1": - version "5.1.1" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.1.tgz#b51e1b55920a4ca26e9285ff79936bbdec910682" - integrity sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g== - dependencies: - "@types/node" "*" - -"@types/connect@^3.4.33": - version "3.4.35" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" - integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== - dependencies: - "@types/node" "*" - -"@types/estree@1.0.6": - version "1.0.6" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50" - integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== - -"@types/invariant@2.2.35": - version "2.2.35" - resolved "https://registry.yarnpkg.com/@types/invariant/-/invariant-2.2.35.tgz#cd3ebf581a6557452735688d8daba6cf0bd5a3be" - integrity sha512-DxX1V9P8zdJPYQat1gHyY0xj3efl8gnMVjiM9iCY6y27lj+PoQWkgjt8jDqmovPqULkKVpKRg8J36iQiA+EtEg== - -"@types/mocha@10.0.1": - version "10.0.1" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.1.tgz#2f4f65bb08bc368ac39c96da7b2f09140b26851b" - integrity sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q== - -"@types/node-fetch@2.6.2": - version "2.6.2" - resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.2.tgz#d1a9c5fd049d9415dce61571557104dec3ec81da" - integrity sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A== - dependencies: - "@types/node" "*" - form-data "^3.0.0" - -"@types/node@*", "@types/node@18.11.17": - version "18.11.17" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.17.tgz#5c009e1d9c38f4a2a9d45c0b0c493fe6cdb4bcb5" - integrity sha512-HJSUJmni4BeDHhfzn6nF0sVmd1SMezP7/4F0Lq+aXzmp2xm9O7WXrUtHW/CHlYVtZUbByEvWidHqRtcJXGF2Ng== - -"@types/node@^12.12.54": - version "12.20.55" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240" - integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ== - -"@types/uuid@^8.3.4": - version "8.3.4" - resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc" - integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw== - -"@types/ws@^7.4.4": - version "7.4.7" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" - integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== - dependencies: - "@types/node" "*" - -"@types/ws@^8.2.2": - version "8.5.13" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.13.tgz#6414c280875e2691d0d1e080b05addbf5cb91e20" - integrity sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA== - dependencies: - "@types/node" "*" - -JSONStream@^1.3.5: - version "1.3.5" - resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" - integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== - dependencies: - jsonparse "^1.2.0" - through ">=2.2.7 <3" - -acorn-walk@^8.1.1: - version "8.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" - integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== - -acorn@^8.4.1: - version "8.8.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73" - integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA== - -agentkeepalive@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.2.1.tgz#a7975cbb9f83b367f06c90cc51ff28fe7d499717" - integrity sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA== - dependencies: - debug "^4.1.0" - depd "^1.1.2" - humanize-ms "^1.2.1" - -agentkeepalive@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.5.0.tgz#2673ad1389b3c418c5a20c5d7364f93ca04be923" - integrity sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew== - dependencies: - humanize-ms "^1.2.1" - -ansi-colors@4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== - -ansi-colors@^4.1.3: - version "4.1.3" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" - integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-regex@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.1.0.tgz#95ec409c69619d6cb1b8b34f14b660ef28ebd654" - integrity sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA== - -ansi-sequence-parser@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/ansi-sequence-parser/-/ansi-sequence-parser-1.1.3.tgz#f2cefb8b681aeb72b7cd50aebc00d509eba64d4c" - integrity sha512-+fksAx9eG3Ab6LDnLs3ZqZa8KVJ/jYnX+D4Qe1azX+LFGFAXqynCQLOdLpNYN/l9e7l6hMWwZbrnctqr6eSQSw== - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -ansi-styles@^6.1.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" - integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== - -ansicolors@^0.3.2, ansicolors@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979" - integrity sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg== - -any-promise@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" - integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== - -anymatch@~3.1.2: - version "3.1.3" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" - integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -arg@^4.1.0: - version "4.1.3" - resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" - integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -assert@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/assert/-/assert-2.0.0.tgz#95fc1c616d48713510680f2eaf2d10dd22e02d32" - integrity sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A== - dependencies: - es6-object-assign "^1.1.0" - is-nan "^1.2.1" - object-is "^1.0.1" - util "^0.12.0" - -assert@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/assert/-/assert-2.1.0.tgz#6d92a238d05dc02e7427c881fb8be81c8448b2dd" - integrity sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw== - dependencies: - call-bind "^1.0.2" - is-nan "^1.3.2" - object-is "^1.1.5" - object.assign "^4.1.4" - util "^0.12.5" - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== - -available-typed-arrays@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" - integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -base-x@^3.0.2: - version "3.0.9" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" - integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== - dependencies: - safe-buffer "^5.0.1" - -base-x@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-4.0.0.tgz#d0e3b7753450c73f8ad2389b5c018a4af7b2224a" - integrity sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw== - -base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - -bigint-buffer@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/bigint-buffer/-/bigint-buffer-1.1.5.tgz#d038f31c8e4534c1f8d0015209bf34b4fa6dd442" - integrity sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA== - dependencies: - bindings "^1.3.0" - -bignumber.js@^9.0.1: - version "9.1.1" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.1.tgz#c4df7dc496bd849d4c9464344c1aa74228b4dac6" - integrity sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig== - -binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== - -bindings@^1.3.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" - integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== - dependencies: - file-uri-to-path "1.0.0" - -bn.js@^5.0.0, bn.js@^5.2.0, bn.js@^5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" - integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== - -borsh@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/borsh/-/borsh-0.7.0.tgz#6e9560d719d86d90dc589bca60ffc8a6c51fec2a" - integrity sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA== - dependencies: - bn.js "^5.2.0" - bs58 "^4.0.0" - text-encoding-utf-8 "^1.0.2" - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -brace-expansion@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" - integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== - dependencies: - balanced-match "^1.0.0" - -braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -browser-stdout@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" - integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== - -bs58@^4.0.0, bs58@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" - integrity sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw== - dependencies: - base-x "^3.0.2" - -bs58@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/bs58/-/bs58-5.0.0.tgz#865575b4d13c09ea2a84622df6c8cbeb54ffc279" - integrity sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ== - dependencies: - base-x "^4.0.0" - -buffer@6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.1.tgz#3cbea8c1463e5a0779e30b66d4c88c6ffa182ac2" - integrity sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.2.1" - -buffer@6.0.3, buffer@^6.0.3, buffer@~6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" - integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.2.1" - -bufferutil@^4.0.1: - version "4.0.7" - resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.7.tgz#60c0d19ba2c992dd8273d3f73772ffc894c153ad" - integrity sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw== - dependencies: - node-gyp-build "^4.3.0" - -bundle-require@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/bundle-require/-/bundle-require-5.1.0.tgz#8db66f41950da3d77af1ef3322f4c3e04009faee" - integrity sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA== - dependencies: - load-tsconfig "^0.2.3" - -cac@^6.7.14: - version "6.7.14" - resolved "https://registry.yarnpkg.com/cac/-/cac-6.7.14.tgz#804e1e6f506ee363cb0e3ccbb09cad5dd9870959" - integrity sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ== - -call-bind-apply-helpers@^1.0.0, call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6" - integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ== - dependencies: - es-errors "^1.3.0" - function-bind "^1.1.2" - -call-bind@^1.0.0, call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -call-bind@^1.0.7, call-bind@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.8.tgz#0736a9660f537e3388826f440d5ec45f744eaa4c" - integrity sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww== - dependencies: - call-bind-apply-helpers "^1.0.0" - es-define-property "^1.0.0" - get-intrinsic "^1.2.4" - set-function-length "^1.2.2" - -call-bound@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/call-bound/-/call-bound-1.0.3.tgz#41cfd032b593e39176a71533ab4f384aa04fd681" - integrity sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA== - dependencies: - call-bind-apply-helpers "^1.0.1" - get-intrinsic "^1.2.6" - -camelcase@^6.0.0, camelcase@^6.2.1: - version "6.3.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" - integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== - -chalk@^4.1.0, chalk@~4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chokidar@3.5.3: - version "3.5.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - -chokidar@^4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-4.0.3.tgz#7be37a4c03c9aee1ecfe862a4a23b2c70c205d30" - integrity sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA== - dependencies: - readdirp "^4.0.1" - -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -combined-stream@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -commander@^12.1.0: - version "12.1.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-12.1.0.tgz#01423b36f501259fdaac4d0e4d60c96c991585d3" - integrity sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA== - -commander@^2.20.3: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -commander@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" - integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - -consola@^3.2.3: - version "3.4.0" - resolved "https://registry.yarnpkg.com/consola/-/consola-3.4.0.tgz#4cfc9348fd85ed16a17940b3032765e31061ab88" - integrity sha512-EiPU8G6dQG0GFHNR8ljnZFki/8a+cQwEQ+7wpxdChl02Q8HXlwEZWD5lqAF8vC2sEC3Tehr8hy7vErz88LHyUA== - -create-require@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" - integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== - -cross-spawn@^7.0.0: - version "7.0.6" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" - integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -debug@4.3.4, debug@^4.1.0, debug@^4.3.3, debug@^4.3.4: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - -debug@^4.3.7: - version "4.4.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.0.tgz#2b3f2aea2ffeb776477460267377dc8710faba8a" - integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA== - dependencies: - ms "^2.1.3" - -decamelize@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" - integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== - -define-data-property@^1.0.1, define-data-property@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" - integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== - dependencies: - es-define-property "^1.0.0" - es-errors "^1.3.0" - gopd "^1.0.1" - -define-properties@^1.1.3: - version "1.1.4" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" - integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== - dependencies: - has-property-descriptors "^1.0.0" - object-keys "^1.1.1" - -define-properties@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" - integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== - dependencies: - define-data-property "^1.0.1" - has-property-descriptors "^1.0.0" - object-keys "^1.1.1" - -delay@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/delay/-/delay-5.0.0.tgz#137045ef1b96e5071060dd5be60bf9334436bd1d" - integrity sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw== - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== - -depd@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== - -diff@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" - integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== - -diff@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - -dot-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" - integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== - dependencies: - no-case "^3.0.4" - tslib "^2.0.3" - -dunder-proto@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a" - integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A== - dependencies: - call-bind-apply-helpers "^1.0.1" - es-errors "^1.3.0" - gopd "^1.2.0" - -eastasianwidth@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" - integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -emoji-regex@^9.2.2: - version "9.2.2" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - -es-define-property@^1.0.0, es-define-property@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa" - integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g== - -es-errors@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" - integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== - -es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz#1c4f2c4837327597ce69d2ca190a7fdd172338c1" - integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA== - dependencies: - es-errors "^1.3.0" - -es6-object-assign@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/es6-object-assign/-/es6-object-assign-1.1.0.tgz#c2c3582656247c39ea107cb1e6652b6f9f24523c" - integrity sha512-MEl9uirslVwqQU369iHNWZXsI8yaZYGg/D65aOgZkeyFJwHYSxilf7rQzXKI7DdDuBPrBXbfk3sl9hJhmd5AUw== - -es6-promise@^4.0.3: - version "4.2.8" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" - integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== - -es6-promisify@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" - integrity sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ== - dependencies: - es6-promise "^4.0.3" - -esbuild@^0.24.0: - version "0.24.2" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.24.2.tgz#b5b55bee7de017bff5fb8a4e3e44f2ebe2c3567d" - integrity sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA== - optionalDependencies: - "@esbuild/aix-ppc64" "0.24.2" - "@esbuild/android-arm" "0.24.2" - "@esbuild/android-arm64" "0.24.2" - "@esbuild/android-x64" "0.24.2" - "@esbuild/darwin-arm64" "0.24.2" - "@esbuild/darwin-x64" "0.24.2" - "@esbuild/freebsd-arm64" "0.24.2" - "@esbuild/freebsd-x64" "0.24.2" - "@esbuild/linux-arm" "0.24.2" - "@esbuild/linux-arm64" "0.24.2" - "@esbuild/linux-ia32" "0.24.2" - "@esbuild/linux-loong64" "0.24.2" - "@esbuild/linux-mips64el" "0.24.2" - "@esbuild/linux-ppc64" "0.24.2" - "@esbuild/linux-riscv64" "0.24.2" - "@esbuild/linux-s390x" "0.24.2" - "@esbuild/linux-x64" "0.24.2" - "@esbuild/netbsd-arm64" "0.24.2" - "@esbuild/netbsd-x64" "0.24.2" - "@esbuild/openbsd-arm64" "0.24.2" - "@esbuild/openbsd-x64" "0.24.2" - "@esbuild/sunos-x64" "0.24.2" - "@esbuild/win32-arm64" "0.24.2" - "@esbuild/win32-ia32" "0.24.2" - "@esbuild/win32-x64" "0.24.2" - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-string-regexp@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -eventemitter3@^4.0.7: - version "4.0.7" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" - integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== - -eventemitter3@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" - integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== - -eyes@^0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" - integrity sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ== - -fast-stable-stringify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz#5c5543462b22aeeefd36d05b34e51c78cb86d313" - integrity sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag== - -fdir@^6.4.3: - version "6.4.3" - resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.4.3.tgz#011cdacf837eca9b811c89dbb902df714273db72" - integrity sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw== - -file-uri-to-path@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" - integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -find-process@^1.4.7: - version "1.4.10" - resolved "https://registry.yarnpkg.com/find-process/-/find-process-1.4.10.tgz#006af3349d8debdb9fb79fb1e859959350307c02" - integrity sha512-ncYFnWEIwL7PzmrK1yZtaccN8GhethD37RzBHG6iOZoFYB4vSmLLXfeWJjeN5nMvCJMjOtBvBBF8OgxEcikiZg== - dependencies: - chalk "~4.1.2" - commander "^12.1.0" - loglevel "^1.9.2" - -find-up@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -flat@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" - integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== - -for-each@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" - integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== - dependencies: - is-callable "^1.1.3" - -foreground-child@^3.1.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.0.tgz#0ac8644c06e431439f8561db8ecf29a7b5519c77" - integrity sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg== - dependencies: - cross-spawn "^7.0.0" - signal-exit "^4.0.1" - -form-data@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" - integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - -fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -function-bind@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" - integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== - -get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385" - integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.3" - -get-intrinsic@^1.2.4, get-intrinsic@^1.2.6: - version "1.3.0" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01" - integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ== - dependencies: - call-bind-apply-helpers "^1.0.2" - es-define-property "^1.0.1" - es-errors "^1.3.0" - es-object-atoms "^1.1.1" - function-bind "^1.1.2" - get-proto "^1.0.1" - gopd "^1.2.0" - has-symbols "^1.1.0" - hasown "^2.0.2" - math-intrinsics "^1.1.0" - -get-proto@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1" - integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g== - dependencies: - dunder-proto "^1.0.1" - es-object-atoms "^1.0.0" - -glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob@7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" - integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^10.3.10: - version "10.4.5" - resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956" - integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg== - dependencies: - foreground-child "^3.1.0" - jackspeak "^3.1.2" - minimatch "^9.0.4" - minipass "^7.1.2" - package-json-from-dist "^1.0.0" - path-scurry "^1.11.1" - -gopd@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" - integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== - dependencies: - get-intrinsic "^1.1.3" - -gopd@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1" - integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-property-descriptors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" - integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== - dependencies: - get-intrinsic "^1.1.1" - -has-property-descriptors@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" - integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== - dependencies: - es-define-property "^1.0.0" - -has-symbols@^1.0.2, has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== - -has-symbols@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338" - integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== - -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== - dependencies: - has-symbols "^1.0.2" - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -hasown@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" - integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== - dependencies: - function-bind "^1.1.2" - -he@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" - integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== - -humanize-ms@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" - integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== - dependencies: - ms "^2.0.0" - -ieee754@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@^2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -invariant@2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== - dependencies: - loose-envify "^1.0.0" - -is-arguments@^1.0.4: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" - integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-callable@^1.1.3: - version "1.2.7" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" - integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-generator-function@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" - integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== - dependencies: - has-tostringtag "^1.0.0" - -is-glob@^4.0.1, is-glob@~4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-nan@^1.2.1, is-nan@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.3.2.tgz#043a54adea31748b55b6cd4e09aadafa69bd9e1d" - integrity sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-plain-obj@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" - integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== - -is-typed-array@^1.1.10, is-typed-array@^1.1.3: - version "1.1.10" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.10.tgz#36a5b5cb4189b575d1a3e4b08536bfb485801e3f" - integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.0" - -is-unicode-supported@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" - integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - -isomorphic-ws@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" - integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== - -jackspeak@^3.1.2: - version "3.4.3" - resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.4.3.tgz#8833a9d89ab4acde6188942bd1c53b6390ed5a8a" - integrity sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw== - dependencies: - "@isaacs/cliui" "^8.0.2" - optionalDependencies: - "@pkgjs/parseargs" "^0.11.0" - -jayson@^3.4.4: - version "3.7.0" - resolved "https://registry.yarnpkg.com/jayson/-/jayson-3.7.0.tgz#b735b12d06d348639ae8230d7a1e2916cb078f25" - integrity sha512-tfy39KJMrrXJ+mFcMpxwBvFDetS8LAID93+rycFglIQM4kl3uNR3W4lBLE/FFhsoUCEox5Dt2adVpDm/XtebbQ== - dependencies: - "@types/connect" "^3.4.33" - "@types/node" "^12.12.54" - "@types/ws" "^7.4.4" - JSONStream "^1.3.5" - commander "^2.20.3" - delay "^5.0.0" - es6-promisify "^5.0.0" - eyes "^0.1.8" - isomorphic-ws "^4.0.1" - json-stringify-safe "^5.0.1" - lodash "^4.17.20" - uuid "^8.3.2" - ws "^7.4.5" - -jayson@^4.1.1: - version "4.1.2" - resolved "https://registry.yarnpkg.com/jayson/-/jayson-4.1.2.tgz#443c26a8658703e0b2e881117b09395d88b6982e" - integrity sha512-5nzMWDHy6f+koZOuYsArh2AXs73NfWYVlFyJJuCedr93GpY+Ku8qq10ropSXVfHK+H0T6paA88ww+/dV+1fBNA== - dependencies: - "@types/connect" "^3.4.33" - "@types/node" "^12.12.54" - "@types/ws" "^7.4.4" - JSONStream "^1.3.5" - commander "^2.20.3" - delay "^5.0.0" - es6-promisify "^5.0.0" - eyes "^0.1.8" - isomorphic-ws "^4.0.1" - json-stringify-safe "^5.0.1" - uuid "^8.3.2" - ws "^7.5.10" - -joycon@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/joycon/-/joycon-3.1.1.tgz#bce8596d6ae808f8b68168f5fc69280996894f03" - integrity sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw== - -js-sha256@^0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/js-sha256/-/js-sha256-0.9.0.tgz#0b89ac166583e91ef9123644bd3c5334ce9d0966" - integrity sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA== - -"js-tokens@^3.0.0 || ^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -json-stringify-safe@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== - -jsonc-parser@^3.2.0: - version "3.3.1" - resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.3.1.tgz#f2a524b4f7fd11e3d791e559977ad60b98b798b4" - integrity sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ== - -jsonparse@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" - integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== - -lilconfig@^3.1.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.1.3.tgz#a1bcfd6257f9585bf5ae14ceeebb7b559025e4c4" - integrity sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw== - -lines-and-columns@^1.1.6: - version "1.2.4" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" - integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== - -load-tsconfig@^0.2.3: - version "0.2.5" - resolved "https://registry.yarnpkg.com/load-tsconfig/-/load-tsconfig-0.2.5.tgz#453b8cd8961bfb912dea77eb6c168fe8cca3d3a1" - integrity sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg== - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -lodash.sortby@^4.7.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" - integrity sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA== - -lodash@^4.17.20: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -log-symbols@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" - integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== - dependencies: - chalk "^4.1.0" - is-unicode-supported "^0.1.0" - -loglevel@^1.9.2: - version "1.9.2" - resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.9.2.tgz#c2e028d6c757720107df4e64508530db6621ba08" - integrity sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg== - -loose-envify@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - -lower-case@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" - integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== - dependencies: - tslib "^2.0.3" - -lru-cache@^10.2.0: - version "10.4.3" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" - integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== - -lunr@^2.3.9: - version "2.3.9" - resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1" - integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow== - -make-error@^1.1.1: - version "1.3.6" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" - integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== - -marked@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/marked/-/marked-4.3.0.tgz#796362821b019f734054582038b116481b456cf3" - integrity sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A== - -math-intrinsics@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9" - integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g== - -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - -mime-types@^2.1.12: - version "2.1.35" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== - dependencies: - mime-db "1.52.0" - -minimatch@5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" - integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== - dependencies: - brace-expansion "^2.0.1" - -minimatch@^3.0.4: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -minimatch@^9.0.3, minimatch@^9.0.4: - version "9.0.5" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" - integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== - dependencies: - brace-expansion "^2.0.1" - -"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.1.2: - version "7.1.2" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707" - integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== - -mocha@10.2.0: - version "10.2.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8" - integrity sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg== - dependencies: - ansi-colors "4.1.1" - browser-stdout "1.3.1" - chokidar "3.5.3" - debug "4.3.4" - diff "5.0.0" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "7.2.0" - he "1.2.0" - js-yaml "4.1.0" - log-symbols "4.1.0" - minimatch "5.0.1" - ms "2.1.3" - nanoid "3.3.3" - serialize-javascript "6.0.0" - strip-json-comments "3.1.1" - supports-color "8.1.1" - workerpool "6.2.1" - yargs "16.2.0" - yargs-parser "20.2.4" - yargs-unparser "2.0.0" - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@2.1.3, ms@^2.0.0, ms@^2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -mz@^2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" - integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== - dependencies: - any-promise "^1.0.0" - object-assign "^4.0.1" - thenify-all "^1.0.0" - -nanoid@3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" - integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== - -no-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" - integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== - dependencies: - lower-case "^2.0.2" - tslib "^2.0.3" - -node-fetch@2: - version "2.6.7" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" - integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== - dependencies: - whatwg-url "^5.0.0" - -node-fetch@^2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" - integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== - dependencies: - whatwg-url "^5.0.0" - -node-gyp-build@^4.3.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.5.0.tgz#7a64eefa0b21112f89f58379da128ac177f20e40" - integrity sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg== - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -object-assign@^4.0.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== - -object-is@^1.0.1: - version "1.1.5" - resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" - integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -object-is@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.6.tgz#1a6a53aed2dd8f7e6775ff870bea58545956ab07" - integrity sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q== - dependencies: - call-bind "^1.0.7" - define-properties "^1.2.1" - -object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object.assign@^4.1.4: - version "4.1.7" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.7.tgz#8c14ca1a424c6a561b0bb2a22f66f5049a945d3d" - integrity sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw== - dependencies: - call-bind "^1.0.8" - call-bound "^1.0.3" - define-properties "^1.2.1" - es-object-atoms "^1.0.0" - has-symbols "^1.1.0" - object-keys "^1.1.1" - -once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== - dependencies: - wrappy "1" - -p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - -package-json-from-dist@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz#4f1471a010827a86f94cfd9b0727e36d267de505" - integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw== - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== - -path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-scurry@^1.11.1: - version "1.11.1" - resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2" - integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA== - dependencies: - lru-cache "^10.2.0" - minipass "^5.0.0 || ^6.0.2 || ^7.0.0" - -picocolors@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" - integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== - -picomatch@^2.0.4, picomatch@^2.2.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -picomatch@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.2.tgz#77c742931e8f3b8820946c76cd0c1f13730d1dab" - integrity sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg== - -pirates@^4.0.1: - version "4.0.6" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" - integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== - -postcss-load-config@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-6.0.1.tgz#6fd7dcd8ae89badcf1b2d644489cbabf83aa8096" - integrity sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g== - dependencies: - lilconfig "^3.1.1" - -prettier@2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.6.2.tgz#e26d71a18a74c3d0f0597f55f01fb6c06c206032" - integrity sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew== - -prettier@^2.5.1: - version "2.8.8" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" - integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== - -punycode@^2.1.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" - integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== - -randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -readdirp@^4.0.1: - version "4.1.2" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-4.1.2.tgz#eb85801435fbf2a7ee58f19e0921b068fc69948d" - integrity sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg== - -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - -regenerator-runtime@^0.13.11: - version "0.13.11" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" - integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== - -regenerator-runtime@^0.14.0: - version "0.14.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" - integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== - -resolve-from@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" - integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== - -rollup@^4.24.0: - version "4.34.8" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.34.8.tgz#e859c1a51d899aba9bcf451d4eed1d11fb8e2a6e" - integrity sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ== - dependencies: - "@types/estree" "1.0.6" - optionalDependencies: - "@rollup/rollup-android-arm-eabi" "4.34.8" - "@rollup/rollup-android-arm64" "4.34.8" - "@rollup/rollup-darwin-arm64" "4.34.8" - "@rollup/rollup-darwin-x64" "4.34.8" - "@rollup/rollup-freebsd-arm64" "4.34.8" - "@rollup/rollup-freebsd-x64" "4.34.8" - "@rollup/rollup-linux-arm-gnueabihf" "4.34.8" - "@rollup/rollup-linux-arm-musleabihf" "4.34.8" - "@rollup/rollup-linux-arm64-gnu" "4.34.8" - "@rollup/rollup-linux-arm64-musl" "4.34.8" - "@rollup/rollup-linux-loongarch64-gnu" "4.34.8" - "@rollup/rollup-linux-powerpc64le-gnu" "4.34.8" - "@rollup/rollup-linux-riscv64-gnu" "4.34.8" - "@rollup/rollup-linux-s390x-gnu" "4.34.8" - "@rollup/rollup-linux-x64-gnu" "4.34.8" - "@rollup/rollup-linux-x64-musl" "4.34.8" - "@rollup/rollup-win32-arm64-msvc" "4.34.8" - "@rollup/rollup-win32-ia32-msvc" "4.34.8" - "@rollup/rollup-win32-x64-msvc" "4.34.8" - fsevents "~2.3.2" - -rpc-websockets@^7.5.0: - version "7.5.0" - resolved "https://registry.yarnpkg.com/rpc-websockets/-/rpc-websockets-7.5.0.tgz#bbeb87572e66703ff151e50af1658f98098e2748" - integrity sha512-9tIRi1uZGy7YmDjErf1Ax3wtqdSSLIlnmL5OtOzgd5eqPKbsPpwDP5whUDO2LQay3Xp0CcHlcNSGzacNRluBaQ== - dependencies: - "@babel/runtime" "^7.17.2" - eventemitter3 "^4.0.7" - uuid "^8.3.2" - ws "^8.5.0" - optionalDependencies: - bufferutil "^4.0.1" - utf-8-validate "^5.0.2" - -rpc-websockets@^9.0.2: - version "9.0.4" - resolved "https://registry.yarnpkg.com/rpc-websockets/-/rpc-websockets-9.0.4.tgz#9d8ee82533b5d1e13d9ded729e3e38d0d8fa083f" - integrity sha512-yWZWN0M+bivtoNLnaDbtny4XchdAIF5Q4g/ZsC5UC61Ckbp0QczwO8fg44rV3uYmY4WHd+EZQbn90W1d8ojzqQ== - dependencies: - "@swc/helpers" "^0.5.11" - "@types/uuid" "^8.3.4" - "@types/ws" "^8.2.2" - buffer "^6.0.3" - eventemitter3 "^5.0.1" - uuid "^8.3.2" - ws "^8.5.0" - optionalDependencies: - bufferutil "^4.0.1" - utf-8-validate "^5.0.2" - -safe-buffer@^5.0.1, safe-buffer@^5.1.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -semver@^7.3.7: - version "7.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.1.tgz#abd5098d82b18c6c81f6074ff2647fd3e7220c9f" - integrity sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA== - -serialize-javascript@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" - integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== - dependencies: - randombytes "^2.1.0" - -set-function-length@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" - integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== - dependencies: - define-data-property "^1.1.4" - es-errors "^1.3.0" - function-bind "^1.1.2" - get-intrinsic "^1.2.4" - gopd "^1.0.1" - has-property-descriptors "^1.0.2" - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -shiki@^0.14.7: - version "0.14.7" - resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.14.7.tgz#c3c9e1853e9737845f1d2ef81b31bcfb07056d4e" - integrity sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg== - dependencies: - ansi-sequence-parser "^1.1.0" - jsonc-parser "^3.2.0" - vscode-oniguruma "^1.7.0" - vscode-textmate "^8.0.0" - -signal-exit@^4.0.1: - version "4.1.0" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" - integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== - -snake-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-3.0.4.tgz#4f2bbd568e9935abdfd593f34c691dadb49c452c" - integrity sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg== - dependencies: - dot-case "^3.0.4" - tslib "^2.0.3" - -source-map@0.8.0-beta.0: - version "0.8.0-beta.0" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.8.0-beta.0.tgz#d4c1bb42c3f7ee925f005927ba10709e0d1d1f11" - integrity sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA== - dependencies: - whatwg-url "^7.0.0" - -spok@^1.4.3: - version "1.5.5" - resolved "https://registry.yarnpkg.com/spok/-/spok-1.5.5.tgz#a51f7f290a53131d7b7a922dfedc461dda0aed72" - integrity sha512-IrJIXY54sCNFASyHPOY+jEirkiJ26JDqsGiI0Dvhwcnkl0PEWi1PSsrkYql0rzDw8LFVTcA7rdUCAJdE2HE+2Q== - dependencies: - ansicolors "~0.3.2" - find-process "^1.4.7" - -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^4.1.0, string-width@^4.2.0: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^5.0.1, string-width@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" - integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== - dependencies: - eastasianwidth "^0.2.0" - emoji-regex "^9.2.2" - strip-ansi "^7.0.1" - -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^7.0.1: - version "7.1.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" - integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== - dependencies: - ansi-regex "^6.0.1" - -strip-json-comments@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -sucrase@^3.35.0: - version "3.35.0" - resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.35.0.tgz#57f17a3d7e19b36d8995f06679d121be914ae263" - integrity sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA== - dependencies: - "@jridgewell/gen-mapping" "^0.3.2" - commander "^4.0.0" - glob "^10.3.10" - lines-and-columns "^1.1.6" - mz "^2.7.0" - pirates "^4.0.1" - ts-interface-checker "^0.1.9" - -superstruct@^0.14.2: - version "0.14.2" - resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-0.14.2.tgz#0dbcdf3d83676588828f1cf5ed35cda02f59025b" - integrity sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ== - -superstruct@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-2.0.2.tgz#3f6d32fbdc11c357deff127d591a39b996300c54" - integrity sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A== - -supports-color@8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -text-encoding-utf-8@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz#585b62197b0ae437e3c7b5d0af27ac1021e10d13" - integrity sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg== - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== - -thenify-all@^1.0.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" - integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== - dependencies: - thenify ">= 3.1.0 < 4" - -"thenify@>= 3.1.0 < 4": - version "3.3.1" - resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" - integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== - dependencies: - any-promise "^1.0.0" - -"through@>=2.2.7 <3": - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== - -tinyexec@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/tinyexec/-/tinyexec-0.3.2.tgz#941794e657a85e496577995c6eef66f53f42b3d2" - integrity sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA== - -tinyglobby@^0.2.9: - version "0.2.12" - resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.12.tgz#ac941a42e0c5773bd0b5d08f32de82e74a1a61b5" - integrity sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww== - dependencies: - fdir "^6.4.3" - picomatch "^4.0.2" - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -toml@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/toml/-/toml-3.0.0.tgz#342160f1af1904ec9d204d03a5d61222d762c5ee" - integrity sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w== - -tr46@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" - integrity sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA== - dependencies: - punycode "^2.1.0" - -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== - -tree-kill@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" - integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== - -ts-interface-checker@^0.1.9: - version "0.1.13" - resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699" - integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== - -ts-node@10.9.1: - version "10.9.1" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" - integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== - dependencies: - "@cspotcode/source-map-support" "^0.8.0" - "@tsconfig/node10" "^1.0.7" - "@tsconfig/node12" "^1.0.7" - "@tsconfig/node14" "^1.0.0" - "@tsconfig/node16" "^1.0.2" - acorn "^8.4.1" - acorn-walk "^8.1.1" - arg "^4.1.0" - create-require "^1.1.0" - diff "^4.0.1" - make-error "^1.1.1" - v8-compile-cache-lib "^3.0.1" - yn "3.1.1" - -tslib@^2.0.3, tslib@^2.8.0: - version "2.8.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" - integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== - -tsup@^8.0.2: - version "8.3.6" - resolved "https://registry.yarnpkg.com/tsup/-/tsup-8.3.6.tgz#a10eb2dc27f84b510a0f00341ab75cad03d13a88" - integrity sha512-XkVtlDV/58S9Ye0JxUUTcrQk4S+EqlOHKzg6Roa62rdjL1nGWNUstG0xgI4vanHdfIpjP448J8vlN0oK6XOJ5g== - dependencies: - bundle-require "^5.0.0" - cac "^6.7.14" - chokidar "^4.0.1" - consola "^3.2.3" - debug "^4.3.7" - esbuild "^0.24.0" - joycon "^3.1.1" - picocolors "^1.1.1" - postcss-load-config "^6.0.1" - resolve-from "^5.0.0" - rollup "^4.24.0" - source-map "0.8.0-beta.0" - sucrase "^3.35.0" - tinyexec "^0.3.1" - tinyglobby "^0.2.9" - tree-kill "^1.2.2" - -turbo-darwin-64@1.6.3: - version "1.6.3" - resolved "https://registry.yarnpkg.com/turbo-darwin-64/-/turbo-darwin-64-1.6.3.tgz#fad7e078784b0fafc0b1f75ce9378828918595f5" - integrity sha512-QmDIX0Yh1wYQl0bUS0gGWwNxpJwrzZU2GIAYt3aOKoirWA2ecnyb3R6ludcS1znfNV2MfunP+l8E3ncxUHwtjA== - -turbo-darwin-arm64@1.6.3: - version "1.6.3" - resolved "https://registry.yarnpkg.com/turbo-darwin-arm64/-/turbo-darwin-arm64-1.6.3.tgz#f0a32cae39e3fcd3da5e3129a94c18bb2e3ed6aa" - integrity sha512-75DXhFpwE7CinBbtxTxH08EcWrxYSPFow3NaeFwsG8aymkWXF+U2aukYHJA6I12n9/dGqf7yRXzkF0S/9UtdyQ== - -turbo-linux-64@1.6.3: - version "1.6.3" - resolved "https://registry.yarnpkg.com/turbo-linux-64/-/turbo-linux-64-1.6.3.tgz#8ddc6ac55ef84641182fe5ff50647f1b355826b0" - integrity sha512-O9uc6J0yoRPWdPg9THRQi69K6E2iZ98cRHNvus05lZbcPzZTxJYkYGb5iagCmCW/pq6fL4T4oLWAd6evg2LGQA== - -turbo-linux-arm64@1.6.3: - version "1.6.3" - resolved "https://registry.yarnpkg.com/turbo-linux-arm64/-/turbo-linux-arm64-1.6.3.tgz#846c1dc84d8dc741651906613c16acccba30428c" - integrity sha512-dCy667qqEtZIhulsRTe8hhWQNCJO0i20uHXv7KjLHuFZGCeMbWxB8rsneRoY+blf8+QNqGuXQJxak7ayjHLxiA== - -turbo-windows-64@1.6.3: - version "1.6.3" - resolved "https://registry.yarnpkg.com/turbo-windows-64/-/turbo-windows-64-1.6.3.tgz#89ac819fa76ad31d12fbfdeb3045bcebd0d308eb" - integrity sha512-lKRqwL3mrVF09b9KySSaOwetehmGknV9EcQTF7d2dxngGYYX1WXoQLjFP9YYH8ZV07oPm+RUOAKSCQuDuMNhiA== - -turbo-windows-arm64@1.6.3: - version "1.6.3" - resolved "https://registry.yarnpkg.com/turbo-windows-arm64/-/turbo-windows-arm64-1.6.3.tgz#977607c9a51f0b76076c8b158bafce06ce813070" - integrity sha512-BXY1sDPEA1DgPwuENvDCD8B7Hb0toscjus941WpL8CVd10hg9pk/MWn9CNgwDO5Q9ks0mw+liDv2EMnleEjeNA== - -turbo@1.6.3: - version "1.6.3" - resolved "https://registry.yarnpkg.com/turbo/-/turbo-1.6.3.tgz#ec26cc8907c38a9fd6eb072fb10dad254733543e" - integrity sha512-FtfhJLmEEtHveGxW4Ye/QuY85AnZ2ZNVgkTBswoap7UMHB1+oI4diHPNyqrQLG4K1UFtCkjOlVoLsllUh/9QRw== - optionalDependencies: - turbo-darwin-64 "1.6.3" - turbo-darwin-arm64 "1.6.3" - turbo-linux-64 "1.6.3" - turbo-linux-arm64 "1.6.3" - turbo-windows-64 "1.6.3" - turbo-windows-arm64 "1.6.3" - -typedoc@^0.25.7: - version "0.25.13" - resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.25.13.tgz#9a98819e3b2d155a6d78589b46fa4c03768f0922" - integrity sha512-pQqiwiJ+Z4pigfOnnysObszLiU3mVLWAExSPf+Mu06G/qsc3wzbuM56SZQvONhHLncLUhYzOVkjFFpFfL5AzhQ== - dependencies: - lunr "^2.3.9" - marked "^4.3.0" - minimatch "^9.0.3" - shiki "^0.14.7" - -typescript@*, typescript@4.9.4: - version "4.9.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.4.tgz#a2a3d2756c079abda241d75f149df9d561091e78" - integrity sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg== - -utf-8-validate@^5.0.2: - version "5.0.10" - resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz#d7d10ea39318171ca982718b6b96a8d2442571a2" - integrity sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ== - dependencies: - node-gyp-build "^4.3.0" - -util@^0.12.0, util@^0.12.5: - version "0.12.5" - resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" - integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== - dependencies: - inherits "^2.0.3" - is-arguments "^1.0.4" - is-generator-function "^1.0.7" - is-typed-array "^1.1.3" - which-typed-array "^1.1.2" - -uuid@^8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" - integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== - -v8-compile-cache-lib@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" - integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== - -vscode-oniguruma@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz#439bfad8fe71abd7798338d1cd3dc53a8beea94b" - integrity sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA== - -vscode-textmate@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-8.0.0.tgz#2c7a3b1163ef0441097e0b5d6389cd5504b59e5d" - integrity sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg== - -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - -webidl-conversions@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" - integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== - -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - -whatwg-url@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" - integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== - dependencies: - lodash.sortby "^4.7.0" - tr46 "^1.0.1" - webidl-conversions "^4.0.2" - -which-typed-array@^1.1.2: - version "1.1.9" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6" - integrity sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.0" - is-typed-array "^1.1.10" - -which@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -workerpool@6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" - integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== - -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" - integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== - dependencies: - ansi-styles "^6.1.0" - string-width "^5.0.1" - strip-ansi "^7.0.1" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - -ws@^7.4.5: - version "7.5.9" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" - integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== - -ws@^7.5.10: - version "7.5.10" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9" - integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== - -ws@^8.5.0: - version "8.11.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.11.0.tgz#6a0d36b8edfd9f96d8b25683db2f8d7de6e8e143" - integrity sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg== - -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - -yargs-parser@20.2.4: - version "20.2.4" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== - -yargs-parser@^20.2.2: - version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - -yargs-unparser@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" - integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== - dependencies: - camelcase "^6.0.0" - decamelize "^4.0.0" - flat "^5.0.2" - is-plain-obj "^2.1.0" - -yargs@16.2.0: - version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - -yn@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" - integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== +# This file is generated by running "yarn install" inside your project. +# Manual changes might be lost - proceed with caution! + +__metadata: + version: 6 + cacheKey: 8 + +"@babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.17.2": + version: 7.20.7 + resolution: "@babel/runtime@npm:7.20.7" + dependencies: + regenerator-runtime: ^0.13.11 + checksum: 4629ce5c46f06cca9cfb9b7fc00d48003335a809888e2b91ec2069a2dcfbfef738480cff32ba81e0b7c290f8918e5c22ddcf2b710001464ee84ba62c7e32a3a3 + languageName: node + linkType: hard + +"@cspotcode/source-map-support@npm:^0.8.0": + version: 0.8.1 + resolution: "@cspotcode/source-map-support@npm:0.8.1" + dependencies: + "@jridgewell/trace-mapping": 0.3.9 + checksum: 5718f267085ed8edb3e7ef210137241775e607ee18b77d95aa5bd7514f47f5019aa2d82d96b3bf342ef7aa890a346fa1044532ff7cc3009e7d24fce3ce6200fa + languageName: node + linkType: hard + +"@esbuild/aix-ppc64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/aix-ppc64@npm:0.24.2" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/android-arm64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/android-arm64@npm:0.24.2" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/android-arm@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/android-arm@npm:0.24.2" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@esbuild/android-x64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/android-x64@npm:0.24.2" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/darwin-arm64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/darwin-arm64@npm:0.24.2" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/darwin-x64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/darwin-x64@npm:0.24.2" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/freebsd-arm64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/freebsd-arm64@npm:0.24.2" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/freebsd-x64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/freebsd-x64@npm:0.24.2" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/linux-arm64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/linux-arm64@npm:0.24.2" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/linux-arm@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/linux-arm@npm:0.24.2" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@esbuild/linux-ia32@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/linux-ia32@npm:0.24.2" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/linux-loong64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/linux-loong64@npm:0.24.2" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + +"@esbuild/linux-mips64el@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/linux-mips64el@npm:0.24.2" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + +"@esbuild/linux-ppc64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/linux-ppc64@npm:0.24.2" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/linux-riscv64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/linux-riscv64@npm:0.24.2" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + +"@esbuild/linux-s390x@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/linux-s390x@npm:0.24.2" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + +"@esbuild/linux-x64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/linux-x64@npm:0.24.2" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/netbsd-arm64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/netbsd-arm64@npm:0.24.2" + conditions: os=netbsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/netbsd-x64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/netbsd-x64@npm:0.24.2" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openbsd-arm64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/openbsd-arm64@npm:0.24.2" + conditions: os=openbsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/openbsd-x64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/openbsd-x64@npm:0.24.2" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/sunos-x64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/sunos-x64@npm:0.24.2" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/win32-arm64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/win32-arm64@npm:0.24.2" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/win32-ia32@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/win32-ia32@npm:0.24.2" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/win32-x64@npm:0.24.2": + version: 0.24.2 + resolution: "@esbuild/win32-x64@npm:0.24.2" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@isaacs/cliui@npm:^8.0.2": + version: 8.0.2 + resolution: "@isaacs/cliui@npm:8.0.2" + dependencies: + string-width: ^5.1.2 + string-width-cjs: "npm:string-width@^4.2.0" + strip-ansi: ^7.0.1 + strip-ansi-cjs: "npm:strip-ansi@^6.0.1" + wrap-ansi: ^8.1.0 + wrap-ansi-cjs: "npm:wrap-ansi@^7.0.0" + checksum: 4a473b9b32a7d4d3cfb7a614226e555091ff0c5a29a1734c28c72a182c2f6699b26fc6b5c2131dfd841e86b185aea714c72201d7c98c2fba5f17709333a67aeb + languageName: node + linkType: hard + +"@isaacs/fs-minipass@npm:^4.0.0": + version: 4.0.1 + resolution: "@isaacs/fs-minipass@npm:4.0.1" + dependencies: + minipass: ^7.0.4 + checksum: 5d36d289960e886484362d9eb6a51d1ea28baed5f5d0140bbe62b99bac52eaf06cc01c2bc0d3575977962f84f6b2c4387b043ee632216643d4787b0999465bf2 + languageName: node + linkType: hard + +"@jridgewell/gen-mapping@npm:^0.3.2": + version: 0.3.8 + resolution: "@jridgewell/gen-mapping@npm:0.3.8" + dependencies: + "@jridgewell/set-array": ^1.2.1 + "@jridgewell/sourcemap-codec": ^1.4.10 + "@jridgewell/trace-mapping": ^0.3.24 + checksum: c0687b5227461717aa537fe71a42e356bcd1c43293b3353796a148bf3b0d6f59109def46c22f05b60e29a46f19b2e4676d027959a7c53a6c92b9d5b0d87d0420 + languageName: node + linkType: hard + +"@jridgewell/resolve-uri@npm:^3.0.3": + version: 3.1.0 + resolution: "@jridgewell/resolve-uri@npm:3.1.0" + checksum: b5ceaaf9a110fcb2780d1d8f8d4a0bfd216702f31c988d8042e5f8fbe353c55d9b0f55a1733afdc64806f8e79c485d2464680ac48a0d9fcadb9548ee6b81d267 + languageName: node + linkType: hard + +"@jridgewell/resolve-uri@npm:^3.1.0": + version: 3.1.2 + resolution: "@jridgewell/resolve-uri@npm:3.1.2" + checksum: 83b85f72c59d1c080b4cbec0fef84528963a1b5db34e4370fa4bd1e3ff64a0d80e0cee7369d11d73c704e0286fb2865b530acac7a871088fbe92b5edf1000870 + languageName: node + linkType: hard + +"@jridgewell/set-array@npm:^1.2.1": + version: 1.2.1 + resolution: "@jridgewell/set-array@npm:1.2.1" + checksum: 832e513a85a588f8ed4f27d1279420d8547743cc37fcad5a5a76fc74bb895b013dfe614d0eed9cb860048e6546b798f8f2652020b4b2ba0561b05caa8c654b10 + languageName: node + linkType: hard + +"@jridgewell/sourcemap-codec@npm:^1.4.10": + version: 1.4.14 + resolution: "@jridgewell/sourcemap-codec@npm:1.4.14" + checksum: 61100637b6d173d3ba786a5dff019e1a74b1f394f323c1fee337ff390239f053b87266c7a948777f4b1ee68c01a8ad0ab61e5ff4abb5a012a0b091bec391ab97 + languageName: node + linkType: hard + +"@jridgewell/sourcemap-codec@npm:^1.4.14": + version: 1.5.0 + resolution: "@jridgewell/sourcemap-codec@npm:1.5.0" + checksum: 05df4f2538b3b0f998ea4c1cd34574d0feba216fa5d4ccaef0187d12abf82eafe6021cec8b49f9bb4d90f2ba4582ccc581e72986a5fcf4176ae0cfeb04cf52ec + languageName: node + linkType: hard + +"@jridgewell/trace-mapping@npm:0.3.9": + version: 0.3.9 + resolution: "@jridgewell/trace-mapping@npm:0.3.9" + dependencies: + "@jridgewell/resolve-uri": ^3.0.3 + "@jridgewell/sourcemap-codec": ^1.4.10 + checksum: d89597752fd88d3f3480845691a05a44bd21faac18e2185b6f436c3b0fd0c5a859fbbd9aaa92050c4052caf325ad3e10e2e1d1b64327517471b7d51babc0ddef + languageName: node + linkType: hard + +"@jridgewell/trace-mapping@npm:^0.3.24": + version: 0.3.25 + resolution: "@jridgewell/trace-mapping@npm:0.3.25" + dependencies: + "@jridgewell/resolve-uri": ^3.1.0 + "@jridgewell/sourcemap-codec": ^1.4.14 + checksum: 9d3c40d225e139987b50c48988f8717a54a8c994d8a948ee42e1412e08988761d0754d7d10b803061cc3aebf35f92a5dbbab493bd0e1a9ef9e89a2130e83ba34 + languageName: node + linkType: hard + +"@metaplex-foundation/beet-solana@npm:0.4.0": + version: 0.4.0 + resolution: "@metaplex-foundation/beet-solana@npm:0.4.0" + dependencies: + "@metaplex-foundation/beet": ">=0.1.0" + "@solana/web3.js": ^1.56.2 + bs58: ^5.0.0 + debug: ^4.3.4 + checksum: ee746c2d15f985c31d133d4ee29efbda445877473cc32aafa4b684ce3fa9a916ddff30d0e3cfef7654ff5725adff59a62a635c76bc781a6e1362c5b5d3137ed0 + languageName: node + linkType: hard + +"@metaplex-foundation/beet-solana@npm:^0.3.1": + version: 0.3.1 + resolution: "@metaplex-foundation/beet-solana@npm:0.3.1" + dependencies: + "@metaplex-foundation/beet": ">=0.1.0" + "@solana/web3.js": ^1.56.2 + bs58: ^5.0.0 + debug: ^4.3.4 + checksum: 5405ec57c8cdb2dce016bf96f1cbd96ae185d6c764b8bdd1aaa68028e1970ad4815e7eb026a61703f57c33ddac261e47874e013bb03d84fa74ad78fce4b6e7cd + languageName: node + linkType: hard + +"@metaplex-foundation/beet@npm:0.7.1, @metaplex-foundation/beet@npm:>=0.1.0": + version: 0.7.1 + resolution: "@metaplex-foundation/beet@npm:0.7.1" + dependencies: + ansicolors: ^0.3.2 + bn.js: ^5.2.0 + debug: ^4.3.3 + checksum: f8a330073ab1a0976478e9847c0e63e32f7bee67ea6306e1f89784e8275e30daaecba7cbc5f3424e5d96c411aa3bfbc2b638c105a90067a985acdfbd33a1a287 + languageName: node + linkType: hard + +"@metaplex-foundation/beet@npm:^0.7.1": + version: 0.7.2 + resolution: "@metaplex-foundation/beet@npm:0.7.2" + dependencies: + ansicolors: ^0.3.2 + assert: ^2.1.0 + bn.js: ^5.2.0 + debug: ^4.3.3 + checksum: 2380ebc6872f89c5911324046d5dca96546a57b10eae29bc785566142e3ac2d079eedd3f7a1709373de6164eb97169354240ee09a14b57dae2d5295a3a5b4fac + languageName: node + linkType: hard + +"@metaplex-foundation/cusper@npm:^0.0.2": + version: 0.0.2 + resolution: "@metaplex-foundation/cusper@npm:0.0.2" + checksum: d157953baf42a2a012cdeb809c1785f29a44d80a3b5a3841c930baeb12ac6ddcf37f1a15eded4dce20d66f7bc8f23bedb87e905758df721e274bfcd816e70ba1 + languageName: node + linkType: hard + +"@metaplex-foundation/rustbin@npm:^0.3.0": + version: 0.3.5 + resolution: "@metaplex-foundation/rustbin@npm:0.3.5" + dependencies: + debug: ^4.3.3 + semver: ^7.3.7 + text-table: ^0.2.0 + toml: ^3.0.0 + checksum: 1a571d788d0d59028c948732506674480a0ee4f9442729bb89f2754c17f634f2f03fb8b34eee14db6513f45e8492b3cf7a9117c4a6d618c43f1f60620f4e1781 + languageName: node + linkType: hard + +"@metaplex-foundation/solita@npm:0.20.0": + version: 0.20.0 + resolution: "@metaplex-foundation/solita@npm:0.20.0" + dependencies: + "@metaplex-foundation/beet": ^0.7.1 + "@metaplex-foundation/beet-solana": ^0.3.1 + "@metaplex-foundation/rustbin": ^0.3.0 + "@solana/web3.js": ^1.56.2 + ansi-colors: ^4.1.3 + camelcase: ^6.2.1 + debug: ^4.3.3 + js-sha256: ^0.9.0 + prettier: ^2.5.1 + snake-case: ^3.0.4 + spok: ^1.4.3 + bin: + solita: dist/src/cli/solita.js + checksum: 9596a80063398193af85b808fc704328916f5d76f3e30bc01d6e3af39fa4004815eb64a63d0b7e59d0e83835f7f83edf569914016b97eef8378d93b68081dcc2 + languageName: node + linkType: hard + +"@noble/ed25519@npm:^1.7.0": + version: 1.7.1 + resolution: "@noble/ed25519@npm:1.7.1" + checksum: b8e50306ac70f5cecc349111997e72e897b47a28d406b96cf95d0ebe7cbdefb8380d26117d7847d94102281db200aa3a494e520f9fc12e2f292e0762cb0fa333 + languageName: node + linkType: hard + +"@noble/hashes@npm:^1.1.2": + version: 1.1.5 + resolution: "@noble/hashes@npm:1.1.5" + checksum: de3f095a7ac1cbf5b4b3d09f193288d4f2eec35fbadf2ed9fd7e47d8a3042fef410052ba62dc0296a185f994c11192f5357fdb1bd9178c905efd82e946c53b00 + languageName: node + linkType: hard + +"@noble/secp256k1@npm:^1.6.3": + version: 1.7.0 + resolution: "@noble/secp256k1@npm:1.7.0" + checksum: 540a2b8e527ee1e5522af1c430e54945ad373883cac983b115136cd0950efa1f2c473ee6a36d8e69b6809b3ee586276de62f5fa705c77a9425721e81bada8116 + languageName: node + linkType: hard + +"@npmcli/agent@npm:^3.0.0": + version: 3.0.0 + resolution: "@npmcli/agent@npm:3.0.0" + dependencies: + agent-base: ^7.1.0 + http-proxy-agent: ^7.0.0 + https-proxy-agent: ^7.0.1 + lru-cache: ^10.0.1 + socks-proxy-agent: ^8.0.3 + checksum: e8fc25d536250ed3e669813b36e8c6d805628b472353c57afd8c4fde0fcfcf3dda4ffe22f7af8c9070812ec2e7a03fb41d7151547cef3508efe661a5a3add20f + languageName: node + linkType: hard + +"@npmcli/fs@npm:^4.0.0": + version: 4.0.0 + resolution: "@npmcli/fs@npm:4.0.0" + dependencies: + semver: ^7.3.5 + checksum: 68951c589e9a4328698a35fd82fe71909a257d6f2ede0434d236fa55634f0fbcad9bb8755553ce5849bd25ee6f019f4d435921ac715c853582c4a7f5983c8d4a + languageName: node + linkType: hard + +"@pkgjs/parseargs@npm:^0.11.0": + version: 0.11.0 + resolution: "@pkgjs/parseargs@npm:0.11.0" + checksum: 6ad6a00fc4f2f2cfc6bff76fb1d88b8ee20bc0601e18ebb01b6d4be583733a860239a521a7fbca73b612e66705078809483549d2b18f370eb346c5155c8e4a0f + languageName: node + linkType: hard + +"@rollup/rollup-android-arm-eabi@npm:4.34.8": + version: 4.34.8 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.34.8" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@rollup/rollup-android-arm64@npm:4.34.8": + version: 4.34.8 + resolution: "@rollup/rollup-android-arm64@npm:4.34.8" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-darwin-arm64@npm:4.34.8": + version: 4.34.8 + resolution: "@rollup/rollup-darwin-arm64@npm:4.34.8" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-darwin-x64@npm:4.34.8": + version: 4.34.8 + resolution: "@rollup/rollup-darwin-x64@npm:4.34.8" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@rollup/rollup-freebsd-arm64@npm:4.34.8": + version: 4.34.8 + resolution: "@rollup/rollup-freebsd-arm64@npm:4.34.8" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-freebsd-x64@npm:4.34.8": + version: 4.34.8 + resolution: "@rollup/rollup-freebsd-x64@npm:4.34.8" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm-gnueabihf@npm:4.34.8": + version: 4.34.8 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.34.8" + conditions: os=linux & cpu=arm & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm-musleabihf@npm:4.34.8": + version: 4.34.8 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.34.8" + conditions: os=linux & cpu=arm & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm64-gnu@npm:4.34.8": + version: 4.34.8 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.34.8" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm64-musl@npm:4.34.8": + version: 4.34.8 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.34.8" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-loongarch64-gnu@npm:4.34.8": + version: 4.34.8 + resolution: "@rollup/rollup-linux-loongarch64-gnu@npm:4.34.8" + conditions: os=linux & cpu=loong64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-powerpc64le-gnu@npm:4.34.8": + version: 4.34.8 + resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.34.8" + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-riscv64-gnu@npm:4.34.8": + version: 4.34.8 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.34.8" + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-s390x-gnu@npm:4.34.8": + version: 4.34.8 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.34.8" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-x64-gnu@npm:4.34.8": + version: 4.34.8 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.34.8" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-x64-musl@npm:4.34.8": + version: 4.34.8 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.34.8" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-win32-arm64-msvc@npm:4.34.8": + version: 4.34.8 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.34.8" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-win32-ia32-msvc@npm:4.34.8": + version: 4.34.8 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.34.8" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@rollup/rollup-win32-x64-msvc@npm:4.34.8": + version: 4.34.8 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.34.8" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@solana/buffer-layout-utils@npm:^0.2.0": + version: 0.2.0 + resolution: "@solana/buffer-layout-utils@npm:0.2.0" + dependencies: + "@solana/buffer-layout": ^4.0.0 + "@solana/web3.js": ^1.32.0 + bigint-buffer: ^1.1.5 + bignumber.js: ^9.0.1 + checksum: 9284242245b18b49577195ba7548263850be865a4a2d183944fa01bb76382039db589aab8473698e9bb734b515ada9b4d70db0a72e341c5d567c59b83d6d0840 + languageName: node + linkType: hard + +"@solana/buffer-layout@npm:^4.0.0": + version: 4.0.1 + resolution: "@solana/buffer-layout@npm:4.0.1" + dependencies: + buffer: ~6.0.3 + checksum: bf846888e813187243d4008a7a9f58b49d16cbd995b9d7f1b72898aa510ed77b1ce5e8468e7b2fd26dd81e557a4e74a666e21fccb95f123c1f740d41138bbacd + languageName: node + linkType: hard + +"@solana/spl-memo@npm:^0.2.3": + version: 0.2.3 + resolution: "@solana/spl-memo@npm:0.2.3" + dependencies: + buffer: ^6.0.3 + peerDependencies: + "@solana/web3.js": ^1.20.0 + checksum: 5dbb0ef8fdca8728332f8de6b066ec08faa585956029eea7120f5286734d6ece7391bd2b64f922ff8d18e3a3d78cfcf4b3ac6147510565d501a02aa738f7481c + languageName: node + linkType: hard + +"@solana/spl-token@npm:0.3.6": + version: 0.3.6 + resolution: "@solana/spl-token@npm:0.3.6" + dependencies: + "@solana/buffer-layout": ^4.0.0 + "@solana/buffer-layout-utils": ^0.2.0 + buffer: ^6.0.3 + peerDependencies: + "@solana/web3.js": ^1.47.4 + checksum: e213db12ff6e443d07033898457854c5659189a00fc58f7cfd1b27229fdafd26edb7f1dcdcd21f76e703a8932b465cd6f418268c04f1b00996802f9894c280e7 + languageName: node + linkType: hard + +"@solana/web3.js@npm:1.70.3": + version: 1.70.3 + resolution: "@solana/web3.js@npm:1.70.3" + dependencies: + "@babel/runtime": ^7.12.5 + "@noble/ed25519": ^1.7.0 + "@noble/hashes": ^1.1.2 + "@noble/secp256k1": ^1.6.3 + "@solana/buffer-layout": ^4.0.0 + agentkeepalive: ^4.2.1 + bigint-buffer: ^1.1.5 + bn.js: ^5.0.0 + borsh: ^0.7.0 + bs58: ^4.0.1 + buffer: 6.0.1 + fast-stable-stringify: ^1.0.0 + jayson: ^3.4.4 + node-fetch: 2 + rpc-websockets: ^7.5.0 + superstruct: ^0.14.2 + checksum: 3a2809fed6ca994930f3b5ac263a1c7ab2e67b0b9d3343bdf43208f53031918327eb23c4b5eecd701d25418aa35f45e46f03245e0eaa05129d88c385725d316d + languageName: node + linkType: hard + +"@sqds/smart-account@workspace:sdk/smart-account": + version: 0.0.0-use.local + resolution: "@sqds/smart-account@workspace:sdk/smart-account" + dependencies: + "@metaplex-foundation/beet": 0.7.1 + "@metaplex-foundation/beet-solana": 0.4.0 + "@metaplex-foundation/cusper": ^0.0.2 + "@metaplex-foundation/solita": 0.20.0 + "@solana/spl-token": ^0.3.6 + "@solana/web3.js": ^1.70.3 + "@types/bn.js": ^5.1.1 + "@types/invariant": 2.2.35 + "@types/node": 24.0.15 + assert: ^2.0.0 + bn.js: ^5.2.1 + buffer: 6.0.3 + invariant: 2.2.4 + tsup: ^8.0.2 + typedoc: ^0.25.7 + typescript: "*" + languageName: unknown + linkType: soft + +"@tsconfig/node10@npm:^1.0.7": + version: 1.0.9 + resolution: "@tsconfig/node10@npm:1.0.9" + checksum: a33ae4dc2a621c0678ac8ac4bceb8e512ae75dac65417a2ad9b022d9b5411e863c4c198b6ba9ef659e14b9fb609bbec680841a2e84c1172df7a5ffcf076539df + languageName: node + linkType: hard + +"@tsconfig/node12@npm:^1.0.7": + version: 1.0.11 + resolution: "@tsconfig/node12@npm:1.0.11" + checksum: 5ce29a41b13e7897a58b8e2df11269c5395999e588b9a467386f99d1d26f6c77d1af2719e407621412520ea30517d718d5192a32403b8dfcc163bf33e40a338a + languageName: node + linkType: hard + +"@tsconfig/node14@npm:^1.0.0": + version: 1.0.3 + resolution: "@tsconfig/node14@npm:1.0.3" + checksum: 19275fe80c4c8d0ad0abed6a96dbf00642e88b220b090418609c4376e1cef81bf16237bf170ad1b341452feddb8115d8dd2e5acdfdea1b27422071163dc9ba9d + languageName: node + linkType: hard + +"@tsconfig/node16@npm:^1.0.2": + version: 1.0.3 + resolution: "@tsconfig/node16@npm:1.0.3" + checksum: 3a8b657dd047495b7ad23437d6afd20297ce90380ff0bdee93fc7d39a900dbd8d9e26e53ff6b465e7967ce2adf0b218782590ce9013285121e6a5928fbd6819f + languageName: node + linkType: hard + +"@types/bn.js@npm:^5.1.1": + version: 5.1.1 + resolution: "@types/bn.js@npm:5.1.1" + dependencies: + "@types/node": "*" + checksum: e50ed2dd3abe997e047caf90e0352c71e54fc388679735217978b4ceb7e336e51477791b715f49fd77195ac26dd296c7bad08a3be9750e235f9b2e1edb1b51c2 + languageName: node + linkType: hard + +"@types/connect@npm:^3.4.33": + version: 3.4.35 + resolution: "@types/connect@npm:3.4.35" + dependencies: + "@types/node": "*" + checksum: fe81351470f2d3165e8b12ce33542eef89ea893e36dd62e8f7d72566dfb7e448376ae962f9f3ea888547ce8b55a40020ca0e01d637fab5d99567673084542641 + languageName: node + linkType: hard + +"@types/estree@npm:1.0.6": + version: 1.0.6 + resolution: "@types/estree@npm:1.0.6" + checksum: 8825d6e729e16445d9a1dd2fb1db2edc5ed400799064cd4d028150701031af012ba30d6d03fe9df40f4d7a437d0de6d2b256020152b7b09bde9f2e420afdffd9 + languageName: node + linkType: hard + +"@types/invariant@npm:2.2.35": + version: 2.2.35 + resolution: "@types/invariant@npm:2.2.35" + checksum: af1b624057c89789ed0917838fea3d42bb0c101cc22b829a24d8777c678be3bc79d6ae05992a13bdf607b94731262467a2e62a809602ea1f7eea5e8c2242660d + languageName: node + linkType: hard + +"@types/mocha@npm:10.0.1": + version: 10.0.1 + resolution: "@types/mocha@npm:10.0.1" + checksum: 224ea9fce7b1734ccdb9aa99a622d902a538ce1847bca7fd22c5fb38adcf3ed536f50f48f587085db988a4bb3c2eb68f4b98e1cd6a38bc5547bd3bbbedc54495 + languageName: node + linkType: hard + +"@types/node-fetch@npm:2.6.2": + version: 2.6.2 + resolution: "@types/node-fetch@npm:2.6.2" + dependencies: + "@types/node": "*" + form-data: ^3.0.0 + checksum: 6f73b1470000d303d25a6fb92875ea837a216656cb7474f66cdd67bb014aa81a5a11e7ac9c21fe19bee9ecb2ef87c1962bceeaec31386119d1ac86e4c30ad7a6 + languageName: node + linkType: hard + +"@types/node@npm:*": + version: 18.11.17 + resolution: "@types/node@npm:18.11.17" + checksum: 1933afd068d5c75c068c6c4df6d10edb3b0b2bb6503d544e2f0496ac007c90596e6a5e284a8ef032451bc16f871b7e46719d7d2bea60e9b25d13a77d52161cac + languageName: node + linkType: hard + +"@types/node@npm:24.0.15": + version: 24.0.15 + resolution: "@types/node@npm:24.0.15" + dependencies: + undici-types: ~7.8.0 + checksum: 27f31e6976587efdfd13c0024703d7e11e6a27a6af48d488c6e5662733c9e8d47ac059e38cd9d491425f68f0c5e8e2bc060859b0b66afe79af0697acb0c25e4d + languageName: node + linkType: hard + +"@types/node@npm:^12.12.54": + version: 12.20.55 + resolution: "@types/node@npm:12.20.55" + checksum: e4f86785f4092706e0d3b0edff8dca5a13b45627e4b36700acd8dfe6ad53db71928c8dee914d4276c7fd3b6ccd829aa919811c9eb708a2c8e4c6eb3701178c37 + languageName: node + linkType: hard + +"@types/ws@npm:^7.4.4": + version: 7.4.7 + resolution: "@types/ws@npm:7.4.7" + dependencies: + "@types/node": "*" + checksum: b4c9b8ad209620c9b21e78314ce4ff07515c0cadab9af101c1651e7bfb992d7fd933bd8b9c99d110738fd6db523ed15f82f29f50b45510288da72e964dedb1a3 + languageName: node + linkType: hard + +"JSONStream@npm:^1.3.5": + version: 1.3.5 + resolution: "JSONStream@npm:1.3.5" + dependencies: + jsonparse: ^1.2.0 + through: ">=2.2.7 <3" + bin: + JSONStream: ./bin.js + checksum: 2605fa124260c61bad38bb65eba30d2f72216a78e94d0ab19b11b4e0327d572b8d530c0c9cc3b0764f727ad26d39e00bf7ebad57781ca6368394d73169c59e46 + languageName: node + linkType: hard + +"abbrev@npm:^3.0.0": + version: 3.0.1 + resolution: "abbrev@npm:3.0.1" + checksum: e70b209f5f408dd3a3bbd0eec4b10a2ffd64704a4a3821d0969d84928cc490a8eb60f85b78a95622c1841113edac10161c62e52f5e7d0027aa26786a8136e02e + languageName: node + linkType: hard + +"acorn-walk@npm:^8.1.1": + version: 8.2.0 + resolution: "acorn-walk@npm:8.2.0" + checksum: 1715e76c01dd7b2d4ca472f9c58968516a4899378a63ad5b6c2d668bba8da21a71976c14ec5f5b75f887b6317c4ae0b897ab141c831d741dc76024d8745f1ad1 + languageName: node + linkType: hard + +"acorn@npm:^8.4.1": + version: 8.8.1 + resolution: "acorn@npm:8.8.1" + bin: + acorn: bin/acorn + checksum: 4079b67283b94935157698831967642f24a075c52ce3feaaaafe095776dfbe15d86a1b33b1e53860fc0d062ed6c83f4284a5c87c85b9ad51853a01173da6097f + languageName: node + linkType: hard + +"agent-base@npm:^7.1.0, agent-base@npm:^7.1.2": + version: 7.1.4 + resolution: "agent-base@npm:7.1.4" + checksum: 86a7f542af277cfbd77dd61e7df8422f90bac512953709003a1c530171a9d019d072e2400eab2b59f84b49ab9dd237be44315ca663ac73e82b3922d10ea5eafa + languageName: node + linkType: hard + +"agentkeepalive@npm:^4.2.1": + version: 4.2.1 + resolution: "agentkeepalive@npm:4.2.1" + dependencies: + debug: ^4.1.0 + depd: ^1.1.2 + humanize-ms: ^1.2.1 + checksum: 39cb49ed8cf217fd6da058a92828a0a84e0b74c35550f82ee0a10e1ee403c4b78ade7948be2279b188b7a7303f5d396ea2738b134731e464bf28de00a4f72a18 + languageName: node + linkType: hard + +"ansi-colors@npm:4.1.1": + version: 4.1.1 + resolution: "ansi-colors@npm:4.1.1" + checksum: 138d04a51076cb085da0a7e2d000c5c0bb09f6e772ed5c65c53cb118d37f6c5f1637506d7155fb5f330f0abcf6f12fa2e489ac3f8cdab9da393bf1bb4f9a32b0 + languageName: node + linkType: hard + +"ansi-colors@npm:^4.1.3": + version: 4.1.3 + resolution: "ansi-colors@npm:4.1.3" + checksum: a9c2ec842038a1fabc7db9ece7d3177e2fe1c5dc6f0c51ecfbf5f39911427b89c00b5dc6b8bd95f82a26e9b16aaae2e83d45f060e98070ce4d1333038edceb0e + languageName: node + linkType: hard + +"ansi-regex@npm:^5.0.1": + version: 5.0.1 + resolution: "ansi-regex@npm:5.0.1" + checksum: 2aa4bb54caf2d622f1afdad09441695af2a83aa3fe8b8afa581d205e57ed4261c183c4d3877cee25794443fde5876417d859c108078ab788d6af7e4fe52eb66b + languageName: node + linkType: hard + +"ansi-regex@npm:^6.0.1": + version: 6.1.0 + resolution: "ansi-regex@npm:6.1.0" + checksum: 495834a53b0856c02acd40446f7130cb0f8284f4a39afdab20d5dc42b2e198b1196119fe887beed8f9055c4ff2055e3b2f6d4641d0be018cdfb64fedf6fc1aac + languageName: node + linkType: hard + +"ansi-sequence-parser@npm:^1.1.0": + version: 1.1.3 + resolution: "ansi-sequence-parser@npm:1.1.3" + checksum: 98e516176fa9177d501a49a12b96dd26359eaa1c6cee9d6261ebd36540cd4d33a9acd5a8cf43ed3e4508f1cf8b28fcc17643abd49bdf017471e840d98d1c036d + languageName: node + linkType: hard + +"ansi-styles@npm:^4.0.0, ansi-styles@npm:^4.1.0": + version: 4.3.0 + resolution: "ansi-styles@npm:4.3.0" + dependencies: + color-convert: ^2.0.1 + checksum: 513b44c3b2105dd14cc42a19271e80f386466c4be574bccf60b627432f9198571ebf4ab1e4c3ba17347658f4ee1711c163d574248c0c1cdc2d5917a0ad582ec4 + languageName: node + linkType: hard + +"ansi-styles@npm:^6.1.0": + version: 6.2.1 + resolution: "ansi-styles@npm:6.2.1" + checksum: ef940f2f0ced1a6347398da88a91da7930c33ecac3c77b72c5905f8b8fe402c52e6fde304ff5347f616e27a742da3f1dc76de98f6866c69251ad0b07a66776d9 + languageName: node + linkType: hard + +"ansicolors@npm:^0.3.2, ansicolors@npm:~0.3.2": + version: 0.3.2 + resolution: "ansicolors@npm:0.3.2" + checksum: e84fae7ebc27ac96d9dbb57f35f078cd6dde1b7046b0f03f73dcefc9fbb1f2e82e3685d083466aded8faf038f9fa9ebb408d215282bcd7aaa301d5ac3c486815 + languageName: node + linkType: hard + +"any-promise@npm:^1.0.0": + version: 1.3.0 + resolution: "any-promise@npm:1.3.0" + checksum: 0ee8a9bdbe882c90464d75d1f55cf027f5458650c4bd1f0467e65aec38ccccda07ca5844969ee77ed46d04e7dded3eaceb027e8d32f385688523fe305fa7e1de + languageName: node + linkType: hard + +"anymatch@npm:~3.1.2": + version: 3.1.3 + resolution: "anymatch@npm:3.1.3" + dependencies: + normalize-path: ^3.0.0 + picomatch: ^2.0.4 + checksum: 3e044fd6d1d26545f235a9fe4d7a534e2029d8e59fa7fd9f2a6eb21230f6b5380ea1eaf55136e60cbf8e613544b3b766e7a6fa2102e2a3a117505466e3025dc2 + languageName: node + linkType: hard + +"arg@npm:^4.1.0": + version: 4.1.3 + resolution: "arg@npm:4.1.3" + checksum: 544af8dd3f60546d3e4aff084d451b96961d2267d668670199692f8d054f0415d86fc5497d0e641e91546f0aa920e7c29e5250e99fc89f5552a34b5d93b77f43 + languageName: node + linkType: hard + +"argparse@npm:^2.0.1": + version: 2.0.1 + resolution: "argparse@npm:2.0.1" + checksum: 83644b56493e89a254bae05702abf3a1101b4fa4d0ca31df1c9985275a5a5bd47b3c27b7fa0b71098d41114d8ca000e6ed90cad764b306f8a503665e4d517ced + languageName: node + linkType: hard + +"assert@npm:^2.0.0": + version: 2.0.0 + resolution: "assert@npm:2.0.0" + dependencies: + es6-object-assign: ^1.1.0 + is-nan: ^1.2.1 + object-is: ^1.0.1 + util: ^0.12.0 + checksum: bb91f181a86d10588ee16c5e09c280f9811373974c29974cbe401987ea34e966699d7989a812b0e19377b511ea0bc627f5905647ce569311824848ede382cae8 + languageName: node + linkType: hard + +"assert@npm:^2.1.0": + version: 2.1.0 + resolution: "assert@npm:2.1.0" + dependencies: + call-bind: ^1.0.2 + is-nan: ^1.3.2 + object-is: ^1.1.5 + object.assign: ^4.1.4 + util: ^0.12.5 + checksum: 1ed1cabba9abe55f4109b3f7292b4e4f3cf2953aad8dc148c0b3c3bd676675c31b1abb32ef563b7d5a19d1715bf90d1e5f09fad2a4ee655199468902da80f7c2 + languageName: node + linkType: hard + +"asynckit@npm:^0.4.0": + version: 0.4.0 + resolution: "asynckit@npm:0.4.0" + checksum: 7b78c451df768adba04e2d02e63e2d0bf3b07adcd6e42b4cf665cb7ce899bedd344c69a1dcbce355b5f972d597b25aaa1c1742b52cffd9caccb22f348114f6be + languageName: node + linkType: hard + +"available-typed-arrays@npm:^1.0.5": + version: 1.0.5 + resolution: "available-typed-arrays@npm:1.0.5" + checksum: 20eb47b3cefd7db027b9bbb993c658abd36d4edd3fe1060e83699a03ee275b0c9b216cc076ff3f2db29073225fb70e7613987af14269ac1fe2a19803ccc97f1a + languageName: node + linkType: hard + +"balanced-match@npm:^1.0.0": + version: 1.0.2 + resolution: "balanced-match@npm:1.0.2" + checksum: 9706c088a283058a8a99e0bf91b0a2f75497f185980d9ffa8b304de1d9e58ebda7c72c07ebf01dadedaac5b2907b2c6f566f660d62bd336c3468e960403b9d65 + languageName: node + linkType: hard + +"base-x@npm:^3.0.2": + version: 3.0.9 + resolution: "base-x@npm:3.0.9" + dependencies: + safe-buffer: ^5.0.1 + checksum: 957101d6fd09e1903e846fd8f69fd7e5e3e50254383e61ab667c725866bec54e5ece5ba49ce385128ae48f9ec93a26567d1d5ebb91f4d56ef4a9cc0d5a5481e8 + languageName: node + linkType: hard + +"base-x@npm:^4.0.0": + version: 4.0.0 + resolution: "base-x@npm:4.0.0" + checksum: b25db9e07eb1998472a20557c7f00c797dc0595f79df95155ab74274e7fa98b9f2659b3ee547ac8773666b7f69540656793aeb97ad2b1ceccdb6fa5faaf69ac0 + languageName: node + linkType: hard + +"base64-js@npm:^1.3.1": + version: 1.5.1 + resolution: "base64-js@npm:1.5.1" + checksum: 669632eb3745404c2f822a18fc3a0122d2f9a7a13f7fb8b5823ee19d1d2ff9ee5b52c53367176ea4ad093c332fd5ab4bd0ebae5a8e27917a4105a4cfc86b1005 + languageName: node + linkType: hard + +"bigint-buffer@npm:^1.1.5": + version: 1.1.5 + resolution: "bigint-buffer@npm:1.1.5" + dependencies: + bindings: ^1.3.0 + node-gyp: latest + checksum: d010c9f57758bcdaccb435d88b483ffcc95fe8bbc6e7fb3a44fb5221f29c894ffaf4a3c5a4a530e0e7d6608203c2cde9b79ee4f2386cd6d4462d1070bc8c9f4e + languageName: node + linkType: hard + +"bignumber.js@npm:^9.0.1": + version: 9.1.1 + resolution: "bignumber.js@npm:9.1.1" + checksum: ad243b7e2f9120b112d670bb3d674128f0bd2ca1745b0a6c9df0433bd2c0252c43e6315d944c2ac07b4c639e7496b425e46842773cf89c6a2dcd4f31e5c4b11e + languageName: node + linkType: hard + +"binary-extensions@npm:^2.0.0": + version: 2.2.0 + resolution: "binary-extensions@npm:2.2.0" + checksum: ccd267956c58d2315f5d3ea6757cf09863c5fc703e50fbeb13a7dc849b812ef76e3cf9ca8f35a0c48498776a7478d7b4a0418e1e2b8cb9cb9731f2922aaad7f8 + languageName: node + linkType: hard + +"bindings@npm:^1.3.0": + version: 1.5.0 + resolution: "bindings@npm:1.5.0" + dependencies: + file-uri-to-path: 1.0.0 + checksum: 65b6b48095717c2e6105a021a7da4ea435aa8d3d3cd085cb9e85bcb6e5773cf318c4745c3f7c504412855940b585bdf9b918236612a1c7a7942491de176f1ae7 + languageName: node + linkType: hard + +"bn.js@npm:^5.0.0, bn.js@npm:^5.2.0, bn.js@npm:^5.2.1": + version: 5.2.1 + resolution: "bn.js@npm:5.2.1" + checksum: 3dd8c8d38055fedfa95c1d5fc3c99f8dd547b36287b37768db0abab3c239711f88ff58d18d155dd8ad902b0b0cee973747b7ae20ea12a09473272b0201c9edd3 + languageName: node + linkType: hard + +"borsh@npm:^0.7.0": + version: 0.7.0 + resolution: "borsh@npm:0.7.0" + dependencies: + bn.js: ^5.2.0 + bs58: ^4.0.0 + text-encoding-utf-8: ^1.0.2 + checksum: e98bfb5f7cfb820819c2870b884dac58dd4b4ce6a86c286c8fbf5c9ca582e73a8c6094df67e81a28c418ff07a309c6b118b2e27fdfea83fd92b8100c741da0b5 + languageName: node + linkType: hard + +"brace-expansion@npm:^1.1.7": + version: 1.1.11 + resolution: "brace-expansion@npm:1.1.11" + dependencies: + balanced-match: ^1.0.0 + concat-map: 0.0.1 + checksum: faf34a7bb0c3fcf4b59c7808bc5d2a96a40988addf2e7e09dfbb67a2251800e0d14cd2bfc1aa79174f2f5095c54ff27f46fb1289fe2d77dac755b5eb3434cc07 + languageName: node + linkType: hard + +"brace-expansion@npm:^2.0.1": + version: 2.0.1 + resolution: "brace-expansion@npm:2.0.1" + dependencies: + balanced-match: ^1.0.0 + checksum: a61e7cd2e8a8505e9f0036b3b6108ba5e926b4b55089eeb5550cd04a471fe216c96d4fe7e4c7f995c728c554ae20ddfc4244cad10aef255e72b62930afd233d1 + languageName: node + linkType: hard + +"braces@npm:~3.0.2": + version: 3.0.2 + resolution: "braces@npm:3.0.2" + dependencies: + fill-range: ^7.0.1 + checksum: e2a8e769a863f3d4ee887b5fe21f63193a891c68b612ddb4b68d82d1b5f3ff9073af066c343e9867a393fe4c2555dcb33e89b937195feb9c1613d259edfcd459 + languageName: node + linkType: hard + +"browser-stdout@npm:1.3.1": + version: 1.3.1 + resolution: "browser-stdout@npm:1.3.1" + checksum: b717b19b25952dd6af483e368f9bcd6b14b87740c3d226c2977a65e84666ffd67000bddea7d911f111a9b6ddc822b234de42d52ab6507bce4119a4cc003ef7b3 + languageName: node + linkType: hard + +"bs58@npm:^4.0.0, bs58@npm:^4.0.1": + version: 4.0.1 + resolution: "bs58@npm:4.0.1" + dependencies: + base-x: ^3.0.2 + checksum: b3c5365bb9e0c561e1a82f1a2d809a1a692059fae016be233a6127ad2f50a6b986467c3a50669ce4c18929dcccb297c5909314dd347a25a68c21b68eb3e95ac2 + languageName: node + linkType: hard + +"bs58@npm:^5.0.0": + version: 5.0.0 + resolution: "bs58@npm:5.0.0" + dependencies: + base-x: ^4.0.0 + checksum: 2475cb0684e07077521aac718e604a13e0f891d58cff923d437a2f7e9e28703ab39fce9f84c7c703ab369815a675f11e3bd394d38643bfe8969fbe42e6833d45 + languageName: node + linkType: hard + +"buffer@npm:6.0.1": + version: 6.0.1 + resolution: "buffer@npm:6.0.1" + dependencies: + base64-js: ^1.3.1 + ieee754: ^1.2.1 + checksum: 0274c2c6c5c5d9e9e1fd48116c26a3e3f824fe262ff379f630771f590c2e4e7d1fa2604a58684bfc4471a3f9cc40c6317be26b50f15c4cca126249bfc84c4f8b + languageName: node + linkType: hard + +"buffer@npm:6.0.3, buffer@npm:^6.0.3, buffer@npm:~6.0.3": + version: 6.0.3 + resolution: "buffer@npm:6.0.3" + dependencies: + base64-js: ^1.3.1 + ieee754: ^1.2.1 + checksum: 5ad23293d9a731e4318e420025800b42bf0d264004c0286c8cc010af7a270c7a0f6522e84f54b9ad65cbd6db20b8badbfd8d2ebf4f80fa03dab093b89e68c3f9 + languageName: node + linkType: hard + +"bufferutil@npm:^4.0.1": + version: 4.0.7 + resolution: "bufferutil@npm:4.0.7" + dependencies: + node-gyp: latest + node-gyp-build: ^4.3.0 + checksum: f75aa87e3d1b99b87a95f60a855e63f70af07b57fb8443e75a2ddfef2e47788d130fdd46e3a78fd7e0c10176082b26dfbed970c5b8632e1cc299cafa0e93ce45 + languageName: node + linkType: hard + +"bundle-require@npm:^5.0.0": + version: 5.1.0 + resolution: "bundle-require@npm:5.1.0" + dependencies: + load-tsconfig: ^0.2.3 + peerDependencies: + esbuild: ">=0.18" + checksum: 78a972b2d83b212f8bf3919bf806cc0846db4fb2182eb85770d4caec459f3b78053477acffb7396c6c15ceb7e132f22b18c1b430388d0f1b335a3b73b5012a1c + languageName: node + linkType: hard + +"cac@npm:^6.7.14": + version: 6.7.14 + resolution: "cac@npm:6.7.14" + checksum: 45a2496a9443abbe7f52a49b22fbe51b1905eff46e03fd5e6c98e3f85077be3f8949685a1849b1a9cd2bc3e5567dfebcf64f01ce01847baf918f1b37c839791a + languageName: node + linkType: hard + +"cacache@npm:^19.0.1": + version: 19.0.1 + resolution: "cacache@npm:19.0.1" + dependencies: + "@npmcli/fs": ^4.0.0 + fs-minipass: ^3.0.0 + glob: ^10.2.2 + lru-cache: ^10.0.1 + minipass: ^7.0.3 + minipass-collect: ^2.0.1 + minipass-flush: ^1.0.5 + minipass-pipeline: ^1.2.4 + p-map: ^7.0.2 + ssri: ^12.0.0 + tar: ^7.4.3 + unique-filename: ^4.0.0 + checksum: e95684717de6881b4cdaa949fa7574e3171946421cd8291769dd3d2417dbf7abf4aa557d1f968cca83dcbc95bed2a281072b09abfc977c942413146ef7ed4525 + languageName: node + linkType: hard + +"call-bind-apply-helpers@npm:^1.0.0, call-bind-apply-helpers@npm:^1.0.1, call-bind-apply-helpers@npm:^1.0.2": + version: 1.0.2 + resolution: "call-bind-apply-helpers@npm:1.0.2" + dependencies: + es-errors: ^1.3.0 + function-bind: ^1.1.2 + checksum: b2863d74fcf2a6948221f65d95b91b4b2d90cfe8927650b506141e669f7d5de65cea191bf788838bc40d13846b7886c5bc5c84ab96c3adbcf88ad69a72fcdc6b + languageName: node + linkType: hard + +"call-bind@npm:^1.0.0, call-bind@npm:^1.0.2": + version: 1.0.2 + resolution: "call-bind@npm:1.0.2" + dependencies: + function-bind: ^1.1.1 + get-intrinsic: ^1.0.2 + checksum: f8e31de9d19988a4b80f3e704788c4a2d6b6f3d17cfec4f57dc29ced450c53a49270dc66bf0fbd693329ee948dd33e6c90a329519aef17474a4d961e8d6426b0 + languageName: node + linkType: hard + +"call-bind@npm:^1.0.7, call-bind@npm:^1.0.8": + version: 1.0.8 + resolution: "call-bind@npm:1.0.8" + dependencies: + call-bind-apply-helpers: ^1.0.0 + es-define-property: ^1.0.0 + get-intrinsic: ^1.2.4 + set-function-length: ^1.2.2 + checksum: aa2899bce917a5392fd73bd32e71799c37c0b7ab454e0ed13af7f6727549091182aade8bbb7b55f304a5bc436d543241c14090fb8a3137e9875e23f444f4f5a9 + languageName: node + linkType: hard + +"call-bound@npm:^1.0.3": + version: 1.0.3 + resolution: "call-bound@npm:1.0.3" + dependencies: + call-bind-apply-helpers: ^1.0.1 + get-intrinsic: ^1.2.6 + checksum: a93bbe0f2d0a2d6c144a4349ccd0593d5d0d5d9309b69101710644af8964286420062f2cc3114dca120b9bc8cc07507952d4b1b3ea7672e0d7f6f1675efedb32 + languageName: node + linkType: hard + +"camelcase@npm:^6.0.0, camelcase@npm:^6.2.1": + version: 6.3.0 + resolution: "camelcase@npm:6.3.0" + checksum: 8c96818a9076434998511251dcb2761a94817ea17dbdc37f47ac080bd088fc62c7369429a19e2178b993497132c8cbcf5cc1f44ba963e76782ba469c0474938d + languageName: node + linkType: hard + +"chalk@npm:^4.1.0, chalk@npm:~4.1.2": + version: 4.1.2 + resolution: "chalk@npm:4.1.2" + dependencies: + ansi-styles: ^4.1.0 + supports-color: ^7.1.0 + checksum: fe75c9d5c76a7a98d45495b91b2172fa3b7a09e0cc9370e5c8feb1c567b85c4288e2b3fded7cfdd7359ac28d6b3844feb8b82b8686842e93d23c827c417e83fc + languageName: node + linkType: hard + +"chokidar@npm:3.5.3": + version: 3.5.3 + resolution: "chokidar@npm:3.5.3" + dependencies: + anymatch: ~3.1.2 + braces: ~3.0.2 + fsevents: ~2.3.2 + glob-parent: ~5.1.2 + is-binary-path: ~2.1.0 + is-glob: ~4.0.1 + normalize-path: ~3.0.0 + readdirp: ~3.6.0 + dependenciesMeta: + fsevents: + optional: true + checksum: b49fcde40176ba007ff361b198a2d35df60d9bb2a5aab228279eb810feae9294a6b4649ab15981304447afe1e6ffbf4788ad5db77235dc770ab777c6e771980c + languageName: node + linkType: hard + +"chokidar@npm:^4.0.1": + version: 4.0.3 + resolution: "chokidar@npm:4.0.3" + dependencies: + readdirp: ^4.0.1 + checksum: a8765e452bbafd04f3f2fad79f04222dd65f43161488bb6014a41099e6ca18d166af613d59a90771908c1c823efa3f46ba36b86ac50b701c20c1b9908c5fe36e + languageName: node + linkType: hard + +"chownr@npm:^3.0.0": + version: 3.0.0 + resolution: "chownr@npm:3.0.0" + checksum: fd73a4bab48b79e66903fe1cafbdc208956f41ea4f856df883d0c7277b7ab29fd33ee65f93b2ec9192fc0169238f2f8307b7735d27c155821d886b84aa97aa8d + languageName: node + linkType: hard + +"cliui@npm:^7.0.2": + version: 7.0.4 + resolution: "cliui@npm:7.0.4" + dependencies: + string-width: ^4.2.0 + strip-ansi: ^6.0.0 + wrap-ansi: ^7.0.0 + checksum: ce2e8f578a4813806788ac399b9e866297740eecd4ad1823c27fd344d78b22c5f8597d548adbcc46f0573e43e21e751f39446c5a5e804a12aace402b7a315d7f + languageName: node + linkType: hard + +"color-convert@npm:^2.0.1": + version: 2.0.1 + resolution: "color-convert@npm:2.0.1" + dependencies: + color-name: ~1.1.4 + checksum: 79e6bdb9fd479a205c71d89574fccfb22bd9053bd98c6c4d870d65c132e5e904e6034978e55b43d69fcaa7433af2016ee203ce76eeba9cfa554b373e7f7db336 + languageName: node + linkType: hard + +"color-name@npm:~1.1.4": + version: 1.1.4 + resolution: "color-name@npm:1.1.4" + checksum: b0445859521eb4021cd0fb0cc1a75cecf67fceecae89b63f62b201cca8d345baf8b952c966862a9d9a2632987d4f6581f0ec8d957dfacece86f0a7919316f610 + languageName: node + linkType: hard + +"combined-stream@npm:^1.0.8": + version: 1.0.8 + resolution: "combined-stream@npm:1.0.8" + dependencies: + delayed-stream: ~1.0.0 + checksum: 49fa4aeb4916567e33ea81d088f6584749fc90c7abec76fd516bf1c5aa5c79f3584b5ba3de6b86d26ddd64bae5329c4c7479343250cfe71c75bb366eae53bb7c + languageName: node + linkType: hard + +"commander@npm:^12.1.0": + version: 12.1.0 + resolution: "commander@npm:12.1.0" + checksum: 68e9818b00fc1ed9cdab9eb16905551c2b768a317ae69a5e3c43924c2b20ac9bb65b27e1cab36aeda7b6496376d4da908996ba2c0b5d79463e0fb1e77935d514 + languageName: node + linkType: hard + +"commander@npm:^2.20.3": + version: 2.20.3 + resolution: "commander@npm:2.20.3" + checksum: ab8c07884e42c3a8dbc5dd9592c606176c7eb5c1ca5ff274bcf907039b2c41de3626f684ea75ccf4d361ba004bbaff1f577d5384c155f3871e456bdf27becf9e + languageName: node + linkType: hard + +"commander@npm:^4.0.0": + version: 4.1.1 + resolution: "commander@npm:4.1.1" + checksum: d7b9913ff92cae20cb577a4ac6fcc121bd6223319e54a40f51a14740a681ad5c574fd29a57da478a5f234a6fa6c52cbf0b7c641353e03c648b1ae85ba670b977 + languageName: node + linkType: hard + +"concat-map@npm:0.0.1": + version: 0.0.1 + resolution: "concat-map@npm:0.0.1" + checksum: 902a9f5d8967a3e2faf138d5cb784b9979bad2e6db5357c5b21c568df4ebe62bcb15108af1b2253744844eb964fc023fbd9afbbbb6ddd0bcc204c6fb5b7bf3af + languageName: node + linkType: hard + +"consola@npm:^3.2.3": + version: 3.4.0 + resolution: "consola@npm:3.4.0" + checksum: 03d9ee487a53b710f53aeff18447a242d95c080aff051389b5ee49915bebb38cb31687e144e1bb3dd6ebcfc454fef566cc5912f6150c7cfe9349947ba09a5a87 + languageName: node + linkType: hard + +"create-require@npm:^1.1.0": + version: 1.1.1 + resolution: "create-require@npm:1.1.1" + checksum: a9a1503d4390d8b59ad86f4607de7870b39cad43d929813599a23714831e81c520bddf61bcdd1f8e30f05fd3a2b71ae8538e946eb2786dc65c2bbc520f692eff + languageName: node + linkType: hard + +"cross-spawn@npm:^7.0.0": + version: 7.0.6 + resolution: "cross-spawn@npm:7.0.6" + dependencies: + path-key: ^3.1.0 + shebang-command: ^2.0.0 + which: ^2.0.1 + checksum: 8d306efacaf6f3f60e0224c287664093fa9185680b2d195852ba9a863f85d02dcc737094c6e512175f8ee0161f9b87c73c6826034c2422e39de7d6569cf4503b + languageName: node + linkType: hard + +"debug@npm:4": + version: 4.4.1 + resolution: "debug@npm:4.4.1" + dependencies: + ms: ^2.1.3 + peerDependenciesMeta: + supports-color: + optional: true + checksum: a43826a01cda685ee4cec00fb2d3322eaa90ccadbef60d9287debc2a886be3e835d9199c80070ede75a409ee57828c4c6cd80e4b154f2843f0dc95a570dc0729 + languageName: node + linkType: hard + +"debug@npm:4.3.4, debug@npm:^4.1.0, debug@npm:^4.3.3, debug@npm:^4.3.4": + version: 4.3.4 + resolution: "debug@npm:4.3.4" + dependencies: + ms: 2.1.2 + peerDependenciesMeta: + supports-color: + optional: true + checksum: 3dbad3f94ea64f34431a9cbf0bafb61853eda57bff2880036153438f50fb5a84f27683ba0d8e5426bf41a8c6ff03879488120cf5b3a761e77953169c0600a708 + languageName: node + linkType: hard + +"debug@npm:^4.3.7": + version: 4.4.0 + resolution: "debug@npm:4.4.0" + dependencies: + ms: ^2.1.3 + peerDependenciesMeta: + supports-color: + optional: true + checksum: fb42df878dd0e22816fc56e1fdca9da73caa85212fbe40c868b1295a6878f9101ae684f4eeef516c13acfc700f5ea07f1136954f43d4cd2d477a811144136479 + languageName: node + linkType: hard + +"decamelize@npm:^4.0.0": + version: 4.0.0 + resolution: "decamelize@npm:4.0.0" + checksum: b7d09b82652c39eead4d6678bb578e3bebd848add894b76d0f6b395bc45b2d692fb88d977e7cfb93c4ed6c119b05a1347cef261174916c2e75c0a8ca57da1809 + languageName: node + linkType: hard + +"define-data-property@npm:^1.0.1, define-data-property@npm:^1.1.4": + version: 1.1.4 + resolution: "define-data-property@npm:1.1.4" + dependencies: + es-define-property: ^1.0.0 + es-errors: ^1.3.0 + gopd: ^1.0.1 + checksum: 8068ee6cab694d409ac25936eb861eea704b7763f7f342adbdfe337fc27c78d7ae0eff2364b2917b58c508d723c7a074326d068eef2e45c4edcd85cf94d0313b + languageName: node + linkType: hard + +"define-properties@npm:^1.1.3": + version: 1.1.4 + resolution: "define-properties@npm:1.1.4" + dependencies: + has-property-descriptors: ^1.0.0 + object-keys: ^1.1.1 + checksum: ce0aef3f9eb193562b5cfb79b2d2c86b6a109dfc9fdcb5f45d680631a1a908c06824ddcdb72b7573b54e26ace07f0a23420aaba0d5c627b34d2c1de8ef527e2b + languageName: node + linkType: hard + +"define-properties@npm:^1.2.1": + version: 1.2.1 + resolution: "define-properties@npm:1.2.1" + dependencies: + define-data-property: ^1.0.1 + has-property-descriptors: ^1.0.0 + object-keys: ^1.1.1 + checksum: b4ccd00597dd46cb2d4a379398f5b19fca84a16f3374e2249201992f36b30f6835949a9429669ee6b41b6e837205a163eadd745e472069e70dfc10f03e5fcc12 + languageName: node + linkType: hard + +"delay@npm:^5.0.0": + version: 5.0.0 + resolution: "delay@npm:5.0.0" + checksum: 62f151151ecfde0d9afbb8a6be37a6d103c4cb24f35a20ef3fe56f920b0d0d0bb02bc9c0a3084d0179ef669ca332b91155f2ee4d9854622cd2cdba5fc95285f9 + languageName: node + linkType: hard + +"delayed-stream@npm:~1.0.0": + version: 1.0.0 + resolution: "delayed-stream@npm:1.0.0" + checksum: 46fe6e83e2cb1d85ba50bd52803c68be9bd953282fa7096f51fc29edd5d67ff84ff753c51966061e5ba7cb5e47ef6d36a91924eddb7f3f3483b1c560f77a0020 + languageName: node + linkType: hard + +"depd@npm:^1.1.2": + version: 1.1.2 + resolution: "depd@npm:1.1.2" + checksum: 6b406620d269619852885ce15965272b829df6f409724415e0002c8632ab6a8c0a08ec1f0bd2add05dc7bd7507606f7e2cc034fa24224ab829580040b835ecd9 + languageName: node + linkType: hard + +"diff@npm:5.0.0": + version: 5.0.0 + resolution: "diff@npm:5.0.0" + checksum: f19fe29284b633afdb2725c2a8bb7d25761ea54d321d8e67987ac851c5294be4afeab532bd84531e02583a3fe7f4014aa314a3eda84f5590e7a9e6b371ef3b46 + languageName: node + linkType: hard + +"diff@npm:^4.0.1": + version: 4.0.2 + resolution: "diff@npm:4.0.2" + checksum: f2c09b0ce4e6b301c221addd83bf3f454c0bc00caa3dd837cf6c127d6edf7223aa2bbe3b688feea110b7f262adbfc845b757c44c8a9f8c0c5b15d8fa9ce9d20d + languageName: node + linkType: hard + +"dot-case@npm:^3.0.4": + version: 3.0.4 + resolution: "dot-case@npm:3.0.4" + dependencies: + no-case: ^3.0.4 + tslib: ^2.0.3 + checksum: a65e3519414856df0228b9f645332f974f2bf5433370f544a681122eab59e66038fc3349b4be1cdc47152779dac71a5864f1ccda2f745e767c46e9c6543b1169 + languageName: node + linkType: hard + +"dunder-proto@npm:^1.0.1": + version: 1.0.1 + resolution: "dunder-proto@npm:1.0.1" + dependencies: + call-bind-apply-helpers: ^1.0.1 + es-errors: ^1.3.0 + gopd: ^1.2.0 + checksum: 149207e36f07bd4941921b0ca929e3a28f1da7bd6b6ff8ff7f4e2f2e460675af4576eeba359c635723dc189b64cdd4787e0255897d5b135ccc5d15cb8685fc90 + languageName: node + linkType: hard + +"eastasianwidth@npm:^0.2.0": + version: 0.2.0 + resolution: "eastasianwidth@npm:0.2.0" + checksum: 7d00d7cd8e49b9afa762a813faac332dee781932d6f2c848dc348939c4253f1d4564341b7af1d041853bc3f32c2ef141b58e0a4d9862c17a7f08f68df1e0f1ed + languageName: node + linkType: hard + +"emoji-regex@npm:^8.0.0": + version: 8.0.0 + resolution: "emoji-regex@npm:8.0.0" + checksum: d4c5c39d5a9868b5fa152f00cada8a936868fd3367f33f71be515ecee4c803132d11b31a6222b2571b1e5f7e13890156a94880345594d0ce7e3c9895f560f192 + languageName: node + linkType: hard + +"emoji-regex@npm:^9.2.2": + version: 9.2.2 + resolution: "emoji-regex@npm:9.2.2" + checksum: 8487182da74aabd810ac6d6f1994111dfc0e331b01271ae01ec1eb0ad7b5ecc2bbbbd2f053c05cb55a1ac30449527d819bbfbf0e3de1023db308cbcb47f86601 + languageName: node + linkType: hard + +"encoding@npm:^0.1.13": + version: 0.1.13 + resolution: "encoding@npm:0.1.13" + dependencies: + iconv-lite: ^0.6.2 + checksum: bb98632f8ffa823996e508ce6a58ffcf5856330fde839ae42c9e1f436cc3b5cc651d4aeae72222916545428e54fd0f6aa8862fd8d25bdbcc4589f1e3f3715e7f + languageName: node + linkType: hard + +"env-paths@npm:^2.2.0": + version: 2.2.1 + resolution: "env-paths@npm:2.2.1" + checksum: 65b5df55a8bab92229ab2b40dad3b387fad24613263d103a97f91c9fe43ceb21965cd3392b1ccb5d77088021e525c4e0481adb309625d0cb94ade1d1fb8dc17e + languageName: node + linkType: hard + +"err-code@npm:^2.0.2": + version: 2.0.3 + resolution: "err-code@npm:2.0.3" + checksum: 8b7b1be20d2de12d2255c0bc2ca638b7af5171142693299416e6a9339bd7d88fc8d7707d913d78e0993176005405a236b066b45666b27b797252c771156ace54 + languageName: node + linkType: hard + +"es-define-property@npm:^1.0.0, es-define-property@npm:^1.0.1": + version: 1.0.1 + resolution: "es-define-property@npm:1.0.1" + checksum: 0512f4e5d564021c9e3a644437b0155af2679d10d80f21adaf868e64d30efdfbd321631956f20f42d655fedb2e3a027da479fad3fa6048f768eb453a80a5f80a + languageName: node + linkType: hard + +"es-errors@npm:^1.3.0": + version: 1.3.0 + resolution: "es-errors@npm:1.3.0" + checksum: ec1414527a0ccacd7f15f4a3bc66e215f04f595ba23ca75cdae0927af099b5ec865f9f4d33e9d7e86f512f252876ac77d4281a7871531a50678132429b1271b5 + languageName: node + linkType: hard + +"es-object-atoms@npm:^1.0.0, es-object-atoms@npm:^1.1.1": + version: 1.1.1 + resolution: "es-object-atoms@npm:1.1.1" + dependencies: + es-errors: ^1.3.0 + checksum: 214d3767287b12f36d3d7267ef342bbbe1e89f899cfd67040309fc65032372a8e60201410a99a1645f2f90c1912c8c49c8668066f6bdd954bcd614dda2e3da97 + languageName: node + linkType: hard + +"es6-object-assign@npm:^1.1.0": + version: 1.1.0 + resolution: "es6-object-assign@npm:1.1.0" + checksum: 8d4fdf63484d78b5c64cacc2c2e1165bc7b6a64b739d2a9db6a4dc8641d99cc9efb433cdd4dc3d3d6b00bfa6ce959694e4665e3255190339945c5f33b692b5d8 + languageName: node + linkType: hard + +"es6-promise@npm:^4.0.3": + version: 4.2.8 + resolution: "es6-promise@npm:4.2.8" + checksum: 95614a88873611cb9165a85d36afa7268af5c03a378b35ca7bda9508e1d4f1f6f19a788d4bc755b3fd37c8ebba40782018e02034564ff24c9d6fa37e959ad57d + languageName: node + linkType: hard + +"es6-promisify@npm:^5.0.0": + version: 5.0.0 + resolution: "es6-promisify@npm:5.0.0" + dependencies: + es6-promise: ^4.0.3 + checksum: fbed9d791598831413be84a5374eca8c24800ec71a16c1c528c43a98e2dadfb99331483d83ae6094ddb9b87e6f799a15d1553cebf756047e0865c753bc346b92 + languageName: node + linkType: hard + +"esbuild@npm:^0.24.0": + version: 0.24.2 + resolution: "esbuild@npm:0.24.2" + dependencies: + "@esbuild/aix-ppc64": 0.24.2 + "@esbuild/android-arm": 0.24.2 + "@esbuild/android-arm64": 0.24.2 + "@esbuild/android-x64": 0.24.2 + "@esbuild/darwin-arm64": 0.24.2 + "@esbuild/darwin-x64": 0.24.2 + "@esbuild/freebsd-arm64": 0.24.2 + "@esbuild/freebsd-x64": 0.24.2 + "@esbuild/linux-arm": 0.24.2 + "@esbuild/linux-arm64": 0.24.2 + "@esbuild/linux-ia32": 0.24.2 + "@esbuild/linux-loong64": 0.24.2 + "@esbuild/linux-mips64el": 0.24.2 + "@esbuild/linux-ppc64": 0.24.2 + "@esbuild/linux-riscv64": 0.24.2 + "@esbuild/linux-s390x": 0.24.2 + "@esbuild/linux-x64": 0.24.2 + "@esbuild/netbsd-arm64": 0.24.2 + "@esbuild/netbsd-x64": 0.24.2 + "@esbuild/openbsd-arm64": 0.24.2 + "@esbuild/openbsd-x64": 0.24.2 + "@esbuild/sunos-x64": 0.24.2 + "@esbuild/win32-arm64": 0.24.2 + "@esbuild/win32-ia32": 0.24.2 + "@esbuild/win32-x64": 0.24.2 + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-arm64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-arm64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: e2303f8331887e31330b5a972fb9640ad93dfc5af76cb2156faa9eaa32bac5c403244096cbdafc45622829913e63664dfd88410987e3468df4354492f908a094 + languageName: node + linkType: hard + +"escalade@npm:^3.1.1": + version: 3.1.1 + resolution: "escalade@npm:3.1.1" + checksum: a3e2a99f07acb74b3ad4989c48ca0c3140f69f923e56d0cba0526240ee470b91010f9d39001f2a4a313841d237ede70a729e92125191ba5d21e74b106800b133 + languageName: node + linkType: hard + +"escape-string-regexp@npm:4.0.0": + version: 4.0.0 + resolution: "escape-string-regexp@npm:4.0.0" + checksum: 98b48897d93060f2322108bf29db0feba7dd774be96cd069458d1453347b25ce8682ecc39859d4bca2203cc0ab19c237bcc71755eff49a0f8d90beadeeba5cc5 + languageName: node + linkType: hard + +"eventemitter3@npm:^4.0.7": + version: 4.0.7 + resolution: "eventemitter3@npm:4.0.7" + checksum: 1875311c42fcfe9c707b2712c32664a245629b42bb0a5a84439762dd0fd637fc54d078155ea83c2af9e0323c9ac13687e03cfba79b03af9f40c89b4960099374 + languageName: node + linkType: hard + +"exponential-backoff@npm:^3.1.1": + version: 3.1.2 + resolution: "exponential-backoff@npm:3.1.2" + checksum: 7e191e3dd6edd8c56c88f2c8037c98fbb8034fe48778be53ed8cb30ccef371a061a4e999a469aab939b92f8f12698f3b426d52f4f76b7a20da5f9f98c3cbc862 + languageName: node + linkType: hard + +"eyes@npm:^0.1.8": + version: 0.1.8 + resolution: "eyes@npm:0.1.8" + checksum: c31703a92bf36ba75ee8d379ee7985c24ee6149f3a6175f44cec7a05b178c38bce9836d3ca48c9acb0329a960ac2c4b2ead4e60cdd4fe6e8c92cad7cd6913687 + languageName: node + linkType: hard + +"fast-stable-stringify@npm:^1.0.0": + version: 1.0.0 + resolution: "fast-stable-stringify@npm:1.0.0" + checksum: ef1203d246a7e8ac15e2bfbda0a89fa375947bccf9f7910be0ea759856dbe8ea5024a0d8cc2cceabe18a9cb67e95927b78bb6173a3ae37ec55a518cf36e5244b + languageName: node + linkType: hard + +"fdir@npm:^6.4.3": + version: 6.4.3 + resolution: "fdir@npm:6.4.3" + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + checksum: fa53e13c63e8c14add5b70fd47e28267dd5481ebbba4b47720ec25aae7d10a800ef0f2e33de350faaf63c10b3d7b64138925718832220d593f75e724846c736d + languageName: node + linkType: hard + +"fdir@npm:^6.4.4": + version: 6.4.6 + resolution: "fdir@npm:6.4.6" + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + checksum: fe9f3014901d023cf631831dcb9eae5447f4d7f69218001dd01ecf007eccc40f6c129a04411b5cc273a5f93c14e02e971e17270afc9022041c80be924091eb6f + languageName: node + linkType: hard + +"file-uri-to-path@npm:1.0.0": + version: 1.0.0 + resolution: "file-uri-to-path@npm:1.0.0" + checksum: b648580bdd893a008c92c7ecc96c3ee57a5e7b6c4c18a9a09b44fb5d36d79146f8e442578bc0e173dc027adf3987e254ba1dfd6e3ec998b7c282873010502144 + languageName: node + linkType: hard + +"fill-range@npm:^7.0.1": + version: 7.0.1 + resolution: "fill-range@npm:7.0.1" + dependencies: + to-regex-range: ^5.0.1 + checksum: cc283f4e65b504259e64fd969bcf4def4eb08d85565e906b7d36516e87819db52029a76b6363d0f02d0d532f0033c9603b9e2d943d56ee3b0d4f7ad3328ff917 + languageName: node + linkType: hard + +"find-process@npm:^1.4.7": + version: 1.4.10 + resolution: "find-process@npm:1.4.10" + dependencies: + chalk: ~4.1.2 + commander: ^12.1.0 + loglevel: ^1.9.2 + bin: + find-process: bin/find-process.js + checksum: fdf3a53578f26004efc9188f36594d641402ebf7dcc1288bb6ce51a59138b1540c11fb39e032eaec11f1ed46b648ffd47ef83df5f0a4195f9b637869a11909eb + languageName: node + linkType: hard + +"find-up@npm:5.0.0": + version: 5.0.0 + resolution: "find-up@npm:5.0.0" + dependencies: + locate-path: ^6.0.0 + path-exists: ^4.0.0 + checksum: 07955e357348f34660bde7920783204ff5a26ac2cafcaa28bace494027158a97b9f56faaf2d89a6106211a8174db650dd9f503f9c0d526b1202d5554a00b9095 + languageName: node + linkType: hard + +"flat@npm:^5.0.2": + version: 5.0.2 + resolution: "flat@npm:5.0.2" + bin: + flat: cli.js + checksum: 12a1536ac746db74881316a181499a78ef953632ddd28050b7a3a43c62ef5462e3357c8c29d76072bb635f147f7a9a1f0c02efef6b4be28f8db62ceb3d5c7f5d + languageName: node + linkType: hard + +"for-each@npm:^0.3.3": + version: 0.3.3 + resolution: "for-each@npm:0.3.3" + dependencies: + is-callable: ^1.1.3 + checksum: 6c48ff2bc63362319c65e2edca4a8e1e3483a2fabc72fbe7feaf8c73db94fc7861bd53bc02c8a66a0c1dd709da6b04eec42e0abdd6b40ce47305ae92a25e5d28 + languageName: node + linkType: hard + +"foreground-child@npm:^3.1.0": + version: 3.3.0 + resolution: "foreground-child@npm:3.3.0" + dependencies: + cross-spawn: ^7.0.0 + signal-exit: ^4.0.1 + checksum: 1989698488f725b05b26bc9afc8a08f08ec41807cd7b92ad85d96004ddf8243fd3e79486b8348c64a3011ae5cc2c9f0936af989e1f28339805d8bc178a75b451 + languageName: node + linkType: hard + +"form-data@npm:^3.0.0": + version: 3.0.1 + resolution: "form-data@npm:3.0.1" + dependencies: + asynckit: ^0.4.0 + combined-stream: ^1.0.8 + mime-types: ^2.1.12 + checksum: b019e8d35c8afc14a2bd8a7a92fa4f525a4726b6d5a9740e8d2623c30e308fbb58dc8469f90415a856698933c8479b01646a9dff33c87cc4e76d72aedbbf860d + languageName: node + linkType: hard + +"fs-minipass@npm:^3.0.0": + version: 3.0.3 + resolution: "fs-minipass@npm:3.0.3" + dependencies: + minipass: ^7.0.3 + checksum: 8722a41109130851d979222d3ec88aabaceeaaf8f57b2a8f744ef8bd2d1ce95453b04a61daa0078822bc5cd21e008814f06fe6586f56fef511e71b8d2394d802 + languageName: node + linkType: hard + +"fs.realpath@npm:^1.0.0": + version: 1.0.0 + resolution: "fs.realpath@npm:1.0.0" + checksum: 99ddea01a7e75aa276c250a04eedeffe5662bce66c65c07164ad6264f9de18fb21be9433ead460e54cff20e31721c811f4fb5d70591799df5f85dce6d6746fd0 + languageName: node + linkType: hard + +"fsevents@npm:~2.3.2": + version: 2.3.2 + resolution: "fsevents@npm:2.3.2" + dependencies: + node-gyp: latest + checksum: 97ade64e75091afee5265e6956cb72ba34db7819b4c3e94c431d4be2b19b8bb7a2d4116da417950c3425f17c8fe693d25e20212cac583ac1521ad066b77ae31f + conditions: os=darwin + languageName: node + linkType: hard + +"fsevents@patch:fsevents@~2.3.2#~builtin": + version: 2.3.2 + resolution: "fsevents@patch:fsevents@npm%3A2.3.2#~builtin::version=2.3.2&hash=df0bf1" + dependencies: + node-gyp: latest + conditions: os=darwin + languageName: node + linkType: hard + +"function-bind@npm:^1.1.1": + version: 1.1.1 + resolution: "function-bind@npm:1.1.1" + checksum: b32fbaebb3f8ec4969f033073b43f5c8befbb58f1a79e12f1d7490358150359ebd92f49e72ff0144f65f2c48ea2a605bff2d07965f548f6474fd8efd95bf361a + languageName: node + linkType: hard + +"function-bind@npm:^1.1.2": + version: 1.1.2 + resolution: "function-bind@npm:1.1.2" + checksum: 2b0ff4ce708d99715ad14a6d1f894e2a83242e4a52ccfcefaee5e40050562e5f6dafc1adbb4ce2d4ab47279a45dc736ab91ea5042d843c3c092820dfe032efb1 + languageName: node + linkType: hard + +"get-caller-file@npm:^2.0.5": + version: 2.0.5 + resolution: "get-caller-file@npm:2.0.5" + checksum: b9769a836d2a98c3ee734a88ba712e62703f1df31b94b784762c433c27a386dd6029ff55c2a920c392e33657d80191edbf18c61487e198844844516f843496b9 + languageName: node + linkType: hard + +"get-intrinsic@npm:^1.0.2, get-intrinsic@npm:^1.1.1, get-intrinsic@npm:^1.1.3": + version: 1.1.3 + resolution: "get-intrinsic@npm:1.1.3" + dependencies: + function-bind: ^1.1.1 + has: ^1.0.3 + has-symbols: ^1.0.3 + checksum: 152d79e87251d536cf880ba75cfc3d6c6c50e12b3a64e1ea960e73a3752b47c69f46034456eae1b0894359ce3bc64c55c186f2811f8a788b75b638b06fab228a + languageName: node + linkType: hard + +"get-intrinsic@npm:^1.2.4, get-intrinsic@npm:^1.2.6": + version: 1.3.0 + resolution: "get-intrinsic@npm:1.3.0" + dependencies: + call-bind-apply-helpers: ^1.0.2 + es-define-property: ^1.0.1 + es-errors: ^1.3.0 + es-object-atoms: ^1.1.1 + function-bind: ^1.1.2 + get-proto: ^1.0.1 + gopd: ^1.2.0 + has-symbols: ^1.1.0 + hasown: ^2.0.2 + math-intrinsics: ^1.1.0 + checksum: 301008e4482bb9a9cb49e132b88fee093bff373b4e6def8ba219b1e96b60158a6084f273ef5cafe832e42cd93462f4accb46a618d35fe59a2b507f2388c5b79d + languageName: node + linkType: hard + +"get-proto@npm:^1.0.1": + version: 1.0.1 + resolution: "get-proto@npm:1.0.1" + dependencies: + dunder-proto: ^1.0.1 + es-object-atoms: ^1.0.0 + checksum: 4fc96afdb58ced9a67558698b91433e6b037aaa6f1493af77498d7c85b141382cf223c0e5946f334fb328ee85dfe6edd06d218eaf09556f4bc4ec6005d7f5f7b + languageName: node + linkType: hard + +"glob-parent@npm:~5.1.2": + version: 5.1.2 + resolution: "glob-parent@npm:5.1.2" + dependencies: + is-glob: ^4.0.1 + checksum: f4f2bfe2425296e8a47e36864e4f42be38a996db40420fe434565e4480e3322f18eb37589617a98640c5dc8fdec1a387007ee18dbb1f3f5553409c34d17f425e + languageName: node + linkType: hard + +"glob@npm:7.2.0": + version: 7.2.0 + resolution: "glob@npm:7.2.0" + dependencies: + fs.realpath: ^1.0.0 + inflight: ^1.0.4 + inherits: 2 + minimatch: ^3.0.4 + once: ^1.3.0 + path-is-absolute: ^1.0.0 + checksum: 78a8ea942331f08ed2e055cb5b9e40fe6f46f579d7fd3d694f3412fe5db23223d29b7fee1575440202e9a7ff9a72ab106a39fee39934c7bedafe5e5f8ae20134 + languageName: node + linkType: hard + +"glob@npm:^10.2.2, glob@npm:^10.3.10": + version: 10.4.5 + resolution: "glob@npm:10.4.5" + dependencies: + foreground-child: ^3.1.0 + jackspeak: ^3.1.2 + minimatch: ^9.0.4 + minipass: ^7.1.2 + package-json-from-dist: ^1.0.0 + path-scurry: ^1.11.1 + bin: + glob: dist/esm/bin.mjs + checksum: 0bc725de5e4862f9f387fd0f2b274baf16850dcd2714502ccf471ee401803997983e2c05590cb65f9675a3c6f2a58e7a53f9e365704108c6ad3cbf1d60934c4a + languageName: node + linkType: hard + +"gopd@npm:^1.0.1": + version: 1.0.1 + resolution: "gopd@npm:1.0.1" + dependencies: + get-intrinsic: ^1.1.3 + checksum: a5ccfb8806e0917a94e0b3de2af2ea4979c1da920bc381667c260e00e7cafdbe844e2cb9c5bcfef4e5412e8bf73bab837285bc35c7ba73aaaf0134d4583393a6 + languageName: node + linkType: hard + +"gopd@npm:^1.2.0": + version: 1.2.0 + resolution: "gopd@npm:1.2.0" + checksum: cc6d8e655e360955bdccaca51a12a474268f95bb793fc3e1f2bdadb075f28bfd1fd988dab872daf77a61d78cbaf13744bc8727a17cfb1d150d76047d805375f3 + languageName: node + linkType: hard + +"graceful-fs@npm:^4.2.6": + version: 4.2.11 + resolution: "graceful-fs@npm:4.2.11" + checksum: ac85f94da92d8eb6b7f5a8b20ce65e43d66761c55ce85ac96df6865308390da45a8d3f0296dd3a663de65d30ba497bd46c696cc1e248c72b13d6d567138a4fc7 + languageName: node + linkType: hard + +"has-flag@npm:^4.0.0": + version: 4.0.0 + resolution: "has-flag@npm:4.0.0" + checksum: 261a1357037ead75e338156b1f9452c016a37dcd3283a972a30d9e4a87441ba372c8b81f818cd0fbcd9c0354b4ae7e18b9e1afa1971164aef6d18c2b6095a8ad + languageName: node + linkType: hard + +"has-property-descriptors@npm:^1.0.0": + version: 1.0.0 + resolution: "has-property-descriptors@npm:1.0.0" + dependencies: + get-intrinsic: ^1.1.1 + checksum: a6d3f0a266d0294d972e354782e872e2fe1b6495b321e6ef678c9b7a06a40408a6891817350c62e752adced73a94ac903c54734fee05bf65b1905ee1368194bb + languageName: node + linkType: hard + +"has-property-descriptors@npm:^1.0.2": + version: 1.0.2 + resolution: "has-property-descriptors@npm:1.0.2" + dependencies: + es-define-property: ^1.0.0 + checksum: fcbb246ea2838058be39887935231c6d5788babed499d0e9d0cc5737494c48aba4fe17ba1449e0d0fbbb1e36175442faa37f9c427ae357d6ccb1d895fbcd3de3 + languageName: node + linkType: hard + +"has-symbols@npm:^1.0.2, has-symbols@npm:^1.0.3": + version: 1.0.3 + resolution: "has-symbols@npm:1.0.3" + checksum: a054c40c631c0d5741a8285010a0777ea0c068f99ed43e5d6eb12972da223f8af553a455132fdb0801bdcfa0e0f443c0c03a68d8555aa529b3144b446c3f2410 + languageName: node + linkType: hard + +"has-symbols@npm:^1.1.0": + version: 1.1.0 + resolution: "has-symbols@npm:1.1.0" + checksum: b2316c7302a0e8ba3aaba215f834e96c22c86f192e7310bdf689dd0e6999510c89b00fbc5742571507cebf25764d68c988b3a0da217369a73596191ac0ce694b + languageName: node + linkType: hard + +"has-tostringtag@npm:^1.0.0": + version: 1.0.0 + resolution: "has-tostringtag@npm:1.0.0" + dependencies: + has-symbols: ^1.0.2 + checksum: cc12eb28cb6ae22369ebaad3a8ab0799ed61270991be88f208d508076a1e99abe4198c965935ce85ea90b60c94ddda73693b0920b58e7ead048b4a391b502c1c + languageName: node + linkType: hard + +"has@npm:^1.0.3": + version: 1.0.3 + resolution: "has@npm:1.0.3" + dependencies: + function-bind: ^1.1.1 + checksum: b9ad53d53be4af90ce5d1c38331e712522417d017d5ef1ebd0507e07c2fbad8686fffb8e12ddecd4c39ca9b9b47431afbb975b8abf7f3c3b82c98e9aad052792 + languageName: node + linkType: hard + +"hasown@npm:^2.0.2": + version: 2.0.2 + resolution: "hasown@npm:2.0.2" + dependencies: + function-bind: ^1.1.2 + checksum: e8516f776a15149ca6c6ed2ae3110c417a00b62260e222590e54aa367cbcd6ed99122020b37b7fbdf05748df57b265e70095d7bf35a47660587619b15ffb93db + languageName: node + linkType: hard + +"he@npm:1.2.0": + version: 1.2.0 + resolution: "he@npm:1.2.0" + bin: + he: bin/he + checksum: 3d4d6babccccd79c5c5a3f929a68af33360d6445587d628087f39a965079d84f18ce9c3d3f917ee1e3978916fc833bb8b29377c3b403f919426f91bc6965e7a7 + languageName: node + linkType: hard + +"http-cache-semantics@npm:^4.1.1": + version: 4.2.0 + resolution: "http-cache-semantics@npm:4.2.0" + checksum: 7a7246ddfce629f96832791176fd643589d954e6f3b49548dadb4290451961237fab8fcea41cd2008fe819d95b41c1e8b97f47d088afc0a1c81705287b4ddbcc + languageName: node + linkType: hard + +"http-proxy-agent@npm:^7.0.0": + version: 7.0.2 + resolution: "http-proxy-agent@npm:7.0.2" + dependencies: + agent-base: ^7.1.0 + debug: ^4.3.4 + checksum: 670858c8f8f3146db5889e1fa117630910101db601fff7d5a8aa637da0abedf68c899f03d3451cac2f83bcc4c3d2dabf339b3aa00ff8080571cceb02c3ce02f3 + languageName: node + linkType: hard + +"https-proxy-agent@npm:^7.0.1": + version: 7.0.6 + resolution: "https-proxy-agent@npm:7.0.6" + dependencies: + agent-base: ^7.1.2 + debug: 4 + checksum: b882377a120aa0544846172e5db021fa8afbf83fea2a897d397bd2ddd8095ab268c24bc462f40a15f2a8c600bf4aa05ce52927f70038d4014e68aefecfa94e8d + languageName: node + linkType: hard + +"humanize-ms@npm:^1.2.1": + version: 1.2.1 + resolution: "humanize-ms@npm:1.2.1" + dependencies: + ms: ^2.0.0 + checksum: 9c7a74a2827f9294c009266c82031030eae811ca87b0da3dceb8d6071b9bde22c9f3daef0469c3c533cc67a97d8a167cd9fc0389350e5f415f61a79b171ded16 + languageName: node + linkType: hard + +"iconv-lite@npm:^0.6.2": + version: 0.6.3 + resolution: "iconv-lite@npm:0.6.3" + dependencies: + safer-buffer: ">= 2.1.2 < 3.0.0" + checksum: 3f60d47a5c8fc3313317edfd29a00a692cc87a19cac0159e2ce711d0ebc9019064108323b5e493625e25594f11c6236647d8e256fbe7a58f4a3b33b89e6d30bf + languageName: node + linkType: hard + +"ieee754@npm:^1.2.1": + version: 1.2.1 + resolution: "ieee754@npm:1.2.1" + checksum: 5144c0c9815e54ada181d80a0b810221a253562422e7c6c3a60b1901154184f49326ec239d618c416c1c5945a2e197107aee8d986a3dd836b53dffefd99b5e7e + languageName: node + linkType: hard + +"imurmurhash@npm:^0.1.4": + version: 0.1.4 + resolution: "imurmurhash@npm:0.1.4" + checksum: 7cae75c8cd9a50f57dadd77482359f659eaebac0319dd9368bcd1714f55e65badd6929ca58569da2b6494ef13fdd5598cd700b1eba23f8b79c5f19d195a3ecf7 + languageName: node + linkType: hard + +"inflight@npm:^1.0.4": + version: 1.0.6 + resolution: "inflight@npm:1.0.6" + dependencies: + once: ^1.3.0 + wrappy: 1 + checksum: f4f76aa072ce19fae87ce1ef7d221e709afb59d445e05d47fba710e85470923a75de35bfae47da6de1b18afc3ce83d70facf44cfb0aff89f0a3f45c0a0244dfd + languageName: node + linkType: hard + +"inherits@npm:2, inherits@npm:^2.0.3": + version: 2.0.4 + resolution: "inherits@npm:2.0.4" + checksum: 4a48a733847879d6cf6691860a6b1e3f0f4754176e4d71494c41f3475553768b10f84b5ce1d40fbd0e34e6bfbb864ee35858ad4dd2cf31e02fc4a154b724d7f1 + languageName: node + linkType: hard + +"invariant@npm:2.2.4": + version: 2.2.4 + resolution: "invariant@npm:2.2.4" + dependencies: + loose-envify: ^1.0.0 + checksum: cc3182d793aad82a8d1f0af697b462939cb46066ec48bbf1707c150ad5fad6406137e91a262022c269702e01621f35ef60269f6c0d7fd178487959809acdfb14 + languageName: node + linkType: hard + +"ip-address@npm:^9.0.5": + version: 9.0.5 + resolution: "ip-address@npm:9.0.5" + dependencies: + jsbn: 1.1.0 + sprintf-js: ^1.1.3 + checksum: aa15f12cfd0ef5e38349744e3654bae649a34c3b10c77a674a167e99925d1549486c5b14730eebce9fea26f6db9d5e42097b00aa4f9f612e68c79121c71652dc + languageName: node + linkType: hard + +"is-arguments@npm:^1.0.4": + version: 1.1.1 + resolution: "is-arguments@npm:1.1.1" + dependencies: + call-bind: ^1.0.2 + has-tostringtag: ^1.0.0 + checksum: 7f02700ec2171b691ef3e4d0e3e6c0ba408e8434368504bb593d0d7c891c0dbfda6d19d30808b904a6cb1929bca648c061ba438c39f296c2a8ca083229c49f27 + languageName: node + linkType: hard + +"is-binary-path@npm:~2.1.0": + version: 2.1.0 + resolution: "is-binary-path@npm:2.1.0" + dependencies: + binary-extensions: ^2.0.0 + checksum: 84192eb88cff70d320426f35ecd63c3d6d495da9d805b19bc65b518984b7c0760280e57dbf119b7e9be6b161784a5a673ab2c6abe83abb5198a432232ad5b35c + languageName: node + linkType: hard + +"is-callable@npm:^1.1.3": + version: 1.2.7 + resolution: "is-callable@npm:1.2.7" + checksum: 61fd57d03b0d984e2ed3720fb1c7a897827ea174bd44402878e059542ea8c4aeedee0ea0985998aa5cc2736b2fa6e271c08587addb5b3959ac52cf665173d1ac + languageName: node + linkType: hard + +"is-extglob@npm:^2.1.1": + version: 2.1.1 + resolution: "is-extglob@npm:2.1.1" + checksum: df033653d06d0eb567461e58a7a8c9f940bd8c22274b94bf7671ab36df5719791aae15eef6d83bbb5e23283967f2f984b8914559d4449efda578c775c4be6f85 + languageName: node + linkType: hard + +"is-fullwidth-code-point@npm:^3.0.0": + version: 3.0.0 + resolution: "is-fullwidth-code-point@npm:3.0.0" + checksum: 44a30c29457c7fb8f00297bce733f0a64cd22eca270f83e58c105e0d015e45c019491a4ab2faef91ab51d4738c670daff901c799f6a700e27f7314029e99e348 + languageName: node + linkType: hard + +"is-generator-function@npm:^1.0.7": + version: 1.0.10 + resolution: "is-generator-function@npm:1.0.10" + dependencies: + has-tostringtag: ^1.0.0 + checksum: d54644e7dbaccef15ceb1e5d91d680eb5068c9ee9f9eb0a9e04173eb5542c9b51b5ab52c5537f5703e48d5fddfd376817c1ca07a84a407b7115b769d4bdde72b + languageName: node + linkType: hard + +"is-glob@npm:^4.0.1, is-glob@npm:~4.0.1": + version: 4.0.3 + resolution: "is-glob@npm:4.0.3" + dependencies: + is-extglob: ^2.1.1 + checksum: d381c1319fcb69d341cc6e6c7cd588e17cd94722d9a32dbd60660b993c4fb7d0f19438674e68dfec686d09b7c73139c9166b47597f846af387450224a8101ab4 + languageName: node + linkType: hard + +"is-nan@npm:^1.2.1, is-nan@npm:^1.3.2": + version: 1.3.2 + resolution: "is-nan@npm:1.3.2" + dependencies: + call-bind: ^1.0.0 + define-properties: ^1.1.3 + checksum: 5dfadcef6ad12d3029d43643d9800adbba21cf3ce2ec849f734b0e14ee8da4070d82b15fdb35138716d02587c6578225b9a22779cab34888a139cc43e4e3610a + languageName: node + linkType: hard + +"is-number@npm:^7.0.0": + version: 7.0.0 + resolution: "is-number@npm:7.0.0" + checksum: 456ac6f8e0f3111ed34668a624e45315201dff921e5ac181f8ec24923b99e9f32ca1a194912dc79d539c97d33dba17dc635202ff0b2cf98326f608323276d27a + languageName: node + linkType: hard + +"is-plain-obj@npm:^2.1.0": + version: 2.1.0 + resolution: "is-plain-obj@npm:2.1.0" + checksum: cec9100678b0a9fe0248a81743041ed990c2d4c99f893d935545cfbc42876cbe86d207f3b895700c690ad2fa520e568c44afc1605044b535a7820c1d40e38daa + languageName: node + linkType: hard + +"is-typed-array@npm:^1.1.10, is-typed-array@npm:^1.1.3": + version: 1.1.10 + resolution: "is-typed-array@npm:1.1.10" + dependencies: + available-typed-arrays: ^1.0.5 + call-bind: ^1.0.2 + for-each: ^0.3.3 + gopd: ^1.0.1 + has-tostringtag: ^1.0.0 + checksum: aac6ecb59d4c56a1cdeb69b1f129154ef462bbffe434cb8a8235ca89b42f258b7ae94073c41b3cb7bce37f6a1733ad4499f07882d5d5093a7ba84dfc4ebb8017 + languageName: node + linkType: hard + +"is-unicode-supported@npm:^0.1.0": + version: 0.1.0 + resolution: "is-unicode-supported@npm:0.1.0" + checksum: a2aab86ee7712f5c2f999180daaba5f361bdad1efadc9610ff5b8ab5495b86e4f627839d085c6530363c6d6d4ecbde340fb8e54bdb83da4ba8e0865ed5513c52 + languageName: node + linkType: hard + +"isexe@npm:^2.0.0": + version: 2.0.0 + resolution: "isexe@npm:2.0.0" + checksum: 26bf6c5480dda5161c820c5b5c751ae1e766c587b1f951ea3fcfc973bafb7831ae5b54a31a69bd670220e42e99ec154475025a468eae58ea262f813fdc8d1c62 + languageName: node + linkType: hard + +"isexe@npm:^3.1.1": + version: 3.1.1 + resolution: "isexe@npm:3.1.1" + checksum: 7fe1931ee4e88eb5aa524cd3ceb8c882537bc3a81b02e438b240e47012eef49c86904d0f0e593ea7c3a9996d18d0f1f3be8d3eaa92333977b0c3a9d353d5563e + languageName: node + linkType: hard + +"isomorphic-ws@npm:^4.0.1": + version: 4.0.1 + resolution: "isomorphic-ws@npm:4.0.1" + peerDependencies: + ws: "*" + checksum: d7190eadefdc28bdb93d67b5f0c603385aaf87724fa2974abb382ac1ec9756ed2cfb27065cbe76122879c2d452e2982bc4314317f3d6c737ddda6c047328771a + languageName: node + linkType: hard + +"jackspeak@npm:^3.1.2": + version: 3.4.3 + resolution: "jackspeak@npm:3.4.3" + dependencies: + "@isaacs/cliui": ^8.0.2 + "@pkgjs/parseargs": ^0.11.0 + dependenciesMeta: + "@pkgjs/parseargs": + optional: true + checksum: be31027fc72e7cc726206b9f560395604b82e0fddb46c4cbf9f97d049bcef607491a5afc0699612eaa4213ca5be8fd3e1e7cd187b3040988b65c9489838a7c00 + languageName: node + linkType: hard + +"jayson@npm:^3.4.4": + version: 3.7.0 + resolution: "jayson@npm:3.7.0" + dependencies: + "@types/connect": ^3.4.33 + "@types/node": ^12.12.54 + "@types/ws": ^7.4.4 + JSONStream: ^1.3.5 + commander: ^2.20.3 + delay: ^5.0.0 + es6-promisify: ^5.0.0 + eyes: ^0.1.8 + isomorphic-ws: ^4.0.1 + json-stringify-safe: ^5.0.1 + lodash: ^4.17.20 + uuid: ^8.3.2 + ws: ^7.4.5 + bin: + jayson: bin/jayson.js + checksum: 4218a4829168a4927e657bde953ff9699f02af561ec72edcc7464446772b50a0c5c7e9f11d4ee5976e4794d0f1040c0f351a0fee51c542bf8492743d30b7a971 + languageName: node + linkType: hard + +"joycon@npm:^3.1.1": + version: 3.1.1 + resolution: "joycon@npm:3.1.1" + checksum: 8003c9c3fc79c5c7602b1c7e9f7a2df2e9916f046b0dbad862aa589be78c15734d11beb9fe846f5e06138df22cb2ad29961b6a986ba81c4920ce2b15a7f11067 + languageName: node + linkType: hard + +"js-sha256@npm:^0.9.0": + version: 0.9.0 + resolution: "js-sha256@npm:0.9.0" + checksum: ffad54b3373f81581e245866abfda50a62c483803a28176dd5c28fd2d313e0bdf830e77dac7ff8afd193c53031618920f3d98daf21cbbe80082753ab639c0365 + languageName: node + linkType: hard + +"js-tokens@npm:^3.0.0 || ^4.0.0": + version: 4.0.0 + resolution: "js-tokens@npm:4.0.0" + checksum: 8a95213a5a77deb6cbe94d86340e8d9ace2b93bc367790b260101d2f36a2eaf4e4e22d9fa9cf459b38af3a32fb4190e638024cf82ec95ef708680e405ea7cc78 + languageName: node + linkType: hard + +"js-yaml@npm:4.1.0": + version: 4.1.0 + resolution: "js-yaml@npm:4.1.0" + dependencies: + argparse: ^2.0.1 + bin: + js-yaml: bin/js-yaml.js + checksum: c7830dfd456c3ef2c6e355cc5a92e6700ceafa1d14bba54497b34a99f0376cecbb3e9ac14d3e5849b426d5a5140709a66237a8c991c675431271c4ce5504151a + languageName: node + linkType: hard + +"jsbn@npm:1.1.0": + version: 1.1.0 + resolution: "jsbn@npm:1.1.0" + checksum: 944f924f2bd67ad533b3850eee47603eed0f6ae425fd1ee8c760f477e8c34a05f144c1bd4f5a5dd1963141dc79a2c55f89ccc5ab77d039e7077f3ad196b64965 + languageName: node + linkType: hard + +"json-stringify-safe@npm:^5.0.1": + version: 5.0.1 + resolution: "json-stringify-safe@npm:5.0.1" + checksum: 48ec0adad5280b8a96bb93f4563aa1667fd7a36334f79149abd42446d0989f2ddc58274b479f4819f1f00617957e6344c886c55d05a4e15ebb4ab931e4a6a8ee + languageName: node + linkType: hard + +"jsonc-parser@npm:^3.2.0": + version: 3.3.1 + resolution: "jsonc-parser@npm:3.3.1" + checksum: 81ef19d98d9c6bd6e4a37a95e2753c51c21705cbeffd895e177f4b542cca9cda5fda12fb942a71a2e824a9132cf119dc2e642e9286386055e1365b5478f49a47 + languageName: node + linkType: hard + +"jsonparse@npm:^1.2.0": + version: 1.3.1 + resolution: "jsonparse@npm:1.3.1" + checksum: 6514a7be4674ebf407afca0eda3ba284b69b07f9958a8d3113ef1005f7ec610860c312be067e450c569aab8b89635e332cee3696789c750692bb60daba627f4d + languageName: node + linkType: hard + +"lilconfig@npm:^3.1.1": + version: 3.1.3 + resolution: "lilconfig@npm:3.1.3" + checksum: 644eb10830350f9cdc88610f71a921f510574ed02424b57b0b3abb66ea725d7a082559552524a842f4e0272c196b88dfe1ff7d35ffcc6f45736777185cd67c9a + languageName: node + linkType: hard + +"lines-and-columns@npm:^1.1.6": + version: 1.2.4 + resolution: "lines-and-columns@npm:1.2.4" + checksum: 0c37f9f7fa212b38912b7145e1cd16a5f3cd34d782441c3e6ca653485d326f58b3caccda66efce1c5812bde4961bbde3374fae4b0d11bf1226152337f3894aa5 + languageName: node + linkType: hard + +"load-tsconfig@npm:^0.2.3": + version: 0.2.5 + resolution: "load-tsconfig@npm:0.2.5" + checksum: 631740833c4a7157bb7b6eeae6e1afb6a6fac7416b7ba91bd0944d5c5198270af2d68bf8347af3cc2ba821adc4d83ef98f66278bd263bc284c863a09ec441503 + languageName: node + linkType: hard + +"locate-path@npm:^6.0.0": + version: 6.0.0 + resolution: "locate-path@npm:6.0.0" + dependencies: + p-locate: ^5.0.0 + checksum: 72eb661788a0368c099a184c59d2fee760b3831c9c1c33955e8a19ae4a21b4116e53fa736dc086cdeb9fce9f7cc508f2f92d2d3aae516f133e16a2bb59a39f5a + languageName: node + linkType: hard + +"lodash.sortby@npm:^4.7.0": + version: 4.7.0 + resolution: "lodash.sortby@npm:4.7.0" + checksum: db170c9396d29d11fe9a9f25668c4993e0c1331bcb941ddbd48fb76f492e732add7f2a47cfdf8e9d740fa59ac41bbfaf931d268bc72aab3ab49e9f89354d718c + languageName: node + linkType: hard + +"lodash@npm:^4.17.20": + version: 4.17.21 + resolution: "lodash@npm:4.17.21" + checksum: eb835a2e51d381e561e508ce932ea50a8e5a68f4ebdd771ea240d3048244a8d13658acbd502cd4829768c56f2e16bdd4340b9ea141297d472517b83868e677f7 + languageName: node + linkType: hard + +"log-symbols@npm:4.1.0": + version: 4.1.0 + resolution: "log-symbols@npm:4.1.0" + dependencies: + chalk: ^4.1.0 + is-unicode-supported: ^0.1.0 + checksum: fce1497b3135a0198803f9f07464165e9eb83ed02ceb2273930a6f8a508951178d8cf4f0378e9d28300a2ed2bc49050995d2bd5f53ab716bb15ac84d58c6ef74 + languageName: node + linkType: hard + +"loglevel@npm:^1.9.2": + version: 1.9.2 + resolution: "loglevel@npm:1.9.2" + checksum: 896c67b90a507bfcfc1e9a4daa7bf789a441dd70d95cd13b998d6dd46233a3bfadfb8fadb07250432bbfb53bf61e95f2520f9b11f9d3175cc460e5c251eca0af + languageName: node + linkType: hard + +"loose-envify@npm:^1.0.0": + version: 1.4.0 + resolution: "loose-envify@npm:1.4.0" + dependencies: + js-tokens: ^3.0.0 || ^4.0.0 + bin: + loose-envify: cli.js + checksum: 6517e24e0cad87ec9888f500c5b5947032cdfe6ef65e1c1936a0c48a524b81e65542c9c3edc91c97d5bddc806ee2a985dbc79be89215d613b1de5db6d1cfe6f4 + languageName: node + linkType: hard + +"lower-case@npm:^2.0.2": + version: 2.0.2 + resolution: "lower-case@npm:2.0.2" + dependencies: + tslib: ^2.0.3 + checksum: 83a0a5f159ad7614bee8bf976b96275f3954335a84fad2696927f609ddae902802c4f3312d86668722e668bef41400254807e1d3a7f2e8c3eede79691aa1f010 + languageName: node + linkType: hard + +"lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0": + version: 10.4.3 + resolution: "lru-cache@npm:10.4.3" + checksum: 6476138d2125387a6d20f100608c2583d415a4f64a0fecf30c9e2dda976614f09cad4baa0842447bd37dd459a7bd27f57d9d8f8ce558805abd487c583f3d774a + languageName: node + linkType: hard + +"lunr@npm:^2.3.9": + version: 2.3.9 + resolution: "lunr@npm:2.3.9" + checksum: 176719e24fcce7d3cf1baccce9dd5633cd8bdc1f41ebe6a180112e5ee99d80373fe2454f5d4624d437e5a8319698ca6837b9950566e15d2cae5f2a543a3db4b8 + languageName: node + linkType: hard + +"make-error@npm:^1.1.1": + version: 1.3.6 + resolution: "make-error@npm:1.3.6" + checksum: b86e5e0e25f7f777b77fabd8e2cbf15737972869d852a22b7e73c17623928fccb826d8e46b9951501d3f20e51ad74ba8c59ed584f610526a48f8ccf88aaec402 + languageName: node + linkType: hard + +"make-fetch-happen@npm:^14.0.3": + version: 14.0.3 + resolution: "make-fetch-happen@npm:14.0.3" + dependencies: + "@npmcli/agent": ^3.0.0 + cacache: ^19.0.1 + http-cache-semantics: ^4.1.1 + minipass: ^7.0.2 + minipass-fetch: ^4.0.0 + minipass-flush: ^1.0.5 + minipass-pipeline: ^1.2.4 + negotiator: ^1.0.0 + proc-log: ^5.0.0 + promise-retry: ^2.0.1 + ssri: ^12.0.0 + checksum: 6fb2fee6da3d98f1953b03d315826b5c5a4ea1f908481afc113782d8027e19f080c85ae998454de4e5f27a681d3ec58d57278f0868d4e0b736f51d396b661691 + languageName: node + linkType: hard + +"marked@npm:^4.3.0": + version: 4.3.0 + resolution: "marked@npm:4.3.0" + bin: + marked: bin/marked.js + checksum: 0db6817893952c3ec710eb9ceafb8468bf5ae38cb0f92b7b083baa13d70b19774674be04db5b817681fa7c5c6a088f61300815e4dd75a59696f4716ad69f6260 + languageName: node + linkType: hard + +"math-intrinsics@npm:^1.1.0": + version: 1.1.0 + resolution: "math-intrinsics@npm:1.1.0" + checksum: 0e513b29d120f478c85a70f49da0b8b19bc638975eca466f2eeae0071f3ad00454c621bf66e16dd435896c208e719fc91ad79bbfba4e400fe0b372e7c1c9c9a2 + languageName: node + linkType: hard + +"mime-db@npm:1.52.0": + version: 1.52.0 + resolution: "mime-db@npm:1.52.0" + checksum: 0d99a03585f8b39d68182803b12ac601d9c01abfa28ec56204fa330bc9f3d1c5e14beb049bafadb3dbdf646dfb94b87e24d4ec7b31b7279ef906a8ea9b6a513f + languageName: node + linkType: hard + +"mime-types@npm:^2.1.12": + version: 2.1.35 + resolution: "mime-types@npm:2.1.35" + dependencies: + mime-db: 1.52.0 + checksum: 89a5b7f1def9f3af5dad6496c5ed50191ae4331cc5389d7c521c8ad28d5fdad2d06fd81baf38fed813dc4e46bb55c8145bb0ff406330818c9cf712fb2e9b3836 + languageName: node + linkType: hard + +"minimatch@npm:5.0.1": + version: 5.0.1 + resolution: "minimatch@npm:5.0.1" + dependencies: + brace-expansion: ^2.0.1 + checksum: b34b98463da4754bc526b244d680c69d4d6089451ebe512edaf6dd9eeed0279399cfa3edb19233513b8f830bf4bfcad911dddcdf125e75074100d52f724774f0 + languageName: node + linkType: hard + +"minimatch@npm:^3.0.4": + version: 3.1.2 + resolution: "minimatch@npm:3.1.2" + dependencies: + brace-expansion: ^1.1.7 + checksum: c154e566406683e7bcb746e000b84d74465b3a832c45d59912b9b55cd50dee66e5c4b1e5566dba26154040e51672f9aa450a9aef0c97cfc7336b78b7afb9540a + languageName: node + linkType: hard + +"minimatch@npm:^9.0.3, minimatch@npm:^9.0.4": + version: 9.0.5 + resolution: "minimatch@npm:9.0.5" + dependencies: + brace-expansion: ^2.0.1 + checksum: 2c035575eda1e50623c731ec6c14f65a85296268f749b9337005210bb2b34e2705f8ef1a358b188f69892286ab99dc42c8fb98a57bde55c8d81b3023c19cea28 + languageName: node + linkType: hard + +"minipass-collect@npm:^2.0.1": + version: 2.0.1 + resolution: "minipass-collect@npm:2.0.1" + dependencies: + minipass: ^7.0.3 + checksum: b251bceea62090f67a6cced7a446a36f4cd61ee2d5cea9aee7fff79ba8030e416327a1c5aa2908dc22629d06214b46d88fdab8c51ac76bacbf5703851b5ad342 + languageName: node + linkType: hard + +"minipass-fetch@npm:^4.0.0": + version: 4.0.1 + resolution: "minipass-fetch@npm:4.0.1" + dependencies: + encoding: ^0.1.13 + minipass: ^7.0.3 + minipass-sized: ^1.0.3 + minizlib: ^3.0.1 + dependenciesMeta: + encoding: + optional: true + checksum: 3dfca705ce887ca9ff14d73e8d8593996dea1a1ecd8101fdbb9c10549d1f9670bc8fb66ad0192769ead4c2dc01b4f9ca1cf567ded365adff17827a303b948140 + languageName: node + linkType: hard + +"minipass-flush@npm:^1.0.5": + version: 1.0.5 + resolution: "minipass-flush@npm:1.0.5" + dependencies: + minipass: ^3.0.0 + checksum: 56269a0b22bad756a08a94b1ffc36b7c9c5de0735a4dd1ab2b06c066d795cfd1f0ac44a0fcae13eece5589b908ecddc867f04c745c7009be0b566421ea0944cf + languageName: node + linkType: hard + +"minipass-pipeline@npm:^1.2.4": + version: 1.2.4 + resolution: "minipass-pipeline@npm:1.2.4" + dependencies: + minipass: ^3.0.0 + checksum: b14240dac0d29823c3d5911c286069e36d0b81173d7bdf07a7e4a91ecdef92cdff4baaf31ea3746f1c61e0957f652e641223970870e2353593f382112257971b + languageName: node + linkType: hard + +"minipass-sized@npm:^1.0.3": + version: 1.0.3 + resolution: "minipass-sized@npm:1.0.3" + dependencies: + minipass: ^3.0.0 + checksum: 79076749fcacf21b5d16dd596d32c3b6bf4d6e62abb43868fac21674078505c8b15eaca4e47ed844985a4514854f917d78f588fcd029693709417d8f98b2bd60 + languageName: node + linkType: hard + +"minipass@npm:^3.0.0": + version: 3.3.6 + resolution: "minipass@npm:3.3.6" + dependencies: + yallist: ^4.0.0 + checksum: a30d083c8054cee83cdcdc97f97e4641a3f58ae743970457b1489ce38ee1167b3aaf7d815cd39ec7a99b9c40397fd4f686e83750e73e652b21cb516f6d845e48 + languageName: node + linkType: hard + +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.0.4, minipass@npm:^7.1.2": + version: 7.1.2 + resolution: "minipass@npm:7.1.2" + checksum: 2bfd325b95c555f2b4d2814d49325691c7bee937d753814861b0b49d5edcda55cbbf22b6b6a60bb91eddac8668771f03c5ff647dcd9d0f798e9548b9cdc46ee3 + languageName: node + linkType: hard + +"minizlib@npm:^3.0.1": + version: 3.0.2 + resolution: "minizlib@npm:3.0.2" + dependencies: + minipass: ^7.1.2 + checksum: 493bed14dcb6118da7f8af356a8947cf1473289c09658e5aabd69a737800a8c3b1736fb7d7931b722268a9c9bc038a6d53c049b6a6af24b34a121823bb709996 + languageName: node + linkType: hard + +"mkdirp@npm:^3.0.1": + version: 3.0.1 + resolution: "mkdirp@npm:3.0.1" + bin: + mkdirp: dist/cjs/src/bin.js + checksum: 972deb188e8fb55547f1e58d66bd6b4a3623bf0c7137802582602d73e6480c1c2268dcbafbfb1be466e00cc7e56ac514d7fd9334b7cf33e3e2ab547c16f83a8d + languageName: node + linkType: hard + +"mocha@npm:10.2.0": + version: 10.2.0 + resolution: "mocha@npm:10.2.0" + dependencies: + ansi-colors: 4.1.1 + browser-stdout: 1.3.1 + chokidar: 3.5.3 + debug: 4.3.4 + diff: 5.0.0 + escape-string-regexp: 4.0.0 + find-up: 5.0.0 + glob: 7.2.0 + he: 1.2.0 + js-yaml: 4.1.0 + log-symbols: 4.1.0 + minimatch: 5.0.1 + ms: 2.1.3 + nanoid: 3.3.3 + serialize-javascript: 6.0.0 + strip-json-comments: 3.1.1 + supports-color: 8.1.1 + workerpool: 6.2.1 + yargs: 16.2.0 + yargs-parser: 20.2.4 + yargs-unparser: 2.0.0 + bin: + _mocha: bin/_mocha + mocha: bin/mocha.js + checksum: 406c45eab122ffd6ea2003c2f108b2bc35ba036225eee78e0c784b6fa2c7f34e2b13f1dbacef55a4fdf523255d76e4f22d1b5aacda2394bd11666febec17c719 + languageName: node + linkType: hard + +"ms@npm:2.1.2": + version: 2.1.2 + resolution: "ms@npm:2.1.2" + checksum: 673cdb2c3133eb050c745908d8ce632ed2c02d85640e2edb3ace856a2266a813b30c613569bf3354fdf4ea7d1a1494add3bfa95e2713baa27d0c2c71fc44f58f + languageName: node + linkType: hard + +"ms@npm:2.1.3, ms@npm:^2.0.0, ms@npm:^2.1.3": + version: 2.1.3 + resolution: "ms@npm:2.1.3" + checksum: aa92de608021b242401676e35cfa5aa42dd70cbdc082b916da7fb925c542173e36bce97ea3e804923fe92c0ad991434e4a38327e15a1b5b5f945d66df615ae6d + languageName: node + linkType: hard + +"mz@npm:^2.7.0": + version: 2.7.0 + resolution: "mz@npm:2.7.0" + dependencies: + any-promise: ^1.0.0 + object-assign: ^4.0.1 + thenify-all: ^1.0.0 + checksum: 8427de0ece99a07e9faed3c0c6778820d7543e3776f9a84d22cf0ec0a8eb65f6e9aee9c9d353ff9a105ff62d33a9463c6ca638974cc652ee8140cd1e35951c87 + languageName: node + linkType: hard + +"nanoid@npm:3.3.3": + version: 3.3.3 + resolution: "nanoid@npm:3.3.3" + bin: + nanoid: bin/nanoid.cjs + checksum: ada019402a07464a694553c61d2dca8a4353645a7d92f2830f0d487fedff403678a0bee5323a46522752b2eab95a0bc3da98b6cccaa7c0c55cd9975130e6d6f0 + languageName: node + linkType: hard + +"negotiator@npm:^1.0.0": + version: 1.0.0 + resolution: "negotiator@npm:1.0.0" + checksum: 20ebfe79b2d2e7cf9cbc8239a72662b584f71164096e6e8896c8325055497c96f6b80cd22c258e8a2f2aa382a787795ec3ee8b37b422a302c7d4381b0d5ecfbb + languageName: node + linkType: hard + +"no-case@npm:^3.0.4": + version: 3.0.4 + resolution: "no-case@npm:3.0.4" + dependencies: + lower-case: ^2.0.2 + tslib: ^2.0.3 + checksum: 0b2ebc113dfcf737d48dde49cfebf3ad2d82a8c3188e7100c6f375e30eafbef9e9124aadc3becef237b042fd5eb0aad2fd78669c20972d045bbe7fea8ba0be5c + languageName: node + linkType: hard + +"node-fetch@npm:2": + version: 2.6.7 + resolution: "node-fetch@npm:2.6.7" + dependencies: + whatwg-url: ^5.0.0 + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + checksum: 8d816ffd1ee22cab8301c7756ef04f3437f18dace86a1dae22cf81db8ef29c0bf6655f3215cb0cdb22b420b6fe141e64b26905e7f33f9377a7fa59135ea3e10b + languageName: node + linkType: hard + +"node-gyp-build@npm:^4.3.0": + version: 4.5.0 + resolution: "node-gyp-build@npm:4.5.0" + bin: + node-gyp-build: bin.js + node-gyp-build-optional: optional.js + node-gyp-build-test: build-test.js + checksum: d888bae0fb88335f69af1b57a2294a931c5042f36e413d8d364c992c9ebfa0b96ffe773179a5a2c8f04b73856e8634e09cce108dbb9804396d3cc8c5455ff2db + languageName: node + linkType: hard + +"node-gyp@npm:latest": + version: 11.2.0 + resolution: "node-gyp@npm:11.2.0" + dependencies: + env-paths: ^2.2.0 + exponential-backoff: ^3.1.1 + graceful-fs: ^4.2.6 + make-fetch-happen: ^14.0.3 + nopt: ^8.0.0 + proc-log: ^5.0.0 + semver: ^7.3.5 + tar: ^7.4.3 + tinyglobby: ^0.2.12 + which: ^5.0.0 + bin: + node-gyp: bin/node-gyp.js + checksum: 2536282ba81f8a94b29482d3622b6ab298611440619e46de4512a6f32396a68b5530357c474b859787069d84a4c537d99e0c71078cce5b9f808bf84eeb78e8fb + languageName: node + linkType: hard + +"nopt@npm:^8.0.0": + version: 8.1.0 + resolution: "nopt@npm:8.1.0" + dependencies: + abbrev: ^3.0.0 + bin: + nopt: bin/nopt.js + checksum: 49cfd3eb6f565e292bf61f2ff1373a457238804d5a5a63a8d786c923007498cba89f3648e3b952bc10203e3e7285752abf5b14eaf012edb821e84f24e881a92a + languageName: node + linkType: hard + +"normalize-path@npm:^3.0.0, normalize-path@npm:~3.0.0": + version: 3.0.0 + resolution: "normalize-path@npm:3.0.0" + checksum: 88eeb4da891e10b1318c4b2476b6e2ecbeb5ff97d946815ffea7794c31a89017c70d7f34b3c2ebf23ef4e9fc9fb99f7dffe36da22011b5b5c6ffa34f4873ec20 + languageName: node + linkType: hard + +"object-assign@npm:^4.0.1": + version: 4.1.1 + resolution: "object-assign@npm:4.1.1" + checksum: fcc6e4ea8c7fe48abfbb552578b1c53e0d194086e2e6bbbf59e0a536381a292f39943c6e9628af05b5528aa5e3318bb30d6b2e53cadaf5b8fe9e12c4b69af23f + languageName: node + linkType: hard + +"object-is@npm:^1.0.1": + version: 1.1.5 + resolution: "object-is@npm:1.1.5" + dependencies: + call-bind: ^1.0.2 + define-properties: ^1.1.3 + checksum: 989b18c4cba258a6b74dc1d74a41805c1a1425bce29f6cabb50dcb1a6a651ea9104a1b07046739a49a5bb1bc49727bcb00efd5c55f932f6ea04ec8927a7901fe + languageName: node + linkType: hard + +"object-is@npm:^1.1.5": + version: 1.1.6 + resolution: "object-is@npm:1.1.6" + dependencies: + call-bind: ^1.0.7 + define-properties: ^1.2.1 + checksum: 3ea22759967e6f2380a2cbbd0f737b42dc9ddb2dfefdb159a1b927fea57335e1b058b564bfa94417db8ad58cddab33621a035de6f5e5ad56d89f2dd03e66c6a1 + languageName: node + linkType: hard + +"object-keys@npm:^1.1.1": + version: 1.1.1 + resolution: "object-keys@npm:1.1.1" + checksum: b363c5e7644b1e1b04aa507e88dcb8e3a2f52b6ffd0ea801e4c7a62d5aa559affe21c55a07fd4b1fd55fc03a33c610d73426664b20032405d7b92a1414c34d6a + languageName: node + linkType: hard + +"object.assign@npm:^4.1.4": + version: 4.1.7 + resolution: "object.assign@npm:4.1.7" + dependencies: + call-bind: ^1.0.8 + call-bound: ^1.0.3 + define-properties: ^1.2.1 + es-object-atoms: ^1.0.0 + has-symbols: ^1.1.0 + object-keys: ^1.1.1 + checksum: 60e07d2651cf4f5528c485f1aa4dbded9b384c47d80e8187cefd11320abb1aebebf78df5483451dfa549059f8281c21f7b4bf7d19e9e5e97d8d617df0df298de + languageName: node + linkType: hard + +"once@npm:^1.3.0": + version: 1.4.0 + resolution: "once@npm:1.4.0" + dependencies: + wrappy: 1 + checksum: cd0a88501333edd640d95f0d2700fbde6bff20b3d4d9bdc521bdd31af0656b5706570d6c6afe532045a20bb8dc0849f8332d6f2a416e0ba6d3d3b98806c7db68 + languageName: node + linkType: hard + +"p-limit@npm:^3.0.2": + version: 3.1.0 + resolution: "p-limit@npm:3.1.0" + dependencies: + yocto-queue: ^0.1.0 + checksum: 7c3690c4dbf62ef625671e20b7bdf1cbc9534e83352a2780f165b0d3ceba21907e77ad63401708145ca4e25bfc51636588d89a8c0aeb715e6c37d1c066430360 + languageName: node + linkType: hard + +"p-locate@npm:^5.0.0": + version: 5.0.0 + resolution: "p-locate@npm:5.0.0" + dependencies: + p-limit: ^3.0.2 + checksum: 1623088f36cf1cbca58e9b61c4e62bf0c60a07af5ae1ca99a720837356b5b6c5ba3eb1b2127e47a06865fee59dd0453cad7cc844cda9d5a62ac1a5a51b7c86d3 + languageName: node + linkType: hard + +"p-map@npm:^7.0.2": + version: 7.0.3 + resolution: "p-map@npm:7.0.3" + checksum: 8c92d533acf82f0d12f7e196edccff773f384098bbb048acdd55a08778ce4fc8889d8f1bde72969487bd96f9c63212698d79744c20bedfce36c5b00b46d369f8 + languageName: node + linkType: hard + +"package-json-from-dist@npm:^1.0.0": + version: 1.0.1 + resolution: "package-json-from-dist@npm:1.0.1" + checksum: 58ee9538f2f762988433da00e26acc788036914d57c71c246bf0be1b60cdbd77dd60b6a3e1a30465f0b248aeb80079e0b34cb6050b1dfa18c06953bb1cbc7602 + languageName: node + linkType: hard + +"path-exists@npm:^4.0.0": + version: 4.0.0 + resolution: "path-exists@npm:4.0.0" + checksum: 505807199dfb7c50737b057dd8d351b82c033029ab94cb10a657609e00c1bc53b951cfdbccab8de04c5584d5eff31128ce6afd3db79281874a5ef2adbba55ed1 + languageName: node + linkType: hard + +"path-is-absolute@npm:^1.0.0": + version: 1.0.1 + resolution: "path-is-absolute@npm:1.0.1" + checksum: 060840f92cf8effa293bcc1bea81281bd7d363731d214cbe5c227df207c34cd727430f70c6037b5159c8a870b9157cba65e775446b0ab06fd5ecc7e54615a3b8 + languageName: node + linkType: hard + +"path-key@npm:^3.1.0": + version: 3.1.1 + resolution: "path-key@npm:3.1.1" + checksum: 55cd7a9dd4b343412a8386a743f9c746ef196e57c823d90ca3ab917f90ab9f13dd0ded27252ba49dbdfcab2b091d998bc446f6220cd3cea65db407502a740020 + languageName: node + linkType: hard + +"path-scurry@npm:^1.11.1": + version: 1.11.1 + resolution: "path-scurry@npm:1.11.1" + dependencies: + lru-cache: ^10.2.0 + minipass: ^5.0.0 || ^6.0.2 || ^7.0.0 + checksum: 890d5abcd593a7912dcce7cf7c6bf7a0b5648e3dee6caf0712c126ca0a65c7f3d7b9d769072a4d1baf370f61ce493ab5b038d59988688e0c5f3f646ee3c69023 + languageName: node + linkType: hard + +"picocolors@npm:^1.1.1": + version: 1.1.1 + resolution: "picocolors@npm:1.1.1" + checksum: e1cf46bf84886c79055fdfa9dcb3e4711ad259949e3565154b004b260cd356c5d54b31a1437ce9782624bf766272fe6b0154f5f0c744fb7af5d454d2b60db045 + languageName: node + linkType: hard + +"picomatch@npm:^2.0.4, picomatch@npm:^2.2.1": + version: 2.3.1 + resolution: "picomatch@npm:2.3.1" + checksum: 050c865ce81119c4822c45d3c84f1ced46f93a0126febae20737bd05ca20589c564d6e9226977df859ed5e03dc73f02584a2b0faad36e896936238238b0446cf + languageName: node + linkType: hard + +"picomatch@npm:^4.0.2": + version: 4.0.2 + resolution: "picomatch@npm:4.0.2" + checksum: a7a5188c954f82c6585720e9143297ccd0e35ad8072231608086ca950bee672d51b0ef676254af0788205e59bd4e4deb4e7708769226bed725bf13370a7d1464 + languageName: node + linkType: hard + +"pirates@npm:^4.0.1": + version: 4.0.6 + resolution: "pirates@npm:4.0.6" + checksum: 46a65fefaf19c6f57460388a5af9ab81e3d7fd0e7bc44ca59d753cb5c4d0df97c6c6e583674869762101836d68675f027d60f841c105d72734df9dfca97cbcc6 + languageName: node + linkType: hard + +"postcss-load-config@npm:^6.0.1": + version: 6.0.1 + resolution: "postcss-load-config@npm:6.0.1" + dependencies: + lilconfig: ^3.1.1 + peerDependencies: + jiti: ">=1.21.0" + postcss: ">=8.0.9" + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + checksum: 701061264cce7646e53e4cecd14aa95432a9bd508f30520a31dfa4c86fe9252d5d8d0204fdbfbddc1559c9b8791556e9c4b92c56070f5fca0a6c60e5ee9ad0fd + languageName: node + linkType: hard + +"prettier@npm:2.6.2": + version: 2.6.2 + resolution: "prettier@npm:2.6.2" + bin: + prettier: bin-prettier.js + checksum: 48d08dde8e9fb1f5bccdd205baa7f192e9fc8bc98f86e1b97d919de804e28c806b0e6cc685e4a88211aa7987fa9668f30baae19580d87ced3ed0f2ec6572106f + languageName: node + linkType: hard + +"prettier@npm:^2.5.1": + version: 2.8.8 + resolution: "prettier@npm:2.8.8" + bin: + prettier: bin-prettier.js + checksum: b49e409431bf129dd89238d64299ba80717b57ff5a6d1c1a8b1a28b590d998a34e083fa13573bc732bb8d2305becb4c9a4407f8486c81fa7d55100eb08263cf8 + languageName: node + linkType: hard + +"proc-log@npm:^5.0.0": + version: 5.0.0 + resolution: "proc-log@npm:5.0.0" + checksum: c78b26ecef6d5cce4a7489a1e9923d7b4b1679028c8654aef0463b27f4a90b0946cd598f55799da602895c52feb085ec76381d007ab8dcceebd40b89c2f9dfe0 + languageName: node + linkType: hard + +"promise-retry@npm:^2.0.1": + version: 2.0.1 + resolution: "promise-retry@npm:2.0.1" + dependencies: + err-code: ^2.0.2 + retry: ^0.12.0 + checksum: f96a3f6d90b92b568a26f71e966cbbc0f63ab85ea6ff6c81284dc869b41510e6cdef99b6b65f9030f0db422bf7c96652a3fff9f2e8fb4a0f069d8f4430359429 + languageName: node + linkType: hard + +"punycode@npm:^2.1.0": + version: 2.3.1 + resolution: "punycode@npm:2.3.1" + checksum: bb0a0ceedca4c3c57a9b981b90601579058903c62be23c5e8e843d2c2d4148a3ecf029d5133486fb0e1822b098ba8bba09e89d6b21742d02fa26bda6441a6fb2 + languageName: node + linkType: hard + +"randombytes@npm:^2.1.0": + version: 2.1.0 + resolution: "randombytes@npm:2.1.0" + dependencies: + safe-buffer: ^5.1.0 + checksum: d779499376bd4cbb435ef3ab9a957006c8682f343f14089ed5f27764e4645114196e75b7f6abf1cbd84fd247c0cb0651698444df8c9bf30e62120fbbc52269d6 + languageName: node + linkType: hard + +"readdirp@npm:^4.0.1": + version: 4.1.2 + resolution: "readdirp@npm:4.1.2" + checksum: 3242ee125422cb7c0e12d51452e993f507e6ed3d8c490bc8bf3366c5cdd09167562224e429b13e9cb2b98d4b8b2b11dc100d3c73883aa92d657ade5a21ded004 + languageName: node + linkType: hard + +"readdirp@npm:~3.6.0": + version: 3.6.0 + resolution: "readdirp@npm:3.6.0" + dependencies: + picomatch: ^2.2.1 + checksum: 1ced032e6e45670b6d7352d71d21ce7edf7b9b928494dcaba6f11fba63180d9da6cd7061ebc34175ffda6ff529f481818c962952004d273178acd70f7059b320 + languageName: node + linkType: hard + +"regenerator-runtime@npm:^0.13.11": + version: 0.13.11 + resolution: "regenerator-runtime@npm:0.13.11" + checksum: 27481628d22a1c4e3ff551096a683b424242a216fee44685467307f14d58020af1e19660bf2e26064de946bad7eff28950eae9f8209d55723e2d9351e632bbb4 + languageName: node + linkType: hard + +"require-directory@npm:^2.1.1": + version: 2.1.1 + resolution: "require-directory@npm:2.1.1" + checksum: fb47e70bf0001fdeabdc0429d431863e9475e7e43ea5f94ad86503d918423c1543361cc5166d713eaa7029dd7a3d34775af04764bebff99ef413111a5af18c80 + languageName: node + linkType: hard + +"resolve-from@npm:^5.0.0": + version: 5.0.0 + resolution: "resolve-from@npm:5.0.0" + checksum: 4ceeb9113e1b1372d0cd969f3468fa042daa1dd9527b1b6bb88acb6ab55d8b9cd65dbf18819f9f9ddf0db804990901dcdaade80a215e7b2c23daae38e64f5bdf + languageName: node + linkType: hard + +"retry@npm:^0.12.0": + version: 0.12.0 + resolution: "retry@npm:0.12.0" + checksum: 623bd7d2e5119467ba66202d733ec3c2e2e26568074923bc0585b6b99db14f357e79bdedb63cab56cec47491c4a0da7e6021a7465ca6dc4f481d3898fdd3158c + languageName: node + linkType: hard + +"rollup@npm:^4.24.0": + version: 4.34.8 + resolution: "rollup@npm:4.34.8" + dependencies: + "@rollup/rollup-android-arm-eabi": 4.34.8 + "@rollup/rollup-android-arm64": 4.34.8 + "@rollup/rollup-darwin-arm64": 4.34.8 + "@rollup/rollup-darwin-x64": 4.34.8 + "@rollup/rollup-freebsd-arm64": 4.34.8 + "@rollup/rollup-freebsd-x64": 4.34.8 + "@rollup/rollup-linux-arm-gnueabihf": 4.34.8 + "@rollup/rollup-linux-arm-musleabihf": 4.34.8 + "@rollup/rollup-linux-arm64-gnu": 4.34.8 + "@rollup/rollup-linux-arm64-musl": 4.34.8 + "@rollup/rollup-linux-loongarch64-gnu": 4.34.8 + "@rollup/rollup-linux-powerpc64le-gnu": 4.34.8 + "@rollup/rollup-linux-riscv64-gnu": 4.34.8 + "@rollup/rollup-linux-s390x-gnu": 4.34.8 + "@rollup/rollup-linux-x64-gnu": 4.34.8 + "@rollup/rollup-linux-x64-musl": 4.34.8 + "@rollup/rollup-win32-arm64-msvc": 4.34.8 + "@rollup/rollup-win32-ia32-msvc": 4.34.8 + "@rollup/rollup-win32-x64-msvc": 4.34.8 + "@types/estree": 1.0.6 + fsevents: ~2.3.2 + dependenciesMeta: + "@rollup/rollup-android-arm-eabi": + optional: true + "@rollup/rollup-android-arm64": + optional: true + "@rollup/rollup-darwin-arm64": + optional: true + "@rollup/rollup-darwin-x64": + optional: true + "@rollup/rollup-freebsd-arm64": + optional: true + "@rollup/rollup-freebsd-x64": + optional: true + "@rollup/rollup-linux-arm-gnueabihf": + optional: true + "@rollup/rollup-linux-arm-musleabihf": + optional: true + "@rollup/rollup-linux-arm64-gnu": + optional: true + "@rollup/rollup-linux-arm64-musl": + optional: true + "@rollup/rollup-linux-loongarch64-gnu": + optional: true + "@rollup/rollup-linux-powerpc64le-gnu": + optional: true + "@rollup/rollup-linux-riscv64-gnu": + optional: true + "@rollup/rollup-linux-s390x-gnu": + optional: true + "@rollup/rollup-linux-x64-gnu": + optional: true + "@rollup/rollup-linux-x64-musl": + optional: true + "@rollup/rollup-win32-arm64-msvc": + optional: true + "@rollup/rollup-win32-ia32-msvc": + optional: true + "@rollup/rollup-win32-x64-msvc": + optional: true + fsevents: + optional: true + bin: + rollup: dist/bin/rollup + checksum: 8c4abc97c16d4e80e4d803544ad004ba00f769aee460ff04200716f526fdcc3dd7ef6b71ae36aa5779bed410ef7244e15ffa0e3370711065dd15e2bd27d0cef5 + languageName: node + linkType: hard + +"root-workspace-0b6124@workspace:.": + version: 0.0.0-use.local + resolution: "root-workspace-0b6124@workspace:." + dependencies: + "@solana/spl-memo": ^0.2.3 + "@solana/spl-token": "*" + "@solana/web3.js": ^1.95.5 + "@types/mocha": 10.0.1 + "@types/node-fetch": 2.6.2 + mocha: 10.2.0 + prettier: 2.6.2 + ts-node: 10.9.1 + turbo: 1.6.3 + typescript: "*" + languageName: unknown + linkType: soft + +"rpc-websockets@npm:^7.5.0": + version: 7.5.0 + resolution: "rpc-websockets@npm:7.5.0" + dependencies: + "@babel/runtime": ^7.17.2 + bufferutil: ^4.0.1 + eventemitter3: ^4.0.7 + utf-8-validate: ^5.0.2 + uuid: ^8.3.2 + ws: ^8.5.0 + dependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: cd4c999e54161f9f40e162f57d7f3313edf086ff5facefbdc0629d52066e9843ace987681dbff8b4329db225deb69f58c528d7818a9c7e89f0100969b7789c2d + languageName: node + linkType: hard + +"safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.0": + version: 5.2.1 + resolution: "safe-buffer@npm:5.2.1" + checksum: b99c4b41fdd67a6aaf280fcd05e9ffb0813654894223afb78a31f14a19ad220bba8aba1cb14eddce1fcfb037155fe6de4e861784eb434f7d11ed58d1e70dd491 + languageName: node + linkType: hard + +"safer-buffer@npm:>= 2.1.2 < 3.0.0": + version: 2.1.2 + resolution: "safer-buffer@npm:2.1.2" + checksum: cab8f25ae6f1434abee8d80023d7e72b598cf1327164ddab31003c51215526801e40b66c5e65d658a0af1e9d6478cadcb4c745f4bd6751f97d8644786c0978b0 + languageName: node + linkType: hard + +"semver@npm:^7.3.5": + version: 7.7.2 + resolution: "semver@npm:7.7.2" + bin: + semver: bin/semver.js + checksum: dd94ba8f1cbc903d8eeb4dd8bf19f46b3deb14262b6717d0de3c804b594058ae785ef2e4b46c5c3b58733c99c83339068203002f9e37cfe44f7e2cc5e3d2f621 + languageName: node + linkType: hard + +"semver@npm:^7.3.7": + version: 7.7.1 + resolution: "semver@npm:7.7.1" + bin: + semver: bin/semver.js + checksum: 586b825d36874007c9382d9e1ad8f93888d8670040add24a28e06a910aeebd673a2eb9e3bf169c6679d9245e66efb9057e0852e70d9daa6c27372aab1dda7104 + languageName: node + linkType: hard + +"serialize-javascript@npm:6.0.0": + version: 6.0.0 + resolution: "serialize-javascript@npm:6.0.0" + dependencies: + randombytes: ^2.1.0 + checksum: 56f90b562a1bdc92e55afb3e657c6397c01a902c588c0fe3d4c490efdcc97dcd2a3074ba12df9e94630f33a5ce5b76a74784a7041294628a6f4306e0ec84bf93 + languageName: node + linkType: hard + +"set-function-length@npm:^1.2.2": + version: 1.2.2 + resolution: "set-function-length@npm:1.2.2" + dependencies: + define-data-property: ^1.1.4 + es-errors: ^1.3.0 + function-bind: ^1.1.2 + get-intrinsic: ^1.2.4 + gopd: ^1.0.1 + has-property-descriptors: ^1.0.2 + checksum: a8248bdacdf84cb0fab4637774d9fb3c7a8e6089866d04c817583ff48e14149c87044ce683d7f50759a8c50fb87c7a7e173535b06169c87ef76f5fb276dfff72 + languageName: node + linkType: hard + +"shebang-command@npm:^2.0.0": + version: 2.0.0 + resolution: "shebang-command@npm:2.0.0" + dependencies: + shebang-regex: ^3.0.0 + checksum: 6b52fe87271c12968f6a054e60f6bde5f0f3d2db483a1e5c3e12d657c488a15474121a1d55cd958f6df026a54374ec38a4a963988c213b7570e1d51575cea7fa + languageName: node + linkType: hard + +"shebang-regex@npm:^3.0.0": + version: 3.0.0 + resolution: "shebang-regex@npm:3.0.0" + checksum: 1a2bcae50de99034fcd92ad4212d8e01eedf52c7ec7830eedcf886622804fe36884278f2be8be0ea5fde3fd1c23911643a4e0f726c8685b61871c8908af01222 + languageName: node + linkType: hard + +"shiki@npm:^0.14.7": + version: 0.14.7 + resolution: "shiki@npm:0.14.7" + dependencies: + ansi-sequence-parser: ^1.1.0 + jsonc-parser: ^3.2.0 + vscode-oniguruma: ^1.7.0 + vscode-textmate: ^8.0.0 + checksum: 2aec3b3519df977c4391df9e1825cb496e9a4d7e11395f05a0da77e4fa2f7c3d9d6e6ee94029ac699533017f2b25637ee68f6d39f05f311535c2704d0329b520 + languageName: node + linkType: hard + +"signal-exit@npm:^4.0.1": + version: 4.1.0 + resolution: "signal-exit@npm:4.1.0" + checksum: 64c757b498cb8629ffa5f75485340594d2f8189e9b08700e69199069c8e3070fb3e255f7ab873c05dc0b3cec412aea7402e10a5990cb6a050bd33ba062a6c549 + languageName: node + linkType: hard + +"smart-buffer@npm:^4.2.0": + version: 4.2.0 + resolution: "smart-buffer@npm:4.2.0" + checksum: b5167a7142c1da704c0e3af85c402002b597081dd9575031a90b4f229ca5678e9a36e8a374f1814c8156a725d17008ae3bde63b92f9cfd132526379e580bec8b + languageName: node + linkType: hard + +"snake-case@npm:^3.0.4": + version: 3.0.4 + resolution: "snake-case@npm:3.0.4" + dependencies: + dot-case: ^3.0.4 + tslib: ^2.0.3 + checksum: 0a7a79900bbb36f8aaa922cf111702a3647ac6165736d5dc96d3ef367efc50465cac70c53cd172c382b022dac72ec91710608e5393de71f76d7142e6fd80e8a3 + languageName: node + linkType: hard + +"socks-proxy-agent@npm:^8.0.3": + version: 8.0.5 + resolution: "socks-proxy-agent@npm:8.0.5" + dependencies: + agent-base: ^7.1.2 + debug: ^4.3.4 + socks: ^2.8.3 + checksum: b4fbcdb7ad2d6eec445926e255a1fb95c975db0020543fbac8dfa6c47aecc6b3b619b7fb9c60a3f82c9b2969912a5e7e174a056ae4d98cb5322f3524d6036e1d + languageName: node + linkType: hard + +"socks@npm:^2.8.3": + version: 2.8.6 + resolution: "socks@npm:2.8.6" + dependencies: + ip-address: ^9.0.5 + smart-buffer: ^4.2.0 + checksum: 3d2a696d42d94b05b2a7e797b9291483d6768b23300b015353f34f8046cce35f23fe59300a38a77a9f0dee4274dd6c333afbdef628cf48f3df171bfb86c2d21c + languageName: node + linkType: hard + +"source-map@npm:0.8.0-beta.0": + version: 0.8.0-beta.0 + resolution: "source-map@npm:0.8.0-beta.0" + dependencies: + whatwg-url: ^7.0.0 + checksum: e94169be6461ab0ac0913313ad1719a14c60d402bd22b0ad96f4a6cffd79130d91ab5df0a5336a326b04d2df131c1409f563c9dc0d21a6ca6239a44b6c8dbd92 + languageName: node + linkType: hard + +"spok@npm:^1.4.3": + version: 1.5.5 + resolution: "spok@npm:1.5.5" + dependencies: + ansicolors: ~0.3.2 + find-process: ^1.4.7 + checksum: 46af901fb712d4666bc57276874d7e174b645a8f34e5d549cbef99f5374075910e6d303c645420197525fa00aa6d014f8f5147b7c9802c790b27f23b215c2834 + languageName: node + linkType: hard + +"sprintf-js@npm:^1.1.3": + version: 1.1.3 + resolution: "sprintf-js@npm:1.1.3" + checksum: a3fdac7b49643875b70864a9d9b469d87a40dfeaf5d34d9d0c5b1cda5fd7d065531fcb43c76357d62254c57184a7b151954156563a4d6a747015cfb41021cad0 + languageName: node + linkType: hard + +"ssri@npm:^12.0.0": + version: 12.0.0 + resolution: "ssri@npm:12.0.0" + dependencies: + minipass: ^7.0.3 + checksum: ef4b6b0ae47b4a69896f5f1c4375f953b9435388c053c36d27998bc3d73e046969ccde61ab659e679142971a0b08e50478a1228f62edb994105b280f17900c98 + languageName: node + linkType: hard + +"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0": + version: 4.2.3 + resolution: "string-width@npm:4.2.3" + dependencies: + emoji-regex: ^8.0.0 + is-fullwidth-code-point: ^3.0.0 + strip-ansi: ^6.0.1 + checksum: e52c10dc3fbfcd6c3a15f159f54a90024241d0f149cf8aed2982a2d801d2e64df0bf1dc351cf8e95c3319323f9f220c16e740b06faecd53e2462df1d2b5443fb + languageName: node + linkType: hard + +"string-width@npm:^5.0.1, string-width@npm:^5.1.2": + version: 5.1.2 + resolution: "string-width@npm:5.1.2" + dependencies: + eastasianwidth: ^0.2.0 + emoji-regex: ^9.2.2 + strip-ansi: ^7.0.1 + checksum: 7369deaa29f21dda9a438686154b62c2c5f661f8dda60449088f9f980196f7908fc39fdd1803e3e01541970287cf5deae336798337e9319a7055af89dafa7193 + languageName: node + linkType: hard + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": + version: 6.0.1 + resolution: "strip-ansi@npm:6.0.1" + dependencies: + ansi-regex: ^5.0.1 + checksum: f3cd25890aef3ba6e1a74e20896c21a46f482e93df4a06567cebf2b57edabb15133f1f94e57434e0a958d61186087b1008e89c94875d019910a213181a14fc8c + languageName: node + linkType: hard + +"strip-ansi@npm:^7.0.1": + version: 7.1.0 + resolution: "strip-ansi@npm:7.1.0" + dependencies: + ansi-regex: ^6.0.1 + checksum: 859c73fcf27869c22a4e4d8c6acfe690064659e84bef9458aa6d13719d09ca88dcfd40cbf31fd0be63518ea1a643fe070b4827d353e09533a5b0b9fd4553d64d + languageName: node + linkType: hard + +"strip-json-comments@npm:3.1.1": + version: 3.1.1 + resolution: "strip-json-comments@npm:3.1.1" + checksum: 492f73e27268f9b1c122733f28ecb0e7e8d8a531a6662efbd08e22cccb3f9475e90a1b82cab06a392f6afae6d2de636f977e231296400d0ec5304ba70f166443 + languageName: node + linkType: hard + +"sucrase@npm:^3.35.0": + version: 3.35.0 + resolution: "sucrase@npm:3.35.0" + dependencies: + "@jridgewell/gen-mapping": ^0.3.2 + commander: ^4.0.0 + glob: ^10.3.10 + lines-and-columns: ^1.1.6 + mz: ^2.7.0 + pirates: ^4.0.1 + ts-interface-checker: ^0.1.9 + bin: + sucrase: bin/sucrase + sucrase-node: bin/sucrase-node + checksum: 9fc5792a9ab8a14dcf9c47dcb704431d35c1cdff1d17d55d382a31c2e8e3063870ad32ce120a80915498486246d612e30cda44f1624d9d9a10423e1a43487ad1 + languageName: node + linkType: hard + +"superstruct@npm:^0.14.2": + version: 0.14.2 + resolution: "superstruct@npm:0.14.2" + checksum: c5c4840f432da82125b923ec45faca5113217e83ae416e314d80eae012b8bb603d2e745025d173450758d116348820bc7028157f8c9a72b6beae879f94b837c0 + languageName: node + linkType: hard + +"supports-color@npm:8.1.1": + version: 8.1.1 + resolution: "supports-color@npm:8.1.1" + dependencies: + has-flag: ^4.0.0 + checksum: c052193a7e43c6cdc741eb7f378df605636e01ad434badf7324f17fb60c69a880d8d8fcdcb562cf94c2350e57b937d7425ab5b8326c67c2adc48f7c87c1db406 + languageName: node + linkType: hard + +"supports-color@npm:^7.1.0": + version: 7.2.0 + resolution: "supports-color@npm:7.2.0" + dependencies: + has-flag: ^4.0.0 + checksum: 3dda818de06ebbe5b9653e07842d9479f3555ebc77e9a0280caf5a14fb877ffee9ed57007c3b78f5a6324b8dbeec648d9e97a24e2ed9fdb81ddc69ea07100f4a + languageName: node + linkType: hard + +"tar@npm:^7.4.3": + version: 7.4.3 + resolution: "tar@npm:7.4.3" + dependencies: + "@isaacs/fs-minipass": ^4.0.0 + chownr: ^3.0.0 + minipass: ^7.1.2 + minizlib: ^3.0.1 + mkdirp: ^3.0.1 + yallist: ^5.0.0 + checksum: 8485350c0688331c94493031f417df069b778aadb25598abdad51862e007c39d1dd5310702c7be4a6784731a174799d8885d2fde0484269aea205b724d7b2ffa + languageName: node + linkType: hard + +"text-encoding-utf-8@npm:^1.0.2": + version: 1.0.2 + resolution: "text-encoding-utf-8@npm:1.0.2" + checksum: ec4c15d50e738c5dba7327ad432ebf0725ec75d4d69c0bd55609254c5a3bc5341272d7003691084a0a73d60d981c8eb0e87603676fdb6f3fed60f4c9192309f9 + languageName: node + linkType: hard + +"text-table@npm:^0.2.0": + version: 0.2.0 + resolution: "text-table@npm:0.2.0" + checksum: b6937a38c80c7f84d9c11dd75e49d5c44f71d95e810a3250bd1f1797fc7117c57698204adf676b71497acc205d769d65c16ae8fa10afad832ae1322630aef10a + languageName: node + linkType: hard + +"thenify-all@npm:^1.0.0": + version: 1.6.0 + resolution: "thenify-all@npm:1.6.0" + dependencies: + thenify: ">= 3.1.0 < 4" + checksum: dba7cc8a23a154cdcb6acb7f51d61511c37a6b077ec5ab5da6e8b874272015937788402fd271fdfc5f187f8cb0948e38d0a42dcc89d554d731652ab458f5343e + languageName: node + linkType: hard + +"thenify@npm:>= 3.1.0 < 4": + version: 3.3.1 + resolution: "thenify@npm:3.3.1" + dependencies: + any-promise: ^1.0.0 + checksum: 84e1b804bfec49f3531215f17b4a6e50fd4397b5f7c1bccc427b9c656e1ecfb13ea79d899930184f78bc2f57285c54d9a50a590c8868f4f0cef5c1d9f898b05e + languageName: node + linkType: hard + +"through@npm:>=2.2.7 <3": + version: 2.3.8 + resolution: "through@npm:2.3.8" + checksum: a38c3e059853c494af95d50c072b83f8b676a9ba2818dcc5b108ef252230735c54e0185437618596c790bbba8fcdaef5b290405981ffa09dce67b1f1bf190cbd + languageName: node + linkType: hard + +"tinyexec@npm:^0.3.1": + version: 0.3.2 + resolution: "tinyexec@npm:0.3.2" + checksum: bd491923020610bdeadb0d8cf5d70e7cbad5a3201620fd01048c9bf3b31ffaa75c33254e1540e13b993ce4e8187852b0b5a93057bb598e7a57afa2ca2048a35c + languageName: node + linkType: hard + +"tinyglobby@npm:^0.2.12": + version: 0.2.14 + resolution: "tinyglobby@npm:0.2.14" + dependencies: + fdir: ^6.4.4 + picomatch: ^4.0.2 + checksum: 261e986e3f2062dec3a582303bad2ce31b4634b9348648b46828c000d464b012cf474e38f503312367d4117c3f2f18611992738fca684040758bba44c24de522 + languageName: node + linkType: hard + +"tinyglobby@npm:^0.2.9": + version: 0.2.12 + resolution: "tinyglobby@npm:0.2.12" + dependencies: + fdir: ^6.4.3 + picomatch: ^4.0.2 + checksum: ef9357fa1b2b661afdccd315cb4995f5f36bce948faaace68aae85fe57bdd8f837883045c88efc50d3186bac6586e4ae2f31026b9a3aac061b884217e6092e23 + languageName: node + linkType: hard + +"to-regex-range@npm:^5.0.1": + version: 5.0.1 + resolution: "to-regex-range@npm:5.0.1" + dependencies: + is-number: ^7.0.0 + checksum: f76fa01b3d5be85db6a2a143e24df9f60dd047d151062d0ba3df62953f2f697b16fe5dad9b0ac6191c7efc7b1d9dcaa4b768174b7b29da89d4428e64bc0a20ed + languageName: node + linkType: hard + +"toml@npm:^3.0.0": + version: 3.0.0 + resolution: "toml@npm:3.0.0" + checksum: 5d7f1d8413ad7780e9bdecce8ea4c3f5130dd53b0a4f2e90b93340979a137739879d7b9ce2ce05c938b8cc828897fe9e95085197342a1377dd8850bf5125f15f + languageName: node + linkType: hard + +"tr46@npm:^1.0.1": + version: 1.0.1 + resolution: "tr46@npm:1.0.1" + dependencies: + punycode: ^2.1.0 + checksum: 96d4ed46bc161db75dbf9247a236ea0bfcaf5758baae6749e92afab0bc5a09cb59af21788ede7e55080f2bf02dce3e4a8f2a484cc45164e29f4b5e68f7cbcc1a + languageName: node + linkType: hard + +"tr46@npm:~0.0.3": + version: 0.0.3 + resolution: "tr46@npm:0.0.3" + checksum: 726321c5eaf41b5002e17ffbd1fb7245999a073e8979085dacd47c4b4e8068ff5777142fc6726d6ca1fd2ff16921b48788b87225cbc57c72636f6efa8efbffe3 + languageName: node + linkType: hard + +"tree-kill@npm:^1.2.2": + version: 1.2.2 + resolution: "tree-kill@npm:1.2.2" + bin: + tree-kill: cli.js + checksum: 49117f5f410d19c84b0464d29afb9642c863bc5ba40fcb9a245d474c6d5cc64d1b177a6e6713129eb346b40aebb9d4631d967517f9fbe8251c35b21b13cd96c7 + languageName: node + linkType: hard + +"ts-interface-checker@npm:^0.1.9": + version: 0.1.13 + resolution: "ts-interface-checker@npm:0.1.13" + checksum: 20c29189c2dd6067a8775e07823ddf8d59a33e2ffc47a1bd59a5cb28bb0121a2969a816d5e77eda2ed85b18171aa5d1c4005a6b88ae8499ec7cc49f78571cb5e + languageName: node + linkType: hard + +"ts-node@npm:10.9.1": + version: 10.9.1 + resolution: "ts-node@npm:10.9.1" + dependencies: + "@cspotcode/source-map-support": ^0.8.0 + "@tsconfig/node10": ^1.0.7 + "@tsconfig/node12": ^1.0.7 + "@tsconfig/node14": ^1.0.0 + "@tsconfig/node16": ^1.0.2 + acorn: ^8.4.1 + acorn-walk: ^8.1.1 + arg: ^4.1.0 + create-require: ^1.1.0 + diff: ^4.0.1 + make-error: ^1.1.1 + v8-compile-cache-lib: ^3.0.1 + yn: 3.1.1 + peerDependencies: + "@swc/core": ">=1.2.50" + "@swc/wasm": ">=1.2.50" + "@types/node": "*" + typescript: ">=2.7" + peerDependenciesMeta: + "@swc/core": + optional: true + "@swc/wasm": + optional: true + bin: + ts-node: dist/bin.js + ts-node-cwd: dist/bin-cwd.js + ts-node-esm: dist/bin-esm.js + ts-node-script: dist/bin-script.js + ts-node-transpile-only: dist/bin-transpile.js + ts-script: dist/bin-script-deprecated.js + checksum: 090adff1302ab20bd3486e6b4799e90f97726ed39e02b39e566f8ab674fd5bd5f727f43615debbfc580d33c6d9d1c6b1b3ce7d8e3cca3e20530a145ffa232c35 + languageName: node + linkType: hard + +"tslib@npm:^2.0.3": + version: 2.8.1 + resolution: "tslib@npm:2.8.1" + checksum: e4aba30e632b8c8902b47587fd13345e2827fa639e7c3121074d5ee0880723282411a8838f830b55100cbe4517672f84a2472667d355b81e8af165a55dc6203a + languageName: node + linkType: hard + +"tsup@npm:^8.0.2": + version: 8.3.6 + resolution: "tsup@npm:8.3.6" + dependencies: + bundle-require: ^5.0.0 + cac: ^6.7.14 + chokidar: ^4.0.1 + consola: ^3.2.3 + debug: ^4.3.7 + esbuild: ^0.24.0 + joycon: ^3.1.1 + picocolors: ^1.1.1 + postcss-load-config: ^6.0.1 + resolve-from: ^5.0.0 + rollup: ^4.24.0 + source-map: 0.8.0-beta.0 + sucrase: ^3.35.0 + tinyexec: ^0.3.1 + tinyglobby: ^0.2.9 + tree-kill: ^1.2.2 + peerDependencies: + "@microsoft/api-extractor": ^7.36.0 + "@swc/core": ^1 + postcss: ^8.4.12 + typescript: ">=4.5.0" + peerDependenciesMeta: + "@microsoft/api-extractor": + optional: true + "@swc/core": + optional: true + postcss: + optional: true + typescript: + optional: true + bin: + tsup: dist/cli-default.js + tsup-node: dist/cli-node.js + checksum: 612e2af5ba3c8eef25cd64e44952c5d91be2d3ab44ca2f3c013c29558eb381e6e6d8ba73c076e280ea214d6f43d49b4479af928eca131de73c5617f94c7f4ba4 + languageName: node + linkType: hard + +"turbo-darwin-64@npm:1.6.3": + version: 1.6.3 + resolution: "turbo-darwin-64@npm:1.6.3" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"turbo-darwin-arm64@npm:1.6.3": + version: 1.6.3 + resolution: "turbo-darwin-arm64@npm:1.6.3" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"turbo-linux-64@npm:1.6.3": + version: 1.6.3 + resolution: "turbo-linux-64@npm:1.6.3" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"turbo-linux-arm64@npm:1.6.3": + version: 1.6.3 + resolution: "turbo-linux-arm64@npm:1.6.3" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + +"turbo-windows-64@npm:1.6.3": + version: 1.6.3 + resolution: "turbo-windows-64@npm:1.6.3" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"turbo-windows-arm64@npm:1.6.3": + version: 1.6.3 + resolution: "turbo-windows-arm64@npm:1.6.3" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"turbo@npm:1.6.3": + version: 1.6.3 + resolution: "turbo@npm:1.6.3" + dependencies: + turbo-darwin-64: 1.6.3 + turbo-darwin-arm64: 1.6.3 + turbo-linux-64: 1.6.3 + turbo-linux-arm64: 1.6.3 + turbo-windows-64: 1.6.3 + turbo-windows-arm64: 1.6.3 + dependenciesMeta: + turbo-darwin-64: + optional: true + turbo-darwin-arm64: + optional: true + turbo-linux-64: + optional: true + turbo-linux-arm64: + optional: true + turbo-windows-64: + optional: true + turbo-windows-arm64: + optional: true + bin: + turbo: bin/turbo + checksum: 35195f4b7623014c25ba152c11a8cb23e51cbd75dc9266d0656692665f85b28faf3496dea8cecacf52795a917410668124186ffbdcf276325ccc3e11df9e9623 + languageName: node + linkType: hard + +"typedoc@npm:^0.25.7": + version: 0.25.13 + resolution: "typedoc@npm:0.25.13" + dependencies: + lunr: ^2.3.9 + marked: ^4.3.0 + minimatch: ^9.0.3 + shiki: ^0.14.7 + peerDependencies: + typescript: 4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x + bin: + typedoc: bin/typedoc + checksum: 703d1f48137300b0ef3df1998a25ae745db3ca0b126f8dd1f7262918f11243a94d24dfc916cdba2baeb5a7d85d5a94faac811caf7f4fa6b7d07144dc02f7639f + languageName: node + linkType: hard + +"typescript@npm:4.9.4": + version: 4.9.4 + resolution: "typescript@npm:4.9.4" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: e782fb9e0031cb258a80000f6c13530288c6d63f1177ed43f770533fdc15740d271554cdae86701c1dd2c83b082cea808b07e97fd68b38a172a83dbf9e0d0ef9 + languageName: node + linkType: hard + +"typescript@patch:typescript@npm%3A4.9.4#~builtin": + version: 4.9.4 + resolution: "typescript@patch:typescript@npm%3A4.9.4#~builtin::version=4.9.4&hash=23ec76" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 3e2ab0772908676d9b9cb83398c70003a3b08e1c6b3b122409df9f4b520f2fdaefa20c3d7d57dce283fed760ac94b3ce94d4a7fa875127b67852904425a1f0dc + languageName: node + linkType: hard + +"undici-types@npm:~7.8.0": + version: 7.8.0 + resolution: "undici-types@npm:7.8.0" + checksum: 59521a5b9b50e72cb838a29466b3557b4eacbc191a83f4df5a2f7b156bc8263072b145dc4bb8ec41da7d56a7e9b178892458da02af769243d57f801a50ac5751 + languageName: node + linkType: hard + +"unique-filename@npm:^4.0.0": + version: 4.0.0 + resolution: "unique-filename@npm:4.0.0" + dependencies: + unique-slug: ^5.0.0 + checksum: 6a62094fcac286b9ec39edbd1f8f64ff92383baa430af303dfed1ffda5e47a08a6b316408554abfddd9730c78b6106bef4ca4d02c1231a735ddd56ced77573df + languageName: node + linkType: hard + +"unique-slug@npm:^5.0.0": + version: 5.0.0 + resolution: "unique-slug@npm:5.0.0" + dependencies: + imurmurhash: ^0.1.4 + checksum: 222d0322bc7bbf6e45c08967863212398313ef73423f4125e075f893a02405a5ffdbaaf150f7dd1e99f8861348a486dd079186d27c5f2c60e465b7dcbb1d3e5b + languageName: node + linkType: hard + +"utf-8-validate@npm:^5.0.2": + version: 5.0.10 + resolution: "utf-8-validate@npm:5.0.10" + dependencies: + node-gyp: latest + node-gyp-build: ^4.3.0 + checksum: 5579350a023c66a2326752b6c8804cc7b39dcd251bb088241da38db994b8d78352e388dcc24ad398ab98385ba3c5ffcadb6b5b14b2637e43f767869055e46ba6 + languageName: node + linkType: hard + +"util@npm:^0.12.0, util@npm:^0.12.5": + version: 0.12.5 + resolution: "util@npm:0.12.5" + dependencies: + inherits: ^2.0.3 + is-arguments: ^1.0.4 + is-generator-function: ^1.0.7 + is-typed-array: ^1.1.3 + which-typed-array: ^1.1.2 + checksum: 705e51f0de5b446f4edec10739752ac25856541e0254ea1e7e45e5b9f9b0cb105bc4bd415736a6210edc68245a7f903bf085ffb08dd7deb8a0e847f60538a38a + languageName: node + linkType: hard + +"uuid@npm:^8.3.2": + version: 8.3.2 + resolution: "uuid@npm:8.3.2" + bin: + uuid: dist/bin/uuid + checksum: 5575a8a75c13120e2f10e6ddc801b2c7ed7d8f3c8ac22c7ed0c7b2ba6383ec0abda88c905085d630e251719e0777045ae3236f04c812184b7c765f63a70e58df + languageName: node + linkType: hard + +"v8-compile-cache-lib@npm:^3.0.1": + version: 3.0.1 + resolution: "v8-compile-cache-lib@npm:3.0.1" + checksum: 78089ad549e21bcdbfca10c08850022b22024cdcc2da9b168bcf5a73a6ed7bf01a9cebb9eac28e03cd23a684d81e0502797e88f3ccd27a32aeab1cfc44c39da0 + languageName: node + linkType: hard + +"vscode-oniguruma@npm:^1.7.0": + version: 1.7.0 + resolution: "vscode-oniguruma@npm:1.7.0" + checksum: 53519d91d90593e6fb080260892e87d447e9b200c4964d766772b5053f5699066539d92100f77f1302c91e8fc5d9c772fbe40fe4c90f3d411a96d5a9b1e63f42 + languageName: node + linkType: hard + +"vscode-textmate@npm:^8.0.0": + version: 8.0.0 + resolution: "vscode-textmate@npm:8.0.0" + checksum: 127780dfea89559d70b8326df6ec344cfd701312dd7f3f591a718693812b7852c30b6715e3cfc8b3200a4e2515b4c96f0843c0eacc0a3020969b5de262c2a4bb + languageName: node + linkType: hard + +"webidl-conversions@npm:^3.0.0": + version: 3.0.1 + resolution: "webidl-conversions@npm:3.0.1" + checksum: c92a0a6ab95314bde9c32e1d0a6dfac83b578f8fa5f21e675bc2706ed6981bc26b7eb7e6a1fab158e5ce4adf9caa4a0aee49a52505d4d13c7be545f15021b17c + languageName: node + linkType: hard + +"webidl-conversions@npm:^4.0.2": + version: 4.0.2 + resolution: "webidl-conversions@npm:4.0.2" + checksum: c93d8dfe908a0140a4ae9c0ebc87a33805b416a33ee638a605b551523eec94a9632165e54632f6d57a39c5f948c4bab10e0e066525e9a4b87a79f0d04fbca374 + languageName: node + linkType: hard + +"whatwg-url@npm:^5.0.0": + version: 5.0.0 + resolution: "whatwg-url@npm:5.0.0" + dependencies: + tr46: ~0.0.3 + webidl-conversions: ^3.0.0 + checksum: b8daed4ad3356cc4899048a15b2c143a9aed0dfae1f611ebd55073310c7b910f522ad75d727346ad64203d7e6c79ef25eafd465f4d12775ca44b90fa82ed9e2c + languageName: node + linkType: hard + +"whatwg-url@npm:^7.0.0": + version: 7.1.0 + resolution: "whatwg-url@npm:7.1.0" + dependencies: + lodash.sortby: ^4.7.0 + tr46: ^1.0.1 + webidl-conversions: ^4.0.2 + checksum: fecb07c87290b47d2ec2fb6d6ca26daad3c9e211e0e531dd7566e7ff95b5b3525a57d4f32640ad4adf057717e0c215731db842ad761e61d947e81010e05cf5fd + languageName: node + linkType: hard + +"which-typed-array@npm:^1.1.2": + version: 1.1.9 + resolution: "which-typed-array@npm:1.1.9" + dependencies: + available-typed-arrays: ^1.0.5 + call-bind: ^1.0.2 + for-each: ^0.3.3 + gopd: ^1.0.1 + has-tostringtag: ^1.0.0 + is-typed-array: ^1.1.10 + checksum: fe0178ca44c57699ca2c0e657b64eaa8d2db2372a4e2851184f568f98c478ae3dc3fdb5f7e46c384487046b0cf9e23241423242b277e03e8ba3dabc7c84c98ef + languageName: node + linkType: hard + +"which@npm:^2.0.1": + version: 2.0.2 + resolution: "which@npm:2.0.2" + dependencies: + isexe: ^2.0.0 + bin: + node-which: ./bin/node-which + checksum: 1a5c563d3c1b52d5f893c8b61afe11abc3bab4afac492e8da5bde69d550de701cf9806235f20a47b5c8fa8a1d6a9135841de2596535e998027a54589000e66d1 + languageName: node + linkType: hard + +"which@npm:^5.0.0": + version: 5.0.0 + resolution: "which@npm:5.0.0" + dependencies: + isexe: ^3.1.1 + bin: + node-which: bin/which.js + checksum: 6ec99e89ba32c7e748b8a3144e64bfc74aa63e2b2eacbb61a0060ad0b961eb1a632b08fb1de067ed59b002cec3e21de18299216ebf2325ef0f78e0f121e14e90 + languageName: node + linkType: hard + +"workerpool@npm:6.2.1": + version: 6.2.1 + resolution: "workerpool@npm:6.2.1" + checksum: c2c6eebbc5225f10f758d599a5c016fa04798bcc44e4c1dffb34050cd361d7be2e97891aa44419e7afe647b1f767b1dc0b85a5e046c409d890163f655028b09d + languageName: node + linkType: hard + +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0, wrap-ansi@npm:^7.0.0": + version: 7.0.0 + resolution: "wrap-ansi@npm:7.0.0" + dependencies: + ansi-styles: ^4.0.0 + string-width: ^4.1.0 + strip-ansi: ^6.0.0 + checksum: a790b846fd4505de962ba728a21aaeda189b8ee1c7568ca5e817d85930e06ef8d1689d49dbf0e881e8ef84436af3a88bc49115c2e2788d841ff1b8b5b51a608b + languageName: node + linkType: hard + +"wrap-ansi@npm:^8.1.0": + version: 8.1.0 + resolution: "wrap-ansi@npm:8.1.0" + dependencies: + ansi-styles: ^6.1.0 + string-width: ^5.0.1 + strip-ansi: ^7.0.1 + checksum: 371733296dc2d616900ce15a0049dca0ef67597d6394c57347ba334393599e800bab03c41d4d45221b6bc967b8c453ec3ae4749eff3894202d16800fdfe0e238 + languageName: node + linkType: hard + +"wrappy@npm:1": + version: 1.0.2 + resolution: "wrappy@npm:1.0.2" + checksum: 159da4805f7e84a3d003d8841557196034155008f817172d4e986bd591f74aa82aa7db55929a54222309e01079a65a92a9e6414da5a6aa4b01ee44a511ac3ee5 + languageName: node + linkType: hard + +"ws@npm:^7.4.5": + version: 7.5.9 + resolution: "ws@npm:7.5.9" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: c3c100a181b731f40b7f2fddf004aa023f79d64f489706a28bc23ff88e87f6a64b3c6651fbec3a84a53960b75159574d7a7385709847a62ddb7ad6af76f49138 + languageName: node + linkType: hard + +"ws@npm:^8.5.0": + version: 8.11.0 + resolution: "ws@npm:8.11.0" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 316b33aba32f317cd217df66dbfc5b281a2f09ff36815de222bc859e3424d83766d9eb2bd4d667de658b6ab7be151f258318fb1da812416b30be13103e5b5c67 + languageName: node + linkType: hard + +"y18n@npm:^5.0.5": + version: 5.0.8 + resolution: "y18n@npm:5.0.8" + checksum: 54f0fb95621ee60898a38c572c515659e51cc9d9f787fb109cef6fde4befbe1c4602dc999d30110feee37456ad0f1660fa2edcfde6a9a740f86a290999550d30 + languageName: node + linkType: hard + +"yallist@npm:^4.0.0": + version: 4.0.0 + resolution: "yallist@npm:4.0.0" + checksum: 343617202af32df2a15a3be36a5a8c0c8545208f3d3dfbc6bb7c3e3b7e8c6f8e7485432e4f3b88da3031a6e20afa7c711eded32ddfb122896ac5d914e75848d5 + languageName: node + linkType: hard + +"yallist@npm:^5.0.0": + version: 5.0.0 + resolution: "yallist@npm:5.0.0" + checksum: eba51182400b9f35b017daa7f419f434424410691bbc5de4f4240cc830fdef906b504424992700dc047f16b4d99100a6f8b8b11175c193f38008e9c96322b6a5 + languageName: node + linkType: hard + +"yargs-parser@npm:20.2.4": + version: 20.2.4 + resolution: "yargs-parser@npm:20.2.4" + checksum: d251998a374b2743a20271c2fd752b9fbef24eb881d53a3b99a7caa5e8227fcafd9abf1f345ac5de46435821be25ec12189a11030c12ee6481fef6863ed8b924 + languageName: node + linkType: hard + +"yargs-parser@npm:^20.2.2": + version: 20.2.9 + resolution: "yargs-parser@npm:20.2.9" + checksum: 8bb69015f2b0ff9e17b2c8e6bfe224ab463dd00ca211eece72a4cd8a906224d2703fb8a326d36fdd0e68701e201b2a60ed7cf81ce0fd9b3799f9fe7745977ae3 + languageName: node + linkType: hard + +"yargs-unparser@npm:2.0.0": + version: 2.0.0 + resolution: "yargs-unparser@npm:2.0.0" + dependencies: + camelcase: ^6.0.0 + decamelize: ^4.0.0 + flat: ^5.0.2 + is-plain-obj: ^2.1.0 + checksum: 68f9a542c6927c3768c2f16c28f71b19008710abd6b8f8efbac6dcce26bbb68ab6503bed1d5994bdbc2df9a5c87c161110c1dfe04c6a3fe5c6ad1b0e15d9a8a3 + languageName: node + linkType: hard + +"yargs@npm:16.2.0": + version: 16.2.0 + resolution: "yargs@npm:16.2.0" + dependencies: + cliui: ^7.0.2 + escalade: ^3.1.1 + get-caller-file: ^2.0.5 + require-directory: ^2.1.1 + string-width: ^4.2.0 + y18n: ^5.0.5 + yargs-parser: ^20.2.2 + checksum: b14afbb51e3251a204d81937c86a7e9d4bdbf9a2bcee38226c900d00f522969ab675703bee2a6f99f8e20103f608382936034e64d921b74df82b63c07c5e8f59 + languageName: node + linkType: hard + +"yn@npm:3.1.1": + version: 3.1.1 + resolution: "yn@npm:3.1.1" + checksum: 2c487b0e149e746ef48cda9f8bad10fc83693cd69d7f9dcd8be4214e985de33a29c9e24f3c0d6bcf2288427040a8947406ab27f7af67ee9456e6b84854f02dd6 + languageName: node + linkType: hard + +"yocto-queue@npm:^0.1.0": + version: 0.1.0 + resolution: "yocto-queue@npm:0.1.0" + checksum: f77b3d8d00310def622123df93d4ee654fc6a0096182af8bd60679ddcdfb3474c56c6c7190817c84a2785648cdee9d721c0154eb45698c62176c322fb46fc700 + languageName: node + linkType: hard