solace 0.0.10 → 0.1.1

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 (33) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +124 -24
  3. data/README.md +10 -8
  4. data/lib/solace/composers/base.rb +35 -0
  5. data/lib/solace/composers/spl_token_program_initialize_mint_composer.rb +95 -0
  6. data/lib/solace/composers/spl_token_program_mint_to_composer.rb +86 -0
  7. data/lib/solace/composers/spl_token_program_transfer_composer.rb +90 -0
  8. data/lib/solace/composers/system_program_create_account_composer.rb +98 -0
  9. data/lib/solace/connection.rb +92 -15
  10. data/lib/solace/errors/confirmation_timeout.rb +18 -4
  11. data/lib/solace/errors/http_error.rb +16 -1
  12. data/lib/solace/errors/parse_error.rb +15 -1
  13. data/lib/solace/errors/rpc_error.rb +17 -1
  14. data/lib/solace/errors.rb +8 -3
  15. data/lib/solace/instructions/associated_token_account/create_associated_token_account_instruction.rb +9 -2
  16. data/lib/solace/instructions/spl_token/initialize_mint_instruction.rb +0 -1
  17. data/lib/solace/instructions/spl_token/transfer_instruction.rb +21 -0
  18. data/lib/solace/instructions/system_program/create_account_instruction.rb +30 -0
  19. data/lib/solace/instructions/system_program/transfer_instruction.rb +11 -0
  20. data/lib/solace/programs/associated_token_account.rb +57 -30
  21. data/lib/solace/programs/base.rb +23 -0
  22. data/lib/solace/programs/spl_token.rb +197 -125
  23. data/lib/solace/serializers/base_serializer.rb +29 -1
  24. data/lib/solace/tokens/token.rb +53 -0
  25. data/lib/solace/tokens.rb +86 -0
  26. data/lib/solace/transaction.rb +24 -21
  27. data/lib/solace/transaction_composer.rb +77 -3
  28. data/lib/solace/utils/account_context.rb +1 -1
  29. data/lib/solace/utils/codecs.rb +17 -0
  30. data/lib/solace/utils/pda.rb +13 -5
  31. data/lib/solace/version.rb +3 -2
  32. data/lib/solace.rb +38 -11
  33. metadata +21 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 669a517f72b280a594613b55fcd3e86c6e0f7ef9ba3d6633b0edfbd5dc5b0a0c
4
- data.tar.gz: a542d3ce4edaeb81d3c6e8aee35fadfb9df4a4cd5a618f9f643ac46544f4cc65
3
+ metadata.gz: a9bca105aef6d20a1a5b6d5dc6b2fce8c7a8523c9a2a24afd3ad15bf36efbb55
4
+ data.tar.gz: e6a70370368a4822249bf7c912f70f54a02ce5389ef128e40acdc769b315ebae
5
5
  SHA512:
6
- metadata.gz: c43a013d3007b0853a5501c96dc7b2e737b0aefa5d35844008127ddcdfd59c0770e4ceaf9db99086aa69c294ae20563b022b3d6e370be84701c9fe8a453ce25d
7
- data.tar.gz: 42eab84e19bf00741e1c29a50facb39966f3020a005c2baa3ee63d545d6a43bcc267cb86d17ba09cb05be6d64875504c9a557275f9c365f6ce5764ce95501baf
6
+ metadata.gz: 44fc38f19753ed736c05e1ba58bc7799fbe96d736553e3df220cfa38cae60a0dc2d2ecb3459990300efc108d56b9ec0ae8ce4fc552c39b31cf668e54878f52bd
7
+ data.tar.gz: 4ffe860837dc85e925f308fdff68129ba01cdc41fb192495af4926bbd91328c62847f862c2847a819c9615cd1b223d512910a421713ee64f9b038bee25def482
data/CHANGELOG CHANGED
@@ -1,46 +1,139 @@
1
1
  # Change Log
2
+
2
3
  All notable changes to this project will be documented in this file.
3
-
4
+
4
5
  The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/).
5
6
 
6
7
  ### Template
7
8
 
