@prktsol/prkt 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/.env.devnet.all-protocols.example +18 -0
  2. package/.env.devnet.autonomous.example +16 -0
  3. package/.env.devnet.jupiter.example +16 -0
  4. package/.env.devnet.kamino.example +17 -0
  5. package/.env.devnet.marinade.example +16 -0
  6. package/.env.devnet.orca.example +16 -0
  7. package/.env.devnet.raydium.example +17 -0
  8. package/.env.example +32 -0
  9. package/ARCHITECTURE.md +159 -0
  10. package/CLI.md +509 -0
  11. package/CLI_QUICKSTART.md +108 -0
  12. package/COMPATIBILITY.md +103 -0
  13. package/DEVNET_PROTOCOL_ADDRESSES.md +72 -0
  14. package/README.md +339 -0
  15. package/dist/agent/AgentManager.js +166 -0
  16. package/dist/agent/AgentRuntime.js +92 -0
  17. package/dist/agent/DecisionEngine.js +95 -0
  18. package/dist/agent/MockPriceFeed.js +13 -0
  19. package/dist/agent/intents/types.js +2 -0
  20. package/dist/agent/new-index.js +17 -0
  21. package/dist/agent/policyFactory.js +54 -0
  22. package/dist/agent/registry/AgentRegistry.js +16 -0
  23. package/dist/agent/runner/AgentRunner.js +266 -0
  24. package/dist/agent/strategies/MemoHeartbeatStrategy.js +15 -0
  25. package/dist/agent/strategies/SimpleScriptedTransferStrategy.js +27 -0
  26. package/dist/agent/strategies/TokenRebalancerStrategy.js +35 -0
  27. package/dist/agent/strategies/TreasuryDistributorStrategy.js +29 -0
  28. package/dist/agent/strategies/UniversalDeFiStrategy.js +19 -0
  29. package/dist/agent/types/AgentContext.js +2 -0
  30. package/dist/cli/index.js +1159 -0
  31. package/dist/cli/services/activityStore.js +42 -0
  32. package/dist/cli/services/agentRegistry.js +123 -0
  33. package/dist/cli/services/agentRuntime.js +55 -0
  34. package/dist/cli/services/storagePaths.js +64 -0
  35. package/dist/cli/services/strategyFactory.js +66 -0
  36. package/dist/cli/services/walletCrypto.js +120 -0
  37. package/dist/cli/services/walletRegistry.js +145 -0
  38. package/dist/cli/types.js +2 -0
  39. package/dist/cli/utils/completion.js +62 -0
  40. package/dist/cli/utils/output.js +44 -0
  41. package/dist/config/agentPolicies.js +37 -0
  42. package/dist/config/env.js +249 -0
  43. package/dist/config/policyPresets.js +105 -0
  44. package/dist/core/balances/BalanceService.js +34 -0
  45. package/dist/core/funding/DevnetFundingService.js +105 -0
  46. package/dist/core/idempotency/ExecutionIdempotencyGuard.js +100 -0
  47. package/dist/core/index.js +19 -0
  48. package/dist/core/rpc/RpcClient.js +45 -0
  49. package/dist/core/rpc/RpcFailoverClient.js +97 -0
  50. package/dist/core/tokens/TokenService.js +75 -0
  51. package/dist/core/transactions/PostTransactionVerifier.js +103 -0
  52. package/dist/core/transactions/TransactionService.js +104 -0
  53. package/dist/core/types/services.js +2 -0
  54. package/dist/core/wallet/WalletManager.js +120 -0
  55. package/dist/defi/DeFiCoordinator.js +93 -0
  56. package/dist/defi/DeFiExecutor.js +29 -0
  57. package/dist/defi/DeFiPolicyGuard.js +31 -0
  58. package/dist/defi/adapters/JupiterAdapter.js +25 -0
  59. package/dist/defi/adapters/KaminoAdapter.js +50 -0
  60. package/dist/defi/adapters/MarinadeAdapter.js +25 -0
  61. package/dist/defi/adapters/RaydiumAdapter.js +45 -0
  62. package/dist/defi/kamino/kaminoInstructionCompat.js +24 -0
  63. package/dist/defi/kamino/kaminoLiveConfig.js +60 -0
  64. package/dist/defi/kamino/loadKaminoMarketWithFallback.js +68 -0
  65. package/dist/defi/lp/LpInstructionBuilder.js +2 -0
  66. package/dist/defi/lp/RaydiumLpInstructionBuilder.js +100 -0
  67. package/dist/defi/lp/raydiumDevnetConfig.js +62 -0
  68. package/dist/defi/protocols.js +29 -0
  69. package/dist/defi/types.js +2 -0
  70. package/dist/defi/universal/UniversalDeFiOrchestrator.js +126 -0
  71. package/dist/defi/universal/adapters.js +73 -0
  72. package/dist/defi/universal/index.js +5 -0
  73. package/dist/defi/universal/liveExecutors.js +394 -0
  74. package/dist/defi/universal/types.js +2 -0
  75. package/dist/demo/scenarios/multiAgentDevnetScenario.js +170 -0
  76. package/dist/demo/scripts/runMultiAgentDevnetDemo.js +17 -0
  77. package/dist/dex/JupiterSwapClient.js +59 -0
  78. package/dist/dex/SwapExecutor.js +52 -0
  79. package/dist/index.js +22 -0
  80. package/dist/kora/KoraRpcClient.js +60 -0
  81. package/dist/kora/KoraSigner.js +57 -0
  82. package/dist/kora/gaslessDemo.js +18 -0
  83. package/dist/policy/PolicyGuard.js +158 -0
  84. package/dist/policy/emergencyLock.js +164 -0
  85. package/dist/policy/engine/PolicyEngine.js +237 -0
  86. package/dist/policy/errors.js +10 -0
  87. package/dist/policy/index.js +7 -0
  88. package/dist/policy/sandbox/SandboxExecutor.js +77 -0
  89. package/dist/policy/types/policy.js +2 -0
  90. package/dist/scripts/devnetFunding.js +28 -0
  91. package/dist/scripts/devnetWalletPreflight.js +16 -0
  92. package/dist/scripts/localnetCheck.js +27 -0
  93. package/dist/scripts/managedAgentWallet.js +81 -0
  94. package/dist/scripts/mode.js +6 -0
  95. package/dist/scripts/releaseReadiness.js +93 -0
  96. package/dist/scripts/runAgentUniversalDeFi.js +115 -0
  97. package/dist/scripts/runAutonomousAgentWalletDevnet.js +154 -0
  98. package/dist/scripts/runAutonomousPortfolioDevnet.js +390 -0
  99. package/dist/scripts/runBorrowStrategy.js +35 -0
  100. package/dist/scripts/runDeFiSuite.js +41 -0
  101. package/dist/scripts/runDemoRehearsal.js +111 -0
  102. package/dist/scripts/runDevnetWalletDemo.js +53 -0
  103. package/dist/scripts/runGaslessMemo.js +23 -0
  104. package/dist/scripts/runGaslessWalletDemo.js +60 -0
  105. package/dist/scripts/runKaminoDevnet.js +109 -0
  106. package/dist/scripts/runLpStrategy.js +32 -0
  107. package/dist/scripts/runMarinadeDevnet.js +97 -0
  108. package/dist/scripts/runOrcaLpDevnet.js +208 -0
  109. package/dist/scripts/runRaydiumLpDevnet.js +95 -0
  110. package/dist/scripts/runReleaseReadiness.js +22 -0
  111. package/dist/scripts/runStakeStrategy.js +33 -0
  112. package/dist/scripts/runStressTest.js +41 -0
  113. package/dist/scripts/runTradeLoop.js +53 -0
  114. package/dist/scripts/runUniversalDeFiDemo.js +84 -0
  115. package/dist/scripts/runYieldStrategy.js +33 -0
  116. package/dist/scripts/runtimeFactory.js +27 -0
  117. package/dist/scripts/shared.js +24 -0
  118. package/dist/scripts/simulateAttack.js +40 -0
  119. package/dist/scripts/simulateSwarm.js +106 -0
  120. package/dist/simulation/attack.js +30 -0
  121. package/dist/solana/programs.js +9 -0
  122. package/dist/spl/TokenWallet.js +65 -0
  123. package/dist/types/policy.js +2 -0
  124. package/dist/wallet/WalletManager.js +5 -0
  125. package/package.json +99 -0
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ExecutionIdempotencyGuard = exports.BalanceService = exports.TokenService = exports.PostTransactionVerifier = exports.TransactionService = exports.WalletManager = exports.RpcFailoverClient = exports.RpcClient = void 0;
4
+ var RpcClient_1 = require("./rpc/RpcClient");
5
+ Object.defineProperty(exports, "RpcClient", { enumerable: true, get: function () { return RpcClient_1.RpcClient; } });
6
+ var RpcFailoverClient_1 = require("./rpc/RpcFailoverClient");
7
+ Object.defineProperty(exports, "RpcFailoverClient", { enumerable: true, get: function () { return RpcFailoverClient_1.RpcFailoverClient; } });
8
+ var WalletManager_1 = require("./wallet/WalletManager");
9
+ Object.defineProperty(exports, "WalletManager", { enumerable: true, get: function () { return WalletManager_1.WalletManager; } });
10
+ var TransactionService_1 = require("./transactions/TransactionService");
11
+ Object.defineProperty(exports, "TransactionService", { enumerable: true, get: function () { return TransactionService_1.TransactionService; } });
12
+ var PostTransactionVerifier_1 = require("./transactions/PostTransactionVerifier");
13
+ Object.defineProperty(exports, "PostTransactionVerifier", { enumerable: true, get: function () { return PostTransactionVerifier_1.PostTransactionVerifier; } });
14
+ var TokenService_1 = require("./tokens/TokenService");
15
+ Object.defineProperty(exports, "TokenService", { enumerable: true, get: function () { return TokenService_1.TokenService; } });
16
+ var BalanceService_1 = require("./balances/BalanceService");
17
+ Object.defineProperty(exports, "BalanceService", { enumerable: true, get: function () { return BalanceService_1.BalanceService; } });
18
+ var ExecutionIdempotencyGuard_1 = require("./idempotency/ExecutionIdempotencyGuard");
19
+ Object.defineProperty(exports, "ExecutionIdempotencyGuard", { enumerable: true, get: function () { return ExecutionIdempotencyGuard_1.ExecutionIdempotencyGuard; } });
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RpcClient = void 0;
4
+ const web3_js_1 = require("@solana/web3.js");
5
+ const env_1 = require("../../config/env");
6
+ class RpcClient {
7
+ connection;
8
+ constructor(rpcUrl = (0, env_1.getRpcUrl)(), commitment = "confirmed") {
9
+ this.connection = new web3_js_1.Connection(rpcUrl, commitment);
10
+ }
11
+ get rpcUrl() {
12
+ return this.connection.rpcEndpoint;
13
+ }
14
+ async getLatestBlockhash(commitment = "confirmed") {
15
+ return this.connection.getLatestBlockhash(commitment);
16
+ }
17
+ async getBalance(publicKey, commitment = "confirmed") {
18
+ return this.connection.getBalance(publicKey, commitment);
19
+ }
20
+ async getTokenAccountBalance(publicKey, commitment = "confirmed") {
21
+ return this.connection.getTokenAccountBalance(publicKey, commitment);
22
+ }
23
+ async getAccountInfo(publicKey, commitment = "confirmed") {
24
+ return this.connection.getAccountInfo(publicKey, commitment);
25
+ }
26
+ async sendTransaction(transaction, options) {
27
+ return this.connection.sendTransaction(transaction, options);
28
+ }
29
+ async confirmTransaction(strategy, commitment = "confirmed") {
30
+ if (typeof strategy === "string") {
31
+ return this.connection.confirmTransaction(strategy, commitment);
32
+ }
33
+ return this.connection.confirmTransaction(strategy, commitment);
34
+ }
35
+ async simulateTransaction(transaction, options) {
36
+ return this.connection.simulateTransaction(transaction, {
37
+ commitment: options?.commitment ?? "confirmed",
38
+ sigVerify: options?.sigVerify ?? true
39
+ });
40
+ }
41
+ async requestAirdrop(publicKey, lamports) {
42
+ return this.connection.requestAirdrop(publicKey, lamports);
43
+ }
44
+ }
45
+ exports.RpcClient = RpcClient;
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RpcFailoverClient = void 0;
4
+ const web3_js_1 = require("@solana/web3.js");
5
+ const DEFAULT_MAX_RETRIES = 3;
6
+ const DEFAULT_BASE_DELAY_MS = 500;
7
+ const DEFAULT_MAX_DELAY_MS = 4000;
8
+ /**
9
+ * RPC client with automatic failover from primary to fallback URL,
10
+ * exponential backoff, and random jitter on retries.
11
+ */
12
+ class RpcFailoverClient {
13
+ primaryConnection;
14
+ fallbackConnection;
15
+ maxRetries;
16
+ baseDelayMs;
17
+ maxDelayMs;
18
+ commitment;
19
+ primaryUrl;
20
+ fallbackUrl;
21
+ constructor(config) {
22
+ this.commitment = config.commitment ?? "confirmed";
23
+ this.primaryUrl = config.primaryUrl;
24
+ this.fallbackUrl = config.fallbackUrl ?? null;
25
+ this.primaryConnection = new web3_js_1.Connection(config.primaryUrl, this.commitment);
26
+ this.fallbackConnection = config.fallbackUrl
27
+ ? new web3_js_1.Connection(config.fallbackUrl, this.commitment)
28
+ : null;
29
+ this.maxRetries = config.maxRetries ?? DEFAULT_MAX_RETRIES;
30
+ this.baseDelayMs = config.baseDelayMs ?? DEFAULT_BASE_DELAY_MS;
31
+ this.maxDelayMs = config.maxDelayMs ?? DEFAULT_MAX_DELAY_MS;
32
+ }
33
+ get connection() {
34
+ return this.primaryConnection;
35
+ }
36
+ get rpcUrl() {
37
+ return this.primaryConnection.rpcEndpoint;
38
+ }
39
+ async getLatestBlockhash(commitment = "confirmed") {
40
+ return this.executeWithFailover((conn) => conn.getLatestBlockhash(commitment));
41
+ }
42
+ async getBalance(publicKey, commitment = "confirmed") {
43
+ return this.executeWithFailover((conn) => conn.getBalance(publicKey, commitment));
44
+ }
45
+ async getTokenAccountBalance(publicKey, commitment = "confirmed") {
46
+ return this.executeWithFailover((conn) => conn.getTokenAccountBalance(publicKey, commitment));
47
+ }
48
+ async getAccountInfo(publicKey, commitment = "confirmed") {
49
+ return this.executeWithFailover((conn) => conn.getAccountInfo(publicKey, commitment));
50
+ }
51
+ async sendTransaction(transaction, options) {
52
+ return this.executeWithFailover((conn) => conn.sendTransaction(transaction, options));
53
+ }
54
+ async confirmTransaction(strategy, commitment = "confirmed") {
55
+ return this.executeWithFailover((conn) => conn.confirmTransaction(strategy, commitment));
56
+ }
57
+ async simulateTransaction(transaction, options) {
58
+ return this.executeWithFailover((conn) => conn.simulateTransaction(transaction, {
59
+ commitment: options?.commitment ?? "confirmed",
60
+ sigVerify: options?.sigVerify ?? true
61
+ }));
62
+ }
63
+ async requestAirdrop(publicKey, lamports) {
64
+ return this.executeWithFailover((conn) => conn.requestAirdrop(publicKey, lamports));
65
+ }
66
+ async executeWithFailover(operation) {
67
+ const connections = [this.primaryConnection];
68
+ if (this.fallbackConnection) {
69
+ connections.push(this.fallbackConnection);
70
+ }
71
+ let lastError = null;
72
+ for (const conn of connections) {
73
+ for (let attempt = 0; attempt < this.maxRetries; attempt += 1) {
74
+ try {
75
+ return await operation(conn);
76
+ }
77
+ catch (error) {
78
+ lastError = error instanceof Error ? error : new Error(String(error));
79
+ if (attempt < this.maxRetries - 1) {
80
+ await this.backoff(attempt);
81
+ }
82
+ }
83
+ }
84
+ }
85
+ throw lastError ?? new Error("RPC failover exhausted all retries on all endpoints.");
86
+ }
87
+ async backoff(attempt) {
88
+ const exponentialDelay = this.baseDelayMs * Math.pow(2, attempt);
89
+ const cappedDelay = Math.min(exponentialDelay, this.maxDelayMs);
90
+ const jitter = Math.random() * cappedDelay * 0.3;
91
+ const totalDelay = cappedDelay + jitter;
92
+ await new Promise((resolve) => {
93
+ setTimeout(resolve, totalDelay);
94
+ });
95
+ }
96
+ }
97
+ exports.RpcFailoverClient = RpcFailoverClient;
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TokenService = void 0;
4
+ const spl_token_1 = require("@solana/spl-token");
5
+ const web3_js_1 = require("@solana/web3.js");
6
+ const programs_1 = require("../../solana/programs");
7
+ class TokenService {
8
+ rpcClient;
9
+ constructor(rpcClient) {
10
+ this.rpcClient = rpcClient;
11
+ }
12
+ async getMintDecimals(mint) {
13
+ const mintInfo = await (0, spl_token_1.getMint)(this.rpcClient.connection, mint, "confirmed");
14
+ return mintInfo.decimals;
15
+ }
16
+ findAssociatedTokenAddress(owner, mint) {
17
+ return (0, spl_token_1.getAssociatedTokenAddressSync)(mint, owner, false, programs_1.TOKEN_PROGRAM_ID, programs_1.ASSOCIATED_TOKEN_PROGRAM_ID);
18
+ }
19
+ async ensureAtaInstruction(input) {
20
+ const address = this.findAssociatedTokenAddress(input.owner, input.mint);
21
+ const accountInfo = await this.rpcClient.getAccountInfo(address, "confirmed");
22
+ if (accountInfo) {
23
+ return {
24
+ address,
25
+ createInstruction: null
26
+ };
27
+ }
28
+ return {
29
+ address,
30
+ createInstruction: (0, spl_token_1.createAssociatedTokenAccountInstruction)(input.payer, address, input.owner, input.mint, programs_1.TOKEN_PROGRAM_ID, programs_1.ASSOCIATED_TOKEN_PROGRAM_ID)
31
+ };
32
+ }
33
+ buildWrapSolInstructions(input) {
34
+ if (!Number.isInteger(input.amountLamports) || input.amountLamports <= 0) {
35
+ throw new Error("Wrap SOL amount must be a positive integer lamport value.");
36
+ }
37
+ const associatedTokenAddress = this.findAssociatedTokenAddress(input.wallet.publicKey, programs_1.NATIVE_MINT);
38
+ const instructions = [];
39
+ if (input.createAtaIfMissing) {
40
+ instructions.push((0, spl_token_1.createAssociatedTokenAccountInstruction)(input.wallet.publicKey, associatedTokenAddress, input.wallet.publicKey, programs_1.NATIVE_MINT, programs_1.TOKEN_PROGRAM_ID, programs_1.ASSOCIATED_TOKEN_PROGRAM_ID));
41
+ }
42
+ instructions.push(web3_js_1.SystemProgram.transfer({
43
+ fromPubkey: input.wallet.publicKey,
44
+ toPubkey: associatedTokenAddress,
45
+ lamports: input.amountLamports
46
+ }), (0, spl_token_1.createSyncNativeInstruction)(associatedTokenAddress, programs_1.TOKEN_PROGRAM_ID));
47
+ return {
48
+ associatedTokenAddress,
49
+ createdAssociatedTokenAccount: input.createAtaIfMissing,
50
+ instructions
51
+ };
52
+ }
53
+ async buildCreateMintInstructions(input) {
54
+ const mintKeypair = web3_js_1.Keypair.generate();
55
+ const rent = await this.rpcClient.connection.getMinimumBalanceForRentExemption(82);
56
+ const instructions = [
57
+ web3_js_1.SystemProgram.createAccount({
58
+ fromPubkey: input.payer,
59
+ newAccountPubkey: mintKeypair.publicKey,
60
+ lamports: rent,
61
+ programId: programs_1.TOKEN_PROGRAM_ID,
62
+ space: 82
63
+ }),
64
+ (0, spl_token_1.createInitializeMint2Instruction)(mintKeypair.publicKey, input.decimals, input.mintAuthority, input.mintAuthority, programs_1.TOKEN_PROGRAM_ID)
65
+ ];
66
+ return {
67
+ mintKeypair,
68
+ instructions
69
+ };
70
+ }
71
+ buildMintToInstruction(input) {
72
+ return (0, spl_token_1.createMintToInstruction)(input.mint, input.destinationAta, input.authority, input.amount, [], programs_1.TOKEN_PROGRAM_ID);
73
+ }
74
+ }
75
+ exports.TokenService = TokenService;
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PostTransactionVerifier = void 0;
4
+ const SOL_DECIMALS = 9;
5
+ class PostTransactionVerifier {
6
+ rpcClient;
7
+ tokenService;
8
+ constructor(rpcClient, tokenService) {
9
+ this.rpcClient = rpcClient;
10
+ this.tokenService = tokenService;
11
+ }
12
+ async snapshotSolBalance(owner, label = "SOL balance") {
13
+ const beforeLamports = await this.rpcClient.getBalance(owner, "confirmed");
14
+ return {
15
+ address: owner,
16
+ beforeRaw: BigInt(beforeLamports),
17
+ decimals: SOL_DECIMALS,
18
+ kind: "sol",
19
+ label
20
+ };
21
+ }
22
+ async snapshotSplBalanceForOwner(input) {
23
+ const tokenAccount = this.tokenService.findAssociatedTokenAddress(input.owner, input.mint);
24
+ return this.snapshotSplTokenAccount({
25
+ label: input.label ?? `Token balance for ${input.mint.toBase58()}`,
26
+ mint: input.mint,
27
+ tokenAccount
28
+ });
29
+ }
30
+ async snapshotSplTokenAccount(input) {
31
+ const decimals = await this.tokenService.getMintDecimals(input.mint);
32
+ const beforeRaw = await this.getSplTokenBalanceRaw(input.tokenAccount);
33
+ return {
34
+ address: input.tokenAccount,
35
+ beforeRaw,
36
+ decimals,
37
+ kind: "spl",
38
+ label: input.label ?? `Token account ${input.tokenAccount.toBase58()}`
39
+ };
40
+ }
41
+ async assertBalanceChanges(expectations) {
42
+ const reports = await Promise.all(expectations.map(async (expectation) => this.buildReport(expectation)));
43
+ for (const [index, report] of reports.entries()) {
44
+ const expectation = expectations[index];
45
+ if (expectation.minIncreaseRaw !== undefined && report.deltaRaw < expectation.minIncreaseRaw) {
46
+ throw new Error(`${report.label} verification failed: expected increase >= ${expectation.minIncreaseRaw.toString()} raw, got ${report.deltaRaw.toString()} raw (${report.beforeUi} -> ${report.afterUi}).`);
47
+ }
48
+ if (expectation.maxDecreaseRaw !== undefined &&
49
+ report.deltaRaw < 0n &&
50
+ -report.deltaRaw > expectation.maxDecreaseRaw) {
51
+ throw new Error(`${report.label} verification failed: expected decrease <= ${expectation.maxDecreaseRaw.toString()} raw, got ${(-report.deltaRaw).toString()} raw (${report.beforeUi} -> ${report.afterUi}).`);
52
+ }
53
+ }
54
+ return reports;
55
+ }
56
+ async buildReport(expectation) {
57
+ const afterRaw = await this.readCurrentRaw(expectation.snapshot);
58
+ const deltaRaw = afterRaw - expectation.snapshot.beforeRaw;
59
+ return {
60
+ address: expectation.snapshot.address.toBase58(),
61
+ afterRaw,
62
+ afterUi: formatRawAmount(afterRaw, expectation.snapshot.decimals),
63
+ beforeRaw: expectation.snapshot.beforeRaw,
64
+ beforeUi: formatRawAmount(expectation.snapshot.beforeRaw, expectation.snapshot.decimals),
65
+ deltaRaw,
66
+ deltaUi: formatSignedRawAmount(deltaRaw, expectation.snapshot.decimals),
67
+ kind: expectation.snapshot.kind,
68
+ label: expectation.label ?? expectation.snapshot.label
69
+ };
70
+ }
71
+ async readCurrentRaw(snapshot) {
72
+ if (snapshot.kind === "sol") {
73
+ return BigInt(await this.rpcClient.getBalance(snapshot.address, "confirmed"));
74
+ }
75
+ return this.getSplTokenBalanceRaw(snapshot.address);
76
+ }
77
+ async getSplTokenBalanceRaw(tokenAccount) {
78
+ const account = await this.rpcClient.getAccountInfo(tokenAccount, "confirmed");
79
+ if (!account) {
80
+ return 0n;
81
+ }
82
+ const tokenBalance = await this.rpcClient.getTokenAccountBalance(tokenAccount, "confirmed");
83
+ return BigInt(tokenBalance.value.amount);
84
+ }
85
+ }
86
+ exports.PostTransactionVerifier = PostTransactionVerifier;
87
+ function formatSignedRawAmount(raw, decimals) {
88
+ const sign = raw < 0n ? "-" : "+";
89
+ const absolute = raw < 0n ? -raw : raw;
90
+ return `${sign}${formatRawAmount(absolute, decimals)}`;
91
+ }
92
+ function formatRawAmount(raw, decimals) {
93
+ const negative = raw < 0n;
94
+ const absolute = negative ? -raw : raw;
95
+ const divisor = 10n ** BigInt(decimals);
96
+ const whole = absolute / divisor;
97
+ const fraction = absolute % divisor;
98
+ if (fraction === 0n) {
99
+ return `${negative ? "-" : ""}${whole.toString()}`;
100
+ }
101
+ const fractionString = fraction.toString().padStart(decimals, "0").replace(/0+$/u, "");
102
+ return `${negative ? "-" : ""}${whole.toString()}.${fractionString}`;
103
+ }
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TransactionService = void 0;
4
+ const web3_js_1 = require("@solana/web3.js");
5
+ const spl_token_1 = require("@solana/spl-token");
6
+ const programs_1 = require("../../solana/programs");
7
+ const LAMPORTS_PER_SOL = 1_000_000_000;
8
+ class TransactionService {
9
+ rpcClient;
10
+ constructor(rpcClient) {
11
+ this.rpcClient = rpcClient;
12
+ }
13
+ async buildTransaction(input) {
14
+ const latestBlockhash = await this.rpcClient.getLatestBlockhash("confirmed");
15
+ const message = new web3_js_1.TransactionMessage({
16
+ payerKey: input.feePayer,
17
+ recentBlockhash: latestBlockhash.blockhash,
18
+ instructions: input.instructions
19
+ }).compileToV0Message();
20
+ const transaction = new web3_js_1.VersionedTransaction(message);
21
+ const signedTransaction = await input.signer.signTransaction(transaction);
22
+ return {
23
+ confirmationStrategy: {
24
+ blockhash: latestBlockhash.blockhash,
25
+ lastValidBlockHeight: latestBlockhash.lastValidBlockHeight,
26
+ signature: ""
27
+ },
28
+ instructionsCount: input.instructions.length,
29
+ transaction: signedTransaction
30
+ };
31
+ }
32
+ buildSolTransferInstruction(input) {
33
+ return web3_js_1.SystemProgram.transfer({
34
+ fromPubkey: input.from,
35
+ toPubkey: input.to,
36
+ lamports: input.lamports
37
+ });
38
+ }
39
+ buildSolTransferInstructionInSol(input) {
40
+ const lamports = Math.round(input.amountSol * LAMPORTS_PER_SOL);
41
+ return this.buildSolTransferInstruction({
42
+ from: input.from,
43
+ to: input.to,
44
+ lamports
45
+ });
46
+ }
47
+ buildSplTransferInstruction(input) {
48
+ return (0, spl_token_1.createTransferInstruction)(input.sourceAta, input.destinationAta, input.owner, input.amount, input.multiSigners, input.programId);
49
+ }
50
+ buildSplTransferCheckedInstruction(input) {
51
+ return (0, spl_token_1.createTransferCheckedInstruction)(input.sourceAta, input.mint, input.destinationAta, input.owner, input.amount, input.decimals, input.multiSigners, input.programId);
52
+ }
53
+ buildMemoInstruction(memo) {
54
+ return new web3_js_1.TransactionInstruction({
55
+ programId: programs_1.MEMO_PROGRAM_ID,
56
+ keys: [],
57
+ data: Buffer.from(memo, "utf8")
58
+ });
59
+ }
60
+ async simulate(transaction) {
61
+ const simulation = await this.rpcClient.simulateTransaction(transaction, {
62
+ commitment: "confirmed",
63
+ sigVerify: true
64
+ });
65
+ return {
66
+ err: simulation.value.err,
67
+ logs: simulation.value.logs ?? null,
68
+ unitsConsumed: simulation.value.unitsConsumed ?? null
69
+ };
70
+ }
71
+ async sendAndConfirm(input) {
72
+ const sendable = this.normalizeSendable(input);
73
+ const signature = await this.rpcClient.sendTransaction(sendable.transaction, {
74
+ maxRetries: 3,
75
+ preflightCommitment: "confirmed"
76
+ });
77
+ const confirmation = await this.rpcClient.confirmTransaction(this.resolveConfirmationTarget(sendable.confirmationStrategy, signature), "confirmed");
78
+ return {
79
+ signature,
80
+ slot: confirmation.context.slot
81
+ };
82
+ }
83
+ normalizeSendable(input) {
84
+ if (input instanceof web3_js_1.VersionedTransaction) {
85
+ return {
86
+ transaction: input
87
+ };
88
+ }
89
+ return input;
90
+ }
91
+ resolveConfirmationTarget(confirmationStrategy, signature) {
92
+ if (!confirmationStrategy) {
93
+ return signature;
94
+ }
95
+ if (typeof confirmationStrategy === "string") {
96
+ return confirmationStrategy;
97
+ }
98
+ return {
99
+ ...confirmationStrategy,
100
+ signature
101
+ };
102
+ }
103
+ }
104
+ exports.TransactionService = TransactionService;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WalletManager = void 0;
4
+ const web3_js_1 = require("@solana/web3.js");
5
+ const env_1 = require("../../config/env");
6
+ class LocalTransactionSigner {
7
+ keypair;
8
+ source;
9
+ constructor(keypair, source) {
10
+ this.keypair = keypair;
11
+ this.source = source;
12
+ }
13
+ get publicKey() {
14
+ return this.keypair.publicKey;
15
+ }
16
+ async signTransaction(transaction) {
17
+ transaction.sign([this.keypair]);
18
+ return transaction;
19
+ }
20
+ }
21
+ class RemoteTransactionSigner {
22
+ publicKey;
23
+ bearerToken;
24
+ url;
25
+ source = "remote";
26
+ constructor(publicKey, bearerToken, url) {
27
+ this.publicKey = publicKey;
28
+ this.bearerToken = bearerToken;
29
+ this.url = url;
30
+ }
31
+ async signTransaction(transaction) {
32
+ const response = await fetch(this.url, {
33
+ body: JSON.stringify({
34
+ publicKey: this.publicKey.toBase58(),
35
+ transactionBase64: Buffer.from(transaction.serialize()).toString("base64")
36
+ }),
37
+ headers: {
38
+ Authorization: `Bearer ${this.bearerToken}`,
39
+ "Content-Type": "application/json"
40
+ },
41
+ method: "POST"
42
+ });
43
+ if (!response.ok) {
44
+ const message = await response.text();
45
+ throw new Error(`Remote signer request failed (${response.status} ${response.statusText}): ${message || "no response body"}`);
46
+ }
47
+ const payload = (await response.json());
48
+ const signedTransactionBase64 = payload.signedTransactionBase64 ?? payload.transactionBase64 ?? null;
49
+ if (!signedTransactionBase64) {
50
+ throw new Error("Remote signer response did not include signedTransactionBase64.");
51
+ }
52
+ return web3_js_1.VersionedTransaction.deserialize(Buffer.from(signedTransactionBase64, "base64"));
53
+ }
54
+ }
55
+ class WalletManager {
56
+ signer;
57
+ constructor(signer) {
58
+ this.signer = signer;
59
+ }
60
+ static generate() {
61
+ return new WalletManager(new LocalTransactionSigner(web3_js_1.Keypair.generate(), "generated"));
62
+ }
63
+ static loadFromEnv() {
64
+ const secretKey = (0, env_1.getOptionalSecretKey)();
65
+ if (!secretKey) {
66
+ throw new Error("AGENT_PRIVATE_KEY is not configured.");
67
+ }
68
+ return new WalletManager(new LocalTransactionSigner(web3_js_1.Keypair.fromSecretKey(secretKey), "env"));
69
+ }
70
+ static loadRemoteSigner() {
71
+ const remoteSigner = (0, env_1.getRemoteSignerConfig)();
72
+ if (!remoteSigner) {
73
+ throw new Error("Remote signer is not configured.");
74
+ }
75
+ return new WalletManager(new RemoteTransactionSigner(remoteSigner.publicKey, remoteSigner.bearerToken, remoteSigner.url));
76
+ }
77
+ static loadConfigured() {
78
+ const remoteSigner = (0, env_1.getRemoteSignerConfig)();
79
+ if (remoteSigner) {
80
+ return new WalletManager(new RemoteTransactionSigner(remoteSigner.publicKey, remoteSigner.bearerToken, remoteSigner.url));
81
+ }
82
+ return WalletManager.loadFromEnv();
83
+ }
84
+ static loadOrGenerate() {
85
+ const remoteSigner = (0, env_1.getRemoteSignerConfig)();
86
+ if (remoteSigner) {
87
+ return new WalletManager(new RemoteTransactionSigner(remoteSigner.publicKey, remoteSigner.bearerToken, remoteSigner.url));
88
+ }
89
+ const secretKey = (0, env_1.getOptionalSecretKey)();
90
+ if (!secretKey) {
91
+ return WalletManager.generate();
92
+ }
93
+ return new WalletManager(new LocalTransactionSigner(web3_js_1.Keypair.fromSecretKey(secretKey), "env"));
94
+ }
95
+ static fromSecretKey(secretKey, source = "env") {
96
+ return new WalletManager(new LocalTransactionSigner(web3_js_1.Keypair.fromSecretKey(secretKey), source));
97
+ }
98
+ get payer() {
99
+ if (!(this.signer instanceof LocalTransactionSigner)) {
100
+ throw new Error("This wallet uses a remote signer and does not expose a local keypair.");
101
+ }
102
+ return this.signer.keypair;
103
+ }
104
+ get publicKey() {
105
+ return this.signer.publicKey;
106
+ }
107
+ get source() {
108
+ return this.signer.source;
109
+ }
110
+ async signTransaction(transaction) {
111
+ return this.signer.signTransaction(transaction);
112
+ }
113
+ toSafeSummary() {
114
+ return {
115
+ publicKey: this.publicKey.toBase58(),
116
+ source: this.source
117
+ };
118
+ }
119
+ }
120
+ exports.WalletManager = WalletManager;
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DeFiCoordinator = void 0;
4
+ const policyFactory_1 = require("../agent/policyFactory");
5
+ const DeFiExecutor_1 = require("./DeFiExecutor");
6
+ const KaminoAdapter_1 = require("./adapters/KaminoAdapter");
7
+ const JupiterAdapter_1 = require("./adapters/JupiterAdapter");
8
+ const MarinadeAdapter_1 = require("./adapters/MarinadeAdapter");
9
+ const RaydiumAdapter_1 = require("./adapters/RaydiumAdapter");
10
+ const protocols_1 = require("./protocols");
11
+ class DeFiCoordinator {
12
+ walletManager;
13
+ koraSigner;
14
+ logger;
15
+ policy;
16
+ kaminoAdapter = new KaminoAdapter_1.KaminoAdapter();
17
+ jupiterAdapter = new JupiterAdapter_1.JupiterAdapter();
18
+ marinadeAdapter = new MarinadeAdapter_1.MarinadeAdapter();
19
+ raydiumAdapter = new RaydiumAdapter_1.RaydiumAdapter();
20
+ constructor(walletManager, koraSigner, logger = () => undefined, policy = (0, policyFactory_1.createDefaultAgentPolicy)({
21
+ maxSpend: {
22
+ lamports: 2_000_000
23
+ }
24
+ })) {
25
+ this.walletManager = walletManager;
26
+ this.koraSigner = koraSigner;
27
+ this.logger = logger;
28
+ this.policy = policy;
29
+ }
30
+ async runStakingStrategy(snapshot) {
31
+ const intent = this.marinadeAdapter.buildStakeIntent(snapshot);
32
+ if (!intent) {
33
+ this.logger("Staking strategy -> HOLD (Marinade adapter found insufficient idle SOL).");
34
+ return null;
35
+ }
36
+ return this.execute(intent);
37
+ }
38
+ async runLiquidityStrategy(snapshot) {
39
+ const intent = this.raydiumAdapter.buildAddLiquidityIntent(snapshot);
40
+ if (!intent) {
41
+ this.logger("LP strategy -> HOLD (Raydium adapter found pool pricing out of range).");
42
+ return null;
43
+ }
44
+ return this.execute(intent);
45
+ }
46
+ async runLendingStrategy(snapshot) {
47
+ const intent = this.kaminoAdapter.buildDepositIntent(snapshot);
48
+ if (!intent) {
49
+ this.logger("Lending strategy -> HOLD (Kamino adapter found insufficient idle USDC).");
50
+ return null;
51
+ }
52
+ return this.execute(intent);
53
+ }
54
+ async runBorrowingStrategy(snapshot) {
55
+ const intent = this.kaminoAdapter.buildBorrowIntent(snapshot);
56
+ if (!intent) {
57
+ this.logger("Borrowing strategy -> HOLD (Kamino adapter found insufficient collateral or borrow demand).");
58
+ return null;
59
+ }
60
+ return this.execute(intent);
61
+ }
62
+ async runTradeStrategy(snapshot) {
63
+ const intent = this.jupiterAdapter.buildTradeIntent(snapshot);
64
+ if (!intent) {
65
+ this.logger("Trade strategy -> HOLD (Jupiter adapter found no favorable setup).");
66
+ return null;
67
+ }
68
+ return this.execute(intent);
69
+ }
70
+ async runFullSuite(snapshot) {
71
+ const results = await Promise.all([
72
+ this.runTradeStrategy(snapshot),
73
+ this.runStakingStrategy(snapshot),
74
+ this.runLiquidityStrategy(snapshot),
75
+ this.runLendingStrategy(snapshot),
76
+ this.runBorrowingStrategy(snapshot)
77
+ ]);
78
+ return results.filter((result) => result !== null);
79
+ }
80
+ async execute(intent) {
81
+ const preset = protocols_1.PROTOCOL_PRESETS[intent.protocol];
82
+ this.logger(`${preset.label} strategy -> Policy Check -> Gasless Execution (${intent.action} on ${intent.marketId}).`);
83
+ const executor = new DeFiExecutor_1.DeFiExecutor(this.policy);
84
+ const result = await executor.executeIntent({
85
+ intent,
86
+ koraSigner: this.koraSigner,
87
+ walletManager: this.walletManager
88
+ });
89
+ this.logger(`${preset.label} strategy -> Executed ${result.mock ? "mock " : ""}${result.action} ${result.signature}`);
90
+ return result;
91
+ }
92
+ }
93
+ exports.DeFiCoordinator = DeFiCoordinator;