solace 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG +0 -0
- data/LICENSE +0 -0
- data/README.md +661 -0
- data/lib/solace/address_lookup_table.rb +50 -0
- data/lib/solace/concerns/binary_serializable.rb +30 -0
- data/lib/solace/connection.rb +187 -0
- data/lib/solace/constants.rb +52 -0
- data/lib/solace/instruction.rb +38 -0
- data/lib/solace/instructions/associated_token_account/create_associated_token_account_instruction.rb +68 -0
- data/lib/solace/instructions/spl_token/initialize_account_instruction.rb +46 -0
- data/lib/solace/instructions/spl_token/initialize_mint_instruction.rb +68 -0
- data/lib/solace/instructions/spl_token/mint_to_instruction.rb +48 -0
- data/lib/solace/instructions/spl_token/transfer_instruction.rb +48 -0
- data/lib/solace/instructions/system_program/create_account_instruction.rb +58 -0
- data/lib/solace/instructions/transfer_checked_instruction.rb +58 -0
- data/lib/solace/instructions/transfer_instruction.rb +48 -0
- data/lib/solace/keypair.rb +121 -0
- data/lib/solace/message.rb +95 -0
- data/lib/solace/programs/associated_token_account.rb +96 -0
- data/lib/solace/programs/base.rb +22 -0
- data/lib/solace/programs/spl_token.rb +187 -0
- data/lib/solace/public_key.rb +74 -0
- data/lib/solace/serializable_record.rb +26 -0
- data/lib/solace/serializers/address_lookup_table_deserializer.rb +62 -0
- data/lib/solace/serializers/address_lookup_table_serializer.rb +54 -0
- data/lib/solace/serializers/base.rb +31 -0
- data/lib/solace/serializers/base_deserializer.rb +56 -0
- data/lib/solace/serializers/base_serializer.rb +52 -0
- data/lib/solace/serializers/instruction_deserializer.rb +62 -0
- data/lib/solace/serializers/instruction_serializer.rb +54 -0
- data/lib/solace/serializers/message_deserializer.rb +116 -0
- data/lib/solace/serializers/message_serializer.rb +95 -0
- data/lib/solace/serializers/transaction_deserializer.rb +49 -0
- data/lib/solace/serializers/transaction_serializer.rb +60 -0
- data/lib/solace/transaction.rb +98 -0
- data/lib/solace/utils/codecs.rb +220 -0
- data/lib/solace/utils/curve25519_dalek.rb +59 -0
- data/lib/solace/utils/libcurve25519_dalek-linux/libcurve25519_dalek.so +0 -0
- data/lib/solace/utils/libcurve25519_dalek-macos/libcurve25519_dalek.dylib +0 -0
- data/lib/solace/utils/libcurve25519_dalek-windows/curve25519_dalek.dll +0 -0
- data/lib/solace/utils/pda.rb +100 -0
- data/lib/solace/version.rb +5 -0
- data/lib/solace.rb +39 -0
- metadata +165 -0
@@ -0,0 +1,50 @@
|
|
1
|
+
# encoding: ASCII-8BIT
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# =============================
|
5
|
+
# Address Lookup Table
|
6
|
+
# =============================
|
7
|
+
#
|
8
|
+
# Class representing an address lookup table.
|
9
|
+
#
|
10
|
+
# The BufferLayout is:
|
11
|
+
# - [Account key (32 bytes)]
|
12
|
+
# - [Number of writable indexes (compact u16)]
|
13
|
+
# - [Writable indexes (variable length)]
|
14
|
+
# - [Number of readonly indexes (compact u16)]
|
15
|
+
# - [Readonly indexes (variable length)]
|
16
|
+
#
|
17
|
+
module Solace
|
18
|
+
class AddressLookupTable
|
19
|
+
include Solace::Concerns::BinarySerializable
|
20
|
+
|
21
|
+
# @!attribute [rw] account
|
22
|
+
# @return [String] The account key of the address lookup table
|
23
|
+
attr_accessor :account
|
24
|
+
|
25
|
+
# @!attribute [rw] writable_indexes
|
26
|
+
# @return [Array<Integer>] The writable indexes in the address lookup table
|
27
|
+
attr_accessor :writable_indexes
|
28
|
+
|
29
|
+
# @!attribute [rw] readonly_indexes
|
30
|
+
# @return [Array<Integer>] The readonly indexes in the address lookup table
|
31
|
+
attr_accessor :readonly_indexes
|
32
|
+
|
33
|
+
class << self
|
34
|
+
# Parse address lookup table from io stream
|
35
|
+
#
|
36
|
+
# @param io [IO or StringIO] The input to read bytes from.
|
37
|
+
# @return [Solace::AddressLookupTable] Parsed address lookup table object
|
38
|
+
def deserialize(io)
|
39
|
+
Solace::Serializers::AddressLookupTableDeserializer.call(io)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Serialize the address lookup table
|
44
|
+
#
|
45
|
+
# @return [String] The serialized address lookup table (base64)
|
46
|
+
def serialize
|
47
|
+
Solace::Serializers::AddressLookupTableSerializer.call(self)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solace
|
4
|
+
module Concerns
|
5
|
+
module BinarySerializable
|
6
|
+
# Returns the binary decoded from the serialized string
|
7
|
+
#
|
8
|
+
# Expects the class to have a `serialize` method that returns a base64 string.
|
9
|
+
#
|
10
|
+
# @return [String] The binary decoded from the serialized string
|
11
|
+
def to_binary
|
12
|
+
Base64.decode64(serialize)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Returns a StringIO stream of the binary data
|
16
|
+
#
|
17
|
+
# @return [IO] The StringIO stream of the binary data
|
18
|
+
def to_io
|
19
|
+
StringIO.new(to_binary)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Returns the bytes of the binary data as an array of integers
|
23
|
+
#
|
24
|
+
# @return [Array] The bytes of the binary data as an array of integers
|
25
|
+
def to_bytes
|
26
|
+
to_binary.bytes
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,187 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'net/http'
|
4
|
+
require 'json'
|
5
|
+
require 'uri'
|
6
|
+
|
7
|
+
module Solace
|
8
|
+
class Connection
|
9
|
+
attr_reader :rpc_url
|
10
|
+
|
11
|
+
# !const default options
|
12
|
+
DEFAULT_OPTIONS = {
|
13
|
+
encoding: 'base64',
|
14
|
+
commitment: 'confirmed'
|
15
|
+
}.freeze
|
16
|
+
|
17
|
+
# Initialize the connection with a default or custom RPC URL
|
18
|
+
#
|
19
|
+
# @param rpc_url [String] The URL of the Solana RPC node
|
20
|
+
# @return [Solace::Connection] The connection object
|
21
|
+
def initialize(rpc_url = 'http://localhost:8899')
|
22
|
+
@rpc_url = rpc_url
|
23
|
+
@request_id = nil
|
24
|
+
end
|
25
|
+
|
26
|
+
# Make an RPC request to the Solana node
|
27
|
+
#
|
28
|
+
# @param method [String] The RPC method to call
|
29
|
+
# @param params [Array] Parameters for the RPC method
|
30
|
+
# @return [Object] Result of the RPC call
|
31
|
+
def rpc_request(method, params = [])
|
32
|
+
uri = URI(rpc_url)
|
33
|
+
|
34
|
+
req = Net::HTTP::Post.new(uri)
|
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)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Request an airdrop of lamports to a given address
|
61
|
+
#
|
62
|
+
# @param pubkey [String] The public key of the account to receive the airdrop
|
63
|
+
# @param lamports [Integer] Amount of lamports to airdrop
|
64
|
+
# @return [String] The transaction signature of the airdrop
|
65
|
+
def request_airdrop(pubkey, lamports, options = {})
|
66
|
+
rpc_request(
|
67
|
+
'requestAirdrop',
|
68
|
+
[
|
69
|
+
pubkey,
|
70
|
+
lamports,
|
71
|
+
DEFAULT_OPTIONS.merge(options)
|
72
|
+
]
|
73
|
+
)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Get the latest blockhash from the Solana node
|
77
|
+
#
|
78
|
+
# @return [String] The latest blockhash
|
79
|
+
def get_latest_blockhash
|
80
|
+
rpc_request('getLatestBlockhash')['result']['value']['blockhash']
|
81
|
+
end
|
82
|
+
|
83
|
+
# Get the minimum required lamports for rent exemption
|
84
|
+
#
|
85
|
+
# @param space [Integer] Number of bytes to allocate for the account
|
86
|
+
# @return [Integer] The minimum required lamports
|
87
|
+
def get_minimum_lamports_for_rent_exemption(space)
|
88
|
+
rpc_request('getMinimumBalanceForRentExemption', [space])['result']
|
89
|
+
end
|
90
|
+
|
91
|
+
# Get the account information from the Solana node
|
92
|
+
#
|
93
|
+
# @param pubkey [String] The public key of the account
|
94
|
+
# @return [Object] The account information
|
95
|
+
def get_account_info(pubkey)
|
96
|
+
response = rpc_request(
|
97
|
+
'getAccountInfo',
|
98
|
+
[
|
99
|
+
pubkey,
|
100
|
+
DEFAULT_OPTIONS
|
101
|
+
]
|
102
|
+
)['result']
|
103
|
+
|
104
|
+
return if response.nil?
|
105
|
+
|
106
|
+
response['value']
|
107
|
+
end
|
108
|
+
|
109
|
+
# Get the balance of a specific account
|
110
|
+
#
|
111
|
+
# @param pubkey [String] The public key of the account
|
112
|
+
# @return [Integer] The balance of the account
|
113
|
+
def get_balance(pubkey)
|
114
|
+
rpc_request(
|
115
|
+
'getBalance',
|
116
|
+
[
|
117
|
+
pubkey,
|
118
|
+
DEFAULT_OPTIONS
|
119
|
+
]
|
120
|
+
)['result']['value']
|
121
|
+
end
|
122
|
+
|
123
|
+
# Get the transaction by signature
|
124
|
+
#
|
125
|
+
# @param signature [String] The signature of the transaction
|
126
|
+
# @return [Solace::Transaction] The transaction object
|
127
|
+
def get_transaction(signature, options = { maxSupportedTransactionVersion: 0 })
|
128
|
+
rpc_request(
|
129
|
+
'getTransaction',
|
130
|
+
[
|
131
|
+
signature,
|
132
|
+
DEFAULT_OPTIONS.merge(options)
|
133
|
+
]
|
134
|
+
)['result']
|
135
|
+
end
|
136
|
+
|
137
|
+
# Get the signature status
|
138
|
+
#
|
139
|
+
# @param signatures [Array] The signatures of the transactions
|
140
|
+
# @return [Object] The signature status
|
141
|
+
def get_signature_status(signatures)
|
142
|
+
rpc_request(
|
143
|
+
'getSignatureStatuses',
|
144
|
+
[
|
145
|
+
signatures,
|
146
|
+
DEFAULT_OPTIONS.merge({ 'searchTransactionHistory' => true })
|
147
|
+
]
|
148
|
+
)['result']
|
149
|
+
end
|
150
|
+
|
151
|
+
# Send a transaction to the Solana node
|
152
|
+
#
|
153
|
+
# @param transaction [Solace::Transaction] The transaction to send
|
154
|
+
# @return [String] The signature of the transaction
|
155
|
+
def send_transaction(transaction, options = {})
|
156
|
+
rpc_request(
|
157
|
+
'sendTransaction',
|
158
|
+
[
|
159
|
+
transaction,
|
160
|
+
DEFAULT_OPTIONS.merge(options)
|
161
|
+
]
|
162
|
+
)
|
163
|
+
end
|
164
|
+
|
165
|
+
# Wait for a confirmed signature from the transaction
|
166
|
+
#
|
167
|
+
# @param commitment [String] The commitment level to wait for
|
168
|
+
# @return [Boolean] True if the transaction was confirmed, false otherwise
|
169
|
+
def wait_for_confirmed_signature(commitment = 'confirmed')
|
170
|
+
raise ArgumentError, 'Block required' unless block_given?
|
171
|
+
|
172
|
+
# Get the signature from the block
|
173
|
+
signature = yield
|
174
|
+
|
175
|
+
# Wait for confirmation
|
176
|
+
loop do
|
177
|
+
status = get_signature_status([signature]).dig('value', 0)
|
178
|
+
|
179
|
+
break if status && status['confirmationStatus'] == commitment
|
180
|
+
|
181
|
+
sleep 0.5
|
182
|
+
end
|
183
|
+
|
184
|
+
signature
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Constants module
|
4
|
+
#
|
5
|
+
# Contains constants used across the library.
|
6
|
+
#
|
7
|
+
# @return [Module] Constants module
|
8
|
+
module Solace
|
9
|
+
module Constants
|
10
|
+
# @!const SYSTEM_PROGRAM_ID
|
11
|
+
# The public key of the System Program (native SOL transfers, account creation, etc)
|
12
|
+
# This is the same across all Solana clusters
|
13
|
+
# @return [String]
|
14
|
+
SYSTEM_PROGRAM_ID = '11111111111111111111111111111111'
|
15
|
+
|
16
|
+
# @!const SYSVAR_RENT_PROGRAM_ID
|
17
|
+
# The public key of the Rent Program
|
18
|
+
# This is the same across all Solana clusters
|
19
|
+
# @return [String]
|
20
|
+
SYSVAR_RENT_PROGRAM_ID = 'SysvarRent111111111111111111111111111111111'
|
21
|
+
|
22
|
+
# @!const COMPUTE_BUDGET_PROGRAM_ID
|
23
|
+
# The public key of the Compute Budget Program
|
24
|
+
# This is the same across all Solana clusters
|
25
|
+
# @return [String]
|
26
|
+
COMPUTE_BUDGET_PROGRAM_ID = 'ComputeBudget111111111111111111111111111111'
|
27
|
+
|
28
|
+
# @!const TOKEN_PROGRAM_ID
|
29
|
+
# The public key of the SPL Token Program
|
30
|
+
# This is the same across all Solana clusters
|
31
|
+
# @return [String]
|
32
|
+
TOKEN_PROGRAM_ID = 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'
|
33
|
+
|
34
|
+
# @!const ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID
|
35
|
+
# The public key of the Associated Token Account Program
|
36
|
+
# This is the same across all Solana clusters
|
37
|
+
# @return [String]
|
38
|
+
ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID = 'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL'
|
39
|
+
|
40
|
+
# @!const MEMO_PROGRAM_ID
|
41
|
+
# The public key of the Memo Program
|
42
|
+
# This is the same across all Solana clusters
|
43
|
+
# @return [String]
|
44
|
+
MEMO_PROGRAM_ID = 'MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr'
|
45
|
+
|
46
|
+
# @!const ADDRESS_LOOKUP_TABLE_PROGRAM_ID
|
47
|
+
# The public key of the Address Lookup Table Program
|
48
|
+
# This is the same across all Solana clusters
|
49
|
+
# @return [String]
|
50
|
+
ADDRESS_LOOKUP_TABLE_PROGRAM_ID = 'AddressLookupTab1e1111111111111111111111111'
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
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
|
+
module Solace
|
17
|
+
class Instruction < Solace::SerializableRecord
|
18
|
+
# @!const SERIALIZER
|
19
|
+
# @return [Solace::Serializers::InstructionSerializer] The serializer for the instruction
|
20
|
+
SERIALIZER = Solace::Serializers::InstructionSerializer
|
21
|
+
|
22
|
+
# @!const DESERIALIZER
|
23
|
+
# @return [Solace::Serializers::InstructionDeserializer] The deserializer for the instruction
|
24
|
+
DESERIALIZER = Solace::Serializers::InstructionDeserializer
|
25
|
+
|
26
|
+
# @!attribute [rw] program_index
|
27
|
+
# @return [Integer] The program index of the instruction
|
28
|
+
attr_accessor :program_index
|
29
|
+
|
30
|
+
# @!attribute [rw] accounts
|
31
|
+
# @return [Array<Integer>] The accounts of the instruction
|
32
|
+
attr_accessor :accounts
|
33
|
+
|
34
|
+
# @!attribute [rw] data
|
35
|
+
# @return [Array<Integer>] The instruction data
|
36
|
+
attr_accessor :data
|
37
|
+
end
|
38
|
+
end
|
data/lib/solace/instructions/associated_token_account/create_associated_token_account_instruction.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solace
|
4
|
+
module Instructions
|
5
|
+
module AssociatedTokenAccount
|
6
|
+
# A class to build the CreateAssociatedTokenAccount instruction for the Associated Token Account Program.
|
7
|
+
# This is a special "all-in-one" instruction that creates and initializes the account.
|
8
|
+
class CreateAssociatedTokenAccountInstruction
|
9
|
+
# !@const INSTRUCTION_INDEX
|
10
|
+
# Instruction index for CreateAssociatedTokenAccount
|
11
|
+
#
|
12
|
+
# @return [Array<Integer>]
|
13
|
+
INSTRUCTION_INDEX = [0].freeze
|
14
|
+
|
15
|
+
# Builds a CreateAssociatedTokenAccount instruction.
|
16
|
+
#
|
17
|
+
# The on-chain program requires accounts in a specific order:
|
18
|
+
# 1. [writable, signer] Funder: The account paying for the rent.
|
19
|
+
# 2. [writable] ATA: The new Associated Token Account to be created.
|
20
|
+
# 3. [readonly] Owner: The wallet that will own the new ATA.
|
21
|
+
# 4. [readonly] Mint: The token mint for the new ATA.
|
22
|
+
# 5. [readonly] System Program: Required to create the account.
|
23
|
+
# 6. [readonly] SPL Token Program: Required to initialize the account.
|
24
|
+
#
|
25
|
+
# @param funder_index [Integer] Index of the funding account (payer).
|
26
|
+
# @param associated_token_account_index [Integer] Index of the Associated Token Account to be created.
|
27
|
+
# @param owner_index [Integer] Index of the wallet that will own the new ATA.
|
28
|
+
# @param mint_index [Integer] Index of the token mint.
|
29
|
+
# @param system_program_index [Integer] Index of the System Program.
|
30
|
+
# @param token_program_index [Integer] Index of the SPL Token Program.
|
31
|
+
# @param program_index [Integer] Index of the Associated Token Program itself.
|
32
|
+
# @return [Solace::Instruction]
|
33
|
+
def self.build(
|
34
|
+
funder_index:,
|
35
|
+
associated_token_account_index:,
|
36
|
+
owner_index:,
|
37
|
+
mint_index:,
|
38
|
+
system_program_index:,
|
39
|
+
token_program_index:,
|
40
|
+
program_index:
|
41
|
+
)
|
42
|
+
Solace::Instruction.new.tap do |ix|
|
43
|
+
ix.program_index = program_index
|
44
|
+
ix.accounts = [
|
45
|
+
funder_index,
|
46
|
+
associated_token_account_index,
|
47
|
+
owner_index,
|
48
|
+
mint_index,
|
49
|
+
system_program_index,
|
50
|
+
token_program_index
|
51
|
+
]
|
52
|
+
ix.data = data
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Data for a CreateAssociatedTokenAccount instruction
|
57
|
+
#
|
58
|
+
# The BufferLayout is:
|
59
|
+
# - [Instruction Index (1 byte)]
|
60
|
+
#
|
61
|
+
# @return [Array] 1-byte instruction index
|
62
|
+
def self.data
|
63
|
+
INSTRUCTION_INDEX
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# lib/solace/instructions/spl_token/initialize_account_instruction.rb
|
2
|
+
|
3
|
+
module Solace
|
4
|
+
module Instructions
|
5
|
+
module SplToken
|
6
|
+
# A class to build the InitializeAccount instruction for the SPL Token Program.
|
7
|
+
class InitializeAccountInstruction
|
8
|
+
# @!const [Array<Integer>] INSTRUCTION_INDEX
|
9
|
+
# Instruction index for SPL Token Program's InitializeAccount instruction.
|
10
|
+
INSTRUCTION_INDEX = [1].freeze
|
11
|
+
|
12
|
+
# Builds a SPLToken::InitializeAccount instruction.
|
13
|
+
#
|
14
|
+
# @param account_index [Integer] Index of the new token account in the transaction's accounts.
|
15
|
+
# @param mint_index [Integer] Index of the mint account in the transaction's accounts.
|
16
|
+
# @param owner_index [Integer] Index of the owner of the new account in the transaction's accounts.
|
17
|
+
# @param rent_sysvar_index [Integer] Index of the Rent Sysvar in the transaction's accounts.
|
18
|
+
# @param program_index [Integer] Index of the SPL Token program in the transaction's accounts.
|
19
|
+
# @return [Solace::Instruction]
|
20
|
+
def self.build(
|
21
|
+
account_index:,
|
22
|
+
mint_index:,
|
23
|
+
owner_index:,
|
24
|
+
rent_sysvar_index:,
|
25
|
+
program_index:
|
26
|
+
)
|
27
|
+
Solace::Instruction.new.tap do |ix|
|
28
|
+
ix.program_index = program_index
|
29
|
+
ix.accounts = [account_index, mint_index, owner_index, rent_sysvar_index]
|
30
|
+
ix.data = data
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Builds the data for a SPLToken::InitializeAccount instruction.
|
35
|
+
#
|
36
|
+
# The BufferLayout is:
|
37
|
+
# - [Instruction Index (1 byte)]
|
38
|
+
#
|
39
|
+
# @return [Array] 1-byte instruction index
|
40
|
+
def self.data
|
41
|
+
INSTRUCTION_INDEX
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solace
|
4
|
+
module Instructions
|
5
|
+
module SplToken
|
6
|
+
class InitializeMintInstruction
|
7
|
+
# Instruction index for Initialize Mint
|
8
|
+
INSTRUCTION_INDEX = [0].freeze
|
9
|
+
|
10
|
+
# Builds a Solace::Instruction for initializing an SPL Token Program mint
|
11
|
+
#
|
12
|
+
# The BufferLayout is:
|
13
|
+
# - [Instruction Index (1 byte)]
|
14
|
+
# - [Decimals (1 byte)]
|
15
|
+
# - [Mint authority (32 bytes)]
|
16
|
+
# - [Freeze authority option (1 byte)]
|
17
|
+
# - [Freeze authority (32 bytes)]
|
18
|
+
#
|
19
|
+
# @param decimals [Integer] Number of decimals for the token
|
20
|
+
# @param mint_authority [String] Public key of the mint authority
|
21
|
+
# @param freeze_authority [String, nil] Public key of the freeze authority
|
22
|
+
# @param rent_sysvar_index [Integer] Index of the rent sysvar in the transaction's accounts
|
23
|
+
# @param mint_account_index [Integer] Index of the mint account in the transaction's accounts
|
24
|
+
# @param program_index [Integer] Index of the SPL Token Program in the transaction's accounts (default: 3)
|
25
|
+
# @return [Solace::Instruction]
|
26
|
+
def self.build(
|
27
|
+
decimals:,
|
28
|
+
mint_authority:,
|
29
|
+
rent_sysvar_index:,
|
30
|
+
mint_account_index:,
|
31
|
+
freeze_authority: nil,
|
32
|
+
program_index: 2
|
33
|
+
)
|
34
|
+
Solace::Instruction.new.tap do |ix|
|
35
|
+
ix.program_index = program_index
|
36
|
+
ix.accounts = [mint_account_index, rent_sysvar_index]
|
37
|
+
ix.data = data(decimals, mint_authority, freeze_authority)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Instruction data for an initialize mint instruction
|
42
|
+
#
|
43
|
+
# The BufferLayout is:
|
44
|
+
# - [Instruction Index (1 byte)]
|
45
|
+
# - [Decimals (1 byte)]
|
46
|
+
# - [Mint authority (32 bytes)]
|
47
|
+
# - [Freeze authority option (33 byte)]
|
48
|
+
#
|
49
|
+
# @param decimals [Integer] Number of decimals for the token
|
50
|
+
# @param mint_authority [String] Public key of the mint authority
|
51
|
+
# @param freeze_authority [String, nil] Public key of the freeze authority
|
52
|
+
# @return [Array] 1-byte instruction index + 1-byte decimals + 32-byte mint authority + 1-byte freeze authority option + 32-byte freeze authority
|
53
|
+
def self.data(decimals, mint_authority, freeze_authority)
|
54
|
+
INSTRUCTION_INDEX +
|
55
|
+
[decimals] +
|
56
|
+
Solace::Utils::Codecs.base58_to_bytes(mint_authority) +
|
57
|
+
(
|
58
|
+
if freeze_authority
|
59
|
+
[1] + Solace::Utils::Codecs.base58_to_bytes(freeze_authority)
|
60
|
+
else
|
61
|
+
[0]
|
62
|
+
end
|
63
|
+
)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solace
|
4
|
+
module Instructions
|
5
|
+
module SplToken
|
6
|
+
# A class to build the MintTo instruction for the SPL Token Program.
|
7
|
+
class MintToInstruction
|
8
|
+
# @!const [Array<Integer>] INSTRUCTION_INDEX
|
9
|
+
# Instruction index for SPL Token Program's MintTo instruction.
|
10
|
+
INSTRUCTION_INDEX = [7].freeze
|
11
|
+
|
12
|
+
# Builds a MintTo instruction.
|
13
|
+
#
|
14
|
+
# @param amount [Integer] The amount of tokens to mint.
|
15
|
+
# @param mint_index [Integer] The index of the mint account.
|
16
|
+
# @param destination_index [Integer] The index of the token account to mint to.
|
17
|
+
# @param mint_authority_index [Integer] The index of the mint authority account.
|
18
|
+
# @param program_index [Integer] The index of the SPL Token Program.
|
19
|
+
# @return [Solace::Instruction]
|
20
|
+
def self.build(
|
21
|
+
amount:,
|
22
|
+
mint_index:,
|
23
|
+
mint_authority_index:,
|
24
|
+
destination_index:,
|
25
|
+
program_index:
|
26
|
+
)
|
27
|
+
Solace::Instruction.new.tap do |ix|
|
28
|
+
ix.program_index = program_index
|
29
|
+
ix.accounts = [mint_index, destination_index, mint_authority_index]
|
30
|
+
ix.data = data(amount)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Builds the data for a MintTo instruction.
|
35
|
+
#
|
36
|
+
# The BufferLayout is:
|
37
|
+
# - [Instruction Index (1 byte)]
|
38
|
+
# - [Amount (8 bytes)]
|
39
|
+
#
|
40
|
+
# @param amount [Integer] The amount of tokens to mint.
|
41
|
+
# @return [Array] 1-byte instruction index + 8-byte amount
|
42
|
+
def self.data(amount)
|
43
|
+
INSTRUCTION_INDEX + Solace::Utils::Codecs.encode_le_u64(amount).bytes
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solace
|
4
|
+
module Instructions
|
5
|
+
module SplToken
|
6
|
+
# A class to build the Transfer instruction for the SPL Token Program.
|
7
|
+
class TransferInstruction
|
8
|
+
# @!const [Array<Integer>] INSTRUCTION_INDEX
|
9
|
+
# Instruction index for SPL Token Program's Transfer instruction.
|
10
|
+
INSTRUCTION_INDEX = [3].freeze
|
11
|
+
|
12
|
+
# Builds a Transfer instruction.
|
13
|
+
#
|
14
|
+
# @param amount [Integer] The amount of tokens to transfer.
|
15
|
+
# @param source_index [Integer] The index of the source token account.
|
16
|
+
# @param destination_index [Integer] The index of the destination token account.
|
17
|
+
# @param owner_index [Integer] The index of the source account's owner.
|
18
|
+
# @param program_index [Integer] The index of the SPL Token Program.
|
19
|
+
# @return [Solace::Instruction]
|
20
|
+
def self.build(
|
21
|
+
amount:,
|
22
|
+
owner_index:,
|
23
|
+
source_index:,
|
24
|
+
destination_index:,
|
25
|
+
program_index:
|
26
|
+
)
|
27
|
+
Solace::Instruction.new.tap do |ix|
|
28
|
+
ix.program_index = program_index
|
29
|
+
ix.accounts = [source_index, destination_index, owner_index]
|
30
|
+
ix.data = data(amount)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Builds the data for a Transfer instruction.
|
35
|
+
#
|
36
|
+
# The BufferLayout is:
|
37
|
+
# - [Instruction Index (1 byte)]
|
38
|
+
# - [Amount (8 bytes)]
|
39
|
+
#
|
40
|
+
# @param amount [Integer] The amount of tokens to transfer.
|
41
|
+
# @return [Array<Integer>] 1-byte instruction index + 8-byte amount
|
42
|
+
def self.data(amount)
|
43
|
+
INSTRUCTION_INDEX + Solace::Utils::Codecs.encode_le_u64(amount).bytes
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|