8
9
  ```markdown
9
10
  ## [VERSION] - yyyy-mm-dd
10
-
11
+
11
12
  ### Added
12
- 1.
13
+
14
+ 1.
13
15
 
14
16
  ### Changed
15
-
17
+
16
18
  ### Fixed
17
19
  ```
18
20
 
19
- ## [0.0.10] - yyyy-mm-dd
20
-
21
+ Got it — here’s your changelog tidied up for clarity and consistency without changing any of the substance. I only fixed grammar/typos and tightened phrasing.
22
+
23
+ ---
24
+
25
+ ## [0.1.1] - 2025-05-11
26
+
21
27
  ### Added
22
- 1.
28
+
29
+ 1. Added support to inject encoding externally to get the data with respective encoding.
30
+
31
+ ## [0.1.0] - 2025-18-10
32
+
33
+ **NOTE (Breaking):**
34
+ All previous `prepare_*` Program methods have been renamed to `compose_*` and now return an **unsigned composer instance**. This enables composition and extensibility that weren’t possible when methods returned a signed transaction that was only editable via low-level manipulation.
35
+ Additionally, unless explicitly required by a composer’s instruction, the `payer:` keyword has been removed from the new `compose_*` methods and is instead only used in their execution counterparts (e.g., `compose_mint_to` → `mint_to`). This allows specifying the fee payer when building the final transaction, while keeping composition steps payer-agnostic.
36
+
37
+ ### Added
38
+
39
+ 1. **`Solace::Tokens`** — a structured registry and lookup system for Solana token metadata.
40
+
41
+ - Developers can define token details via a YAML configuration file scoped by network (e.g., `mainnet`, `devnet`).
42
+ - Programmatic access to token metadata:
43
+
44
+ ```ruby
45
+ Solace::Tokens.load(path: 'tokens.yml', network: :devnet)
46
+ Solace::Tokens::USDC.decimals # => 6
47
+ Solace::Tokens.fetch('USDC') # => <Solace::Tokens::Token ...>
48
+ Solace::Tokens.where(decimals: 6)
49
+ ```
50
+
51
+ - Dynamically registers constants for each token symbol (`USDC`, `SOL`, etc.).
52
+ - Safety improvements to preserve internal constants (`Token`) during reloads.
53
+
54
+ 2. **`SystemProgramCreateAccountComposer`** — composer for building account creation flows via the Solana System Program.
55
+
56
+ - Wraps `SystemProgram::CreateAccountInstruction`.
57
+ - Handles lamport allocation, rent exemption, and ownership assignment.
58
+ - Simplifies creation of system-owned and program-owned accounts.
59
+
60
+ 3. **`SplTokenProgramInitializeMintComposer`** — composer for initializing new SPL Token mints.
61
+
62
+ - Wraps `SplToken::InitializeMintInstruction`.
63
+ - Supports decimals, mint authority, and optional freeze authority.
64
+ - Designed to pair with `SystemProgramCreateAccountComposer` for one-transaction mint creation.
65
+
66
+ 4. **`SplTokenProgramMintToComposer`** — composer for minting tokens to an ATA.
67
+
68
+ - Wraps `SplToken::MintToInstruction`.
69
+ - Supports minting tokens to a destination ATA.
70
+
71
+ 5. **`SplTokenProgramTransferComposer`** — composer for transferring tokens.
72
+
73
+ - Wraps `SplToken::TransferInstruction`.
74
+ - Supports sending SPL tokens.
75
+
76
+ 6. **`Solace::Connection`** — cached blockhash accessors.
77
+
78
+ - Added `last_fetched_blockhash` and `last_fetched_block_height`.
79
+ - Stores the most recently retrieved blockhash and corresponding `lastValidBlockHeight`.
80
+ - Enables reuse without re-fetching between sequential transactions.
81
+ - `get_latest_blockhash` now sets these values automatically.
82
+
83
+ 7. **`TransactionComposer`** — instruction ordering helpers.
84
+
85
+ - Added `prepend_instruction` and `insert_instruction` for finer control of instruction order.
86
+
87
+ 8. **`Transaction`** — signature helper.
88
+
89
+ - Added `transaction.signature` to get the signature from a signed transaction.
90
+
91
+ 9. **Program method options** — higher-level control.
92
+
93
+ - Added `execute`, `sign`, and a yield block to relevant Program methods for flow control and composer access.
23
94
 
