@prktsol/prkt 1.0.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.
Files changed (125) hide show
  1. package/.env.devnet.all-protocols.example +18 -0
  2. package/.env.devnet.autonomous.example +16 -0
  3. package/.env.devnet.jupiter.example +16 -0
  4. package/.env.devnet.kamino.example +17 -0
  5. package/.env.devnet.marinade.example +16 -0
  6. package/.env.devnet.orca.example +16 -0
  7. package/.env.devnet.raydium.example +17 -0
  8. package/.env.example +32 -0
  9. package/ARCHITECTURE.md +159 -0
  10. package/CLI.md +509 -0
  11. package/CLI_QUICKSTART.md +108 -0
  12. package/COMPATIBILITY.md +103 -0
  13. package/DEVNET_PROTOCOL_ADDRESSES.md +72 -0
  14. package/README.md +339 -0
  15. package/dist/agent/AgentManager.js +166 -0
  16. package/dist/agent/AgentRuntime.js +92 -0
  17. package/dist/agent/DecisionEngine.js +95 -0
  18. package/dist/agent/MockPriceFeed.js +13 -0
  19. package/dist/agent/intents/types.js +2 -0
  20. package/dist/agent/new-index.js +17 -0
  21. package/dist/agent/policyFactory.js +54 -0
  22. package/dist/agent/registry/AgentRegistry.js +16 -0
  23. package/dist/agent/runner/AgentRunner.js +266 -0
  24. package/dist/agent/strategies/MemoHeartbeatStrategy.js +15 -0
  25. package/dist/agent/strategies/SimpleScriptedTransferStrategy.js +27 -0
  26. package/dist/agent/strategies/TokenRebalancerStrategy.js +35 -0
  27. package/dist/agent/strategies/TreasuryDistributorStrategy.js +29 -0
  28. package/dist/agent/strategies/UniversalDeFiStrategy.js +19 -0
  29. package/dist/agent/types/AgentContext.js +2 -0
  30. package/dist/cli/index.js +1159 -0
  31. package/dist/cli/services/activityStore.js +42 -0
  32. package/dist/cli/services/agentRegistry.js +123 -0
  33. package/dist/cli/services/agentRuntime.js +55 -0
  34. package/dist/cli/services/storagePaths.js +64 -0
  35. package/dist/cli/services/strategyFactory.js +66 -0
  36. package/dist/cli/services/walletCrypto.js +120 -0
  37. package/dist/cli/services/walletRegistry.js +145 -0
  38. package/dist/cli/types.js +2 -0
  39. package/dist/cli/utils/completion.js +62 -0
  40. package/dist/cli/utils/output.js +44 -0
  41. package/dist/config/agentPolicies.js +37 -0
  42. package/dist/config/env.js +249 -0
  43. package/dist/config/policyPresets.js +105 -0
  44. package/dist/core/balances/BalanceService.js +34 -0
  45. package/dist/core/funding/DevnetFundingService.js +105 -0
  46. package/dist/core/idempotency/ExecutionIdempotencyGuard.js +100 -0
  47. package/dist/core/index.js +19 -0
  48. package/dist/core/rpc/RpcClient.js +45 -0
  49. package/dist/core/rpc/RpcFailoverClient.js +97 -0
  50. package/dist/core/tokens/TokenService.js +75 -0
  51. package/dist/core/transactions/PostTransactionVerifier.js +103 -0
  52. package/dist/core/transactions/TransactionService.js +104 -0
  53. package/dist/core/types/services.js +2 -0
  54. package/dist/core/wallet/WalletManager.js +120 -0
  55. package/dist/defi/DeFiCoordinator.js +93 -0
  56. package/dist/defi/DeFiExecutor.js +29 -0
  57. package/dist/defi/DeFiPolicyGuard.js +31 -0
  58. package/dist/defi/adapters/JupiterAdapter.js +25 -0
  59. package/dist/defi/adapters/KaminoAdapter.js +50 -0
  60. package/dist/defi/adapters/MarinadeAdapter.js +25 -0
  61. package/dist/defi/adapters/RaydiumAdapter.js +45 -0
  62. package/dist/defi/kamino/kaminoInstructionCompat.js +24 -0
  63. package/dist/defi/kamino/kaminoLiveConfig.js +60 -0
  64. package/dist/defi/kamino/loadKaminoMarketWithFallback.js +68 -0
  65. package/dist/defi/lp/LpInstructionBuilder.js +2 -0
  66. package/dist/defi/lp/RaydiumLpInstructionBuilder.js +100 -0
  67. package/dist/defi/lp/raydiumDevnetConfig.js +62 -0
  68. package/dist/defi/protocols.js +29 -0
  69. package/dist/defi/types.js +2 -0
  70. package/dist/defi/universal/UniversalDeFiOrchestrator.js +126 -0
  71. package/dist/defi/universal/adapters.js +73 -0
  72. package/dist/defi/universal/index.js +5 -0
  73. package/dist/defi/universal/liveExecutors.js +394 -0
  74. package/dist/defi/universal/types.js +2 -0
  75. package/dist/demo/scenarios/multiAgentDevnetScenario.js +170 -0
  76. package/dist/demo/scripts/runMultiAgentDevnetDemo.js +17 -0
  77. package/dist/dex/JupiterSwapClient.js +59 -0
  78. package/dist/dex/SwapExecutor.js +52 -0
  79. package/dist/index.js +22 -0
  80. package/dist/kora/KoraRpcClient.js +60 -0
  81. package/dist/kora/KoraSigner.js +57 -0
  82. package/dist/kora/gaslessDemo.js +18 -0
  83. package/dist/policy/PolicyGuard.js +158 -0
  84. package/dist/policy/emergencyLock.js +164 -0
  85. package/dist/policy/engine/PolicyEngine.js +237 -0
  86. package/dist/policy/errors.js +10 -0
  87. package/dist/policy/index.js +7 -0
  88. package/dist/policy/sandbox/SandboxExecutor.js +77 -0
  89. package/dist/policy/types/policy.js +2 -0
  90. package/dist/scripts/devnetFunding.js +28 -0
  91. package/dist/scripts/devnetWalletPreflight.js +16 -0
  92. package/dist/scripts/localnetCheck.js +27 -0
  93. package/dist/scripts/managedAgentWallet.js +81 -0
  94. package/dist/scripts/mode.js +6 -0
  95. package/dist/scripts/releaseReadiness.js +93 -0
  96. package/dist/scripts/runAgentUniversalDeFi.js +115 -0
  97. package/dist/scripts/runAutonomousAgentWalletDevnet.js +154 -0
  98. package/dist/scripts/runAutonomousPortfolioDevnet.js +390 -0
  99. package/dist/scripts/runBorrowStrategy.js +35 -0
  100. package/dist/scripts/runDeFiSuite.js +41 -0
  101. package/dist/scripts/runDemoRehearsal.js +111 -0
  102. package/dist/scripts/runDevnetWalletDemo.js +53 -0
  103. package/dist/scripts/runGaslessMemo.js +23 -0
  104. package/dist/scripts/runGaslessWalletDemo.js +60 -0
  105. package/dist/scripts/runKaminoDevnet.js +109 -0
  106. package/dist/scripts/runLpStrategy.js +32 -0
  107. package/dist/scripts/runMarinadeDevnet.js +97 -0
  108. package/dist/scripts/runOrcaLpDevnet.js +208 -0
  109. package/dist/scripts/runRaydiumLpDevnet.js +95 -0
  110. package/dist/scripts/runReleaseReadiness.js +22 -0
  111. package/dist/scripts/runStakeStrategy.js +33 -0
  112. package/dist/scripts/runStressTest.js +41 -0
  113. package/dist/scripts/runTradeLoop.js +53 -0
  114. package/dist/scripts/runUniversalDeFiDemo.js +84 -0
  115. package/dist/scripts/runYieldStrategy.js +33 -0
  116. package/dist/scripts/runtimeFactory.js +27 -0
  117. package/dist/scripts/shared.js +24 -0
  118. package/dist/scripts/simulateAttack.js +40 -0
  119. package/dist/scripts/simulateSwarm.js +106 -0
  120. package/dist/simulation/attack.js +30 -0
  121. package/dist/solana/programs.js +9 -0
  122. package/dist/spl/TokenWallet.js +65 -0
  123. package/dist/types/policy.js +2 -0
  124. package/dist/wallet/WalletManager.js +5 -0
  125. package/package.json +99 -0
