|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Essential Commands |
| 6 | + |
| 7 | +### Linting |
| 8 | +```bash |
| 9 | +make lint # Run golangci-lint (auto-installs if missing) |
| 10 | +make lint-fix # Run gofmt to fix formatting issues |
| 11 | +``` |
| 12 | + |
| 13 | +### Testing |
| 14 | +```bash |
| 15 | +# Unit tests |
| 16 | +make test-ci # Run all unit tests (CI mode, clean cache, parallel) |
| 17 | +make test-all # Run all unit tests (standard mode) |
| 18 | + |
| 19 | +# Package-specific tests |
| 20 | +make test-binary-codec # Test binary-codec package |
| 21 | +make test-address-codec # Test address-codec package |
| 22 | +make test-keypairs # Test keypairs package |
| 23 | +make test-xrpl # Test xrpl package |
| 24 | + |
| 25 | +# Integration tests (require running network) |
| 26 | +make run-localnet-linux/amd64 # Start local rippled node (amd64) |
| 27 | +make run-localnet-linux/arm64 # Start local rippled node (arm64) |
| 28 | +make test-integration-localnet # Run integration tests on localnet |
| 29 | +make test-integration-devnet # Run integration tests on devnet |
| 30 | +make test-integration-testnet # Run integration tests on testnet |
| 31 | + |
| 32 | +# Coverage and benchmarks |
| 33 | +make coverage-unit # Generate coverage report (coverage.html) |
| 34 | +make benchmark # Run benchmarks |
| 35 | +``` |
| 36 | + |
| 37 | +### Running Single Tests |
| 38 | +```bash |
| 39 | +# Run specific test file |
| 40 | +go test ./xrpl/transaction/payment_test.go |
| 41 | + |
| 42 | +# Run specific test function |
| 43 | +go test -run TestPayment ./xrpl/transaction |
| 44 | + |
| 45 | +# Run with verbose output |
| 46 | +go test -v ./xrpl/transaction |
| 47 | + |
| 48 | +# Run integration tests (set INTEGRATION env var) |
| 49 | +INTEGRATION=localnet go test ./xrpl/transaction/integration -v |
| 50 | +``` |
| 51 | + |
| 52 | +## Architecture Overview |
| 53 | + |
| 54 | +### Package Structure |
| 55 | + |
| 56 | +The repository follows a modular architecture with four primary layers: |
| 57 | + |
| 58 | +1. **Low-level cryptographic primitives** (`address-codec/`, `keypairs/`, `binary-codec/`) |
| 59 | + - `address-codec/`: Encodes/decodes XRPL addresses using Base58Check |
| 60 | + - `keypairs/`: Cryptographic key generation and management (secp256k1, ed25519) |
| 61 | + - `binary-codec/`: Binary serialization/deserialization of XRPL objects |
| 62 | + - `definitions/`: Field type definitions from XRPL protocol |
| 63 | + - `serdes/`: Serialization/deserialization logic |
| 64 | + - `types/`: Type implementations for each XRPL field type |
| 65 | + |
| 66 | +2. **Core XRPL functionality** (`xrpl/`) |
| 67 | + - `transaction/`: All transaction types and transaction handling |
| 68 | + - Each transaction type has its own file (e.g., `payment.go`, `account_set.go`) |
| 69 | + - `BaseTx` struct contains common fields for all transactions |
| 70 | + - All transactions implement `Tx` interface with `TxType()` method |
| 71 | + - `integration/` subdirectory contains integration tests |
| 72 | + - `rpc/`: JSON-RPC client for synchronous requests to rippled nodes |
| 73 | + - `websocket/`: WebSocket client for real-time subscriptions and async requests |
| 74 | + - `wallet/`: Wallet creation, derivation from seed/mnemonic, and offline signing |
| 75 | + - `queries/`: Query request/response types for ledger data |
| 76 | + - `ledger-entry-types/`: Types for different ledger objects |
| 77 | + - `hash/`, `time/`, `currency/`, `common/`: Utilities for XRPL-specific data types |
| 78 | + |
| 79 | +3. **Internal utilities** (`pkg/`) |
| 80 | + - Shared utilities that don't depend on XRPL-specific logic |
| 81 | + - `crypto/`, `big-decimal/`, `map_utils/`, `random/`, `typecheck/` |
| 82 | + |
| 83 | +4. **Examples and documentation** (`examples/`, `docs/`) |
| 84 | + - `examples/` contains working examples for each major feature |
| 85 | + - Each example is self-contained in its own directory |
| 86 | + |
| 87 | +### Key Design Patterns |
| 88 | + |
| 89 | +#### Interfaces and Abstractions |
| 90 | +- Each major package has an `interfaces/` subdirectory defining contracts |
| 91 | +- Enables dependency injection and testing with mocks |
| 92 | +- See `xrpl/interfaces/`, `keypairs/interfaces/`, etc. |
| 93 | + |
| 94 | +#### Test Organization |
| 95 | +- `testutil/` directories provide test helpers and fixtures for each package |
| 96 | +- Unit tests exclude: `faucet/`, `examples/`, `testutil/`, `interfaces/` |
| 97 | +- Integration tests in `xrpl/transaction/integration/` require live network |
| 98 | +- Use `golang/mock` for generating mocks |
| 99 | + |
| 100 | +#### Type Safety |
| 101 | +- Transaction types use specific Go types from `xrpl/transaction/types/` |
| 102 | +- Currency amounts distinguish between XRP (drops) and issued currencies |
| 103 | +- Address validation through `addresscodec` package |
| 104 | + |
| 105 | +### Client Usage Pattern |
| 106 | + |
| 107 | +Two primary client types for interacting with XRPL: |
| 108 | + |
| 109 | +1. **RPC Client** (`xrpl/rpc/`): Synchronous JSON-RPC requests |
| 110 | + - Used for one-off queries and transaction submission |
| 111 | + - Methods in `queries.go` map to rippled API methods |
| 112 | + |
| 113 | +2. **WebSocket Client** (`xrpl/websocket/`): Asynchronous connections |
| 114 | + - Used for subscriptions and real-time data |
| 115 | + - Supports streaming ledger updates, transaction monitoring |
| 116 | + - Methods in `queries.go` and subscription handlers in `subscription.go` |
| 117 | + |
| 118 | +Both clients share similar query interfaces but differ in connection management. |
| 119 | + |
| 120 | +### Transaction Lifecycle |
| 121 | + |
| 122 | +1. **Create**: Construct transaction struct (e.g., `Payment`, `AccountSet`) |
| 123 | +2. **Autofill**: Set `Fee`, `Sequence`, `LastLedgerSequence` (via RPC/WebSocket client helpers) |
| 124 | +3. **Sign**: Use `wallet.Sign()` to add signature |
| 125 | +4. **Encode**: Serialize with `binarycodec.Encode()` for submission |
| 126 | +5. **Submit**: Send via `rpc.Submit()` or `websocket.Submit()` |
| 127 | +6. **Monitor**: Wait for validation and check result |
| 128 | + |
| 129 | +See `examples/send-xrp/` or `examples/send-payment/` for complete workflows. |
| 130 | + |
| 131 | +## Important Development Notes |
| 132 | + |
| 133 | +### Test Exclusions |
| 134 | +The Makefile excludes certain packages from standard test runs: |
| 135 | +- `faucet/` - Interacts with external testnet faucets |
| 136 | +- `examples/` - Standalone example code, not library tests |
| 137 | +- `testutil/` - Test helpers, not tests themselves |
| 138 | +- `interfaces/` - Interface definitions only |
| 139 | + |
| 140 | +### Integration Tests |
| 141 | +Integration tests require `INTEGRATION` environment variable: |
| 142 | +- `localnet`: Requires local rippled node (Docker) |
| 143 | +- `devnet`: Uses XRPL devnet |
| 144 | +- `testnet`: Uses XRPL testnet |
| 145 | + |
| 146 | +Start localnet with `make run-localnet-linux/amd64` before running integration tests. |
| 147 | + |
| 148 | +### Lint Configuration |
| 149 | +- Uses `golangci-lint v2.2.2` (configured in Makefile) |
| 150 | +- Config in `.golangci.yml` enables: govet, errcheck, staticcheck, gosec, etc. |
| 151 | +- Excludes package-comments linter for examples/ |
| 152 | + |
| 153 | +### Binary Codec |
| 154 | +The binary codec is critical for transaction signing and submission: |
| 155 | +- Canonical field ordering defined in `binary-codec/definitions/` |
| 156 | +- Type serializers in `binary-codec/types/` |
| 157 | +- Always use `binarycodec.Encode()` for creating transaction blobs |
| 158 | +- Use `binarycodec.EncodeForSigning()` when preparing transactions for signature |
| 159 | + |
| 160 | +### Common Gotchas |
| 161 | +- XRP amounts are always in "drops" (1 XRP = 1,000,000 drops) |
| 162 | +- Transaction `Fee` must be set before signing |
| 163 | +- `Sequence` numbers must be consecutive (or use Tickets) |
| 164 | +- `LastLedgerSequence` prevents transaction from staying in queue indefinitely |
| 165 | +- Address encoding differs between classic addresses and X-addresses |
0 commit comments