solana-ruby-web3js 2.1.5 → 2.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/CHANGELOG.md +14 -0
- data/Gemfile.lock +1 -1
- data/README.md +403 -363
- data/lib/solana_ruby/ed25519_curve_checker.rb +15 -5
- data/lib/solana_ruby/transaction_helpers/token_account.rb +2 -1
- data/lib/solana_ruby/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d2808f06359bc53bf28e0b37def2f3121ec06cd2bfbd395c7dc4d76fadafbb5d
|
|
4
|
+
data.tar.gz: ccf0936cc418819993e11c8e1d8f2560e347dcbe6f04619cd35fdda2bfcff87a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 117640ecc3f311f9a934c21b02e406fea8a2d374cb1a63259932a228517aaa5ac23877462bc978253babd944deb3a9f0bcf429e6f5f172f5d7850380b4bd2056
|
|
7
|
+
data.tar.gz: dea3c75aff80061569d54e9a14b82f424fdcdf8d50f60da38756e79addcebb110953fd4312a99d99e9cb87aa0c47f479c7841b57d24140c7d13feacec5dc9744
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## 2.1.6 – 2026-02-24
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- Fixed Ed25519 public key curve validation:
|
|
8
|
+
- Clear x-sign bit correctly
|
|
9
|
+
- Interpret y-coordinate as little-endian
|
|
10
|
+
- Fixed PDA / ATA derivation mismatches caused by incorrect seed hashing
|
|
11
|
+
- Resolves invalid Associated Token Address generation (issue #13)
|
|
12
|
+
|
|
13
|
+
This release fixes cases where previously generated ATAs could differ
|
|
14
|
+
from on-chain derivation and fail with:
|
|
15
|
+
"Provided seeds do not result in a valid address"
|
|
16
|
+
|
|
3
17
|
## [0.1.0] - 2024-07-31
|
|
4
18
|
|
|
5
19
|
- Initial release
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -22,40 +22,46 @@ Or install it yourself as:
|
|
|
22
22
|
|
|
23
23
|
To start using the Solana RPC client, initialize it with or without the RPC URL. The default URL points to the Solana Mainnet. If you wish to connect to another network like Devnet or Testnet, you can specify the URL.
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
```ruby
|
|
26
|
+
require 'solana_ruby'
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
# Initialize the client (defaults to Mainnet(https://api.mainnet-beta.solana.com))
|
|
29
|
+
client = SolanaRuby::HttpClient.new()
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
# Optionally, provide a custom RPC URL
|
|
32
|
+
# client = SolanaRuby::HttpClient.new("https://api.devnet.solana.com")
|
|
33
|
+
```
|
|
32
34
|
|
|
33
35
|
### Fetch Solana Account Balance
|
|
34
36
|
|
|
35
37
|
Once the client is initialized, you can make API calls to the Solana network. For example, to get the solana balance of a given account:
|
|
36
38
|
|
|
37
|
-
|
|
39
|
+
```ruby
|
|
40
|
+
# Replace 'pubkey' with the actual public key of the solana account
|
|
38
41
|
|
|
39
|
-
|
|
42
|
+
pubkey = 'Fg6PaFpoGXkYsidMpWxTWqSKJf6KJkUxX92cnv7WMd2J'
|
|
40
43
|
|
|
41
|
-
|
|
44
|
+
result = client.get_balance(pubkey)
|
|
42
45
|
|
|
43
|
-
|
|
46
|
+
puts result
|
|
47
|
+
```
|
|
44
48
|
|
|
45
49
|
### Fetch Parsed Account Info
|
|
46
50
|
|
|
47
|
-
|
|
48
|
-
|
|
51
|
+
```ruby
|
|
52
|
+
# Replace 'pubkey' with the actual public key of the account
|
|
53
|
+
pubkey = 'Fg6PaFpoGXkYsidMpWxTWqSKJf6KJkUxX92cnv7WMd2J'
|
|
49
54
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
+
# Example of options that can be passed:
|
|
56
|
+
options = {
|
|
57
|
+
commitment: 'finalized', # Specifies the level of commitment for querying state (e.g., 'finalized', 'confirmed', 'processed')
|
|
58
|
+
encoding: 'jsonParsed' # Specifies the encoding format (e.g., 'jsonParsed', 'base64', etc.)
|
|
59
|
+
}
|
|
55
60
|
|
|
56
|
-
|
|
61
|
+
result = client.get_parsed_account_info(pubkey, options)
|
|
57
62
|
|
|
58
|
-
|
|
63
|
+
puts result
|
|
64
|
+
```
|
|
59
65
|
|
|
60
66
|
### More Information on Solana Methods
|
|
61
67
|
|
|
@@ -71,15 +77,15 @@ The options parameter is a hash that can include the following fields and more,
|
|
|
71
77
|
|
|
72
78
|
- **commitment**: Specifies the level of commitment desired when querying state. Options include:
|
|
73
79
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
80
|
+
- 'finalized': Query the most recent block confirmed by supermajority of the cluster.
|
|
81
|
+
- 'confirmed': Query the most recent block that has been voted on by supermajority of the cluster.
|
|
82
|
+
- 'processed': Query the most recent block regardless of cluster voting.
|
|
77
83
|
|
|
78
84
|
- **encoding**: Defines the format of the returned account data. Possible values include:
|
|
79
85
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
86
|
+
- 'jsonParsed': Returns data in a JSON-parsed format.
|
|
87
|
+
- 'base64': Returns raw account data in Base64 encoding.
|
|
88
|
+
- 'base64+zstd': Returns compressed Base64 data.
|
|
83
89
|
|
|
84
90
|
- **epoch**: Specify the epoch when querying for certain information like epoch details.
|
|
85
91
|
|
|
@@ -97,15 +103,17 @@ The filters parameter allows you to specify conditions when querying accounts an
|
|
|
97
103
|
|
|
98
104
|
#### Token Accounts by Owner
|
|
99
105
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
106
|
+
```ruby
|
|
107
|
+
# Replace 'owner_pubkey' with the owner's public key
|
|
108
|
+
owner_pubkey = 'Fg6PaFpoGXkYsidMpWxTWqSKJf6KJkUxX92cnv7WMd2J'
|
|
109
|
+
|
|
110
|
+
# Query for token accounts owned by this public key
|
|
111
|
+
filters = [{ mint: 'TokenMintPublicKey' }]
|
|
112
|
+
|
|
113
|
+
result = client.get_token_accounts_by_owner(owner_pubkey, filters)
|
|
114
|
+
|
|
115
|
+
puts result
|
|
116
|
+
```
|
|
109
117
|
|
|
110
118
|
#### Account Filters
|
|
111
119
|
|
|
@@ -115,101 +123,110 @@ You can use the filters parameter to apply conditions for certain queries, such
|
|
|
115
123
|
|
|
116
124
|
- Filter accounts by a specific token mint.
|
|
117
125
|
|
|
118
|
-
|
|
126
|
+
```ruby
|
|
127
|
+
filters = [{ mint: 'TokenMintPublicKey' }]
|
|
119
128
|
|
|
120
|
-
|
|
129
|
+
result = client.get_token_accounts_by_owner(owner_pubkey, filters)
|
|
130
|
+
```
|
|
121
131
|
|
|
122
132
|
#### Program Filter
|
|
123
133
|
|
|
124
134
|
- Filter accounts associated with a particular program, such as the token program.
|
|
125
135
|
|
|
126
|
-
|
|
136
|
+
```ruby
|
|
137
|
+
filters = [{ programId: 'TokenProgramPublicKey' }]
|
|
127
138
|
|
|
128
|
-
|
|
139
|
+
result = client.get_token_accounts_by_owner(owner_pubkey, filters)
|
|
140
|
+
```
|
|
129
141
|
|
|
130
142
|
#### Data Size Filter
|
|
131
143
|
|
|
132
144
|
- Filter accounts by the exact size of the account data.
|
|
133
145
|
|
|
134
|
-
|
|
146
|
+
```ruby
|
|
147
|
+
filters = [{ dataSize: 165 }]
|
|
135
148
|
|
|
136
|
-
|
|
149
|
+
result = client.get_program_accounts('ProgramPublicKey', filters)
|
|
150
|
+
```
|
|
137
151
|
|
|
138
152
|
#### Memcmp Filter
|
|
139
153
|
|
|
140
154
|
- Filter by matching a specific slice of bytes at a given offset in account data.
|
|
141
155
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
156
|
+
```ruby
|
|
157
|
+
filters = [{
|
|
158
|
+
memcmp: {
|
|
159
|
+
offset: 0,
|
|
160
|
+
bytes: 'Base58EncodedBytes'
|
|
161
|
+
}
|
|
162
|
+
}]
|
|
163
|
+
|
|
164
|
+
result = client.get_program_accounts('ProgramPublicKey', filters)
|
|
165
|
+
```
|
|
150
166
|
|
|
151
167
|
## WebSocket Methods
|
|
152
168
|
|
|
153
169
|
The SolanaRuby gem also provides WebSocket methods to handle real-time notifications and updates from the Solana blockchain. To use the WebSocket client:
|
|
154
170
|
|
|
155
|
-
|
|
156
|
-
|
|
171
|
+
```ruby
|
|
172
|
+
# Initialize the WebSocket client
|
|
173
|
+
ws_client = SolanaRuby::WebSocketClient.new("wss://api.mainnet-beta.solana.com")
|
|
157
174
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
175
|
+
# Subscribe to slot change notifications
|
|
176
|
+
subscription_id = ws_client.on_slot_change do |slot_info|
|
|
177
|
+
puts "Slot changed: #{slot_info}"
|
|
178
|
+
end
|
|
162
179
|
|
|
163
|
-
|
|
164
|
-
|
|
180
|
+
# Sleep to hold the process and show updates
|
|
181
|
+
sleep 60 # Adjust the duration as needed to view updates
|
|
165
182
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
183
|
+
# Unsubscribe from slot change notifications
|
|
184
|
+
ws_client.remove_slot_change_listener(subscription_id)
|
|
185
|
+
puts "Unsubscribed from slot change notifications."
|
|
186
|
+
```
|
|
169
187
|
|
|
170
188
|
The following methods are supported by the WebSocketClient:
|
|
171
189
|
|
|
172
190
|
- **Account Change**: Subscribe to changes in an account's state.
|
|
173
191
|
|
|
174
|
-
|
|
192
|
+
`ws_client.on_account_change(pubkey) { |account_info| puts account_info }`
|
|
175
193
|
|
|
176
194
|
- **Program Account Change**: Subscribe to changes in accounts owned by a specific program.
|
|
177
195
|
|
|
178
|
-
|
|
196
|
+
`ws_client.on_program_account_change(program_id, filters) { |program_account_info| puts program_account_info }`
|
|
179
197
|
|
|
180
198
|
- **Logs**: Subscribe to transaction logs.
|
|
181
199
|
|
|
182
|
-
|
|
200
|
+
`ws_client.on_logs { |logs_info| puts logs_info }`
|
|
183
201
|
|
|
184
202
|
- **Logs for a Specific Account**: Subscribe to logs related to a specific account.
|
|
185
203
|
|
|
186
|
-
|
|
204
|
+
`ws_client.on_logs_for_account(account_pubkey) { |logs_info| puts logs_info }`
|
|
187
205
|
|
|
188
206
|
- **Logs for a Specific Program**: Subscribe to logs related to a specific program.
|
|
189
207
|
|
|
190
|
-
|
|
208
|
+
`ws_client.on_logs_for_program(program_id) { |logs_info| puts logs_info }`
|
|
191
209
|
|
|
192
210
|
- **Root Change**: Subscribe to root changes.
|
|
193
211
|
|
|
194
|
-
|
|
212
|
+
ws_client.on_root_change { |root_info| puts root_info }
|
|
195
213
|
|
|
196
214
|
- **Signature**: Subscribe to a signature notification.
|
|
197
215
|
|
|
198
|
-
|
|
216
|
+
`ws_client.on_signature(signature) { |signature_info| puts signature_info }`
|
|
199
217
|
|
|
200
218
|
- **Slot Change**: Subscribe to slot changes.
|
|
201
219
|
|
|
202
|
-
|
|
220
|
+
`ws_client.on_slot_change { |slot_info| puts slot_info }`
|
|
203
221
|
|
|
204
222
|
- **Unsubscribe Methods**: Each WebSocket method has a corresponding unsubscribe method:
|
|
205
223
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
224
|
+
- remove_account_change_listener(subscription_id)
|
|
225
|
+
- remove_program_account_listener(subscription_id)
|
|
226
|
+
- remove_logs_listener(subscription_id)
|
|
227
|
+
- remove_root_listener(subscription_id)
|
|
228
|
+
- remove_signature_listener(subscription_id)
|
|
229
|
+
- remove_slot_change_listener(subscription_id)
|
|
213
230
|
|
|
214
231
|
## Complete List of Available Methods
|
|
215
232
|
|
|
@@ -218,6 +235,7 @@ The following methods are supported by the WebSocketClient:
|
|
|
218
235
|
The following methods are supported by the SolanaRuby::HttpClient:
|
|
219
236
|
|
|
220
237
|
#### Basic
|
|
238
|
+
|
|
221
239
|
get_balance(pubkey)
|
|
222
240
|
get_balance_and_context(pubkey)
|
|
223
241
|
get_slot()
|
|
@@ -240,6 +258,7 @@ The following methods are supported by the SolanaRuby::HttpClient:
|
|
|
240
258
|
get_recent_prioritization_fees(addresses)
|
|
241
259
|
|
|
242
260
|
#### Account
|
|
261
|
+
|
|
243
262
|
get_account_info(pubkey)
|
|
244
263
|
get_parsed_account_info(pubkey, options)
|
|
245
264
|
get_account_info_and_context(pubkey, options)
|
|
@@ -255,6 +274,7 @@ The following methods are supported by the SolanaRuby::HttpClient:
|
|
|
255
274
|
get_nonce(pubkey)
|
|
256
275
|
|
|
257
276
|
#### Block
|
|
277
|
+
|
|
258
278
|
get_nonce(pubkey)
|
|
259
279
|
get_block(slot, options)
|
|
260
280
|
get_block_production()
|
|
@@ -270,20 +290,24 @@ The following methods are supported by the SolanaRuby::HttpClient:
|
|
|
270
290
|
get_block_commitment(block_slot)
|
|
271
291
|
|
|
272
292
|
#### Blockhash
|
|
293
|
+
|
|
273
294
|
get_latest_blockhash()
|
|
274
295
|
get_latest_blockhash()
|
|
275
296
|
get_fee_for_message(blockhash, options)
|
|
276
297
|
is_blockhash_valid?(blockhash, options)
|
|
277
298
|
|
|
278
299
|
#### Lookup Table
|
|
300
|
+
|
|
279
301
|
get_address_lookup_table(pubkey)
|
|
280
302
|
|
|
281
303
|
#### Signature
|
|
304
|
+
|
|
282
305
|
get_signature_statuses(signatures)
|
|
283
306
|
get_signature_status(signature, options)
|
|
284
307
|
get_signatures_for_address(address, options)
|
|
285
308
|
|
|
286
309
|
#### Slot
|
|
310
|
+
|
|
287
311
|
get_slot()
|
|
288
312
|
get_slot_leader(options)
|
|
289
313
|
get_slot_leaders(start_slot, limit)
|
|
@@ -293,12 +317,14 @@ The following methods are supported by the SolanaRuby::HttpClient:
|
|
|
293
317
|
get_max_shred_insert_slot()
|
|
294
318
|
|
|
295
319
|
#### Token
|
|
320
|
+
|
|
296
321
|
get_token_balance(pubkey, options)
|
|
297
322
|
get_token_supply(pubkey)
|
|
298
323
|
get_token_accounts_by_owner(owner_pubkey, filters, options)
|
|
299
324
|
get_token_largest_accounts(mint_pubkey, options)
|
|
300
325
|
|
|
301
326
|
#### Transaction
|
|
327
|
+
|
|
302
328
|
send_transaction(signed_transaction, options)
|
|
303
329
|
confirm_transaction(signature, commitment, timeout)
|
|
304
330
|
get_transaction(signature, options)
|
|
@@ -347,62 +373,64 @@ To transfer SOL (the native cryptocurrency of the Solana blockchain) from one ac
|
|
|
347
373
|
|
|
348
374
|
#### Example Usage:
|
|
349
375
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
376
|
+
```ruby
|
|
377
|
+
require 'solana_ruby'
|
|
378
|
+
|
|
379
|
+
# Initialize the client (defaults to Mainnet(https://api.mainnet-beta.solana.com))
|
|
380
|
+
client = SolanaRuby::HttpClient.new('https://api.devnet.solana.com')
|
|
381
|
+
|
|
382
|
+
# Fetch the recent blockhash
|
|
383
|
+
recent_blockhash = client.get_latest_blockhash["blockhash"]
|
|
384
|
+
|
|
385
|
+
# Generate or fetch the sender's keypair
|
|
386
|
+
# Option 1: Generate a new keypair
|
|
387
|
+
sender_keypair = SolanaRuby::Keypair.generate
|
|
388
|
+
# Option 2: Use an existing private key
|
|
389
|
+
# sender_keypair = SolanaRuby::Keypair.from_private_key("InsertPrivateKeyHere")
|
|
390
|
+
|
|
391
|
+
sender_pubkey = sender_keypair[:public_key]
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
# Airdrop some lamports to the sender's account when needed.
|
|
395
|
+
lamports = 10 * 1_000_000_000
|
|
396
|
+
sleep(1)
|
|
397
|
+
result = client.request_airdrop(sender_pubkey, lamports)
|
|
398
|
+
puts "Solana Balance #{lamports} lamports added sucessfully for the public key: #{sender_pubkey}"
|
|
399
|
+
sleep(10)
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
# Generate or use an existing receiver's public key
|
|
403
|
+
# Option 1: Generate a new keypair for the receiver
|
|
404
|
+
receiver_keypair = SolanaRuby::Keypair.generate
|
|
405
|
+
receiver_pubkey = receiver_keypair[:public_key]
|
|
406
|
+
# Option 2: Use an existing public key
|
|
407
|
+
# receiver_pubkey = 'InsertExistingPublicKeyHere'
|
|
408
|
+
|
|
409
|
+
transfer_lamports = 1 * 1_000_000
|
|
410
|
+
puts "Payer's full private key: #{sender_keypair[:full_private_key]}"
|
|
411
|
+
puts "Receiver's full private key: #{receiver_keypair[:full_private_key]}"
|
|
412
|
+
puts "Receiver's Public Key: #{receiver_keypair[:public_key]}"
|
|
413
|
+
|
|
414
|
+
# Create a new transaction
|
|
415
|
+
transaction = SolanaRuby::TransactionHelper.sol_transfer(
|
|
416
|
+
sender_pubkey,
|
|
417
|
+
receiver_pubkey,
|
|
418
|
+
transfer_lamports,
|
|
419
|
+
recent_blockhash
|
|
420
|
+
)
|
|
421
|
+
|
|
422
|
+
# Get the sender's private key (ensure it's a string)
|
|
423
|
+
private_key = sender_keypair[:private_key]
|
|
424
|
+
puts "Private key type: #{private_key.class}, Value: #{private_key.inspect}"
|
|
425
|
+
|
|
426
|
+
# Sign the transaction
|
|
427
|
+
signed_transaction = transaction.sign([sender_keypair])
|
|
428
|
+
|
|
429
|
+
# Send the transaction to the Solana network
|
|
430
|
+
sleep(5)
|
|
431
|
+
response = client.send_transaction(transaction.to_base64, { encoding: 'base64' })
|
|
432
|
+
puts "Response: #{response}"
|
|
433
|
+
```
|
|
406
434
|
|
|
407
435
|
### Account Creation
|
|
408
436
|
|
|
@@ -419,49 +447,51 @@ The create_account helper allows creating a new account with specified parameter
|
|
|
419
447
|
|
|
420
448
|
#### Example Usage:
|
|
421
449
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
450
|
+
```ruby
|
|
451
|
+
require 'solana_ruby'
|
|
452
|
+
|
|
453
|
+
# Initialize the client (defaults to Mainnet(https://api.mainnet-beta.solana.com))
|
|
454
|
+
client = SolanaRuby::HttpClient.new('https://api.devnet.solana.com')
|
|
455
|
+
|
|
456
|
+
# Fetch the recent blockhash
|
|
457
|
+
recent_blockhash = client.get_latest_blockhash["blockhash"]
|
|
458
|
+
|
|
459
|
+
# Generate or fetch the sender/payer keypair
|
|
460
|
+
# Option 1: Generate a new keypair
|
|
461
|
+
sender_keypair = SolanaRuby::Keypair.generate
|
|
462
|
+
# Option 2: Use an existing private key
|
|
463
|
+
# sender_keypair = SolanaRuby::Keypair.from_private_key("InsertPrivateKeyHere")
|
|
464
|
+
sender_pubkey = sender_keypair[:public_key]
|
|
465
|
+
|
|
466
|
+
# Generate new account keypair
|
|
467
|
+
new_account = SolanaRuby::Keypair.generate
|
|
468
|
+
new_account_pubkey = new_account[:public_key]
|
|
469
|
+
|
|
470
|
+
# Parameters for account creation
|
|
471
|
+
lamports = 1_000_000_000
|
|
472
|
+
space = 165
|
|
473
|
+
program_id = SolanaRuby::TransactionHelper::SYSTEM_PROGRAM_ID
|
|
474
|
+
|
|
475
|
+
# Create the account creation transaction
|
|
476
|
+
transaction = SolanaRuby::TransactionHelper.create_account(
|
|
477
|
+
sender_pubkey,
|
|
478
|
+
new_account_pubkey,
|
|
479
|
+
lamports,
|
|
480
|
+
space,
|
|
481
|
+
recent_blockhash,
|
|
482
|
+
program_id
|
|
483
|
+
)
|
|
484
|
+
|
|
485
|
+
# Sign with both keypairs
|
|
486
|
+
transaction.sign([sender_keypair, new_account])
|
|
487
|
+
|
|
488
|
+
# Send the transaction
|
|
489
|
+
response = client.send_transaction(transaction.to_base64, { encoding: 'base64' })
|
|
490
|
+
|
|
491
|
+
# Output transaction results
|
|
492
|
+
puts "Transaction Signature: #{response}"
|
|
493
|
+
puts "New account created with Public Key: #{new_account_pubkey}"
|
|
494
|
+
```
|
|
465
495
|
|
|
466
496
|
### SPL Token Account Creation
|
|
467
497
|
|
|
@@ -476,44 +506,46 @@ The create_associated_token_account helper allows you to create an associated to
|
|
|
476
506
|
|
|
477
507
|
#### Example Usage:
|
|
478
508
|
|
|
479
|
-
|
|
509
|
+
```ruby
|
|
510
|
+
require 'solana_ruby'
|
|
480
511
|
|
|
481
|
-
|
|
482
|
-
|
|
512
|
+
# Initialize the Solana client (defaults to Mainnet: https://api.mainnet-beta.solana.com)
|
|
513
|
+
client = SolanaRuby::HttpClient.new('https://api.devnet.solana.com')
|
|
483
514
|
|
|
484
|
-
|
|
485
|
-
|
|
515
|
+
# Fetch the recent blockhash
|
|
516
|
+
recent_blockhash = client.get_latest_blockhash["blockhash"]
|
|
486
517
|
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
518
|
+
# Load the keypair for the payer
|
|
519
|
+
payer_keypair = SolanaRuby::Keypair.load_keypair('InsertYourJsonFilePathHere')
|
|
520
|
+
payer_pubkey = payer_keypair.public_key
|
|
490
521
|
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
522
|
+
# Generate or load the owner keypair
|
|
523
|
+
owner_keypair = SolanaRuby::Keypair.generate
|
|
524
|
+
owner_pubkey = owner_keypair.public_key
|
|
494
525
|
|
|
495
|
-
|
|
496
|
-
|
|
526
|
+
puts "Owner Public Key: #{owner_pubkey}"
|
|
527
|
+
puts "Owner Private Key: #{owner_keypair.private_key}"
|
|
497
528
|
|
|
498
|
-
|
|
499
|
-
|
|
529
|
+
# Define the mint public key for the SPL token
|
|
530
|
+
mint_pubkey = "InsertMintPublicKeyHere"
|
|
500
531
|
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
532
|
+
# Create the associated token account transaction
|
|
533
|
+
transaction = SolanaRuby::TransactionHelper.create_associated_token_account(
|
|
534
|
+
payer_pubkey,
|
|
535
|
+
mint_pubkey,
|
|
536
|
+
owner_pubkey,
|
|
537
|
+
recent_blockhash
|
|
538
|
+
)
|
|
508
539
|
|
|
509
|
-
|
|
510
|
-
|
|
540
|
+
# Sign the transaction
|
|
541
|
+
transaction.sign([payer_keypair])
|
|
511
542
|
|
|
512
|
-
|
|
513
|
-
|
|
543
|
+
# Send the transaction
|
|
544
|
+
response = client.send_transaction(transaction.to_base64, { encoding: 'base64' })
|
|
514
545
|
|
|
515
|
-
|
|
516
|
-
|
|
546
|
+
# Output transaction results
|
|
547
|
+
puts "Transaction Signature: #{response}"
|
|
548
|
+
```
|
|
517
549
|
|
|
518
550
|
### Close Account
|
|
519
551
|
|
|
@@ -530,51 +562,53 @@ The close_account helper allows you to close an associated token account on the
|
|
|
530
562
|
|
|
531
563
|
#### Example Usage:
|
|
532
564
|
|
|
533
|
-
|
|
565
|
+
```ruby
|
|
566
|
+
require 'solana_ruby'
|
|
534
567
|
|
|
535
|
-
|
|
536
|
-
|
|
568
|
+
# Initialize the Solana client (defaults to Mainnet: https://api.mainnet-beta.solana.com)
|
|
569
|
+
client = SolanaRuby::HttpClient.new('https://api.devnet.solana.com')
|
|
537
570
|
|
|
538
|
-
|
|
539
|
-
|
|
571
|
+
# Fetch the recent blockhash
|
|
572
|
+
recent_blockhash = client.get_latest_blockhash["blockhash"]
|
|
540
573
|
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
574
|
+
# Load the keypairs
|
|
575
|
+
payer_keypair = SolanaRuby::Keypair.from_private_key("InsertPayerPrivateKeyHere")
|
|
576
|
+
owner_keypair = SolanaRuby::Keypair.from_private_key("InsertOwnerPrivateKeyHere")
|
|
544
577
|
|
|
545
|
-
|
|
546
|
-
|
|
578
|
+
payer_pubkey = payer_keypair[:public_key]
|
|
579
|
+
owner_pubkey = owner_keypair[:public_key]
|
|
547
580
|
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
581
|
+
# Define the associated token account to be closed and the destination account
|
|
582
|
+
account_to_close_pubkey = 'InsertAccountToClosePublicKeyHere' # Replace with the actual account to close
|
|
583
|
+
destination_pubkey = 'InsertDestinationPublicKeyHere' # Replace with the actual recipient address
|
|
551
584
|
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
585
|
+
# Multi-signers (if required)
|
|
586
|
+
# multi_signers = [SolanaRuby::Keypair.from_private_key("InsertAdditionalSignerPrivateKeyHere")]
|
|
587
|
+
multi_signers = []
|
|
555
588
|
|
|
556
|
-
|
|
557
|
-
|
|
589
|
+
# Extract public keys of multi-signers
|
|
590
|
+
multi_signer_pubkeys = multi_signers.map { |signer| signer[:public_key] }
|
|
558
591
|
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
592
|
+
# Create the close account transaction
|
|
593
|
+
transaction = SolanaRuby::TransactionHelper.close_account(
|
|
594
|
+
account_to_close_pubkey,
|
|
595
|
+
destination_pubkey,
|
|
596
|
+
owner_pubkey,
|
|
597
|
+
payer_pubkey,
|
|
598
|
+
multi_signer_pubkeys,
|
|
599
|
+
recent_blockhash
|
|
600
|
+
)
|
|
568
601
|
|
|
569
|
-
|
|
570
|
-
|
|
602
|
+
# Sign the transaction
|
|
603
|
+
transaction.sign([payer_keypair, owner_keypair])
|
|
571
604
|
|
|
572
|
-
|
|
573
|
-
|
|
605
|
+
# Send the transaction
|
|
606
|
+
response = client.send_transaction(transaction.to_base64, { encoding: 'base64' })
|
|
574
607
|
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
608
|
+
# Output transaction results
|
|
609
|
+
puts "Transaction Signature: #{response}"
|
|
610
|
+
puts "Closed account: #{account_to_close_pubkey}, funds sent to: #{destination_pubkey}"
|
|
611
|
+
```
|
|
578
612
|
|
|
579
613
|
### Get Associated Token Address
|
|
580
614
|
|
|
@@ -587,19 +621,21 @@ The get_associated_token_address helper fetches the associated token account for
|
|
|
587
621
|
|
|
588
622
|
#### Example Usage:
|
|
589
623
|
|
|
590
|
-
|
|
624
|
+
```ruby
|
|
625
|
+
require 'solana_ruby'
|
|
591
626
|
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
627
|
+
# Define mint address and owner public key
|
|
628
|
+
mint_address = 'InsertMintPublicKeyHere'
|
|
629
|
+
owner_pubkey = 'InsertOwnerPublicKeyHere'
|
|
595
630
|
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
631
|
+
# Fetch associated token address
|
|
632
|
+
associated_token_address = SolanaRuby::TransactionHelpers::TokenAccount.get_associated_token_address(
|
|
633
|
+
mint_address,
|
|
634
|
+
owner_pubkey
|
|
635
|
+
)
|
|
601
636
|
|
|
602
|
-
|
|
637
|
+
puts "Associated Token Address: #{associated_token_address}"
|
|
638
|
+
```
|
|
603
639
|
|
|
604
640
|
### Mint SPL Tokens
|
|
605
641
|
|
|
@@ -616,48 +652,50 @@ The mint_spl_tokens helper allows you to mint new SPL tokens to a specified dest
|
|
|
616
652
|
|
|
617
653
|
#### Example Usage:
|
|
618
654
|
|
|
619
|
-
|
|
655
|
+
```ruby
|
|
656
|
+
require 'solana_ruby'
|
|
620
657
|
|
|
621
|
-
|
|
622
|
-
|
|
658
|
+
# Initialize the Solana client (defaults to Mainnet: https://api.mainnet-beta.solana.com)
|
|
659
|
+
client = SolanaRuby::HttpClient.new('https://api.devnet.solana.com')
|
|
623
660
|
|
|
624
|
-
|
|
625
|
-
|
|
661
|
+
# Fetch the recent blockhash
|
|
662
|
+
recent_blockhash = client.get_latest_blockhash["blockhash"]
|
|
626
663
|
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
664
|
+
# Define the mint account and recipient
|
|
665
|
+
mint_account = "InsertMintPublicKeyHere"
|
|
666
|
+
destination_account = "InsertDestinationPublicKeyHere"
|
|
630
667
|
|
|
631
|
-
|
|
632
|
-
|
|
668
|
+
# Load the mint authority keypair
|
|
669
|
+
mint_authority = SolanaRuby::Keypair.load_keypair('InsertYourJsonFilePathHere')
|
|
633
670
|
|
|
634
|
-
|
|
671
|
+
puts "Mint Authority Public Key: #{mint_authority[:public_key]}"
|
|
635
672
|
|
|
636
|
-
|
|
637
|
-
|
|
673
|
+
# Define the amount to mint (in smallest units)
|
|
674
|
+
amount = 1_000_000_00_00 # Adjust based on token decimals
|
|
638
675
|
|
|
639
|
-
|
|
640
|
-
|
|
676
|
+
# Multi-signers (if required)
|
|
677
|
+
multi_signers = [] # Example: [additional_signer_pubkey]
|
|
641
678
|
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
679
|
+
# Create the mint transaction
|
|
680
|
+
transaction = SolanaRuby::TransactionHelper.mint_spl_tokens(
|
|
681
|
+
mint_account,
|
|
682
|
+
destination_account,
|
|
683
|
+
mint_authority[:public_key],
|
|
684
|
+
amount,
|
|
685
|
+
recent_blockhash,
|
|
686
|
+
multi_signers
|
|
687
|
+
)
|
|
651
688
|
|
|
652
|
-
|
|
653
|
-
|
|
689
|
+
# Sign the transaction with the mint authority
|
|
690
|
+
transaction.sign([mint_authority])
|
|
654
691
|
|
|
655
|
-
|
|
656
|
-
|
|
692
|
+
# Send the transaction
|
|
693
|
+
response = client.send_transaction(transaction.to_base64, { encoding: 'base64' })
|
|
657
694
|
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
695
|
+
# Output transaction results
|
|
696
|
+
puts "Transaction Signature: #{response}"
|
|
697
|
+
puts "Minted #{amount} tokens to: #{destination_account}"
|
|
698
|
+
```
|
|
661
699
|
|
|
662
700
|
### Burn SPL Tokens
|
|
663
701
|
|
|
@@ -673,42 +711,44 @@ The burn_spl_tokens helper allows you to burn (destroy) a specified amount of SP
|
|
|
673
711
|
|
|
674
712
|
#### Example Usage:
|
|
675
713
|
|
|
676
|
-
|
|
714
|
+
```ruby
|
|
715
|
+
require 'solana_ruby'
|
|
677
716
|
|
|
678
|
-
|
|
679
|
-
|
|
717
|
+
# Initialize the Solana client (defaults to Mainnet: https://api.mainnet-beta.solana.com)
|
|
718
|
+
client = SolanaRuby::HttpClient.new('https://api.devnet.solana.com')
|
|
680
719
|
|
|
681
|
-
|
|
682
|
-
|
|
720
|
+
# Fetch the recent blockhash
|
|
721
|
+
recent_blockhash = client.get_latest_blockhash["blockhash"]
|
|
683
722
|
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
723
|
+
# Define token account and mint address
|
|
724
|
+
token_account = "InsertTokenAccountPublicKeyHere"
|
|
725
|
+
mint_address = "InsertMintPublicKeyHere"
|
|
687
726
|
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
727
|
+
# Load the mint authority keypair
|
|
728
|
+
mint_authority = SolanaRuby::Keypair.load_keypair('/path/to/id.json')
|
|
729
|
+
owner = mint_authority[:public_key]
|
|
691
730
|
|
|
692
|
-
|
|
693
|
-
|
|
731
|
+
# Define the amount to burn
|
|
732
|
+
amount = 500_000 # Tokens to burn in smallest units
|
|
694
733
|
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
734
|
+
# Create burn transaction
|
|
735
|
+
transaction = SolanaRuby::TransactionHelper.burn_spl_tokens(
|
|
736
|
+
token_account,
|
|
737
|
+
mint_address,
|
|
738
|
+
owner,
|
|
739
|
+
amount,
|
|
740
|
+
recent_blockhash
|
|
741
|
+
)
|
|
703
742
|
|
|
704
|
-
|
|
705
|
-
|
|
743
|
+
# Sign the transaction
|
|
744
|
+
transaction.sign([mint_authority])
|
|
706
745
|
|
|
707
|
-
|
|
708
|
-
|
|
746
|
+
# Send the transaction
|
|
747
|
+
response = client.send_transaction(transaction.to_base64, { encoding: 'base64' })
|
|
709
748
|
|
|
710
|
-
|
|
711
|
-
|
|
749
|
+
# Output transaction results
|
|
750
|
+
puts "Transaction Signature: #{response}"
|
|
751
|
+
```
|
|
712
752
|
|
|
713
753
|
### Transfer SPL Tokens
|
|
714
754
|
|
|
@@ -727,64 +767,64 @@ The new_spl_token_transaction helper allows you to transfer SPL tokens from one
|
|
|
727
767
|
|
|
728
768
|
#### Example Usage:
|
|
729
769
|
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
770
|
+
```ruby
|
|
771
|
+
require 'solana_ruby'
|
|
772
|
+
|
|
773
|
+
# Initialize the Solana client
|
|
774
|
+
client = SolanaRuby::HttpClient.new('http://127.0.0.1:8899')
|
|
775
|
+
|
|
776
|
+
# Fetch the recent blockhash
|
|
777
|
+
recent_blockhash = client.get_latest_blockhash["blockhash"]
|
|
778
|
+
|
|
779
|
+
# Load the fee payer's keypair
|
|
780
|
+
fee_payer = SolanaRuby::Keypair.from_private_key('InsertFeePayerPrivateKeyHere')
|
|
781
|
+
fee_payer_pubkey = fee_payer[:public_key]
|
|
782
|
+
|
|
783
|
+
# Define the SPL token mint address
|
|
784
|
+
mint_address = 'InsertMintPublicKeyHere'
|
|
785
|
+
|
|
786
|
+
# Define sender and receiver public keys
|
|
787
|
+
sender_pubkey = 'InsertSenderPublicKeyHere'
|
|
788
|
+
receiver_pubkey = 'InsertReceiverPublicKeyHere'
|
|
789
|
+
|
|
790
|
+
# Fetch the associated token accounts
|
|
791
|
+
senders_token_account = SolanaRuby::TransactionHelpers::TokenAccount.get_associated_token_address(mint_address, sender_pubkey)
|
|
792
|
+
receivers_token_account = SolanaRuby::TransactionHelpers::TokenAccount.get_associated_token_address(mint_address, receiver_pubkey)
|
|
793
|
+
|
|
794
|
+
puts "Sender's Token Account: #{senders_token_account}"
|
|
795
|
+
puts "Receiver's Token Account: #{receivers_token_account}"
|
|
796
|
+
|
|
797
|
+
# Define the transfer amount and decimals
|
|
798
|
+
transfer_lamports = 1_000_000 # Amount in smallest units
|
|
799
|
+
decimals = 9 # Adjust based on token precision
|
|
800
|
+
|
|
801
|
+
# Multi-signers (Optional, default is an empty array)
|
|
802
|
+
# multi_signers = [
|
|
803
|
+
# SolanaRuby::Keypair.from_private_key('InsertMultiSigner1PrivateKeyHere'),
|
|
804
|
+
# SolanaRuby::Keypair.from_private_key('InsertMultiSigner2PrivateKeyHere')
|
|
805
|
+
# ]
|
|
806
|
+
# multi_signer_pubkeys = multi_signers.map { |signer| signer[:public_key] }
|
|
807
|
+
multi_signers = []
|
|
808
|
+
|
|
809
|
+
# Create the transaction
|
|
810
|
+
transaction = SolanaRuby::TransactionHelper.new_spl_token_transaction(
|
|
811
|
+
senders_token_account,
|
|
812
|
+
mint_address,
|
|
813
|
+
receivers_token_account,
|
|
814
|
+
fee_payer_pubkey,
|
|
815
|
+
transfer_lamports,
|
|
816
|
+
decimals,
|
|
817
|
+
recent_blockhash,
|
|
818
|
+
multi_signer_pubkeys
|
|
819
|
+
)
|
|
820
|
+
|
|
821
|
+
# Sign the transaction (Only fee payer, unless multi-signers are provided)
|
|
822
|
+
transaction.sign([fee_payer] + multi_signers)
|
|
823
|
+
|
|
824
|
+
# Send the transaction
|
|
825
|
+
puts "Sending transaction..."
|
|
826
|
+
response = client.send_transaction(transaction.to_base64, { encoding: 'base64' })
|
|
827
|
+
|
|
828
|
+
# Output transaction results
|
|
829
|
+
puts "Transaction Signature: #{response}"
|
|
830
|
+
```
|
|
@@ -10,12 +10,22 @@ module SolanaRuby
|
|
|
10
10
|
def self.on_curve?(public_key)
|
|
11
11
|
return false unless public_key.bytesize == 32 # Must be exactly 32 bytes
|
|
12
12
|
|
|
13
|
-
# Extract
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
# Extract bytes - needed for bitwise operations
|
|
14
|
+
y_bytes = public_key.bytes
|
|
15
|
+
# Ed25519 Curve does not use the x sign bit, y value is (0-254) so we need to clear the bit 255 (x sign bit)
|
|
16
|
+
# Byte 31, bit 7 is the sign bit
|
|
17
|
+
y_bytes[31] &= 0x7F # binary 01111111
|
|
18
|
+
|
|
19
|
+
# shift left bytes by 8 bits to get little-endian order then sum to get integer
|
|
20
|
+
# In little-endian: byte[0] is 2^0, byte[1] is 2^8, ..., byte[31] is 2^248
|
|
21
|
+
y = y_bytes.each_with_index.sum { |byte, index| byte << (8 * index) }
|
|
22
|
+
|
|
23
|
+
# Reduce modulo Q (field arithmetic) to ensure it's within the valid range
|
|
24
|
+
y = y % Q
|
|
16
25
|
# Compute x² from the Ed25519 curve equation: x² = (y² - 1) / (d * y² + 1) mod Q
|
|
17
|
-
|
|
18
|
-
|
|
26
|
+
y_squared = (y * y) % Q
|
|
27
|
+
numerator = (y_squared - 1) % Q
|
|
28
|
+
denominator = (D * y_squared + 1) % Q
|
|
19
29
|
|
|
20
30
|
# Compute the modular inverse of the denominator
|
|
21
31
|
denominator_inv = OpenSSL::BN.new(denominator).mod_inverse(Q).to_i rescue nil
|
|
@@ -65,7 +65,8 @@ module SolanaRuby
|
|
|
65
65
|
|
|
66
66
|
def self.hash_seeds(seeds, program_id)
|
|
67
67
|
# Combine seeds and program ID with the PDA derivation logic
|
|
68
|
-
|
|
68
|
+
# strict encoding to binary
|
|
69
|
+
buffer = seeds.join.b + program_id.b + "ProgramDerivedAddress".b
|
|
69
70
|
RbNaCl::Hash.sha256(buffer)
|
|
70
71
|
end
|
|
71
72
|
end
|
data/lib/solana_ruby/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: solana-ruby-web3js
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.1.
|
|
4
|
+
version: 2.1.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- BuildSquad
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-02-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: websocket-client-simple
|
|
@@ -307,7 +307,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
307
307
|
- !ruby/object:Gem::Version
|
|
308
308
|
version: '0'
|
|
309
309
|
requirements: []
|
|
310
|
-
rubygems_version: 3.5.
|
|
310
|
+
rubygems_version: 3.5.9
|
|
311
311
|
signing_key:
|
|
312
312
|
specification_version: 4
|
|
313
313
|
summary: Solana Ruby SDK
|