@@ -0,0 +1,164 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getEmergencyLockStatus = getEmergencyLockStatus;
7
+ const crypto_1 = require("crypto");
8
+ const fs_1 = require("fs");
9
+ const path_1 = __importDefault(require("path"));
10
+ const EMERGENCY_FLAG_ENV = "POLICY_EMERGENCY_LOCK";
11
+ const EMERGENCY_LOCK_PATH_ENV = "POLICY_EMERGENCY_LOCK_PATH";
12
+ const EMERGENCY_COMMAND_PATH_ENV = "POLICY_EMERGENCY_COMMAND_PATH";
13
+ const EMERGENCY_COMMAND_SECRET_ENV = "POLICY_EMERGENCY_ADMIN_SECRET";
14
+ const EMERGENCY_COMMAND_MAX_AGE_SECONDS_ENV = "POLICY_EMERGENCY_MAX_AGE_SECONDS";
15
+ const DEFAULT_EMERGENCY_LOCK_PATH = path_1.default.join(process.cwd(), "emergency_lock.json");
16
+ const DEFAULT_EMERGENCY_COMMAND_PATH = path_1.default.join(process.cwd(), "emergency_command.json");
17
+ function getEmergencyLockStatus() {
18
+ const flag = process.env[EMERGENCY_FLAG_ENV]?.trim().toLowerCase();
19
+ if (flag === "true" || flag === "1") {
20
+ return {
21
+ locked: true,
22
+ reason: `Human-in-the-loop Override engaged via ${EMERGENCY_FLAG_ENV}.`
23
+ };
24
+ }
25
+ const signedCommandStatus = getSignedEmergencyCommandStatus();
26
+ if (signedCommandStatus.locked) {
27
+ return signedCommandStatus;
28
+ }
29
+ const emergencyLockPath = getEmergencyLockPath();
30
+ if (!(0, fs_1.existsSync)(emergencyLockPath)) {
31
+ return {
32
+ locked: false,
33
+ reason: null
34
+ };
35
+ }
36
+ try {
37
+ const raw = (0, fs_1.readFileSync)(emergencyLockPath, "utf8").trim();
38
+ if (raw.length === 0) {
39
+ return {
40
+ locked: true,
41
+ reason: `Human-in-the-loop Override engaged via ${path_1.default.basename(emergencyLockPath)}.`
42
+ };
43
+ }
44
+ const parsed = JSON.parse(raw);
45
+ const enabled = parsed.enabled ?? parsed.locked ?? false;
46
+ if (enabled) {
47
+ return {
48
+ locked: true,
49
+ reason: parsed.reason?.trim() ||
50
+ `Human-in-the-loop Override engaged via ${path_1.default.basename(emergencyLockPath)}.`
51
+ };
52
+ }
53
+ return {
54
+ locked: false,
55
+ reason: null
56
+ };
57
+ }
58
+ catch {
59
+ return {
60
+ locked: true,
61
+ reason: `Human-in-the-loop Override engaged because ${path_1.default.basename(emergencyLockPath)} is invalid.`
62
+ };
63
+ }
64
+ }
65
+ function getEmergencyLockPath() {
66
+ const override = process.env[EMERGENCY_LOCK_PATH_ENV]?.trim();
67
+ if (!override) {
68
+ return DEFAULT_EMERGENCY_LOCK_PATH;
69
+ }
70
+ return path_1.default.isAbsolute(override) ? override : path_1.default.join(process.cwd(), override);
71
+ }
72
+ function getEmergencyCommandPath() {
73
+ const override = process.env[EMERGENCY_COMMAND_PATH_ENV]?.trim();
74
+ if (!override) {
75
+ return DEFAULT_EMERGENCY_COMMAND_PATH;
76
+ }
77
+ return path_1.default.isAbsolute(override) ? override : path_1.default.join(process.cwd(), override);
78
+ }
79
+ function getEmergencyCommandMaxAgeMs() {
80
+ const raw = process.env[EMERGENCY_COMMAND_MAX_AGE_SECONDS_ENV]?.trim();
81
+ if (!raw) {
82
+ return 10 * 60 * 1000;
83
+ }
84
+ const parsed = Number(raw);
85
+ if (!Number.isFinite(parsed) || parsed <= 0) {
86
+ return 10 * 60 * 1000;
87
+ }
88
+ return parsed * 1000;
89
+ }
90
+ function getSignedEmergencyCommandStatus() {
91
+ const commandPath = getEmergencyCommandPath();
92
+ if (!(0, fs_1.existsSync)(commandPath)) {
93
+ return {
94
+ locked: false,
95
+ reason: null
96
+ };
97
+ }
98
+ const secret = process.env[EMERGENCY_COMMAND_SECRET_ENV]?.trim();
99
+ if (!secret) {
100
+ return {
101
+ locked: true,
102
+ reason: `Human-in-the-loop Override engaged because ${path_1.default.basename(commandPath)} exists but ${EMERGENCY_COMMAND_SECRET_ENV} is not configured.`
103
+ };
104
+ }
105
+ try {
106
+ const raw = (0, fs_1.readFileSync)(commandPath, "utf8").trim();
107
+ if (!raw) {
108
+ return {
109
+ locked: true,
110
+ reason: `Human-in-the-loop Override engaged because ${path_1.default.basename(commandPath)} is empty.`
111
+ };
112
+ }
113
+ const command = JSON.parse(raw);
114
+ const payload = `${command.enabled}:${command.issuedAtIso8601}:${command.reason ?? ""}`;
115
+ if (!verifySignature(payload, command.signature, secret)) {
116
+ return {
117
+ locked: true,
118
+ reason: `Human-in-the-loop Override engaged because ${path_1.default.basename(commandPath)} signature verification failed.`
119
+ };
120
+ }
121
+ const issuedAt = Date.parse(command.issuedAtIso8601);
122
+ if (Number.isNaN(issuedAt)) {
123
+ return {
124
+ locked: true,
125
+ reason: `Human-in-the-loop Override engaged because ${path_1.default.basename(commandPath)} timestamp is invalid.`
126
+ };
127
+ }
128
+ if (Date.now() - issuedAt > getEmergencyCommandMaxAgeMs()) {
129
+ return {
130
+ locked: true,
131
+ reason: `Human-in-the-loop Override engaged because ${path_1.default.basename(commandPath)} is stale.`
132
+ };
133
+ }
134
+ if (command.enabled) {
135
+ return {
136
+ locked: true,
137
+ reason: command.reason?.trim() ||
138
+ `Human-in-the-loop Override engaged via signed ${path_1.default.basename(commandPath)}.`
139
+ };
140
+ }
141
+ return {
142
+ locked: false,
143
+ reason: null
144
+ };
145
+ }
146
+ catch {
147
+ return {
148
+ locked: true,
149
+ reason: `Human-in-the-loop Override engaged because ${path_1.default.basename(commandPath)} is invalid.`
150
+ };
151
+ }
152
+ }
153
+ function verifySignature(payload, signature, secret) {
154
+ if (!signature || !secret) {
155
+ return false;
156
+ }
157
+ const expected = (0, crypto_1.createHmac)("sha256", secret).update(payload).digest("hex");
158
+ const expectedBytes = Buffer.from(expected, "utf8");
159
+ const providedBytes = Buffer.from(signature, "utf8");
160
+ if (expectedBytes.length !== providedBytes.length) {
161
+ return false;
162
+ }
163
+ return (0, crypto_1.timingSafeEqual)(expectedBytes, providedBytes);
164
+ }
@@ -0,0 +1,237 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PolicyEngine = void 0;
4
+ const spl_token_1 = require("@solana/spl-token");
5
+ const web3_js_1 = require("@solana/web3.js");
6
+ const emergencyLock_1 = require("../emergencyLock");
7
+ const programs_1 = require("../../solana/programs");
8
+ class PolicyEngine {
9
+ policyConfig;
10
+ sessionStart = Date.now();
11
+ txCountSession = 0;
12
+ perDayCounts = new Map();
13
+ auditLog = [];
14
+ constructor(policyConfig) {
15
+ this.policyConfig = policyConfig;
16
+ }
17
+ inspect(transaction, context) {
18
+ const reasons = [];
19
+ const decompiledMessage = web3_js_1.TransactionMessage.decompile(transaction.message);
20
+ let totalSolSpendLamports = 0n;
21
+ let totalSplSpendRaw = 0n;
22
+ const programsSeen = new Set();
23
+ const mintsSeen = new Set();
24
+ let hasUncheckedSplSpend = false;
25
+ const now = Date.now();
26
+ const emergencyStatus = (0, emergencyLock_1.getEmergencyLockStatus)();
27
+ if (emergencyStatus.locked) {
28
+ reasons.push(emergencyStatus.reason ?? "Human-in-the-loop Override engaged.");
29
+ }
30
+ const sessionExpiry = Date.parse(this.policyConfig.sessionExpiresAtIso8601);
31
+ if (Number.isNaN(sessionExpiry) || now > sessionExpiry) {
32
+ reasons.push("session expired");
33
+ }
34
+ const dayKey = new Date(now).toISOString().slice(0, 10);
35
+ const todaysCount = this.perDayCounts.get(dayKey) ?? 0;
36
+ if (this.txCountSession >= this.policyConfig.limits.maxTransactionsPerSession) {
37
+ reasons.push("max transactions per session exceeded");
38
+ }
39
+ if (todaysCount >= this.policyConfig.limits.maxTransactionsPerDay) {
40
+ reasons.push("max transactions per day exceeded");
41
+ }
42
+ for (const instruction of decompiledMessage.instructions) {
43
+ const programId = instruction.programId.toBase58();
44
+ programsSeen.add(programId);
45
+ if (!this.policyConfig.rules.allowedProgramIds.includes(programId)) {
46
+ reasons.push(`program not allowed: ${programId}`);
47
+ if (this.policyConfig.rules.denyUnknownInstructionsByDefault) {
48
+ continue;
49
+ }
50
+ }
51
+ const blockedVectorReason = this.detectBlockedSpendVector(instruction);
52
+ if (blockedVectorReason) {
53
+ reasons.push(blockedVectorReason);
54
+ continue;
55
+ }
56
+ const spend = this.tryDecodeSpend(instruction);
57
+ if (!spend) {
58
+ if (this.policyConfig.rules.denyUnknownInstructionsByDefault &&
59
+ !this.policyConfig.rules.allowOpaqueProgramIds?.includes(programId) &&
60
+ !this.isKnownNonSpendInstruction(programId)) {
61
+ reasons.push(`opaque instruction blocked: ${programId}`);
62
+ }
63
+ continue;
64
+ }
65
+ if (spend.kind === "sol") {
66
+ totalSolSpendLamports += spend.amount;
67
+ }
68
+ else {
69
+ totalSplSpendRaw += spend.amount;
70
+ hasUncheckedSplSpend ||= !spend.mintVerified;
71
+ if (spend.mint) {
72
+ mintsSeen.add(spend.mint.toBase58());
73
+ }
74
+ }
75
+ if (this.policyConfig.rules.allowedTransferDestinations &&
76
+ this.policyConfig.rules.allowedTransferDestinations.length > 0) {
77
+ const destination = spend.destination.toBase58();
78
+ if (!this.policyConfig.rules.allowedTransferDestinations.includes(destination)) {
79
+ reasons.push(`destination not allowlisted: ${destination}`);
80
+ }
81
+ }
82
+ }
83
+ if (totalSolSpendLamports > BigInt(this.policyConfig.limits.maxSolPerTxLamports)) {
84
+ reasons.push("max SOL per transaction exceeded");
85
+ }
86
+ if (totalSplSpendRaw > this.policyConfig.limits.maxSplPerTxRawAmount) {
87
+ reasons.push("max SPL per transaction exceeded");
88
+ }
89
+ if (this.policyConfig.rules.allowedMintAddresses.length > 0) {
90
+ if (hasUncheckedSplSpend) {
91
+ reasons.push("unchecked SPL transfer cannot be validated against mint allowlist");
92
+ }
93
+ for (const seenMint of mintsSeen) {
94
+ if (!this.policyConfig.rules.allowedMintAddresses.includes(seenMint)) {
95
+ reasons.push(`mint not allowed: ${seenMint}`);
96
+ }
97
+ }
98
+ }
99
+ if (this.policyConfig.rules.rejectSuspiciousBalanceDeltas &&
100
+ context?.expectedBalanceDeltas &&
101
+ context.expectedBalanceDeltas.some((delta) => delta.maxNegativeDeltaRaw < 0n)) {
102
+ reasons.push("invalid expected balance delta");
103
+ }
104
+ const allowed = reasons.length === 0;
105
+ const result = {
106
+ allowed,
107
+ reasons,
108
+ details: {
109
+ totalSolSpendLamports,
110
+ totalSplSpendRaw,
111
+ programsSeen: Array.from(programsSeen),
112
+ mintsSeen: Array.from(mintsSeen)
113
+ }
114
+ };
115
+ this.auditLog.push({
116
+ agentId: this.policyConfig.agentId,
117
+ timestampIso8601: new Date().toISOString(),
118
+ decision: allowed ? "allow" : "deny",
119
+ reason: allowed ? "policy checks passed" : reasons.join("; ")
120
+ });
121
+ return result;
122
+ }
123
+ recordBroadcast(signature) {
124
+ this.txCountSession += 1;
125
+ const dayKey = new Date().toISOString().slice(0, 10);
126
+ this.perDayCounts.set(dayKey, (this.perDayCounts.get(dayKey) ?? 0) + 1);
127
+ this.auditLog.push({
128
+ agentId: this.policyConfig.agentId,
129
+ timestampIso8601: new Date().toISOString(),
130
+ decision: "allow",
131
+ reason: "broadcasted",
132
+ txSignature: signature
133
+ });
134
+ }
135
+ getAuditTrail() {
136
+ return [...this.auditLog];
137
+ }
138
+ getSessionAgeMs() {
139
+ return Date.now() - this.sessionStart;
140
+ }
141
+ tryDecodeSpend(instruction) {
142
+ if (instruction.programId.equals(web3_js_1.SystemProgram.programId)) {
143
+ try {
144
+ const transfer = web3_js_1.SystemInstruction.decodeTransfer(instruction);
145
+ return {
146
+ kind: "sol",
147
+ amount: transfer.lamports,
148
+ destination: transfer.toPubkey
149
+ };
150
+ }
151
+ catch {
152
+ return null;
153
+ }
154
+ }
155
+ try {
156
+ const transfer = (0, spl_token_1.decodeTransferInstruction)(instruction);
157
+ return {
158
+ kind: "spl",
159
+ amount: BigInt(transfer.data.amount.toString()),
160
+ destination: transfer.keys.destination.pubkey,
161
+ mint: null,
162
+ mintVerified: false
163
+ };
164
+ }
165
+ catch {
166
+ // ignore
167
+ }
168
+ try {
169
+ const transfer = (0, spl_token_1.decodeTransferCheckedInstruction)(instruction);
170
+ return {
171
+ kind: "spl",
172
+ amount: BigInt(transfer.data.amount.toString()),
173
+ destination: transfer.keys.destination.pubkey,
174
+ mint: transfer.keys.mint.pubkey,
175
+ mintVerified: true
176
+ };
177
+ }
178
+ catch {
179
+ // ignore
180
+ }
181
+ return null;
182
+ }
183
+ detectBlockedSpendVector(instruction) {
184
+ try {
185
+ const approve = (0, spl_token_1.decodeApproveInstruction)(instruction);
186
+ return `delegate approval blocked: ${approve.keys.delegate.pubkey.toBase58()}`;
187
+ }
188
+ catch {
189
+ // ignore
190
+ }
191
+ try {
192
+ const approveChecked = (0, spl_token_1.decodeApproveCheckedInstruction)(instruction);
193
+ return `delegate approval blocked: ${approveChecked.keys.delegate.pubkey.toBase58()}`;
194
+ }
195
+ catch {
196
+ // ignore
197
+ }
198
+ try {
199
+ const revoke = (0, spl_token_1.decodeRevokeInstruction)(instruction);
200
+ return `delegate revoke requires explicit approval: ${revoke.keys.account.pubkey.toBase58()}`;
201
+ }
202
+ catch {
203
+ // ignore
204
+ }
205
+ try {
206
+ const closeAccount = (0, spl_token_1.decodeCloseAccountInstruction)(instruction);
207
+ const destination = closeAccount.keys.destination.pubkey.toBase58();
208
+ if (this.policyConfig.rules.allowedCloseAccountDestinations?.includes(destination) ?? false) {
209
+ return null;
210
+ }
211
+ return `close-account drain blocked: ${closeAccount.keys.destination.pubkey.toBase58()}`;
212
+ }
213
+ catch {
214
+ // ignore
215
+ }
216
+ try {
217
+ const setAuthority = (0, spl_token_1.decodeSetAuthorityInstruction)(instruction);
218
+ if (setAuthority.data.authorityType === spl_token_1.AuthorityType.AccountOwner ||
219
+ setAuthority.data.authorityType === spl_token_1.AuthorityType.CloseAccount ||
220
+ setAuthority.data.authorityType === spl_token_1.AuthorityType.MintTokens) {
221
+ return `authority change blocked: ${spl_token_1.AuthorityType[setAuthority.data.authorityType]}`;
222
+ }
223
+ }
224
+ catch {
225
+ // ignore
226
+ }
227
+ return null;
228
+ }
229
+ isKnownNonSpendInstruction(programId) {
230
+ return (programId === web3_js_1.SystemProgram.programId.toBase58() ||
231
+ programId === programs_1.TOKEN_PROGRAM_ID.toBase58() ||
232
+ programId === programs_1.ASSOCIATED_TOKEN_PROGRAM_ID.toBase58() ||
233
+ programId === programs_1.MEMO_PROGRAM_ID.toBase58() ||
234
+ (this.policyConfig.rules.allowOpaqueProgramIds?.includes(programId) ?? false));
235
+ }
236
+ }
237
+ exports.PolicyEngine = PolicyEngine;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SecurityViolationError = void 0;
4
+ class SecurityViolationError extends Error {
5
+ constructor(message) {
6
+ super(message);
7
+ this.name = "SecurityViolationError";
8
+ }
9
+ }
10
+ exports.SecurityViolationError = SecurityViolationError;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SandboxExecutor = exports.PolicyEngine = void 0;
4
+ var PolicyEngine_1 = require("./engine/PolicyEngine");
5
+ Object.defineProperty(exports, "PolicyEngine", { enumerable: true, get: function () { return PolicyEngine_1.PolicyEngine; } });
6
+ var SandboxExecutor_1 = require("./sandbox/SandboxExecutor");
7
+ Object.defineProperty(exports, "SandboxExecutor", { enumerable: true, get: function () { return SandboxExecutor_1.SandboxExecutor; } });
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SandboxExecutor = void 0;
4
+ class SandboxExecutor {
5
+ policyEngine;
6
+ transactionService;
7
+ approvalMode;
8
+ approvalCallback;
9
+ constructor(policyEngine, transactionService, approvalMode, approvalCallback) {
10
+ this.policyEngine = policyEngine;
11
+ this.transactionService = transactionService;
12
+ this.approvalMode = approvalMode;
13
+ this.approvalCallback = approvalCallback;
14
+ }
15
+ async executePreparedTransaction(input) {
16
+ const inspection = this.policyEngine.inspect(input.transaction, input.inspectionContext);
17
+ if (!inspection.allowed) {
18
+ return {
19
+ inspection,
20
+ signature: null,
21
+ simulationLogs: null
22
+ };
23
+ }
24
+ const simulation = await this.transactionService.simulate(input.transaction);
25
+ if (simulation.err) {
26
+ return {
27
+ inspection: {
28
+ ...inspection,
29
+ allowed: false,
30
+ reasons: [...inspection.reasons, "simulation failed"]
31
+ },
32
+ signature: null,
33
+ simulationLogs: simulation.logs
34
+ };
35
+ }
36
+ if (this.approvalMode === "live") {
37
+ if (!this.approvalCallback) {
38
+ return {
39
+ inspection: {
40
+ ...inspection,
41
+ allowed: false,
42
+ reasons: [...inspection.reasons, "live approval callback missing"]
43
+ },
44
+ signature: null,
45
+ simulationLogs: simulation.logs
46
+ };
47
+ }
48
+ const approved = await this.approvalCallback({
49
+ agentId: this.policyEngine.getAuditTrail().at(-1)?.agentId ?? "unknown-agent",
50
+ inspection,
51
+ transaction: input.transaction
52
+ });
53
+ if (!approved) {
54
+ return {
55
+ inspection: {
56
+ ...inspection,
57
+ allowed: false,
58
+ reasons: [...inspection.reasons, "manual approval rejected"]
59
+ },
60
+ signature: null,
61
+ simulationLogs: simulation.logs
62
+ };
63
+ }
64
+ }
65
+ const send = await this.transactionService.sendAndConfirm({
66
+ confirmationStrategy: input.confirmationStrategy,
67
+ transaction: input.transaction
68
+ });
69
+ this.policyEngine.recordBroadcast(send.signature);
70
+ return {
71
+ inspection,
72
+ signature: send.signature,
73
+ simulationLogs: simulation.logs
74
+ };
75
+ }
76
+ }
77
+ exports.SandboxExecutor = SandboxExecutor;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ensureWalletHasMinimumSol = ensureWalletHasMinimumSol;
4
+ const SOL_BALANCE_TOLERANCE = 0.000001;
5
+ async function ensureWalletHasMinimumSol(input) {
6
+ const funding = await input.fundingService.ensureMinimumSol({
7
+ airdropAmountSol: 1,
8
+ balanceService: input.balanceService,
9
+ minimumSol: input.minimumSol,
10
+ recipient: input.publicKey
11
+ });
12
+ if (!funding) {
13
+ return;
14
+ }
15
+ const updatedBalance = await input.fundingService.waitForMinimumBalance({
16
+ balanceService: input.balanceService,
17
+ minimumSol: input.minimumSol,
18
+ recipient: input.publicKey
19
+ });
20
+ if (updatedBalance + SOL_BALANCE_TOLERANCE >= input.minimumSol) {
21
+ console.log(`Funding source: ${funding.source}`);
22
+ console.log(`Funding signature: ${funding.signature}`);
23
+ console.log(`SOL after funding: ${updatedBalance.toFixed(4)}`);
24
+ return;
25
+ }
26
+ const finalBalance = await input.balanceService.getSolBalance(input.publicKey);
27
+ throw new Error(`Funding failed: wallet balance is ${finalBalance.toFixed(4)} SOL after ${funding.source}, below required ${input.minimumSol.toFixed(4)} SOL.`);
28
+ }
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MAX_STARTING_WSOL_FOR_WRAP_DEMO = exports.REQUIRED_STARTING_SOL = void 0;
4
+ exports.assertDeterministicWrapPreflight = assertDeterministicWrapPreflight;
5
+ exports.REQUIRED_STARTING_SOL = 0.12;
6
+ exports.MAX_STARTING_WSOL_FOR_WRAP_DEMO = 0.0099;
7
+ function assertDeterministicWrapPreflight(input) {
8
+ const requiredStartingSol = input.requiredStartingSol ?? exports.REQUIRED_STARTING_SOL;
9
+ const maxStartingWsol = input.maxStartingWsol ?? exports.MAX_STARTING_WSOL_FOR_WRAP_DEMO;
10
+ if (input.startingSolBalance < requiredStartingSol) {
11
+ throw new Error(`Preflight failed: wallet has ${input.startingSolBalance.toFixed(4)} SOL. Fund at least ${requiredStartingSol.toFixed(2)} SOL on devnet before running wallet:devnet.`);
12
+ }
13
+ if (input.startingWsolBalance > maxStartingWsol) {
14
+ throw new Error(`Preflight failed: wallet already has ${input.startingWsolBalance.toFixed(4)} wSOL. For a deterministic wrap demo, reduce wSOL below ${maxStartingWsol.toFixed(4)} and rerun.`);
15
+ }
16
+ }
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const web3_js_1 = require("@solana/web3.js");
4
+ const env_1 = require("../config/env");
5
+ const WalletManager_1 = require("../wallet/WalletManager");
6
+ async function main() {
7
+ try {
8
+ const rpcUrl = (0, env_1.getRpcUrl)();
9
+ console.log(`RPC URL: ${rpcUrl}`);
10
+ const walletManager = WalletManager_1.WalletManager.loadConfigured();
11
+ console.log(`Wallet pubkey: ${walletManager.publicKey.toBase58()}`);
12
+ console.log(`Wallet source: ${walletManager.source}`);
13
+ const connection = new web3_js_1.Connection(rpcUrl, "confirmed");
14
+ const balance = await connection.getBalance(walletManager.publicKey);
15
+ console.log(`Balance: ${balance / 1_000_000_000} SOL (${balance} lamports)`);
16
+ console.log("Localnet connectivity check PASSED.");
17
+ }
18
+ catch (error) {
19
+ const message = error instanceof Error ? error.message : String(error);
20
+ console.error(`Localnet check FAILED: ${message}`);
21
+ if (error instanceof Error && error.stack) {
22
+ console.error(error.stack);
23
+ }
24
+ process.exitCode = 1;
25
+ }
26
+ }
27
+ main();
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getManagedAgentName = getManagedAgentName;
4
+ exports.getManagedOwnerId = getManagedOwnerId;
5
+ exports.resolveManagedAgentWallet = resolveManagedAgentWallet;
6
+ exports.ensureManagedAgentWalletFunding = ensureManagedAgentWalletFunding;
7
+ exports.logManagedAgentWallet = logManagedAgentWallet;
8
+ const agentRegistry_1 = require("../cli/services/agentRegistry");
9
+ const walletRegistry_1 = require("../cli/services/walletRegistry");
10
+ const devnetFunding_1 = require("./devnetFunding");
11
+ const AGENT_NAME_ENV = "PRKT_AGENT_NAME";
12
+ const OWNER_ID_ENV = "PRKT_OWNER_ID";
13
+ function getManagedAgentName(input) {
14
+ const configuredName = input.env?.[AGENT_NAME_ENV]?.trim();
15
+ if (configuredName) {
16
+ return configuredName;
17
+ }
18
+ return input.defaultAgentName;
19
+ }
20
+ function getManagedOwnerId(env) {
21
+ const configuredOwnerId = env?.[OWNER_ID_ENV]?.trim();
22
+ return configuredOwnerId && configuredOwnerId.length > 0 ? configuredOwnerId : undefined;
23
+ }
24
+ function resolveManagedAgentWallet(input) {
25
+ const walletRegistry = input.walletRegistry ?? new walletRegistry_1.WalletRegistry();
26
+ const agentRegistry = input.agentRegistry ?? new agentRegistry_1.AgentRegistryStore(walletRegistry);
27
+ let wallet = walletRegistry.find(input.agentName);
28
+ let recoveryKey = null;
29
+ const createdWallet = !wallet;
30
+ if (!wallet) {
31
+ const provisioned = walletRegistry.create(input.agentName);
32
+ wallet = provisioned.record;
33
+ recoveryKey = provisioned.recoveryKey;
34
+ }
35
+ let agent = agentRegistry.find(input.agentName);
36
+ const createdAgent = !agent;
37
+ if (!agent) {
38
+ agent = agentRegistry.createAgent({
39
+ agentId: input.agentName,
40
+ ownerId: input.ownerId,
41
+ walletName: wallet.name
42
+ });
43
+ }
44
+ return {
45
+ agent,
46
+ agentName: agent.name,
47
+ createdAgent,
48
+ createdWallet,
49
+ recoveryKey,
50
+ wallet,
51
+ walletManager: walletRegistry.toWalletManager(wallet.name)
52
+ };
53
+ }
54
+ async function ensureManagedAgentWalletFunding(input) {
55
+ await (0, devnetFunding_1.ensureWalletHasMinimumSol)({
56
+ balanceService: input.balanceService,
57
+ fundingService: input.fundingService,
58
+ minimumSol: input.minimumSol,
59
+ publicKey: input.publicKey
60
+ });
61
+ }
62
+ function logManagedAgentWallet(input) {
63
+ console.log(`Agent: ${input.agent.name}`);
64
+ if (input.agent.ownerId) {
65
+ console.log(`Owner: ${input.agent.ownerId}`);
66
+ }
67
+ console.log(`Wallet: ${input.wallet.publicKey}`);
68
+ console.log(`Wallet source: managed-registry`);
69
+ if (input.createdWallet) {
70
+ console.log("Wallet provisioning: created persistent wallet for agent");
71
+ }
72
+ else {
73
+ console.log("Wallet provisioning: reused persistent wallet for agent");
74
+ }
75
+ if (input.createdAgent) {
76
+ console.log("Agent provisioning: created agent-to-wallet assignment");
77
+ }
78
+ if (input.recoveryKey) {
79
+ console.log(`Recovery key: ${input.recoveryKey}`);
80
+ }
81
+ }
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.printDemoMode = printDemoMode;
4
+ function printDemoMode(mode, detail) {
5
+ console.log(`Mode: ${mode} (${detail})`);
6
+ }