24
95
  ### Changed
25
- 2. Updated `build_instructions` method on `TransactionComposer` to flatten the array, allowing composers to return multiple instructions when relevant (i.e. creating an account and then writing to it).
26
- 3. Changed get_latest_blockhash to use the expected comittment level by the connection or passed options and return array (blockhash and lastValidBlockheight)
27
- 4. Changed default commitment level to `processed` in `Solace::Connection`.
96
+
97
+ 1. `TransactionComposer#build_instructions` now flattens arrays so composers can return multiple instructions (e.g., create an account then initialize it).
98
+
99
+ 2. `Connection#get_latest_blockhash` now uses the connection’s expected commitment (or provided options) and returns `[blockhash, lastValidBlockheight]`.
100
+
101
+ 3. Default commitment level changed to `processed` in `Solace::Connection`.
102
+
103
+ 4. SPL Program: renamed/adjusted kwargs for `compose_create_mint` and moved signing logic to `create_mint`.
104
+
105
+ 5. SPL Program: `compose_mint_to` moved signing logic to `mint_to`.
106
+
107
+ 6. SPL Program: `compose_transfer` moved signing logic to `transfer`.
108
+
109
+ 7. SPL Program: `create_mint`, `compose_create_mint`, and `compose_create_associated_token_account` now accept separate `funder` and `payer` keys. Both may be the same value, but splitting them allows one account to pay transaction fees while another covers rent exemption.
110
+
111
+ 8. All executable Program methods now return the **Solace transaction instance** instead of an encoded signature.
112
+
113
+ 9. Updated `test/bootstrap.rb` to use composers for setting up test fixtures in a single transaction.
28
114
 
29
115
  ### Fixed
30
116
 
117
+ - Improved token loading safety in `Solace::Tokens` to prevent internal constant removal during reloads.
118
+
119
+ ---
120
+
31
121
  ## [0.0.9] - 2025-08-12
32
-
122
+
33
123
  ### Added
124
+
34
125
  1. Added `get_program_accounts` to `Solace::Connection`.
35
126
 
36
127
  ### Changed
37
-
128
+
38
129
  ### Fixed
130
+
39
131
  1. Removed use of the `try` method for supporting non-rails environments.
40
132
 
41
133
  ## [0.0.8] - 2025-08-11
42
-
134
+
43
135
  ### Added
136
+
44
137
  1. Added `load` method to `Solace::Constants` to load constants from a YAML file. This method allows for loading constants from a YAML file (i.e. custom program addresses and mint accounts).
45
138
  2. Added `to_s` and `address` method to `Solace::Keypair` and `Solace::PublicKey` to return the public key as a Base58 string.
46
139
  3. Added `get_signature_status` and `get_signature_statuses` to `Solace::Connection`.
@@ -48,39 +141,46 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
48
141
  5. Added `Errors` module to `Solace::Utils` to handle errors from the HTTP requests made to the Solana RPC node.
49
142
 
50
143
  ### Changed
144
+
51
145
  1. All methods that take a `Solace::Keypair` or `Solace::Pubkey` where an address is needed now also accept a plain string address. This prevents the need of creating instances of the classes when all that is needed is the address. This is with the exception of the low-level instruction builders, which only expect the correct data and indicies with no required casting.
52
146
  2. Changed `wait_for_confirmed_signature` method to accept a `timeout`, `interval`, and `commitment` arguments.
53
-
147
+
54
148
  ### Fixed
149
+
55
150
  1. Fixed `get_or_create_address` method in `Solace::Programs::AssociatedTokenAccount` to return the address of the associated token account if it already exists by checking if there is any data at the address.
56
151
 
57
152
  ## [0.0.7] - 2025-08-09
58
-
153
+
59
154
  ### Added
155
+
60
156
  1. Added `AssociatedTokenAccountProgramCreateAccountComposer` with tests.
61
157
 
62
158
  ### Changed
