solana-ruby 0.1.0 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,105 @@
1
+ require 'rbnacl'
2
+ require 'json'
3
+ require_relative 'utils'
4
+
5
+ module Solana
6
+ ##
7
+ # The Keypair class represents a keypair for signing transactions on the Solana blockchain.
8
+ #
9
+ class Keypair
10
+ attr_reader :public_key, :secret_key
11
+
12
+ ##
13
+ # Initializes a new Keypair.
14
+ #
15
+ # If a +secret_key+ is provided, it must be 64 bytes long. The first 32 bytes are used as the signing key,
16
+ # and the public key is derived from it. If no +secret_key+ is provided, a new keypair is generated.
17
+ #
18
+ # Raises an error if the +secret_key+ is not 64 bytes long.
19
+ #
20
+ # @param [String, nil] secret_key The secret key to use for the keypair, in binary format (optional).
21
+ def initialize(secret_key = nil)
22
+ if secret_key
23
+ raise 'Bad secret key size' unless secret_key.bytesize == 64
24
+ @signing_key = RbNaCl::Signatures::Ed25519::SigningKey.new(secret_key[0, 32])
25
+ @public_key = @signing_key.verify_key.to_bytes
26
+ else
27
+ @signing_key = RbNaCl::Signatures::Ed25519::SigningKey.generate
28
+ @public_key = @signing_key.verify_key.to_bytes
29
+ end
30
+ @secret_key = @signing_key.to_bytes + @public_key
31
+ end
32
+
33
+ ##
34
+ # Generates a new Keypair.
35
+ #
36
+ # @return [Keypair] A new Keypair instance.
37
+ def self.generate
38
+ new
39
+ end
40
+
41
+ ##
42
+ # Creates a Keypair from a provided secret key.
43
+ #
44
+ # @param [String] secret_key The secret key in binary format.
45
+ # @return [Keypair] A new Keypair instance initialized with the provided secret key.
46
+ def self.from_secret_key(secret_key)
47
+ new(secret_key)
48
+ end
49
+
50
+ ##
51
+ # Saves the keypair to a JSON file.
52
+ #
53
+ # The public and secret keys are encoded in Base58 format before being saved.
54
+ #
55
+ # @param [String] file_path The path to the file where the keypair will be saved.
56
+ def save_to_json(file_path)
57
+ data = {
58
+ public_key: Utils::base58_encode(@public_key),
59
+ secret_key: Utils::base58_encode(@secret_key)
60
+ }
61
+ File.write(file_path, data.to_json)
62
+ end
63
+
64
+ ##
65
+ # Loads a keypair from a JSON file.
66
+ #
67
+ # The file must contain the public and secret keys in Base58 format. The method verifies the size of the secret key and
68
+ # checks that the derived public key matches the saved public key.
69
+ #
70
+ # Raises an error if the +secret_key+ is not 64 bytes long or if the derived public key does not match the saved public key.
71
+ #
72
+ # @param [String] file_path The path to the file from which the keypair will be loaded.
73
+ # @return [Keypair] The loaded keypair.
74
+ def self.load_from_json(file_path)
75
+ data = JSON.parse(File.read(file_path), symbolize_names: true)
76
+ secret_key = Utils::base58_decode(data[:secret_key])
77
+ public_key = Utils::base58_decode(data[:public_key])
78
+
79
+ raise 'Bad secret key size' unless secret_key.bytesize == 64
80
+
81
+ signing_key = RbNaCl::Signatures::Ed25519::SigningKey.new(secret_key[0, 32])
82
+ loaded_public_key = signing_key.verify_key.to_bytes
83
+
84
+ raise 'Provided secretKey is invalid' unless loaded_public_key == public_key
85
+
86
+ new(secret_key)
87
+ end
88
+
89
+ ##
90
+ # Returns the public key for this keypair in Base58 format.
91
+ #
92
+ # @return [String] The public key in Base58 format.
93
+ def public_key_base58
94
+ Utils::base58_encode(@public_key)
95
+ end
96
+
97
+ ##
98
+ # Returns the raw secret key for this keypair in Base58 format.
99
+ #
100
+ # @return [String] The secret key in Base58 format.
101
+ def secret_key_base58
102
+ Utils::base58_encode(@secret_key)
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,107 @@
1
+ require 'base58'
2
+ require 'base64'
3
+
4
+ module Solana
5
+ ##
6
+ # The Utils module provides utility methods and constants for interacting with the Solana blockchain.
7
+ #
8
+ module Utils
9
+ ##
10
+ # The system program ID for Solana.
11
+ SYSTEM_PROGRAM_ID = '11111111111111111111111111111111'
12
+
13
+ ##
14
+ # The maximum packet data size for Solana transactions.
15
+ PACKET_DATA_SIZE = 1232
16
+
17
+ ##
18
+ # Endpoints for the mainnet.
19
+ module MAINNET
20
+ ##
21
+ # HTTP endpoint for the mainnet.
22
+ HTTP = 'https://api.mainnet-beta.solana.com'
23
+
24
+ ##
25
+ # WebSocket endpoint for the mainnet.
26
+ WS = 'wss://api.mainnet-beta.solana.com'
27
+ end
28
+
29
+ ##
30
+ # Endpoints for the testnet.
31
+ module TESTNET
32
+ ##
33
+ # HTTP endpoint for the testnet.
34
+ HTTP = 'https://api.testnet.solana.com'
35
+
36
+ ##
37
+ # WebSocket endpoint for the testnet.
38
+ WS = 'wss://api.testnet.solana.com'
39
+ end
40
+
41
+ ##
42
+ # Endpoints for the devnet.
43
+ module DEVNET
44
+ ##
45
+ # HTTP endpoint for the devnet.
46
+ HTTP = 'https://api.devnet.solana.com'
47
+
48
+ ##
49
+ # WebSocket endpoint for the devnet.
50
+ WS = 'wss://api.devnet.solana.com'
51
+ end
52
+
53
+ ##
54
+ # Instruction types for Solana transactions.
55
+ module InstructionType
56
+ CREATE_ACCOUNT = 0
57
+ ASSIGN = 1
58
+ TRANSFER = 2
59
+ CREATE_ACCOUNT_WITH_SEED = 3
60
+ ADVANCE_NONCE_ACCOUNT = 4
61
+ WITHDRAW_NONCE_ACCOUNT = 5
62
+ INITIALIZE_NONCE_ACCOUNT = 6
63
+ AUTHORIZE_NONCE_ACCOUNT = 7
64
+ ALLOCATE = 8
65
+ ALLOCATE_WITH_SEED = 9
66
+ ASSIGN_WITH_SEED = 10
67
+ TRANSFER_WITH_SEED = 11
68
+ end
69
+
70
+ ##
71
+ # Encodes a byte array into a Base58 string.
72
+ #
73
+ # @param [String] bytes The byte array to encode.
74
+ # @return [String] The Base58-encoded string.
75
+ def self.base58_encode(bytes)
76
+ Base58.binary_to_base58(bytes, :bitcoin)
77
+ end
78
+
79
+ ##
80
+ # Decodes a Base58 string into a byte array.
81
+ #
82
+ # @param [String] base58 The Base58 string to decode.
83
+ # @return [String] The decoded byte array.
84
+ def self.base58_decode(base58)
85
+ Base58.base58_to_binary(base58, :bitcoin)
86
+ end
87
+
88
+ ##
89
+ # Encodes a byte array into a Base64 string.
90
+ #
91
+ # @param [String] bytes The byte array to encode.
92
+ # @return [String] The Base64-encoded string.
93
+ def self.base64_encode(bytes)
94
+ Base64.strict_encode64(bytes)
95
+ end
96
+
97
+ ##
98
+ # Decodes a Base64 string into a byte array.
99
+ #
100
+ # @param [String] base64 The Base64 string to decode.
101
+ # @return [String] The decoded byte array.
102
+ def self.base64_decode(base64)
103
+ Base64.strict_decode64(base64)
104
+ end
105
+ end
106
+ Utils.freeze
107
+ end
@@ -1,3 +1,3 @@
1
- module SolanaRB
2
- VERSION = '0.1.0'.freeze
3
- end
1
+ module Solana
2
+ VERSION = '0.1.2'.freeze
3
+ end
data/lib/solana-ruby.rb CHANGED
@@ -1,5 +1,7 @@
1
- require_relative 'solana-ruby/version'
2
1
  require_relative 'solana-ruby/client'
