solace 0.1.4 → 0.1.5
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.
- checksums.yaml +4 -4
- data/CHANGELOG +17 -0
- data/README.md +60 -0
- data/lib/solace/composers/associated_token_account_program_create_account_composer.rb +5 -4
- data/lib/solace/composers/token_2022_program_close_account_composer.rb +75 -0
- data/lib/solace/composers/token_2022_program_initialize_mint_composer.rb +93 -0
- data/lib/solace/composers/token_2022_program_mint_to_composer.rb +84 -0
- data/lib/solace/composers/token_2022_program_transfer_checked_composer.rb +109 -0
- data/lib/solace/composers/token_2022_program_transfer_composer.rb +86 -0
- data/lib/solace/connection.rb +24 -4
- data/lib/solace/constants.rb +8 -2
- data/lib/solace/instructions/spl_token/transfer_checked_instruction.rb +1 -1
- data/lib/solace/instructions/token_2022/close_account_instruction.rb +50 -0
- data/lib/solace/instructions/token_2022/initialize_account_instruction.rb +62 -0
- data/lib/solace/instructions/token_2022/initialize_mint_instruction.rb +75 -0
- data/lib/solace/instructions/token_2022/mint_to_instruction.rb +59 -0
- data/lib/solace/instructions/token_2022/transfer_checked_instruction.rb +68 -0
- data/lib/solace/instructions/token_2022/transfer_instruction.rb +71 -0
- data/lib/solace/programs/associated_token_account.rb +27 -10
- data/lib/solace/programs/spl_token.rb +18 -254
- data/lib/solace/programs/token_2022.rb +70 -0
- data/lib/solace/programs/token_program_interface.rb +312 -0
- data/lib/solace/version.rb +1 -1
- data/lib/solace.rb +2 -0
- metadata +14 -1
|
@@ -2,11 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
module Solace
|
|
4
4
|
module Programs
|
|
5
|
-
# Client for interacting with the SPL Token Program.
|
|
5
|
+
# Client for interacting with the legacy SPL Token Program.
|
|
6
6
|
#
|
|
7
|
-
# This client provides methods for
|
|
8
|
-
#
|
|
9
|
-
#
|
|
7
|
+
# This client provides methods for creating mints, minting tokens, and
|
|
8
|
+
# transferring tokens via the legacy SPL Token program
|
|
9
|
+
# (+TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA+). The shared method shape
|
|
10
|
+
# comes from {TokenProgramInterface}; this class supplies the SPL-bound
|
|
11
|
+
# composer classes.
|
|
10
12
|
#
|
|
11
13
|
# @example Create an SPL Token mint
|
|
12
14
|
# # Initialize the program with a connection
|
|
@@ -25,8 +27,11 @@ module Solace
|
|
|
25
27
|
# # Wait for the transaction to be finalized
|
|
26
28
|
# connection.wait_for_confirmed_signature('finalized') { result['result'] }
|
|
27
29
|
#
|
|
30
|
+
# @see Solace::Programs::Token2022 for the Token-2022 successor program.
|
|
28
31
|
# @since 0.0.2
|
|
29
32
|
class SplToken < Base
|
|
33
|
+
include TokenProgramInterface
|
|
34
|
+
|
|
30
35
|
# Initializes a new SPL Token client.
|
|
31
36
|
#
|
|
32
37
|
# @param connection [Solace::Connection] The connection to the Solana cluster.
|
|
@@ -34,263 +39,22 @@ module Solace
|
|
|
34
39
|
super(connection: connection, program_id: Solace::Constants::TOKEN_PROGRAM_ID)
|
|
35
40
|
end
|
|
36
41
|
|
|
37
|
-
|
|
38
|
-
#
|
|
39
|
-
# @param payer [#to_s, PublicKey] The keypair that will pay for fees and rent.
|
|
40
|
-
# @param sign [Boolean] Whether to sign the transaction.
|
|
41
|
-
# @param execute [Boolean] Whether to execute the transaction.
|
|
42
|
-
# @param composer_opts [Hash] Options for calling the compose_create_mint method.
|
|
43
|
-
# @return [String] The signature of the transaction.
|
|
44
|
-
def create_mint(
|
|
45
|
-
payer:,
|
|
46
|
-
sign: true,
|
|
47
|
-
execute: true,
|
|
48
|
-
**composer_opts
|
|
49
|
-
)
|
|
50
|
-
composer = compose_create_mint(**composer_opts)
|
|
51
|
-
|
|
52
|
-
yield composer if block_given?
|
|
53
|
-
|
|
54
|
-
tx = composer
|
|
55
|
-
.set_fee_payer(payer)
|
|
56
|
-
.compose_transaction
|
|
57
|
-
|
|
58
|
-
if sign
|
|
59
|
-
tx.sign(
|
|
60
|
-
payer,
|
|
61
|
-
composer_opts[:funder],
|
|
62
|
-
composer_opts[:mint_account]
|
|
63
|
-
)
|
|
64
|
-
|
|
65
|
-
connection.send_transaction(tx.serialize) if execute
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
tx
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
# Prepares a new SPL Token mint transaction.
|
|
72
|
-
#
|
|
73
|
-
# @param funder [#to_s, PublicKey] The keypair that will pay for rent of the new mint account.
|
|
74
|
-
# @param decimals [Integer] The number of decimal places for the token.
|
|
75
|
-
# @param mint_authority [#to_s, PublicKey] The base58 public key for the mint authority.
|
|
76
|
-
# @param freeze_authority [#to_s, PublicKey] (Optional) The base58 public key for the freeze authority.
|
|
77
|
-
# @param mint_account [#to_s, PublicKey] (Optional) The keypair for the new mint.
|
|
78
|
-
# @return [TransactionComposer] A composer with required instructions.
|
|
79
|
-
# rubocop:disable Metrics/MethodLength
|
|
80
|
-
def compose_create_mint(
|
|
81
|
-
funder:,
|
|
82
|
-
decimals:,
|
|
83
|
-
mint_authority:,
|
|
84
|
-
freeze_authority: nil,
|
|
85
|
-
mint_account: Solace::Keypair.generate
|
|
86
|
-
)
|
|
87
|
-
# Mint accounts need 82 bytes of space, and we need to fund it with enough lamports to be rent-exempt
|
|
88
|
-
rent_lamports = connection.get_minimum_lamports_for_rent_exemption(82)
|
|
89
|
-
|
|
90
|
-
# Build the account for the mint
|
|
91
|
-
create_account_ix = Composers::SystemProgramCreateAccountComposer.new(
|
|
92
|
-
from: funder,
|
|
93
|
-
new_account: mint_account,
|
|
94
|
-
owner: program_id,
|
|
95
|
-
lamports: rent_lamports,
|
|
96
|
-
space: 82
|
|
97
|
-
)
|
|
42
|
+
private
|
|
98
43
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
decimals: decimals,
|
|
102
|
-
mint_account: mint_account,
|
|
103
|
-
mint_authority: mint_authority,
|
|
104
|
-
freeze_authority: freeze_authority
|
|
105
|
-
)
|
|
106
|
-
|
|
107
|
-
TransactionComposer
|
|
108
|
-
.new(connection: @connection)
|
|
109
|
-
.add_instruction(create_account_ix)
|
|
110
|
-
.add_instruction(initialize_mint_ix)
|
|
44
|
+
def initialize_mint_composer_class
|
|
45
|
+
Composers::SplTokenProgramInitializeMintComposer
|
|
111
46
|
end
|
|
112
|
-
# rubocop:enable Metrics/MethodLength
|
|
113
|
-
|
|
114
|
-
# Mint tokens to a token account
|
|
115
|
-
#
|
|
116
|
-
# @param payer [#to_s, PublicKey] The keypair that will pay for fees and rent.
|
|
117
|
-
# @param sign [Boolean] Whether to sign the transaction.
|
|
118
|
-
# @param execute [Boolean] Whether to execute the transaction.
|
|
119
|
-
# @param composer_opts [Hash] Options for calling the compose_mint_to method.
|
|
120
|
-
# @return [String] The signature of the transaction.
|
|
121
|
-
def mint_to(
|
|
122
|
-
payer:,
|
|
123
|
-
sign: true,
|
|
124
|
-
execute: true,
|
|
125
|
-
**composer_opts
|
|
126
|
-
)
|
|
127
|
-
composer = compose_mint_to(**composer_opts)
|
|
128
|
-
|
|
129
|
-
yield composer if block_given?
|
|
130
|
-
|
|
131
|
-
tx = composer
|
|
132
|
-
.set_fee_payer(payer)
|
|
133
|
-
.compose_transaction
|
|
134
|
-
|
|
135
|
-
if sign
|
|
136
|
-
tx.sign(
|
|
137
|
-
payer,
|
|
138
|
-
composer_opts[:mint_authority]
|
|
139
|
-
)
|
|
140
47
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
tx
|
|
48
|
+
def mint_to_composer_class
|
|
49
|
+
Composers::SplTokenProgramMintToComposer
|
|
145
50
|
end
|
|
146
51
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
# @param [Integer] amount The amount of tokens to mint.
|
|
150
|
-
# @param [#to_s, PublicKey] mint The mint of the token.
|
|
151
|
-
# @param [#to_s, PublicKey] destination The destination of the token.
|
|
152
|
-
# @param [#to_s, PublicKey] mint_authority The mint authority of the token.
|
|
153
|
-
# @return [TransactionComposer] A composer with required instructions.
|
|
154
|
-
#
|
|
155
|
-
# @param [Boolean] ensure_account
|
|
156
|
-
def compose_mint_to(
|
|
157
|
-
mint:,
|
|
158
|
-
amount:,
|
|
159
|
-
destination:,
|
|
160
|
-
mint_authority:
|
|
161
|
-
)
|
|
162
|
-
ix = Composers::SplTokenProgramMintToComposer.new(
|
|
163
|
-
amount: amount,
|
|
164
|
-
mint: mint,
|
|
165
|
-
destination: destination,
|
|
166
|
-
mint_authority: mint_authority
|
|
167
|
-
)
|
|
168
|
-
|
|
169
|
-
TransactionComposer
|
|
170
|
-
.new(connection: connection)
|
|
171
|
-
.add_instruction(ix)
|
|
52
|
+
def transfer_composer_class
|
|
53
|
+
Composers::SplTokenProgramTransferComposer
|
|
172
54
|
end
|
|
173
55
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
# @param payer [#to_s, PublicKey] The keypair that will pay for fees and rent.
|
|
177
|
-
# @param sign [Boolean] Whether to sign the transaction.
|
|
178
|
-
# @param execute [Boolean] Whether to execute the transaction.
|
|
179
|
-
# @param composer_opts [Hash] Options for calling the compose_transfer method.
|
|
180
|
-
# @return [String] The signature of the transaction.
|
|
181
|
-
def transfer(
|
|
182
|
-
payer:,
|
|
183
|
-
sign: true,
|
|
184
|
-
execute: true,
|
|
185
|
-
**composer_opts
|
|
186
|
-
)
|
|
187
|
-
composer = compose_transfer(**composer_opts)
|
|
188
|
-
|
|
189
|
-
yield composer if block_given?
|
|
190
|
-
|
|
191
|
-
tx = composer
|
|
192
|
-
.set_fee_payer(payer)
|
|
193
|
-
.compose_transaction
|
|
194
|
-
|
|
195
|
-
if sign
|
|
196
|
-
tx.sign(
|
|
197
|
-
payer,
|
|
198
|
-
composer_opts[:owner]
|
|
199
|
-
)
|
|
200
|
-
|
|
201
|
-
connection.send_transaction(tx.serialize) if execute
|
|
202
|
-
end
|
|
203
|
-
tx
|
|
204
|
-
end
|
|
205
|
-
|
|
206
|
-
# Prepares a transfer instruction and returns the signed transaction.
|
|
207
|
-
#
|
|
208
|
-
# @param source [#to_s, PublicKey] The source token account address.
|
|
209
|
-
# @param destination [#to_s, PublicKey] The destination token account address.
|
|
210
|
-
# @param amount [Integer] The number of tokens to transfer.
|
|
211
|
-
# @param owner [#to_s, PublicKey] The keypair of the owner of the source account.
|
|
212
|
-
# @return [TransactionComposer] A composer with required instructions.
|
|
213
|
-
#
|
|
214
|
-
def compose_transfer(
|
|
215
|
-
amount:,
|
|
216
|
-
source:,
|
|
217
|
-
destination:,
|
|
218
|
-
owner:
|
|
219
|
-
)
|
|
220
|
-
ix = Composers::SplTokenProgramTransferComposer.new(
|
|
221
|
-
amount: amount,
|
|
222
|
-
owner: owner,
|
|
223
|
-
source: source,
|
|
224
|
-
destination: destination
|
|
225
|
-
)
|
|
226
|
-
|
|
227
|
-
TransactionComposer
|
|
228
|
-
.new(connection: connection)
|
|
229
|
-
.add_instruction(ix)
|
|
230
|
-
end
|
|
231
|
-
|
|
232
|
-
# Transfers tokens with decimal precision and validation checks
|
|
233
|
-
#
|
|
234
|
-
# @param payer [#to_s, PublicKey] The keypair that will pay for fees and rent.
|
|
235
|
-
# @param sign [Boolean] Whether to sign the transaction.
|
|
236
|
-
# @param execute [Boolean] Whether to execute the transaction.
|
|
237
|
-
# @param composer_opts [Hash] Options for calling the compose_transfer_checked method.
|
|
238
|
-
# @return [String] The signature of the transaction.
|
|
239
|
-
def transfer_checked(
|
|
240
|
-
payer:,
|
|
241
|
-
sign: true,
|
|
242
|
-
execute: true,
|
|
243
|
-
**composer_opts
|
|
244
|
-
)
|
|
245
|
-
composer = compose_transfer_checked(**composer_opts)
|
|
246
|
-
|
|
247
|
-
yield composer if block_given?
|
|
248
|
-
|
|
249
|
-
tx = composer
|
|
250
|
-
.set_fee_payer(payer)
|
|
251
|
-
.compose_transaction
|
|
252
|
-
|
|
253
|
-
if sign
|
|
254
|
-
tx.sign(
|
|
255
|
-
payer,
|
|
256
|
-
composer_opts[:authority]
|
|
257
|
-
)
|
|
258
|
-
|
|
259
|
-
connection.send_transaction(tx.serialize) if execute
|
|
260
|
-
end
|
|
261
|
-
|
|
262
|
-
tx
|
|
263
|
-
end
|
|
264
|
-
|
|
265
|
-
# Prepares a transfer checked instruction and returns the signed transaction.
|
|
266
|
-
#
|
|
267
|
-
# @param amount [Integer] The number of tokens to transfer.
|
|
268
|
-
# @param decimals [Integer] The number of decimals for the token.
|
|
269
|
-
# @param from [#to_s, PublicKey] The source token account address.
|
|
270
|
-
# @param to [#to_s, PublicKey] The destination token account address.
|
|
271
|
-
# @param mint [#to_s, PublicKey] The mint address
|
|
272
|
-
# @param authority [#to_s, PublicKey] The keypair of the owner of the source account.
|
|
273
|
-
# @return [TransactionComposer] A composer with required instructions.
|
|
274
|
-
def compose_transfer_checked(
|
|
275
|
-
to:,
|
|
276
|
-
from:,
|
|
277
|
-
mint:,
|
|
278
|
-
authority:,
|
|
279
|
-
amount:,
|
|
280
|
-
decimals:
|
|
281
|
-
)
|
|
282
|
-
ix = Composers::SplTokenProgramTransferCheckedComposer.new(
|
|
283
|
-
to: to,
|
|
284
|
-
from: from,
|
|
285
|
-
mint: mint,
|
|
286
|
-
authority: authority,
|
|
287
|
-
amount: amount,
|
|
288
|
-
decimals: decimals
|
|
289
|
-
)
|
|
290
|
-
|
|
291
|
-
TransactionComposer
|
|
292
|
-
.new(connection: connection)
|
|
293
|
-
.add_instruction(ix)
|
|
56
|
+
def transfer_checked_composer_class
|
|
57
|
+
Composers::SplTokenProgramTransferCheckedComposer
|
|
294
58
|
end
|
|
295
59
|
end
|
|
296
60
|
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solace
|
|
4
|
+
module Programs
|
|
5
|
+
# Client for interacting with the Token-2022 Program (formerly Token Extensions).
|
|
6
|
+
#
|
|
7
|
+
# Token-2022 is the successor to the legacy SPL Token program
|
|
8
|
+
# (+TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb+). Its base instructions —
|
|
9
|
+
# Transfer, TransferChecked, CloseAccount, MintTo, InitializeMint — are
|
|
10
|
+
# wire-compatible with the legacy program; only the program account they
|
|
11
|
+
# target is different. The shared method shape comes from
|
|
12
|
+
# {TokenProgramInterface}; this class supplies the Token-2022-bound
|
|
13
|
+
# composer classes. Branching between SPL Token and Token-2022 belongs at
|
|
14
|
+
# the call site, where the developer already knows which mint they hold.
|
|
15
|
+
#
|
|
16
|
+
# Important: mints owned by Token-2022 (e.g. PYUSD on Solana) derive
|
|
17
|
+
# their Associated Token Accounts with this program ID in the seed.
|
|
18
|
+
# When working with such a mint, pass
|
|
19
|
+
# +token_program_id: Solace::Constants::TOKEN_2022_PROGRAM_ID+ to
|
|
20
|
+
# {Programs::AssociatedTokenAccount.get_address}. Use
|
|
21
|
+
# {Connection#get_mint_program_id} to discover which token program owns
|
|
22
|
+
# a given mint at runtime.
|
|
23
|
+
#
|
|
24
|
+
# This class does not yet expose the Token-2022 extension instructions
|
|
25
|
+
# (transfer hooks, transfer fees, confidential transfer, etc.); those
|
|
26
|
+
# are out of scope for the base instruction surface.
|
|
27
|
+
#
|
|
28
|
+
# @example Create a Token-2022 mint
|
|
29
|
+
# program = Solace::Programs::Token2022.new(connection: connection)
|
|
30
|
+
#
|
|
31
|
+
# tx = program.create_mint(
|
|
32
|
+
# payer: payer,
|
|
33
|
+
# funder: funder,
|
|
34
|
+
# decimals: 6,
|
|
35
|
+
# mint_account: mint_account,
|
|
36
|
+
# mint_authority: mint_authority
|
|
37
|
+
# )
|
|
38
|
+
#
|
|
39
|
+
# @see Solace::Programs::SplToken
|
|
40
|
+
# @since 0.1.5
|
|
41
|
+
class Token2022 < Base
|
|
42
|
+
include TokenProgramInterface
|
|
43
|
+
|
|
44
|
+
# Initializes a new Token-2022 client.
|
|
45
|
+
#
|
|
46
|
+
# @param connection [Solace::Connection] The connection to the Solana cluster.
|
|
47
|
+
def initialize(connection:)
|
|
48
|
+
super(connection: connection, program_id: Solace::Constants::TOKEN_2022_PROGRAM_ID)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
def initialize_mint_composer_class
|
|
54
|
+
Composers::Token2022ProgramInitializeMintComposer
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def mint_to_composer_class
|
|
58
|
+
Composers::Token2022ProgramMintToComposer
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def transfer_composer_class
|
|
62
|
+
Composers::Token2022ProgramTransferComposer
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def transfer_checked_composer_class
|
|
66
|
+
Composers::Token2022ProgramTransferCheckedComposer
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solace
|
|
4
|
+
module Programs
|
|
5
|
+
# Mixin describing the common surface of a token-program client.
|
|
6
|
+
#
|
|
7
|
+
# The legacy SPL Token program and Token-2022 expose a wire-compatible
|
|
8
|
+
# base instruction set (Transfer, TransferChecked, CloseAccount, MintTo,
|
|
9
|
+
# InitializeMint). This module captures the *shape* of a client that
|
|
10
|
+
# speaks that surface — the public methods +create_mint+, +mint_to+,
|
|
11
|
+
# +transfer+, +transfer_checked+ and their +compose_*+ pairs — without
|
|
12
|
+
# binding to either program.
|
|
13
|
+
#
|
|
14
|
+
# State (connection, program_id) lives on {Programs::Base}; this module
|
|
15
|
+
# is purely behavior. Including classes must implement four private
|
|
16
|
+
# readers that name the composer class for each operation:
|
|
17
|
+
#
|
|
18
|
+
# - {#initialize_mint_composer_class}
|
|
19
|
+
# - {#mint_to_composer_class}
|
|
20
|
+
# - {#transfer_composer_class}
|
|
21
|
+
# - {#transfer_checked_composer_class}
|
|
22
|
+
#
|
|
23
|
+
# Each composer returned by those readers is itself bound to a single
|
|
24
|
+
# on-chain program, which is how this mixin keeps the boundary clean:
|
|
25
|
+
# +SplToken+ and +Token2022+ share *methods* but never share a composer.
|
|
26
|
+
#
|
|
27
|
+
# @see Solace::Programs::SplToken
|
|
28
|
+
# @see Solace::Programs::Token2022
|
|
29
|
+
# @since 0.1.5
|
|
30
|
+
# rubocop:disable Metrics/ModuleLength
|
|
31
|
+
module TokenProgramInterface
|
|
32
|
+
# Creates a new mint, signs it, and (optionally) sends it.
|
|
33
|
+
#
|
|
34
|
+
# @param payer [#to_s, PublicKey] The keypair that will pay for fees and rent.
|
|
35
|
+
# @param sign [Boolean] Whether to sign the transaction.
|
|
36
|
+
# @param execute [Boolean] Whether to execute the transaction.
|
|
37
|
+
# @param composer_opts [Hash] Options for {#compose_create_mint}.
|
|
38
|
+
# @return [Transaction] The created or sent transaction.
|
|
39
|
+
def create_mint(
|
|
40
|
+
payer:,
|
|
41
|
+
sign: true,
|
|
42
|
+
execute: true,
|
|
43
|
+
**composer_opts
|
|
44
|
+
)
|
|
45
|
+
composer = compose_create_mint(**composer_opts)
|
|
46
|
+
|
|
47
|
+
yield composer if block_given?
|
|
48
|
+
|
|
49
|
+
tx = composer
|
|
50
|
+
.set_fee_payer(payer)
|
|
51
|
+
.compose_transaction
|
|
52
|
+
|
|
53
|
+
if sign
|
|
54
|
+
tx.sign(
|
|
55
|
+
payer,
|
|
56
|
+
composer_opts[:funder],
|
|
57
|
+
composer_opts[:mint_account]
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
connection.send_transaction(tx.serialize) if execute
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
tx
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Prepares a new mint transaction.
|
|
67
|
+
#
|
|
68
|
+
# @param funder [#to_s, PublicKey] The keypair that will pay for rent of the new mint account.
|
|
69
|
+
# @param decimals [Integer] The number of decimal places for the token.
|
|
70
|
+
# @param mint_authority [#to_s, PublicKey] The base58 public key for the mint authority.
|
|
71
|
+
# @param freeze_authority [#to_s, PublicKey] (Optional) The base58 public key for the freeze authority.
|
|
72
|
+
# @param mint_account [#to_s, PublicKey] (Optional) The keypair for the new mint.
|
|
73
|
+
# @return [TransactionComposer] A composer with required instructions.
|
|
74
|
+
# rubocop:disable Metrics/MethodLength
|
|
75
|
+
def compose_create_mint(
|
|
76
|
+
funder:,
|
|
77
|
+
decimals:,
|
|
78
|
+
mint_authority:,
|
|
79
|
+
freeze_authority: nil,
|
|
80
|
+
mint_account: Solace::Keypair.generate
|
|
81
|
+
)
|
|
82
|
+
# Mint accounts need 82 bytes of space, and we need to fund it with enough lamports to be rent-exempt
|
|
83
|
+
rent_lamports = connection.get_minimum_lamports_for_rent_exemption(82)
|
|
84
|
+
|
|
85
|
+
# Build the account for the mint
|
|
86
|
+
create_account_ix = Composers::SystemProgramCreateAccountComposer.new(
|
|
87
|
+
from: funder,
|
|
88
|
+
new_account: mint_account,
|
|
89
|
+
owner: program_id,
|
|
90
|
+
lamports: rent_lamports,
|
|
91
|
+
space: 82
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
# Build the initialize mint composer (per-program class supplied by includer)
|
|
95
|
+
initialize_mint_ix = initialize_mint_composer_class.new(
|
|
96
|
+
decimals: decimals,
|
|
97
|
+
mint_account: mint_account,
|
|
98
|
+
mint_authority: mint_authority,
|
|
99
|
+
freeze_authority: freeze_authority
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
TransactionComposer
|
|
103
|
+
.new(connection: connection)
|
|
104
|
+
.add_instruction(create_account_ix)
|
|
105
|
+
.add_instruction(initialize_mint_ix)
|
|
106
|
+
end
|
|
107
|
+
# rubocop:enable Metrics/MethodLength
|
|
108
|
+
|
|
109
|
+
# Mints tokens to a token account.
|
|
110
|
+
#
|
|
111
|
+
# @param payer [#to_s, PublicKey] The keypair that will pay for fees and rent.
|
|
112
|
+
# @param sign [Boolean] Whether to sign the transaction.
|
|
113
|
+
# @param execute [Boolean] Whether to execute the transaction.
|
|
114
|
+
# @param composer_opts [Hash] Options for {#compose_mint_to}.
|
|
115
|
+
# @return [Transaction] The created or sent transaction.
|
|
116
|
+
def mint_to(
|
|
117
|
+
payer:,
|
|
118
|
+
sign: true,
|
|
119
|
+
execute: true,
|
|
120
|
+
**composer_opts
|
|
121
|
+
)
|
|
122
|
+
composer = compose_mint_to(**composer_opts)
|
|
123
|
+
|
|
124
|
+
yield composer if block_given?
|
|
125
|
+
|
|
126
|
+
tx = composer
|
|
127
|
+
.set_fee_payer(payer)
|
|
128
|
+
.compose_transaction
|
|
129
|
+
|
|
130
|
+
if sign
|
|
131
|
+
tx.sign(
|
|
132
|
+
payer,
|
|
133
|
+
composer_opts[:mint_authority]
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
connection.send_transaction(tx.serialize) if execute
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
tx
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# Prepares a mint_to instruction.
|
|
143
|
+
#
|
|
144
|
+
# @param amount [Integer] The amount of tokens to mint.
|
|
145
|
+
# @param mint [#to_s, PublicKey] The mint of the token.
|
|
146
|
+
# @param destination [#to_s, PublicKey] The destination token account.
|
|
147
|
+
# @param mint_authority [#to_s, PublicKey] The mint authority.
|
|
148
|
+
# @return [TransactionComposer] A composer with the mint_to instruction.
|
|
149
|
+
def compose_mint_to(
|
|
150
|
+
mint:,
|
|
151
|
+
amount:,
|
|
152
|
+
destination:,
|
|
153
|
+
mint_authority:
|
|
154
|
+
)
|
|
155
|
+
ix = mint_to_composer_class.new(
|
|
156
|
+
amount: amount,
|
|
157
|
+
mint: mint,
|
|
158
|
+
destination: destination,
|
|
159
|
+
mint_authority: mint_authority
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
TransactionComposer
|
|
163
|
+
.new(connection: connection)
|
|
164
|
+
.add_instruction(ix)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# Transfers tokens from one account to another.
|
|
168
|
+
#
|
|
169
|
+
# @param payer [#to_s, PublicKey] The keypair that will pay for fees and rent.
|
|
170
|
+
# @param sign [Boolean] Whether to sign the transaction.
|
|
171
|
+
# @param execute [Boolean] Whether to execute the transaction.
|
|
172
|
+
# @param composer_opts [Hash] Options for {#compose_transfer}.
|
|
173
|
+
# @return [Transaction] The created or sent transaction.
|
|
174
|
+
def transfer(
|
|
175
|
+
payer:,
|
|
176
|
+
sign: true,
|
|
177
|
+
execute: true,
|
|
178
|
+
**composer_opts
|
|
179
|
+
)
|
|
180
|
+
composer = compose_transfer(**composer_opts)
|
|
181
|
+
|
|
182
|
+
yield composer if block_given?
|
|
183
|
+
|
|
184
|
+
tx = composer
|
|
185
|
+
.set_fee_payer(payer)
|
|
186
|
+
.compose_transaction
|
|
187
|
+
|
|
188
|
+
if sign
|
|
189
|
+
tx.sign(
|
|
190
|
+
payer,
|
|
191
|
+
composer_opts[:owner]
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
connection.send_transaction(tx.serialize) if execute
|
|
195
|
+
end
|
|
196
|
+
tx
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# Prepares a transfer instruction.
|
|
200
|
+
#
|
|
201
|
+
# @param source [#to_s, PublicKey] The source token account address.
|
|
202
|
+
# @param destination [#to_s, PublicKey] The destination token account address.
|
|
203
|
+
# @param amount [Integer] The number of tokens to transfer.
|
|
204
|
+
# @param owner [#to_s, PublicKey] The owner of the source account.
|
|
205
|
+
# @return [TransactionComposer] A composer with the transfer instruction.
|
|
206
|
+
def compose_transfer(
|
|
207
|
+
amount:,
|
|
208
|
+
source:,
|
|
209
|
+
destination:,
|
|
210
|
+
owner:
|
|
211
|
+
)
|
|
212
|
+
ix = transfer_composer_class.new(
|
|
213
|
+
amount: amount,
|
|
214
|
+
owner: owner,
|
|
215
|
+
source: source,
|
|
216
|
+
destination: destination
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
TransactionComposer
|
|
220
|
+
.new(connection: connection)
|
|
221
|
+
.add_instruction(ix)
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
# Transfers tokens with decimal precision and validation checks.
|
|
225
|
+
#
|
|
226
|
+
# @param payer [#to_s, PublicKey] The keypair that will pay for fees and rent.
|
|
227
|
+
# @param sign [Boolean] Whether to sign the transaction.
|
|
228
|
+
# @param execute [Boolean] Whether to execute the transaction.
|
|
229
|
+
# @param composer_opts [Hash] Options for {#compose_transfer_checked}.
|
|
230
|
+
# @return [Transaction] The created or sent transaction.
|
|
231
|
+
def transfer_checked(
|
|
232
|
+
payer:,
|
|
233
|
+
sign: true,
|
|
234
|
+
execute: true,
|
|
235
|
+
**composer_opts
|
|
236
|
+
)
|
|
237
|
+
composer = compose_transfer_checked(**composer_opts)
|
|
238
|
+
|
|
239
|
+
yield composer if block_given?
|
|
240
|
+
|
|
241
|
+
tx = composer
|
|
242
|
+
.set_fee_payer(payer)
|
|
243
|
+
.compose_transaction
|
|
244
|
+
|
|
245
|
+
if sign
|
|
246
|
+
tx.sign(
|
|
247
|
+
payer,
|
|
248
|
+
composer_opts[:authority]
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
connection.send_transaction(tx.serialize) if execute
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
tx
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
# Prepares a transfer_checked instruction.
|
|
258
|
+
#
|
|
259
|
+
# @param amount [Integer] The number of tokens to transfer.
|
|
260
|
+
# @param decimals [Integer] The number of decimals for the token.
|
|
261
|
+
# @param from [#to_s, PublicKey] The source token account address.
|
|
262
|
+
# @param to [#to_s, PublicKey] The destination token account address.
|
|
263
|
+
# @param mint [#to_s, PublicKey] The mint address.
|
|
264
|
+
# @param authority [#to_s, PublicKey] The owner of the source account.
|
|
265
|
+
# @return [TransactionComposer] A composer with the transfer_checked instruction.
|
|
266
|
+
def compose_transfer_checked(
|
|
267
|
+
to:,
|
|
268
|
+
from:,
|
|
269
|
+
mint:,
|
|
270
|
+
authority:,
|
|
271
|
+
amount:,
|
|
272
|
+
decimals:
|
|
273
|
+
)
|
|
274
|
+
ix = transfer_checked_composer_class.new(
|
|
275
|
+
to: to,
|
|
276
|
+
from: from,
|
|
277
|
+
mint: mint,
|
|
278
|
+
authority: authority,
|
|
279
|
+
amount: amount,
|
|
280
|
+
decimals: decimals
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
TransactionComposer
|
|
284
|
+
.new(connection: connection)
|
|
285
|
+
.add_instruction(ix)
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
private
|
|
289
|
+
|
|
290
|
+
# @return [Class] Composer class used by {#compose_create_mint}.
|
|
291
|
+
def initialize_mint_composer_class
|
|
292
|
+
raise NotImplementedError, "#{self.class} must implement #initialize_mint_composer_class"
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
# @return [Class] Composer class used by {#compose_mint_to}.
|
|
296
|
+
def mint_to_composer_class
|
|
297
|
+
raise NotImplementedError, "#{self.class} must implement #mint_to_composer_class"
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
# @return [Class] Composer class used by {#compose_transfer}.
|
|
301
|
+
def transfer_composer_class
|
|
302
|
+
raise NotImplementedError, "#{self.class} must implement #transfer_composer_class"
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
# @return [Class] Composer class used by {#compose_transfer_checked}.
|
|
306
|
+
def transfer_checked_composer_class
|
|
307
|
+
raise NotImplementedError, "#{self.class} must implement #transfer_checked_composer_class"
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
# rubocop:enable Metrics/ModuleLength
|
|
311
|
+
end
|
|
312
|
+
end
|
data/lib/solace/version.rb
CHANGED
data/lib/solace.rb
CHANGED
|
@@ -68,5 +68,7 @@ Dir[File.join(__dir__, 'solace/composers', '**', '*.rb')].each { |file| require
|
|
|
68
68
|
Dir[File.join(__dir__, 'solace/instructions', '**', '*.rb')].each { |file| require file }
|
|
69
69
|
|
|
70
70
|
# Programs
|
|
71
|
+
require_relative 'solace/programs/token_program_interface'
|
|
71
72
|
require_relative 'solace/programs/spl_token'
|
|
73
|
+
require_relative 'solace/programs/token_2022'
|
|
72
74
|
require_relative 'solace/programs/associated_token_account'
|