63
- 1. Updated `AssociatedTokenAccount` to use `AssociatedTokenAccountProgramCreateAccountComposer` and sign the transaction in the `create_associated_token_account` method instead of the `prepare_create_associated_token_account` method.
64
-
159
+
160
+ 1. Updated `AssociatedTokenAccount` to use `AssociatedTokenAccountProgramCreateAccountComposer` and sign the transaction in the `create_associated_token_account` method instead of the `compose_create_associated_token_account` method.
161
+
65
162
  ### Fixed
66
163
 
67
164
  ## [0.0.6] - 2025-08-07
68
-
165
+
69
166
  ### Added
167
+
70
168
  1. Added `from_address` method to `Solace::PublicKey`.
71
169
  2. Change docs on most methods to include an `@example` section.
72
170
 
73
171
  ### Changed
172
+
74
173
  1. Change `private_key` method on Keypair to `pivate_key_bytes`
75
174
  2. Change README to include a practical example of using composers.
76
-
175
+
77
176
  ### Fixed
78
- 1. Fix `encode_signatures` method in `Solace::Serializers::TransactionSerializer` to correctly count the number of signatures using the `num_required_signatures` field in the message.
79
177
 
178
+ 1. Fix `encode_signatures` method in `Solace::Serializers::TransactionSerializer` to correctly count the number of signatures using the `num_required_signatures` field in the message.
80
179
 
81
180
  ## [0.0.3] - 2025-07-30
82
-
181
+
83
182
  ### Added
183
+
84
184
  1. Moved `TransferCheckedInstruction` and `TransferInstruction` to `Solace::Instructions::SystemProgram` namespace.
85
185
  2. Added `get_token_account_balance` to `Solace::Connection`.
86
186
  3. Added `get_or_create_address` to `Solace::Programs::AssociatedTokenAccount`.
@@ -94,14 +194,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
94
194
 
95
195
  ### Changed
96
196
 
97
- THESE ARE BREAKING CHANGES FROM 0.0.2 TO 0.0.3. Solice is still in alpha and the API is subject to change.
197
+ THESE ARE BREAKING CHANGES FROM 0.0.2 TO 0.0.3. Solice is still in alpha and the API is subject to change.
98
198
 
99
199
  There was a bit of a refactoring of the codebase to make it more maintainable and to make it easier to add new features. Additonally, the SDK now has `Composers` for handling accounts and instructions in a higher level abstraction. These composers are used in the tests and can be used in your own code as well.
100
200
 
101
- Soon, YARD documentation will be added to the SDK and published to https://solace-rb.github.io/solace/.
201
+ Soon, YARD documentation will be added to the SDK and published to https://solace-rb.github.io/solace/.
102
202
 
103
203
  Stay tuned.
104
-
204
+
105
205
  ### Fixed
106
206
 
107
207
  N/A
data/README.md CHANGED
@@ -1,4 +1,5 @@
1
1
  # Solace Ruby SDK Documentation
2
+
2
3
  A Ruby SDK for the Solana blockchain.
3
4
 
4
5
  ## Overview
@@ -10,9 +11,9 @@ Solace is a comprehensive Ruby SDK for interacting with the Solana blockchain. I
10
11
  The Solace SDK is organized into several key layers:
11
12
 
12
13
  ### 1. **Core Classes** (Low-Level)
13
- - **Keypair/PublicKey**: Ed25519 cryptographic operations
14
+ - **Keypair, PublicKey**: Ed25519 cryptographic operations
14
15
  - **Connection**: RPC client for Solana nodes
15
- - **Transaction/Message/Instruction/AddressLookupTable**: Transaction building blocks
16
+ - **Transaction, Message, Instruction, AddressLookupTable**: Transaction building blocks
16
17
  - **Serializers**: Binary serialization/deserialization system
17
18
 
18
19
  ### 2. **Instruction Builders** (Low-Level)
@@ -34,7 +35,8 @@ The Solace SDK is organized into several key layers:
34
35
  - **Codecs**: Base58/Base64 encoding, compact integers, little-endian encoding
35
36
  - **PDA**: Program Derived Address generation
36
37
  - **Curve25519**: Native curve operations via FFI
37
- - **More...**: Checkout `lib/solace/utils`
38
+ - **Token**: Classes for loading and accessing token data
39
+ - **More...**: Checkout `lib/solace/utils`
38
40
 
39
41
  ## Core Components
40
42
 