2
+ require_relative 'solana-ruby/keypair'
3
+ require_relative 'solana-ruby/utils'
4
+ require_relative 'solana-ruby/version'
3
5
 
4
- module SolanaRB
6
+ module Solana
5
7
  end
metadata CHANGED
@@ -1,29 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solana-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fabrice Renard
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-06-23 00:00:00.000000000 Z
11
+ date: 2024-06-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: httparty
14
+ name: httpx
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.18.0
19
+ version: '1.2'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.18.0
26
+ version: '1.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: faye-websocket
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.11.3
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.11.3
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: csv
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -38,6 +52,76 @@ dependencies:
38
52
  - - "~>"
39
53
  - !ruby/object:Gem::Version
40
54
  version: '3.1'
55
+ - !ruby/object:Gem::Dependency
56
+ name: ed25519
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.3'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.3'
69
+ - !ruby/object:Gem::Dependency
70
+ name: base58
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.2.3
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.2.3
83
+ - !ruby/object:Gem::Dependency
84
+ name: base64
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.2.0
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.2.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: rdoc
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 6.7.0
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 6.7.0
111
+ - !ruby/object:Gem::Dependency
112
+ name: rqrcode
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '2.0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '2.0'
41
125
  - !ruby/object:Gem::Dependency
42
126
  name: rspec
43
127
  requirement: !ruby/object:Gem::Requirement
@@ -75,11 +159,14 @@ extra_rdoc_files: []
75
159
  files:
76
160
  - lib/solana-ruby.rb
77
161
  - lib/solana-ruby/client.rb
162
+ - lib/solana-ruby/keypair.rb
163
+ - lib/solana-ruby/utils.rb
78
164
  - lib/solana-ruby/version.rb
79
165
  homepage: https://github.com/fabricerenard12/solana-ruby
80
166
  licenses:
81
167
  - MIT
82
- metadata: {}
168
+ metadata:
169
+ homepage_uri: https://github.com/fabricerenard12/solana-ruby
83
170
  post_install_message:
84
171
  rdoc_options: []
85
172
  require_paths:
@@ -98,5 +185,5 @@ requirements: []
98
185
  rubygems_version: 3.5.9
99
186
  signing_key:
100
187
  specification_version: 4
101
- summary: A Ruby wrapper for the Solana blockchain API
188
+ summary: A Ruby SDK for the Solana blockchain API
102
189
  test_files: []