This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
- Main branch:
main(protected, requires PRs) - Release branch:
release/{id}(requires PRs) - Commit format: Use conventional commits for automatic releases
feat:→ minor version bump (1.0.3 → 1.1.0)fix:→ patch version bump (1.0.3 → 1.0.4)BREAKING CHANGE:→ major version bump (1.0.3 → 2.0.0)chore:,docs:,refactor:→ patch version bump
- Rust crates: Manual release process with synchronized versioning (both kora-lib and kora-cli released together)
- TypeScript SDKs: Changeset-based releases (require
pnpm changeset) - CHANGELOG: Auto-generated from conventional commits using git-cliff
- GitHub releases: Auto-generated with commit-based release notes
Kora is a Solana paymaster node that provides a JSON-RPC interface for handling gasless transactions and fee abstractions. It enables developers to build applications where users can pay transaction fees in tokens other than SOL.
The repository consists of 2 main workspace crates:
kora-lib: Core library with integrated RPC server functionality, signers, transaction handling, and configurationkora-cli: Unified command-line interface with RPC server and configuration commandstests: Integration tests for the entire workspacesdks/: TypeScript SDKs for client integration
Kora supports two authentication methods that can be used individually or together:
- API Key Authentication: Simple header-based auth using
x-api-keyheader - HMAC Authentication: Request signature auth using
x-timestampandx-hmac-signatureheaders
Testing:
make integration-test # Run all integration tests# Build all workspace packages
make build
# Build specific packages
make build-lib # Build the lib crate
make build-cli # Build the CLI tool
# Install all binaries
make install
# Check formatting
make check
# Format code and run linter with auto-fix
make fmt# Run unit tests
make unit-test
# Run integration tests (automatically handles environment setup)
make integration-test
# Run all tests
cargo test --workspaceIntegration tests are fully automated using a Rust test runner binary that handles sequential test execution:
Quick Start:
make integration-testWhat happens automatically:
- Solana Validator: Starts local test validator with reset
- Test Environment Setup: Creates test accounts, tokens, and ATAs
- Sequential Test Phases: Runs 3 test suites with different configurations
Test Phases (Configured in tests/src/test_runner/test_cases.toml):
Regular Tests
- Config:
tests/src/common/fixtures/kora-test.toml(no auth) - Tests: Core RPC functionality, token operations, compute budget
Auth Tests
- Config:
tests/src/common/fixtures/auth-test.toml(auth enabled) - Tests: API key and HMAC authentication validation
Payment Address Tests
- Config:
tests/src/common/fixtures/paymaster-address-test.toml(payment address) - CLI ATA Initialization: Automatically runs
kora rpc initialize-atasbefore tests - Tests: Payment address validation and wrong destination rejection
Multi-Signer Tests
- Config:
tests/src/common/fixtures/signers-multi.toml - Tests: Multiple signer configurations
TypeScript Tests
- Tests: TypeScript SDK integration tests
File Structure:
tests/
├── src/
│ ├── common/
│ │ ├── fixtures/
│ │ │ ├── kora-test.toml # Regular tests config
│ │ │ ├── auth-test.toml # Auth tests config
│ │ │ └── paymaster-address-test.toml # Payment address config
│ │ ├── local-keys/
│ │ │ ├── fee-payer-local.json # Fee payer keypair
│ │ │ ├── payment-local.json # Payment address keypair
│ │ │ ├── sender-local.json # Sender keypair
│ │ │ └── usdc-mint-local.json # USDC mint keypair
│ │ └── setup.rs # Test environment setup
│ ├── test_runner/ # Test runner modules
│ │ ├── accounts.rs # Account management
│ │ ├── commands.rs # Test command execution
│ │ ├── config.rs # Test configuration
│ │ ├── kora.rs # Kora server management
│ │ ├── output.rs # Output handling
│ │ ├── test_cases.toml # Test phase configurations
│ │ └── validator.rs # Solana validator management
│ └── bin/
│ └── test_runner.rs # Main test runner binary
├── integration/ # Regular integration tests
├── auth/ # Authentication tests
└── payment-address/ # Payment address tests
Test Runner Commands:
# Run all integration tests (default)
make integration-test
# Run with verbose output
make integration-test-verbose
# Force refresh test accounts (ignore cached)
make integration-test-fresh
# Run specific test
cargo run -p tests --bin test_runner -- --filter regular
cargo run -p tests --bin test_runner -- --filter auth
cargo run -p tests --bin test_runner -- --filter payment_address
cargo run -p tests --bin test_runner -- --filter multi_signer
cargo run -p tests --bin test_runner -- --filter typescript_basic
cargo run -p tests --bin test_runner -- --filter typescript_authThe test suite uses environment variables for configuration specified in tests/src/common/constants.rs.
Make sure to update the appropriate config file (kora.toml for production, tests/common/fixtures/kora-test.toml for testing) to reflect the public key of TEST_USDC_MINT_KEYPAIR.
# Basic server run (production config)
make run
# Run with test configuration (for integration testing)
cargo run -p kora --bin kora -- --config tests/common/fixtures/kora-test.toml --rpc-url http://127.0.0.1:8899 rpc --signers-config tests/common/fixtures/signers.toml
# Run with debug logging
RUST_LOG=debug cargo run -p kora --bin kora -- rpc start
# Run RPC server with all parameters
cargo run -p kora --bin kora -- --config kora.toml --rpc-url https://api.devnet.solana.com rpc start \
--port 8080 \
--logging-format standard
# Run with Turnkey signer
cargo run -p kora --bin kora -- rpc start --signers-config path/to/turnkey-signers.toml
# Run with Privy signer
cargo run -p kora --bin kora -- rpc start --signers-config path/to/privy-signers.toml
# Run with Vault signer
cargo run -p kora --bin kora -- rpc start \
--signers-config path/to/vault-signers.toml
# Configuration validation commands
cargo run -p kora --bin kora -- config validate
cargo run -p kora --bin kora -- config validate-with-rpc
# Generate OpenAPI documentation
cargo run -p kora --bin kora --features docs -- openapi -o openapi.json# In sdks/ts/
pnpm run build
pnpm run test
pnpm run lint
pnpm run formatKora uses a manual release process with synchronized versioning across all workspace crates. Both kora-lib and kora-cli are always released together with the same version number.
Prerequisites:
# Install required tools
cargo install cargo-edit # For cargo set-version
cargo install git-cliff # For CHANGELOG generationRelease Steps:
-
Prepare Release (on feature branch)
make release
This interactive command will:
- Check working directory is clean
- Prompt for new version (e.g., 2.0.0)
- Update version in workspace
Cargo.toml - Generate
CHANGELOG.mdfrom conventional commits since last release - Commit changes with message:
chore: release v{VERSION}
-
Create PR and Merge
git push origin HEAD
- Create pull request to
main - Get review and merge PR
- Create pull request to
-
Publish to crates.io (after PR merge)
- Go to GitHub Actions
- Manually trigger the "Publish Rust Crates" workflow
- This will:
- Build and verify the workspace
- Read version from
Cargo.toml - Create git tags on main:
v{VERSION}(generic version tag)kora-lib-v{VERSION}(crate-specific tag)kora-cli-v{VERSION}(crate-specific tag)
- Publish
kora-libto crates.io - Wait for indexing
- Publish
kora-clito crates.io
Conventional Commits:
The CHANGELOG is auto-generated from conventional commits. Use these prefixes:
feat:- New features (grouped under "Features")fix:- Bug fixes (grouped under "Bug Fixes")perf:- Performance improvements (grouped under "Performance")refactor:- Code refactoring (grouped under "Refactoring")doc:- Documentation changes (grouped under "Documentation")test:- Test changes (grouped under "Testing")chore:,ci:,build:- Skipped in CHANGELOG
Version Strategy:
Kora uses synchronized versioning where all workspace crates share the same version number:
- Simplifies user understanding ("Kora v2.0.0")
- Ensures compatibility across all components
- Both crates published together in dependency order
GitHub Secrets Required:
KORA_CLI_REGISTRY_TOKEN- crates.io API token for publishing
A Claude skill is available at .claude/skills/release.md that automates the complete release process for both Rust and TypeScript SDK.
What it does:
- Detects release type (beta on
release/*branch, stable onmain) - Detects build system (justfile or Makefile)
- Runs Rust release (updates versions, generates CHANGELOG, stages changes)
- Stashes Rust changes
- Runs TypeScript SDK release (updates package.json, stages changes)
- Unstashes Rust changes to combine both
- Commits everything together
- Creates PR against the appropriate base branch
PR targeting:
- On
release/*branch → PR targets that release branch (beta) - On
main→ PR targetsmain(stable)
Usage: Ask Claude to "run the full release" or "prepare a release for version X.Y.Z"
-
signer/ - Abstraction layer supporting multiple signer types (configured in
signers.toml)SolanaMemorySigner- Local keypair signingVaultSigner- HashiCorp Vault integrationTurnkeySigner- Turnkey API integrationPrivySigner- Privy API integration- Unified
KoraSignerenum with trait implementation - optionally,
--no-signerflag to run Kora without a signer
-
transaction/ - Transaction processing pipeline:
- Fee estimation and calculation
- Transaction validation against configuration rules
- Paid transaction verification
- Solana transaction utilities
- Lookup Table Resolution: V0 transactions require address lookup table resolution for proper fee calculation and validation. The system uses
VersionedTransactionExttrait andVersionedTransactionResolvedwrapper for efficient caching of resolved addresses.
-
token/ - SPL token handling:
- Token interface abstractions (SPL vs Token-2022)
- Token account management
- Token validation and metadata
-
oracle/ - Price feed integration:
- Jupiter API integration for token pricing
- Price calculation for fee estimation
-
config.rs - TOML-based configuration system with validation
-
state.rs - Global signer state management
-
cache.rs - Token account caching
-
rpc.rs - Solana RPC client utilities
-
server.rs - HTTP JSON-RPC server setup with middleware:
- CORS configuration
- Rate limiting
- Proxy layer for health checks
- Uses
jsonrpseefor JSON-RPC protocol
-
method/ - RPC method implementations:
estimateTransactionFee- Calculate gas fees in different tokenssignTransaction- Sign transaction without broadcastingsignAndSendTransaction- Sign and broadcast to networktransferTransaction- Handle token transfersgetBlockhash- Get recent blockhashgetConfig- Return server configurationgetSupportedTokens- List accepted payment tokensgetPayerSigner- Get the payer signer and payment destination- (client-only)
getPaymentInstruction- Get a payment instruction for a transaction
-
openapi/ - Auto-generated API documentation using
utoipa -
args.rs - RPC-specific command line arguments
- Unified command-line interface with subcommands:
kora config validate- Validate configuration filekora config validate-with-rpc- Validate configuration with RPC callskora rpc start --signers-config path/to/signers.toml- Start the RPC server with all signer options (kora.toml in cwd)kora --config path/to/kora.toml rpc start --signers-config path/to/signers.toml- Start the RPC server with specific config and signerskora openapi- Generate OpenAPI documentation
- Global arguments (rpc-url, config) separated from RPC-specific arguments
- All signer types supported for RPC server mode
Example CLI usage:
# Validate configuration
cargo run -p kora --bin kora -- --config kora.toml config validate
# Start RPC server with local private key
cargo run -p kora --bin kora -- --config path/to/kora.toml --rpc-url https://api.devnet.solana.com rpc start --signers-config path/to/signers.toml
# Start RPC server with Turnkey signer
cargo run -p kora --bin kora -- rpc start --signers-config path/to/turnkey-signers.toml
# Generate OpenAPI documentation
cargo run -p kora --bin kora --features docs -- openapi -o openapi.json- kora-turnkey - Turnkey key management API integration (separate crate)
- kora-privy - Privy wallet API integration (separate crate)
- VaultSigner - HashiCorp Vault integration (built into kora-lib)
- Remote signers integrate via HTTP APIs to external services
- sdks/ts/ - Main TypeScript SDK for client integration
- Provide typed interfaces for all RPC methods
[kora]
rate_limit = 100 # Requests per second
[validation]
max_allowed_lamports = 1000000 # Maximum transaction value
max_signatures = 10 # Maximum signatures per transaction
price_source = "Mock" # Price source: "Mock", "Jupiter", etc.
# Allowed Solana programs (by public key)
allowed_programs = [
"11111111111111111111111111111111", # System Program
"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", # Token Program
"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", # Associated Token Program
"AddressLookupTab1e1111111111111111111111111", # Address Lookup Table Program
"ComputeBudget111111111111111111111111111111", # Compute Budget Program
]
# Supported tokens for fee payment (by mint address)
allowed_tokens = [
"4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU", # USDC devnet
]
# SPL tokens accepted for paid transactions
allowed_spl_paid_tokens = [
"4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU", # USDC devnet
]
disallowed_accounts = [] # Blocked account addresses
# Fee payer policy controls what actions the fee payer can perform
# Organized by program type with 28 granular controls
# All default to false for security
[validation.fee_payer_policy.system]
allow_transfer = false # System Transfer/TransferWithSeed
allow_assign = false # System Assign/AssignWithSeed
allow_create_account = false # System CreateAccount/CreateAccountWithSeed
allow_allocate = false # System Allocate/AllocateWithSeed
[validation.fee_payer_policy.system.nonce]
allow_initialize = false # InitializeNonceAccount
allow_advance = false # AdvanceNonceAccount
allow_authorize = false # AuthorizeNonceAccount
allow_withdraw = false # WithdrawNonceAccount
[validation.fee_payer_policy.spl_token]
allow_transfer = false # Transfer/TransferChecked
allow_burn = false # Burn/BurnChecked
allow_close_account = false # CloseAccount
allow_approve = false # Approve/ApproveChecked
allow_revoke = false # Revoke
allow_set_authority = false # SetAuthority
allow_mint_to = false # MintTo/MintToChecked
allow_initialize_mint = false # InitializeMint/InitializeMint2
allow_initialize_account = false # InitializeAccount/InitializeAccount3
allow_initialize_multisig = false # InitializeMultisig/InitializeMultisig2
allow_freeze_account = false # FreezeAccount
allow_thaw_account = false # ThawAccount
[validation.fee_payer_policy.token_2022]
allow_transfer = false # Transfer/TransferChecked
allow_burn = false # Burn/BurnChecked
allow_close_account = false # CloseAccount
allow_approve = false # Approve/ApproveChecked
allow_revoke = false # Revoke
allow_set_authority = false # SetAuthority
allow_mint_to = false # MintTo/MintToChecked
allow_initialize_mint = false # InitializeMint/InitializeMint2
allow_initialize_account = false # InitializeAccount/InitializeAccount3
allow_initialize_multisig = false # InitializeMultisig/InitializeMultisig2
allow_freeze_account = false # FreezeAccount
allow_thaw_account = false # ThawAccountGeneral:
RUST_LOG=debug # Logging levelThe fee payer policy system provides granular control over what actions the fee payer can perform in transactions. The policy is organized by program type (System, SPL Token, Token-2022) and covers 28 different instruction types. By default, all actions are permitted to maintain backward compatibility with existing behavior.
The fee payer policy is configured via nested sections in kora.toml:
[validation.fee_payer_policy.system]- System program instructions (4 fields)[validation.fee_payer_policy.system.nonce]- Nonce account operations (4 fields)[validation.fee_payer_policy.spl_token]- SPL Token program instructions (12 fields)[validation.fee_payer_policy.token_2022]- Token-2022 program instructions (12 fields)
Core Structure (crates/lib/src/config.rs):
FeePayerPolicystruct with nested policy structs for each program typeSystemInstructionPolicy- Controls System program operations including nestedNonceInstructionPolicySplTokenInstructionPolicy- Controls SPL Token program operationsToken2022InstructionPolicy- Controls Token-2022 program operations- All
Defaultimplementations set fields totrue(permissive) for backward compatibility #[serde(default)]attribute ensures backward compatibility
Validation Logic (crates/lib/src/transaction/validator.rs):
TransactionValidatorstores the policy configuration- Program-specific validation methods check policy flags before validating restrictions
- Uses macro-based validation patterns for consistent enforcement across instruction types
- Different validation logic for each program type (System, SPL Token, Token2022)
Supported Actions by Program Type:
System Program (8 controls):
- Transfer - Transfer and TransferWithSeed instructions (fee payer as sender)
- Assign - Assign and AssignWithSeed instructions (fee payer as authority)
- CreateAccount - CreateAccount and CreateAccountWithSeed instructions (fee payer as funding source)
- Allocate - Allocate and AllocateWithSeed instructions (fee payer as account owner)
- Nonce Initialize - InitializeNonceAccount instruction (fee payer set as authority)
- Nonce Advance - AdvanceNonceAccount instruction (fee payer as authority)
- Nonce Authorize - AuthorizeNonceAccount instruction (fee payer as current authority)
- Nonce Withdraw - WithdrawNonceAccount instruction (fee payer as authority)
SPL Token Program (12 controls):
- Transfer - Transfer and TransferChecked instructions (fee payer as owner)
- Burn - Burn and BurnChecked instructions (fee payer as owner)
- CloseAccount - CloseAccount instruction (fee payer as owner)
- Approve - Approve and ApproveChecked instructions (fee payer as owner)
- Revoke - Revoke instruction (fee payer as owner)
- SetAuthority - SetAuthority instruction (fee payer as current authority)
- MintTo - MintTo and MintToChecked instructions (fee payer as mint authority)
- InitializeMint - InitializeMint and InitializeMint2 instructions (fee payer as mint authority)
- InitializeAccount - InitializeAccount and InitializeAccount3 instructions (fee payer as owner)
- InitializeMultisig - InitializeMultisig and InitializeMultisig2 instructions (fee payer as signer)
- FreezeAccount - FreezeAccount instruction (fee payer as freeze authority)
- ThawAccount - ThawAccount instruction (fee payer as freeze authority)
Token-2022 Program (12 controls):
- Identical instruction set and controls as SPL Token Program
Kora supports multiple private key formats for enhanced usability and compatibility with different tooling, each specified in signers.toml
Traditional Solana private key format - base58-encoded 64-byte private key:
KORA_PRIVATE_KEY=your_base58_private_keyComma-separated byte array format compatible with Solana CLI outputs:
KORA_PRIVATE_KEY="[123,45,67,89,12,34,56,78,90,12,34,56,78,90,12,34,56,78,90,12,34,56,78,90,12,34,56,78,90,12,34,56,78,90,12,34,56,78,90,12,34,56,78,90,12,34,56,78,90,12,34,56,78,90,12,34,56]"Path to a JSON file containing the private key:
KORA_PRIVATE_KEY="/path/to/keypair.json"The system automatically detects the format based on input patterns:
- File path - Attempts to read as file first
- U8Array - Detects
[...]format - Base58 - Default fallback format
All private key environment variables support the same multiple formats.
Kora handles both legacy and V0 versioned transactions. V0 transactions use address lookup tables to compress transaction size by referencing frequently used addresses. Before processing V0 transactions for fee calculation or validation, these lookup tables must be resolved to get the actual addresses.
Trait-Based Abstraction: The system uses the VersionedTransactionExt trait to provide a unified interface for both legacy and V0 transactions:
pub trait VersionedTransactionExt {
fn get_all_account_keys(&self) -> Vec<Pubkey>;
fn get_transaction(&self) -> &VersionedTransaction;
}Caller Responsibility Pattern: Following Rust best practices, the system uses caller responsibility where expensive operations (RPC calls to resolve lookup tables) are explicit:
VersionedTransaction- Implements trait directly, returns only static account keysVersionedTransactionResolved<'a>- Wrapper that caches resolved addresses after callingresolve_addresses(rpc_client).await
- Client Request - Client submits transaction to RPC endpoint
- Validation - Transaction validated against configuration rules including fee payer policy
- Fee Calculation - Fee calculated based on token type and current prices
- Signing - Transaction signed using configured signer backend
- Response - Signed transaction returned or broadcast to network
- Trait-based design - All signers implement unified
Signertrait - State management - Global signer state with thread-safe access via
get_signer() - Multiple backends - Runtime selection between Memory, Vault, Turnkey, Privy
- Initialization - Lazy initialization with validation on first use
- API Integration - Turnkey and Privy use HTTP APIs for remote signing
- All RPC methods are async
- Use
tokioruntime for async execution - Signer operations are async to support remote API calls
Kora is designed for high-performance concurrent operations:
- Global State Management: Use
Arc<Mutex<T>>for shared state across threads - Signer State: Global signer accessed via
get_signer()with thread-safe initialization - RPC Server: Handles multiple concurrent requests using
jsonrpseeasync framework - Cache Operations:
TokenAccountCachesupports concurrent access for token account lookups - Token Account Access: Always prioritize cache lookups before making on-chain RPC calls
All I/O operations and external API calls are async:
- RPC Client Operations: Solana RPC calls are async to avoid blocking
- Remote Signer APIs: Turnkey and Privy API calls are async HTTP requests
- Database Operations: Token cache operations are async
- Error Propagation: Use
?operator with async functions
Use structured logging throughout the codebase:
- Error Level (
log::error!): System failures, critical errors, panics - Warn Level (
log::warn!): Recoverable errors, validation failures - Info Level (
log::info!): Important state changes, successful operations - Debug Level (
log::debug!): Detailed execution flow, parameter values - Trace Level (
log::trace!): Very verbose debugging information
Logging Guidelines:
- Include relevant context (transaction IDs, user addresses, amounts)
- Log entry and exit points for important operations
- Use structured data when possible for better parsing
- Never log sensitive information (private keys, secrets)
- Log errors with full context for debugging
- CLI Output: Use
println!for CLI command results and user-facing output (notlog::info!)
- Error Transformation: Convert external errors to
KoraErrorat module boundaries - Error Context: Add meaningful context when propagating errors up the call stack
- Error Classification: Distinguish between recoverable validation errors and critical system failures
- Error Responses: Structure JSON-RPC error responses consistently across all methods
- Memory Allocation: Minimize allocations in hot paths, reuse buffers where possible
- Connection Pooling: Reuse HTTP clients and RPC connections across requests
- Batch Operations: Prefer batch APIs when available for multiple token account operations
- Rate Limiting: Implement client-side rate limiting for external API calls
- Secret Handling: Never log, print, or serialize sensitive data (keys, tokens, secrets)
- Input Sanitization: Validate all user inputs against allow-lists and size limits
- Audit Trail: Log security-relevant events (authentication, authorization, signing)
- Fail Secure: Default to restrictive behavior when validation or authentication fails
- Secure Communication: Use secure communication for remote signer APIs
- Rate Limiting & Authentication: Implement proper rate limiting and authentication
Kora supports two optional authentication methods:
- API Key Auth (
api_keyin kora.toml): Simple header-based auth usingx-api-key - HMAC Auth (
hmac_secretin kora.toml): Secure signature-based auth usingx-timestamp+x-hmac-signature(SHA256 of timestamp+body)
Both skip /liveness endpoint and can be used simultaneously. Implementation uses async tower middleware for non-blocking concurrent requests.
- Test Organization: Mirror source code structure in test file organization
- Mock Strategy: Mock external dependencies (RPC clients, HTTP APIs) consistently
- Test Data: Use deterministic test data, avoid random values in tests
- Integration Coverage: Test complete request/response cycles for all RPC methods
- Error Scenarios: Test error conditions and edge cases, not just happy paths
- Unit tests - Located in
src/directories alongside source code - Integration tests - Located in
tests/directory for end-to-end workflows - API tests - Include example JSON payloads in
tests/examples/ - SDK tests - TypeScript tests in
sdks/*/test/directories
The project uses a Rust-based test runner for integration testing:
/tests/src/
├── bin/test_runner.rs # Main test runner binary
├── test_runner/ # Test runner modules
│ ├── test_cases.toml # Test phase configurations
│ ├── accounts.rs # Account management & caching
│ ├── commands.rs # Test execution logic
│ ├── kora.rs # Kora server lifecycle
│ └── validator.rs # Solana validator management
└── common/ # Shared test utilities
Key Features:
- Rust Test Runner: Single binary manages all test phases
- TOML Configuration: Test phases defined in
test_cases.toml - Account Caching: Reuses test accounts for faster execution
- Isolated Ports: Each test phase uses unique ports to avoid conflicts
- TypeScript Integration: Seamlessly runs TS SDK tests alongside Rust tests
- Always run linting and formatting commands before committing
- Use the Makefile targets for consistent builds across the workspace
- Test both unit and integration levels when making changes
- Verify TypeScript SDK compatibility when changing RPC interfaces
- Follow existing patterns for RPC method implementations
- Add new signer types by implementing the
Signertrait - Update configuration schema when adding new validation rules
- Keep OpenAPI documentation in sync with method signatures
✅ Complete Sequential Test Runner
- Makefile-based orchestration with 3 automated phases
- Proper server lifecycle management (start/stop/restart)
- Config isolation between test suites
- Zero manual intervention required
✅ CLI Integration for Payment Address Tests
- Automated
kora rpc initialize-atasexecution before payment tests - Real-world workflow simulation (CLI → tests)
- Payment address ATA creation and validation
✅ Payment Validation Testing
- Tests payment address validation logic (not transaction simulation)
- Proper positive/negative test cases:
- ✅ Transfer to payment address → should succeed
- ✅ Transfer to wrong destination → should fail validation
- Removed transaction simulation dependency (caused AccountNotFound issues)
✅ Test Infrastructure
- File reorganization:
tests/src/common/structure for proper Rust crate organization - Config files:
kora-test.toml,auth-test.toml,paymaster-address-test.toml - Binary setup:
setup_test_envbinary for account/token initialization - Path resolution fixes for workspace vs. crate directory differences
Test Results:
- Integration tests: 26/26 passed ✅
- Auth tests: 4/4 passed ✅
- Payment address tests: 2/2 passed ✅
- CLI ATA initialization: Working ✅