• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

bmresearch / Solnet / 15457586163

05 Jun 2025 03:15AM UTC coverage: 70.35% (-0.4%) from 70.792%
15457586163

Pull #498

github

web-flow
Merge 6feec6863 into 632c6bef2
Pull Request #498: Account compression program

1137 of 1834 branches covered (62.0%)

Branch coverage included in aggregate %.

148 of 239 new or added lines in 4 files covered. (61.92%)

5267 of 7269 relevant lines covered (72.46%)

1161944.55 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

65.87
/src/Solnet.Programs/AccountCompression/AccountCompressionProgram.cs
1
using Solnet.Programs.Abstract;
2
using Solnet.Programs.AccountCompression;
3
using Solnet.Programs.Utilities;
4
using Solnet.Rpc.Models;
5
using Solnet.Wallet;
6
using System;
7
using System.Collections.Generic;
8
using static Solnet.Programs.Models.Stake.State;
9

10

11
namespace Solnet.Programs
12
{
13
    /// <summary>
14
    /// Implements the Stake Program methods.
15
    /// <remarks>
16
    /// For more information see:
17
    /// https://docs.rs/spl-account-compression/latest/spl_account_compression/instruction/index.html
18
    /// https://github.com/solana-program/account-compression/blob/ac-mainnet-tag/account-compression/sdk/src/instructions/index.ts
19
    /// </remarks>
20
    /// </summary>
21
    public static class AccountCompressionProgram
22
    {
23
        /// <summary>
24
        /// The public key of the Stake Program.
25
        /// </summary>
26
        public static PublicKey ProgramIdKey = new ("compr6CUsB5m2jS4Y3831ztGSTnDpnKJTKS95d64XVq");
1✔
27

28
        /// <summary>
29
        /// The public key of the account compression program.
30
        /// </summary>
31
        public static readonly PublicKey ConfigKey = new("ComprConfig11111111111111111111111111111111");
1✔
32
        /// <summary>
33
        /// The program's name.
34
        /// </summary>
35
        private const string ProgramName = "Account Compression Program";
36

37

38

39
        /// <summary>
40
        /// Creates an instruction to append a leaf to a Merkle tree.
41
        /// </summary>
42
        /// <param name="merkleTree"></param>
43
        /// <param name="authority"></param>
44
        /// <param name="leaf"></param>
45
        /// <returns></returns>
46
        public static TransactionInstruction Append(
47
            PublicKey merkleTree,
48
            PublicKey authority,
49
            byte[] leaf)
50
        {
51
            List<AccountMeta> keys = new()
1✔
52
            {
1✔
53
                AccountMeta.Writable(authority, true),      // Authority (signer)                
1✔
54
                AccountMeta.Writable(merkleTree, false),  // Merkle tree account (writable)
1✔
55
            };
1✔
56

57
           
58
            return new TransactionInstruction
1✔
59
            {
1✔
60
                ProgramId = ProgramIdKey.KeyBytes,
1✔
61
                Keys = keys,
1✔
62
                Data = AccountCompressionProgramData.EncodeAppendData(leaf)
1✔
63
            };
1✔
64
        }
65
        /// <summary>
66
        /// /// Creates an instruction to close an empty Merkle tree and transfer its lamports to a recipient.
67
        /// </summary>
68
        /// <param name="merkleTree"></param>
69
        /// <param name="authority"></param>
70
        /// <param name="recipient"></param>
71
        /// <returns></returns>
72
        public static TransactionInstruction CloseEmptyTree(
73
            PublicKey merkleTree,
74
            PublicKey authority,
75
            PublicKey recipient
76
        )
77
        {
78
            List<AccountMeta> keys = new()
1✔
79
            {
1✔
80
                AccountMeta.Writable(merkleTree, false),  // Merkle tree account (writable)
1✔
81
                AccountMeta.Writable(authority, true),      // Authority (signer)          
1✔
82
                AccountMeta.ReadOnly(recipient, false)  // recipient
1✔
83
            };
1✔
84

85

86
            return new TransactionInstruction
1✔
87
            {
1✔
88
                ProgramId = ProgramIdKey.KeyBytes,
1✔
89
                Keys = keys,
1✔
90
                Data = AccountCompressionProgramData.EncodeCloseEmptyTreeData()
1✔
91
            };
1✔
92
        }
93
        /// <summary>
94
        /// /// Creates an instruction to initialize an empty Merkle tree.
95
        /// </summary>
96
        /// <param name="merkleTree"></param>
97
        /// <param name="authority"></param>
98
        /// <param name="maxDepth"></param>
99
        /// <param name="maxBufferSize"></param>
100
        /// <returns></returns>
101
        public static TransactionInstruction InitEmptyMerkleTree(
102
            PublicKey merkleTree,
103
            PublicKey authority,
104
            byte maxDepth, byte maxBufferSize
105
        )
106
        {
107
            List<AccountMeta> keys = new()
1✔
108
            {
1✔
109
                AccountMeta.Writable(merkleTree, false),  // Merkle tree account (writable)
1✔
110
                AccountMeta.Writable(authority, true),      // Authority (signer)  
1✔
111
            };
1✔
112

113

114
            return new TransactionInstruction
1✔
115
            {
1✔
116
                ProgramId = ProgramIdKey.KeyBytes,
1✔
117
                Keys = keys,
1✔
118
                Data = AccountCompressionProgramData.EncodeInitEmptyMerkleTreeData(maxDepth, maxBufferSize)
1✔
119
            };
1✔
120
        }
121
        /// <summary>
122
        /// /// Creates an instruction to replace a leaf in a Merkle tree.
123
        /// </summary>
124
        /// <param name="merkleTree"></param>
125
        /// <param name="authority"></param>
126
        /// <param name="newLeaf"></param>
127
        /// <param name="previousLeaf"></param>
128
        /// <param name="root"></param>
129
        /// <param name="index"></param>
130
        /// <returns></returns>
131
        public static TransactionInstruction ReplaceLeaf(
132
            PublicKey merkleTree,
133
            PublicKey authority,
134
            byte[] newLeaf,
135
            byte[] previousLeaf,
136
            byte[] root,
137
            uint index
138
       )
139
        {
140
            List<AccountMeta> keys = new()
1✔
141
            {
1✔
142
                AccountMeta.Writable(merkleTree, false),  // Merkle tree account (writable)
1✔
143
                AccountMeta.Writable(authority, true),      // Authority (signer)  
1✔
144
            };
1✔
145

146

147
            return new TransactionInstruction
1✔
148
            {
1✔
149
                ProgramId = ProgramIdKey.KeyBytes,
1✔
150
                Keys = keys,
1✔
151
                Data = AccountCompressionProgramData.EncodeReplaceLeafData(newLeaf, previousLeaf, root, index)
1✔
152
            };
1✔
153
        }
154
        /// <summary>
155
        /// /// Creates an instruction to insert or append a leaf to a Merkle tree.
156
        /// </summary>
157
        /// <param name="merkleTree"></param>
158
        /// <param name="authority"></param>
159
        /// <param name="Leaf"></param>
160
        /// <param name="root"></param>
161
        /// <param name="index"></param>
162
        /// <returns></returns>
163
        public static TransactionInstruction InsertOrAppend(
164
            PublicKey merkleTree,
165
            PublicKey authority,
166
            byte[] Leaf,
167
            byte[] root,
168
            uint index
169
       )
170
        {
171
            List<AccountMeta> keys = new()
1✔
172
            {
1✔
173
                AccountMeta.Writable(merkleTree, false),  // Merkle tree account (writable)
1✔
174
                AccountMeta.Writable(authority, true),      // Authority (signer)  
1✔
175
            };
1✔
176

177

178
            return new TransactionInstruction
1✔
179
            {
1✔
180
                ProgramId = ProgramIdKey.KeyBytes,
1✔
181
                Keys = keys,
1✔
182
                Data = AccountCompressionProgramData.EncodeInsertOrAppendData(Leaf, root, index)
1✔
183
            };
1✔
184
        }
185
        /// <summary>
186
        /// Creates an instruction to transfer authority of a Merkle tree.
187
        /// </summary>
188
        /// <param name="merkleTree"></param>
189
        /// <param name="authority"></param>
190
        /// <param name="newAuthority"></param>
191
        /// <returns></returns>
192
        public static TransactionInstruction TransferAuthority(
193
            PublicKey merkleTree,
194
            PublicKey authority,
195
            PublicKey newAuthority
196
       )
197
        {
198
            List<AccountMeta> keys = new()
1✔
199
            {
1✔
200
                AccountMeta.Writable(merkleTree, false),  // Merkle tree account (writable)
1✔
201
                AccountMeta.Writable(authority, true),      // Authority (signer)  
1✔
202
                AccountMeta.ReadOnly(newAuthority, false),      //new Authority  
1✔
203

1✔
204
            };
1✔
205

206

207
            return new TransactionInstruction
1✔
208
            {
1✔
209
                ProgramId = ProgramIdKey.KeyBytes,
1✔
210
                Keys = keys,
1✔
211
                Data = AccountCompressionProgramData.EncodeTransferAuthorityData(newAuthority)
1✔
212
            };
1✔
213
        }
214
        /// <summary>
215
        /// Creates an instruction to verify a leaf in a Merkle tree.
216
        /// </summary>
217
        /// <param name="merkleTree"></param>
218
        /// <param name="authority"></param>
219
        /// <param name="root"></param>
220
        /// <param name="leaf"></param>
221
        /// <param name="index"></param>
222
        /// <returns></returns>
223
        public static TransactionInstruction VerifyLeaf(
224
            PublicKey merkleTree,
225
            PublicKey authority,
226
            byte[] root, byte[] leaf, uint index
227
       )
228
        {
229
            List<AccountMeta> keys = new()
1✔
230
            {
1✔
231
                AccountMeta.Writable(merkleTree, false),  // Merkle tree account (writable)
1✔
232
                AccountMeta.Writable(authority, true),      // Authority (signer) 
1✔
233

1✔
234
            };
1✔
235

236

237
            return new TransactionInstruction
1✔
238
            {
1✔
239
                ProgramId = ProgramIdKey.KeyBytes,
1✔
240
                Keys = keys,
1✔
241
                Data = AccountCompressionProgramData.EncodeVerifyLeafData(root, leaf, index)
1✔
242
            };
1✔
243
        }
244
        /// <summary>
245
        /// Decodes the instruction data for the <see cref="AccountCompressionProgram"/>.
246
        /// </summary>
247
        /// <param name="data"></param>
248
        /// <param name="keys"></param>
249
        /// <param name="keyIndices"></param>
250
        /// <returns></returns>
251
        public static DecodedInstruction Decode(ReadOnlySpan<byte> data, IList<PublicKey> keys, byte[] keyIndices)
252
        {
NEW
253
            uint instruction = data.GetU32(AccountCompressionProgramData.MethodOffset);
×
254

NEW
255
            if (!Enum.IsDefined(typeof(NameServiceInstructions.Values), instruction))
×
256
            {
NEW
257
                return new()
×
NEW
258
                {
×
NEW
259
                    PublicKey = ProgramIdKey,
×
NEW
260
                    InstructionName = "Unknown Instruction",
×
NEW
261
                    ProgramName = ProgramName,
×
NEW
262
                    Values = new Dictionary<string, object>(),
×
NEW
263
                    InnerInstructions = new List<DecodedInstruction>()
×
NEW
264
                };
×
265
            }
266
            
NEW
267
            AccountCompressionProgramInstructions.Values instructionValue = (AccountCompressionProgramInstructions.Values)instruction;
×
268

NEW
269
            DecodedInstruction decodedInstruction = new()
×
NEW
270
            {
×
NEW
271
                PublicKey = ProgramIdKey,
×
NEW
272
                InstructionName = AccountCompressionProgramInstructions.Names[instructionValue],
×
NEW
273
                ProgramName = ProgramName,
×
NEW
274
                Values = new Dictionary<string, object>() { },
×
NEW
275
                InnerInstructions = new List<DecodedInstruction>()
×
NEW
276
            };
×
277

278
            switch (instructionValue)
279
            {
280
                case AccountCompressionProgramInstructions.Values.Append:
NEW
281
                    AccountCompressionProgramData.DecodeAppendLeafData(decodedInstruction, data, keys, keyIndices);
×
NEW
282
                    break;
×
283
                case AccountCompressionProgramInstructions.Values.InsertOrAppend:
NEW
284
                    AccountCompressionProgramData.DecodeInsertOrAppendData(decodedInstruction, data, keys, keyIndices);
×
NEW
285
                    break;
×
286
                case AccountCompressionProgramInstructions.Values.VerifyLeaf:
NEW
287
                    AccountCompressionProgramData.DecodeVerifyLeafData(decodedInstruction, data, keys, keyIndices);
×
NEW
288
                    break;
×
289
                case AccountCompressionProgramInstructions.Values.InitEmptyMerkleTree:
NEW
290
                    AccountCompressionProgramData.DecodeInitEmptyMerkleTreeData(decodedInstruction, data, keys, keyIndices);
×
NEW
291
                    break;
×
292
                case AccountCompressionProgramInstructions.Values.CloseEmptyTree:
NEW
293
                    AccountCompressionProgramData.DecodeCloseEmptyTreeData(decodedInstruction, data, keys, keyIndices);
×
NEW
294
                    break;
×
295
                case AccountCompressionProgramInstructions.Values.TransferAuthority:
NEW
296
                    AccountCompressionProgramData.DecodeTransferAuthorityInstruction(decodedInstruction, data, keys, keyIndices);
×
NEW
297
                    break;
×
298
                case AccountCompressionProgramInstructions.Values.ReplaceLeaf:
NEW
299
                    AccountCompressionProgramData.DecodeReplaceLeafData(decodedInstruction, data, keys, keyIndices);
×
300
                    break;
301
                
302
            }
NEW
303
            return decodedInstruction;
×
304
        }
305
    }
306
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc