@5ive-tech/sdk 1.1.2

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.
Files changed (119) hide show
  1. package/README.md +279 -0
  2. package/dist/FiveSDK.d.ts +336 -0
  3. package/dist/FiveSDK.js +395 -0
  4. package/dist/accounts/index.d.ts +254 -0
  5. package/dist/accounts/index.js +543 -0
  6. package/dist/assets/vm/dummy.file +0 -0
  7. package/dist/assets/vm/five_vm_wasm.d.ts +762 -0
  8. package/dist/assets/vm/five_vm_wasm.js +3754 -0
  9. package/dist/assets/vm/five_vm_wasm_bg.js +3307 -0
  10. package/dist/assets/vm/five_vm_wasm_bg.wasm +0 -0
  11. package/dist/assets/vm/five_vm_wasm_bg.wasm.d.ts +247 -0
  12. package/dist/assets/vm/package.json +11 -0
  13. package/dist/bin/gen-types.d.ts +2 -0
  14. package/dist/bin/gen-types.js +35 -0
  15. package/dist/compiler/BytecodeCompiler.d.ts +83 -0
  16. package/dist/compiler/BytecodeCompiler.js +379 -0
  17. package/dist/config/ConfigManager.d.ts +13 -0
  18. package/dist/config/ConfigManager.js +27 -0
  19. package/dist/config/ProgramIdResolver.d.ts +62 -0
  20. package/dist/config/ProgramIdResolver.js +104 -0
  21. package/dist/crypto/index.d.ts +211 -0
  22. package/dist/crypto/index.js +451 -0
  23. package/dist/encoding/ParameterEncoder.d.ts +31 -0
  24. package/dist/encoding/ParameterEncoder.js +278 -0
  25. package/dist/index.d.ts +21 -0
  26. package/dist/index.js +28 -0
  27. package/dist/lib/bytecode-encoder.d.ts +62 -0
  28. package/dist/lib/bytecode-encoder.js +281 -0
  29. package/dist/logging/index.d.ts +9 -0
  30. package/dist/logging/index.js +10 -0
  31. package/dist/metadata/index.d.ts +213 -0
  32. package/dist/metadata/index.js +296 -0
  33. package/dist/modules/accounts.d.ts +60 -0
  34. package/dist/modules/accounts.js +275 -0
  35. package/dist/modules/deploy.d.ts +90 -0
  36. package/dist/modules/deploy.js +1118 -0
  37. package/dist/modules/execute.d.ts +90 -0
  38. package/dist/modules/execute.js +649 -0
  39. package/dist/modules/fees.d.ts +14 -0
  40. package/dist/modules/fees.js +112 -0
  41. package/dist/modules/namespaces.d.ts +39 -0
  42. package/dist/modules/namespaces.js +190 -0
  43. package/dist/modules/state-diff.d.ts +35 -0
  44. package/dist/modules/state-diff.js +342 -0
  45. package/dist/modules/vm-state.d.ts +7 -0
  46. package/dist/modules/vm-state.js +44 -0
  47. package/dist/program/AccountResolver.d.ts +67 -0
  48. package/dist/program/AccountResolver.js +134 -0
  49. package/dist/program/BorshSchemaGenerator.d.ts +8 -0
  50. package/dist/program/BorshSchemaGenerator.js +57 -0
  51. package/dist/program/FiveProgram.d.ts +144 -0
  52. package/dist/program/FiveProgram.js +282 -0
  53. package/dist/program/FunctionBuilder.d.ts +114 -0
  54. package/dist/program/FunctionBuilder.js +347 -0
  55. package/dist/program/ProgramAccount.d.ts +38 -0
  56. package/dist/program/ProgramAccount.js +170 -0
  57. package/dist/program/TypeGenerator.d.ts +90 -0
  58. package/dist/program/TypeGenerator.js +195 -0
  59. package/dist/program/index.d.ts +24 -0
  60. package/dist/program/index.js +21 -0
  61. package/dist/project/config.d.ts +5 -0
  62. package/dist/project/config.js +33 -0
  63. package/dist/project/toml.d.ts +6 -0
  64. package/dist/project/toml.js +43 -0
  65. package/dist/project/workspace.d.ts +160 -0
  66. package/dist/project/workspace.js +73 -0
  67. package/dist/testing/AccountMetaGenerator.d.ts +121 -0
  68. package/dist/testing/AccountMetaGenerator.js +261 -0
  69. package/dist/testing/AccountTestFixture.d.ts +211 -0
  70. package/dist/testing/AccountTestFixture.js +530 -0
  71. package/dist/testing/OnChainAccountManager.d.ts +81 -0
  72. package/dist/testing/OnChainAccountManager.js +260 -0
  73. package/dist/testing/StateSerializer.d.ts +65 -0
  74. package/dist/testing/StateSerializer.js +330 -0
  75. package/dist/testing/TestDiscovery.d.ts +79 -0
  76. package/dist/testing/TestDiscovery.js +274 -0
  77. package/dist/testing/TestRunner.d.ts +117 -0
  78. package/dist/testing/TestRunner.js +346 -0
  79. package/dist/testing/index.d.ts +14 -0
  80. package/dist/testing/index.js +13 -0
  81. package/dist/types.d.ts +356 -0
  82. package/dist/types.js +32 -0
  83. package/dist/utils/abi.d.ts +31 -0
  84. package/dist/utils/abi.js +92 -0
  85. package/dist/utils/transaction.d.ts +5 -0
  86. package/dist/utils/transaction.js +48 -0
  87. package/dist/validation/InputValidator.d.ts +142 -0
  88. package/dist/validation/InputValidator.js +332 -0
  89. package/dist/validation/index.d.ts +4 -0
  90. package/dist/validation/index.js +4 -0
  91. package/dist/wasm/compiler/AbiLogic.d.ts +4 -0
  92. package/dist/wasm/compiler/AbiLogic.js +37 -0
  93. package/dist/wasm/compiler/AnalysisLogic.d.ts +6 -0
  94. package/dist/wasm/compiler/AnalysisLogic.js +61 -0
  95. package/dist/wasm/compiler/CompilationLogic.d.ts +10 -0
  96. package/dist/wasm/compiler/CompilationLogic.js +431 -0
  97. package/dist/wasm/compiler/FiveCompiler.d.ts +48 -0
  98. package/dist/wasm/compiler/FiveCompiler.js +183 -0
  99. package/dist/wasm/compiler/InfoLogic.d.ts +6 -0
  100. package/dist/wasm/compiler/InfoLogic.js +24 -0
  101. package/dist/wasm/compiler/OptimizationLogic.d.ts +2 -0
  102. package/dist/wasm/compiler/OptimizationLogic.js +13 -0
  103. package/dist/wasm/compiler/ValidationLogic.d.ts +7 -0
  104. package/dist/wasm/compiler/ValidationLogic.js +26 -0
  105. package/dist/wasm/compiler/index.d.ts +2 -0
  106. package/dist/wasm/compiler/index.js +2 -0
  107. package/dist/wasm/compiler/types.d.ts +8 -0
  108. package/dist/wasm/compiler/types.js +1 -0
  109. package/dist/wasm/compiler/utils.d.ts +8 -0
  110. package/dist/wasm/compiler/utils.js +75 -0
  111. package/dist/wasm/index.d.ts +9 -0
  112. package/dist/wasm/index.js +12 -0
  113. package/dist/wasm/instance.d.ts +1 -0
  114. package/dist/wasm/instance.js +26 -0
  115. package/dist/wasm/loader.d.ts +7 -0
  116. package/dist/wasm/loader.js +112 -0
  117. package/dist/wasm/vm.d.ts +33 -0
  118. package/dist/wasm/vm.js +250 -0
  119. package/package.json +59 -0
