@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,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DecisionEngine = void 0;
|
|
4
|
+
const policyFactory_1 = require("./policyFactory");
|
|
5
|
+
const PolicyGuard_1 = require("../policy/PolicyGuard");
|
|
6
|
+
const programs_1 = require("../solana/programs");
|
|
7
|
+
const TokenWallet_1 = require("../spl/TokenWallet");
|
|
8
|
+
const MINIMUM_WSOL_FOR_TRADING = 0.01;
|
|
9
|
+
const MINIMUM_SOL_RESERVE = 0.1;
|
|
10
|
+
const WRAP_SOL_AMOUNT = 0.05;
|
|
11
|
+
const LAMPORTS_PER_SOL = 1_000_000_000;
|
|
12
|
+
const ANSI_CYAN = "\u001b[36m";
|
|
13
|
+
const ANSI_RESET = "\u001b[0m";
|
|
14
|
+
class DecisionEngine {
|
|
15
|
+
connection;
|
|
16
|
+
walletManager;
|
|
17
|
+
logger;
|
|
18
|
+
constructor(connection, walletManager, logger = console.log) {
|
|
19
|
+
this.connection = connection;
|
|
20
|
+
this.walletManager = walletManager;
|
|
21
|
+
this.logger = logger;
|
|
22
|
+
}
|
|
23
|
+
async think() {
|
|
24
|
+
const associatedTokenAddress = TokenWallet_1.TokenWallet.findAssociatedTokenAddress(this.walletManager.publicKey, programs_1.NATIVE_MINT);
|
|
25
|
+
const existingTokenAccount = await this.connection.getAccountInfo(associatedTokenAddress, "confirmed");
|
|
26
|
+
const solBalanceLamports = await this.connection.getBalance(this.walletManager.publicKey, "confirmed");
|
|
27
|
+
const wsolBalance = await this.getWsolBalance(associatedTokenAddress, existingTokenAccount !== null);
|
|
28
|
+
const solBalance = solBalanceLamports / LAMPORTS_PER_SOL;
|
|
29
|
+
this.logger(`SOL balance: ${solBalance.toFixed(4)} SOL`);
|
|
30
|
+
this.logger(`wSOL balance: ${wsolBalance.toFixed(4)} wSOL`);
|
|
31
|
+
if (wsolBalance < MINIMUM_WSOL_FOR_TRADING && solBalance > MINIMUM_SOL_RESERVE) {
|
|
32
|
+
const reason = "Reasoning: My wSOL liquidity is low for trading. I am initiating a 0.05 SOL wrap to maintain operational readiness.";
|
|
33
|
+
this.logger(colorizeReasoning(reason));
|
|
34
|
+
const latestBlockhash = await this.connection.getLatestBlockhash("confirmed");
|
|
35
|
+
const wrapLamports = Math.round(WRAP_SOL_AMOUNT * LAMPORTS_PER_SOL);
|
|
36
|
+
const wrapSol = await TokenWallet_1.TokenWallet.buildWrapSolTransaction({
|
|
37
|
+
amountLamports: wrapLamports,
|
|
38
|
+
createAssociatedTokenAccount: existingTokenAccount === null,
|
|
39
|
+
recentBlockhash: latestBlockhash.blockhash,
|
|
40
|
+
walletManager: this.walletManager
|
|
41
|
+
});
|
|
42
|
+
const policyGuard = new PolicyGuard_1.PolicyGuard((0, policyFactory_1.createDefaultAgentPolicy)({
|
|
43
|
+
maxSpend: {
|
|
44
|
+
lamports: wrapLamports + 1_000_000
|
|
45
|
+
},
|
|
46
|
+
whitelistedTransferDestinations: [wrapSol.associatedTokenAddress.toBase58()]
|
|
47
|
+
}));
|
|
48
|
+
policyGuard.validate(wrapSol.transaction);
|
|
49
|
+
const signature = await this.connection.sendTransaction(wrapSol.transaction, {
|
|
50
|
+
maxRetries: 3,
|
|
51
|
+
preflightCommitment: "confirmed"
|
|
52
|
+
});
|
|
53
|
+
await this.connection.confirmTransaction({
|
|
54
|
+
blockhash: latestBlockhash.blockhash,
|
|
55
|
+
lastValidBlockHeight: latestBlockhash.lastValidBlockHeight,
|
|
56
|
+
signature
|
|
57
|
+
}, "confirmed");
|
|
58
|
+
const updatedWsolBalance = await this.getWsolBalance(wrapSol.associatedTokenAddress, true);
|
|
59
|
+
return {
|
|
60
|
+
action: "wrap",
|
|
61
|
+
associatedTokenAddress: wrapSol.associatedTokenAddress.toBase58(),
|
|
62
|
+
createdAssociatedTokenAccount: wrapSol.createdAssociatedTokenAccount,
|
|
63
|
+
reason,
|
|
64
|
+
signature,
|
|
65
|
+
solBalance,
|
|
66
|
+
wrapAmount: WRAP_SOL_AMOUNT,
|
|
67
|
+
wsolBalance: updatedWsolBalance
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
const reason = "Reasoning: My current SOL and wSOL balances are sufficient. No liquidity adjustment is required.";
|
|
71
|
+
this.logger(colorizeReasoning(reason));
|
|
72
|
+
return {
|
|
73
|
+
action: "hold",
|
|
74
|
+
associatedTokenAddress: associatedTokenAddress.toBase58(),
|
|
75
|
+
reason,
|
|
76
|
+
solBalance,
|
|
77
|
+
wsolBalance
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
async getWsolBalance(associatedTokenAddress, tokenAccountExists) {
|
|
81
|
+
if (!tokenAccountExists) {
|
|
82
|
+
return 0;
|
|
83
|
+
}
|
|
84
|
+
const tokenBalance = await this.connection.getTokenAccountBalance(associatedTokenAddress, "confirmed");
|
|
85
|
+
const uiAmount = tokenBalance.value.uiAmount;
|
|
86
|
+
if (uiAmount !== null && uiAmount !== undefined) {
|
|
87
|
+
return uiAmount;
|
|
88
|
+
}
|
|
89
|
+
return Number(tokenBalance.value.amount) / LAMPORTS_PER_SOL;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
exports.DecisionEngine = DecisionEngine;
|
|
93
|
+
function colorizeReasoning(message) {
|
|
94
|
+
return `${ANSI_CYAN}${message}${ANSI_RESET}`;
|
|
95
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MockPriceFeed = void 0;
|
|
4
|
+
class MockPriceFeed {
|
|
5
|
+
snapshot;
|
|
6
|
+
constructor(snapshot) {
|
|
7
|
+
this.snapshot = snapshot;
|
|
8
|
+
}
|
|
9
|
+
read() {
|
|
10
|
+
return this.snapshot;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
exports.MockPriceFeed = MockPriceFeed;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UniversalDeFiStrategy = exports.TreasuryDistributorStrategy = exports.TokenRebalancerStrategy = exports.SimpleScriptedTransferStrategy = exports.MemoHeartbeatStrategy = exports.AgentRegistry = exports.AgentRunner = void 0;
|
|
4
|
+
var AgentRunner_1 = require("./runner/AgentRunner");
|
|
5
|
+
Object.defineProperty(exports, "AgentRunner", { enumerable: true, get: function () { return AgentRunner_1.AgentRunner; } });
|
|
6
|
+
var AgentRegistry_1 = require("./registry/AgentRegistry");
|
|
7
|
+
Object.defineProperty(exports, "AgentRegistry", { enumerable: true, get: function () { return AgentRegistry_1.AgentRegistry; } });
|
|
8
|
+
var MemoHeartbeatStrategy_1 = require("./strategies/MemoHeartbeatStrategy");
|
|
9
|
+
Object.defineProperty(exports, "MemoHeartbeatStrategy", { enumerable: true, get: function () { return MemoHeartbeatStrategy_1.MemoHeartbeatStrategy; } });
|
|
10
|
+
var SimpleScriptedTransferStrategy_1 = require("./strategies/SimpleScriptedTransferStrategy");
|
|
11
|
+
Object.defineProperty(exports, "SimpleScriptedTransferStrategy", { enumerable: true, get: function () { return SimpleScriptedTransferStrategy_1.SimpleScriptedTransferStrategy; } });
|
|
12
|
+
var TokenRebalancerStrategy_1 = require("./strategies/TokenRebalancerStrategy");
|
|
13
|
+
Object.defineProperty(exports, "TokenRebalancerStrategy", { enumerable: true, get: function () { return TokenRebalancerStrategy_1.TokenRebalancerStrategy; } });
|
|
14
|
+
var TreasuryDistributorStrategy_1 = require("./strategies/TreasuryDistributorStrategy");
|
|
15
|
+
Object.defineProperty(exports, "TreasuryDistributorStrategy", { enumerable: true, get: function () { return TreasuryDistributorStrategy_1.TreasuryDistributorStrategy; } });
|
|
16
|
+
var UniversalDeFiStrategy_1 = require("./strategies/UniversalDeFiStrategy");
|
|
17
|
+
Object.defineProperty(exports, "UniversalDeFiStrategy", { enumerable: true, get: function () { return UniversalDeFiStrategy_1.UniversalDeFiStrategy; } });
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createDefaultAgentPolicy = createDefaultAgentPolicy;
|
|
4
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
5
|
+
const env_1 = require("../config/env");
|
|
6
|
+
const programs_1 = require("../solana/programs");
|
|
7
|
+
function createDefaultAgentPolicy(overrides) {
|
|
8
|
+
const sessionTtlMinutes = (0, env_1.getPolicySessionTtlMinutes)();
|
|
9
|
+
const sessionExpiryIso = new Date(Date.now() + sessionTtlMinutes * 60_000).toISOString();
|
|
10
|
+
return {
|
|
11
|
+
protocolPolicies: {
|
|
12
|
+
kamino: {
|
|
13
|
+
allowedMarkets: ["main-usdc-vault"],
|
|
14
|
+
enabled: true,
|
|
15
|
+
maxExposureLamports: 1_000_000_000,
|
|
16
|
+
maxSlippageBps: 75,
|
|
17
|
+
minHealthFactor: 1.5
|
|
18
|
+
},
|
|
19
|
+
jupiter: {
|
|
20
|
+
allowedMarkets: ["sol-usdc"],
|
|
21
|
+
enabled: true,
|
|
22
|
+
maxExposureLamports: 1_000_000_000,
|
|
23
|
+
maxSlippageBps: 100
|
|
24
|
+
},
|
|
25
|
+
marinade: {
|
|
26
|
+
allowedMarkets: ["primary-stake-pool"],
|
|
27
|
+
enabled: true,
|
|
28
|
+
maxExposureLamports: 1_000_000_000,
|
|
29
|
+
maxSlippageBps: 50
|
|
30
|
+
},
|
|
31
|
+
raydium: {
|
|
32
|
+
allowedMarkets: ["sol-usdc-core-pool"],
|
|
33
|
+
enabled: true,
|
|
34
|
+
maxExposureLamports: 1_000_000_000,
|
|
35
|
+
maxSlippageBps: 100
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
maxSpend: {
|
|
39
|
+
lamports: 1_000_000
|
|
40
|
+
},
|
|
41
|
+
whitelistedPrograms: [
|
|
42
|
+
web3_js_1.SystemProgram.programId.toBase58(),
|
|
43
|
+
programs_1.TOKEN_PROGRAM_ID.toBase58(),
|
|
44
|
+
programs_1.ASSOCIATED_TOKEN_PROGRAM_ID.toBase58(),
|
|
45
|
+
programs_1.MEMO_PROGRAM_ID.toBase58(),
|
|
46
|
+
...(0, env_1.getExtraWhitelistedPrograms)()
|
|
47
|
+
],
|
|
48
|
+
sessionExpiry: {
|
|
49
|
+
iso8601: sessionExpiryIso
|
|
50
|
+
},
|
|
51
|
+
whitelistedTransferDestinations: [],
|
|
52
|
+
...overrides
|
|
53
|
+
};
|
|
54
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AgentRegistry = void 0;
|
|
4
|
+
class AgentRegistry {
|
|
5
|
+
agents = new Map();
|
|
6
|
+
register(agent) {
|
|
7
|
+
this.agents.set(agent.context.id, agent);
|
|
8
|
+
}
|
|
9
|
+
get(agentId) {
|
|
10
|
+
return this.agents.get(agentId);
|
|
11
|
+
}
|
|
12
|
+
list() {
|
|
13
|
+
return Array.from(this.agents.values());
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
exports.AgentRegistry = AgentRegistry;
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AgentRunner = void 0;
|
|
4
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
5
|
+
const policy_1 = require("../../policy");
|
|
6
|
+
const AgentRegistry_1 = require("../registry/AgentRegistry");
|
|
7
|
+
class AgentRunner {
|
|
8
|
+
registry = new AgentRegistry_1.AgentRegistry();
|
|
9
|
+
runtimes = new Map();
|
|
10
|
+
registerAgent(input) {
|
|
11
|
+
const policyConfig = input.policyConfig ?? input.context.policyConfig;
|
|
12
|
+
const policyEngine = new policy_1.PolicyEngine({
|
|
13
|
+
...policyConfig,
|
|
14
|
+
approvalMode: input.approvalMode ?? policyConfig.approvalMode
|
|
15
|
+
});
|
|
16
|
+
const sandboxExecutor = new policy_1.SandboxExecutor(policyEngine, input.context.transactionService, input.approvalMode ?? policyConfig.approvalMode, input.approvalCallback);
|
|
17
|
+
this.registry.register({
|
|
18
|
+
context: {
|
|
19
|
+
...input.context,
|
|
20
|
+
policyConfig
|
|
21
|
+
},
|
|
22
|
+
strategy: input.strategy
|
|
23
|
+
});
|
|
24
|
+
this.runtimes.set(input.context.id, {
|
|
25
|
+
context: {
|
|
26
|
+
...input.context,
|
|
27
|
+
policyConfig
|
|
28
|
+
},
|
|
29
|
+
approvalCallback: input.approvalCallback,
|
|
30
|
+
approvalMode: input.approvalMode ?? policyConfig.approvalMode,
|
|
31
|
+
strategy: input.strategy,
|
|
32
|
+
policyEngine,
|
|
33
|
+
sandboxExecutor
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
listAgents() {
|
|
37
|
+
return this.registry.list().map((entry) => ({
|
|
38
|
+
id: entry.context.id,
|
|
39
|
+
strategy: entry.strategy.name
|
|
40
|
+
}));
|
|
41
|
+
}
|
|
42
|
+
async runOnceParallel() {
|
|
43
|
+
const agents = this.registry.list();
|
|
44
|
+
return Promise.all(agents.map(async (registered) => {
|
|
45
|
+
const runtime = this.runtimes.get(registered.context.id);
|
|
46
|
+
if (!runtime) {
|
|
47
|
+
return {
|
|
48
|
+
agentId: registered.context.id,
|
|
49
|
+
strategy: registered.strategy.name,
|
|
50
|
+
outcomes: []
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
const intents = await registered.strategy.nextIntents(registered.context);
|
|
54
|
+
const outcomes = await this.executeIntents(runtime, intents);
|
|
55
|
+
return {
|
|
56
|
+
agentId: registered.context.id,
|
|
57
|
+
strategy: registered.strategy.name,
|
|
58
|
+
outcomes
|
|
59
|
+
};
|
|
60
|
+
}));
|
|
61
|
+
}
|
|
62
|
+
async runRounds(rounds) {
|
|
63
|
+
const aggregate = new Map();
|
|
64
|
+
for (let index = 0; index < rounds; index += 1) {
|
|
65
|
+
const results = await this.runOnceParallel();
|
|
66
|
+
for (const result of results) {
|
|
67
|
+
const existing = aggregate.get(result.agentId);
|
|
68
|
+
if (!existing) {
|
|
69
|
+
aggregate.set(result.agentId, {
|
|
70
|
+
...result,
|
|
71
|
+
outcomes: [...result.outcomes]
|
|
72
|
+
});
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
existing.outcomes.push(...result.outcomes);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return Array.from(aggregate.values());
|
|
79
|
+
}
|
|
80
|
+
async executeIntents(runtime, intents) {
|
|
81
|
+
const outcomes = [];
|
|
82
|
+
for (const intent of intents) {
|
|
83
|
+
try {
|
|
84
|
+
if (intent.type === "defi-capability") {
|
|
85
|
+
if (!runtime.context.universalDeFiExecutor) {
|
|
86
|
+
throw new Error("universal DeFi executor is not configured for this agent");
|
|
87
|
+
}
|
|
88
|
+
const result = await runtime.context.universalDeFiExecutor.execute({
|
|
89
|
+
capability: intent.capability,
|
|
90
|
+
protocol: intent.protocol,
|
|
91
|
+
snapshot: intent.snapshot
|
|
92
|
+
}, {
|
|
93
|
+
liveExecutor: {
|
|
94
|
+
executePreparedTransaction: (input) => this.executePreparedTransaction(runtime, input)
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
outcomes.push({
|
|
98
|
+
intent,
|
|
99
|
+
allowed: result.result !== null,
|
|
100
|
+
signature: result.result?.signature ?? null,
|
|
101
|
+
reasons: result.result
|
|
102
|
+
? result.result.mock
|
|
103
|
+
? ["executed via memo/mock fallback"]
|
|
104
|
+
: []
|
|
105
|
+
: [`no execution for ${result.capability}/${result.protocol}`]
|
|
106
|
+
});
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
const built = await this.buildIntentTransaction(runtime.context, intent);
|
|
110
|
+
const execution = await runtime.sandboxExecutor.executePreparedTransaction({
|
|
111
|
+
confirmationStrategy: built.confirmationStrategy,
|
|
112
|
+
transaction: built.transaction
|
|
113
|
+
});
|
|
114
|
+
const allowed = execution.signature !== null;
|
|
115
|
+
outcomes.push({
|
|
116
|
+
intent,
|
|
117
|
+
allowed,
|
|
118
|
+
signature: execution.signature,
|
|
119
|
+
reasons: execution.inspection.reasons
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
outcomes.push({
|
|
124
|
+
intent,
|
|
125
|
+
allowed: false,
|
|
126
|
+
signature: null,
|
|
127
|
+
reasons: [error instanceof Error ? error.message : "unknown intent failure"]
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return outcomes;
|
|
132
|
+
}
|
|
133
|
+
async buildIntentTransaction(context, intent) {
|
|
134
|
+
if (intent.type === "write-memo") {
|
|
135
|
+
return context.transactionService.buildTransaction({
|
|
136
|
+
feePayer: context.walletPublicKey,
|
|
137
|
+
instructions: [context.transactionService.buildMemoInstruction(intent.memo)],
|
|
138
|
+
signer: context.walletManager
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
if (intent.type === "transfer-sol") {
|
|
142
|
+
return context.transactionService.buildTransaction({
|
|
143
|
+
feePayer: context.walletPublicKey,
|
|
144
|
+
instructions: [
|
|
145
|
+
context.transactionService.buildSolTransferInstruction({
|
|
146
|
+
from: context.walletPublicKey,
|
|
147
|
+
to: new web3_js_1.PublicKey(intent.to),
|
|
148
|
+
lamports: intent.lamports
|
|
149
|
+
})
|
|
150
|
+
],
|
|
151
|
+
signer: context.walletManager
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
if (intent.type === "create-ata") {
|
|
155
|
+
const ata = await context.tokenService.ensureAtaInstruction({
|
|
156
|
+
mint: new web3_js_1.PublicKey(intent.mint),
|
|
157
|
+
owner: new web3_js_1.PublicKey(intent.owner),
|
|
158
|
+
payer: context.walletPublicKey
|
|
159
|
+
});
|
|
160
|
+
if (!ata.createInstruction) {
|
|
161
|
+
return context.transactionService.buildTransaction({
|
|
162
|
+
feePayer: context.walletPublicKey,
|
|
163
|
+
instructions: [context.transactionService.buildMemoInstruction(`ata-exists:${ata.address.toBase58()}`)],
|
|
164
|
+
signer: context.walletManager
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
return context.transactionService.buildTransaction({
|
|
168
|
+
feePayer: context.walletPublicKey,
|
|
169
|
+
instructions: [ata.createInstruction],
|
|
170
|
+
signer: context.walletManager
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
if (intent.type === "transfer-spl") {
|
|
174
|
+
const mint = new web3_js_1.PublicKey(intent.mint);
|
|
175
|
+
const mintDecimals = await context.tokenService.getMintDecimals(mint);
|
|
176
|
+
const sourceAta = context.tokenService.findAssociatedTokenAddress(context.walletPublicKey, mint);
|
|
177
|
+
const destinationAta = context.tokenService.findAssociatedTokenAddress(new web3_js_1.PublicKey(intent.toOwner), mint);
|
|
178
|
+
const createDestination = await context.tokenService.ensureAtaInstruction({
|
|
179
|
+
mint,
|
|
180
|
+
owner: new web3_js_1.PublicKey(intent.toOwner),
|
|
181
|
+
payer: context.walletPublicKey
|
|
182
|
+
});
|
|
183
|
+
const instructions = [
|
|
184
|
+
...(createDestination.createInstruction ? [createDestination.createInstruction] : []),
|
|
185
|
+
context.transactionService.buildSplTransferCheckedInstruction({
|
|
186
|
+
sourceAta,
|
|
187
|
+
mint,
|
|
188
|
+
destinationAta,
|
|
189
|
+
owner: context.walletPublicKey,
|
|
190
|
+
amount: intent.amountRaw,
|
|
191
|
+
decimals: mintDecimals
|
|
192
|
+
})
|
|
193
|
+
];
|
|
194
|
+
return context.transactionService.buildTransaction({
|
|
195
|
+
feePayer: context.walletPublicKey,
|
|
196
|
+
instructions,
|
|
197
|
+
signer: context.walletManager
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
if (intent.type === "mint-token") {
|
|
201
|
+
const mint = new web3_js_1.PublicKey(intent.mint);
|
|
202
|
+
const destinationOwner = new web3_js_1.PublicKey(intent.toOwner);
|
|
203
|
+
const destination = await context.tokenService.ensureAtaInstruction({
|
|
204
|
+
mint,
|
|
205
|
+
owner: destinationOwner,
|
|
206
|
+
payer: context.walletPublicKey
|
|
207
|
+
});
|
|
208
|
+
const instructions = [
|
|
209
|
+
...(destination.createInstruction ? [destination.createInstruction] : []),
|
|
210
|
+
context.tokenService.buildMintToInstruction({
|
|
211
|
+
mint,
|
|
212
|
+
destinationAta: destination.address,
|
|
213
|
+
authority: context.walletPublicKey,
|
|
214
|
+
amount: intent.amountRaw
|
|
215
|
+
})
|
|
216
|
+
];
|
|
217
|
+
return context.transactionService.buildTransaction({
|
|
218
|
+
feePayer: context.walletPublicKey,
|
|
219
|
+
instructions,
|
|
220
|
+
signer: context.walletManager
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
throw new Error(`Unsupported intent type: ${intent.type}`);
|
|
224
|
+
}
|
|
225
|
+
executePreparedTransaction(runtime, input) {
|
|
226
|
+
const sandboxExecutor = input.policyConfigPatch
|
|
227
|
+
? this.createSandboxExecutor(runtime, input.policyConfigPatch)
|
|
228
|
+
: runtime.sandboxExecutor;
|
|
229
|
+
return sandboxExecutor.executePreparedTransaction({
|
|
230
|
+
confirmationStrategy: input.confirmationStrategy,
|
|
231
|
+
inspectionContext: input.inspectionContext,
|
|
232
|
+
transaction: input.transaction
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
createSandboxExecutor(runtime, patch) {
|
|
236
|
+
const merged = this.mergePolicyConfig(runtime.context.policyConfig, patch);
|
|
237
|
+
const policyEngine = new policy_1.PolicyEngine({
|
|
238
|
+
...merged,
|
|
239
|
+
approvalMode: runtime.approvalMode
|
|
240
|
+
});
|
|
241
|
+
return new policy_1.SandboxExecutor(policyEngine, runtime.context.transactionService, runtime.approvalMode, runtime.approvalCallback);
|
|
242
|
+
}
|
|
243
|
+
mergePolicyConfig(base, patch) {
|
|
244
|
+
return {
|
|
245
|
+
...base,
|
|
246
|
+
limits: {
|
|
247
|
+
...base.limits,
|
|
248
|
+
...patch.limits
|
|
249
|
+
},
|
|
250
|
+
rules: {
|
|
251
|
+
...base.rules,
|
|
252
|
+
...patch.rules,
|
|
253
|
+
allowedMintAddresses: this.mergeUnique(base.rules.allowedMintAddresses, patch.rules?.allowedMintAddresses),
|
|
254
|
+
allowedProgramIds: this.mergeUnique(base.rules.allowedProgramIds, patch.rules?.allowedProgramIds),
|
|
255
|
+
allowOpaqueProgramIds: this.mergeUnique(base.rules.allowOpaqueProgramIds ?? [], patch.rules?.allowOpaqueProgramIds),
|
|
256
|
+
allowedCloseAccountDestinations: this.mergeUnique(base.rules.allowedCloseAccountDestinations ?? [], patch.rules?.allowedCloseAccountDestinations),
|
|
257
|
+
allowedTransferDestinations: this.mergeUnique(base.rules.allowedTransferDestinations ?? [], patch.rules?.allowedTransferDestinations)
|
|
258
|
+
},
|
|
259
|
+
sessionExpiresAtIso8601: patch.sessionExpiresAtIso8601 ?? base.sessionExpiresAtIso8601
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
mergeUnique(base, extra) {
|
|
263
|
+
return Array.from(new Set([...base, ...(extra ?? [])]));
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
exports.AgentRunner = AgentRunner;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MemoHeartbeatStrategy = void 0;
|
|
4
|
+
class MemoHeartbeatStrategy {
|
|
5
|
+
name = "memo-heartbeat";
|
|
6
|
+
async nextIntents(context) {
|
|
7
|
+
return [
|
|
8
|
+
{
|
|
9
|
+
type: "write-memo",
|
|
10
|
+
memo: `heartbeat:${context.id}:${new Date().toISOString()}`
|
|
11
|
+
}
|
|
12
|
+
];
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
exports.MemoHeartbeatStrategy = MemoHeartbeatStrategy;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SimpleScriptedTransferStrategy = void 0;
|
|
4
|
+
class SimpleScriptedTransferStrategy {
|
|
5
|
+
plan;
|
|
6
|
+
name = "simple-scripted-transfer";
|
|
7
|
+
constructor(plan) {
|
|
8
|
+
this.plan = plan;
|
|
9
|
+
}
|
|
10
|
+
async nextIntents(_context) {
|
|
11
|
+
const intents = [
|
|
12
|
+
{
|
|
13
|
+
type: "transfer-sol",
|
|
14
|
+
to: this.plan.to,
|
|
15
|
+
lamports: this.plan.lamports
|
|
16
|
+
}
|
|
17
|
+
];
|
|
18
|
+
if (this.plan.memo) {
|
|
19
|
+
intents.push({
|
|
20
|
+
type: "write-memo",
|
|
21
|
+
memo: this.plan.memo
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
return intents;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.SimpleScriptedTransferStrategy = SimpleScriptedTransferStrategy;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TokenRebalancerStrategy = void 0;
|
|
4
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
5
|
+
class TokenRebalancerStrategy {
|
|
6
|
+
config;
|
|
7
|
+
name = "token-rebalancer";
|
|
8
|
+
constructor(config) {
|
|
9
|
+
this.config = config;
|
|
10
|
+
}
|
|
11
|
+
async nextIntents(context) {
|
|
12
|
+
const mint = new web3_js_1.PublicKey(this.config.mint);
|
|
13
|
+
const currentBalance = await context.balanceService.getSplTokenBalance({
|
|
14
|
+
owner: context.walletPublicKey,
|
|
15
|
+
mint
|
|
16
|
+
});
|
|
17
|
+
if (currentBalance >= this.config.minBalanceUi) {
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
return [
|
|
21
|
+
{
|
|
22
|
+
type: "create-ata",
|
|
23
|
+
mint: this.config.mint,
|
|
24
|
+
owner: this.config.targetOwner
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
type: "transfer-spl",
|
|
28
|
+
mint: this.config.mint,
|
|
29
|
+
toOwner: this.config.targetOwner,
|
|
30
|
+
amountRaw: this.config.topUpRawAmount
|
|
31
|
+
}
|
|
32
|
+
];
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.TokenRebalancerStrategy = TokenRebalancerStrategy;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TreasuryDistributorStrategy = void 0;
|
|
4
|
+
class TreasuryDistributorStrategy {
|
|
5
|
+
config;
|
|
6
|
+
name = "treasury-distributor";
|
|
7
|
+
constructor(config) {
|
|
8
|
+
this.config = config;
|
|
9
|
+
}
|
|
10
|
+
async nextIntents(_context) {
|
|
11
|
+
return this.config.recipients.flatMap((recipient) => {
|
|
12
|
+
const intents = [
|
|
13
|
+
{
|
|
14
|
+
type: "create-ata",
|
|
15
|
+
mint: this.config.mint,
|
|
16
|
+
owner: recipient
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
type: "transfer-spl",
|
|
20
|
+
mint: this.config.mint,
|
|
21
|
+
toOwner: recipient,
|
|
22
|
+
amountRaw: this.config.amountRawPerRecipient
|
|
23
|
+
}
|
|
24
|
+
];
|
|
25
|
+
return intents;
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.TreasuryDistributorStrategy = TreasuryDistributorStrategy;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UniversalDeFiStrategy = void 0;
|
|
4
|
+
class UniversalDeFiStrategy {
|
|
5
|
+
requests;
|
|
6
|
+
name = "universal-defi";
|
|
7
|
+
constructor(requests) {
|
|
8
|
+
this.requests = requests;
|
|
9
|
+
}
|
|
10
|
+
async nextIntents(_context) {
|
|
11
|
+
return this.requests.map((request) => ({
|
|
12
|
+
type: "defi-capability",
|
|
13
|
+
capability: request.capability,
|
|
14
|
+
protocol: request.protocol,
|
|
15
|
+
snapshot: request.snapshot
|
|
16
|
+
}));
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.UniversalDeFiStrategy = UniversalDeFiStrategy;
|