@prktsol/prkt 1.0.0 → 1.0.1
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 +5 -0
- package/.env.example +7 -0
- package/CLI.md +24 -0
- package/CLI_QUICKSTART.md +16 -0
- package/README.md +59 -12
- package/dist/agent/AgentManager.d.ts +61 -0
- package/dist/agent/AgentRuntime.d.ts +28 -0
- package/dist/agent/DecisionEngine.d.ts +51 -0
- package/dist/agent/MockPriceFeed.d.ts +10 -0
- package/dist/agent/intents/types.d.ts +35 -0
- package/dist/agent/new-index.d.ts +9 -0
- package/dist/agent/policyFactory.d.ts +2 -0
- package/dist/agent/registry/AgentRegistry.d.ts +11 -0
- package/dist/agent/runner/AgentRunner.d.ts +51 -0
- package/dist/agent/runner/AgentRunner.js +59 -2
- package/dist/agent/strategies/MemoHeartbeatStrategy.d.ts +6 -0
- package/dist/agent/strategies/SimpleScriptedTransferStrategy.d.ts +12 -0
- package/dist/agent/strategies/TokenRebalancerStrategy.d.ts +13 -0
- package/dist/agent/strategies/TreasuryDistributorStrategy.d.ts +12 -0
- package/dist/agent/strategies/UniversalDeFiStrategy.d.ts +22 -0
- package/dist/agent/types/AgentContext.d.ts +28 -0
- package/dist/anchoring/SessionAnchor.d.ts +42 -0
- package/dist/anchoring/SessionAnchor.js +161 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +157 -16
- package/dist/cli/services/activityStore.d.ts +8 -0
- package/dist/cli/services/agentRegistry.d.ts +20 -0
- package/dist/cli/services/agentRuntime.d.ts +6 -0
- package/dist/cli/services/storagePaths.d.ts +8 -0
- package/dist/cli/services/strategyFactory.d.ts +5 -0
- package/dist/cli/services/walletCrypto.d.ts +12 -0
- package/dist/cli/services/walletRegistry.d.ts +26 -0
- package/dist/cli/types.d.ts +68 -0
- package/dist/cli/utils/completion.d.ts +4 -0
- package/dist/cli/utils/output.d.ts +5 -0
- package/dist/cli/utils/output.js +4 -1
- package/dist/compression/AuditLogManager.d.ts +9 -0
- package/dist/compression/AuditLogManager.js +86 -0
- package/dist/compression/PolicyAccountManager.d.ts +11 -0
- package/dist/compression/PolicyAccountManager.js +113 -0
- package/dist/compression/types.d.ts +20 -0
- package/dist/compression/types.js +2 -0
- package/dist/config/PRKTConfig.d.ts +17 -0
- package/dist/config/PRKTConfig.js +19 -0
- package/dist/config/agentPolicies.d.ts +14 -0
- package/dist/config/env.d.ts +39 -0
- package/dist/config/env.js +37 -0
- package/dist/config/policyPresets.d.ts +22 -0
- package/dist/core/balances/BalanceService.d.ts +14 -0
- package/dist/core/funding/DevnetFundingService.d.ts +38 -0
- package/dist/core/funding/DevnetFundingService.js +73 -6
- package/dist/core/idempotency/ExecutionIdempotencyGuard.d.ts +39 -0
- package/dist/core/index.d.ts +8 -0
- package/dist/core/rpc/RpcClient.d.ts +21 -0
- package/dist/core/rpc/RpcClient.js +35 -0
- package/dist/core/rpc/RpcFailoverClient.d.ts +42 -0
- package/dist/core/tokens/TokenService.d.ts +40 -0
- package/dist/core/transactions/PostTransactionVerifier.d.ts +47 -0
- package/dist/core/transactions/TransactionService.d.ts +46 -0
- package/dist/core/types/services.d.ts +27 -0
- package/dist/core/wallet/WalletManager.d.ts +21 -0
- package/dist/defi/DeFiCoordinator.d.ts +24 -0
- package/dist/defi/DeFiExecutor.d.ts +15 -0
- package/dist/defi/DeFiPolicyGuard.d.ts +7 -0
- package/dist/defi/adapters/JupiterAdapter.d.ts +5 -0
- package/dist/defi/adapters/KaminoAdapter.d.ts +6 -0
- package/dist/defi/adapters/MarinadeAdapter.d.ts +5 -0
- package/dist/defi/adapters/RaydiumAdapter.d.ts +20 -0
- package/dist/defi/kamino/kaminoInstructionCompat.d.ts +3 -0
- package/dist/defi/kamino/kaminoLiveConfig.d.ts +14 -0
- package/dist/defi/kamino/loadKaminoMarketWithFallback.d.ts +11 -0
- package/dist/defi/lp/LpInstructionBuilder.d.ts +15 -0
- package/dist/defi/lp/RaydiumLpInstructionBuilder.d.ts +28 -0
- package/dist/defi/lp/raydiumDevnetConfig.d.ts +11 -0
- package/dist/defi/protocols.d.ts +8 -0
- package/dist/defi/types.d.ts +65 -0
- package/dist/defi/universal/UniversalDeFiOrchestrator.d.ts +24 -0
- package/dist/defi/universal/UniversalDeFiOrchestrator.js +157 -0
- package/dist/defi/universal/adapters.d.ts +25 -0
- package/dist/defi/universal/index.d.ts +2 -0
- package/dist/defi/universal/liveExecutors.d.ts +23 -0
- package/dist/defi/universal/types.d.ts +45 -0
- package/dist/demo/scenarios/multiAgentDevnetScenario.d.ts +5 -0
- package/dist/demo/scripts/runMultiAgentDevnetDemo.d.ts +1 -0
- package/dist/dex/JupiterSwapClient.d.ts +28 -0
- package/dist/dex/SwapExecutor.d.ts +36 -0
- package/dist/errors/PRKTError.d.ts +15 -0
- package/dist/errors/PRKTError.js +38 -0
- package/dist/evm/EvmAdapter.d.ts +45 -0
- package/dist/evm/EvmAdapter.js +2 -0
- package/dist/evm/NeonWalletBridge.d.ts +9 -0
- package/dist/evm/NeonWalletBridge.js +40 -0
- package/dist/evm/adapters/AaveAdapter.d.ts +17 -0
- package/dist/evm/adapters/AaveAdapter.js +100 -0
- package/dist/evm/adapters/UniswapV3Adapter.d.ts +18 -0
- package/dist/evm/adapters/UniswapV3Adapter.js +146 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +35 -20
- package/dist/kora/KoraRpcClient.d.ts +14 -0
- package/dist/kora/KoraSigner.d.ts +22 -0
- package/dist/kora/KoraSigner.js +33 -10
- package/dist/kora/gaslessDemo.d.ts +9 -0
- package/dist/onchain/index.d.ts +2 -0
- package/dist/onchain/index.js +17 -0
- package/dist/onchain/policyGuardProgram.d.ts +86 -0
- package/dist/onchain/policyGuardProgram.js +248 -0
- package/dist/policy/PolicyGuard.d.ts +13 -0
- package/dist/policy/emergencyLock.d.ts +4 -0
- package/dist/policy/engine/PolicyEngine.d.ts +28 -0
- package/dist/policy/engine/PolicyEngine.js +109 -1
- package/dist/policy/errors.d.ts +3 -0
- package/dist/policy/index.d.ts +3 -0
- package/dist/policy/sandbox/SandboxExecutor.d.ts +44 -0
- package/dist/policy/sandbox/SandboxExecutor.js +245 -3
- package/dist/policy/types/policy.d.ts +55 -0
- package/dist/scripts/devnetFunding.d.ts +9 -0
- package/dist/scripts/devnetFunding.js +0 -1
- package/dist/scripts/devnetWalletPreflight.d.ts +8 -0
- package/dist/scripts/localnetCheck.d.ts +1 -0
- package/dist/scripts/managedAgentWallet.d.ts +34 -0
- package/dist/scripts/mode.d.ts +2 -0
- package/dist/scripts/releaseReadiness.d.ts +9 -0
- package/dist/scripts/runAgentUniversalDeFi.d.ts +1 -0
- package/dist/scripts/runAutonomousAgentWalletDevnet.d.ts +1 -0
- package/dist/scripts/runAutonomousAgentWalletDevnet.js +1 -1
- package/dist/scripts/runAutonomousPortfolioDevnet.d.ts +1 -0
- package/dist/scripts/runAutonomousPortfolioDevnet.js +1 -1
- package/dist/scripts/runBorrowStrategy.d.ts +1 -0
- package/dist/scripts/runDeFiSuite.d.ts +1 -0
- package/dist/scripts/runDemoRehearsal.d.ts +1 -0
- package/dist/scripts/runDemoRehearsal.js +39 -10
- package/dist/scripts/runDevnetFeatureMatrix.d.ts +43 -0
- package/dist/scripts/runDevnetFeatureMatrix.js +787 -0
- package/dist/scripts/runDevnetWalletDemo.d.ts +1 -0
- package/dist/scripts/runGaslessMemo.d.ts +1 -0
- package/dist/scripts/runGaslessMemo.js +9 -1
- package/dist/scripts/runGaslessWalletDemo.d.ts +1 -0
- package/dist/scripts/runGaslessWalletDemo.js +9 -1
- package/dist/scripts/runKaminoDevnet.d.ts +1 -0
- package/dist/scripts/runKaminoDevnet.js +82 -42
- package/dist/scripts/runLpStrategy.d.ts +1 -0
- package/dist/scripts/runMarinadeDevnet.d.ts +1 -0
- package/dist/scripts/runOnchainPolicyGuardDevnet.d.ts +1 -0
- package/dist/scripts/runOnchainPolicyGuardDevnet.js +113 -0
- package/dist/scripts/runOrcaLpDevnet.d.ts +1 -0
- package/dist/scripts/runRaydiumLpDevnet.d.ts +1 -0
- package/dist/scripts/runReleaseReadiness.d.ts +1 -0
- package/dist/scripts/runStakeStrategy.d.ts +1 -0
- package/dist/scripts/runStatus.d.ts +1 -0
- package/dist/scripts/runStatus.js +22 -0
- package/dist/scripts/runStressTest.d.ts +1 -0
- package/dist/scripts/runTradeLoop.d.ts +1 -0
- package/dist/scripts/runUniversalDeFiDemo.d.ts +1 -0
- package/dist/scripts/runYieldStrategy.d.ts +1 -0
- package/dist/scripts/runtimeFactory.d.ts +8 -0
- package/dist/scripts/shared.d.ts +3 -0
- package/dist/scripts/shared.js +1 -0
- package/dist/scripts/simulateAttack.d.ts +1 -0
- package/dist/scripts/simulateSwarm.d.ts +1 -0
- package/dist/simulation/attack.d.ts +8 -0
- package/dist/solana/memoLedger.d.ts +33 -0
- package/dist/solana/memoLedger.js +205 -0
- package/dist/solana/programs.d.ts +6 -0
- package/dist/spl/TokenWallet.d.ts +18 -0
- package/dist/types/policy.d.ts +23 -0
- package/dist/wallet/WalletManager.d.ts +1 -0
- package/dist/zk/PolicyCircuit.d.ts +48 -0
- package/dist/zk/PolicyCircuit.js +171 -0
- package/dist/zk/ProofAnchor.d.ts +33 -0
- package/dist/zk/ProofAnchor.js +109 -0
- package/dist/zkCompression/CompressedCommitmentAnchor.d.ts +31 -0
- package/dist/zkCompression/CompressedCommitmentAnchor.js +90 -0
- package/dist/zkCompression/CompressedDataAccount.d.ts +45 -0
- package/dist/zkCompression/CompressedDataAccount.js +349 -0
- package/dist/zkCompression/LocalPayloadRegistry.d.ts +23 -0
- package/dist/zkCompression/LocalPayloadRegistry.js +53 -0
- package/package.json +20 -4
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolvePolicyGuardProgramId = resolvePolicyGuardProgramId;
|
|
4
|
+
exports.createSessionId = createSessionId;
|
|
5
|
+
exports.getPolicyStateSpace = getPolicyStateSpace;
|
|
6
|
+
exports.findPolicyPda = findPolicyPda;
|
|
7
|
+
exports.findVaultPda = findVaultPda;
|
|
8
|
+
exports.findSessionPda = findSessionPda;
|
|
9
|
+
exports.buildInitializePolicyInstruction = buildInitializePolicyInstruction;
|
|
10
|
+
exports.buildSetKillSwitchInstruction = buildSetKillSwitchInstruction;
|
|
11
|
+
exports.buildOpenSessionInstruction = buildOpenSessionInstruction;
|
|
12
|
+
exports.buildCloseSessionInstruction = buildCloseSessionInstruction;
|
|
13
|
+
exports.buildManagedTransferInstructions = buildManagedTransferInstructions;
|
|
14
|
+
exports.encodeManagedTransferPayload = encodeManagedTransferPayload;
|
|
15
|
+
exports.deriveTransferIntentHash = deriveTransferIntentHash;
|
|
16
|
+
const crypto_1 = require("crypto");
|
|
17
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
18
|
+
const env_1 = require("../config/env");
|
|
19
|
+
const DEFAULT_POLICY_GUARD_PROGRAM_ID = new web3_js_1.PublicKey("3sUkfLW4jtwSQFgdtWyEj8FPedtvKfXSB1J16PMUZhMG");
|
|
20
|
+
const POLICY_SEED = Buffer.from("policy", "utf8");
|
|
21
|
+
const SESSION_SEED = Buffer.from("session", "utf8");
|
|
22
|
+
const VAULT_SEED = Buffer.from("vault", "utf8");
|
|
23
|
+
const EXECUTE_TRANSFER_OPCODE = 4;
|
|
24
|
+
const EXECUTE_TRANSFER_PAYLOAD_SIZE = 160;
|
|
25
|
+
const POLICY_STATE_HEADER_SIZE = 100;
|
|
26
|
+
function resolvePolicyGuardProgramId(programId) {
|
|
27
|
+
if (programId) {
|
|
28
|
+
return programId;
|
|
29
|
+
}
|
|
30
|
+
const configured = (0, env_1.getOnchainPolicyGuardProgramId)();
|
|
31
|
+
return configured ? new web3_js_1.PublicKey(configured) : DEFAULT_POLICY_GUARD_PROGRAM_ID;
|
|
32
|
+
}
|
|
33
|
+
function createSessionId(seed) {
|
|
34
|
+
if (!seed) {
|
|
35
|
+
return (0, crypto_1.randomBytes)(32);
|
|
36
|
+
}
|
|
37
|
+
const source = typeof seed === "string" ? Buffer.from(seed, "utf8") : Buffer.from(seed);
|
|
38
|
+
return (0, crypto_1.createHash)("sha256").update(source).digest();
|
|
39
|
+
}
|
|
40
|
+
function getPolicyStateSpace(input) {
|
|
41
|
+
const allowedPrograms = input.allowedPrograms ?? [];
|
|
42
|
+
const allowedRecipients = input.allowedRecipients ?? [];
|
|
43
|
+
return POLICY_STATE_HEADER_SIZE + (allowedPrograms.length + allowedRecipients.length) * 32;
|
|
44
|
+
}
|
|
45
|
+
function findPolicyPda(owner, programId) {
|
|
46
|
+
return web3_js_1.PublicKey.findProgramAddressSync([POLICY_SEED, owner.toBuffer()], resolvePolicyGuardProgramId(programId));
|
|
47
|
+
}
|
|
48
|
+
function findVaultPda(policyPda, programId) {
|
|
49
|
+
return web3_js_1.PublicKey.findProgramAddressSync([VAULT_SEED, policyPda.toBuffer()], resolvePolicyGuardProgramId(programId));
|
|
50
|
+
}
|
|
51
|
+
function findSessionPda(policyPda, sessionId, programId) {
|
|
52
|
+
return web3_js_1.PublicKey.findProgramAddressSync([SESSION_SEED, policyPda.toBuffer(), toFixedBuffer(sessionId, 32)], resolvePolicyGuardProgramId(programId));
|
|
53
|
+
}
|
|
54
|
+
function buildInitializePolicyInstruction(input) {
|
|
55
|
+
const programId = resolvePolicyGuardProgramId(input.programId);
|
|
56
|
+
const allowedPrograms = input.allowedPrograms ?? [];
|
|
57
|
+
const allowedRecipients = input.allowedRecipients ?? [];
|
|
58
|
+
const [policyPda] = findPolicyPda(input.owner, programId);
|
|
59
|
+
const [vaultPda] = findVaultPda(policyPda, programId);
|
|
60
|
+
const data = Buffer.concat([
|
|
61
|
+
Buffer.from([0]),
|
|
62
|
+
encodeU32(input.sessionTtlMinutes),
|
|
63
|
+
encodeU64(input.dailySpendLimitLamports),
|
|
64
|
+
input.verifier.toBuffer(),
|
|
65
|
+
encodePubkeyArray(allowedPrograms),
|
|
66
|
+
encodePubkeyArray(allowedRecipients)
|
|
67
|
+
]);
|
|
68
|
+
return {
|
|
69
|
+
instruction: new web3_js_1.TransactionInstruction({
|
|
70
|
+
programId,
|
|
71
|
+
keys: [
|
|
72
|
+
{ pubkey: input.owner, isSigner: true, isWritable: true },
|
|
73
|
+
{ pubkey: policyPda, isSigner: false, isWritable: true },
|
|
74
|
+
{ pubkey: vaultPda, isSigner: false, isWritable: true },
|
|
75
|
+
{ pubkey: web3_js_1.SystemProgram.programId, isSigner: false, isWritable: false }
|
|
76
|
+
],
|
|
77
|
+
data
|
|
78
|
+
}),
|
|
79
|
+
policyPda,
|
|
80
|
+
vaultPda
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
function buildSetKillSwitchInstruction(input) {
|
|
84
|
+
const programId = resolvePolicyGuardProgramId(input.programId);
|
|
85
|
+
const [policyPda] = findPolicyPda(input.owner, programId);
|
|
86
|
+
return {
|
|
87
|
+
instruction: new web3_js_1.TransactionInstruction({
|
|
88
|
+
programId,
|
|
89
|
+
keys: [
|
|
90
|
+
{ pubkey: input.owner, isSigner: true, isWritable: false },
|
|
91
|
+
{ pubkey: policyPda, isSigner: false, isWritable: true }
|
|
92
|
+
],
|
|
93
|
+
data: Buffer.from([1, input.active ? 1 : 0])
|
|
94
|
+
}),
|
|
95
|
+
policyPda
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function buildOpenSessionInstruction(input) {
|
|
99
|
+
const programId = resolvePolicyGuardProgramId(input.programId);
|
|
100
|
+
const [policyPda] = findPolicyPda(input.owner, programId);
|
|
101
|
+
const [sessionPda] = findSessionPda(policyPda, input.sessionId, programId);
|
|
102
|
+
return {
|
|
103
|
+
instruction: new web3_js_1.TransactionInstruction({
|
|
104
|
+
programId,
|
|
105
|
+
keys: [
|
|
106
|
+
{ pubkey: input.owner, isSigner: true, isWritable: true },
|
|
107
|
+
{ pubkey: policyPda, isSigner: false, isWritable: false },
|
|
108
|
+
{ pubkey: sessionPda, isSigner: false, isWritable: true },
|
|
109
|
+
{ pubkey: web3_js_1.SystemProgram.programId, isSigner: false, isWritable: false }
|
|
110
|
+
],
|
|
111
|
+
data: Buffer.concat([Buffer.from([2]), toFixedBuffer(input.sessionId, 32)])
|
|
112
|
+
}),
|
|
113
|
+
policyPda,
|
|
114
|
+
sessionPda
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
function buildCloseSessionInstruction(input) {
|
|
118
|
+
const programId = resolvePolicyGuardProgramId(input.programId);
|
|
119
|
+
const [policyPda] = findPolicyPda(input.owner, programId);
|
|
120
|
+
const [sessionPda] = findSessionPda(policyPda, input.sessionId, programId);
|
|
121
|
+
return {
|
|
122
|
+
instruction: new web3_js_1.TransactionInstruction({
|
|
123
|
+
programId,
|
|
124
|
+
keys: [
|
|
125
|
+
{ pubkey: input.owner, isSigner: true, isWritable: false },
|
|
126
|
+
{ pubkey: policyPda, isSigner: false, isWritable: false },
|
|
127
|
+
{ pubkey: sessionPda, isSigner: false, isWritable: true }
|
|
128
|
+
],
|
|
129
|
+
data: Buffer.concat([Buffer.from([3]), toFixedBuffer(input.sessionId, 32)])
|
|
130
|
+
}),
|
|
131
|
+
policyPda,
|
|
132
|
+
sessionPda
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
function buildManagedTransferInstructions(input) {
|
|
136
|
+
const programId = resolvePolicyGuardProgramId(input.programId);
|
|
137
|
+
const signer = normalizeSigner(input.signer);
|
|
138
|
+
const [policyPda] = findPolicyPda(input.policyOwner, programId);
|
|
139
|
+
const [vaultPda] = findVaultPda(policyPda, programId);
|
|
140
|
+
const [sessionPda] = findSessionPda(policyPda, input.sessionId, programId);
|
|
141
|
+
const payload = encodeManagedTransferPayload({
|
|
142
|
+
amountLamports: input.amountLamports,
|
|
143
|
+
expiresAtUnix: input.expiresAtUnix,
|
|
144
|
+
intentHash: Buffer.from(input.intentHash ?? deriveTransferIntentHash(input)),
|
|
145
|
+
nonce: input.nonce,
|
|
146
|
+
recipient: input.recipient,
|
|
147
|
+
sessionId: Buffer.from(input.sessionId),
|
|
148
|
+
targetProgram: input.targetProgram ?? programId,
|
|
149
|
+
timestampUnix: input.timestampUnix ?? Math.floor(Date.now() / 1000)
|
|
150
|
+
});
|
|
151
|
+
return {
|
|
152
|
+
ed25519Instruction: web3_js_1.Ed25519Program.createInstructionWithPrivateKey({
|
|
153
|
+
privateKey: signer.secretKey,
|
|
154
|
+
message: payload
|
|
155
|
+
}),
|
|
156
|
+
payload,
|
|
157
|
+
policyPda,
|
|
158
|
+
programInstruction: new web3_js_1.TransactionInstruction({
|
|
159
|
+
programId,
|
|
160
|
+
keys: [
|
|
161
|
+
{ pubkey: policyPda, isSigner: false, isWritable: true },
|
|
162
|
+
{ pubkey: vaultPda, isSigner: false, isWritable: true },
|
|
163
|
+
{ pubkey: sessionPda, isSigner: false, isWritable: true },
|
|
164
|
+
{ pubkey: input.recipient, isSigner: false, isWritable: true },
|
|
165
|
+
{ pubkey: web3_js_1.SYSVAR_INSTRUCTIONS_PUBKEY, isSigner: false, isWritable: false }
|
|
166
|
+
],
|
|
167
|
+
data: Buffer.concat([Buffer.from([EXECUTE_TRANSFER_OPCODE]), payload])
|
|
168
|
+
}),
|
|
169
|
+
sessionPda,
|
|
170
|
+
vaultPda
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
function encodeManagedTransferPayload(input) {
|
|
174
|
+
const sessionId = toFixedBuffer(input.sessionId, 32);
|
|
175
|
+
const intentHash = toFixedBuffer(input.intentHash, 32);
|
|
176
|
+
const payload = Buffer.alloc(EXECUTE_TRANSFER_PAYLOAD_SIZE);
|
|
177
|
+
let offset = 0;
|
|
178
|
+
sessionId.copy(payload, offset);
|
|
179
|
+
offset += 32;
|
|
180
|
+
encodeU64(input.nonce).copy(payload, offset);
|
|
181
|
+
offset += 8;
|
|
182
|
+
encodeU64(input.amountLamports).copy(payload, offset);
|
|
183
|
+
offset += 8;
|
|
184
|
+
encodeI64(input.timestampUnix).copy(payload, offset);
|
|
185
|
+
offset += 8;
|
|
186
|
+
encodeI64(input.expiresAtUnix).copy(payload, offset);
|
|
187
|
+
offset += 8;
|
|
188
|
+
input.targetProgram.toBuffer().copy(payload, offset);
|
|
189
|
+
offset += 32;
|
|
190
|
+
input.recipient.toBuffer().copy(payload, offset);
|
|
191
|
+
offset += 32;
|
|
192
|
+
intentHash.copy(payload, offset);
|
|
193
|
+
return payload;
|
|
194
|
+
}
|
|
195
|
+
function deriveTransferIntentHash(input) {
|
|
196
|
+
const hash = (0, crypto_1.createHash)("sha256");
|
|
197
|
+
hash.update(toFixedBuffer(input.sessionId, 32));
|
|
198
|
+
hash.update(encodeU64(input.nonce));
|
|
199
|
+
hash.update(encodeU64(input.amountLamports));
|
|
200
|
+
hash.update(input.recipient.toBuffer());
|
|
201
|
+
hash.update((input.targetProgram ?? DEFAULT_POLICY_GUARD_PROGRAM_ID).toBuffer());
|
|
202
|
+
return hash.digest();
|
|
203
|
+
}
|
|
204
|
+
function normalizeSigner(input) {
|
|
205
|
+
if (input instanceof web3_js_1.Keypair) {
|
|
206
|
+
return input;
|
|
207
|
+
}
|
|
208
|
+
if (input.length === 64) {
|
|
209
|
+
return web3_js_1.Keypair.fromSecretKey(input);
|
|
210
|
+
}
|
|
211
|
+
if (input.length === 32) {
|
|
212
|
+
return web3_js_1.Keypair.fromSeed(input);
|
|
213
|
+
}
|
|
214
|
+
throw new Error("Signer must be a Keypair, 32-byte seed, or 64-byte secret key.");
|
|
215
|
+
}
|
|
216
|
+
function toFixedBuffer(value, expectedLength) {
|
|
217
|
+
const buffer = Buffer.from(value);
|
|
218
|
+
if (buffer.length !== expectedLength) {
|
|
219
|
+
throw new Error(`Expected ${expectedLength} bytes but received ${buffer.length}.`);
|
|
220
|
+
}
|
|
221
|
+
return buffer;
|
|
222
|
+
}
|
|
223
|
+
function encodePubkeyArray(values) {
|
|
224
|
+
return Buffer.concat([
|
|
225
|
+
encodeU16(values.length),
|
|
226
|
+
...values.map((value) => value.toBuffer())
|
|
227
|
+
]);
|
|
228
|
+
}
|
|
229
|
+
function encodeU16(value) {
|
|
230
|
+
const out = Buffer.alloc(2);
|
|
231
|
+
out.writeUInt16LE(value, 0);
|
|
232
|
+
return out;
|
|
233
|
+
}
|
|
234
|
+
function encodeU32(value) {
|
|
235
|
+
const out = Buffer.alloc(4);
|
|
236
|
+
out.writeUInt32LE(value, 0);
|
|
237
|
+
return out;
|
|
238
|
+
}
|
|
239
|
+
function encodeU64(value) {
|
|
240
|
+
const out = Buffer.alloc(8);
|
|
241
|
+
out.writeBigUInt64LE(value, 0);
|
|
242
|
+
return out;
|
|
243
|
+
}
|
|
244
|
+
function encodeI64(value) {
|
|
245
|
+
const out = Buffer.alloc(8);
|
|
246
|
+
out.writeBigInt64LE(BigInt(value), 0);
|
|
247
|
+
return out;
|
|
248
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type VersionedTransaction } from "@solana/web3.js";
|
|
2
|
+
import type { PolicyConstraints } from "../types/policy";
|
|
3
|
+
export declare class PolicyGuard {
|
|
4
|
+
private readonly policy;
|
|
5
|
+
constructor(policy: PolicyConstraints);
|
|
6
|
+
validate(transaction: VersionedTransaction): void;
|
|
7
|
+
private ensureEmergencyOverrideInactive;
|
|
8
|
+
private ensureSessionActive;
|
|
9
|
+
private ensureProgramAllowed;
|
|
10
|
+
private tryDecodeSpend;
|
|
11
|
+
private ensureInstructionShapeAllowed;
|
|
12
|
+
private detectBlockedSpendVector;
|
|
13
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type VersionedTransaction } from "@solana/web3.js";
|
|
2
|
+
import type { PolicyConfig, SecurityAuditEntry, TxInspectionContext, TxInspectionResult } from "../types/policy";
|
|
3
|
+
import { ethers } from "ethers";
|
|
4
|
+
export declare class PolicyEngine {
|
|
5
|
+
private readonly policyConfig;
|
|
6
|
+
private readonly sessionStart;
|
|
7
|
+
private txCountSession;
|
|
8
|
+
private readonly perDayCounts;
|
|
9
|
+
private readonly auditLog;
|
|
10
|
+
private lastResetTimestamp;
|
|
11
|
+
private spentTodaySol;
|
|
12
|
+
constructor(policyConfig: PolicyConfig);
|
|
13
|
+
inspect(transaction: VersionedTransaction, context?: TxInspectionContext): TxInspectionResult;
|
|
14
|
+
inspectEvm(transaction: ethers.TransactionRequest): TxInspectionResult;
|
|
15
|
+
recordBroadcast(signature: string, amountSol?: number): void;
|
|
16
|
+
getAuditTrail(): SecurityAuditEntry[];
|
|
17
|
+
getSessionAgeMs(): number;
|
|
18
|
+
getPolicyConfig(): PolicyConfig;
|
|
19
|
+
getSpentToday(): number;
|
|
20
|
+
recordSpend(amountSol: number): void;
|
|
21
|
+
resetDailySpend(): void;
|
|
22
|
+
private tryDecodeSpend;
|
|
23
|
+
private detectBlockedSpendVector;
|
|
24
|
+
private isKnownNonSpendInstruction;
|
|
25
|
+
private maybeResetDailySpend;
|
|
26
|
+
private getUtcDayKey;
|
|
27
|
+
private lamportsToSol;
|
|
28
|
+
}
|
|
@@ -11,6 +11,8 @@ class PolicyEngine {
|
|
|
11
11
|
txCountSession = 0;
|
|
12
12
|
perDayCounts = new Map();
|
|
13
13
|
auditLog = [];
|
|
14
|
+
lastResetTimestamp = Date.now();
|
|
15
|
+
spentTodaySol = 0;
|
|
14
16
|
constructor(policyConfig) {
|
|
15
17
|
this.policyConfig = policyConfig;
|
|
16
18
|
}
|
|
@@ -23,6 +25,7 @@ class PolicyEngine {
|
|
|
23
25
|
const mintsSeen = new Set();
|
|
24
26
|
let hasUncheckedSplSpend = false;
|
|
25
27
|
const now = Date.now();
|
|
28
|
+
this.maybeResetDailySpend(now);
|
|
26
29
|
const emergencyStatus = (0, emergencyLock_1.getEmergencyLockStatus)();
|
|
27
30
|
if (emergencyStatus.locked) {
|
|
28
31
|
reasons.push(emergencyStatus.reason ?? "Human-in-the-loop Override engaged.");
|
|
@@ -83,6 +86,10 @@ class PolicyEngine {
|
|
|
83
86
|
if (totalSolSpendLamports > BigInt(this.policyConfig.limits.maxSolPerTxLamports)) {
|
|
84
87
|
reasons.push("max SOL per transaction exceeded");
|
|
85
88
|
}
|
|
89
|
+
if (this.getSpentToday() + this.lamportsToSol(totalSolSpendLamports) >
|
|
90
|
+
this.lamportsToSol(BigInt(this.policyConfig.limits.maxSolPerTxLamports))) {
|
|
91
|
+
reasons.push("DAILY_LIMIT_EXCEEDED");
|
|
92
|
+
}
|
|
86
93
|
if (totalSplSpendRaw > this.policyConfig.limits.maxSplPerTxRawAmount) {
|
|
87
94
|
reasons.push("max SPL per transaction exceeded");
|
|
88
95
|
}
|
|
@@ -104,6 +111,7 @@ class PolicyEngine {
|
|
|
104
111
|
const allowed = reasons.length === 0;
|
|
105
112
|
const result = {
|
|
106
113
|
allowed,
|
|
114
|
+
reason: reasons[0],
|
|
107
115
|
reasons,
|
|
108
116
|
details: {
|
|
109
117
|
totalSolSpendLamports,
|
|
@@ -120,10 +128,69 @@ class PolicyEngine {
|
|
|
120
128
|
});
|
|
121
129
|
return result;
|
|
122
130
|
}
|
|
123
|
-
|
|
131
|
+
inspectEvm(transaction) {
|
|
132
|
+
const reasons = [];
|
|
133
|
+
const now = Date.now();
|
|
134
|
+
this.maybeResetDailySpend(now);
|
|
135
|
+
const emergencyStatus = (0, emergencyLock_1.getEmergencyLockStatus)();
|
|
136
|
+
if (emergencyStatus.locked) {
|
|
137
|
+
reasons.push(emergencyStatus.reason ?? "Human-in-the-loop Override engaged.");
|
|
138
|
+
}
|
|
139
|
+
const sessionExpiry = Date.parse(this.policyConfig.sessionExpiresAtIso8601);
|
|
140
|
+
if (Number.isNaN(sessionExpiry) || now > sessionExpiry) {
|
|
141
|
+
reasons.push("session expired");
|
|
142
|
+
}
|
|
143
|
+
const dayKey = new Date(now).toISOString().slice(0, 10);
|
|
144
|
+
const todaysCount = this.perDayCounts.get(dayKey) ?? 0;
|
|
145
|
+
if (this.txCountSession >= this.policyConfig.limits.maxTransactionsPerSession) {
|
|
146
|
+
reasons.push("max transactions per session exceeded");
|
|
147
|
+
}
|
|
148
|
+
if (todaysCount >= this.policyConfig.limits.maxTransactionsPerDay) {
|
|
149
|
+
reasons.push("max transactions per day exceeded");
|
|
150
|
+
}
|
|
151
|
+
// EVM contract address allowlist (analogous to program allowlist)
|
|
152
|
+
const toAddress = transaction.to?.toString().toLowerCase();
|
|
153
|
+
const allowedProgramsLower = this.policyConfig.rules.allowedProgramIds.map(id => id.toLowerCase());
|
|
154
|
+
if (toAddress && !allowedProgramsLower.includes(toAddress)) {
|
|
155
|
+
reasons.push(`EVM contract not allowed: ${toAddress}`);
|
|
156
|
+
if (!this.policyConfig.rules.allowOpaqueProgramIds?.map(id => id.toLowerCase()).includes(toAddress) && !this.policyConfig.rules.denyUnknownInstructionsByDefault) {
|
|
157
|
+
// allow
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
// Aggregate spend limit applies to EVM too (approximate 1 ETH = X SOL if needed, or raw values for test)
|
|
161
|
+
if (transaction.value && BigInt(transaction.value.toString()) > BigInt(this.policyConfig.limits.maxSolPerTxLamports)) {
|
|
162
|
+
reasons.push("max spend per transaction exceeded");
|
|
163
|
+
}
|
|
164
|
+
if (this.getSpentToday() + this.lamportsToSol(BigInt(transaction.value?.toString() || "0")) >
|
|
165
|
+
this.lamportsToSol(BigInt(this.policyConfig.limits.maxSolPerTxLamports))) {
|
|
166
|
+
reasons.push("DAILY_LIMIT_EXCEEDED");
|
|
167
|
+
}
|
|
168
|
+
const allowed = reasons.length === 0;
|
|
169
|
+
const result = {
|
|
170
|
+
allowed,
|
|
171
|
+
reason: reasons[0],
|
|
172
|
+
reasons,
|
|
173
|
+
details: {
|
|
174
|
+
totalSolSpendLamports: BigInt(transaction.value?.toString() || "0"),
|
|
175
|
+
totalSplSpendRaw: 0n,
|
|
176
|
+
programsSeen: toAddress ? [toAddress] : [],
|
|
177
|
+
mintsSeen: []
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
this.auditLog.push({
|
|
181
|
+
agentId: this.policyConfig.agentId,
|
|
182
|
+
timestampIso8601: new Date().toISOString(),
|
|
183
|
+
decision: allowed ? "allow" : "deny",
|
|
184
|
+
reason: allowed ? "policy checks passed" : reasons.join("; ")
|
|
185
|
+
});
|
|
186
|
+
return result;
|
|
187
|
+
}
|
|
188
|
+
recordBroadcast(signature, amountSol = 0) {
|
|
189
|
+
this.maybeResetDailySpend();
|
|
124
190
|
this.txCountSession += 1;
|
|
125
191
|
const dayKey = new Date().toISOString().slice(0, 10);
|
|
126
192
|
this.perDayCounts.set(dayKey, (this.perDayCounts.get(dayKey) ?? 0) + 1);
|
|
193
|
+
this.recordSpend(amountSol);
|
|
127
194
|
this.auditLog.push({
|
|
128
195
|
agentId: this.policyConfig.agentId,
|
|
129
196
|
timestampIso8601: new Date().toISOString(),
|
|
@@ -138,6 +205,34 @@ class PolicyEngine {
|
|
|
138
205
|
getSessionAgeMs() {
|
|
139
206
|
return Date.now() - this.sessionStart;
|
|
140
207
|
}
|
|
208
|
+
getPolicyConfig() {
|
|
209
|
+
return {
|
|
210
|
+
...this.policyConfig,
|
|
211
|
+
limits: {
|
|
212
|
+
...this.policyConfig.limits
|
|
213
|
+
},
|
|
214
|
+
rules: {
|
|
215
|
+
...this.policyConfig.rules,
|
|
216
|
+
allowOpaqueProgramIds: [...(this.policyConfig.rules.allowOpaqueProgramIds ?? [])],
|
|
217
|
+
allowedCloseAccountDestinations: [...(this.policyConfig.rules.allowedCloseAccountDestinations ?? [])],
|
|
218
|
+
allowedMintAddresses: [...this.policyConfig.rules.allowedMintAddresses],
|
|
219
|
+
allowedProgramIds: [...this.policyConfig.rules.allowedProgramIds],
|
|
220
|
+
allowedTransferDestinations: [...(this.policyConfig.rules.allowedTransferDestinations ?? [])]
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
getSpentToday() {
|
|
225
|
+
this.maybeResetDailySpend();
|
|
226
|
+
return this.spentTodaySol;
|
|
227
|
+
}
|
|
228
|
+
recordSpend(amountSol) {
|
|
229
|
+
this.maybeResetDailySpend();
|
|
230
|
+
this.spentTodaySol += amountSol;
|
|
231
|
+
}
|
|
232
|
+
resetDailySpend() {
|
|
233
|
+
this.spentTodaySol = 0;
|
|
234
|
+
this.lastResetTimestamp = Date.now();
|
|
235
|
+
}
|
|
141
236
|
tryDecodeSpend(instruction) {
|
|
142
237
|
if (instruction.programId.equals(web3_js_1.SystemProgram.programId)) {
|
|
143
238
|
try {
|
|
@@ -233,5 +328,18 @@ class PolicyEngine {
|
|
|
233
328
|
programId === programs_1.MEMO_PROGRAM_ID.toBase58() ||
|
|
234
329
|
(this.policyConfig.rules.allowOpaqueProgramIds?.includes(programId) ?? false));
|
|
235
330
|
}
|
|
331
|
+
maybeResetDailySpend(now = Date.now()) {
|
|
332
|
+
if (this.getUtcDayKey(this.lastResetTimestamp) === this.getUtcDayKey(now)) {
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
this.spentTodaySol = 0;
|
|
336
|
+
this.lastResetTimestamp = now;
|
|
337
|
+
}
|
|
338
|
+
getUtcDayKey(timestamp) {
|
|
339
|
+
return new Date(timestamp).toISOString().slice(0, 10);
|
|
340
|
+
}
|
|
341
|
+
lamportsToSol(amountLamports) {
|
|
342
|
+
return Number(amountLamports) / 1_000_000_000;
|
|
343
|
+
}
|
|
236
344
|
}
|
|
237
345
|
exports.PolicyEngine = PolicyEngine;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { PolicyEngine } from "./engine/PolicyEngine";
|
|
2
|
+
export { SandboxExecutor, type SandboxExecutionResult } from "./sandbox/SandboxExecutor";
|
|
3
|
+
export type { ApprovalCallback, ApprovalMode, PolicyConfig, PolicyLimits, PolicyRules, SecurityAuditEntry, TxInspectionContext, TxInspectionResult } from "./types/policy";
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type TransactionConfirmationStrategy, VersionedTransaction } from "@solana/web3.js";
|
|
2
|
+
import { TransactionService } from "../../core/transactions/TransactionService";
|
|
3
|
+
import { PolicyEngine } from "../engine/PolicyEngine";
|
|
4
|
+
import type { ApprovalCallback, TxInspectionContext, TxInspectionResult } from "../types/policy";
|
|
5
|
+
import { PolicyProof } from "../../zk/PolicyCircuit";
|
|
6
|
+
import { Keypair } from "@solana/web3.js";
|
|
7
|
+
import { ethers } from "ethers";
|
|
8
|
+
export type SandboxExecutionResult = {
|
|
9
|
+
inspection: TxInspectionResult;
|
|
10
|
+
signature: string | null;
|
|
11
|
+
simulationLogs: string[] | null;
|
|
12
|
+
zkProof?: PolicyProof;
|
|
13
|
+
};
|
|
14
|
+
export declare class SandboxExecutor {
|
|
15
|
+
private readonly policyEngine;
|
|
16
|
+
private readonly transactionService;
|
|
17
|
+
private readonly approvalMode;
|
|
18
|
+
private readonly approvalCallback?;
|
|
19
|
+
private readonly auditLogManager;
|
|
20
|
+
private readonly proofAnchor;
|
|
21
|
+
private readonly useCompression;
|
|
22
|
+
private readonly useZkProofs;
|
|
23
|
+
constructor(policyEngine: PolicyEngine, transactionService: TransactionService, approvalMode: "sandbox" | "live", approvalCallback?: ApprovalCallback | undefined);
|
|
24
|
+
executePreparedTransaction(input: {
|
|
25
|
+
confirmationStrategy?: TransactionConfirmationStrategy | string;
|
|
26
|
+
solanaKeypair?: Keypair;
|
|
27
|
+
transaction: VersionedTransaction;
|
|
28
|
+
inspectionContext?: TxInspectionContext;
|
|
29
|
+
}): Promise<SandboxExecutionResult>;
|
|
30
|
+
executePreparedEvmTransaction(input: {
|
|
31
|
+
solanaKeypair?: Keypair;
|
|
32
|
+
transaction: ethers.TransactionRequest;
|
|
33
|
+
address: string;
|
|
34
|
+
inspectionContext?: TxInspectionContext;
|
|
35
|
+
}): Promise<{
|
|
36
|
+
signature: string | null;
|
|
37
|
+
allowed: boolean;
|
|
38
|
+
reason?: string;
|
|
39
|
+
zkProof?: PolicyProof;
|
|
40
|
+
}>;
|
|
41
|
+
private resolveProofSigner;
|
|
42
|
+
private serializeEvmTransaction;
|
|
43
|
+
private buildProofState;
|
|
44
|
+
}
|