solace 0.0.2 → 0.0.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 +57 -0
- data/LICENSE +21 -0
- data/README.md +142 -287
- data/lib/solace/address_lookup_table.rb +34 -18
- data/lib/solace/composers/base.rb +45 -0
- data/lib/solace/composers/spl_token_program_transfer_checked_composer.rb +113 -0
- data/lib/solace/composers/system_program_transfer_composer.rb +80 -0
- data/lib/solace/concerns/binary_serializable.rb +39 -0
- data/lib/solace/connection.rb +101 -44
- data/lib/solace/constants.rb +7 -14
- data/lib/solace/instruction.rb +30 -19
- data/lib/solace/instructions/associated_token_account/create_associated_token_account_instruction.rb +18 -3
- data/lib/solace/instructions/spl_token/initialize_account_instruction.rb +24 -3
- data/lib/solace/instructions/spl_token/initialize_mint_instruction.rb +18 -1
- data/lib/solace/instructions/spl_token/mint_to_instruction.rb +16 -3
- data/lib/solace/instructions/spl_token/transfer_checked_instruction.rb +76 -0
- data/lib/solace/instructions/spl_token/transfer_instruction.rb +15 -2
- data/lib/solace/instructions/system_program/create_account_instruction.rb +18 -3
- data/lib/solace/instructions/system_program/transfer_instruction.rb +58 -0
- data/lib/solace/keypair.rb +64 -31
- data/lib/solace/message.rb +22 -10
- data/lib/solace/programs/associated_token_account.rb +58 -11
- data/lib/solace/programs/base.rb +6 -0
- data/lib/solace/programs/spl_token.rb +52 -14
- data/lib/solace/public_key.rb +45 -20
- data/lib/solace/serializers/address_lookup_table_deserializer.rb +3 -5
- data/lib/solace/serializers/address_lookup_table_serializer.rb +7 -7
- data/lib/solace/serializers/base_deserializer.rb +29 -19
- data/lib/solace/serializers/base_serializer.rb +18 -9
- data/lib/solace/serializers/instruction_deserializer.rb +5 -7
- data/lib/solace/serializers/instruction_serializer.rb +4 -6
- data/lib/solace/serializers/message_deserializer.rb +3 -5
- data/lib/solace/serializers/message_serializer.rb +3 -5
- data/lib/solace/serializers/transaction_deserializer.rb +5 -7
- data/lib/solace/serializers/transaction_serializer.rb +5 -7
- data/lib/solace/transaction.rb +38 -23
- data/lib/solace/transaction_composer.rb +115 -0
- data/lib/solace/utils/account_context.rb +252 -0
- data/lib/solace/utils/codecs.rb +56 -128
- data/lib/solace/utils/curve25519_dalek.rb +9 -4
- data/lib/solace/utils/pda.rb +22 -24
- data/lib/solace/version.rb +2 -1
- data/lib/solace.rb +9 -7
- metadata +15 -12
- data/lib/solace/instructions/transfer_checked_instruction.rb +0 -58
- data/lib/solace/instructions/transfer_instruction.rb +0 -48
- data/lib/solace/serializable_record.rb +0 -26
- data/lib/solace/serializers/base.rb +0 -31
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solace
|
4
|
+
module Composers
|
5
|
+
# A Base class for all composers
|
6
|
+
#
|
7
|
+
# @since 0.0.3
|
8
|
+
class Base
|
9
|
+
# @!attribute params
|
10
|
+
# The params for the composer
|
11
|
+
#
|
12
|
+
# @return [Hash] The parameters passed to the composer
|
13
|
+
attr_reader :params
|
14
|
+
|
15
|
+
# @!attribute account_context
|
16
|
+
# The account_context for the composer
|
17
|
+
#
|
18
|
+
# @return [Utils::AccountContext] The AccountContext instance for the composer
|
19
|
+
attr_reader :account_context
|
20
|
+
|
21
|
+
# Initialize the composer
|
22
|
+
#
|
23
|
+
# @param params [Hash] Parameters to pass to the composer constructor
|
24
|
+
def initialize(params)
|
25
|
+
@params = params
|
26
|
+
@account_context = Utils::AccountContext.new
|
27
|
+
setup_accounts
|
28
|
+
end
|
29
|
+
|
30
|
+
# Setup accounts required for this instruction
|
31
|
+
#
|
32
|
+
# @return [void]
|
33
|
+
def setup_accounts
|
34
|
+
raise NotImplementedError, 'Subclasses must implement setup_accounts method'
|
35
|
+
end
|
36
|
+
|
37
|
+
# Build instruction with resolved account indices
|
38
|
+
#
|
39
|
+
# @return [void]
|
40
|
+
def build_instruction(indices)
|
41
|
+
raise NotImplementedError, 'Subclasses must implement build_instruction method'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solace
|
4
|
+
module Composers
|
5
|
+
# Composer for creating a SPL Token Program `TransferChecked` instruction.
|
6
|
+
#
|
7
|
+
# This composer resolves and orders the required accounts for a `TransferChecked` instruction,
|
8
|
+
# sets up their access permissions, and delegates construction to the appropriate
|
9
|
+
# instruction builder (`Instructions::SplToken::TransferCheckedInstruction`).
|
10
|
+
#
|
11
|
+
# It is used for transferring SPL tokens with decimal precision and validation checks.
|
12
|
+
#
|
13
|
+
# Required accounts:
|
14
|
+
# - **From**: source token account (writable, non-signer)
|
15
|
+
# - **To**: destination token account (writable, non-signer)
|
16
|
+
# - **Mint**: mint address (readonly, non-signer)
|
17
|
+
# - **Authority**: token owner (writable, signer)
|
18
|
+
# - **Program**: SPL Token program (readonly, non-signer)
|
19
|
+
#
|
20
|
+
# @example Compose and build a transfer_checked instruction
|
21
|
+
# composer = SplTokenProgramTransferCheckedComposer.new(
|
22
|
+
# from: from_address,
|
23
|
+
# to: to_address,
|
24
|
+
# mint: mint_address,
|
25
|
+
# authority: authority_pubkey,
|
26
|
+
# amount: 1_000_000,
|
27
|
+
# decimals: 6
|
28
|
+
# )
|
29
|
+
#
|
30
|
+
# @see Instructions::SplToken::TransferCheckedInstruction
|
31
|
+
# @since 0.0.3
|
32
|
+
class SplTokenProgramTransferCheckedComposer < Base
|
33
|
+
# Extracts the to address from the params
|
34
|
+
#
|
35
|
+
# @return [String] The to address
|
36
|
+
def to
|
37
|
+
params[:to].is_a?(String) ? params[:to] : params[:to].address
|
38
|
+
end
|
39
|
+
|
40
|
+
# Extracts the from address from the params
|
41
|
+
#
|
42
|
+
# @return [String] The from address
|
43
|
+
def from
|
44
|
+
params[:from].is_a?(String) ? params[:from] : params[:from].address
|
45
|
+
end
|
46
|
+
|
47
|
+
# Extracts the authority address from the params
|
48
|
+
#
|
49
|
+
# The authority is the owner of the token account
|
50
|
+
#
|
51
|
+
# @return [String] The authority address
|
52
|
+
def authority
|
53
|
+
params[:authority].is_a?(String) ? params[:authority] : params[:authority].address
|
54
|
+
end
|
55
|
+
|
56
|
+
# Extracts the mint address from the params
|
57
|
+
#
|
58
|
+
# @return [String] The mint address
|
59
|
+
def mint
|
60
|
+
params[:mint].is_a?(String) ? params[:mint] : params[:mint].address
|
61
|
+
end
|
62
|
+
|
63
|
+
# Returns the spl token program id
|
64
|
+
#
|
65
|
+
# @return [String] The spl token program id
|
66
|
+
def spl_token_program
|
67
|
+
Constants::TOKEN_PROGRAM_ID
|
68
|
+
end
|
69
|
+
|
70
|
+
# Returns the lamports to transfer
|
71
|
+
#
|
72
|
+
# @return [Integer] The lamports to transfer
|
73
|
+
def amount
|
74
|
+
params[:amount]
|
75
|
+
end
|
76
|
+
|
77
|
+
# Returns the decimals for the mint of the token
|
78
|
+
#
|
79
|
+
# @return [Integer] The decimals for the mint
|
80
|
+
def decimals
|
81
|
+
params[:decimals]
|
82
|
+
end
|
83
|
+
|
84
|
+
# Setup accounts required for transfer instruction
|
85
|
+
# Called automatically during initialization
|
86
|
+
#
|
87
|
+
# @return [void]
|
88
|
+
def setup_accounts
|
89
|
+
account_context.add_writable_signer(authority)
|
90
|
+
account_context.add_writable_nonsigner(to)
|
91
|
+
account_context.add_writable_nonsigner(from)
|
92
|
+
account_context.add_readonly_nonsigner(mint)
|
93
|
+
account_context.add_readonly_nonsigner(spl_token_program)
|
94
|
+
end
|
95
|
+
|
96
|
+
# Build instruction with resolved account indices
|
97
|
+
#
|
98
|
+
# @param account_context [Utils::AccountContext] The account context
|
99
|
+
# @return [Solace::Instruction]
|
100
|
+
def build_instruction(account_context)
|
101
|
+
Instructions::SplToken::TransferCheckedInstruction.build(
|
102
|
+
amount: amount,
|
103
|
+
decimals: decimals,
|
104
|
+
to_index: account_context.index_of(to),
|
105
|
+
from_index: account_context.index_of(from),
|
106
|
+
mint_index: account_context.index_of(mint),
|
107
|
+
authority_index: account_context.index_of(authority),
|
108
|
+
program_index: account_context.index_of(spl_token_program)
|
109
|
+
)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solace
|
4
|
+
module Composers
|
5
|
+
# Composer for creating a system 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::SystemProgram::TransferInstruction`).
|
10
|
+
#
|
11
|
+
# It is used for transferring lamports from one account to another.
|
12
|
+
#
|
13
|
+
# Required accounts:
|
14
|
+
# - **From**: source account (writable, signer)
|
15
|
+
# - **To**: destination account (writable, non-signer)
|
16
|
+
# - **Program**: System program (readonly, non-signer)
|
17
|
+
#
|
18
|
+
# @example Compose and build a transfer instruction
|
19
|
+
# composer = SystemProgramTransferComposer.new(
|
20
|
+
# from: from_address,
|
21
|
+
# to: to_address,
|
22
|
+
# lamports: 1_000_000
|
23
|
+
# )
|
24
|
+
#
|
25
|
+
# @see Instructions::SystemProgram::TransferInstruction
|
26
|
+
# @since 0.0.3
|
27
|
+
class SystemProgramTransferComposer < Base
|
28
|
+
# Extracts the to address from the params
|
29
|
+
#
|
30
|
+
# @return [String] The to address
|
31
|
+
def to
|
32
|
+
params[:to].is_a?(String) ? params[:to] : params[:to].address
|
33
|
+
end
|
34
|
+
|
35
|
+
# Extracts the from address from the params
|
36
|
+
#
|
37
|
+
# @return [String] The from address
|
38
|
+
def from
|
39
|
+
params[:from].is_a?(String) ? params[:from] : params[:from].address
|
40
|
+
end
|
41
|
+
|
42
|
+
# Returns the system program id
|
43
|
+
#
|
44
|
+
# @return [String] The system program id
|
45
|
+
def system_program
|
46
|
+
Solace::Constants::SYSTEM_PROGRAM_ID
|
47
|
+
end
|
48
|
+
|
49
|
+
# Returns the lamports to transfer
|
50
|
+
#
|
51
|
+
# @return [Integer] The lamports to transfer
|
52
|
+
def lamports
|
53
|
+
params[:lamports]
|
54
|
+
end
|
55
|
+
|
56
|
+
# Setup accounts required for transfer instruction
|
57
|
+
# Called automatically during initialization
|
58
|
+
#
|
59
|
+
# @return [void]
|
60
|
+
def setup_accounts
|
61
|
+
account_context.add_writable_signer(from)
|
62
|
+
account_context.add_writable_nonsigner(to)
|
63
|
+
account_context.add_readonly_nonsigner(system_program)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Build instruction with resolved account indices
|
67
|
+
#
|
68
|
+
# @param account_context [Utils::AccountContext] The account context
|
69
|
+
# @return [Solace::Instruction]
|
70
|
+
def build_instruction(account_context)
|
71
|
+
Instructions::SystemProgram::TransferInstruction.build(
|
72
|
+
lamports: lamports,
|
73
|
+
to_index: account_context.index_of(to),
|
74
|
+
from_index: account_context.index_of(from),
|
75
|
+
program_index: account_context.index_of(system_program)
|
76
|
+
)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -2,7 +2,24 @@
|
|
2
2
|
|
3
3
|
module Solace
|
4
4
|
module Concerns
|
5
|
+
# Adds binary serialization support to a class
|
6
|
+
#
|
7
|
+
# Transactions, Messages, Instructions, and AddressLookupTables are all binary serializable.
|
8
|
+
# These classes use this concern to add binary serialization support.
|
9
|
+
#
|
10
|
+
# @see Solace::Transaction
|
11
|
+
# @see Solace::Message
|
12
|
+
# @see Solace::Instruction
|
13
|
+
# @see Solace::AddressLookupTable
|
14
|
+
# @since 0.0.1
|
5
15
|
module BinarySerializable
|
16
|
+
# Include the module
|
17
|
+
#
|
18
|
+
# @param base [Class] The base class to include the module into
|
19
|
+
def self.included(base)
|
20
|
+
base.extend ClassMethods
|
21
|
+
end
|
22
|
+
|
6
23
|
# Returns the binary decoded from the serialized string
|
7
24
|
#
|
8
25
|
# Expects the class to have a `serialize` method that returns a base64 string.
|
@@ -25,6 +42,28 @@ module Solace
|
|
25
42
|
def to_bytes
|
26
43
|
to_binary.bytes
|
27
44
|
end
|
45
|
+
|
46
|
+
# Serializes the record to a binary format
|
47
|
+
#
|
48
|
+
# @return [String] The serialized record (binary)
|
49
|
+
def serialize
|
50
|
+
self.class::SERIALIZER.new(self).call
|
51
|
+
rescue NameError => e
|
52
|
+
raise "SERIALIZER must be defined: #{e.message}"
|
53
|
+
end
|
54
|
+
|
55
|
+
# Class methods for binary serializable
|
56
|
+
module ClassMethods
|
57
|
+
# Parse record from bytestream
|
58
|
+
#
|
59
|
+
# @param stream [IO, StringIO] The input to read bytes from.
|
60
|
+
# @return [Solace::Instruction] Parsed instruction instance
|
61
|
+
def deserialize(stream)
|
62
|
+
self::DESERIALIZER.new(stream).call
|
63
|
+
rescue NameError => e
|
64
|
+
raise "DESERIALIZER must be defined: #{e.message}"
|
65
|
+
end
|
66
|
+
end
|
28
67
|
end
|
29
68
|
end
|
30
69
|
end
|
data/lib/solace/connection.rb
CHANGED
@@ -5,62 +5,69 @@ require 'json'
|
|
5
5
|
require 'uri'
|
6
6
|
|
7
7
|
module Solace
|
8
|
+
# Connection to a Solana RPC node
|
9
|
+
#
|
10
|
+
# This class provides methods for sending JSON-RPC requests to a Solana RPC node and parsing responses.
|
11
|
+
# It includes methods for sending transactions, getting account information, and getting blockhashes.
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
# # Initialize the connection
|
15
|
+
# connection = Solace::Connection.new('http://localhost:8899', commitment: 'confirmed')
|
16
|
+
#
|
17
|
+
# # Get account information
|
18
|
+
# connection.get_account_info(account.address)
|
19
|
+
#
|
20
|
+
# # Request an airdrop
|
21
|
+
# result = connection.request_airdrop(account.address, 1000000)
|
22
|
+
#
|
23
|
+
# # Wait for the transaction to be finalized
|
24
|
+
# connection.wait_for_confirmed_signature('finalized') { result['result'] }
|
25
|
+
#
|
26
|
+
# @since 0.0.1
|
27
|
+
#
|
28
|
+
# rubocop:disable Metrics/ClassLength
|
8
29
|
class Connection
|
30
|
+
# @!attribute [r] rpc_url
|
31
|
+
# The URL of the Solana RPC node
|
9
32
|
attr_reader :rpc_url
|
10
33
|
|
11
|
-
#
|
12
|
-
|
13
|
-
|
14
|
-
commitment: 'confirmed'
|
15
|
-
}.freeze
|
34
|
+
# @!attribute [r] default_options
|
35
|
+
# The default options for RPC requests
|
36
|
+
attr_reader :default_options
|
16
37
|
|
17
38
|
# Initialize the connection with a default or custom RPC URL
|
18
39
|
#
|
19
40
|
# @param rpc_url [String] The URL of the Solana RPC node
|
41
|
+
# @param commitment [String] The commitment level for RPC requests
|
20
42
|
# @return [Solace::Connection] The connection object
|
21
|
-
def initialize(rpc_url = 'http://localhost:8899')
|
22
|
-
@rpc_url = rpc_url
|
43
|
+
def initialize(rpc_url = 'http://localhost:8899', commitment: 'confirmed')
|
23
44
|
@request_id = nil
|
45
|
+
@rpc_url = rpc_url
|
46
|
+
|
47
|
+
# Set default options
|
48
|
+
@default_options = {
|
49
|
+
commitment: commitment,
|
50
|
+
encoding: 'base64'
|
51
|
+
}
|
24
52
|
end
|
25
53
|
|
26
|
-
#
|
54
|
+
# Sends a JSON-RPC request to the configured Solana RPC server.
|
27
55
|
#
|
28
|
-
# @param method [String]
|
29
|
-
# @param params [Array]
|
30
|
-
# @return [
|
56
|
+
# @param method [String] the JSON-RPC method name
|
57
|
+
# @param params [Array] the parameters for the RPC method
|
58
|
+
# @return [Hash] the parsed JSON response
|
59
|
+
# @raise [RuntimeError] if the response is not successful
|
31
60
|
def rpc_request(method, params = [])
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
req['Accept'] = 'application/json'
|
36
|
-
req['Content-Type'] = 'application/json'
|
37
|
-
|
38
|
-
@request_id = SecureRandom.uuid
|
39
|
-
|
40
|
-
req.body = {
|
41
|
-
jsonrpc: '2.0',
|
42
|
-
id: @request_id,
|
43
|
-
method: method,
|
44
|
-
params: params
|
45
|
-
}.to_json
|
46
|
-
|
47
|
-
res = Net::HTTP.start(
|
48
|
-
uri.hostname,
|
49
|
-
uri.port,
|
50
|
-
use_ssl: uri.scheme == 'https'
|
51
|
-
) do |http|
|
52
|
-
http.request(req)
|
53
|
-
end
|
54
|
-
|
55
|
-
raise "RPC error: #{res.body}" unless res.is_a?(Net::HTTPSuccess)
|
56
|
-
|
57
|
-
JSON.parse(res.body)
|
61
|
+
request = build_rpc_request(method, params)
|
62
|
+
response = perform_http_request(request)
|
63
|
+
handle_rpc_response(response)
|
58
64
|
end
|
59
65
|
|
60
66
|
# Request an airdrop of lamports to a given address
|
61
67
|
#
|
62
68
|
# @param pubkey [String] The public key of the account to receive the airdrop
|
63
69
|
# @param lamports [Integer] Amount of lamports to airdrop
|
70
|
+
# @param [Hash{Symbol => Object}] options The options for the request
|
64
71
|
# @return [String] The transaction signature of the airdrop
|
65
72
|
def request_airdrop(pubkey, lamports, options = {})
|
66
73
|
rpc_request(
|
@@ -68,7 +75,7 @@ module Solace
|
|
68
75
|
[
|
69
76
|
pubkey,
|
70
77
|
lamports,
|
71
|
-
|
78
|
+
default_options.merge(options)
|
72
79
|
]
|
73
80
|
)
|
74
81
|
end
|
@@ -97,7 +104,7 @@ module Solace
|
|
97
104
|
'getAccountInfo',
|
98
105
|
[
|
99
106
|
pubkey,
|
100
|
-
|
107
|
+
default_options
|
101
108
|
]
|
102
109
|
)['result']
|
103
110
|
|
@@ -115,7 +122,21 @@ module Solace
|
|
115
122
|
'getBalance',
|
116
123
|
[
|
117
124
|
pubkey,
|
118
|
-
|
125
|
+
default_options
|
126
|
+
]
|
127
|
+
)['result']['value']
|
128
|
+
end
|
129
|
+
|
130
|
+
# Get the balance of a token account
|
131
|
+
#
|
132
|
+
# @param token_account [String] The public key of the token account
|
133
|
+
# @return [Hash] Token account balance information with amount and decimals
|
134
|
+
def get_token_account_balance(token_account)
|
135
|
+
rpc_request(
|
136
|
+
'getTokenAccountBalance',
|
137
|
+
[
|
138
|
+
token_account,
|
139
|
+
default_options
|
119
140
|
]
|
120
141
|
)['result']['value']
|
121
142
|
end
|
@@ -124,12 +145,13 @@ module Solace
|
|
124
145
|
#
|
125
146
|
# @param signature [String] The signature of the transaction
|
126
147
|
# @return [Solace::Transaction] The transaction object
|
148
|
+
# @param [Hash{Symbol => Object}] options
|
127
149
|
def get_transaction(signature, options = { maxSupportedTransactionVersion: 0 })
|
128
150
|
rpc_request(
|
129
151
|
'getTransaction',
|
130
152
|
[
|
131
153
|
signature,
|
132
|
-
|
154
|
+
default_options.merge(options)
|
133
155
|
]
|
134
156
|
)['result']
|
135
157
|
end
|
@@ -143,7 +165,7 @@ module Solace
|
|
143
165
|
'getSignatureStatuses',
|
144
166
|
[
|
145
167
|
signatures,
|
146
|
-
|
168
|
+
default_options.merge({ 'searchTransactionHistory' => true })
|
147
169
|
]
|
148
170
|
)['result']
|
149
171
|
end
|
@@ -152,12 +174,13 @@ module Solace
|
|
152
174
|
#
|
153
175
|
# @param transaction [Solace::Transaction] The transaction to send
|
154
176
|
# @return [String] The signature of the transaction
|
177
|
+
# @param [Hash{Symbol => Object}] options
|
155
178
|
def send_transaction(transaction, options = {})
|
156
179
|
rpc_request(
|
157
180
|
'sendTransaction',
|
158
181
|
[
|
159
182
|
transaction,
|
160
|
-
|
183
|
+
default_options.merge(options)
|
161
184
|
]
|
162
185
|
)
|
163
186
|
end
|
@@ -172,16 +195,50 @@ module Solace
|
|
172
195
|
# Get the signature from the block
|
173
196
|
signature = yield
|
174
197
|
|
198
|
+
interval = 0.1
|
199
|
+
|
175
200
|
# Wait for confirmation
|
176
201
|
loop do
|
177
202
|
status = get_signature_status([signature]).dig('value', 0)
|
178
203
|
|
179
204
|
break if status && status['confirmationStatus'] == commitment
|
180
205
|
|
181
|
-
sleep
|
206
|
+
sleep interval
|
182
207
|
end
|
183
208
|
|
184
209
|
signature
|
185
210
|
end
|
211
|
+
|
212
|
+
private
|
213
|
+
|
214
|
+
def build_rpc_request(method, params)
|
215
|
+
uri = URI(rpc_url)
|
216
|
+
req = Net::HTTP::Post.new(uri)
|
217
|
+
req['Accept'] = 'application/json'
|
218
|
+
req['Content-Type'] = 'application/json'
|
219
|
+
@request_id = SecureRandom.uuid
|
220
|
+
|
221
|
+
req.body = {
|
222
|
+
jsonrpc: '2.0',
|
223
|
+
id: @request_id,
|
224
|
+
method: method,
|
225
|
+
params: params
|
226
|
+
}.to_json
|
227
|
+
|
228
|
+
[uri, req]
|
229
|
+
end
|
230
|
+
|
231
|
+
def perform_http_request((uri, req))
|
232
|
+
Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
|
233
|
+
http.request(req)
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
def handle_rpc_response(response)
|
238
|
+
raise "RPC error: #{response.body}" unless response.is_a?(Net::HTTPSuccess)
|
239
|
+
|
240
|
+
JSON.parse(response.body)
|
241
|
+
end
|
186
242
|
end
|
243
|
+
# rubocop:enable Metrics/ClassLength
|
187
244
|
end
|
data/lib/solace/constants.rb
CHANGED
@@ -7,46 +7,39 @@
|
|
7
7
|
# @return [Module] Constants module
|
8
8
|
module Solace
|
9
9
|
module Constants
|
10
|
-
# @!
|
10
|
+
# @!attribute SYSTEM_PROGRAM_ID
|
11
11
|
# The public key of the System Program (native SOL transfers, account creation, etc)
|
12
12
|
# This is the same across all Solana clusters
|
13
|
-
# @return [String]
|
14
13
|
SYSTEM_PROGRAM_ID = '11111111111111111111111111111111'
|
15
14
|
|
16
|
-
# @!
|
15
|
+
# @!attribute SYSVAR_RENT_PROGRAM_ID
|
17
16
|
# The public key of the Rent Program
|
18
17
|
# This is the same across all Solana clusters
|
19
|
-
# @return [String]
|
20
18
|
SYSVAR_RENT_PROGRAM_ID = 'SysvarRent111111111111111111111111111111111'
|
21
19
|
|
22
|
-
# @!
|
20
|
+
# @!attribute COMPUTE_BUDGET_PROGRAM_ID
|
23
21
|
# The public key of the Compute Budget Program
|
24
22
|
# This is the same across all Solana clusters
|
25
|
-
# @return [String]
|
26
23
|
COMPUTE_BUDGET_PROGRAM_ID = 'ComputeBudget111111111111111111111111111111'
|
27
24
|
|
28
|
-
# @!
|
25
|
+
# @!attribute TOKEN_PROGRAM_ID
|
29
26
|
# The public key of the SPL Token Program
|
30
27
|
# This is the same across all Solana clusters
|
31
|
-
# @return [String]
|
32
28
|
TOKEN_PROGRAM_ID = 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'
|
33
29
|
|
34
|
-
# @!
|
30
|
+
# @!attribute ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID
|
35
31
|
# The public key of the Associated Token Account Program
|
36
32
|
# This is the same across all Solana clusters
|
37
|
-
# @return [String]
|
38
33
|
ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID = 'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL'
|
39
34
|
|
40
|
-
# @!
|
35
|
+
# @!attribute MEMO_PROGRAM_ID
|
41
36
|
# The public key of the Memo Program
|
42
37
|
# This is the same across all Solana clusters
|
43
|
-
# @return [String]
|
44
38
|
MEMO_PROGRAM_ID = 'MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr'
|
45
39
|
|
46
|
-
# @!
|
40
|
+
# @!attribute ADDRESS_LOOKUP_TABLE_PROGRAM_ID
|
47
41
|
# The public key of the Address Lookup Table Program
|
48
42
|
# This is the same across all Solana clusters
|
49
|
-
# @return [String]
|
50
43
|
ADDRESS_LOOKUP_TABLE_PROGRAM_ID = 'AddressLookupTab1e1111111111111111111111111'
|
51
44
|
end
|
52
45
|
end
|
data/lib/solace/instruction.rb
CHANGED
@@ -1,37 +1,48 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# =============================
|
4
|
-
# Instruction
|
5
|
-
# =============================
|
6
|
-
#
|
7
|
-
# Class representing a Solana instruction.
|
8
|
-
#
|
9
|
-
# The BufferLayout is:
|
10
|
-
# - [Program index (1 byte)]
|
11
|
-
# - [Number of accounts (compact u16)]
|
12
|
-
# - [Accounts (variable length)]
|
13
|
-
# - [Data length (compact u16)]
|
14
|
-
# - [Data (variable length)]
|
15
|
-
#
|
16
3
|
module Solace
|
17
|
-
|
18
|
-
|
4
|
+
# Class representing a Solana instruction.
|
5
|
+
#
|
6
|
+
# Handles serialization and deserialization of instruction fields. Instructions are used to
|
7
|
+
# encode the data that is sent to a program on the Solana blockchain. Instructions are part of
|
8
|
+
# transaction messages. All instruction builders and instruction composers return an instance of
|
9
|
+
# this class.
|
10
|
+
#
|
11
|
+
# The BufferLayout is:
|
12
|
+
# - [Program index (1 byte)]
|
13
|
+
# - [Number of accounts (compact u16)]
|
14
|
+
# - [Accounts (variable length)]
|
15
|
+
# - [Data length (compact u16)]
|
16
|
+
# - [Data (variable length)]
|
17
|
+
#
|
18
|
+
# @example
|
19
|
+
# instruction = Solace::Instruction.new(
|
20
|
+
# program_index: 0,
|
21
|
+
# accounts: [1, 2, 3],
|
22
|
+
# data: [4, 5, 6]
|
23
|
+
# )
|
24
|
+
#
|
25
|
+
# @since 0.0.1
|
26
|
+
class Instruction
|
27
|
+
include Solace::Concerns::BinarySerializable
|
28
|
+
|
29
|
+
# @!attribute SERIALIZER
|
19
30
|
# @return [Solace::Serializers::InstructionSerializer] The serializer for the instruction
|
20
31
|
SERIALIZER = Solace::Serializers::InstructionSerializer
|
21
32
|
|
22
|
-
# @!
|
33
|
+
# @!attribute DESERIALIZER
|
23
34
|
# @return [Solace::Serializers::InstructionDeserializer] The deserializer for the instruction
|
24
35
|
DESERIALIZER = Solace::Serializers::InstructionDeserializer
|
25
36
|
|
26
|
-
# @!attribute
|
37
|
+
# @!attribute [rw] program_index
|
27
38
|
# @return [Integer] The program index of the instruction
|
28
39
|
attr_accessor :program_index
|
29
40
|
|
30
|
-
# @!attribute
|
41
|
+
# @!attribute [rw] accounts
|
31
42
|
# @return [Array<Integer>] The accounts of the instruction
|
32
43
|
attr_accessor :accounts
|
33
44
|
|
34
|
-
# @!attribute
|
45
|
+
# @!attribute [rw] data
|
35
46
|
# @return [Array<Integer>] The instruction data
|
36
47
|
attr_accessor :data
|
37
48
|
end
|
data/lib/solace/instructions/associated_token_account/create_associated_token_account_instruction.rb
CHANGED
@@ -3,8 +3,23 @@
|
|
3
3
|
module Solace
|
4
4
|
module Instructions
|
5
5
|
module AssociatedTokenAccount
|
6
|
-
#
|
7
|
-
#
|
6
|
+
# Instruction for creating an Associated Token Account.
|
7
|
+
#
|
8
|
+
# This is a special "all-in-one" instruction that creates and initializes the account. It
|
9
|
+
# is used to create an Associated Token Account (ATA) for a given mint and owner.
|
10
|
+
#
|
11
|
+
# @example Build a CreateAssociatedTokenAccount instruction
|
12
|
+
# instruction = Solace::Instructions::AssociatedTokenAccount::CreateAssociatedTokenAccountInstruction.build(
|
13
|
+
# funder_index: 0,
|
14
|
+
# associated_token_account_index: 1,
|
15
|
+
# owner_index: 2,
|
16
|
+
# mint_index: 3,
|
17
|
+
# system_program_index: 4,
|
18
|
+
# token_program_index: 5,
|
19
|
+
# program_index: 6
|
20
|
+
# )
|
21
|
+
#
|
22
|
+
# @since 0.0.2
|
8
23
|
class CreateAssociatedTokenAccountInstruction
|
9
24
|
# !@const INSTRUCTION_INDEX
|
10
25
|
# Instruction index for CreateAssociatedTokenAccount
|
@@ -65,4 +80,4 @@ module Solace
|
|
65
80
|
end
|
66
81
|
end
|
67
82
|
end
|
68
|
-
end
|
83
|
+
end
|