solace-squads-smart-accounts 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 +7 -0
- data/lib/solace/squads_smart_accounts/codecs_extensions.rb +259 -0
- data/lib/solace/squads_smart_accounts/composers/activate_proposal_composer.rb +69 -0
- data/lib/solace/squads_smart_accounts/composers/add_signer_as_authority_composer.rb +94 -0
- data/lib/solace/squads_smart_accounts/composers/add_spending_limit_as_authority_composer.rb +170 -0
- data/lib/solace/squads_smart_accounts/composers/approve_proposal_composer.rb +80 -0
- data/lib/solace/squads_smart_accounts/composers/cancel_proposal_composer.rb +86 -0
- data/lib/solace/squads_smart_accounts/composers/change_threshold_as_authority_composer.rb +94 -0
- data/lib/solace/squads_smart_accounts/composers/close_settings_transaction_composer.rb +98 -0
- data/lib/solace/squads_smart_accounts/composers/close_transaction_composer.rb +97 -0
- data/lib/solace/squads_smart_accounts/composers/create_proposal_composer.rb +104 -0
- data/lib/solace/squads_smart_accounts/composers/create_settings_transaction_composer.rb +105 -0
- data/lib/solace/squads_smart_accounts/composers/create_smart_account_composer.rb +142 -0
- data/lib/solace/squads_smart_accounts/composers/create_transaction_composer.rb +154 -0
- data/lib/solace/squads_smart_accounts/composers/execute_settings_transaction_composer.rb +112 -0
- data/lib/solace/squads_smart_accounts/composers/execute_settings_transaction_sync_composer.rb +114 -0
- data/lib/solace/squads_smart_accounts/composers/execute_transaction_composer.rb +122 -0
- data/lib/solace/squads_smart_accounts/composers/execute_transaction_sync_composer.rb +157 -0
- data/lib/solace/squads_smart_accounts/composers/reject_proposal_composer.rb +80 -0
- data/lib/solace/squads_smart_accounts/composers/remove_signer_as_authority_composer.rb +94 -0
- data/lib/solace/squads_smart_accounts/composers/remove_spending_limit_as_authority_composer.rb +88 -0
- data/lib/solace/squads_smart_accounts/composers/set_new_settings_authority_as_authority_composer.rb +100 -0
- data/lib/solace/squads_smart_accounts/composers/set_time_lock_as_authority_composer.rb +94 -0
- data/lib/solace/squads_smart_accounts/composers/use_spending_limit_composer.rb +203 -0
- data/lib/solace/squads_smart_accounts/constants.rb +27 -0
- data/lib/solace/squads_smart_accounts/idl/squads_smart_account_program.json +3966 -0
- data/lib/solace/squads_smart_accounts/instructions/activate_proposal_instruction.rb +60 -0
- data/lib/solace/squads_smart_accounts/instructions/add_signer_as_authority_instruction.rb +69 -0
- data/lib/solace/squads_smart_accounts/instructions/add_spending_limit_as_authority_instruction.rb +112 -0
- data/lib/solace/squads_smart_accounts/instructions/approve_proposal_instruction.rb +66 -0
- data/lib/solace/squads_smart_accounts/instructions/cancel_proposal_instruction.rb +67 -0
- data/lib/solace/squads_smart_accounts/instructions/change_threshold_as_authority_instruction.rb +66 -0
- data/lib/solace/squads_smart_accounts/instructions/close_settings_transaction_instruction.rb +71 -0
- data/lib/solace/squads_smart_accounts/instructions/close_transaction_instruction.rb +72 -0
- data/lib/solace/squads_smart_accounts/instructions/create_proposal_instruction.rb +78 -0
- data/lib/solace/squads_smart_accounts/instructions/create_settings_transaction_instruction.rb +78 -0
- data/lib/solace/squads_smart_accounts/instructions/create_smart_account_instruction.rb +96 -0
- data/lib/solace/squads_smart_accounts/instructions/create_transaction_instruction.rb +95 -0
- data/lib/solace/squads_smart_accounts/instructions/execute_settings_transaction_instruction.rb +79 -0
- data/lib/solace/squads_smart_accounts/instructions/execute_settings_transaction_sync_instruction.rb +78 -0
- data/lib/solace/squads_smart_accounts/instructions/execute_transaction_instruction.rb +71 -0
- data/lib/solace/squads_smart_accounts/instructions/execute_transaction_sync_instruction.rb +80 -0
- data/lib/solace/squads_smart_accounts/instructions/reject_proposal_instruction.rb +66 -0
- data/lib/solace/squads_smart_accounts/instructions/remove_signer_as_authority_instruction.rb +66 -0
- data/lib/solace/squads_smart_accounts/instructions/remove_spending_limit_as_authority_instruction.rb +62 -0
- data/lib/solace/squads_smart_accounts/instructions/set_new_settings_authority_as_authority_instruction.rb +66 -0
- data/lib/solace/squads_smart_accounts/instructions/set_time_lock_as_authority_instruction.rb +66 -0
- data/lib/solace/squads_smart_accounts/instructions/use_spending_limit_instruction.rb +96 -0
- data/lib/solace/squads_smart_accounts/programs/squads_smart_account.rb +1841 -0
- data/lib/solace/squads_smart_accounts/types/period.rb +24 -0
- data/lib/solace/squads_smart_accounts/types/permissions.rb +43 -0
- data/lib/solace/squads_smart_accounts/types/program_config.rb +36 -0
- data/lib/solace/squads_smart_accounts/types/proposal.rb +91 -0
- data/lib/solace/squads_smart_accounts/types/settings.rb +50 -0
- data/lib/solace/squads_smart_accounts/types/settings_action.rb +109 -0
- data/lib/solace/squads_smart_accounts/types/settings_transaction.rb +40 -0
- data/lib/solace/squads_smart_accounts/types/smart_account_identity.rb +20 -0
- data/lib/solace/squads_smart_accounts/types/smart_account_signer.rb +26 -0
- data/lib/solace/squads_smart_accounts/types/spending_limit.rb +52 -0
- data/lib/solace/squads_smart_accounts/types/transaction.rb +115 -0
- data/lib/solace/squads_smart_accounts/types/transaction_message.rb +41 -0
- data/lib/solace/squads_smart_accounts/vault_index.rb +113 -0
- data/lib/solace/squads_smart_accounts/version.rb +7 -0
- data/lib/solace/squads_smart_accounts.rb +29 -0
- metadata +210 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 02a25a8f810ed514e72c62cf865dd3ea92a4edb614260fc5fbc110f913d79b6e
|
|
4
|
+
data.tar.gz: 898e4feceedc71e37de62c3dcd02ef19cc79fbed1d6a982a6b3c294ddc58e11a
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 15b4b488be4b53df4c2d61729c58fdae258478d24b59bd5b35f361b6087b9bcb2fdc4b204f3d796bcd21b833e0f76d476df7bdacd2f084b7fd3643ce5f0e421f
|
|
7
|
+
data.tar.gz: 746d685aba1a248a94f947910350396ce64b1dbf84ba9b86d50d29ab84a7ea597f65286003a0becf963630af77167e2fd5f37a1b530154503553cc5189708c21
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solace
|
|
4
|
+
module Utils
|
|
5
|
+
# Extensions to Solace::Utils::Codecs for Anchor programs and Borsh types not
|
|
6
|
+
# covered by the base gem. Candidates for upstreaming to solace when the need
|
|
7
|
+
# is confirmed across other extension gems.
|
|
8
|
+
module Codecs
|
|
9
|
+
extend self
|
|
10
|
+
|
|
11
|
+
# Encodes a SmallVec<u8, u8>: u8 length prefix + raw bytes.
|
|
12
|
+
#
|
|
13
|
+
# @param bytes [Array<Integer>] The raw bytes (max 255).
|
|
14
|
+
# @return [Array<Integer>]
|
|
15
|
+
def encode_smallvec_u8_bytes(bytes)
|
|
16
|
+
[bytes.length] + bytes
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Encodes a u16 as 2 little-endian bytes.
|
|
20
|
+
#
|
|
21
|
+
# @param u16 [Integer] Value in range 0..65535.
|
|
22
|
+
# @return [String] 2-byte little-endian binary string.
|
|
23
|
+
def encode_le_u16(u16)
|
|
24
|
+
[u16].pack('S<')
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Encodes a SmallVec<u16, u8>: u16 LE length prefix + raw bytes.
|
|
28
|
+
#
|
|
29
|
+
# @param bytes [Array<Integer>] The raw bytes (max 65535).
|
|
30
|
+
# @return [Array<Integer>]
|
|
31
|
+
def encode_smallvec_u16_bytes(bytes)
|
|
32
|
+
encode_le_u16(bytes.length).bytes + bytes
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Encodes a u32 as 4 little-endian bytes.
|
|
36
|
+
#
|
|
37
|
+
# @param u32 [Integer] Value in range 0..4294967295.
|
|
38
|
+
# @return [String] 4-byte little-endian binary string.
|
|
39
|
+
def encode_le_u32(u32)
|
|
40
|
+
[u32].pack('L<')
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Encodes an i64 as 8 little-endian bytes (two's complement).
|
|
44
|
+
#
|
|
45
|
+
# @param i64 [Integer] Value in range -2**63..2**63-1.
|
|
46
|
+
# @return [String] 8-byte little-endian binary string.
|
|
47
|
+
def encode_le_i64(i64)
|
|
48
|
+
[i64].pack('q<')
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Encodes a Borsh bool as a single byte: false → 0, true → 1.
|
|
52
|
+
#
|
|
53
|
+
# @param bool [Boolean] The value to encode.
|
|
54
|
+
# @return [Array<Integer>] A single-element byte array.
|
|
55
|
+
def encode_bool(bool)
|
|
56
|
+
[bool ? 1 : 0]
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Encodes a u128 as 16 little-endian bytes (two u64 words, low word first).
|
|
60
|
+
#
|
|
61
|
+
# @param u128 [Integer] Value in range 0..2**128-1.
|
|
62
|
+
# @return [String] 16-byte little-endian binary string.
|
|
63
|
+
def encode_le_u128(u128)
|
|
64
|
+
[u128 & 0xFFFFFFFFFFFFFFFF, u128 >> 64].pack('Q<Q<')
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Encodes a Borsh bytes field: u32 LE length prefix + raw bytes.
|
|
68
|
+
#
|
|
69
|
+
# @param bytes [Array<Integer>] The raw bytes.
|
|
70
|
+
# @return [Array<Integer>]
|
|
71
|
+
def encode_bytes(bytes)
|
|
72
|
+
encode_le_u32(bytes.length).bytes + bytes
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Encodes an Option<String> in Borsh format.
|
|
76
|
+
# None → [0], Some(str) → [1] + u32 length + UTF-8 bytes.
|
|
77
|
+
#
|
|
78
|
+
# @param str [String, nil]
|
|
79
|
+
# @return [Array<Integer>]
|
|
80
|
+
def encode_option_string(str)
|
|
81
|
+
return [0] if str.nil?
|
|
82
|
+
|
|
83
|
+
bytes = str.encode('UTF-8').bytes
|
|
84
|
+
[1] + encode_le_u32(bytes.length).bytes + bytes
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Encodes a public key as 32 bytes. Accepts any representation that
|
|
88
|
+
# resolves to a base58 string via #to_s (String, Keypair, PublicKey).
|
|
89
|
+
#
|
|
90
|
+
# @param pubkey [#to_s] The public key in any representation.
|
|
91
|
+
# @return [Array<Integer>] 32 bytes.
|
|
92
|
+
def encode_pubkey(pubkey)
|
|
93
|
+
Solace::Utils::Codecs.base58_to_bytes(pubkey.to_s)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Encodes an Option<publicKey> in Borsh format.
|
|
97
|
+
# None → [0], Some(key) → [1] + 32 bytes.
|
|
98
|
+
#
|
|
99
|
+
# @param pubkey [String, nil] Base58 public key or nil.
|
|
100
|
+
# @return [Array<Integer>]
|
|
101
|
+
def encode_option_pubkey(pubkey)
|
|
102
|
+
return [0] if pubkey.nil?
|
|
103
|
+
|
|
104
|
+
[1] + encode_pubkey(pubkey)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Encodes a Vec<publicKey> in Borsh format.
|
|
108
|
+
# u32 LE count prefix followed by each 32-byte pubkey.
|
|
109
|
+
#
|
|
110
|
+
# @param pubkeys [Array<#to_s>] The public keys in any representation.
|
|
111
|
+
# @return [Array<Integer>]
|
|
112
|
+
def encode_vec_pubkeys(pubkeys)
|
|
113
|
+
encode_le_u32(pubkeys.length).bytes +
|
|
114
|
+
pubkeys.flat_map { |pubkey| encode_pubkey(pubkey) }
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Encodes a SmallVec<u8, Pubkey>: u8 count prefix followed by each 32-byte
|
|
118
|
+
# pubkey. Used by the transaction message header's account_keys (distinct
|
|
119
|
+
# from encode_vec_pubkeys, which uses a u32 count).
|
|
120
|
+
#
|
|
121
|
+
# @param pubkeys [Array<#to_s>] The public keys in any representation (max 255).
|
|
122
|
+
# @return [Array<Integer>]
|
|
123
|
+
def encode_smallvec_u8_pubkeys(pubkeys)
|
|
124
|
+
[pubkeys.length] + pubkeys.flat_map { |pubkey| encode_pubkey(pubkey) }
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Encodes a Vec<SmartAccountSigner> in Borsh format.
|
|
128
|
+
# u32 length prefix followed by each signer's 32-byte pubkey + 1-byte permission mask.
|
|
129
|
+
#
|
|
130
|
+
# @param signers [Array<SquadsSmartAccounts::SmartAccountSigner>]
|
|
131
|
+
# @return [Array<Integer>]
|
|
132
|
+
def encode_smart_account_signers(signers)
|
|
133
|
+
encode_le_u32(signers.length).bytes +
|
|
134
|
+
signers.flat_map do |signer|
|
|
135
|
+
encode_pubkey(signer.pubkey) + [signer.permission]
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Encodes a Vec<SettingsAction> in Borsh format.
|
|
140
|
+
# u32 LE count prefix followed by each action's variant index + field bytes.
|
|
141
|
+
#
|
|
142
|
+
# @param actions [Array<SquadsSmartAccounts::SettingsAction>]
|
|
143
|
+
# @return [Array<Integer>]
|
|
144
|
+
def encode_settings_actions(actions)
|
|
145
|
+
encode_le_u32(actions.length).bytes + actions.flat_map(&:serialize)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
# Encodes a SmallVec<u8, CompiledInstruction> — the wire format the Squads
|
|
149
|
+
# program expects for synchronously executed inner instructions.
|
|
150
|
+
#
|
|
151
|
+
# NOTE: this intentionally does NOT reuse Solace's InstructionSerializer.
|
|
152
|
+
# That serializer produces the Solana transaction wire format, which uses
|
|
153
|
+
# compact-u16 (varint) length prefixes for the vec count, account indexes,
|
|
154
|
+
# and data. The Squads SmallVec format uses fixed-width prefixes instead:
|
|
155
|
+
# u8 for the vec count, u8 for the account indexes length, and u16 LE for
|
|
156
|
+
# the data length. The two encodings coincide for lengths < 128 (compact-u16
|
|
157
|
+
# encodes those as a single byte) but diverge beyond that, so reusing the
|
|
158
|
+
# Solana format would corrupt larger instructions silently.
|
|
159
|
+
#
|
|
160
|
+
# Each instruction is a {Solace::Instruction} whose program_index and
|
|
161
|
+
# accounts are indexes into the full remaining-accounts list (signers included).
|
|
162
|
+
# Layout per instruction: u8 program_id_index + SmallVec<u8,u8> account
|
|
163
|
+
# indexes + SmallVec<u16,u8> data.
|
|
164
|
+
#
|
|
165
|
+
# @param instructions [Array<Solace::Instruction>]
|
|
166
|
+
# @return [Array<Integer>]
|
|
167
|
+
def encode_compiled_instructions(instructions)
|
|
168
|
+
[instructions.length] +
|
|
169
|
+
instructions.flat_map do |ix|
|
|
170
|
+
[ix.program_index] +
|
|
171
|
+
encode_smallvec_u8_bytes(ix.accounts) +
|
|
172
|
+
encode_smallvec_u16_bytes(ix.data)
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# Decodes an i64 from 8 little-endian bytes (two's complement).
|
|
177
|
+
#
|
|
178
|
+
# @param stream [IO, StringIO] The stream to read from.
|
|
179
|
+
# @return [Integer] Value in range -2**63..2**63-1.
|
|
180
|
+
def decode_le_i64(stream)
|
|
181
|
+
stream.read(8).unpack1('q<')
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
# Decodes a Vec<publicKey> in Borsh format.
|
|
185
|
+
#
|
|
186
|
+
# @param stream [IO, StringIO] The stream to read from.
|
|
187
|
+
# @return [Array<String>] Base58 public keys.
|
|
188
|
+
def decode_vec_pubkeys(stream)
|
|
189
|
+
Array.new(decode_le_u32(stream)) { decode_pubkey(stream) }
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
# Decodes a u8 from 1 byte.
|
|
193
|
+
#
|
|
194
|
+
# @param stream [IO, StringIO] The stream to read from.
|
|
195
|
+
# @return [Integer] Value in range 0..255.
|
|
196
|
+
def decode_u8(stream)
|
|
197
|
+
stream.read(1).unpack1('C')
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
# Decodes a u16 from 2 little-endian bytes.
|
|
201
|
+
#
|
|
202
|
+
# @param stream [IO, StringIO] The stream to read from.
|
|
203
|
+
# @return [Integer] Value in range 0..65535.
|
|
204
|
+
def decode_le_u16(stream)
|
|
205
|
+
stream.read(2).unpack1('S<')
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
# Decodes a u32 from 4 little-endian bytes.
|
|
209
|
+
#
|
|
210
|
+
# @param stream [IO, StringIO] The stream to read from.
|
|
211
|
+
# @return [Integer] Value in range 0..4294967295.
|
|
212
|
+
def decode_le_u32(stream)
|
|
213
|
+
stream.read(4).unpack1('L<')
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
# Decodes a u128 from 16 little-endian bytes (two u64 words, low word first).
|
|
217
|
+
#
|
|
218
|
+
# @param stream [IO, StringIO] The stream to read from.
|
|
219
|
+
# @return [Integer] Value in range 0..2**128-1.
|
|
220
|
+
def decode_le_u128(stream)
|
|
221
|
+
lo, hi = stream.read(16).unpack('Q<Q<')
|
|
222
|
+
lo + (hi << 64)
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
# Decodes a public key from 32 bytes.
|
|
226
|
+
#
|
|
227
|
+
# @param stream [IO, StringIO] The stream to read from.
|
|
228
|
+
# @return [String] Base58 public key.
|
|
229
|
+
def decode_pubkey(stream)
|
|
230
|
+
Solace::Utils::Codecs.bytes_to_base58(stream.read(32).bytes)
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
# Decodes an Option<publicKey> in Borsh format.
|
|
234
|
+
# None → nil, Some(key) → base58 pubkey.
|
|
235
|
+
#
|
|
236
|
+
# @param stream [IO, StringIO] The stream to read from.
|
|
237
|
+
# @return [String, nil] Base58 public key or nil.
|
|
238
|
+
def decode_option_pubkey(stream)
|
|
239
|
+
return nil if decode_u8(stream).zero?
|
|
240
|
+
|
|
241
|
+
decode_pubkey(stream)
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
# Decodes a Vec<SmartAccountSigner> in Borsh format.
|
|
245
|
+
# u32 length prefix followed by each signer's 32-byte pubkey + 1-byte permission mask.
|
|
246
|
+
#
|
|
247
|
+
# @param stream [IO, StringIO] The stream to read from.
|
|
248
|
+
# @return [Array<SquadsSmartAccounts::SmartAccountSigner>]
|
|
249
|
+
def decode_smart_account_signers(stream)
|
|
250
|
+
Array.new(decode_le_u32(stream)) do
|
|
251
|
+
SquadsSmartAccounts::SmartAccountSigner.new(
|
|
252
|
+
pubkey: decode_pubkey(stream),
|
|
253
|
+
permission: decode_u8(stream)
|
|
254
|
+
)
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solace
|
|
4
|
+
module Composers
|
|
5
|
+
# Composes an `activateProposal` instruction for the Squads Smart Account program.
|
|
6
|
+
#
|
|
7
|
+
# Moves a Draft proposal to Active. The signer must be a smart-account member
|
|
8
|
+
# with the Initiate permission. Only needed for proposals created as drafts.
|
|
9
|
+
#
|
|
10
|
+
# Required params:
|
|
11
|
+
# :settings [#to_s] Base58 address of the settings account.
|
|
12
|
+
# :signer [#to_s, Keypair] The activating signer (must sign).
|
|
13
|
+
# :proposal [#to_s] The Proposal PDA to activate.
|
|
14
|
+
class SquadsSmartAccountsActivateProposalComposer < Base
|
|
15
|
+
# Extracts the settings address from the params
|
|
16
|
+
#
|
|
17
|
+
# @return [String] The settings address
|
|
18
|
+
def settings
|
|
19
|
+
params[:settings].to_s
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Extracts the activating signer address from the params
|
|
23
|
+
#
|
|
24
|
+
# @return [String] The signer address
|
|
25
|
+
def signer
|
|
26
|
+
params[:signer].to_s
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Extracts the proposal PDA address from the params
|
|
30
|
+
#
|
|
31
|
+
# @return [String] The proposal address
|
|
32
|
+
def proposal
|
|
33
|
+
params[:proposal].to_s
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Returns the Squads Smart Account program id from the constants
|
|
37
|
+
#
|
|
38
|
+
# @return [String] The Squads Smart Account program id
|
|
39
|
+
def program_id
|
|
40
|
+
SquadsSmartAccounts::PROGRAM_ID
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Declares all accounts required by this instruction. The Squads program
|
|
44
|
+
# is registered so it appears in the message account keys (it is the
|
|
45
|
+
# invoked program), but — unlike the other proposal instructions — it is
|
|
46
|
+
# NOT included in this instruction's account-metas list (no trailing
|
|
47
|
+
# program account).
|
|
48
|
+
def setup_accounts
|
|
49
|
+
account_context.add_readonly_nonsigner(settings)
|
|
50
|
+
account_context.add_writable_signer(signer)
|
|
51
|
+
account_context.add_writable_nonsigner(proposal)
|
|
52
|
+
account_context.add_readonly_nonsigner(program_id)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Builds the instruction with resolved account indices.
|
|
56
|
+
#
|
|
57
|
+
# @param context [Solace::Utils::AccountContext] Merged context from TransactionComposer.
|
|
58
|
+
# @return [Solace::Instruction]
|
|
59
|
+
def build_instruction(context)
|
|
60
|
+
SquadsSmartAccounts::Instructions::ActivateProposalInstruction.build(
|
|
61
|
+
settings_index: context.index_of(settings),
|
|
62
|
+
signer_index: context.index_of(signer),
|
|
63
|
+
proposal_index: context.index_of(proposal),
|
|
64
|
+
program_index: context.index_of(program_id)
|
|
65
|
+
)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solace
|
|
4
|
+
module Composers
|
|
5
|
+
# Composes an `addSignerAsAuthority` instruction for the Squads Smart Account program.
|
|
6
|
+
#
|
|
7
|
+
# Adds a new signer to a controlled smart account. Only the account's
|
|
8
|
+
# settings authority may do this — single signature, no consensus.
|
|
9
|
+
#
|
|
10
|
+
# Required params:
|
|
11
|
+
# :settings [String] Base58 address of the settings account.
|
|
12
|
+
# :settings_authority [#to_s, Keypair] The account's settings authority (must sign).
|
|
13
|
+
# :rent_payer [#to_s, Keypair] Pays for settings account reallocation (must sign).
|
|
14
|
+
# :new_signer [SquadsSmartAccounts::SmartAccountSigner] The signer to add.
|
|
15
|
+
#
|
|
16
|
+
# Optional params:
|
|
17
|
+
# :memo [String] Indexing memo (default: nil).
|
|
18
|
+
class SquadsSmartAccountsAddSignerAsAuthorityComposer < Base
|
|
19
|
+
# Extracts the settings address from the params
|
|
20
|
+
#
|
|
21
|
+
# @return [String] The settings address
|
|
22
|
+
def settings
|
|
23
|
+
params[:settings].to_s
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Extracts the settings authority address from the params
|
|
27
|
+
#
|
|
28
|
+
# @return [String] The settings authority address
|
|
29
|
+
def settings_authority
|
|
30
|
+
params[:settings_authority].to_s
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Extracts the rent payer address from the params
|
|
34
|
+
#
|
|
35
|
+
# @return [String] The rent payer address
|
|
36
|
+
def rent_payer
|
|
37
|
+
params[:rent_payer].to_s
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Extracts the new signer from the params
|
|
41
|
+
#
|
|
42
|
+
# @return [SquadsSmartAccounts::SmartAccountSigner] The signer to add
|
|
43
|
+
def new_signer
|
|
44
|
+
params[:new_signer]
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Extracts the memo from the params
|
|
48
|
+
#
|
|
49
|
+
# @return [String, nil] The memo
|
|
50
|
+
def memo
|
|
51
|
+
params[:memo]
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Returns the Squads Smart Account program id from the constants
|
|
55
|
+
#
|
|
56
|
+
# @return [String] The Squads Smart Account program id
|
|
57
|
+
def program_id
|
|
58
|
+
SquadsSmartAccounts::PROGRAM_ID
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Returns the system program id from the constants
|
|
62
|
+
#
|
|
63
|
+
# @return [String] The system program id
|
|
64
|
+
def system_program
|
|
65
|
+
Solace::Constants::SYSTEM_PROGRAM_ID
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Declares all accounts required by this instruction.
|
|
69
|
+
def setup_accounts
|
|
70
|
+
account_context.add_writable_nonsigner(settings)
|
|
71
|
+
account_context.add_readonly_signer(settings_authority)
|
|
72
|
+
account_context.add_writable_signer(rent_payer)
|
|
73
|
+
account_context.add_readonly_nonsigner(system_program)
|
|
74
|
+
account_context.add_readonly_nonsigner(program_id)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Builds the instruction with resolved account indices.
|
|
78
|
+
#
|
|
79
|
+
# @param context [Solace::Utils::AccountContext] Merged context from TransactionComposer.
|
|
80
|
+
# @return [Solace::Instruction]
|
|
81
|
+
def build_instruction(context)
|
|
82
|
+
SquadsSmartAccounts::Instructions::AddSignerAsAuthorityInstruction.build(
|
|
83
|
+
new_signer:,
|
|
84
|
+
memo:,
|
|
85
|
+
settings_index: context.index_of(settings),
|
|
86
|
+
settings_authority_index: context.index_of(settings_authority),
|
|
87
|
+
rent_payer_index: context.index_of(rent_payer),
|
|
88
|
+
system_program_index: context.index_of(system_program),
|
|
89
|
+
program_index: context.index_of(program_id)
|
|
90
|
+
)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solace
|
|
4
|
+
module Composers
|
|
5
|
+
# Composes an `addSpendingLimitAsAuthority` instruction for the Squads
|
|
6
|
+
# Smart Account program.
|
|
7
|
+
#
|
|
8
|
+
# Creates a SpendingLimit PDA granting designated signers a pre-authorized
|
|
9
|
+
# allowance from a vault. Only the account's settings authority may do
|
|
10
|
+
# this — single signature, no consensus.
|
|
11
|
+
#
|
|
12
|
+
# Required params:
|
|
13
|
+
# :settings [#to_s] Base58 address of the settings account.
|
|
14
|
+
# :settings_authority [#to_s, Keypair] The account's settings authority (must sign).
|
|
15
|
+
# :spending_limit [#to_s] The SpendingLimit PDA to create — derive via
|
|
16
|
+
# Programs::SquadsSmartAccount.get_spending_limit_address.
|
|
17
|
+
# :rent_payer [#to_s, Keypair] Funds the new account's rent (must sign).
|
|
18
|
+
# :seed [#to_s] The pubkey the spending_limit PDA was derived with.
|
|
19
|
+
# :amount [Integer] Amount spendable per period (mint decimals).
|
|
20
|
+
# :period [Integer] Period enum value (reset cadence).
|
|
21
|
+
# :signers [Array<#to_s>] Pubkeys allowed to use the limit.
|
|
22
|
+
#
|
|
23
|
+
# Optional params:
|
|
24
|
+
# :account_index [Integer] Vault index the limit spends from (default: 0).
|
|
25
|
+
# :mint [#to_s] Token mint (default: DEFAULT_PUBKEY = SOL).
|
|
26
|
+
# :destinations [Array<#to_s>] Allowed destinations; empty = any (default: []).
|
|
27
|
+
# :expiration [Integer] Unix expiration timestamp (default: I64_MAX = never).
|
|
28
|
+
# :memo [String] Indexing memo (default: nil).
|
|
29
|
+
class SquadsSmartAccountsAddSpendingLimitAsAuthorityComposer < Base
|
|
30
|
+
# Extracts the settings address from the params
|
|
31
|
+
#
|
|
32
|
+
# @return [String] The settings address
|
|
33
|
+
def settings
|
|
34
|
+
params[:settings].to_s
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Extracts the settings authority address from the params
|
|
38
|
+
#
|
|
39
|
+
# @return [String] The settings authority address
|
|
40
|
+
def settings_authority
|
|
41
|
+
params[:settings_authority].to_s
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Extracts the spending limit PDA address from the params
|
|
45
|
+
#
|
|
46
|
+
# @return [String] The spending limit address
|
|
47
|
+
def spending_limit
|
|
48
|
+
params[:spending_limit].to_s
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Extracts the rent payer address from the params
|
|
52
|
+
#
|
|
53
|
+
# @return [String] The rent payer address
|
|
54
|
+
def rent_payer
|
|
55
|
+
params[:rent_payer].to_s
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Extracts the PDA seed pubkey from the params
|
|
59
|
+
#
|
|
60
|
+
# @return [String] The seed pubkey
|
|
61
|
+
def seed
|
|
62
|
+
params[:seed].to_s
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Extracts the vault index from the params
|
|
66
|
+
#
|
|
67
|
+
# @return [Integer] The vault index (defaults to 0)
|
|
68
|
+
def account_index
|
|
69
|
+
params[:account_index] || 0
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Extracts the mint from the params
|
|
73
|
+
#
|
|
74
|
+
# @return [String] The mint address (defaults to DEFAULT_PUBKEY = SOL)
|
|
75
|
+
def mint
|
|
76
|
+
(params[:mint] || SquadsSmartAccounts::DEFAULT_PUBKEY).to_s
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Extracts the per-period amount from the params
|
|
80
|
+
#
|
|
81
|
+
# @return [Integer] The amount spendable per period
|
|
82
|
+
def amount
|
|
83
|
+
params[:amount]
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Extracts the reset period from the params
|
|
87
|
+
#
|
|
88
|
+
# @return [Integer] The Period enum value
|
|
89
|
+
def period
|
|
90
|
+
params[:period]
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Extracts the allowed signer pubkeys from the params
|
|
94
|
+
#
|
|
95
|
+
# @return [Array<String>] The allowed signer addresses
|
|
96
|
+
def signers
|
|
97
|
+
params[:signers].map(&:to_s)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Extracts the allowed destinations from the params
|
|
101
|
+
#
|
|
102
|
+
# @return [Array<String>] The allowed destination addresses (defaults to [])
|
|
103
|
+
def destinations
|
|
104
|
+
(params[:destinations] || []).map(&:to_s)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Extracts the expiration from the params
|
|
108
|
+
#
|
|
109
|
+
# @return [Integer] Unix expiration timestamp (defaults to I64_MAX = never)
|
|
110
|
+
def expiration
|
|
111
|
+
params[:expiration] || SquadsSmartAccounts::I64_MAX
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Extracts the memo from the params
|
|
115
|
+
#
|
|
116
|
+
# @return [String, nil] The memo
|
|
117
|
+
def memo
|
|
118
|
+
params[:memo]
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Returns the Squads Smart Account program id from the constants
|
|
122
|
+
#
|
|
123
|
+
# @return [String] The Squads Smart Account program id
|
|
124
|
+
def program_id
|
|
125
|
+
SquadsSmartAccounts::PROGRAM_ID
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Returns the system program id from the constants
|
|
129
|
+
#
|
|
130
|
+
# @return [String] The system program id
|
|
131
|
+
def system_program
|
|
132
|
+
Solace::Constants::SYSTEM_PROGRAM_ID
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# Declares all accounts required by this instruction.
|
|
136
|
+
def setup_accounts
|
|
137
|
+
account_context.add_readonly_nonsigner(settings)
|
|
138
|
+
account_context.add_readonly_signer(settings_authority)
|
|
139
|
+
account_context.add_writable_nonsigner(spending_limit)
|
|
140
|
+
account_context.add_writable_signer(rent_payer)
|
|
141
|
+
account_context.add_readonly_nonsigner(system_program)
|
|
142
|
+
account_context.add_readonly_nonsigner(program_id)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Builds the instruction with resolved account indices.
|
|
146
|
+
#
|
|
147
|
+
# @param context [Solace::Utils::AccountContext] Merged context from TransactionComposer.
|
|
148
|
+
# @return [Solace::Instruction]
|
|
149
|
+
def build_instruction(context)
|
|
150
|
+
SquadsSmartAccounts::Instructions::AddSpendingLimitAsAuthorityInstruction.build(
|
|
151
|
+
seed:,
|
|
152
|
+
account_index:,
|
|
153
|
+
mint:,
|
|
154
|
+
amount:,
|
|
155
|
+
period:,
|
|
156
|
+
signers:,
|
|
157
|
+
destinations:,
|
|
158
|
+
expiration:,
|
|
159
|
+
memo:,
|
|
160
|
+
settings_index: context.index_of(settings),
|
|
161
|
+
settings_authority_index: context.index_of(settings_authority),
|
|
162
|
+
spending_limit_index: context.index_of(spending_limit),
|
|
163
|
+
rent_payer_index: context.index_of(rent_payer),
|
|
164
|
+
system_program_index: context.index_of(system_program),
|
|
165
|
+
program_index: context.index_of(program_id)
|
|
166
|
+
)
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solace
|
|
4
|
+
module Composers
|
|
5
|
+
# Composes an `approveProposal` instruction for the Squads Smart Account program.
|
|
6
|
+
#
|
|
7
|
+
# Casts an approval vote on an active proposal. The signer must be a smart
|
|
8
|
+
# account member with the Vote permission.
|
|
9
|
+
#
|
|
10
|
+
# Required params:
|
|
11
|
+
# :settings [#to_s] Base58 address of the settings account.
|
|
12
|
+
# :signer [#to_s, Keypair] The voting signer (must sign).
|
|
13
|
+
# :proposal [#to_s] The Proposal PDA to vote on.
|
|
14
|
+
#
|
|
15
|
+
# Optional params:
|
|
16
|
+
# :memo [String] Indexing memo (default: nil).
|
|
17
|
+
class SquadsSmartAccountsApproveProposalComposer < Base
|
|
18
|
+
# Extracts the settings address from the params
|
|
19
|
+
#
|
|
20
|
+
# @return [String] The settings address
|
|
21
|
+
def settings
|
|
22
|
+
params[:settings].to_s
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Extracts the voting signer address from the params
|
|
26
|
+
#
|
|
27
|
+
# @return [String] The signer address
|
|
28
|
+
def signer
|
|
29
|
+
params[:signer].to_s
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Extracts the proposal PDA address from the params
|
|
33
|
+
#
|
|
34
|
+
# @return [String] The proposal address
|
|
35
|
+
def proposal
|
|
36
|
+
params[:proposal].to_s
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Extracts the memo from the params
|
|
40
|
+
#
|
|
41
|
+
# @return [String, nil] The memo
|
|
42
|
+
def memo
|
|
43
|
+
params[:memo]
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Returns the Squads Smart Account program id from the constants. The
|
|
47
|
+
# systemProgram account is optional and absent for a vote, so this id
|
|
48
|
+
# also fills that slot.
|
|
49
|
+
#
|
|
50
|
+
# @return [String] The Squads Smart Account program id
|
|
51
|
+
def program_id
|
|
52
|
+
SquadsSmartAccounts::PROGRAM_ID
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Declares all accounts required by this instruction.
|
|
56
|
+
def setup_accounts
|
|
57
|
+
account_context.add_readonly_nonsigner(settings)
|
|
58
|
+
account_context.add_writable_signer(signer)
|
|
59
|
+
account_context.add_writable_nonsigner(proposal)
|
|
60
|
+
account_context.add_readonly_nonsigner(program_id)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Builds the instruction with resolved account indices. The absent
|
|
64
|
+
# systemProgram slot resolves to the Squads program id index.
|
|
65
|
+
#
|
|
66
|
+
# @param context [Solace::Utils::AccountContext] Merged context from TransactionComposer.
|
|
67
|
+
# @return [Solace::Instruction]
|
|
68
|
+
def build_instruction(context)
|
|
69
|
+
SquadsSmartAccounts::Instructions::ApproveProposalInstruction.build(
|
|
70
|
+
memo:,
|
|
71
|
+
settings_index: context.index_of(settings),
|
|
72
|
+
signer_index: context.index_of(signer),
|
|
73
|
+
proposal_index: context.index_of(proposal),
|
|
74
|
+
system_program_index: context.index_of(program_id),
|
|
75
|
+
program_index: context.index_of(program_id)
|
|
76
|
+
)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|