@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.
- package/.env.devnet.all-protocols.example +18 -0
- package/.env.devnet.autonomous.example +16 -0
- package/.env.devnet.jupiter.example +16 -0
- package/.env.devnet.kamino.example +17 -0
- package/.env.devnet.marinade.example +16 -0
- package/.env.devnet.orca.example +16 -0
- package/.env.devnet.raydium.example +17 -0
- package/.env.example +32 -0
- package/ARCHITECTURE.md +159 -0
- package/CLI.md +509 -0
- package/CLI_QUICKSTART.md +108 -0
- package/COMPATIBILITY.md +103 -0
- package/DEVNET_PROTOCOL_ADDRESSES.md +72 -0
- package/README.md +339 -0
- package/dist/agent/AgentManager.js +166 -0
- package/dist/agent/AgentRuntime.js +92 -0
- package/dist/agent/DecisionEngine.js +95 -0
- package/dist/agent/MockPriceFeed.js +13 -0
- package/dist/agent/intents/types.js +2 -0
- package/dist/agent/new-index.js +17 -0
- package/dist/agent/policyFactory.js +54 -0
- package/dist/agent/registry/AgentRegistry.js +16 -0
- package/dist/agent/runner/AgentRunner.js +266 -0
- package/dist/agent/strategies/MemoHeartbeatStrategy.js +15 -0
- package/dist/agent/strategies/SimpleScriptedTransferStrategy.js +27 -0
- package/dist/agent/strategies/TokenRebalancerStrategy.js +35 -0
- package/dist/agent/strategies/TreasuryDistributorStrategy.js +29 -0
- package/dist/agent/strategies/UniversalDeFiStrategy.js +19 -0
- package/dist/agent/types/AgentContext.js +2 -0
- package/dist/cli/index.js +1159 -0
- package/dist/cli/services/activityStore.js +42 -0
- package/dist/cli/services/agentRegistry.js +123 -0
- package/dist/cli/services/agentRuntime.js +55 -0
- package/dist/cli/services/storagePaths.js +64 -0
- package/dist/cli/services/strategyFactory.js +66 -0
- package/dist/cli/services/walletCrypto.js +120 -0
- package/dist/cli/services/walletRegistry.js +145 -0
- package/dist/cli/types.js +2 -0
- package/dist/cli/utils/completion.js +62 -0
- package/dist/cli/utils/output.js +44 -0
- package/dist/config/agentPolicies.js +37 -0
- package/dist/config/env.js +249 -0
- package/dist/config/policyPresets.js +105 -0
- package/dist/core/balances/BalanceService.js +34 -0
- package/dist/core/funding/DevnetFundingService.js +105 -0
- package/dist/core/idempotency/ExecutionIdempotencyGuard.js +100 -0
- package/dist/core/index.js +19 -0
- package/dist/core/rpc/RpcClient.js +45 -0
- package/dist/core/rpc/RpcFailoverClient.js +97 -0
- package/dist/core/tokens/TokenService.js +75 -0
- package/dist/core/transactions/PostTransactionVerifier.js +103 -0
- package/dist/core/transactions/TransactionService.js +104 -0
- package/dist/core/types/services.js +2 -0
- package/dist/core/wallet/WalletManager.js +120 -0
- package/dist/defi/DeFiCoordinator.js +93 -0
- package/dist/defi/DeFiExecutor.js +29 -0
- package/dist/defi/DeFiPolicyGuard.js +31 -0
- package/dist/defi/adapters/JupiterAdapter.js +25 -0
- package/dist/defi/adapters/KaminoAdapter.js +50 -0
- package/dist/defi/adapters/MarinadeAdapter.js +25 -0
- package/dist/defi/adapters/RaydiumAdapter.js +45 -0
- package/dist/defi/kamino/kaminoInstructionCompat.js +24 -0
- package/dist/defi/kamino/kaminoLiveConfig.js +60 -0
- package/dist/defi/kamino/loadKaminoMarketWithFallback.js +68 -0
- package/dist/defi/lp/LpInstructionBuilder.js +2 -0
- package/dist/defi/lp/RaydiumLpInstructionBuilder.js +100 -0
- package/dist/defi/lp/raydiumDevnetConfig.js +62 -0
- package/dist/defi/protocols.js +29 -0
- package/dist/defi/types.js +2 -0
- package/dist/defi/universal/UniversalDeFiOrchestrator.js +126 -0
- package/dist/defi/universal/adapters.js +73 -0
- package/dist/defi/universal/index.js +5 -0
- package/dist/defi/universal/liveExecutors.js +394 -0
- package/dist/defi/universal/types.js +2 -0
- package/dist/demo/scenarios/multiAgentDevnetScenario.js +170 -0
- package/dist/demo/scripts/runMultiAgentDevnetDemo.js +17 -0
- package/dist/dex/JupiterSwapClient.js +59 -0
- package/dist/dex/SwapExecutor.js +52 -0
- package/dist/index.js +22 -0
- package/dist/kora/KoraRpcClient.js +60 -0
- package/dist/kora/KoraSigner.js +57 -0
- package/dist/kora/gaslessDemo.js +18 -0
- package/dist/policy/PolicyGuard.js +158 -0
- package/dist/policy/emergencyLock.js +164 -0
- package/dist/policy/engine/PolicyEngine.js +237 -0
- package/dist/policy/errors.js +10 -0
- package/dist/policy/index.js +7 -0
- package/dist/policy/sandbox/SandboxExecutor.js +77 -0
- package/dist/policy/types/policy.js +2 -0
- package/dist/scripts/devnetFunding.js +28 -0
- package/dist/scripts/devnetWalletPreflight.js +16 -0
- package/dist/scripts/localnetCheck.js +27 -0
- package/dist/scripts/managedAgentWallet.js +81 -0
- package/dist/scripts/mode.js +6 -0
- package/dist/scripts/releaseReadiness.js +93 -0
- package/dist/scripts/runAgentUniversalDeFi.js +115 -0
- package/dist/scripts/runAutonomousAgentWalletDevnet.js +154 -0
- package/dist/scripts/runAutonomousPortfolioDevnet.js +390 -0
- package/dist/scripts/runBorrowStrategy.js +35 -0
- package/dist/scripts/runDeFiSuite.js +41 -0
- package/dist/scripts/runDemoRehearsal.js +111 -0
- package/dist/scripts/runDevnetWalletDemo.js +53 -0
- package/dist/scripts/runGaslessMemo.js +23 -0
- package/dist/scripts/runGaslessWalletDemo.js +60 -0
- package/dist/scripts/runKaminoDevnet.js +109 -0
- package/dist/scripts/runLpStrategy.js +32 -0
- package/dist/scripts/runMarinadeDevnet.js +97 -0
- package/dist/scripts/runOrcaLpDevnet.js +208 -0
- package/dist/scripts/runRaydiumLpDevnet.js +95 -0
- package/dist/scripts/runReleaseReadiness.js +22 -0
- package/dist/scripts/runStakeStrategy.js +33 -0
- package/dist/scripts/runStressTest.js +41 -0
- package/dist/scripts/runTradeLoop.js +53 -0
- package/dist/scripts/runUniversalDeFiDemo.js +84 -0
- package/dist/scripts/runYieldStrategy.js +33 -0
- package/dist/scripts/runtimeFactory.js +27 -0
- package/dist/scripts/shared.js +24 -0
- package/dist/scripts/simulateAttack.js +40 -0
- package/dist/scripts/simulateSwarm.js +106 -0
- package/dist/simulation/attack.js +30 -0
- package/dist/solana/programs.js +9 -0
- package/dist/spl/TokenWallet.js +65 -0
- package/dist/types/policy.js +2 -0
- package/dist/wallet/WalletManager.js +5 -0
- 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
|
+
}
|