@@ -199,7 +201,7 @@ For more control, use "prepare" methods that return signed transactions without
199
201
 
200
202
  ```ruby
201
203
  # Prepare transaction without sending
202
- transaction = spl_token.prepare_create_mint(
204
+ transaction = spl_token.compose_create_mint(
203
205
  payer: payer_keypair,
204
206
  decimals: 6,
205
207
  mint_authority: authority_keypair,
@@ -317,10 +319,10 @@ Composers are intended to be extended by developers with custom instruction comp
317
319
  class MyProgramComposer < Solace::Composers::Base
318
320
  # All keyword arguments are passed to the constructor and available
319
321
  # as a `params` hash.
320
- #
322
+ #
321
323
  # The setup_accounts method is called automatically by the transaction composer
322
- # during compilation and should be used to add accounts to the account_context
323
- # with the appropriate access permissions. Conditional logic is fine here given
324
+ # during compilation and should be used to add accounts to the account_context
325
+ # with the appropriate access permissions. Conditional logic is fine here given
324
326
  # and available params to determine the access permissions.
325
327
  def setup_accounts
326
328
  account_context.add_writable_signer(params[:from])
@@ -330,7 +332,7 @@ class MyProgramComposer < Solace::Composers::Base
330
332
 
331
333
  # The build_instruction method is called automatically by the transaction composer
332
334
  # during compilation and should be used to build the instruction using an instruction builder.
333
- #
335
+ #
334
336
  # The passed context to the build_instruction method provides the indices of all accounts
335
337
  # that were added to the account_context in the setup_accounts method. These are accessible
336
338
  # by the index_of method of the context using the account address as a parameter.
@@ -1,6 +1,41 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Solace
4
+ # The Composers module contains classes responsible for building and ordering
5
+ # the accounts and instructions required for common Solana operations.
6
+ #
7
+ # Composers abstract away the complexity of account ordering, permission management,
8
+ # and instruction data construction. They provide a high-level interface for
9
+ # creating instructions that interact with on-chain programs. Each composer
10
+ # corresponds to a specific program instruction (e.g., transferring SOL,
11
+ # minting tokens, creating accounts).
12
+ #
13
+ # Composers handle:
14
+ # - Account resolution and ordering
15
+ # - Permission flags (signer, writable)
16
+ # - Account deduplication
17
+ # - Instruction data formatting
18
+ #
19
+ # @example Using a composer
20
+ # # Initialize a transaction composer
21
+ # composer = TransactionComposer.new(connection: connection)
22
+ #
23
+ # # Create a transfer instruction composer
24
+ # ix = Solace::Composers::SystemProgramTransferComposer.new(
25
+ # from: sender.public_key,
26
+ # to: recipient.public_key,
27
+ # lamports: 1_000_000
28
+ # )
29
+ #
30
+ # # Add the instruction to the transaction composer and compose the transaction
31
+ # tx = composer
32
+ # .add_instruction(ix)
33
+ # .set_fee_payer(sender.public_key)
34
+ # .compose_transaction
35
+ #
36
+ # @see Solace::TransactionComposer
37
+ # @see Solace::Composers::Base
38
+ # @since 0.0.3
4
39
  module Composers
5
40
  # A Base class for all composers
6
41
  #
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solace
4
+ module Composers
5
+ # Composer for initializing a mint via the SPL Token Program.
6
+ #
7
+ # This composer resolves and orders the required accounts for an `InitializeMint` instruction,
8
+ # sets up their access permissions, and delegates construction to the appropriate
9
+ # instruction builder (`Instructions::SplToken::InitializeMintInstruction`).
10
+ #
11
+ # It is used for initializing a new SPL Token mint.
12
+ #
13
+ # Required accounts:
14
+ # - **Mint Account**: the mint account to initialize (writable, non-signer)
15
+ #
16
+ # @example Compose and build an initialize_mint instruction
17
+ # composer = SplTokenProgramInitializeMintComposer.new(
18
+ # decimals: 6,
19
+ # mint_authority: mint_authority_pubkey,
20
+ # freeze_authority: freeze_authority_pubkey,
21
+ # mint_account: mint_address,
22
+ # )
23
+ #
24
+ # @see Instructions::SplToken::InitializeMintInstruction
25
+ # @since 0.1.0
26
+ class SplTokenProgramInitializeMintComposer < Base
27
+ # Extracts the mint account address from the params
28
+ #
29
+ # @return [String] The mint account address
30
+ def mint_account
31
+ params[:mint_account].to_s
32
+ end
33
+
34
+ # Returns the rent sysvar address
35
+ #
36
+ # @return [String] The rent sysvar address
37
+ def rent_sysvar
38
+ Constants::SYSVAR_RENT_PROGRAM_ID.to_s
39
+ end
40
+
41
+ # Returns the spl token program id
42
+ #
43
+ # @return [String] The spl token program id
44
+ def spl_token_program
45
+ Constants::TOKEN_PROGRAM_ID.to_s
46
+ end
47
+
48
+ # Extracts the mint authority address from the params
49
+ #
50
+ # @return [String] The mint authority address
51
+ def mint_authority
52
+ params[:mint_authority].to_s
53
+ end
54
+
55
+ # Extracts the freeze authority address from the params
56
+ #
57
+ # @return [String] The freeze authority address
58
+ def freeze_authority
59
+ params[:freeze_authority]&.to_s
60
+ end
61
+
62
+ # Returns the decimals for the mint
63
+ #
64
+ # @return [Integer] The decimals for the mint
65
+ def decimals
66
+ params[:decimals]
67
+ end
68
+
69
+ # Setup accounts required for transfer instruction
70
+ # Called automatically during initialization
71
+ #
72
+ # @return [void]
73
+ def setup_accounts
74
+ account_context.add_writable_nonsigner(mint_account)
75
+ account_context.add_readonly_nonsigner(rent_sysvar)
76
+ account_context.add_readonly_nonsigner(spl_token_program)
77
+ end
78
+
79
+ # Build instruction with resolved account indices
80
+ #
81
+ # @param account_context [Utils::AccountContext] The account context
82
+ # @return [Solace::Instruction]
83
+ def build_instruction(account_context)
84
+ Instructions::SplToken::InitializeMintInstruction.build(
85
+ mint_account_index: account_context.index_of(mint_account),
86
+ rent_sysvar_index: account_context.index_of(rent_sysvar),
87
+ program_index: account_context.index_of(spl_token_program),
88
+ decimals: decimals,
89
+ mint_authority: mint_authority,
90
+ freeze_authority: freeze_authority
91
+ )
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solace
4
+ module Composers
5
+ # Composer for creating a MintTo instruction for the SPL Token Program.
6
+ #
7
+ # This composer builds a MintTo instruction that can be added to a transaction to mint tokens
8
+ # to a specified token account. It is used to mint new tokens for a given mint and destination account.
9
+ #
10
+ # Required accounts:
11
+ # - **Mint**: The mint account (writable, non-signer)
12
+ # - **Destination**: The token account to mint to (writable, non-signer)
13
+ # - **Mint Authority**: The mint authority account (readonly, signer)
14
+ #
15
+ # @example Build a MintTo instruction
16
+ # composer = Solace::Composers::SplTokenProgramMintToComposer.new(
17
+ # mint: mint,
18
+ # destination: destination,
19
+ # mint_authority: mint_authority,
20
+ # amount: 100
21
+ # )
22
+ #
23
+ # @since 0.1.0
24
+ class SplTokenProgramMintToComposer < Base
25
+ # Extracts the mint address from the params
26
+ #
27
+ # @return [String] The mint address
28
+ def mint
29
+ params[:mint].to_s
30
+ end
31
+
32
+ # Extracts the destination address from the params
33
+ #
34
+ # @return [String] The destination address
35
+ def destination
36
+ params[:destination].to_s
37
+ end
38
+
39
+ # Extracts the mint authority address from the params
40
+ #
41
+ # @return [String] The mint authority address
42
+ def mint_authority
43
+ params[:mint_authority].to_s
44
+ end
45
+
46
+ # Returns the spl token program id
47
+ #
48
+ # @return [String] The spl token program id
49
+ def spl_token_program
50
+ Constants::TOKEN_PROGRAM_ID.to_s
51
+ end
52
+
53
+ # Extracts the amount from the params
54
+ #
55
+ # @return [Integer] The amount
56
+ def amount
57
+ params[:amount].to_i
58
+ end
59
+
60
+ # Setup accounts required for MintTo instruction
61
+ # Called automatically during initialization
62
+ #
63
+ # @return [void]
64
+ def setup_accounts
65
+ account_context.add_writable_nonsigner(mint)
66
+ account_context.add_writable_nonsigner(destination)
67
+ account_context.add_readonly_signer(mint_authority)
68
+ account_context.add_readonly_nonsigner(spl_token_program)
69
+ end
70
+
71
+ # Build instruction with resolved account indices
72
+ #
73
+ # @param account_context [Utils::AccountContext] The account context
74
+ # @return [Solace::Instruction]
75
+ def build_instruction(account_context)
76
+ Instructions::SplToken::MintToInstruction.build(
77
+ amount: amount,
78
+ mint_index: account_context.index_of(mint),
79
+ destination_index: account_context.index_of(destination),
80
+ mint_authority_index: account_context.index_of(mint_authority),
81
+ program_index: account_context.index_of(spl_token_program)
82
+ )
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solace
4
+ module Composers
5
+ # Composer for creating a SPL Token Program Transfer instruction.
6
+ #
7
+ # This composer resolves and orders the required accounts for a `Transfer` instruction,
8
+ # sets up their access permissions, and delegates construction to the appropriate
9
+ # instruction builder (`Instructions::SplToken::TransferInstruction`).
10
+ #
11
+ # It is used for transferring SPL tokens with decimal precision and validation checks.
12
+ #
13
+ # Required accounts:
14
+ # - **Owner**: token account owner (writable, signer)
15
+ # - **Source**: source token account (writable, non-signer)
16
+ # - **Destination**: destination token account (writable, non-signer)
17
+ #
18
+ # @example Compose and build a transfer instruction
19
+ # composer = SplTokenProgramTransferComposer.new(
20
+ # amount: 1_000_000,
21
+ # owner: owner_address,
22
+ # source: source_address,
23
+ # destination: destination_address,
24
+ # )
25
+ #
26
+ # @see Instructions::SplToken::TransferInstruction
27
+ # @since 0.1.0
28
+ class SplTokenProgramTransferComposer < Base
29
+ # Extracts the owner address from the params
30
+ #
31
+ # @return [String] The owner address
32
+ def owner
33
+ params[:owner].to_s
34
+ end
35
+
36
+ # Extracts the source associated token address from the params
37
+ #
38
+ # @return [String] The source associated token address
39
+ def source
40
+ params[:source].to_s
41
+ end
42
+
43
+ # Extracts the destination associated token address from the params
44
+ #
45
+ # @return [String] The destination associated token address
46
+ def destination
47
+ params[:destination].to_s
48
+ end
49
+
50
+ # Returns the spl token program id
51
+ #
52
+ # @return [String] The spl token program id
53
+ def spl_token_program
54
+ Constants::TOKEN_PROGRAM_ID.to_s
55
+ end
56
+
57
+ # Returns the lamports to transfer
58
+ #
59
+ # @return [Integer] The lamports to transfer
60
+ def amount
61
+ params[:amount]
62
+ end
63
+
64
+ # Setup accounts required for transfer instruction
65
+ # Called automatically during initialization
66
+ #
67
+ # @return [void]
68
+ def setup_accounts
69
+ account_context.add_writable_signer(owner)
70
+ account_context.add_writable_nonsigner(source)
71
+ account_context.add_writable_nonsigner(destination)
72
+ account_context.add_readonly_nonsigner(spl_token_program)
73
+ end
74
+
75
+ # Build instruction with resolved account indices
76
+ #
77
+ # @param account_context [Utils::AccountContext] The account context
78
+ # @return [Solace::Instruction]
79
+ def build_instruction(account_context)
80
+ Instructions::SplToken::TransferInstruction.build(
81
+ amount: amount,
82
+ owner_index: account_context.index_of(owner),
83
+ source_index: account_context.index_of(source),
84
+ destination_index: account_context.index_of(destination),
85
+ program_index: account_context.index_of(spl_token_program)
86
+ )
87
+ end
88
+ end
89
+ end
90
+ end