@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,72 @@
1
+ # Devnet Protocol Addresses
2
+
3
+ This file records the devnet protocol values that were verified or inferred for the current repo.
4
+
5
+ ## Kamino
6
+
7
+ Current devnet values from Kamino's public API / official SDK surface:
8
+
9
+ - Program ID: `KLend2g3cP87fffoy8q1mQqGKjrxjC8boSyAYavgmjD`
10
+ - Primary market from Kamino public API: `ARVAgHAZiNGCbZ8Cb4BitwZoNQ8eBWsk7ZeinPgmNjgi`
11
+
12
+ Repo test config written to `kamino_live.json`:
13
+
14
+ - `programId`: `KLend2g3cP87fffoy8q1mQqGKjrxjC8boSyAYavgmjD`
15
+ - `marketAddress`: `HqCoqWT42Qdg1fbsWFo6TNCkH6eSY2MtxHFEkPoBvCHm`
16
+ - `depositMint`: `So11111111111111111111111111111111111111112`
17
+ - `borrowMint`: `4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU`
18
+
19
+ Notes:
20
+
21
+ - `programId` and the primary devnet market were verified from Kamino's public market API for `env=devnet`.
22
+ - The repo points `kamino_live.json` at `HqCo...` because that market exposes canonical `So111...` and devnet USDC mints, which lets the autonomous wallet attempt a real Kamino deposit/borrow path on a generated wallet.
23
+ - Current devnet status is still not fully live-demoable: the selected Kamino market fails reserve refresh on-chain (`ReserveStale` / `InvalidOracleConfig`), so the autonomous portfolio demo now falls back to simulated Kamino intents after logging the live failure details.
24
+
25
+ ## Raydium
26
+
27
+ Verified from official Raydium docs:
28
+
29
+ - Legacy AMM v4 devnet program: `DRaya7Kj3aMWQSy19kSjvmuwq9docCHofyP9kanQGaav`
30
+ - CPMM devnet program: `DRaycpLY18LhpbydsBWbVJtxpNv9oXPgjRSfpF2bWpYb`
31
+ - CLMM devnet program: `DRayAUgENGQBKVaX8owNhgzkEDyoHTGVEGHVJT1E9pfH`
32
+
33
+ Repo note:
34
+
35
+ - This repo's `raydium_lp.devnet.json` schema matches the legacy AMM/OpenBook style account set (`openOrders`, `targetOrders`, `marketEventQueue`), so the likely program for this repo is `DRaya7Kj3aMWQSy19kSjvmuwq9docCHofyP9kanQGaav`.
36
+ - Official Raydium docs do not provide a full ready-made devnet pool account set for this exact schema. You still need a real pool's:
37
+ - `poolId`
38
+ - `authority`
39
+ - `baseVault`
40
+ - `quoteVault`
41
+ - `openOrders`
42
+ - `targetOrders`
43
+ - `marketId`
44
+ - `marketEventQueue`
45
+ - `lpMint`
46
+
47
+ ## Orca
48
+
49
+ Verified from official Orca docs:
50
+
51
+ - Whirlpool program: `whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc`
52
+ - Devnet WhirlpoolConfig: `FcrweFY1G9HJAHG5inkGB6pKg1HZ6x9UC2WioAfWrGkR`
53
+ - Devnet WhirlpoolConfigExtension: `475EJ7JqnRpVLoFVzp2ruEYvWWMCf6Z8KMWRujtXXNSU`
54
+ - Devnet concentrated `SOL/devUSDC` token mints:
55
+ - `So11111111111111111111111111111111111111112`
56
+ - `BRjpCHtyQLNCo8gqRUr8jtdAj5AjPYQaoqbvcZiHok1k`
57
+ - Public concentrated pool parameters used by the repo's Orca demo:
58
+ - `tickSpacing = 64`
59
+ - whirlpool PDA derived from the program/config/token-pair/tick-spacing combination above
60
+
61
+ Repo note:
62
+
63
+ - `src/scripts/runOrcaLpDevnet.ts` computes the devnet pool PDA at runtime and opens a one-sided SOL position.
64
+ - This path avoids the splash pool example and uses the public concentrated pool so the demo can LP with SOL only.
65
+
66
+ ## Jupiter
67
+
68
+ Official Jupiter docs state the core programs are deployed on Solana mainnet. Do not rely on a Jupiter "devnet address" story for submission.
69
+
70
+ ## Marinade
71
+
72
+ No manual protocol address file is required in this repo. The Marinade SDK resolves the cluster-side program/state addresses for the live staking path.
package/README.md ADDED
@@ -0,0 +1,339 @@
1
+ # PRKT — Operator Runbook
2
+
3
+ Policy-enforced agentic wallet runtime for Solana. Agents decide intent; policy, simulation, and execution controls decide what actually executes.
4
+
5
+ Canonical full documentation for users and website publishing:
6
+ - [FULL_DOCUMENTATION.md](./FULL_DOCUMENTATION.md)
7
+
8
+ ## 5-Minute Devnet Quickstart
9
+
10
+ ### 1. Install
11
+
12
+ Published CLI:
13
+
14
+ ```bash
15
+ npm install -g @prktsol/prkt
16
+ prkt --help
17
+ prkt init
18
+ ```
19
+
20
+ From source:
21
+
22
+ ```bash
23
+ git clone <repo-url> && cd PRKT
24
+ npm install
25
+ npm run cli -- --help
26
+ npm run cli -- init
27
+ ```
28
+
29
+ ### 2. Configure environment
30
+
31
+ ```bash
32
+ cp .env.example .env
33
+ ```
34
+
35
+ Protocol-specific presets are available if you want a faster start:
36
+ - `.env.devnet.autonomous.example`
37
+ - `.env.devnet.marinade.example`
38
+ - `.env.devnet.jupiter.example`
39
+ - `.env.devnet.kamino.example`
40
+ - `.env.devnet.orca.example`
41
+ - `.env.devnet.raydium.example`
42
+ - `.env.devnet.all-protocols.example`
43
+
44
+ Edit `.env`:
45
+
46
+ | Variable | Required | Default | What to set |
47
+ |----------|----------|---------|-------------|
48
+ | `SOLANA_RPC_URL` | Yes | `https://api.devnet.solana.com` | Devnet RPC endpoint |
49
+ | `SOLANA_RPC_FALLBACK_URL` | No | none | Optional secondary RPC for failover |
50
+ | `AGENT_PRIVATE_KEY` | Optional | `[]` | Only for operator-funded wallet demos; the autonomous devnet demo generates its own wallet |
51
+ | `DEVNET_TREASURY_PRIVATE_KEY` | No | `[]` | Optional funded devnet treasury used as an internal faucet for generated agent wallets |
52
+ | `USDC_MINT` | No | devnet USDC | Override only if using a custom mint |
53
+ | `KORA_MOCK_MODE` | No | `true` | Set `false` for live Kora gasless signing |
54
+ | `ENABLE_LIVE_SWAP_PATH` | No | `false` | Set `true` for live Jupiter swaps |
55
+ | `ENABLE_LIVE_RAYDIUM_LP` | No | `false` | Set `true` for live Raydium LP |
56
+ | `ENABLE_LIVE_KAMINO` | No | `false` | Set `true` for live Kamino lending / borrowing |
57
+ | `ENABLE_LIVE_MARINADE` | No | `false` | Set `true` for live Marinade staking |
58
+ | `KAMINO_LIVE_CONFIG_PATH` | No | `kamino_live.json` | Path to Kamino live config copied from `kamino_live.example.json` |
59
+ | `POLICY_SESSION_TTL_MINUTES` | No | `60` | Session TTL in minutes (1–1440) |
60
+
61
+ > **Production**: Use `REMOTE_SIGNER_URL`, `REMOTE_SIGNER_BEARER_TOKEN`, and `REMOTE_SIGNER_PUBKEY` instead of `AGENT_PRIVATE_KEY`. All three must be set together.
62
+
63
+ For the autonomous bounty demo, set `ENABLE_LIVE_MARINADE=true`. No pre-existing wallet is required, but setting `DEVNET_TREASURY_PRIVATE_KEY` lets generated wallets fund from your own devnet treasury instead of the public faucet.
64
+
65
+ ### 3. Run the autonomous agent wallet demo
66
+
67
+ ```bash
68
+ npm run demo:autonomous-agent-wallet:devnet
69
+ ```
70
+
71
+ Expected output: generated wallet address, devnet funding signature, live Marinade staking signature, and an owner emergency-lock block message.
72
+
73
+ ### 4. Run the autonomous portfolio demo
74
+
75
+ ```bash
76
+ npm run demo:autonomous-portfolio:devnet
77
+ ```
78
+
79
+ Expected output: generated wallet address, funding signature, simulated Jupiter swap intent signature on devnet, live Orca LP signature, and Kamino deposit/borrow signatures that are live-first with simulated fallback on the same wallet.
80
+ Current devnet behavior: Orca runs live; Kamino is attempted live first and then falls back to simulated deposit/borrow intents if the selected devnet market cannot refresh reserves.
81
+ On devnet, the Jupiter step stays simulated because Jupiter’s swap programs are mainnet-only; the LP and lending legs run live on the generated wallet.
82
+
83
+ ### 5. Optional operator-funded wallet demo
84
+
85
+ ```bash
86
+ npm run wallet:devnet
87
+ ```
88
+
89
+ This path uses `AGENT_PRIVATE_KEY` or the remote signer and demonstrates direct wallet-controlled execution.
90
+
91
+ ### 6. Verify
92
+
93
+ ```bash
94
+ npm run release:check
95
+ ```
96
+
97
+ Build and automated checks should pass. `release:check` will still fail until the manual mainnet gate items in `PRODUCTION_READINESS_TODO.md` are completed.
98
+
99
+ ---
100
+
101
+ ## Architecture
102
+
103
+ ```mermaid
104
+ flowchart TD
105
+ S[Agent Strategy] --> R[AgentRunner]
106
+ R --> I[Typed Intents]
107
+ I --> P[PolicyEngine]
108
+ P --> X[SandboxExecutor]
109
+ X --> T[TransactionService]
110
+ T --> C[RpcClient / RpcFailoverClient]
111
+ C --> D[Solana Devnet]
112
+
113
+ R --> U[UniversalDeFiOrchestrator]
114
+ U --> LJ[Live Jupiter]
115
+ U --> LM[Live Marinade]
116
+ U --> LR[Live Raydium LP]
117
+ U --> LK[Live Kamino]
118
+ U --> FB[Safe Fallback Path]
119
+ ```
120
+
121
+ ### 4-Layer Design
122
+
123
+ 1. **Wallet Core** (`src/core`) — RPC abstraction, tx building/simulation/sending, token and balance services, idempotency guard, RPC failover
124
+ 2. **Policy + Sandbox** (`src/policy`) — Tx inspection, limits, allowlists, audit trail, simulation and approval gating
125
+ 3. **Agent Runner** (`src/agent`) — Strategy execution, intent orchestration, isolated agent contexts, rate limits, circuit breakers
126
+ 4. **Protocol Interaction** (`src/defi`, `src/demo`, `src/scripts`) — Live-first devnet scripts and universal DeFi harness
127
+
128
+ ---
129
+
130
+ ## Commands
131
+
132
+ ### Core
133
+
134
+ | Command | Mode | Description |
135
+ |---------|------|-------------|
136
+ | `npm run build` | — | TypeScript compile |
137
+ | `npm test` | — | Run all tests |
138
+ | `npm run test:coverage` | — | Tests with coverage |
139
+ | `npm run release:check` | — | Preflight readiness check |
140
+ | `npm run cli -- --help` | — | CLI help |
141
+
142
+ ### Live Devnet
143
+
144
+ | Command | Mode | Description |
145
+ |---------|------|-------------|
146
+ | `npm run demo:autonomous-agent-wallet:devnet` | `LIVE` | Provision or reuse the assigned agent wallet, fund on devnet, stake via Marinade, and show owner stop control |
147
+ | `npm run demo:autonomous-portfolio:devnet` | `LIVE` / `SIMULATED` | Provision or reuse the assigned agent wallet, fund on devnet, then execute a Jupiter swap intent plus live Orca LP and a live-first Kamino deposit/borrow path that falls back to simulated intents when devnet reserve refresh is broken |
148
+ | `npm run wallet:devnet` | `LIVE` | Wallet demo with wSOL wrap |
149
+ | `npm run defi:stake:devnet -- 0.15` | `LIVE` | Marinade stake on devnet |
150
+ | `npm run defi:orca:devnet -- 0.05` | `LIVE` | Orca Whirlpool LP position on devnet |
151
+ | `npm run defi:lp:devnet` | `LIVE` | Raydium LP on devnet |
152
+ | `npm run defi:kamino:devnet -- deposit` | `LIVE` | Kamino deposit on devnet |
153
+ | `npm run defi:kamino:devnet -- borrow` | `LIVE` | Kamino borrow on devnet |
154
+ | `npm run demo:multi-agent:devnet` | `LIVE` | Multi-agent devnet demo |
155
+ | `npm run simulate-attack` | `LIVE` | Security guardrail demo |
156
+ | `npm run stress:agents` | `LIVE` | Rate limit + circuit breaker demo |
157
+
158
+ Set `PRKT_AGENT_NAME=<agent-id>` to pin these autonomous/live scripts to a specific persistent agent wallet across reruns.
159
+
160
+ ### Simulated
161
+
162
+ | Command | Mode | Description |
163
+ |---------|------|-------------|
164
+ | `npm run defi:universal` | `SIMULATED` | All DeFi capabilities (memo path) |
165
+ | `npm run agent:defi:universal` | `SIMULATED` | Agent-runner universal harness |
166
+ | `npm run defi:borrow` | `SIMULATED` | Kamino borrow simulation |
167
+ | `npm run defi:all` | `SIMULATED` | Full DeFi suite |
168
+
169
+ ### CLI Areas
170
+
171
+ - **Wallet**: `wallet create`, `wallet list`, `wallet show`, `wallet fund`, `wallet balance`, `wallet export-secret`, `wallet transfer-sol`, `wallet transfer-spl`
172
+ - **Token**: `token mint-demo`, `token create-ata`
173
+ - **Policy**: `policy show`, `policy validate-intent`
174
+ - **Provider policy presets**: `policy presets`, `policy set-preset`, `policy set-limits`, `policy clear-overrides`
175
+ - **Agent**: `agent create`, `agent fund`, `agent balance`, `agent export-wallet`, `agent list`, `agent show`, `agent run`, `agent run-all`, `agent stop`, `agent logs`
176
+ - **Monitoring**: `monitor overview`, `monitor balances`, `monitor txs`, `monitor agents`, `monitor watch`
177
+ - **Platform**: `doctor`, `config show`, `audit`, `completion`
178
+
179
+ ### Agent Provisioning
180
+
181
+ Managed agents are now agent-first:
182
+
183
+ - `agent create --agent <agent-id> --owner <user-id>` provisions a persistent wallet for that agent
184
+ - the wallet secret is stored encrypted for autonomous execution
185
+ - the CLI returns a one-time `recoveryKey` that the user can use with `agent export-wallet` for full custody export
186
+ - the default custody model is local-per-user: each install gets its own local wallet encryption key and local state directory
187
+ - `PRKT_WALLET_MASTER_KEY` is an advanced override for managed/server deployments; if unset, PRKT creates a per-user local key file in the PRKT CLI data directory (`%APPDATA%/PRKT` on Windows, `~/Library/Application Support/PRKT` on macOS, `${XDG_DATA_HOME:-~/.local/share}/prkt` on Linux)
188
+ - `PRKT_CLI_HOME` optionally pins that local state to a specific directory
189
+ - `PRKT_AGENT_NAME` and optional `PRKT_OWNER_ID` let autonomous/live scripts provision or reuse a specific managed agent wallet
190
+
191
+ ### Provider Policy Defaults
192
+
193
+ Auto-created wallets are usable immediately. When you create a wallet or agent, PRKT attaches the `auto-devnet-safe` provider preset by default, which keeps the wallet autonomous but constrained:
194
+
195
+ - sandbox approval mode
196
+ - conservative per-tx and per-session limits
197
+ - unknown instructions denied by default
198
+ - simulation required before broadcast
199
+ - only explicitly allowed protocol exceptions permitted
200
+
201
+ Operators can inspect and adjust the policy without editing code:
202
+
203
+ ```bash
204
+ npm run cli -- policy presets
205
+ npm run cli -- policy show --agent <agent>
206
+ npm run cli -- policy set-preset --agent <agent> --preset guarded-live
207
+ npm run cli -- policy set-limits --agent <agent> --max-sol-per-tx-lamports 500000000
208
+ ```
209
+
210
+ ---
211
+
212
+ ## Security Model
213
+
214
+ ### Controls
215
+
216
+ - Agent isolation per wallet/config
217
+ - Program and mint allowlists
218
+ - Spend limits per tx/session/day
219
+ - Unknown instructions denied by default
220
+ - SPL delegate approval, close-account drain, and authority change blocking
221
+ - Simulation required before broadcast (sandbox path)
222
+ - Emergency kill switch (env, file, HMAC-signed command)
223
+ - Session TTL (configurable, max 24h)
224
+ - Rate limiting and circuit breakers per agent
225
+ - Post-transaction balance verification
226
+
227
+ ### Key Management
228
+
229
+ - **Production**: `REMOTE_SIGNER_URL` + bearer auth + `REMOTE_SIGNER_PUBKEY`
230
+ - **Devnet/demo only**: `AGENT_PRIVATE_KEY` as JSON integer array
231
+ - **Managed agent wallets**: encrypted locally per user, with an optional `PRKT_WALLET_MASTER_KEY` override for managed/server environments, plus a user-held recovery key for export
232
+
233
+ ### Caveats
234
+
235
+ - CLI-managed wallets are local-only custody unless you move them behind a remote signer/HSM-backed service
236
+ - `AGENT_PRIVATE_KEY` is a devnet escape hatch, not for production
237
+ - See `artifacts/security-deep-dive.md` for full threat model
238
+
239
+ ## Local User Custody Model
240
+
241
+ PRKT is designed so users can install the CLI and operate their own agent wallets locally.
242
+
243
+ - each user install keeps its own encrypted wallet registry and activity log
244
+ - each user install gets its own local encryption key by default
245
+ - agents can autonomously create and use wallets, but every execution still resolves through the active policy preset and policy overrides
246
+ - users tighten or relax that autonomy with `policy set-preset`, `policy set-limits`, and `policy validate-intent`
247
+ - `prkt init`, `prkt config show`, and `prkt doctor` expose the current custody model, local state path, and runtime safety posture
248
+
249
+ In other words: PRKT can behave like a "Phantom for agents" without turning wallet custody into a shared backend secret.
250
+
251
+ ---
252
+
253
+ ## Troubleshooting
254
+
255
+ | Symptom | Cause | Fix |
256
+ |---------|-------|-----|
257
+ | `EnvConfigError: AGENT_PRIVATE_KEY must contain exactly 64 integers` | Malformed key in `.env` | Re-export from `solana-keygen` as JSON array |
258
+ | `USDC_MINT is set to the mainnet mint while RPC is devnet` | Cluster/mint mismatch | Set `USDC_MINT=4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU` |
259
+ | `Session blocked: session has expired` | Session TTL exceeded | Restart the agent or increase `POLICY_SESSION_TTL_MINUTES` |
260
+ | `Human-in-the-loop Override engaged` | Emergency lock active | Set `emergency_lock.json` `"enabled": false` or unset `POLICY_EMERGENCY_LOCK` env |
261
+ | `Program blocked: <id> is not whitelisted` | Missing program in allowlist | Add program ID to `EXTRA_WHITELISTED_PROGRAMS` in `.env` |
262
+ | `Kamino live config not found` | Missing `kamino_live.json` | Copy `kamino_live.example.json` to `kamino_live.json` and fill in market/mint/program IDs |
263
+ | `Kamino market <id> could not be loaded` | Wrong market/program/RPC cluster | Verify `SOLANA_RPC_URL`, `ENABLE_LIVE_KAMINO=true`, and the addresses in `kamino_live.json` |
264
+ | `ReserveStale` or `InvalidOracleConfig` during Kamino devnet execution | Kamino devnet market cannot refresh reserves on-chain | Use `npm run demo:autonomous-portfolio:devnet` for the live-first + simulated-fallback demo path, or wait for Kamino to refresh/fix the devnet market |
265
+ | `Could not load the public Orca devnet SOL/devUSDC concentrated pool` | RPC unhealthy or cluster mismatch | Use a healthy devnet RPC and keep `SOLANA_RPC_URL` pointed at devnet |
266
+ | `Orca quote returned zero liquidity` | Chosen tick range or RPC state invalid | Retry with the default amount or a healthier devnet RPC |
267
+ | `Marinade live execution was not prepared` | Marinade live path disabled or unsupported cluster | Set `ENABLE_LIVE_MARINADE=true` and use a devnet RPC |
268
+ | `Marinade stake verification failed` | mSOL balance did not increase after confirmation | Check wallet funding, RPC health, and whether the transaction landed on the intended cluster |
269
+ | `Funding failed` | Devnet airdrop did not settle or faucet is rate-limited | Retry after a short delay or switch to a healthier devnet RPC |
270
+ | `Autonomous agent wallet demo requires devnet` | RPC points at the wrong cluster | Set `SOLANA_RPC_URL=https://api.devnet.solana.com` or another devnet endpoint |
271
+ | `Wallet master key is not configured` | No `PRKT_WALLET_MASTER_KEY` and no local fallback key file | Set `PRKT_WALLET_MASTER_KEY` for live deployments or allow PRKT to create the local fallback file in non-production environments |
272
+ | `Unsupported state or unable to export wallet` | Wrong `recoveryKey` or the wallet predates encrypted custody migration | Re-run provisioning for a new managed agent wallet or supply the correct recovery key returned at creation time |
273
+ | `Transfer blocked: destination is not whitelisted` | Destination not in policy | Add the destination pubkey to the agent's policy `whitelistedTransferDestinations` |
274
+ | `RPC request failed` | Devnet RPC down/rate-limited | Set `SOLANA_RPC_FALLBACK_URL` in `.env` or wait and retry |
275
+ | Build fails | TypeScript errors | Run `npx tsc --noEmit` for details |
276
+ | Tests fail | Environment contamination | Run `npm test -- --runInBand` for isolation |
277
+
278
+ ---
279
+
280
+ ## Deterministic Demo Sequence
281
+
282
+ For bounty judges or recorded demonstrations:
283
+
284
+ ```bash
285
+ # 1. Preflight
286
+ npm run release:check
287
+
288
+ # 2. Rehearsal (generates demo-session.json)
289
+ npm run demo:rehearsal
290
+
291
+ # 3. Autonomous agent wallet demo (LIVE)
292
+ npm run demo:autonomous-agent-wallet:devnet
293
+
294
+ # 4. Autonomous portfolio demo (LIVE)
295
+ npm run demo:autonomous-portfolio:devnet
296
+
297
+ # 5. Wallet demo (LIVE)
298
+ npm run wallet:devnet
299
+
300
+ # 6. Raydium LP (LIVE) — requires raydium_lp.devnet.json
301
+ npm run defi:lp:devnet
302
+
303
+ # 7. Marinade stake (LIVE)
304
+ npm run defi:stake:devnet -- 0.15
305
+
306
+ # 8. Orca Whirlpool LP (LIVE)
307
+ npm run defi:orca:devnet -- 0.05
308
+
309
+ # 9. Kamino deposit (LIVE attempt on devnet; current portfolio demo falls back to simulated if reserve refresh is broken)
310
+ npm run defi:kamino:devnet -- deposit
311
+
312
+ # 9. Security guardrails
313
+ npm run simulate-attack
314
+
315
+ # 10. Multi-agent stress test
316
+ npm run stress:agents
317
+
318
+ # 11. Fill artifacts/bounty-evidence.md with signatures
319
+ ```
320
+
321
+ ---
322
+
323
+ ## Repo Structure
324
+
325
+ ```text
326
+ src/
327
+ core/ # Wallet, RPC, tx service, balances, tokens, idempotency
328
+ policy/ # PolicyGuard, PolicyEngine, SandboxExecutor, emergency lock
329
+ agent/ # AgentManager, AgentRuntime, DecisionEngine, strategies
330
+ defi/ # DeFi coordinators, adapters, universal orchestrator
331
+ cli/ # Operational CLI commands
332
+ config/ # Environment configuration
333
+ scripts/ # Demo and utility scripts
334
+ demo/ # Multi-agent demo scripts
335
+ tests/ # Unit and integration tests (28 suites, 100+ tests)
336
+ artifacts/ # Bounty evidence, security deep-dive
337
+ ```
338
+
339
+ Full CLI reference: [CLI.md](./CLI.md) · Quick path: [CLI_QUICKSTART.md](./CLI_QUICKSTART.md) · Compatibility: [COMPATIBILITY.md](./COMPATIBILITY.md)
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AgentManager = void 0;
4
+ const PolicyGuard_1 = require("../policy/PolicyGuard");
5
+ const WalletManager_1 = require("../wallet/WalletManager");
6
+ const policyFactory_1 = require("./policyFactory");
7
+ const AgentRuntime_1 = require("./AgentRuntime");
8
+ function createDefaultSafetyControls() {
9
+ return {
10
+ cooldownMs: 30_000,
11
+ maxActionsPerWindow: 5,
12
+ maxConsecutiveFailures: 3,
13
+ windowMs: 60_000
14
+ };
15
+ }
16
+ class AgentExecutionController {
17
+ controls;
18
+ attemptsInWindow = [];
19
+ consecutiveFailures = 0;
20
+ openUntilTimestamp = 0;
21
+ constructor(controls) {
22
+ this.controls = controls;
23
+ }
24
+ beforeExecution(now) {
25
+ this.pruneAttempts(now);
26
+ if (now < this.openUntilTimestamp) {
27
+ return {
28
+ allowed: false,
29
+ reason: `circuit breaker open until ${new Date(this.openUntilTimestamp).toISOString()}`
30
+ };
31
+ }
32
+ if (this.attemptsInWindow.length >= this.controls.maxActionsPerWindow) {
33
+ return {
34
+ allowed: false,
35
+ reason: `rate limit exceeded: max ${this.controls.maxActionsPerWindow} actions per ${this.controls.windowMs}ms`
36
+ };
37
+ }
38
+ this.attemptsInWindow.push(now);
39
+ return { allowed: true };
40
+ }
41
+ recordSuccess() {
42
+ this.consecutiveFailures = 0;
43
+ }
44
+ recordFailure(now) {
45
+ this.consecutiveFailures += 1;
46
+ if (this.consecutiveFailures >= this.controls.maxConsecutiveFailures) {
47
+ this.openUntilTimestamp = now + this.controls.cooldownMs;
48
+ this.consecutiveFailures = 0;
49
+ }
50
+ }
51
+ pruneAttempts(now) {
52
+ const windowStart = now - this.controls.windowMs;
53
+ this.attemptsInWindow = this.attemptsInWindow.filter((timestamp) => timestamp >= windowStart);
54
+ }
55
+ }
56
+ class AgentManager {
57
+ static spawnAgents(count) {
58
+ return Array.from({ length: count }, (_, index) => {
59
+ const walletManager = WalletManager_1.WalletManager.generate();
60
+ const policy = (0, policyFactory_1.createDefaultAgentPolicy)({
61
+ maxSpend: {
62
+ lamports: 500_000 + index * 250_000
63
+ }
64
+ });
65
+ return {
66
+ id: `agent-${index + 1}`,
67
+ policy,
68
+ policyGuard: new PolicyGuard_1.PolicyGuard(policy),
69
+ walletManager
70
+ };
71
+ });
72
+ }
73
+ static async runConcurrentTradeSimulation(input) {
74
+ const agents = AgentManager.spawnAgents(3);
75
+ const logger = input.logger ?? (() => undefined);
76
+ const results = await Promise.all(agents.map(async (agent) => {
77
+ logger(`Scheduling ${agent.id} (${agent.walletManager.publicKey.toBase58()})`);
78
+ const result = await (0, AgentRuntime_1.simulateMarketAction)({
79
+ amountSol: input.amountSol,
80
+ koraSigner: input.koraSigner,
81
+ liveSwapConfig: input.liveSwapConfig,
82
+ logger: (message) => logger(`${agent.id}: ${message}`),
83
+ policyGuard: agent.policyGuard,
84
+ priceFeed: input.priceFeed,
85
+ walletManager: agent.walletManager
86
+ });
87
+ return {
88
+ agentId: agent.id,
89
+ result
90
+ };
91
+ }));
92
+ return results;
93
+ }
94
+ static async runManagedTradeSimulation(input) {
95
+ const agents = AgentManager.spawnAgents(3);
96
+ const logger = input.logger ?? (() => undefined);
97
+ const controls = {
98
+ ...createDefaultSafetyControls(),
99
+ ...input.safetyControls
100
+ };
101
+ const controllers = new Map();
102
+ for (const agent of agents) {
103
+ controllers.set(agent.id, new AgentExecutionController(controls));
104
+ }
105
+ const events = [];
106
+ for (let iteration = 1; iteration <= input.rounds; iteration += 1) {
107
+ const iterationEvents = await Promise.all(agents.map(async (agent) => {
108
+ const controller = controllers.get(agent.id);
109
+ if (!controller) {
110
+ return {
111
+ agentId: agent.id,
112
+ iteration,
113
+ reason: "agent controller missing",
114
+ status: "failed"
115
+ };
116
+ }
117
+ const now = Date.now();
118
+ const precheck = controller.beforeExecution(now);
119
+ if (!precheck.allowed) {
120
+ const message = `${agent.id}: blocked (${precheck.reason})`;
121
+ logger(message);
122
+ return {
123
+ agentId: agent.id,
124
+ iteration,
125
+ reason: precheck.reason,
126
+ status: "blocked"
127
+ };
128
+ }
129
+ try {
130
+ const result = input.simulateAction
131
+ ? await input.simulateAction(agent)
132
+ : await (0, AgentRuntime_1.simulateMarketAction)({
133
+ amountSol: input.amountSol,
134
+ koraSigner: input.koraSigner,
135
+ liveSwapConfig: input.liveSwapConfig,
136
+ logger: (message) => logger(`${agent.id}: ${message}`),
137
+ policyGuard: agent.policyGuard,
138
+ priceFeed: input.priceFeed,
139
+ walletManager: agent.walletManager
140
+ });
141
+ controller.recordSuccess();
142
+ return {
143
+ agentId: agent.id,
144
+ iteration,
145
+ result,
146
+ status: "executed"
147
+ };
148
+ }
149
+ catch (error) {
150
+ controller.recordFailure(now);
151
+ const reason = error instanceof Error ? error.message : "unknown execution error";
152
+ logger(`${agent.id}: failed (${reason})`);
153
+ return {
154
+ agentId: agent.id,
155
+ iteration,
156
+ reason,
157
+ status: "failed"
158
+ };
159
+ }
160
+ }));
161
+ events.push(...iterationEvents);
162
+ }
163
+ return events;
164
+ }
165
+ }
166
+ exports.AgentManager = AgentManager;
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.simulateMarketAction = simulateMarketAction;
4
+ const RpcClient_1 = require("../core/rpc/RpcClient");
5
+ const PostTransactionVerifier_1 = require("../core/transactions/PostTransactionVerifier");
6
+ const TokenService_1 = require("../core/tokens/TokenService");
7
+ const env_1 = require("../config/env");
8
+ const web3_js_1 = require("@solana/web3.js");
9
+ async function simulateMarketAction(input) {
10
+ const market = input.priceFeed.read();
11
+ const logger = input.logger ?? (() => undefined);
12
+ if (market.solPriceUsd > market.buyThresholdUsd) {
13
+ logger(`Decision -> HOLD (SOL @ $${market.solPriceUsd.toFixed(2)} exceeds threshold $${market.buyThresholdUsd.toFixed(2)})`);
14
+ return {
15
+ action: "hold",
16
+ execution: null,
17
+ liveSwap: null,
18
+ market,
19
+ memo: null
20
+ };
21
+ }
22
+ if (input.liveSwapConfig?.enabled && input.liveSwapConfig.swapExecutor) {
23
+ if (input.liveSwapConfig.guardedExecutor) {
24
+ logger("Decision -> Policy Check -> Guarded Live Jupiter Swap.");
25
+ const rpcClient = new RpcClient_1.RpcClient((0, env_1.getRpcUrl)(), "confirmed");
26
+ const tokenService = new TokenService_1.TokenService(rpcClient);
27
+ const verifier = new PostTransactionVerifier_1.PostTransactionVerifier(rpcClient, tokenService);
28
+ const outputBalanceSnapshot = await verifier.snapshotSplBalanceForOwner({
29
+ label: `Jupiter output token balance (${input.liveSwapConfig.outputMint})`,
30
+ mint: new web3_js_1.PublicKey(input.liveSwapConfig.outputMint),
31
+ owner: input.walletManager.publicKey
32
+ });
33
+ const preparedSwap = await input.liveSwapConfig.swapExecutor.buildSolToTokenSwapTransaction({
34
+ amountSol: input.amountSol,
35
+ outputMint: input.liveSwapConfig.outputMint,
36
+ walletManager: input.walletManager
37
+ });
38
+ const guardedExecution = await input.liveSwapConfig.guardedExecutor.executePreparedTransaction({
39
+ transaction: preparedSwap.transaction
40
+ });
41
+ if (guardedExecution.signature) {
42
+ const [verification] = await verifier.assertBalanceChanges([
43
+ {
44
+ minIncreaseRaw: 1n,
45
+ snapshot: outputBalanceSnapshot
46
+ }
47
+ ]);
48
+ logger(`Verified ${guardedExecution.signature}: ${verification.label} ${verification.beforeUi} -> ${verification.afterUi} (${verification.deltaUi})`);
49
+ logger(`Executed live swap ${guardedExecution.signature}`);
50
+ return {
51
+ action: "execute_swap",
52
+ execution: {
53
+ endpoint: "guarded-solana-rpc",
54
+ memo: `JUPITER_SWAP:${input.amountSol.toFixed(2)} SOL->${input.liveSwapConfig.outputMint}`,
55
+ mock: false,
56
+ signature: guardedExecution.signature
57
+ },
58
+ liveSwap: {
59
+ execution: {
60
+ endpoint: "guarded-solana-rpc",
61
+ memo: `JUPITER_SWAP:${input.amountSol.toFixed(2)} SOL->${input.liveSwapConfig.outputMint}`,
62
+ mock: false,
63
+ signature: guardedExecution.signature
64
+ },
65
+ outputMint: preparedSwap.outputMint,
66
+ quoteOutAmount: preparedSwap.quoteOutAmount,
67
+ routeType: preparedSwap.routeType
68
+ },
69
+ market,
70
+ memo: null
71
+ };
72
+ }
73
+ logger(`Guarded live swap blocked${guardedExecution.inspection.reasons.length > 0 ? `: ${guardedExecution.inspection.reasons.join("; ")}` : ""}. Falling back to memo execution.`);
74
+ }
75
+ else {
76
+ logger("Guarded live swap executor missing. Falling back to memo execution.");
77
+ }
78
+ }
79
+ const memo = `SWAP_INTENT:${input.amountSol.toFixed(2)} SOL->USDC @ $${market.solPriceUsd.toFixed(2)}`;
80
+ logger("Decision -> Policy Check -> Gasless Execution.");
81
+ const transaction = await input.koraSigner.buildMemoTransaction(input.walletManager, memo);
82
+ input.policyGuard.validate(transaction);
83
+ const execution = await input.koraSigner.signAndSendGasless(transaction, memo);
84
+ logger(`Executed ${execution.mock ? "mock " : ""}gasless swap intent ${execution.signature}`);
85
+ return {
86
+ action: "execute_swap",
87
+ execution,
88
+ liveSwap: null,
89
+ market,
90
+ memo
91
+ };
92
+ }