ClassyX403 SDK
Production-grade SDK for integrating policy-native execution control into Solana applications.
Overview
The ClassyX403 SDK provides a complete toolkit for creating, managing, and enforcing policies within your Solana applications. Built with TypeScript, the SDK offers type-safe interfaces and comprehensive integration with Solana's web3.js library.
The SDK abstracts the complexity of policy management while maintaining full transparency and control over policy evaluation and enforcement.
Installation
Install the ClassyX403 SDK via npm or yarn:
npm install @classyx403/sdk @solana/web3.jsyarn add @classyx403/sdk @solana/web3.jsSolana-First Integration
The SDK is designed to integrate seamlessly with existing Solana applications. Policy enforcement is added as a composable layer without requiring modifications to existing program logic.
import { ClassyX403Client, PolicyBuilder } from '@classyx403/sdk';
import { Connection, Keypair, PublicKey } from '@solana/web3.js';const connection = new Connection('https://api.mainnet-beta.solana.com');
const client = new ClassyX403Client(connection);Policy Creation Flow
Creating a policy involves defining access rules, specifying the target program, and submitting the policy to the ClassyX403 program.
Define Policy Rules
const policy = new PolicyBuilder()
.setAuthority(authorityKeypair.publicKey)
.setTargetProgram(targetProgramId)
.addRule({
type: 'AllowedSigners',
signers: [signer1.publicKey, signer2.publicKey],
})
.addRule({
type: 'TimeWindow',
start: Date.now(),
end: Date.now() + 86400000, // 24 hours
})
.build();Create Policy Account
const signature = await client.createPolicy({
policy,
payer: payerKeypair,
authority: authorityKeypair,
});
console.log('Policy created:', signature);Verify Policy
const policyAccount = await client.getPolicy({
authority: authorityKeypair.publicKey,
targetProgram: targetProgramId,
});
console.log('Policy rules:', policyAccount.rules);Attaching Policy to Transactions
Once a policy is created, transactions targeting the protected program must include a policy check instruction before the target instruction.
import { Transaction } from '@solana/web3.js';
// Create the target instruction (e.g., transfer, swap, etc.)
const targetInstruction = createTargetInstruction({
programId: targetProgramId,
// ... other instruction params
});
// Create policy check instruction
const policyCheckInstruction = await client.createPolicyCheckInstruction({
authority: authorityKeypair.publicKey,
targetProgram: targetProgramId,
signer: signerKeypair.publicKey,
});
// Build transaction with policy check first
const transaction = new Transaction()
.add(policyCheckInstruction)
.add(targetInstruction);
// Sign and send
transaction.feePayer = payerKeypair.publicKey;
transaction.recentBlockhash = (await connection.getLatestBlockhash()).blockhash;
const signature = await connection.sendTransaction(
transaction,
[payerKeypair, signerKeypair]
);
await connection.confirmTransaction(signature);Important
The policy check instruction must precede the target instruction. If the policy check fails, the entire transaction reverts before the target instruction executes.
Execution Validation Lifecycle
The SDK provides utilities for validating policy compliance before submitting transactions, enabling client-side checks and improved user experience.
Pre-Transaction Validation
// Validate before sending transaction
const validationResult = await client.validatePolicyCompliance({
authority: authorityKeypair.publicKey,
targetProgram: targetProgramId,
signer: signerKeypair.publicKey,
transactionData: targetInstruction.data,
});
if (validationResult.compliant) {
console.log('Transaction complies with policy');
// Proceed with transaction
} else {
console.error('Policy violation:', validationResult.reason);
// Handle rejection
}Policy Status Monitoring
// Subscribe to policy account changes
const subscriptionId = connection.onAccountChange(
policyAccountAddress,
(accountInfo) => {
const policy = client.decodePolicy(accountInfo.data);
console.log('Policy updated:', policy);
}
);
// Unsubscribe when done
connection.removeAccountChangeListener(subscriptionId);Advanced Features
Multi-Policy Enforcement
Enforce multiple policies across different programs within a single transaction.
const transaction = new Transaction()
.add(await client.createPolicyCheckInstruction({
authority: authority1,
targetProgram: program1,
signer: signer1.publicKey,
}))
.add(createProgram1Instruction())
.add(await client.createPolicyCheckInstruction({
authority: authority2,
targetProgram: program2,
signer: signer2.publicKey,
}))
.add(createProgram2Instruction());Policy Updates
Update existing policies with new rules while maintaining the same policy account.
await client.updatePolicy({
authority: authorityKeypair,
targetProgram: targetProgramId,
newRules: [
{ type: 'AllowedSigners', signers: [newSigner.publicKey] },
],
});Batch Operations
Create and manage multiple policies efficiently with batch operations.
const policies = [policy1, policy2, policy3];
const signatures = await client.createPoliciesBatch({
policies,
payer: payerKeypair,
authority: authorityKeypair,
});
console.log('Policies created:', signatures);Best Practices
Validate Client-Side Before Submission
Always use pre-transaction validation to check policy compliance before submitting transactions. This improves user experience and reduces failed transaction costs.
Use Multisig for Policy Authority
For production systems, always use a multisig or governance program as the policy authority to prevent single points of failure.
Monitor Policy Account Changes
Subscribe to policy account updates to stay informed of policy modifications and adjust client behavior accordingly.
Test Policies in Devnet First
Always test policy configurations thoroughly in devnet before deploying to mainnet. Policy mistakes can be difficult to reverse.