solana-ruby-kit 0.1.5 → 0.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/lib/solana/ruby/kit/programs/stake_program.rb +162 -0
- data/lib/solana/ruby/kit/programs.rb +1 -0
- data/lib/solana/ruby/kit/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dddb792ac729b3981104e68f18131191f6775d864e785d25cd47ad5d169e94cc
|
|
4
|
+
data.tar.gz: 4fd955c2fb214186034906194a530ad62461ee7d3169b7e0718233de4331d4a8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9341acdd7f36e55078fa7a21989ec8e29aa00a351e52e3caa05a2f2b14ccee3fbe443f6b35d9914ccb4e53192e215e12659c4c7f83090bc2c027c9ff4fa52f87
|
|
7
|
+
data.tar.gz: 0dc330cd1fc6f3177d283eb6b251e0ad187c92f482c328aae1c72a9881bf338206ff2a9fadf7ab3c0a9f4744ce798244bac7368cb8517beee3cb89252abcea75
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require_relative '../addresses/address'
|
|
5
|
+
require_relative '../encoding/base58'
|
|
6
|
+
require_relative '../instructions/instruction'
|
|
7
|
+
require_relative '../instructions/accounts'
|
|
8
|
+
require_relative '../sysvars/addresses'
|
|
9
|
+
require_relative 'system_program'
|
|
10
|
+
|
|
11
|
+
module Solana::Ruby::Kit
|
|
12
|
+
module Programs
|
|
13
|
+
# Ruby interface for the Solana Stake Program.
|
|
14
|
+
#
|
|
15
|
+
# The Stake Program manages stake accounts used for delegating SOL to
|
|
16
|
+
# validators and earning staking rewards. Instruction data uses
|
|
17
|
+
# little-endian encoding: a u32 discriminator followed by any
|
|
18
|
+
# instruction-specific fields.
|
|
19
|
+
#
|
|
20
|
+
# Reference: https://github.com/solana-labs/solana-web3.js/blob/master/packages/library-legacy/src/programs/stake.ts
|
|
21
|
+
module StakeProgram
|
|
22
|
+
extend T::Sig
|
|
23
|
+
|
|
24
|
+
# The Stake Program address.
|
|
25
|
+
PROGRAM_ID = T.let(
|
|
26
|
+
Addresses::Address.new('Stake11111111111111111111111111111111111111111'),
|
|
27
|
+
Addresses::Address
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
# The Stake Config sysvar / config account.
|
|
31
|
+
STAKE_CONFIG_ID = T.let(
|
|
32
|
+
Addresses::Address.new('StakeConfig11111111111111111111111111111111'),
|
|
33
|
+
Addresses::Address
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
# Number of bytes required to store a stake account on-chain.
|
|
37
|
+
STAKE_ACCOUNT_SPACE = T.let(200, Integer)
|
|
38
|
+
|
|
39
|
+
# Instruction discriminators (u32 little-endian).
|
|
40
|
+
DISCRIMINATOR_INITIALIZE = T.let(0, Integer)
|
|
41
|
+
DISCRIMINATOR_DELEGATE = T.let(2, Integer)
|
|
42
|
+
|
|
43
|
+
module_function
|
|
44
|
+
|
|
45
|
+
# Builds the two instructions needed to create and initialise a new stake
|
|
46
|
+
# account funded from +from+.
|
|
47
|
+
#
|
|
48
|
+
# Instruction 0 — System Program createAccount
|
|
49
|
+
# Data layout (52 bytes):
|
|
50
|
+
# [0..3] u32 LE = 0 (CREATE_ACCOUNT discriminant)
|
|
51
|
+
# [4..11] u64 LE = lamports
|
|
52
|
+
# [12..19] u64 LE = 200 (STAKE_ACCOUNT_SPACE)
|
|
53
|
+
# [20..51] 32 bytes (Stake Program ID — the owner to assign)
|
|
54
|
+
# Pack string: 'VQ<Q<a32'
|
|
55
|
+
#
|
|
56
|
+
# Instruction 1 — Stake Program Initialize
|
|
57
|
+
# Data layout (116 bytes):
|
|
58
|
+
# [0..3] u32 LE = 0 (Initialize discriminant)
|
|
59
|
+
# [4..35] 32 bytes (authorized staker pubkey)
|
|
60
|
+
# [36..67] 32 bytes (authorized withdrawer pubkey)
|
|
61
|
+
# [68..75] i64 LE = 0 (lockup unix_timestamp — no lockup)
|
|
62
|
+
# [76..83] u64 LE = 0 (lockup epoch — no lockup)
|
|
63
|
+
# [84..115] 32 bytes = \x00*32 (lockup custodian — zero pubkey)
|
|
64
|
+
# Pack string: 'Va32a32q<Q<a32'
|
|
65
|
+
#
|
|
66
|
+
# @param from [Addresses::Address] funding account (writable, signer)
|
|
67
|
+
# @param stake_account [Addresses::Address] new stake account (writable, signer)
|
|
68
|
+
# @param authorized [Addresses::Address] pubkey set as both staker and withdrawer
|
|
69
|
+
# @param lamports [Integer] total lamports to fund the stake account
|
|
70
|
+
# @return [T::Array[Instructions::Instruction]]
|
|
71
|
+
sig do
|
|
72
|
+
params(
|
|
73
|
+
from: Addresses::Address,
|
|
74
|
+
stake_account: Addresses::Address,
|
|
75
|
+
authorized: Addresses::Address,
|
|
76
|
+
lamports: Integer
|
|
77
|
+
).returns(T::Array[Instructions::Instruction])
|
|
78
|
+
end
|
|
79
|
+
def create_account_instructions(from:, stake_account:, authorized:, lamports:)
|
|
80
|
+
stake_program_bytes = Encoding::Base58.decode(PROGRAM_ID.value)
|
|
81
|
+
authorized_bytes = Encoding::Base58.decode(authorized.value)
|
|
82
|
+
zero_pubkey = ("\x00" * 32).b
|
|
83
|
+
|
|
84
|
+
# Instruction 0: System Program createAccount (discriminant = 0)
|
|
85
|
+
create_data = [0, lamports, STAKE_ACCOUNT_SPACE, stake_program_bytes].pack('VQ<Q<a32').b
|
|
86
|
+
|
|
87
|
+
create_account_ix = Instructions::Instruction.new(
|
|
88
|
+
program_address: SystemProgram::PROGRAM_ID,
|
|
89
|
+
accounts: [
|
|
90
|
+
Instructions.writable_signer_account(from), # 0 from
|
|
91
|
+
Instructions.writable_signer_account(stake_account), # 1 stake_account
|
|
92
|
+
],
|
|
93
|
+
data: create_data
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
# Instruction 1: Stake Program Initialize
|
|
97
|
+
initialize_data = [
|
|
98
|
+
DISCRIMINATOR_INITIALIZE,
|
|
99
|
+
authorized_bytes, # staker
|
|
100
|
+
authorized_bytes, # withdrawer
|
|
101
|
+
0, # lockup.unix_timestamp (i64)
|
|
102
|
+
0, # lockup.epoch (u64)
|
|
103
|
+
zero_pubkey # lockup.custodian
|
|
104
|
+
].pack('Va32a32q<Q<a32').b
|
|
105
|
+
|
|
106
|
+
initialize_ix = Instructions::Instruction.new(
|
|
107
|
+
program_address: PROGRAM_ID,
|
|
108
|
+
accounts: [
|
|
109
|
+
Instructions.writable_account(stake_account), # 0 stake_account
|
|
110
|
+
Instructions.readonly_account(Addresses::Address.new(Sysvars::SYSVAR_RENT_ADDRESS)), # 1 sysvar rent
|
|
111
|
+
],
|
|
112
|
+
data: initialize_data
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
[create_account_ix, initialize_ix]
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# Builds a DelegateStake instruction that delegates an initialised stake
|
|
119
|
+
# account to a validator vote account.
|
|
120
|
+
#
|
|
121
|
+
# Data layout (4 bytes):
|
|
122
|
+
# [0..3] u32 LE = 2 (DelegateStake discriminant)
|
|
123
|
+
# Pack string: 'V'
|
|
124
|
+
#
|
|
125
|
+
# Accounts:
|
|
126
|
+
# 0. stake_account — writable, not signer
|
|
127
|
+
# 1. vote_account — readonly, not signer
|
|
128
|
+
# 2. SYSVAR_CLOCK — readonly, not signer
|
|
129
|
+
# 3. SYSVAR_STAKE_HISTORY — readonly, not signer
|
|
130
|
+
# 4. STAKE_CONFIG_ID — readonly, not signer
|
|
131
|
+
# 5. authorized — readonly, signer
|
|
132
|
+
#
|
|
133
|
+
# @param stake_account [Addresses::Address] stake account to delegate
|
|
134
|
+
# @param vote_account [Addresses::Address] validator's vote account
|
|
135
|
+
# @param authorized [Addresses::Address] authorised staker (must sign)
|
|
136
|
+
# @return [Instructions::Instruction]
|
|
137
|
+
sig do
|
|
138
|
+
params(
|
|
139
|
+
stake_account: Addresses::Address,
|
|
140
|
+
vote_account: Addresses::Address,
|
|
141
|
+
authorized: Addresses::Address
|
|
142
|
+
).returns(Instructions::Instruction)
|
|
143
|
+
end
|
|
144
|
+
def delegate_instruction(stake_account:, vote_account:, authorized:)
|
|
145
|
+
data = [DISCRIMINATOR_DELEGATE].pack('V').b
|
|
146
|
+
|
|
147
|
+
Instructions::Instruction.new(
|
|
148
|
+
program_address: PROGRAM_ID,
|
|
149
|
+
accounts: [
|
|
150
|
+
Instructions.writable_account(stake_account), # 0 stake_account
|
|
151
|
+
Instructions.readonly_account(vote_account), # 1 vote_account
|
|
152
|
+
Instructions.readonly_account(Addresses::Address.new(Sysvars::SYSVAR_CLOCK_ADDRESS)), # 2 clock
|
|
153
|
+
Instructions.readonly_account(Addresses::Address.new(Sysvars::SYSVAR_STAKE_HISTORY_ADDRESS)), # 3 stake history
|
|
154
|
+
Instructions.readonly_account(STAKE_CONFIG_ID), # 4 stake config
|
|
155
|
+
Instructions.readonly_signer_account(authorized), # 5 authorized staker
|
|
156
|
+
],
|
|
157
|
+
data: data
|
|
158
|
+
)
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
# returned in Solana transaction failures.
|
|
6
6
|
require_relative 'programs/associated_token_account'
|
|
7
7
|
require_relative 'programs/system_program'
|
|
8
|
+
require_relative 'programs/stake_program'
|
|
8
9
|
#
|
|
9
10
|
# A program error in a transaction result looks like:
|
|
10
11
|
# { "InstructionError" => [0, { "Custom" => 1234 }] }
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: solana-ruby-kit
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Paul Zupan, Idhra Inc.
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: openssl
|
|
@@ -231,6 +231,7 @@ files:
|
|
|
231
231
|
- lib/solana/ruby/kit/plugin_core.rb
|
|
232
232
|
- lib/solana/ruby/kit/programs.rb
|
|
233
233
|
- lib/solana/ruby/kit/programs/associated_token_account.rb
|
|
234
|
+
- lib/solana/ruby/kit/programs/stake_program.rb
|
|
234
235
|
- lib/solana/ruby/kit/programs/system_program.rb
|
|
235
236
|
- lib/solana/ruby/kit/promises.rb
|
|
236
237
|
- lib/solana/ruby/kit/railtie.rb
|
|
@@ -313,7 +314,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
313
314
|
- !ruby/object:Gem::Version
|
|
314
315
|
version: '0'
|
|
315
316
|
requirements: []
|
|
316
|
-
rubygems_version:
|
|
317
|
+
rubygems_version: 4.0.10
|
|
317
318
|
specification_version: 4
|
|
318
319
|
summary: Ruby port of the Anza TypeScript SDK (@anza-xyz/kit)
|
|
319
320
|
test_files: []
|