@@ -0,0 +1,530 @@
1
+ /**
2
+ * Account Test Fixture Framework for Five VM
3
+ *
4
+ * Provides a reusable, composable pattern for testing Five account-system scripts.
5
+ * Builders use this to:
6
+ * 1. Define test accounts with specific constraints
7
+ * 2. Initialize account state before test execution
8
+ * 3. Validate constraints locally before on-chain testing
9
+ * 4. Reuse common account setups across multiple tests
10
+ *
11
+ * Example:
12
+ * ```
13
+ * const fixture = new AccountTestFixture()
14
+ * .addSignerAccount('payer')
15
+ * .addStateAccount('counter', { value: 0 })
16
+ * .addMutableAccount('target')
17
+ * .build();
18
+ * ```
19
+ */
20
+ import { AccountMetaGenerator } from './AccountMetaGenerator.js';
21
+ import { PublicKey, LAMPORTS_PER_SOL } from '@solana/web3.js';
22
+ import { OnChainAccountManager } from './OnChainAccountManager.js';
23
+ import { StateSerializer } from './StateSerializer.js';
24
+ /**
25
+ * Account Test Fixture Builder
26
+ * Fluent API for constructing test account setups
27
+ */
28
+ export class AccountTestFixture {
29
+ constructor() {
30
+ this.specs = [];
31
+ this.stateTemplates = new Map();
32
+ }
33
+ /**
34
+ * Add a signer account (@signer constraint)
35
+ * Used for transaction signers, authority checks
36
+ */
37
+ addSignerAccount(name, options = {}) {
38
+ this.specs.push({
39
+ name,
40
+ type: 'signer',
41
+ description: options.description || `Signer account: ${name}`
42
+ });
43
+ return this;
44
+ }
45
+ /**
46
+ * Add a mutable account (@mut constraint)
47
+ * Can be modified by the script
48
+ */
49
+ addMutableAccount(name, state, options = {}) {
50
+ this.specs.push({
51
+ name,
52
+ type: 'mutable',
53
+ state,
54
+ description: options.description || `Mutable account: ${name}`
55
+ });
56
+ if (state) {
57
+ this.stateTemplates.set(name, state);
58
+ }
59
+ return this;
60
+ }
61
+ /**
62
+ * Add a read-only account
63
+ * Cannot be modified by the script
64
+ */
65
+ addReadOnlyAccount(name, state, options = {}) {
66
+ this.specs.push({
67
+ name,
68
+ type: 'readonly',
69
+ state,
70
+ description: options.description || `Read-only account: ${name}`
71
+ });
72
+ if (state) {
73
+ this.stateTemplates.set(name, state);
74
+ }
75
+ return this;
76
+ }
77
+ /**
78
+ * Add a state account (@mut state: StateType)
79
+ * Typically for program state storage
80
+ */
81
+ addStateAccount(name, state = {}, options = {}) {
82
+ this.specs.push({
83
+ name,
84
+ type: 'state',
85
+ state,
86
+ description: options.description || `State account: ${name}`
87
+ });
88
+ this.stateTemplates.set(name, state);
89
+ return this;
90
+ }
91
+ /**
92
+ * Add an initialization account (@init constraint)
93
+ * For account creation patterns
94
+ */
95
+ addInitAccount(name, options = {}) {
96
+ this.specs.push({
97
+ name,
98
+ type: 'init',
99
+ description: options.description || `Init account: ${name}`
100
+ });
101
+ return this;
102
+ }
103
+ /**
104
+ * Add multiple accounts in one call
105
+ * Useful for standard patterns
106
+ */
107
+ addPattern(pattern) {
108
+ switch (pattern) {
109
+ case 'authorization':
110
+ this.addSignerAccount('authority');
111
+ this.addStateAccount('state', { admin: '', authorized_users: 0 });
112
+ break;
113
+ case 'state-mutation':
114
+ this.addStateAccount('state', { count: 0, modification_count: 0 });
115
+ break;
116
+ case 'batch-operation':
117
+ this.addSignerAccount('authority');
118
+ this.addMutableAccount('account1');
119
+ this.addMutableAccount('account2');
120
+ this.addStateAccount('state', { operation_count: 0 });
121
+ break;
122
+ }
123
+ return this;
124
+ }
125
+ /**
126
+ * Compile fixture into accounts ready for execution
127
+ * Supports both local (synthetic) and on-chain (real) account modes
128
+ */
129
+ async build(options = {}) {
130
+ const mode = options.mode || 'local';
131
+ if (mode === 'local') {
132
+ return this.buildLocal(options);
133
+ }
134
+ else if (mode === 'onchain') {
135
+ if (!options.connection || !options.payer) {
136
+ throw new Error('connection and payer required for onchain mode');
137
+ }
138
+ return this.buildOnChain(options);
139
+ }
140
+ else {
141
+ throw new Error(`Unknown mode: ${mode}`);
142
+ }
143
+ }
144
+ /**
145
+ * Build fixture with local synthetic accounts (existing behavior)
146
+ */
147
+ async buildLocal(options = {}) {
148
+ const accounts = [];
149
+ const accountsByName = new Map();
150
+ const signerCount = this.specs.filter(s => s.type === 'signer').length;
151
+ const mutableCount = this.specs.filter(s => s.type === 'mutable' || s.type === 'state').length;
152
+ const readonlyCount = this.specs.filter(s => s.type === 'readonly').length;
153
+ const stateCount = this.specs.filter(s => s.type === 'state').length;
154
+ if (options.debug) {
155
+ console.log(`[AccountTestFixture] Building local fixture with ${this.specs.length} accounts:`);
156
+ }
157
+ for (const spec of this.specs) {
158
+ const account = await this.createAccount(spec, options);
159
+ accounts.push(account);
160
+ accountsByName.set(spec.name, account);
161
+ if (options.debug) {
162
+ console.log(` ${spec.name} (${spec.type}): ${account.pubkey.substring(0, 8)}...`);
163
+ }
164
+ }
165
+ return {
166
+ accounts,
167
+ accountsByName,
168
+ stateData: this.stateTemplates,
169
+ specs: this.specs,
170
+ metadata: {
171
+ signerCount,
172
+ mutableCount,
173
+ readonlyCount,
174
+ stateCount
175
+ }
176
+ };
177
+ }
178
+ /**
179
+ * Build fixture with real on-chain accounts
180
+ */
181
+ async buildOnChain(options) {
182
+ const manager = new OnChainAccountManager(options.connection, options.payer, {
183
+ debug: options.debug,
184
+ cleanup: options.cleanup
185
+ });
186
+ const accounts = [];
187
+ const accountsByName = new Map();
188
+ const createdAccounts = [];
189
+ const signerCount = this.specs.filter(s => s.type === 'signer').length;
190
+ const mutableCount = this.specs.filter(s => s.type === 'mutable' || s.type === 'state').length;
191
+ const readonlyCount = this.specs.filter(s => s.type === 'readonly').length;
192
+ const stateCount = this.specs.filter(s => s.type === 'state').length;
193
+ if (options.debug) {
194
+ console.log(`[AccountTestFixture] Building on-chain fixture with ${this.specs.length} accounts`);
195
+ }
196
+ // Create each account on-chain
197
+ for (const spec of this.specs) {
198
+ let publicKey;
199
+ let keypair;
200
+ try {
201
+ if (spec.type === 'signer') {
202
+ // Create signer account with keypair
203
+ const result = await manager.createSignerAccount(LAMPORTS_PER_SOL);
204
+ publicKey = result.publicKey;
205
+ keypair = result.keypair;
206
+ if (options.debug) {
207
+ console.log(` ${spec.name} (signer): ${publicKey.toString()}`);
208
+ }
209
+ accounts.push({
210
+ pubkey: publicKey.toString(),
211
+ isSigner: true,
212
+ isWritable: true,
213
+ keypair: {
214
+ publicKey: publicKey.toString(),
215
+ secretKey: keypair.secretKey
216
+ }
217
+ });
218
+ }
219
+ else if (spec.type === 'state' || spec.type === 'mutable') {
220
+ // Create state/mutable account with initial data
221
+ const space = 1024; // Default space
222
+ const owner = options.fiveVMProgramId || new PublicKey('9MHGM73eszNUtmJS6ypDCESguxWhCBnkUPpTMyLGqURH');
223
+ // Serialize state data if provided
224
+ let initialData;
225
+ if (spec.state && spec.type === 'state') {
226
+ const stateDefinition = {
227
+ name: spec.name,
228
+ fields: Object.keys(spec.state).map(name => ({ name, type: 'u64' })) // Simple default types
229
+ };
230
+ initialData = StateSerializer.serialize(stateDefinition, spec.state, { debug: options.debug });
231
+ }
232
+ publicKey = await manager.createStateAccount(space, owner, initialData);
233
+ if (options.debug) {
234
+ console.log(` ${spec.name} (${spec.type}): ${publicKey.toString()}`);
235
+ }
236
+ accounts.push({
237
+ pubkey: publicKey.toString(),
238
+ isSigner: false,
239
+ isWritable: true
240
+ });
241
+ }
242
+ else if (spec.type === 'init') {
243
+ // Create init account (will be initialized by script)
244
+ const space = 1024;
245
+ const owner = options.fiveVMProgramId || new PublicKey('9MHGM73eszNUtmJS6ypDCESguxWhCBnkUPpTMyLGqURH');
246
+ publicKey = await manager.createAccount(space, owner);
247
+ if (options.debug) {
248
+ console.log(` ${spec.name} (init): ${publicKey.toString()}`);
249
+ }
250
+ accounts.push({
251
+ pubkey: publicKey.toString(),
252
+ isSigner: false,
253
+ isWritable: true
254
+ });
255
+ }
256
+ else {
257
+ // Create readonly account
258
+ const space = 0;
259
+ const owner = options.fiveVMProgramId || new PublicKey('9MHGM73eszNUtmJS6ypDCESguxWhCBnkUPpTMyLGqURH');
260
+ publicKey = await manager.createAccount(space, owner);
261
+ if (options.debug) {
262
+ console.log(` ${spec.name} (readonly): ${publicKey.toString()}`);
263
+ }
264
+ accounts.push({
265
+ pubkey: publicKey.toString(),
266
+ isSigner: false,
267
+ isWritable: false
268
+ });
269
+ }
270
+ accountsByName.set(spec.name, accounts[accounts.length - 1]);
271
+ createdAccounts.push(publicKey);
272
+ }
273
+ catch (error) {
274
+ const errorMessage = error instanceof Error ? error.message : String(error);
275
+ throw new Error(`Failed to create account '${spec.name}': ${errorMessage}`);
276
+ }
277
+ }
278
+ // Create cleanup function if enabled
279
+ const cleanup = options.cleanup
280
+ ? async () => manager.cleanup()
281
+ : undefined;
282
+ return {
283
+ accounts,
284
+ accountsByName,
285
+ stateData: this.stateTemplates,
286
+ specs: this.specs,
287
+ metadata: {
288
+ signerCount,
289
+ mutableCount,
290
+ readonlyCount,
291
+ stateCount
292
+ },
293
+ cleanup
294
+ };
295
+ }
296
+ /**
297
+ * Create individual account based on spec
298
+ */
299
+ async createAccount(spec, options) {
300
+ // Determine writable and signer flags based on type
301
+ const isWritable = spec.type === 'mutable' || spec.type === 'state' || spec.type === 'init';
302
+ const isSigner = spec.type === 'signer';
303
+ // Use AccountMetaGenerator for consistent account creation
304
+ const constraints = {
305
+ name: spec.name,
306
+ writable: isWritable,
307
+ signer: isSigner
308
+ };
309
+ if (isSigner) {
310
+ return await AccountMetaGenerator['generateSignerAccount'](constraints, { debug: options.debug });
311
+ }
312
+ else {
313
+ return await AccountMetaGenerator['generateRegularAccount'](constraints, { debug: options.debug });
314
+ }
315
+ }
316
+ /**
317
+ * Validate fixture against ABI constraints
318
+ */
319
+ validateAgainstABI(abiFunction) {
320
+ const errors = [];
321
+ const warnings = [];
322
+ const requiredAccounts = abiFunction.accounts || [];
323
+ if (this.specs.length !== requiredAccounts.length) {
324
+ errors.push(`Account count mismatch: fixture has ${this.specs.length} accounts, ` +
325
+ `ABI requires ${requiredAccounts.length}`);
326
+ }
327
+ for (let i = 0; i < Math.min(this.specs.length, requiredAccounts.length); i++) {
328
+ const spec = this.specs[i];
329
+ const abiAccount = requiredAccounts[i];
330
+ // Check signer constraint
331
+ if (spec.type === 'signer' && !abiAccount.signer) {
332
+ warnings.push(`Account ${i} (${spec.name}): marked as signer but ABI doesn't require it`);
333
+ }
334
+ if (spec.type !== 'signer' && abiAccount.signer) {
335
+ errors.push(`Account ${i} (${spec.name}): ABI requires signer, but fixture provides ${spec.type}`);
336
+ }
337
+ // Check mutability constraint
338
+ const isWritable = spec.type === 'mutable' || spec.type === 'state' || spec.type === 'init';
339
+ if (isWritable && !abiAccount.writable) {
340
+ warnings.push(`Account ${i} (${spec.name}): marked as writable but ABI doesn't require it`);
341
+ }
342
+ if (!isWritable && abiAccount.writable) {
343
+ errors.push(`Account ${i} (${spec.name}): ABI requires writable, but fixture provides ${spec.type}`);
344
+ }
345
+ }
346
+ return {
347
+ valid: errors.length === 0,
348
+ errors,
349
+ warnings
350
+ };
351
+ }
352
+ /**
353
+ * Get summary of fixture specs for debugging
354
+ */
355
+ getSummary() {
356
+ const lines = [
357
+ `Account Test Fixture (${this.specs.length} accounts)`,
358
+ '─'.repeat(40)
359
+ ];
360
+ for (const spec of this.specs) {
361
+ const stateStr = spec.state ? ` with state: ${JSON.stringify(spec.state)}` : '';
362
+ lines.push(` • ${spec.name} (${spec.type})${stateStr}`);
363
+ }
364
+ lines.push('─'.repeat(40));
365
+ lines.push(`Signers: ${this.specs.filter(s => s.type === 'signer').length}, ` +
366
+ `Writable: ${this.specs.filter(s => s.type !== 'readonly' && s.type !== 'signer').length}`);
367
+ return lines.join('\n');
368
+ }
369
+ }
370
+ /**
371
+ * Predefined fixture templates for common patterns
372
+ * Builders can extend these for their specific needs
373
+ */
374
+ export class FixtureTemplates {
375
+ /**
376
+ * Simple state mutation pattern
377
+ * For scripts that increment counters, track modifications, etc.
378
+ */
379
+ static stateCounter() {
380
+ return new AccountTestFixture()
381
+ .addStateAccount('state', {
382
+ count: 0,
383
+ modification_count: 0
384
+ });
385
+ }
386
+ /**
387
+ * Authorization pattern
388
+ * For scripts that check permissions via @signer
389
+ */
390
+ static authorization() {
391
+ return new AccountTestFixture()
392
+ .addSignerAccount('authority', {
393
+ description: 'Signer that has authorization'
394
+ })
395
+ .addStateAccount('state', {
396
+ admin: '11111111111111111111111111111111', // Placeholder public key
397
+ authorized_users: 0
398
+ });
399
+ }
400
+ /**
401
+ * Account creation pattern
402
+ * For scripts using @init constraint
403
+ */
404
+ static accountCreation() {
405
+ return new AccountTestFixture()
406
+ .addSignerAccount('payer')
407
+ .addInitAccount('new_account')
408
+ .addStateAccount('state', {
409
+ total_created: 0,
410
+ last_created: '11111111111111111111111111111111'
411
+ });
412
+ }
413
+ /**
414
+ * Multi-account transaction pattern
415
+ * For scripts that operate on multiple mutable accounts
416
+ */
417
+ static batchOperation() {
418
+ return new AccountTestFixture()
419
+ .addSignerAccount('authority')
420
+ .addMutableAccount('account1')
421
+ .addMutableAccount('account2')
422
+ .addStateAccount('state', {
423
+ operation_count: 0,
424
+ last_operator: '11111111111111111111111111111111'
425
+ });
426
+ }
427
+ /**
428
+ * Complex authorization pattern
429
+ * For multi-signature or advanced permission schemes
430
+ */
431
+ static multiSigPattern() {
432
+ return new AccountTestFixture()
433
+ .addSignerAccount('primary')
434
+ .addSignerAccount('secondary')
435
+ .addStateAccount('state', {
436
+ owner: '11111111111111111111111111111111',
437
+ authorized_signers: 2,
438
+ transaction_count: 0
439
+ });
440
+ }
441
+ /**
442
+ * PDA pattern
443
+ * For scripts that use Program Derived Addresses
444
+ */
445
+ static pdaPattern() {
446
+ return new AccountTestFixture()
447
+ .addSignerAccount('payer')
448
+ .addInitAccount('pda_vault')
449
+ .addStateAccount('state', {
450
+ vault_bump: 255,
451
+ token_bump: 255
452
+ });
453
+ }
454
+ }
455
+ /**
456
+ * Test execution builder
457
+ * Combines fixture with test parameters for execution
458
+ */
459
+ export class AccountTestExecutor {
460
+ /**
461
+ * Bind fixture accounts to a test execution
462
+ */
463
+ static bindFixture(fixture, functionName, parameters = []) {
464
+ const keypairs = new Map();
465
+ // Collect keypairs from signer accounts for transaction signing
466
+ for (const [name, account] of fixture.accountsByName) {
467
+ if (account.keypair) {
468
+ keypairs.set(name, account.keypair.secretKey);
469
+ }
470
+ }
471
+ return {
472
+ fixture,
473
+ functionName,
474
+ parameters,
475
+ accountAddresses: fixture.accounts.map(a => a.pubkey),
476
+ keypairs
477
+ };
478
+ }
479
+ /**
480
+ * Validate execution context before running
481
+ */
482
+ static validateContext(context) {
483
+ const errors = [];
484
+ const warnings = [];
485
+ // Verify all accounts are properly initialized
486
+ if (context.fixture.accounts.length === 0) {
487
+ errors.push('No accounts in fixture');
488
+ }
489
+ // Verify signer accounts have keypairs
490
+ for (const account of context.fixture.accounts) {
491
+ const spec = context.fixture.specs.find(s => s.name ===
492
+ Array.from(context.fixture.accountsByName.entries())
493
+ .find(([_, acc]) => acc === account)?.[0]);
494
+ if (spec?.type === 'signer' && !account.keypair) {
495
+ errors.push(`Signer account '${spec.name}' missing keypair`);
496
+ }
497
+ }
498
+ // Verify account addresses are valid
499
+ if (context.accountAddresses.length !== context.fixture.accounts.length) {
500
+ errors.push('Account address count mismatch');
501
+ }
502
+ return {
503
+ valid: errors.length === 0,
504
+ errors,
505
+ warnings
506
+ };
507
+ }
508
+ /**
509
+ * Get human-readable execution summary
510
+ */
511
+ static getSummary(context) {
512
+ const lines = [
513
+ `Test Execution Context`,
514
+ '─'.repeat(50),
515
+ `Function: ${context.functionName}`,
516
+ `Parameters: ${JSON.stringify(context.parameters)}`,
517
+ `Accounts: ${context.fixture.accounts.length}`,
518
+ '─'.repeat(50)
519
+ ];
520
+ for (let i = 0; i < context.fixture.accounts.length; i++) {
521
+ const account = context.fixture.accounts[i];
522
+ const spec = context.fixture.specs[i];
523
+ const signer = account.isSigner ? ' [SIGNER]' : '';
524
+ const writable = account.isWritable ? ' [WRITABLE]' : ' [READONLY]';
525
+ lines.push(` ${i}: ${spec.name}${signer}${writable}`);
526
+ lines.push(` Address: ${account.pubkey}`);
527
+ }
528
+ return lines.join('\n');
529
+ }
530
+ }
@@ -0,0 +1,81 @@
1
+ /**
2
+ * On-Chain Account Manager for Five VM Account-System Testing
3
+ *
4
+ * Creates and manages real Solana accounts on-chain for comprehensive account-system testing.
5
+ * Handles account creation, funding, initialization, and cleanup.
6
+ */
7
+ import { Connection, Keypair, PublicKey } from '@solana/web3.js';
8
+ export interface OnChainAccountManagerOptions {
9
+ debug?: boolean;
10
+ cleanup?: boolean;
11
+ maxRetries?: number;
12
+ retryDelay?: number;
13
+ }
14
+ /**
15
+ * Manages creation and lifecycle of real Solana accounts for testing
16
+ */
17
+ export declare class OnChainAccountManager {
18
+ private connection;
19
+ private payer;
20
+ private options;
21
+ private createdAccounts;
22
+ private signers;
23
+ constructor(connection: Connection, payer: Keypair, options?: OnChainAccountManagerOptions);
24
+ /**
25
+ * Create a signer account with generated keypair
26
+ * Transfers SOL from payer to fund the account
27
+ */
28
+ createSignerAccount(lamports?: number): Promise<{
29
+ publicKey: PublicKey;
30
+ keypair: Keypair;
31
+ }>;
32
+ /**
33
+ * Create a regular account with specified space and owner
34
+ * Uses SystemProgram.createAccount for account creation
35
+ */
36
+ createAccount(space: number, owner: PublicKey, lamports?: number): Promise<PublicKey>;
37
+ /**
38
+ * Create and initialize a state account with initial data
39
+ */
40
+ createStateAccount(space: number, owner: PublicKey, initialData?: Uint8Array, lamports?: number): Promise<PublicKey>;
41
+ /**
42
+ * Create a PDA account at a specific seed path
43
+ */
44
+ createPDAAccount(seeds: Buffer[], programId: PublicKey, space: number, owner?: PublicKey, lamports?: number): Promise<{
45
+ publicKey: PublicKey;
46
+ bump: number;
47
+ }>;
48
+ /**
49
+ * Write data to an account (requires account to be writable)
50
+ */
51
+ writeAccountData(accountAddress: PublicKey, data: Uint8Array): Promise<void>;
52
+ /**
53
+ * Check if an account exists
54
+ */
55
+ checkAccountExists(publicKey: PublicKey): Promise<boolean>;
56
+ /**
57
+ * Ensure payer has sufficient balance
58
+ */
59
+ ensureSufficientBalance(required: number): Promise<void>;
60
+ /**
61
+ * Create account with retry logic
62
+ */
63
+ createAccountWithRetry(createFn: () => Promise<PublicKey>, options?: {
64
+ maxRetries?: number;
65
+ retryDelay?: number;
66
+ }): Promise<PublicKey>;
67
+ /**
68
+ * Get a signer keypair if it was created by this manager
69
+ */
70
+ getSignerKeypair(publicKey: PublicKey | string): Keypair | undefined;
71
+ /**
72
+ * Get all created accounts
73
+ */
74
+ getCreatedAccounts(): PublicKey[];
75
+ /**
76
+ * Cleanup: Close all created accounts and transfer remaining SOL back to payer
77
+ * This helps with test isolation and prevents account accumulation on testnet
78
+ */
79
+ cleanup(): Promise<void>;
80
+ }
81
+ export default OnChainAccountManager;