solace 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +0 -0
  3. data/LICENSE +0 -0
  4. data/README.md +661 -0
  5. data/lib/solace/address_lookup_table.rb +50 -0
  6. data/lib/solace/concerns/binary_serializable.rb +30 -0
  7. data/lib/solace/connection.rb +187 -0
  8. data/lib/solace/constants.rb +52 -0
  9. data/lib/solace/instruction.rb +38 -0
  10. data/lib/solace/instructions/associated_token_account/create_associated_token_account_instruction.rb +68 -0
  11. data/lib/solace/instructions/spl_token/initialize_account_instruction.rb +46 -0
  12. data/lib/solace/instructions/spl_token/initialize_mint_instruction.rb +68 -0
  13. data/lib/solace/instructions/spl_token/mint_to_instruction.rb +48 -0
  14. data/lib/solace/instructions/spl_token/transfer_instruction.rb +48 -0
  15. data/lib/solace/instructions/system_program/create_account_instruction.rb +58 -0
  16. data/lib/solace/instructions/transfer_checked_instruction.rb +58 -0
  17. data/lib/solace/instructions/transfer_instruction.rb +48 -0
  18. data/lib/solace/keypair.rb +121 -0
  19. data/lib/solace/message.rb +95 -0
  20. data/lib/solace/programs/associated_token_account.rb +96 -0
  21. data/lib/solace/programs/base.rb +22 -0
  22. data/lib/solace/programs/spl_token.rb +187 -0
  23. data/lib/solace/public_key.rb +74 -0
  24. data/lib/solace/serializable_record.rb +26 -0
  25. data/lib/solace/serializers/address_lookup_table_deserializer.rb +62 -0
  26. data/lib/solace/serializers/address_lookup_table_serializer.rb +54 -0
  27. data/lib/solace/serializers/base.rb +31 -0
  28. data/lib/solace/serializers/base_deserializer.rb +56 -0
  29. data/lib/solace/serializers/base_serializer.rb +52 -0
  30. data/lib/solace/serializers/instruction_deserializer.rb +62 -0
  31. data/lib/solace/serializers/instruction_serializer.rb +54 -0
  32. data/lib/solace/serializers/message_deserializer.rb +116 -0
  33. data/lib/solace/serializers/message_serializer.rb +95 -0
  34. data/lib/solace/serializers/transaction_deserializer.rb +49 -0
  35. data/lib/solace/serializers/transaction_serializer.rb +60 -0
  36. data/lib/solace/transaction.rb +98 -0
  37. data/lib/solace/utils/codecs.rb +220 -0
  38. data/lib/solace/utils/curve25519_dalek.rb +59 -0
  39. data/lib/solace/utils/libcurve25519_dalek-linux/libcurve25519_dalek.so +0 -0
  40. data/lib/solace/utils/libcurve25519_dalek-macos/libcurve25519_dalek.dylib +0 -0
  41. data/lib/solace/utils/libcurve25519_dalek-windows/curve25519_dalek.dll +0 -0
  42. data/lib/solace/utils/pda.rb +100 -0
  43. data/lib/solace/version.rb +5 -0
  44. data/lib/solace.rb +39 -0
  45. metadata +165 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 78ff45cbaff80411dfec8433e478a0b7a97caea5fb97ae6b8159e2ea7fa409fc
