solace 0.0.10 → 0.1.0
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 +104 -23
- data/README.md +10 -8
- data/lib/solace/composers/base.rb +35 -0
- data/lib/solace/composers/spl_token_program_initialize_mint_composer.rb +95 -0
- data/lib/solace/composers/spl_token_program_mint_to_composer.rb +86 -0
- data/lib/solace/composers/spl_token_program_transfer_composer.rb +90 -0
- data/lib/solace/composers/system_program_create_account_composer.rb +98 -0
- data/lib/solace/connection.rb +88 -13
- data/lib/solace/errors/confirmation_timeout.rb +18 -4
- data/lib/solace/errors/http_error.rb +16 -1
- data/lib/solace/errors/parse_error.rb +15 -1
- data/lib/solace/errors/rpc_error.rb +17 -1
- data/lib/solace/errors.rb +8 -3
- data/lib/solace/instructions/associated_token_account/create_associated_token_account_instruction.rb +9 -2
- data/lib/solace/instructions/spl_token/initialize_mint_instruction.rb +0 -1
- data/lib/solace/instructions/spl_token/transfer_instruction.rb +21 -0
- data/lib/solace/instructions/system_program/create_account_instruction.rb +30 -0
- data/lib/solace/instructions/system_program/transfer_instruction.rb +11 -0
- data/lib/solace/programs/associated_token_account.rb +57 -30
- data/lib/solace/programs/base.rb +23 -0
- data/lib/solace/programs/spl_token.rb +197 -125
- data/lib/solace/serializers/base_serializer.rb +29 -1
- data/lib/solace/tokens/token.rb +53 -0
- data/lib/solace/tokens.rb +86 -0
- data/lib/solace/transaction.rb +24 -21
- data/lib/solace/transaction_composer.rb +77 -3
- data/lib/solace/utils/account_context.rb +1 -1
- data/lib/solace/utils/codecs.rb +17 -0
- data/lib/solace/utils/pda.rb +13 -5
- data/lib/solace/version.rb +3 -2
- data/lib/solace.rb +38 -11
- metadata +21 -1
@@ -2,7 +2,16 @@
|
|
2
2
|
|
3
3
|
# lib/solace/transaction_composer.rb
|
4
4
|
module Solace
|
5
|
-
# Composes
|
5
|
+
# Composes transactions with automatic account management and instruction building.
|
6
|
+
#
|
7
|
+
# This class allows you to add multiple instruction composers, manage account contexts,
|
8
|
+
# and build a complete transaction in a flexible way. It is a high-level abstraction over
|
9
|
+
# the process of creating Solana transactions, making it easier to work with complex
|
10
|
+
# transaction scenarios.
|
11
|
+
#
|
12
|
+
# For most use cases, you will create an instance of this class, add instruction composers,
|
13
|
+
# and then call the `compose_transaction` method to build the final transaction. That said,
|
14
|
+
# all of the individual pieces are also accessible for more advanced use cases.
|
6
15
|
#
|
7
16
|
# @example
|
8
17
|
# # Initialize a transaction composer
|
@@ -38,6 +47,18 @@ module Solace
|
|
38
47
|
# # Sign the transaction with all required signers
|
39
48
|
# tx.sign(*required_signers)
|
40
49
|
#
|
50
|
+
# @example
|
51
|
+
# # Chaining methods will return the composer itself for further modifications. The add, prepend,
|
52
|
+
# # and insert methods allow for dynamic insertion of instruction composers at required positions.
|
53
|
+
# transaction_composer = Solace::TransactionComposer
|
54
|
+
# .new(connection: connection)
|
55
|
+
# .add_instruction(instruction_composer_1)
|
56
|
+
# .prepend_instruction(instruction_composer_2)
|
57
|
+
# .insert_instruction(1, instruction_composer_3)
|
58
|
+
# .set_fee_payer(fee_payer_pubkey)
|
59
|
+
# .compose_transaction
|
60
|
+
#
|
61
|
+
# @see Solace::Composers::Base
|
41
62
|
# @since 0.0.6
|
42
63
|
class TransactionComposer
|
43
64
|
# @!attribute connection
|
@@ -71,9 +92,62 @@ module Solace
|
|
71
92
|
self
|
72
93
|
end
|
73
94
|
|
95
|
+
# Prepend an instruction composer to the transaction
|
96
|
+
#
|
97
|
+
# @param composer [Composers::Base] The instruction composer
|
98
|
+
# @return [TransactionComposer] Self for chaining
|
99
|
+
#
|
100
|
+
# @since 0.1.0
|
101
|
+
def prepend_instruction(composer)
|
102
|
+
merge_accounts(composer.account_context)
|
103
|
+
instruction_composers.unshift(composer)
|
104
|
+
self
|
105
|
+
end
|
106
|
+
|
107
|
+
# Insert an instruction composer at a specific index
|
108
|
+
#
|
109
|
+
# @param index [Integer] The index to insert at
|
110
|
+
# @param composer [Composers::Base] The instruction composer
|
111
|
+
# @return [TransactionComposer] Self for chaining
|
112
|
+
#
|
113
|
+
# @since 0.1.0
|
114
|
+
def insert_instruction(index, composer)
|
115
|
+
merge_accounts(composer.account_context)
|
116
|
+
instruction_composers.insert(index, composer)
|
117
|
+
self
|
118
|
+
end
|
119
|
+
|
120
|
+
# Merge another TransactionComposer into this one
|
121
|
+
#
|
122
|
+
# @param other [TransactionComposer] The other composer to merge
|
123
|
+
# @param placement [Symbol] :add to append, :prepend to prepend
|
124
|
+
# @param index [Integer, nil] The index to insert at if placement is :insert
|
125
|
+
# @return [TransactionComposer] Self for chaining
|
126
|
+
#
|
127
|
+
# @since 0.1.0
|
128
|
+
def merge(other, placement: :add, index: nil)
|
129
|
+
merge_accounts(other.context)
|
130
|
+
|
131
|
+
case placement
|
132
|
+
when :add
|
133
|
+
# Appends the other's instruction composers to this one's list
|
134
|
+
instruction_composers.concat(other.instruction_composers)
|
135
|
+
when :insert
|
136
|
+
# Inserts the other's instruction composers at the specified index
|
137
|
+
instruction_composers.insert(index, *other.instruction_composers)
|
138
|
+
when :prepend
|
139
|
+
# Prepends the other's instruction composers to this one's list
|
140
|
+
instruction_composers.unshift(*other.instruction_composers)
|
141
|
+
else
|
142
|
+
raise ArgumentError, "Invalid placement option: #{placement}"
|
143
|
+
end
|
144
|
+
|
145
|
+
self
|
146
|
+
end
|
147
|
+
|
74
148
|
# Set the fee payer for the transaction
|
75
149
|
#
|
76
|
-
# @param pubkey [
|
150
|
+
# @param pubkey [#to_s, PublicKey] The fee payer pubkey
|
77
151
|
# @return [TransactionComposer] Self for chaining
|
78
152
|
def set_fee_payer(pubkey)
|
79
153
|
context.set_fee_payer(pubkey.to_s)
|
@@ -82,7 +156,7 @@ module Solace
|
|
82
156
|
|
83
157
|
# Compose the final transaction
|
84
158
|
#
|
85
|
-
# @return [
|
159
|
+
# @return [Transaction] The composed transaction (unsigned)
|
86
160
|
def compose_transaction
|
87
161
|
context.compile
|
88
162
|
|
@@ -199,7 +199,7 @@ module Solace
|
|
199
199
|
|
200
200
|
# Add or merge an account into the context
|
201
201
|
#
|
202
|
-
# @param pubkey [
|
202
|
+
# @param pubkey [#to_s, PublicKey] The public key of the account
|
203
203
|
# @param signer [Boolean] Whether the account is a signer
|
204
204
|
# @param writable [Boolean] Whether the account is writable
|
205
205
|
# @param [Boolean] fee_payer
|
data/lib/solace/utils/codecs.rb
CHANGED
@@ -6,6 +6,23 @@ require 'base58'
|
|
6
6
|
require 'stringio'
|
7
7
|
|
8
8
|
module Solace
|
9
|
+
# The Utils module contains utility classes and helper methods used throughout
|
10
|
+
# the Solace gem.
|
11
|
+
#
|
12
|
+
# This module provides foundational utilities that support the core functionality
|
13
|
+
# of the gem, including:
|
14
|
+
# - {Solace::Utils::AccountContext} - Account management for transactions
|
15
|
+
# - {Solace::Utils::Codecs} - Encoding and decoding utilities
|
16
|
+
# - {Solace::Utils::Curve25519Dalek} - Cryptographic operations via FFI
|
17
|
+
# - {Solace::Utils::PDA} - Program Derived Address generation
|
18
|
+
# - {Solace::Utils::RPCClient} - Low-level RPC communication
|
19
|
+
#
|
20
|
+
# These utilities are primarily used internally by other parts of the gem, but
|
21
|
+
# can also be used directly for advanced use cases.
|
22
|
+
#
|
23
|
+
# @see Solace::Connection
|
24
|
+
# @see Solace::Keypair
|
25
|
+
# @since 0.0.1
|
9
26
|
module Utils
|
10
27
|
# Module for encoding and decoding data
|
11
28
|
#
|
data/lib/solace/utils/pda.rb
CHANGED
@@ -5,13 +5,21 @@ require 'digest'
|
|
5
5
|
|
6
6
|
module Solace
|
7
7
|
module Utils
|
8
|
-
#
|
8
|
+
# Raised when Program Derived Address (PDA) generation fails.
|
9
9
|
#
|
10
|
-
# This
|
11
|
-
#
|
12
|
-
#
|
10
|
+
# This error is raised when attempting to derive a PDA that is invalid, typically
|
11
|
+
# because the seeds and program ID combination results in a point that lies on
|
12
|
+
# the Ed25519 curve (PDAs must be off-curve). This is a rare occurrence but can
|
13
|
+
# happen with certain seed combinations.
|
13
14
|
#
|
14
|
-
# @
|
15
|
+
# @example Handling invalid PDA
|
16
|
+
# begin
|
17
|
+
# pda = Solace::Utils::PDA.find_program_address(seeds, program_id)
|
18
|
+
# rescue Solace::Utils::PDA::InvalidPDAError => e
|
19
|
+
# puts "Failed to derive PDA: #{e.message}"
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# @see Solace::Utils::PDA
|
15
23
|
# @since 0.0.1
|
16
24
|
module PDA
|
17
25
|
# InvalidPDAError is an error raised when an invalid PDA is generated
|
data/lib/solace/version.rb
CHANGED
data/lib/solace.rb
CHANGED
@@ -1,9 +1,37 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
#
|
3
|
+
# Solace is a Ruby gem for interacting with the Solana blockchain.
|
4
|
+
#
|
5
|
+
# This gem provides a comprehensive toolkit for building, signing, and sending
|
6
|
+
# transactions to Solana RPC nodes. It includes utilities for managing keypairs,
|
7
|
+
# composing complex instructions, serializing data, and interacting with
|
8
|
+
# on-chain programs like the System Program, SPL Token Program, and Associated
|
9
|
+
# Token Account Program.
|
10
|
+
#
|
11
|
+
# The gem is designed to be modular and extensible, with clear separation between
|
12
|
+
# low-level primitives (instructions, serializers) and high-level abstractions
|
13
|
+
# (composers, programs).
|
14
|
+
#
|
15
|
+
# @example Basic usage
|
16
|
+
# # Connect to a Solana RPC node
|
17
|
+
# connection = Solace::Connection.new('https://api.mainnet-beta.solana.com')
|
18
|
+
#
|
19
|
+
# # Generate a keypair
|
20
|
+
# keypair = Solace::Keypair.generate
|
21
|
+
#
|
22
|
+
# # Check balance
|
23
|
+
# balance = connection.get_balance(keypair.public_key)
|
24
|
+
#
|
25
|
+
# @see https://docs.solana.com/
|
26
|
+
# @see https://github.com/zarpay/solace
|
27
|
+
# @author Sebastian Scholl
|
28
|
+
# @since 0.0.1
|
29
|
+
module Solace; end
|
30
|
+
|
31
|
+
# Version
|
4
32
|
require_relative 'solace/version'
|
5
33
|
|
6
|
-
#
|
34
|
+
# Helpers
|
7
35
|
require_relative 'solace/errors'
|
8
36
|
require_relative 'solace/constants'
|
9
37
|
require_relative 'solace/connection'
|
@@ -13,11 +41,14 @@ require_relative 'solace/utils/account_context'
|
|
13
41
|
require_relative 'solace/utils/curve25519_dalek'
|
14
42
|
require_relative 'solace/concerns/binary_serializable'
|
15
43
|
|
16
|
-
#
|
44
|
+
# Tokens
|
45
|
+
require_relative 'solace/tokens'
|
46
|
+
|
47
|
+
# Serializers
|
17
48
|
require_relative 'solace/serializers/base_serializer'
|
18
49
|
require_relative 'solace/serializers/base_deserializer'
|
19
50
|
|
20
|
-
#
|
51
|
+
# Primitives
|
21
52
|
require_relative 'solace/keypair'
|
22
53
|
require_relative 'solace/public_key'
|
23
54
|
require_relative 'solace/transaction'
|
@@ -30,16 +61,12 @@ require_relative 'solace/transaction_composer'
|
|
30
61
|
require_relative 'solace/programs/base'
|
31
62
|
require_relative 'solace/composers/base'
|
32
63
|
|
33
|
-
#
|
34
|
-
#
|
35
|
-
# Glob require all composers
|
64
|
+
# Composers
|
36
65
|
Dir[File.join(__dir__, 'solace/composers', '**', '*.rb')].each { |file| require file }
|
37
66
|
|
38
|
-
#
|
39
|
-
#
|
40
|
-
# Glob require all instructions
|
67
|
+
# Instructions (Builders)
|
41
68
|
Dir[File.join(__dir__, 'solace/instructions', '**', '*.rb')].each { |file| require file }
|
42
69
|
|
43
|
-
#
|
70
|
+
# Programs
|
44
71
|
require_relative 'solace/programs/spl_token'
|
45
72
|
require_relative 'solace/programs/associated_token_account'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: solace
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sebastian Scholl
|
@@ -79,6 +79,20 @@ dependencies:
|
|
79
79
|
- - "~>"
|
80
80
|
- !ruby/object:Gem::Version
|
81
81
|
version: '13.0'
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
name: tty-spinner
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
type: :development
|
90
|
+
prerelease: false
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
82
96
|
description: A Ruby library for working with Solana blockchain. Provides both low-level
|
83
97
|
instruction builders and high-level program clients for interacting with Solana
|
84
98
|
programs.
|
@@ -95,7 +109,11 @@ files:
|
|
95
109
|
- lib/solace/address_lookup_table.rb
|
96
110
|
- lib/solace/composers/associated_token_account_program_create_account_composer.rb
|
97
111
|
- lib/solace/composers/base.rb
|
112
|
+
- lib/solace/composers/spl_token_program_initialize_mint_composer.rb
|
113
|
+
- lib/solace/composers/spl_token_program_mint_to_composer.rb
|
98
114
|
- lib/solace/composers/spl_token_program_transfer_checked_composer.rb
|
115
|
+
- lib/solace/composers/spl_token_program_transfer_composer.rb
|
116
|
+
- lib/solace/composers/system_program_create_account_composer.rb
|
99
117
|
- lib/solace/composers/system_program_transfer_composer.rb
|
100
118
|
- lib/solace/concerns/binary_serializable.rb
|
101
119
|
- lib/solace/connection.rb
|
@@ -130,6 +148,8 @@ files:
|
|
130
148
|
- lib/solace/serializers/message_serializer.rb
|
131
149
|
- lib/solace/serializers/transaction_deserializer.rb
|
132
150
|
- lib/solace/serializers/transaction_serializer.rb
|
151
|
+
- lib/solace/tokens.rb
|
152
|
+
- lib/solace/tokens/token.rb
|
133
153
|
- lib/solace/transaction.rb
|
134
154
|
- lib/solace/transaction_composer.rb
|
135
155
|
- lib/solace/utils/account_context.rb
|