@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,24 @@
1
+ import { createCompilerError } from "./utils.js";
2
+ export function getCompilerInfo(ctx) {
3
+ if (!ctx.compiler) {
4
+ throw createCompilerError("Compiler not initialized");
5
+ }
6
+ try {
7
+ const info = ctx.compiler.get_compiler_stats();
8
+ return JSON.parse(info);
9
+ }
10
+ catch (error) {
11
+ throw createCompilerError("Failed to get compiler info", error);
12
+ }
13
+ }
14
+ export async function discoverModules(ctx, entryPoint) {
15
+ if (!ctx.compiler) {
16
+ throw createCompilerError("Compiler not initialized");
17
+ }
18
+ try {
19
+ return ctx.compiler.discoverModules(entryPoint);
20
+ }
21
+ catch (error) {
22
+ throw createCompilerError(`Module discovery failed: ${error instanceof Error ? error.message : String(error)}`, error);
23
+ }
24
+ }
@@ -0,0 +1,2 @@
1
+ import { CompilationContext } from "./types.js";
2
+ export declare function optimizeBytecode(ctx: CompilationContext, bytecode: Uint8Array): Promise<Uint8Array>;
@@ -0,0 +1,13 @@
1
+ import { createCompilerError } from "./utils.js";
2
+ export async function optimizeBytecode(ctx, bytecode) {
3
+ if (!ctx.compiler) {
4
+ throw createCompilerError("Compiler not initialized");
5
+ }
6
+ try {
7
+ const optimized = ctx.compiler.optimize_bytecode(bytecode);
8
+ return new Uint8Array(optimized);
9
+ }
10
+ catch (error) {
11
+ throw createCompilerError("Bytecode optimization failed", error);
12
+ }
13
+ }
@@ -0,0 +1,7 @@
1
+ import { CompilationContext } from "./types.js";
2
+ export declare function validateSource(ctx: CompilationContext, sourceCode: string): Promise<{
3
+ valid: boolean;
4
+ errors: string[];
5
+ warnings: string[];
6
+ }>;
7
+ export declare function validateAccountConstraints(ctx: CompilationContext, sourceCode: string, functionName: string, accounts: any[]): Promise<any>;
@@ -0,0 +1,26 @@
1
+ import { createCompilerError } from "./utils.js";
2
+ export async function validateSource(ctx, sourceCode) {
3
+ if (!ctx.compiler) {
4
+ throw createCompilerError("Compiler not initialized");
5
+ }
6
+ try {
7
+ const result = ctx.compiler.validate_syntax(sourceCode);
8
+ return JSON.parse(result);
9
+ }
10
+ catch (error) {
11
+ throw createCompilerError("Syntax validation failed", error);
12
+ }
13
+ }
14
+ export async function validateAccountConstraints(ctx, sourceCode, functionName, accounts) {
15
+ if (!ctx.compiler) {
16
+ throw createCompilerError("Compiler not initialized");
17
+ }
18
+ try {
19
+ const accountsJson = JSON.stringify(accounts);
20
+ const validation = ctx.compiler.validate_account_constraints(sourceCode, functionName, accountsJson);
21
+ return JSON.parse(validation);
22
+ }
23
+ catch (error) {
24
+ throw createCompilerError("Account constraint validation failed", error);
25
+ }
26
+ }
@@ -0,0 +1,2 @@
1
+ export { FiveCompiler } from "./FiveCompiler.js";
2
+ export * from "./types.js";
@@ -0,0 +1,2 @@
1
+ export { FiveCompiler } from "./FiveCompiler.js";
2
+ export * from "./types.js";
@@ -0,0 +1,8 @@
1
+ import { Logger } from "../../types.js";
2
+ export interface CompilationContext {
3
+ compiler: any;
4
+ wasmModuleRef: any;
5
+ WasmCompilationOptions: any;
6
+ BytecodeAnalyzer: any;
7
+ logger: Logger;
8
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,8 @@
1
+ import { CLIError } from "../../types.js";
2
+ export declare function createCompilerError(message: string, cause?: Error): CLIError;
3
+ export declare function extractMetrics(result: any, defaultFormat: string): {
4
+ format: string;
5
+ exported: string;
6
+ detailed?: any;
7
+ } | undefined;
8
+ export declare function extractAbi(result: any, logger: any): any | undefined;
@@ -0,0 +1,75 @@
1
+ export function createCompilerError(message, cause) {
2
+ const error = new Error(message);
3
+ error.name = "CompilerError";
4
+ error.code = "COMPILER_ERROR";
5
+ error.category = "wasm";
6
+ error.exitCode = 1;
7
+ if (cause) {
8
+ error.details = {
9
+ cause: cause.message,
10
+ stack: cause.stack,
11
+ };
12
+ }
13
+ return error;
14
+ }
15
+ export function extractMetrics(result, defaultFormat) {
16
+ if (!result || typeof result !== "object") {
17
+ return undefined;
18
+ }
19
+ const exported = result.metrics;
20
+ if (!exported) {
21
+ return undefined;
22
+ }
23
+ const format = result.metrics_format || defaultFormat;
24
+ let detailed;
25
+ try {
26
+ const getDetailed = result.get_metrics_detailed;
27
+ if (typeof getDetailed === "function") {
28
+ detailed = getDetailed.call(result);
29
+ }
30
+ else {
31
+ const getObject = result.get_metrics_object;
32
+ if (typeof getObject === "function") {
33
+ detailed = getObject.call(result);
34
+ }
35
+ }
36
+ }
37
+ catch {
38
+ // Ignore metrics errors
39
+ }
40
+ return {
41
+ format,
42
+ exported,
43
+ detailed,
44
+ };
45
+ }
46
+ export function extractAbi(result, logger) {
47
+ if (!result) {
48
+ return undefined;
49
+ }
50
+ if (typeof result.get_abi === "function") {
51
+ try {
52
+ const abiJson = result.get_abi();
53
+ if (abiJson) {
54
+ return JSON.parse(abiJson);
55
+ }
56
+ }
57
+ catch (error) {
58
+ logger.debug("Failed to parse ABI from get_abi():", error);
59
+ }
60
+ }
61
+ const directAbi = result.abi;
62
+ if (!directAbi) {
63
+ return undefined;
64
+ }
65
+ if (typeof directAbi === "string") {
66
+ try {
67
+ return JSON.parse(directAbi);
68
+ }
69
+ catch (error) {
70
+ logger.debug("Failed to parse ABI from result.abi string:", error);
71
+ return undefined;
72
+ }
73
+ }
74
+ return directAbi;
75
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Five SDK WASM Integration Index
3
+ *
4
+ * Provides access to WASM VM and Compiler classes for the SDK.
5
+ * Includes cross-platform path resolution and resource management.
6
+ */
7
+ export { FiveVM } from './vm.js';
8
+ export { FiveCompiler } from './compiler/index.js';
9
+ export { BytecodeEncoder } from '../lib/bytecode-encoder.js';
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Five SDK WASM Integration Index
3
+ *
4
+ * Provides access to WASM VM and Compiler classes for the SDK.
5
+ * Includes cross-platform path resolution and resource management.
6
+ */
7
+ // Direct re-exports from CLI WASM modules
8
+ export { FiveVM } from './vm.js';
9
+ export { FiveCompiler } from './compiler/index.js';
10
+ // Bytecode encoder from lib
11
+ export { BytecodeEncoder } from '../lib/bytecode-encoder.js';
12
+ // Simple WASM utilities (no over-engineering)
@@ -0,0 +1 @@
1
+ export declare function loadWasmVM(): Promise<any>;
@@ -0,0 +1,26 @@
1
+ import { FiveSDKError } from "../types.js";
2
+ let wasmVMInstance = null;
3
+ export async function loadWasmVM() {
4
+ if (wasmVMInstance) {
5
+ return wasmVMInstance;
6
+ }
7
+ try {
8
+ // Import existing WASM VM from five-cli infrastructure
9
+ const { FiveVM } = await import('./vm.js');
10
+ // Create a simple logger for WASM VM
11
+ const logger = {
12
+ debug: (msg) => console.debug("[WASM VM]", msg),
13
+ info: (msg) => console.info("[WASM VM]", msg),
14
+ warn: (msg) => console.warn("[WASM VM]", msg),
15
+ error: (msg) => console.error("[WASM VM]", msg),
16
+ };
17
+ wasmVMInstance = new FiveVM(logger); // Initialize WASM VM
18
+ if (wasmVMInstance.initialize) {
19
+ await wasmVMInstance.initialize();
20
+ }
21
+ return wasmVMInstance;
22
+ }
23
+ catch (error) {
24
+ throw new FiveSDKError(`Failed to load WASM VM: ${error instanceof Error ? error.message : "Unknown error"}`, "WASM_LOAD_ERROR");
25
+ }
26
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * WASM Loader for Five VM
3
+ *
4
+ * Loader that uses the main wasm-pack generated entry point.
5
+ * Compatible with both Node.js and Browser environments.
6
+ */
7
+ export declare function getWasmModule(): Promise<any>;
@@ -0,0 +1,112 @@
1
+ /**
2
+ * WASM Loader for Five VM
3
+ *
4
+ * Loader that uses the main wasm-pack generated entry point.
5
+ * Compatible with both Node.js and Browser environments.
6
+ */
7
+ // Store the initialized module instance globally within this module's scope.
8
+ let wasmModule = null;
9
+ import { ConfigManager } from '../config/ConfigManager.js';
10
+ export async function getWasmModule() {
11
+ if (wasmModule) {
12
+ return wasmModule;
13
+ }
14
+ // Build candidate list from config and sensible defaults
15
+ const cfg = await ConfigManager.getInstance().get();
16
+ const prefer = cfg.wasm?.loader || 'auto';
17
+ const configured = Array.isArray(cfg.wasm?.modulePaths) ? cfg.wasm.modulePaths : [];
18
+ const nodeCandidates = [
19
+ '../../five_vm_wasm.cjs',
20
+ '../five_vm_wasm.cjs',
21
+ './five_vm_wasm.cjs',
22
+ '../../five_vm_wasm.js',
23
+ '../five_vm_wasm.js',
24
+ './five_vm_wasm.js', // Sibling check
25
+ ];
26
+ const bundlerCandidates = [
27
+ '../../assets/vm/five_vm_wasm.cjs',
28
+ '../assets/vm/five_vm_wasm.cjs',
29
+ '../../assets/vm/five_vm_wasm.js',
30
+ '../assets/vm/five_vm_wasm.js',
31
+ // Fallback for direct import (bundler alias)
32
+ 'five-wasm',
33
+ 'five-vm-wasm'
34
+ ];
35
+ let candidates = [];
36
+ candidates.push(...configured);
37
+ // Detect environment to prioritize candidates
38
+ const isNode = typeof process !== 'undefined' && process.versions != null && process.versions.node != null;
39
+ if (prefer === 'node' || (prefer === 'auto' && isNode)) {
40
+ candidates.push(...nodeCandidates);
41
+ candidates.push(...bundlerCandidates);
42
+ }
43
+ else {
44
+ candidates.push(...bundlerCandidates); // Bundler/Browser preferred
45
+ candidates.push(...nodeCandidates);
46
+ }
47
+ const tried = [];
48
+ for (const candidate of candidates) {
49
+ try {
50
+ const mod = await import(candidate);
51
+ // Node.js specific initialization using fs/path (Dynamic Import to avoid Browser errors)
52
+ if (mod && typeof mod.initSync === 'function' && isNode) {
53
+ try {
54
+ const fs = await import('fs');
55
+ const path = await import('path');
56
+ const url = await import('url');
57
+ const dirname = path.dirname;
58
+ const resolve = path.resolve;
59
+ const fileURLToPath = url.fileURLToPath;
60
+ const existsSync = fs.existsSync;
61
+ const readFileSync = fs.readFileSync;
62
+ // Resolve path safely
63
+ let here;
64
+ try {
65
+ here = dirname(fileURLToPath(import.meta.url));
66
+ }
67
+ catch (e) {
68
+ // Fallback if import.meta.url is not file://
69
+ here = process.cwd();
70
+ }
71
+ const wasmFiles = [
72
+ resolve(here, '../five_vm_wasm_bg.wasm'),
73
+ resolve(here, '../../five_vm_wasm_bg.wasm'),
74
+ resolve(here, '../assets/vm/five_vm_wasm_bg.wasm'),
75
+ resolve(here, '../../assets/vm/five_vm_wasm_bg.wasm'),
76
+ ];
77
+ for (const wf of wasmFiles) {
78
+ if (existsSync(wf)) {
79
+ mod.initSync(readFileSync(wf));
80
+ break;
81
+ }
82
+ }
83
+ }
84
+ catch (syncErr) {
85
+ // Ignore sync init errors in node, might work with default init
86
+ // tried.push({ path: candidate, error: syncErr });
87
+ }
88
+ }
89
+ // Universal initialization (Browser/Node) if default export is init function
90
+ if (mod && typeof mod.default === 'function') {
91
+ try {
92
+ await mod.default();
93
+ }
94
+ catch (initErr) {
95
+ tried.push({ path: candidate, error: initErr });
96
+ }
97
+ }
98
+ if (mod) {
99
+ wasmModule = mod;
100
+ return wasmModule;
101
+ }
102
+ tried.push({ path: candidate, error: 'Module import returned null/undefined' });
103
+ }
104
+ catch (e) {
105
+ tried.push({ path: candidate, error: e });
106
+ }
107
+ }
108
+ const attempted = tried
109
+ .map(t => ` - ${t.path}: ${t.error instanceof Error ? t.error.message : String(t.error)}`)
110
+ .join('\n');
111
+ throw new Error(`Five VM WASM module not found or failed to load. Please ensure five-wasm is built.\nAttempts:\n${attempted}`);
112
+ }
@@ -0,0 +1,33 @@
1
+ import { VMExecutionOptions, VMExecutionResult, AccountInfo, Logger } from '../types.js';
2
+ export declare class FiveVM {
3
+ private vm;
4
+ private logger;
5
+ private initialized;
6
+ constructor(logger: Logger);
7
+ initialize(): Promise<void>;
8
+ private isWasmOnlyExecution;
9
+ private hasFiveMagic;
10
+ private looksLikeScriptHeader;
11
+ private looksLikeOptimizedHeader;
12
+ execute(options: VMExecutionOptions): Promise<VMExecutionResult>;
13
+ private parseVMResult;
14
+ executeFunction(bytecode: Uint8Array, functionIndex: number, parameters: Array<{
15
+ type: string;
16
+ value: any;
17
+ }>, accounts?: AccountInfo[]): Promise<VMExecutionResult>;
18
+ getState(): Promise<any>;
19
+ validateBytecode(bytecode: Uint8Array): Promise<{
20
+ valid: boolean;
21
+ error?: string;
22
+ }>;
23
+ getVMConstants(): any;
24
+ private convertAccountsToWasm;
25
+ private loggerwarn;
26
+ private createVMError;
27
+ getVMInfo(): {
28
+ version: string;
29
+ features: string[];
30
+ };
31
+ isReady(): boolean;
32
+ cleanup(): void;
33
+ }
@@ -0,0 +1,250 @@
1
+ // Five VM WASM integration.
2
+ import { getWasmModule } from './loader.js';
3
+ let FiveVMWasm;
4
+ let WasmAccount;
5
+ let ParameterEncoder;
6
+ let wrap_with_script_header;
7
+ const SCRIPT_HEADER_LEN = 64; // ScriptHeader::LEN
8
+ const OPTIMIZED_HEADER_LEN = 7; // OptimizedHeader V2 size
9
+ const FIVE_MAGIC = [0x35, 0x49, 0x56, 0x45];
10
+ export class FiveVM {
11
+ constructor(logger) {
12
+ this.vm = null;
13
+ this.initialized = false;
14
+ this.logger = logger;
15
+ }
16
+ async initialize() {
17
+ try {
18
+ this.logger.debug('[DEBUG] Starting VM WASM initialization...');
19
+ const wasmModule = await getWasmModule();
20
+ FiveVMWasm = wasmModule.FiveVMWasm;
21
+ WasmAccount = wasmModule.WasmAccount;
22
+ ParameterEncoder = wasmModule.ParameterEncoder;
23
+ if (typeof wasmModule.wrap_with_script_header !== 'function') {
24
+ // Warning only? Or throw?
25
+ this.logger.warn('WASM VM missing wrap_with_script_header');
26
+ }
27
+ else {
28
+ wrap_with_script_header = wasmModule.wrap_with_script_header;
29
+ }
30
+ this.initialized = true;
31
+ }
32
+ catch (error) {
33
+ throw this.createVMError('Five VM WASM modules not found. Please run "npm run build:wasm".', error);
34
+ }
35
+ }
36
+ isWasmOnlyExecution() {
37
+ // Check basic env
38
+ if (typeof process !== 'undefined' && process.argv) {
39
+ if (process.argv.includes('local'))
40
+ return true;
41
+ }
42
+ return true;
43
+ }
44
+ hasFiveMagic(data) {
45
+ if (data.length < FIVE_MAGIC.length)
46
+ return false;
47
+ return FIVE_MAGIC.every((byte, index) => data[index] === byte);
48
+ }
49
+ looksLikeScriptHeader(data) {
50
+ if (data.length < SCRIPT_HEADER_LEN)
51
+ return false;
52
+ if (!this.hasFiveMagic(data))
53
+ return false;
54
+ const encodedLen = data[4] + (data[5] << 8) + (data[6] << 16);
55
+ const payloadLen = data.length - SCRIPT_HEADER_LEN;
56
+ return encodedLen === payloadLen;
57
+ }
58
+ looksLikeOptimizedHeader(data) {
59
+ if (data.length < OPTIMIZED_HEADER_LEN)
60
+ return false;
61
+ if (!this.hasFiveMagic(data))
62
+ return false;
63
+ return !this.looksLikeScriptHeader(data);
64
+ }
65
+ async execute(options) {
66
+ if (!this.initialized)
67
+ await this.initialize();
68
+ if (!this.initialized)
69
+ throw this.createVMError('VM not initialized');
70
+ const startTime = Date.now();
71
+ try {
72
+ let scriptData;
73
+ const hasScriptHeader = this.looksLikeScriptHeader(options.bytecode);
74
+ const hasOptimizedHeader = this.looksLikeOptimizedHeader(options.bytecode);
75
+ if (hasScriptHeader || hasOptimizedHeader) {
76
+ scriptData = options.bytecode;
77
+ }
78
+ else {
79
+ if (!wrap_with_script_header) {
80
+ // Fallback if binding missing
81
+ scriptData = options.bytecode;
82
+ }
83
+ else {
84
+ const wrapped = wrap_with_script_header(options.bytecode);
85
+ scriptData = new Uint8Array(wrapped);
86
+ }
87
+ }
88
+ // Create VM instance
89
+ this.vm = new FiveVMWasm(scriptData);
90
+ const wasmAccounts = this.convertAccountsToWasm(options.accounts || []);
91
+ const inputData = options.inputData || new Uint8Array(0);
92
+ // Execute
93
+ const result = this.vm.execute_partial(inputData, wasmAccounts);
94
+ const executionTime = Date.now() - startTime;
95
+ return this.parseVMResult(result, executionTime);
96
+ }
97
+ catch (error) {
98
+ const executionTime = Date.now() - startTime;
99
+ return {
100
+ success: false,
101
+ error: {
102
+ type: 'ExecutionError',
103
+ message: error instanceof Error ? error.message : 'Unknown VM error',
104
+ instructionPointer: 0,
105
+ stackTrace: [],
106
+ errorCode: -1
107
+ },
108
+ executionTime,
109
+ logs: []
110
+ };
111
+ }
112
+ }
113
+ parseVMResult(result, executionTime) {
114
+ let resultValue = null;
115
+ let success = false;
116
+ let status = 'Failed';
117
+ let errorMessage = undefined;
118
+ // Handle simple string results.
119
+ if (typeof result === 'string') {
120
+ if (result.startsWith('Ok(')) {
121
+ success = true;
122
+ status = 'Completed';
123
+ // Regex parsing for basic types
124
+ const u64Match = result.match(/Ok\(Some\(U64\((\d+)\)\)\)/);
125
+ if (u64Match)
126
+ resultValue = { type: 'U64', value: parseInt(u64Match[1]) };
127
+ // ... (Can expand primitive parsing if needed, but maintaining minimal logic here)
128
+ }
129
+ else if (result.startsWith('Err(')) {
130
+ success = false;
131
+ status = 'Failed';
132
+ errorMessage = result;
133
+ }
134
+ }
135
+ else {
136
+ // Handle Object result (WASM binding struct)
137
+ const resultStatus = typeof result.status === 'function' ? result.status() : result.status;
138
+ success = resultStatus === 'Completed';
139
+ status = resultStatus || 'Completed';
140
+ const resultErrorMessage = typeof result.error_message === 'function' ? result.error_message() : result.error_message;
141
+ errorMessage = resultErrorMessage;
142
+ if (result.has_result_value) {
143
+ const raw = result.get_result_value;
144
+ resultValue = typeof raw === 'bigint' ? Number(raw) : raw;
145
+ }
146
+ else if (result.result_value !== undefined) {
147
+ resultValue = result.result_value;
148
+ }
149
+ }
150
+ return {
151
+ success,
152
+ result: resultValue,
153
+ computeUnitsUsed: typeof result === 'object' ? result.compute_units_used : 0,
154
+ executionTime,
155
+ logs: [],
156
+ status,
157
+ stoppedAt: typeof result === 'object' ? result.stopped_at_opcode_name : undefined,
158
+ errorMessage
159
+ };
160
+ }
161
+ async executeFunction(bytecode, functionIndex, parameters, accounts) {
162
+ if (!this.initialized)
163
+ await this.initialize();
164
+ // Import BytecodeEncoder
165
+ const { BytecodeEncoder } = await import('../lib/bytecode-encoder.js');
166
+ // Pass typed parameters through to WASM encoder
167
+ const typedParams = parameters.map(param => ({
168
+ type: param.type,
169
+ value: param.value
170
+ }));
171
+ if (!ParameterEncoder || !ParameterEncoder.encode_execute) {
172
+ throw new Error('ParameterEncoder WASM binding not loaded or missing encode_execute');
173
+ }
174
+ // Use WASM binding to encode parameters (returns fixed-size encoded params)
175
+ const rawParams = ParameterEncoder.encode_execute(functionIndex, typedParams);
176
+ // EXECUTE_INSTRUCTION is 9 (matches on-chain protocol)
177
+ const discriminator = new Uint8Array([9]);
178
+ // Encode function index as u32 little endian
179
+ const functionIndexBytes = BytecodeEncoder.encodeU32(functionIndex);
180
+ // Assemble: [discriminator, function_index(u32), param_count(u32), rawParams...]
181
+ // Construct instruction:
182
+ const functionIndexArr = BytecodeEncoder.encodeU32(functionIndex); // 4 bytes
183
+ const paramCountArr = BytecodeEncoder.encodeU32(parameters.length);
184
+ const properInstructionData = new Uint8Array(discriminator.length + functionIndexArr.length + paramCountArr.length + rawParams.length);
185
+ properInstructionData.set(discriminator, 0);
186
+ properInstructionData.set(functionIndexArr, discriminator.length);
187
+ properInstructionData.set(paramCountArr, discriminator.length + functionIndexArr.length);
188
+ properInstructionData.set(rawParams, discriminator.length + functionIndexArr.length + paramCountArr.length);
189
+ return await this.execute({
190
+ bytecode,
191
+ inputData: properInstructionData,
192
+ accounts: accounts || []
193
+ });
194
+ }
195
+ async getState() {
196
+ if (!this.vm)
197
+ throw this.createVMError('No VM instance available');
198
+ return JSON.parse(this.vm.get_state());
199
+ }
200
+ async validateBytecode(bytecode) {
201
+ if (!this.initialized)
202
+ await this.initialize();
203
+ try {
204
+ const valid = FiveVMWasm.validate_bytecode(bytecode);
205
+ return { valid };
206
+ }
207
+ catch (error) {
208
+ return { valid: false, error: String(error) };
209
+ }
210
+ }
211
+ getVMConstants() {
212
+ if (!this.initialized)
213
+ throw this.createVMError('VM not initialized');
214
+ return JSON.parse(FiveVMWasm.get_constants());
215
+ }
216
+ convertAccountsToWasm(accounts) {
217
+ const wasmAccounts = [];
218
+ for (const account of accounts) {
219
+ try {
220
+ const wasmAccount = new WasmAccount(account.key, account.data || new Uint8Array(0), account.lamports || 0, account.isWritable || false, account.isSigner || false, account.owner || new Uint8Array(32));
221
+ wasmAccounts.push(wasmAccount);
222
+ }
223
+ catch (error) {
224
+ this.loggerwarn(`Failed to convert account ${account.key}: ${error}`);
225
+ }
226
+ }
227
+ return wasmAccounts;
228
+ }
229
+ loggerwarn(msg) {
230
+ if (this.logger && this.logger.warn)
231
+ this.logger.warn(msg);
232
+ else
233
+ console.warn(msg);
234
+ }
235
+ createVMError(message, cause) {
236
+ const error = new Error(message);
237
+ error.name = 'VMError';
238
+ error.code = 'VM_ERROR';
239
+ error.category = 'wasm';
240
+ if (cause) {
241
+ error.details = { cause: cause.message };
242
+ }
243
+ return error;
244
+ }
245
+ getVMInfo() {
246
+ return { version: '1.0.0', features: ['wasm', 'sdk'] };
247
+ }
248
+ isReady() { return this.initialized; }
249
+ cleanup() { this.vm = null; }
250
+ }