4
+ data.tar.gz: 13c025072948cc13dfc61d0d7c431df5ae4af90bcca76e239d1fff6cb0033d4f
5
+ SHA512:
6
+ metadata.gz: 6d7dfe812cbe1a44275a6a62d36555cdf666e838d1ed37777efc9072bd91605ac4e0a8fca931a29405c387944c3bcef5c949022c21af762dfba09e7e6ab2530d
7
+ data.tar.gz: 181f9c5eb217ad0499b76f6e0052e3f9131d46c12c76583f8a3b1ad05d10274347158512e490656ed41c0c44a07b7645648b0e89b956de8691bf2b4916eebdd6
data/CHANGELOG ADDED
File without changes
data/LICENSE ADDED
File without changes
data/README.md ADDED
@@ -0,0 +1,661 @@
1
+ # Solace Ruby SDK Documentation
2
+
3
+ ## Overview
4
+
5
+ **Solace** is a comprehensive Ruby SDK for interacting with the Solana blockchain. It provides both low-level building blocks and high-level abstractions for creating, signing, and sending Solana transactions. The library follows Ruby conventions while maintaining compatibility with Solana's binary protocols.
6
+
7
+ ## Architecture
8
+
9
+ The Solace SDK is organized into several key layers:
10
+
11
+ ### 1. **Core Primitives** (Low-Level)
12
+ - **Keypair/PublicKey**: Ed25519 cryptographic operations
13
+ - **Connection**: RPC client for Solana nodes
14
+ - **Transaction/Message/Instruction**: Transaction building blocks
15
+ - **Serializers**: Binary serialization/deserialization system
16
+
17
+ ### 2. **Instruction Builders** (Low-Level)
18
+ - Service objects that build specific instruction types
19
+ - Handle binary data encoding and account indexing
20
+ - Located in `lib/solace/instructions/`
21
+
22
+ ### 3. **Program Clients** (High-Level)
23
+ - Convenient interfaces for interacting with on-chain programs
24
+ - Handle transaction assembly, signing, and submission
25
+ - Located in `lib/solace/programs/`
26
+
27
+ ### 4. **Utilities** (Supporting)
28
+ - **Codecs**: Base58/Base64 encoding, compact integers, little-endian encoding
29
+ - **PDA**: Program Derived Address generation
30
+ - **Curve25519**: Native curve operations via FFI
31
+
32
+ ## Core Components
33
+
34
+ ### Keypair
35
+
36
+ The `Solace::Keypair` class represents Ed25519 keypairs for signing transactions.
37
+
38
+ ```ruby
39
+ # Generate a new random keypair
40
+ keypair = Solace::Keypair.generate
41
+
42
+ # Create from seed (32 bytes)
43
+ seed = SecureRandom.random_bytes(32)
44
+ keypair = Solace::Keypair.from_seed(seed)
45
+
46
+ # Create from secret key (64 bytes)
47
+ keypair = Solace::Keypair.from_secret_key(secret_key_bytes)
48
+
49
+ # Usage
50
+ puts keypair.address # Base58 public key
51
+ signature = keypair.sign(message) # Sign binary data
52
+ ```
53
+
54
+ **Key Features:**
55
+ - Ed25519 signature support via RbNaCl
56
+ - Base58 address encoding
57
+ - Secure random generation
58
+ - Compatible with Solana's key format
59
+
60
+ ### PublicKey
61
+
62
+ The `Solace::PublicKey` class represents Solana public keys with utility methods.
63
+
64
+ ```ruby
65
+ # Create from bytes
66
+ pubkey = Solace::PublicKey.new(32_byte_array)
67
+
68
+ # Usage
69
+ puts pubkey.to_base58 # Base58 representation
70
+ puts pubkey.to_s # Same as to_base58
71
+ bytes = pubkey.to_bytes # Get raw bytes
72
+ ```
73
+
74
+ **Key Features:**
75
+ - 32-byte Ed25519 public keys
76
+ - Base58 encoding/decoding
77
+ - PDA (Program Derived Address) support via mixin
78
+ - Equality comparison
79
+
80
+ ### Connection
81
+
82
+ The `Solace::Connection` class provides RPC communication with Solana nodes.
83
+
84
+ ```ruby
85
+ # Connect to local validator (default = http://localhost:8899)
86
+ connection = Solace::Connection.new
87
+
88
+ # Connect to devnet or other RPC nodes
89
+ connection = Solace::Connection.new('https://api.devnet.solana.com')
90
+
91
+ # RPC methods
92
+ balance = connection.get_balance(pubkey)
93
+ blockhash = connection.get_latest_blockhash
94
+ account_info = connection.get_account_info(pubkey)
95
+ signature = connection.send_transaction(transaction)
96
+
97
+ # Airdrop (devnet/testnet only)
98
+ response = connection.request_airdrop(pubkey, 1_000_000_000) # 1 SOL
99
+ connection.wait_for_confirmed_signature { response['result'] }
100
+ ```
101
+
102
+ **Key Features:**
103
+ - JSON-RPC 2.0 client
104
+ - Automatic request ID generation
105
+ - Built-in error handling
106
+ - Support for all major RPC methods
107
+ - Transaction confirmation waiting
108
+
109
+ ### Transaction & Message
110
+
111
+ Transactions contain a message and signatures. Messages contain instructions and metadata.
112
+
113
+ ```ruby
114
+ # Create a message
115
+ message = Solace::Message.new(
116
+ header: [
117
+ 1, # required_signatures
118
+ 0, # readonly_signed
119
+ 1 # readonly_unsigned
120
+ ],
121
+ accounts: [
122
+ payer.address,
123
+ recipient.address,
124
+ system_program_id
125
+ ],
126
+ instructions: [transfer_instruction],
127
+ recent_blockhash: connection.get_latest_blockhash,
128
+ )
129
+
130
+ # Create and sign transaction
131
+ transaction = Solace::Transaction.new(message: message)
132
+ transaction.sign(payer_keypair)
133
+
134
+ # Send transaction
135
+ signature = connection.send_transaction(transaction.serialize)
136
+ ```
137
+
138
+ **Key Features:**
139
+ - Legacy and versioned transaction support
140
+ - Automatic signature management
141
+ - Binary serialization/deserialization
142
+ - Address lookup table support (versioned)
143
+
144
+ ### Instruction
145
+
146
+ Instructions represent individual operations within a transaction.
147
+
148
+ ```ruby
149
+ instruction = Solace::Instruction.new(
150
+ program_index: 2, # Index in accounts array
151
+ accounts: [0, 1], # Account indices
152
+ data: [2, 0, 0, 0] + amount_bytes # Instruction data
153
+ )
154
+
155
+ # All instructions have accessor methods for program_index, accounts, and data
156
+ instruction.program_index # => 2
157
+ instruction.accounts # => [0, 1]
158
+ instruction.data # => [2, 0, 0, 0] + amount_bytes
159
+ ```
160
+
161
+ **Key Features:**
162
+ - Program index referencing
163
+ - Account index arrays
164
+ - Binary data payload
165
+ - Serializable format
166
+
167
+ ## Low-Level Instruction Builders
168
+
169
+ Instruction builders are service objects that create specific instruction types. They handle the binary encoding required by Solana programs.
170
+
171
+ ### System Program Instructions
172
+
173
+ #### Transfer Instruction
174
+
175
+ ```ruby
176
+ # Build a SOL transfer instruction
177
+ transfer_ix = Solace::Instructions::TransferInstruction.build(
178
+ lamports: 1_000_000, # 0.001 SOL
179
+ from_index: 0, # Sender account index
180
+ to_index: 1, # Recipient account index
181
+ program_index: 2 # System program index
182
+ )
183
+ ```
184
+
185
+ #### Create Account Instruction
186
+
187
+ ```ruby
188
+ # Build account creation instruction
189
+ create_ix = Solace::Instructions::SystemProgram::CreateAccountInstruction.build(
190
+ from_index: 0, # Payer account index
191
+ new_account_index: 1, # New account index
192
+ system_program_index: 2, # System program index
193
+ lamports: rent_lamports, # Rent-exempt amount
194
+ space: 165, # Account data size
195
+ owner: token_program_id # Owning program
196
+ )
197
+ ```
198
+
199
+ ### SPL Token Instructions
200
+
201
+ #### Initialize Mint Instruction
202
+
203
+ ```ruby
204
+ # Initialize a new token mint
205
+ init_mint_ix = Solace::Instructions::SplToken::InitializeMintInstruction.build(
206
+ mint_account_index: 1, # Mint account index
207
+ rent_sysvar_index: 2, # Rent sysvar index
208
+ program_index: 3, # Token program index
209
+ decimals: 6, # Token decimals
210
+ mint_authority: authority_pubkey,
211
+ freeze_authority: freeze_pubkey # Optional
212
+ )
213
+ ```
214
+
215
+ #### Mint To Instruction
216
+
217
+ ```ruby
218
+ # Mint tokens to an account
219
+ mint_to_ix = Solace::Instructions::SplToken::MintToInstruction.build(
220
+ amount: 1_000_000, # Amount to mint
221
+ mint_index: 0, # Mint account index
222
+ destination_index: 1, # Destination token account
223
+ mint_authority_index: 2, # Mint authority index
224
+ program_index: 3 # Token program index
225
+ )
226
+ ```
227
+
228
+ #### Transfer Instruction
229
+
230
+ ```ruby
231
+ # Transfer tokens between accounts
232
+ transfer_ix = Solace::Instructions::SplToken::TransferInstruction.build(
233
+ amount: 500_000, # Amount to transfer
234
+ source_index: 0, # Source token account
235
+ destination_index: 1, # Destination token account
236
+ owner_index: 2, # Owner/authority index
237
+ program_index: 3 # Token program index
238
+ )
239
+ ```
240
+
241
+ **Common Patterns:**
242
+ - All builders use `.build()` class method
243
+ - Account indices reference the transaction's accounts array
244
+ - Binary data encoding handled automatically
245
+ - Instruction-specific data layouts documented in comments
246
+
247
+ ## High-Level Program Methods
248
+
249
+ Program clients provide convenient interfaces for common operations, handling transaction assembly, signing, and submission.
250
+
251
+ ### SPL Token Program
252
+
253
+ ```ruby
254
+ # Initialize program client
255
+ spl_token = Solace::Programs::SplToken.new(connection: connection)
256
+
257
+ # Create a new token mint
258
+ signature = spl_token.create_mint(
259
+ payer: payer_keypair,
260
+ decimals: 6,
261
+ mint_authority: authority_keypair,
262
+ freeze_authority: freeze_keypair, # Optional
263
+ mint_keypair: mint_keypair # Optional, generates if not provided
264
+ )
265
+
266
+ # Mint tokens to an account
267
+ signature = spl_token.mint_to(
268
+ payer: payer_keypair,
269
+ mint: mint_keypair,
270
+ destination: token_account_address,
271
+ amount: 1_000_000,
272
+ mint_authority: authority_keypair
273
+ )
274
+
275
+ # Transfer tokens
276
+ signature = spl_token.transfer(
277
+ payer: payer_keypair,
278
+ source: source_token_account,
279
+ destination: dest_token_account,
280
+ amount: 500_000,
281
+ owner: owner_keypair
282
+ )
283
+ ```
284
+
285
+ **Key Features:**
286
+ - Automatic transaction assembly
287
+ - Built-in signing and submission
288
+ - Error handling and validation
289
+ - Sensible defaults for common operations
290
+ - Returns transaction signatures
291
+
292
+ ### Prepare Methods
293
+
294
+ For more control, use "prepare" methods that return signed transactions without sending:
295
+
296
+ ```ruby
297
+ # Prepare transaction without sending
298
+ transaction = spl_token.prepare_create_mint(
299
+ payer: payer_keypair,
300
+ decimals: 6,
301
+ mint_authority: authority_keypair,
302
+ freeze_authority: nil,
303
+ mint_keypair: mint_keypair
304
+ )
305
+
306
+ # Inspect or modify transaction before sending
307
+ puts transaction.serialize # Base64 transaction
308
+ signature = connection.send_transaction(transaction.serialize)
309
+ ```
310
+
311
+ ## Serialization System
312
+
313
+ Solace uses a serialization system for converting Ruby objects to/from Solana's binary format.
314
+
315
+ ### SerializableRecord Base Class
316
+
317
+ ```ruby
318
+ class Transaction < Solace::SerializableRecord
319
+ SERIALIZER = Solace::Serializers::TransactionSerializer
320
+ DESERIALIZER = Solace::Serializers::TransactionDeserializer
321
+
322
+ # Automatic serialization
323
+ def serialize
324
+ self.class::SERIALIZER.call(self)
325
+ end
326
+
327
+ # Automatic deserialization
328
+ def self.deserialize(io)
329
+ self::DESERIALIZER.call(io)
330
+ end
331
+ end
332
+ ```
333
+
334
+ ### Serializer Pattern
335
+
336
+ ```ruby
337
+ class TransactionSerializer < Solace::Serializers::Base
338
+ STEPS = %i[
339
+ serialize_signatures
340
+ serialize_message
341
+ ].freeze
342
+
343
+ def serialize_signatures
344
+ # Convert signatures to binary format
345
+ end
346
+
347
+ def serialize_message
348
+ # Serialize message component
349
+ end
350
+ end
351
+ ```
352
+
353
+ **Key Features:**
354
+ - Step-based serialization process
355
+ - Automatic Base64 encoding
356
+ - Consistent error handling
357
+ - Reversible serialization/deserialization
358
+
359
+ ## Utility Modules
360
+
361
+ ### Codecs
362
+
363
+ The `Solace::Utils::Codecs` module provides encoding/decoding utilities for Solana data types.
364
+
365
+ ```ruby
366
+ # Base58 operations
367
+ base58_string = Solace::Utils::Codecs.bytes_to_base58(bytes)
368
+ bytes = Solace::Utils::Codecs.base58_to_bytes(base58_string)
369
+
370
+ # Compact u16 encoding (ShortVec)
371
+ encoded = Solace::Utils::Codecs.encode_compact_u16(1234)
372
+ value, bytes_read = Solace::Utils::Codecs.decode_compact_u16(io)
373
+
374
+ # Little-endian u64
375
+ encoded = Solace::Utils::Codecs.encode_le_u64(amount)
376
+ value = Solace::Utils::Codecs.decode_le_u64(io)
377
+
378
+ # Base64 to IO stream
379
+ io = Solace::Utils::Codecs.base64_to_bytestream(base64_string)
380
+ ```
381
+
382
+ ### Program Derived Addresses (PDA)
383
+
384
+ ```ruby
385
+ # Find PDA with bump seed
386
+ seeds = ['metadata', mint_address, 'edition']
387
+ program_id = 'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s'
388
+
389
+ address, bump = Solace::Utils::PDA.find_program_address(seeds, program_id)
390
+
391
+ # Create PDA directly
392
+ address = Solace::Utils::PDA.create_program_address(seeds + [bump], program_id)
393
+ ```
394
+
395
+ **Key Features:**
396
+ - Automatic bump seed finding
397
+ - Multiple seed type support (String, Integer, Array)
398
+ - Base58 address detection
399
+ - SHA256 hashing with curve validation
400
+
401
+ ### Curve25519 Operations
402
+
403
+ ```ruby
404
+ # Check if point is on curve (used in PDA validation)
405
+ on_curve = Solace::Utils::Curve25519Dalek.on_curve?(32_byte_point)
406
+ ```
407
+
408
+ ## Constants
409
+
410
+ Common Solana program IDs are defined in `Solace::Constants`:
411
+
412
+ ```ruby
413
+ Solace::Constants::SYSTEM_PROGRAM_ID # '11111111111111111111111111111111'
414
+ Solace::Constants::TOKEN_PROGRAM_ID # 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'
415
+ Solace::Constants::ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID # 'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL'
416
+ Solace::Constants::SYSVAR_RENT_PROGRAM_ID # 'SysvarRent111111111111111111111111111111111'
417
+ Solace::Constants::MEMO_PROGRAM_ID # 'MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr'
418
+ ```
419
+
420
+ ## Practical Examples
421
+
422
+ ### Complete SOL Transfer
423
+
424
+ ```ruby
425
+ require 'solace'
426
+
427
+ # Setup
428
+ connection = Solace::Connection.new('https://api.devnet.solana.com')
429
+ payer = Solace::Keypair.generate
430
+ recipient = Solace::Keypair.generate
431
+
432
+ # Fund payer (devnet only)
433
+ connection.request_airdrop(payer.address, 1_000_000_000)
434
+
435
+ # Build transfer instruction
436
+ transfer_ix = Solace::Instructions::TransferInstruction.build(
437
+ lamports: 100_000_000, # 0.1 SOL
438
+ from_index: 0,
439
+ to_index: 1,
440
+ program_index: 2
441
+ )
442
+
443
+ # Create message
444
+ message = Solace::Message.new(
445
+ accounts: [
446
+ payer.address,
447
+ recipient.address,
448
+ Solace::Constants::SYSTEM_PROGRAM_ID
449
+ ],
450
+ instructions: [transfer_ix],
451
+ recent_blockhash: connection.get_latest_blockhash,
452
+ header: [1, 0, 1]
453
+ )
454
+
455
+ # Sign and send
456
+ transaction = Solace::Transaction.new(message: message)
457
+ transaction.sign(payer)
458
+ signature = connection.send_transaction(transaction.serialize)
459
+
460
+ puts "Transaction: #{signature}"
461
+ ```
462
+
463
+ ### Complete Token Mint Creation
464
+
465
+ ```ruby
466
+ require 'solace'
467
+
468
+ # Setup
469
+ connection = Solace::Connection.new('https://api.devnet.solana.com')
470
+ payer = Solace::Keypair.generate
471
+ mint_keypair = Solace::Keypair.generate
472
+
473
+ # Fund payer
474
+ connection.request_airdrop(payer.address, 1_000_000_000)
475
+
476
+ # High-level approach
477
+ spl_token = Solace::Programs::SplToken.new(connection: connection)
478
+ signature = spl_token.create_mint(
479
+ payer: payer,
480
+ decimals: 6,
481
+ mint_authority: payer,
482
+ freeze_authority: nil,
483
+ mint_keypair: mint_keypair
484
+ )
485
+
486
+ puts "Mint created: #{mint_keypair.address}"
487
+ puts "Transaction: #{signature}"
488
+ ```
489
+
490
+ ### Manual Transaction Building
491
+
492
+ ```ruby
493
+ # Low-level approach for maximum control
494
+ rent_lamports = connection.get_minimum_lamports_for_rent_exemption(82)
495
+
496
+ # Build instructions
497
+ create_account_ix = Solace::Instructions::SystemProgram::CreateAccountInstruction.build(
498
+ from_index: 0,
499
+ new_account_index: 1,
500
+ system_program_index: 4,
501
+ lamports: rent_lamports,
502
+ space: 82,
503
+ owner: Solace::Constants::TOKEN_PROGRAM_ID
504
+ )
505
+
506
+ initialize_mint_ix = Solace::Instructions::SplToken::InitializeMintInstruction.build(
507
+ mint_account_index: 1,
508
+ rent_sysvar_index: 2,
509
+ program_index: 3,
510
+ decimals: 6,
511
+ mint_authority: payer.address
512
+ )
513
+
514
+ # Assemble transaction
515
+ message = Solace::Message.new(
516
+ accounts: [
517
+ payer.address,
518
+ mint_keypair.address,
519
+ Solace::Constants::SYSVAR_RENT_PROGRAM_ID,
520
+ Solace::Constants::TOKEN_PROGRAM_ID,
521
+ Solace::Constants::SYSTEM_PROGRAM_ID
522
+ ],
523
+ instructions: [create_account_ix, initialize_mint_ix],
524
+ recent_blockhash: connection.get_latest_blockhash,
525
+ header: [2, 0, 3] # 2 signers, 0 readonly signed, 3 readonly unsigned
526
+ )
527
+
528
+ transaction = Solace::Transaction.new(message: message)
529
+ transaction.sign(payer, mint_keypair)
530
+ signature = connection.send_transaction(transaction.serialize)
531
+ ```
532
+
533
+ ## Design Patterns
534
+
535
+ ### Service Objects
536
+ Instruction builders follow the service object pattern:
537
+ - Single responsibility (build one instruction type)
538
+ - Class methods for stateless operations
539
+ - Consistent `.build()` interface
540
+ - Separate `.data()` methods for instruction data
541
+
542
+ ### Serializable Records
543
+ Core data structures inherit from `SerializableRecord`:
544
+ - Automatic serialization/deserialization
545
+ - Consistent binary format handling
546
+ - SERIALIZER/DESERIALIZER constants pattern
547
+
548
+ ### Mixin Modules
549
+ Shared functionality via mixins:
550
+ - `BinarySerializable` for serialization support
551
+ - `PDA` for Program Derived Address operations
552
+ - `Utils` modules for common operations
553
+
554
+ ### Builder Pattern
555
+ High-level program methods use builder pattern:
556
+ - Fluent interfaces with keyword arguments
557
+ - Sensible defaults for optional parameters
558
+ - Automatic transaction assembly and signing
559
+
560
+ ## Error Handling
561
+
562
+ The SDK provides comprehensive error handling:
563
+
564
+ ```ruby
565
+ begin
566
+ signature = connection.send_transaction(transaction.serialize)
567
+ rescue StandardError => e
568
+ puts "Transaction failed: #{e.message}"
569
+ end
570
+
571
+ # PDA validation
572
+ begin
573
+ address = Solace::Utils::PDA.create_program_address(seeds, program_id)
574
+ rescue Solace::Utils::PDA::InvalidPDAError => e
575
+ puts "Invalid PDA: #{e.message}"
576
+ end
577
+ ```
578
+
579
+ ## Testing Support
580
+
581
+ The SDK includes comprehensive test utilities:
582
+
583
+ ```ruby
584
+ # Test fixtures for keypairs
585
+ bob = Fixtures.load_keypair('bob')
586
+ alice = Fixtures.load_keypair('anna')
587
+
588
+ # Automatic funding in test environment
589
+ response = connection.request_airdrop(keypair.address, 10_000_000_000)
590
+ connection.wait_for_confirmed_signature { response['result'] }
591
+
592
+ # Transaction confirmation helpers
593
+ response = connection.send_transaction(transaction.serialize)
594
+ connection.wait_for_confirmed_signature { response['result'] }
595
+ ```
596
+
597
+ ## Dependencies
598
+
599
+ - **base58**: Base58 encoding/decoding
600
+ - **rbnacl**: Ed25519 cryptography
601
+ - **ffi**: Foreign Function Interface for native libraries
602
+ - **json**: JSON parsing for RPC
603
+ - **net/http**: HTTP client for RPC calls
604
+
605
+ ## Current Limitations
606
+
607
+ ### High-Impact/Foundational Next Steps
608
+
609
+ 1. **Associated Token Account Program**
610
+ - Implement: close_associated_token_account, and helpers for derivation.
611
+ - Rationale: Required for user wallets and token UX. **Most SPL Token operations depend on ATAs to be useful in real-world workflows.**
612
+
613
+ 2. **Full SPL Token Program Coverage** _(depends on ATA support)_
614
+ - Implement: mint_to, burn, close_account, set_authority, freeze/thaw, approve/revoke, etc.
615
+ - Rationale: Most dApps and DeFi protocols rely on SPL tokens. **For practical use, SPL Token instructions should leverage ATA helpers.**
616
+
617
+ 3. **Account Data Parsing**
618
+ - Implement: Decoders for token accounts, mint accounts, stake accounts, etc.
619
+ - Rationale: Needed to read on-chain state.
620
+
621
+ 4. **Transaction Simulation**
622
+ - Implement: `simulateTransaction` RPC endpoint.
623
+ - Rationale: Allows dry-run and error debugging.
624
+
625
+ 5. **Error Decoding**
626
+ - Implement: Map program error codes to readable errors.
627
+ - Rationale: Improves DX and debugging.
628
+
629
+ ---
630
+
631
+ ### Medium-Impact
632
+
633
+ 6. **Address Lookup Table Support**
634
+ - Implement: Create, extend, use ALT in transactions.
635
+ - Rationale: Needed for scalable DeFi/protocols.
636
+
637
+ 7. **Stake Program**
638
+ - Implement: delegate, deactivate, withdraw, split, merge.
639
+ - Rationale: For validators, staking dApps.
640
+
641
+ 8. **Websocket/Event Subscription**
642
+ - Implement: Account/slot/transaction subscriptions.
643
+ - Rationale: For real-time apps and bots.
644
+
645
+ 9. **Utility Functions**
646
+ - base58/base64 encode/decode, lamports/SOL conversions, etc.
647
+
648
+ 10. **Advanced Transaction Features**
649
+ - Durable nonce, versioned transactions, partial signing.
650
+
651
+ ---
652
+
653
+ ### Low-Impact/Advanced
654
+
655
+ - Governance program
656
+ - Anchor IDL/Anchor-style program support
657
+ - Program deployment (BPF loader)
658
+
659
+ ## Conclusion
660
+
661
+ Solace provides a comprehensive, Ruby-idiomatic interface to the Solana blockchain. Its layered architecture allows developers to choose the appropriate level of abstraction for their needs, from low-level instruction building to high-level program interactions. The consistent patterns and thorough documentation make it accessible to Ruby developers while maintaining the power and flexibility needed for complex Solana applications.