solace 0.1.4 → 0.1.6
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/lib/solace/composers/associated_token_account_program_create_account_composer.rb +11 -10
- data/lib/solace/composers/associated_token_account_program_create_idempotent_account_composer.rb +2 -1
- data/lib/solace/composers/base.rb +1 -1
- data/lib/solace/composers/spl_token_program_close_account_composer.rb +3 -3
- data/lib/solace/composers/spl_token_program_initialize_mint_composer.rb +5 -5
- data/lib/solace/composers/spl_token_program_mint_to_composer.rb +4 -4
- data/lib/solace/composers/spl_token_program_transfer_checked_composer.rb +6 -6
- data/lib/solace/composers/spl_token_program_transfer_composer.rb +4 -4
- data/lib/solace/composers/system_program_create_account_composer.rb +5 -5
- data/lib/solace/composers/system_program_transfer_composer.rb +3 -3
- 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 +29 -9
- data/lib/solace/constants.rb +8 -2
- data/lib/solace/errors/confirmation_timeout.rb +4 -4
- data/lib/solace/errors/rpc_error.rb +4 -4
- data/lib/solace/instructions/associated_token_account/create_account_instruction.rb +2 -1
- data/lib/solace/instructions/spl_token/close_account_instruction.rb +2 -2
- data/lib/solace/instructions/spl_token/initialize_account_instruction.rb +2 -2
- data/lib/solace/instructions/spl_token/initialize_mint_instruction.rb +2 -2
- data/lib/solace/instructions/spl_token/mint_to_instruction.rb +2 -2
- data/lib/solace/instructions/spl_token/transfer_checked_instruction.rb +3 -3
- data/lib/solace/instructions/spl_token/transfer_instruction.rb +2 -2
- data/lib/solace/instructions/system_program/create_account_instruction.rb +2 -2
- data/lib/solace/instructions/system_program/transfer_instruction.rb +2 -2
- 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/message.rb +5 -5
- data/lib/solace/programs/associated_token_account.rb +35 -17
- 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/serializers/address_lookup_table_deserializer.rb +2 -2
- data/lib/solace/serializers/base_deserializer.rb +1 -1
- data/lib/solace/serializers/instruction_deserializer.rb +2 -2
- data/lib/solace/serializers/message_deserializer.rb +3 -3
- data/lib/solace/serializers/transaction_deserializer.rb +1 -1
- data/lib/solace/tokens/token.rb +1 -1
- data/lib/solace/tokens.rb +2 -2
- data/lib/solace/transaction.rb +1 -1
- data/lib/solace/transaction_composer.rb +5 -5
- data/lib/solace/utils/account_context.rb +9 -9
- data/lib/solace/utils/codecs.rb +309 -49
- data/lib/solace/utils/rpc_client.rb +9 -9
- data/lib/solace/version.rb +1 -1
- data/lib/solace.rb +2 -0
- metadata +124 -9
- data/CHANGELOG +0 -226
- data/LICENSE +0 -21
- data/README.md +0 -518
data/lib/solace/connection.rb
CHANGED
|
@@ -33,6 +33,7 @@ module Solace
|
|
|
33
33
|
# Solace::Errors::ConfirmationTimeout
|
|
34
34
|
# ]
|
|
35
35
|
# @since 0.0.1
|
|
36
|
+
# rubocop:disable Metrics/ClassLength
|
|
36
37
|
class Connection
|
|
37
38
|
# @!attribute [r] rpc_url
|
|
38
39
|
# The URL of the Solana RPC node
|
|
@@ -73,7 +74,7 @@ module Solace
|
|
|
73
74
|
# Set default options for rpc requests
|
|
74
75
|
@default_options = {
|
|
75
76
|
commitment: commitment,
|
|
76
|
-
encoding:
|
|
77
|
+
encoding: encoding
|
|
77
78
|
}
|
|
78
79
|
end
|
|
79
80
|
|
|
@@ -196,15 +197,33 @@ module Solace
|
|
|
196
197
|
@rpc_client.rpc_request('getTokenAccountBalance', [token_account, default_options]).dig('result', 'value')
|
|
197
198
|
end
|
|
198
199
|
|
|
199
|
-
# Gets the token accounts by owner
|
|
200
|
+
# Gets the token accounts by owner.
|
|
201
|
+
#
|
|
202
|
+
# Defaults to the legacy SPL Token program; pass
|
|
203
|
+
# +token_program_id: Solace::Constants::TOKEN_2022_PROGRAM_ID+ for Token-2022.
|
|
200
204
|
#
|
|
201
205
|
# @param owner [String] The public key of the owner
|
|
202
|
-
# @
|
|
203
|
-
|
|
204
|
-
|
|
206
|
+
# @param token_program_id [String] The token program to filter by (defaults to legacy SPL Token)
|
|
207
|
+
# @return [Array<Hash>] The token accounts owned by the owner under the given token program
|
|
208
|
+
def get_token_accounts_by_owner(owner, token_program_id: Constants::TOKEN_PROGRAM_ID)
|
|
209
|
+
params = [owner, { programId: token_program_id }, default_options]
|
|
205
210
|
@rpc_client.rpc_request('getTokenAccountsByOwner', params).dig('result', 'value')
|
|
206
211
|
end
|
|
207
212
|
|
|
213
|
+
# Discovery-only helper: returns the program ID that owns a given mint.
|
|
214
|
+
#
|
|
215
|
+
# Use this to dispatch between {Constants::TOKEN_PROGRAM_ID} and
|
|
216
|
+
# {Constants::TOKEN_2022_PROGRAM_ID} when the mint's program is not known
|
|
217
|
+
# ahead of time. If you also need the rest of the mint's account data
|
|
218
|
+
# (decimals, supply, ...), call {#get_account_info} directly and read
|
|
219
|
+
# +'owner'+ yourself — calling both would cost two RPC roundtrips.
|
|
220
|
+
#
|
|
221
|
+
# @param mint [String] The mint address
|
|
222
|
+
# @return [String, nil] The program ID that owns the mint, or +nil+ if the account does not exist
|
|
223
|
+
def get_mint_program_id(mint)
|
|
224
|
+
get_account_info(mint)&.dig('owner')
|
|
225
|
+
end
|
|
226
|
+
|
|
208
227
|
# Get the transaction by signature
|
|
209
228
|
#
|
|
210
229
|
# @param signature [String] The signature of the transaction
|
|
@@ -247,9 +266,9 @@ module Solace
|
|
|
247
266
|
# @return [Hash] The options for the send_transaction call
|
|
248
267
|
def build_send_transaction_options(overrides)
|
|
249
268
|
{
|
|
250
|
-
skipPreflight:
|
|
251
|
-
encoding:
|
|
252
|
-
commitment:
|
|
269
|
+
skipPreflight: false,
|
|
270
|
+
encoding: default_options[:encoding],
|
|
271
|
+
commitment: default_options[:commitment],
|
|
253
272
|
preflightCommitment: default_options[:commitment]
|
|
254
273
|
}.merge(overrides)
|
|
255
274
|
end
|
|
@@ -288,7 +307,7 @@ module Solace
|
|
|
288
307
|
raise ArgumentError, 'Block required' unless block_given?
|
|
289
308
|
|
|
290
309
|
signature = extract_signature_from(yield)
|
|
291
|
-
deadline
|
|
310
|
+
deadline = monotonic_deadline(timeout)
|
|
292
311
|
|
|
293
312
|
# Wait for confirmation
|
|
294
313
|
until deadline_passed?(deadline)
|
|
@@ -335,4 +354,5 @@ module Solace
|
|
|
335
354
|
Process.clock_gettime(Process::CLOCK_MONOTONIC) + seconds
|
|
336
355
|
end
|
|
337
356
|
end
|
|
357
|
+
# rubocop:enable Metrics/ClassLength
|
|
338
358
|
end
|
data/lib/solace/constants.rb
CHANGED
|
@@ -23,10 +23,16 @@ module Solace
|
|
|
23
23
|
COMPUTE_BUDGET_PROGRAM_ID = 'ComputeBudget111111111111111111111111111111'
|
|
24
24
|
|
|
25
25
|
# @!attribute TOKEN_PROGRAM_ID
|
|
26
|
-
# The public key of the SPL Token Program
|
|
27
|
-
# This is the same across all Solana clusters
|
|
26
|
+
# The public key of the SPL Token Program (legacy).
|
|
27
|
+
# This is the same across all Solana clusters.
|
|
28
28
|
TOKEN_PROGRAM_ID = 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'
|
|
29
29
|
|
|
30
|
+
# @!attribute TOKEN_2022_PROGRAM_ID
|
|
31
|
+
# The public key of the Token-2022 Program (formerly Token Extensions).
|
|
32
|
+
# This is the same across all Solana clusters. See {Programs::Token2022}
|
|
33
|
+
# for the full description of how it relates to the legacy program.
|
|
34
|
+
TOKEN_2022_PROGRAM_ID = 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb'
|
|
35
|
+
|
|
30
36
|
# @!attribute ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID
|
|
31
37
|
# The public key of the Associated Token Account Program
|
|
32
38
|
# This is the same across all Solana clusters
|
|
@@ -26,9 +26,9 @@ module Solace
|
|
|
26
26
|
# @param [Integer] timeout The time out reached
|
|
27
27
|
def initialize(message, signature:, commitment:, timeout:)
|
|
28
28
|
super(message)
|
|
29
|
-
@signature
|
|
29
|
+
@signature = signature
|
|
30
30
|
@commitment = commitment
|
|
31
|
-
@timeout
|
|
31
|
+
@timeout = timeout
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
# Formats a confirmation timeout error
|
|
@@ -40,9 +40,9 @@ module Solace
|
|
|
40
40
|
def self.format(signature, commitment, timeout)
|
|
41
41
|
new(
|
|
42
42
|
"Timed out waiting for signature #{signature} at commitment=#{commitment} after #{timeout}s",
|
|
43
|
-
signature:
|
|
43
|
+
signature: signature,
|
|
44
44
|
commitment: commitment,
|
|
45
|
-
timeout:
|
|
45
|
+
timeout: timeout
|
|
46
46
|
)
|
|
47
47
|
end
|
|
48
48
|
end
|
|
@@ -28,9 +28,9 @@ module Solace
|
|
|
28
28
|
# @param [Object] rpc_data The JSON-RPC error data
|
|
29
29
|
def initialize(message, rpc_code:, rpc_message:, rpc_data: nil)
|
|
30
30
|
super(message)
|
|
31
|
-
@rpc_code
|
|
31
|
+
@rpc_code = rpc_code
|
|
32
32
|
@rpc_message = rpc_message
|
|
33
|
-
@rpc_data
|
|
33
|
+
@rpc_data = rpc_data
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
# Formats a response to an error
|
|
@@ -40,8 +40,8 @@ module Solace
|
|
|
40
40
|
def self.format_response(response)
|
|
41
41
|
new(
|
|
42
42
|
"RPC error #{response['error']['code']}: #{response['error']['message']}",
|
|
43
|
-
rpc_data:
|
|
44
|
-
rpc_code:
|
|
43
|
+
rpc_data: response['error']['data'],
|
|
44
|
+
rpc_code: response['error']['code'],
|
|
45
45
|
rpc_message: response['error']['message']
|
|
46
46
|
)
|
|
47
47
|
end
|
|
@@ -63,7 +63,7 @@ module Solace
|
|
|
63
63
|
)
|
|
64
64
|
Solace::Instruction.new.tap do |ix|
|
|
65
65
|
ix.program_index = program_index
|
|
66
|
-
ix.accounts
|
|
66
|
+
ix.accounts = [
|
|
67
67
|
funder_index,
|
|
68
68
|
associated_token_account_index,
|
|
69
69
|
owner_index,
|
|
@@ -71,6 +71,7 @@ module Solace
|
|
|
71
71
|
system_program_index,
|
|
72
72
|
token_program_index
|
|
73
73
|
]
|
|
74
|
+
|
|
74
75
|
ix.data = data
|
|
75
76
|
end
|
|
76
77
|
end
|
|
@@ -30,8 +30,8 @@ module Solace
|
|
|
30
30
|
def self.build(account_index:, destination_index:, authority_index:, program_index:)
|
|
31
31
|
Solace::Instruction.new.tap do |ix|
|
|
32
32
|
ix.program_index = program_index
|
|
33
|
-
ix.accounts
|
|
34
|
-
ix.data
|
|
33
|
+
ix.accounts = [account_index, destination_index, authority_index]
|
|
34
|
+
ix.data = data
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
37
|
|
|
@@ -47,8 +47,8 @@ module Solace
|
|
|
47
47
|
)
|
|
48
48
|
Solace::Instruction.new.tap do |ix|
|
|
49
49
|
ix.program_index = program_index
|
|
50
|
-
ix.accounts
|
|
51
|
-
ix.data
|
|
50
|
+
ix.accounts = [account_index, mint_index, owner_index, rent_sysvar_index]
|
|
51
|
+
ix.data = data
|
|
52
52
|
end
|
|
53
53
|
end
|
|
54
54
|
|
|
@@ -49,8 +49,8 @@ module Solace
|
|
|
49
49
|
)
|
|
50
50
|
Solace::Instruction.new.tap do |ix|
|
|
51
51
|
ix.program_index = program_index
|
|
52
|
-
ix.accounts
|
|
53
|
-
ix.data
|
|
52
|
+
ix.accounts = [mint_account_index, rent_sysvar_index]
|
|
53
|
+
ix.data = data(decimals, mint_authority, freeze_authority)
|
|
54
54
|
end
|
|
55
55
|
end
|
|
56
56
|
|
|
@@ -39,8 +39,8 @@ module Solace
|
|
|
39
39
|
)
|
|
40
40
|
Solace::Instruction.new.tap do |ix|
|
|
41
41
|
ix.program_index = program_index
|
|
42
|
-
ix.accounts
|
|
43
|
-
ix.data
|
|
42
|
+
ix.accounts = [mint_index, destination_index, mint_authority_index]
|
|
43
|
+
ix.data = data(amount)
|
|
44
44
|
end
|
|
45
45
|
end
|
|
46
46
|
|
|
@@ -29,7 +29,7 @@ module Solace
|
|
|
29
29
|
# SPL Token Program transfer instruction layout:
|
|
30
30
|
# - 1 byte: instruction index (12 for transfer checked)
|
|
31
31
|
# - 8 bytes: amount (u64, little-endian)
|
|
32
|
-
# -
|
|
32
|
+
# - 1 byte: decimals (u8)
|
|
33
33
|
#
|
|
34
34
|
# @param amount [Integer] Amount to transfer (in tokens, according to mint's decimals)
|
|
35
35
|
# @param decimals [Integer] Number of decimals for the token
|
|
@@ -50,8 +50,8 @@ module Solace
|
|
|
50
50
|
)
|
|
51
51
|
Solace::Instruction.new.tap do |ix|
|
|
52
52
|
ix.program_index = program_index
|
|
53
|
-
ix.accounts
|
|
54
|
-
ix.data
|
|
53
|
+
ix.accounts = [from_index, mint_index, to_index, authority_index]
|
|
54
|
+
ix.data = data(amount, decimals)
|
|
55
55
|
end
|
|
56
56
|
end
|
|
57
57
|
|
|
@@ -60,8 +60,8 @@ module Solace
|
|
|
60
60
|
)
|
|
61
61
|
Solace::Instruction.new.tap do |ix|
|
|
62
62
|
ix.program_index = program_index
|
|
63
|
-
ix.accounts
|
|
64
|
-
ix.data
|
|
63
|
+
ix.accounts = [source_index, destination_index, owner_index]
|
|
64
|
+
ix.data = data(amount)
|
|
65
65
|
end
|
|
66
66
|
end
|
|
67
67
|
|
|
@@ -73,8 +73,8 @@ module Solace
|
|
|
73
73
|
)
|
|
74
74
|
Solace::Instruction.new.tap do |ix|
|
|
75
75
|
ix.program_index = system_program_index
|
|
76
|
-
ix.accounts
|
|
77
|
-
ix.data
|
|
76
|
+
ix.accounts = [from_index, new_account_index]
|
|
77
|
+
ix.data = data(lamports, space, owner)
|
|
78
78
|
end
|
|
79
79
|
end
|
|
80
80
|
# rubocop:enable Metrics/ParameterLists
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solace
|
|
4
|
+
module Instructions
|
|
5
|
+
module Token2022
|
|
6
|
+
# Instruction builder for Token-2022 CloseAccount.
|
|
7
|
+
#
|
|
8
|
+
# Closes a Token-2022 token account and transfers all remaining lamports
|
|
9
|
+
# to a destination account. The token account must have a balance of zero.
|
|
10
|
+
#
|
|
11
|
+
# Instruction discriminator: 9
|
|
12
|
+
#
|
|
13
|
+
# Accounts:
|
|
14
|
+
# 1. [writable] Token account to close
|
|
15
|
+
# 2. [writable] Destination account to receive lamports
|
|
16
|
+
# 3. [signer] Account authority
|
|
17
|
+
#
|
|
18
|
+
# @since 0.1.5
|
|
19
|
+
class CloseAccountInstruction
|
|
20
|
+
# Instruction discriminator for CloseAccount
|
|
21
|
+
INSTRUCTION_DISCRIMINATOR = [9].freeze
|
|
22
|
+
|
|
23
|
+
# Builds a CloseAccount instruction.
|
|
24
|
+
#
|
|
25
|
+
# @param account_index [Integer] Index of the token account to close
|
|
26
|
+
# @param destination_index [Integer] Index of the destination account
|
|
27
|
+
# @param authority_index [Integer] Index of the account authority
|
|
28
|
+
# @param program_index [Integer] Index of the Token-2022 program
|
|
29
|
+
# @return [Solace::Instruction] The constructed instruction
|
|
30
|
+
def self.build(account_index:, destination_index:, authority_index:, program_index:)
|
|
31
|
+
Solace::Instruction.new.tap do |ix|
|
|
32
|
+
ix.program_index = program_index
|
|
33
|
+
ix.accounts = [account_index, destination_index, authority_index]
|
|
34
|
+
ix.data = data
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Builds the data for a CloseAccount instruction.
|
|
39
|
+
#
|
|
40
|
+
# The BufferLayout is:
|
|
41
|
+
# - [Instruction Index (1 byte)]
|
|
42
|
+
#
|
|
43
|
+
# @return [Array] 1-byte instruction index
|
|
44
|
+
def self.data
|
|
45
|
+
INSTRUCTION_DISCRIMINATOR
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solace
|
|
4
|
+
module Instructions
|
|
5
|
+
module Token2022
|
|
6
|
+
# Instruction for initializing a new Token-2022 token account.
|
|
7
|
+
#
|
|
8
|
+
# Used in conjunction with the SystemProgram::CreateAccount instruction
|
|
9
|
+
# to create and initialize a new token account. For the common case of
|
|
10
|
+
# an associated token account, prefer
|
|
11
|
+
# {AssociatedTokenAccount::CreateAccountInstruction}.
|
|
12
|
+
#
|
|
13
|
+
# @example Build an InitializeAccount instruction
|
|
14
|
+
# instruction = Solace::Instructions::Token2022::InitializeAccountInstruction.build(
|
|
15
|
+
# account_index: 0,
|
|
16
|
+
# mint_index: 1,
|
|
17
|
+
# owner_index: 2,
|
|
18
|
+
# rent_sysvar_index: 3,
|
|
19
|
+
# program_index: 4
|
|
20
|
+
# )
|
|
21
|
+
#
|
|
22
|
+
# @since 0.1.5
|
|
23
|
+
class InitializeAccountInstruction
|
|
24
|
+
# @!attribute [Array<Integer>] INSTRUCTION_INDEX
|
|
25
|
+
# Instruction index for Token-2022's InitializeAccount instruction.
|
|
26
|
+
INSTRUCTION_INDEX = [1].freeze
|
|
27
|
+
|
|
28
|
+
# Builds a Token2022::InitializeAccount instruction.
|
|
29
|
+
#
|
|
30
|
+
# @param account_index [Integer] Index of the new token account in the transaction's accounts.
|
|
31
|
+
# @param mint_index [Integer] Index of the mint account in the transaction's accounts.
|
|
32
|
+
# @param owner_index [Integer] Index of the owner of the new account in the transaction's accounts.
|
|
33
|
+
# @param rent_sysvar_index [Integer] Index of the Rent Sysvar in the transaction's accounts.
|
|
34
|
+
# @param program_index [Integer] Index of the Token-2022 program in the transaction's accounts.
|
|
35
|
+
# @return [Solace::Instruction]
|
|
36
|
+
def self.build(
|
|
37
|
+
account_index:,
|
|
38
|
+
mint_index:,
|
|
39
|
+
owner_index:,
|
|
40
|
+
rent_sysvar_index:,
|
|
41
|
+
program_index:
|
|
42
|
+
)
|
|
43
|
+
Solace::Instruction.new.tap do |ix|
|
|
44
|
+
ix.program_index = program_index
|
|
45
|
+
ix.accounts = [account_index, mint_index, owner_index, rent_sysvar_index]
|
|
46
|
+
ix.data = data
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Builds the data for a Token2022::InitializeAccount instruction.
|
|
51
|
+
#
|
|
52
|
+
# The BufferLayout is:
|
|
53
|
+
# - [Instruction Index (1 byte)]
|
|
54
|
+
#
|
|
55
|
+
# @return [Array] 1-byte instruction index
|
|
56
|
+
def self.data
|
|
57
|
+
INSTRUCTION_INDEX
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solace
|
|
4
|
+
module Instructions
|
|
5
|
+
module Token2022
|
|
6
|
+
# Instruction for initializing a new Token-2022 mint.
|
|
7
|
+
#
|
|
8
|
+
# @example Build an InitializeMint instruction
|
|
9
|
+
# instruction = Solace::Instructions::Token2022::InitializeMintInstruction.build(
|
|
10
|
+
# decimals: 6,
|
|
11
|
+
# mint_authority: mint_authority.address,
|
|
12
|
+
# freeze_authority: freeze_authority.address,
|
|
13
|
+
# rent_sysvar_index: 2,
|
|
14
|
+
# mint_account_index: 1,
|
|
15
|
+
# program_index: 3
|
|
16
|
+
# )
|
|
17
|
+
#
|
|
18
|
+
# @since 0.1.5
|
|
19
|
+
class InitializeMintInstruction
|
|
20
|
+
# Instruction index for Initialize Mint
|
|
21
|
+
INSTRUCTION_INDEX = [0].freeze
|
|
22
|
+
|
|
23
|
+
# Builds a Solace::Instruction for initializing a Token-2022 mint.
|
|
24
|
+
#
|
|
25
|
+
# The BufferLayout is:
|
|
26
|
+
# - [Instruction Index (1 byte)]
|
|
27
|
+
# - [Decimals (1 byte)]
|
|
28
|
+
# - [Mint authority (32 bytes)]
|
|
29
|
+
# - [Freeze authority option (1 byte)]
|
|
30
|
+
# - [Freeze authority (32 bytes)]
|
|
31
|
+
#
|
|
32
|
+
# @param decimals [Integer] Number of decimals for the token
|
|
33
|
+
# @param mint_authority [String] Public key of the mint authority
|
|
34
|
+
# @param freeze_authority [String, nil] Public key of the freeze authority
|
|
35
|
+
# @param rent_sysvar_index [Integer] Index of the rent sysvar in the transaction's accounts
|
|
36
|
+
# @param mint_account_index [Integer] Index of the mint account in the transaction's accounts
|
|
37
|
+
# @param program_index [Integer] Index of the Token-2022 Program in the transaction's accounts
|
|
38
|
+
# @return [Solace::Instruction]
|
|
39
|
+
def self.build(
|
|
40
|
+
decimals:,
|
|
41
|
+
mint_authority:,
|
|
42
|
+
rent_sysvar_index:,
|
|
43
|
+
mint_account_index:,
|
|
44
|
+
freeze_authority: nil,
|
|
45
|
+
program_index: 2
|
|
46
|
+
)
|
|
47
|
+
Solace::Instruction.new.tap do |ix|
|
|
48
|
+
ix.program_index = program_index
|
|
49
|
+
ix.accounts = [mint_account_index, rent_sysvar_index]
|
|
50
|
+
ix.data = data(decimals, mint_authority, freeze_authority)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Instruction data for an initialize mint instruction.
|
|
55
|
+
#
|
|
56
|
+
# @param decimals [Integer] Number of decimals for the token
|
|
57
|
+
# @param mint_authority [String] Public key of the mint authority
|
|
58
|
+
# @param freeze_authority [String, nil] Public key of the freeze authority
|
|
59
|
+
# @return [Array<u8>] The instruction data
|
|
60
|
+
def self.data(decimals, mint_authority, freeze_authority)
|
|
61
|
+
INSTRUCTION_INDEX +
|
|
62
|
+
[decimals] +
|
|
63
|
+
Solace::Utils::Codecs.base58_to_bytes(mint_authority) +
|
|
64
|
+
(
|
|
65
|
+
if freeze_authority
|
|
66
|
+
[1] + Solace::Utils::Codecs.base58_to_bytes(freeze_authority)
|
|
67
|
+
else
|
|
68
|
+
[0]
|
|
69
|
+
end
|
|
70
|
+
)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solace
|
|
4
|
+
module Instructions
|
|
5
|
+
module Token2022
|
|
6
|
+
# Instruction for minting Token-2022 tokens to a token account.
|
|
7
|
+
#
|
|
8
|
+
# @example Build a MintTo instruction
|
|
9
|
+
# instruction = Solace::Instructions::Token2022::MintToInstruction.build(
|
|
10
|
+
# amount: 100,
|
|
11
|
+
# mint_index: 1,
|
|
12
|
+
# mint_authority_index: 2,
|
|
13
|
+
# destination_index: 3,
|
|
14
|
+
# program_index: 4
|
|
15
|
+
# )
|
|
16
|
+
#
|
|
17
|
+
# @since 0.1.5
|
|
18
|
+
class MintToInstruction
|
|
19
|
+
# @!attribute [Array<Integer>] INSTRUCTION_INDEX
|
|
20
|
+
# Instruction index for Token-2022's MintTo instruction.
|
|
21
|
+
INSTRUCTION_INDEX = [7].freeze
|
|
22
|
+
|
|
23
|
+
# Builds a MintTo instruction.
|
|
24
|
+
#
|
|
25
|
+
# @param amount [Integer] The amount of tokens to mint.
|
|
26
|
+
# @param mint_index [Integer] The index of the mint account.
|
|
27
|
+
# @param destination_index [Integer] The index of the token account to mint to.
|
|
28
|
+
# @param mint_authority_index [Integer] The index of the mint authority account.
|
|
29
|
+
# @param program_index [Integer] The index of the Token-2022 Program.
|
|
30
|
+
# @return [Solace::Instruction]
|
|
31
|
+
def self.build(
|
|
32
|
+
amount:,
|
|
33
|
+
mint_index:,
|
|
34
|
+
mint_authority_index:,
|
|
35
|
+
destination_index:,
|
|
36
|
+
program_index:
|
|
37
|
+
)
|
|
38
|
+
Solace::Instruction.new.tap do |ix|
|
|
39
|
+
ix.program_index = program_index
|
|
40
|
+
ix.accounts = [mint_index, destination_index, mint_authority_index]
|
|
41
|
+
ix.data = data(amount)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Builds the data for a MintTo instruction.
|
|
46
|
+
#
|
|
47
|
+
# The BufferLayout is:
|
|
48
|
+
# - [Instruction Index (1 byte)]
|
|
49
|
+
# - [Amount (8 bytes)]
|
|
50
|
+
#
|
|
51
|
+
# @param amount [Integer] The amount of tokens to mint.
|
|
52
|
+
# @return [Array] 1-byte instruction index + 8-byte amount
|
|
53
|
+
def self.data(amount)
|
|
54
|
+
INSTRUCTION_INDEX + Solace::Utils::Codecs.encode_le_u64(amount).bytes
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solace
|
|
4
|
+
module Instructions
|
|
5
|
+
module Token2022
|
|
6
|
+
# Instruction for transferring Token-2022 tokens with decimal validation.
|
|
7
|
+
#
|
|
8
|
+
# @example Build a TransferChecked instruction
|
|
9
|
+
# instruction = Solace::Instructions::Token2022::TransferCheckedInstruction.build(
|
|
10
|
+
# amount: 100,
|
|
11
|
+
# decimals: 6,
|
|
12
|
+
# to_index: 1,
|
|
13
|
+
# from_index: 2,
|
|
14
|
+
# mint_index: 3,
|
|
15
|
+
# authority_index: 4,
|
|
16
|
+
# program_index: 5
|
|
17
|
+
# )
|
|
18
|
+
#
|
|
19
|
+
# @since 0.1.5
|
|
20
|
+
class TransferCheckedInstruction
|
|
21
|
+
# Token-2022 instruction index for Transfer Checked
|
|
22
|
+
INSTRUCTION_INDEX = [12].freeze
|
|
23
|
+
|
|
24
|
+
# Builds a Solace::Instruction for transferring Token-2022 tokens.
|
|
25
|
+
#
|
|
26
|
+
# The BufferLayout is:
|
|
27
|
+
# - [Instruction Index (1 byte)]
|
|
28
|
+
# - [Amount (8 bytes little-endian u64)]
|
|
29
|
+
# - [Decimals (1 byte)]
|
|
30
|
+
#
|
|
31
|
+
# @param amount [Integer] Amount to transfer (in tokens, according to mint's decimals)
|
|
32
|
+
# @param decimals [Integer] Number of decimals for the token
|
|
33
|
+
# @param to_index [Integer] Index of the destination token account in the transaction's accounts
|
|
34
|
+
# @param from_index [Integer] Index of the source token account in the transaction's accounts
|
|
35
|
+
# @param mint_index [Integer] Index of the mint in the transaction's accounts
|
|
36
|
+
# @param authority_index [Integer] Index of the authority (owner) in the transaction's accounts
|
|
37
|
+
# @param program_index [Integer] Index of the Token-2022 Program in the transaction's accounts
|
|
38
|
+
# @return [Solace::Instruction]
|
|
39
|
+
def self.build(
|
|
40
|
+
amount:,
|
|
41
|
+
decimals:,
|
|
42
|
+
to_index:,
|
|
43
|
+
from_index:,
|
|
44
|
+
mint_index:,
|
|
45
|
+
authority_index:,
|
|
46
|
+
program_index: 3
|
|
47
|
+
)
|
|
48
|
+
Solace::Instruction.new.tap do |ix|
|
|
49
|
+
ix.program_index = program_index
|
|
50
|
+
ix.accounts = [from_index, mint_index, to_index, authority_index]
|
|
51
|
+
ix.data = data(amount, decimals)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Instruction data for a TransferChecked instruction.
|
|
56
|
+
#
|
|
57
|
+
# @param amount [Integer] Amount to transfer
|
|
58
|
+
# @param decimals [Integer] Number of decimals for the token
|
|
59
|
+
# @return [Array] 1-byte instruction index + 8-byte amount + 1-byte decimals
|
|
60
|
+
def self.data(amount, decimals)
|
|
61
|
+
INSTRUCTION_INDEX +
|
|
62
|
+
Solace::Utils::Codecs.encode_le_u64(amount).bytes +
|
|
63
|
+
[decimals]
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solace
|
|
4
|
+
module Instructions
|
|
5
|
+
# The Token2022 module contains instruction builders for the Token-2022 Program
|
|
6
|
+
# (formerly Token Extensions, +TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb+).
|
|
7
|
+
#
|
|
8
|
+
# Token-2022 is wire-compatible with the legacy SPL Token program for its
|
|
9
|
+
# base instructions (Transfer, TransferChecked, CloseAccount, MintTo,
|
|
10
|
+
# InitializeMint, InitializeAccount). The instruction discriminators and
|
|
11
|
+
# data layouts are identical; only the program the instruction targets
|
|
12
|
+
# differs. These builders are duplicated from the {SplToken} namespace so
|
|
13
|
+
# that each instruction is unambiguously bound to a single on-chain program.
|
|
14
|
+
#
|
|
15
|
+
# @see Solace::Instructions::SplToken
|
|
16
|
+
# @since 0.1.5
|
|
17
|
+
module Token2022
|
|
18
|
+
# Instruction for transferring tokens via the Token-2022 program.
|
|
19
|
+
#
|
|
20
|
+
# @example Build a Transfer instruction
|
|
21
|
+
# instruction = Solace::Instructions::Token2022::TransferInstruction.build(
|
|
22
|
+
# amount: 100,
|
|
23
|
+
# owner_index: 1,
|
|
24
|
+
# source_index: 2,
|
|
25
|
+
# destination_index: 3,
|
|
26
|
+
# program_index: 4
|
|
27
|
+
# )
|
|
28
|
+
#
|
|
29
|
+
# @since 0.1.5
|
|
30
|
+
class TransferInstruction
|
|
31
|
+
# @!attribute [Array<Integer>] INSTRUCTION_INDEX
|
|
32
|
+
# Instruction index for Token-2022's Transfer instruction.
|
|
33
|
+
INSTRUCTION_INDEX = [3].freeze
|
|
34
|
+
|
|
35
|
+
# Builds a Transfer instruction.
|
|
36
|
+
#
|
|
37
|
+
# @param amount [Integer] The amount of tokens to transfer.
|
|
38
|
+
# @param source_index [Integer] The index of the source token account.
|
|
39
|
+
# @param destination_index [Integer] The index of the destination token account.
|
|
40
|
+
# @param owner_index [Integer] The index of the source account's owner.
|
|
41
|
+
# @param program_index [Integer] The index of the Token-2022 Program.
|
|
42
|
+
# @return [Solace::Instruction]
|
|
43
|
+
def self.build(
|
|
44
|
+
amount:,
|
|
45
|
+
owner_index:,
|
|
46
|
+
source_index:,
|
|
47
|
+
destination_index:,
|
|
48
|
+
program_index:
|
|
49
|
+
)
|
|
50
|
+
Solace::Instruction.new.tap do |ix|
|
|
51
|
+
ix.program_index = program_index
|
|
52
|
+
ix.accounts = [source_index, destination_index, owner_index]
|
|
53
|
+
ix.data = data(amount)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Builds the data for a Transfer instruction.
|
|
58
|
+
#
|
|
59
|
+
# The BufferLayout is:
|
|
60
|
+
# - [Instruction Index (1 byte)]
|
|
61
|
+
# - [Amount (8 bytes)]
|
|
62
|
+
#
|
|
63
|
+
# @param amount [Integer] The amount of tokens to transfer.
|
|
64
|
+
# @return [Array<Integer>] 1-byte instruction index + 8-byte amount
|
|
65
|
+
def self.data(amount)
|
|
66
|
+
INSTRUCTION_INDEX + Solace::Utils::Codecs.encode_le_u64(amount).bytes
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|