@elizaos/plugin-steward-app 2.0.3-beta.5 → 2.0.3-beta.7

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 (219) hide show
  1. package/dist/ApprovalQueue.d.ts +18 -0
  2. package/dist/ApprovalQueue.d.ts.map +1 -0
  3. package/dist/ApprovalQueue.js +420 -0
  4. package/dist/ApprovalQueue.js.map +1 -0
  5. package/dist/StewardLogo.d.ts +11 -0
  6. package/dist/StewardLogo.d.ts.map +1 -0
  7. package/dist/StewardLogo.js +36 -0
  8. package/dist/StewardLogo.js.map +1 -0
  9. package/dist/StewardView.d.ts +13 -0
  10. package/dist/StewardView.d.ts.map +1 -0
  11. package/dist/StewardView.helpers.d.ts +15 -0
  12. package/dist/StewardView.helpers.d.ts.map +1 -0
  13. package/dist/StewardView.helpers.js +45 -0
  14. package/dist/StewardView.helpers.js.map +1 -0
  15. package/dist/StewardView.interact.d.ts +2 -0
  16. package/dist/StewardView.interact.d.ts.map +1 -0
  17. package/dist/StewardView.interact.js +54 -0
  18. package/dist/StewardView.interact.js.map +1 -0
  19. package/dist/StewardView.js +249 -0
  20. package/dist/StewardView.js.map +1 -0
  21. package/dist/TransactionHistory.d.ts +22 -0
  22. package/dist/TransactionHistory.d.ts.map +1 -0
  23. package/dist/TransactionHistory.js +361 -0
  24. package/dist/TransactionHistory.js.map +1 -0
  25. package/dist/__fixtures__/steward-sdk-fixtures.d.ts +10 -0
  26. package/dist/__fixtures__/steward-sdk-fixtures.d.ts.map +1 -0
  27. package/dist/__fixtures__/steward-sdk-fixtures.js +60 -0
  28. package/dist/__fixtures__/steward-sdk-fixtures.js.map +1 -0
  29. package/dist/actions/wallet-action-shared.d.ts +15 -0
  30. package/dist/actions/wallet-action-shared.d.ts.map +1 -0
  31. package/dist/actions/wallet-action-shared.js +16 -0
  32. package/dist/actions/wallet-action-shared.js.map +1 -0
  33. package/dist/api/binance-skill-helpers.d.ts +21 -0
  34. package/dist/api/binance-skill-helpers.d.ts.map +1 -0
  35. package/dist/api/binance-skill-helpers.js +790 -0
  36. package/dist/api/binance-skill-helpers.js.map +1 -0
  37. package/dist/api/bsc-trade.d.ts +36 -0
  38. package/dist/api/bsc-trade.d.ts.map +1 -0
  39. package/dist/api/bsc-trade.js +796 -0
  40. package/dist/api/bsc-trade.js.map +1 -0
  41. package/dist/api/trade-safety.d.ts +35 -0
  42. package/dist/api/trade-safety.d.ts.map +1 -0
  43. package/dist/api/trade-safety.js +56 -0
  44. package/dist/api/trade-safety.js.map +1 -0
  45. package/dist/api/tx-service.d.ts +53 -0
  46. package/dist/api/tx-service.d.ts.map +1 -0
  47. package/dist/api/tx-service.js +206 -0
  48. package/dist/api/tx-service.js.map +1 -0
  49. package/dist/api/wallet-bsc-routes.d.ts +63 -0
  50. package/dist/api/wallet-bsc-routes.d.ts.map +1 -0
  51. package/dist/api/wallet-bsc-routes.js +337 -0
  52. package/dist/api/wallet-bsc-routes.js.map +1 -0
  53. package/dist/api/wallet-capability.d.ts +2 -0
  54. package/dist/api/wallet-capability.d.ts.map +1 -0
  55. package/dist/api/wallet-capability.js +15 -0
  56. package/dist/api/wallet-capability.js.map +1 -0
  57. package/dist/api/wallet-dex-prices.d.ts +43 -0
  58. package/dist/api/wallet-dex-prices.d.ts.map +1 -0
  59. package/dist/api/wallet-dex-prices.js +132 -0
  60. package/dist/api/wallet-dex-prices.js.map +1 -0
  61. package/dist/api/wallet-evm-balance.d.ts +72 -0
  62. package/dist/api/wallet-evm-balance.d.ts.map +1 -0
  63. package/dist/api/wallet-evm-balance.js +697 -0
  64. package/dist/api/wallet-evm-balance.js.map +1 -0
  65. package/dist/api/wallet-routes.d.ts +27 -0
  66. package/dist/api/wallet-routes.d.ts.map +1 -0
  67. package/dist/api/wallet-routes.js +556 -0
  68. package/dist/api/wallet-routes.js.map +1 -0
  69. package/dist/api/wallet-rpc.d.ts +73 -0
  70. package/dist/api/wallet-rpc.d.ts.map +1 -0
  71. package/dist/api/wallet-rpc.js +460 -0
  72. package/dist/api/wallet-rpc.js.map +1 -0
  73. package/dist/api/wallet-trade-routes.d.ts +104 -0
  74. package/dist/api/wallet-trade-routes.d.ts.map +1 -0
  75. package/dist/api/wallet-trade-routes.js +353 -0
  76. package/dist/api/wallet-trade-routes.js.map +1 -0
  77. package/dist/api/wallet-trading-profile.d.ts +31 -0
  78. package/dist/api/wallet-trading-profile.d.ts.map +1 -0
  79. package/dist/api/wallet-trading-profile.js +500 -0
  80. package/dist/api/wallet-trading-profile.js.map +1 -0
  81. package/dist/api/wallet.d.ts +60 -0
  82. package/dist/api/wallet.d.ts.map +1 -0
  83. package/dist/api/wallet.js +617 -0
  84. package/dist/api/wallet.js.map +1 -0
  85. package/dist/chain-utils.d.ts +10 -0
  86. package/dist/chain-utils.d.ts.map +1 -0
  87. package/dist/chain-utils.js +81 -0
  88. package/dist/chain-utils.js.map +1 -0
  89. package/dist/components/StewardSpatialView.d.ts +74 -0
  90. package/dist/components/StewardSpatialView.d.ts.map +1 -0
  91. package/dist/components/StewardSpatialView.js +309 -0
  92. package/dist/components/StewardSpatialView.js.map +1 -0
  93. package/dist/index.d.ts +20 -0
  94. package/dist/index.d.ts.map +1 -0
  95. package/dist/index.js +77 -0
  96. package/dist/index.js.map +1 -0
  97. package/dist/plugin.d.ts +21 -0
  98. package/dist/plugin.d.ts.map +1 -0
  99. package/dist/plugin.js +319 -0
  100. package/dist/plugin.js.map +1 -0
  101. package/dist/providers/steward-balance.d.ts +12 -0
  102. package/dist/providers/steward-balance.d.ts.map +1 -0
  103. package/dist/providers/steward-balance.js +85 -0
  104. package/dist/providers/steward-balance.js.map +1 -0
  105. package/dist/providers/steward-receive-address.d.ts +12 -0
  106. package/dist/providers/steward-receive-address.d.ts.map +1 -0
  107. package/dist/providers/steward-receive-address.js +47 -0
  108. package/dist/providers/steward-receive-address.js.map +1 -0
  109. package/dist/register-routes.d.ts +2 -0
  110. package/dist/register-routes.d.ts.map +1 -0
  111. package/dist/register-routes.js +6 -0
  112. package/dist/register-routes.js.map +1 -0
  113. package/dist/register-terminal-view.d.ts +15 -0
  114. package/dist/register-terminal-view.d.ts.map +1 -0
  115. package/dist/register-terminal-view.js +34 -0
  116. package/dist/register-terminal-view.js.map +1 -0
  117. package/dist/routes/steward-bridge.d.ts +202 -0
  118. package/dist/routes/steward-bridge.d.ts.map +1 -0
  119. package/dist/routes/steward-bridge.js +776 -0
  120. package/dist/routes/steward-bridge.js.map +1 -0
  121. package/dist/routes/steward-compat-routes.d.ts +21 -0
  122. package/dist/routes/steward-compat-routes.d.ts.map +1 -0
  123. package/dist/routes/steward-compat-routes.js +350 -0
  124. package/dist/routes/steward-compat-routes.js.map +1 -0
  125. package/dist/routes/wallet-browser-compat-routes.d.ts +6 -0
  126. package/dist/routes/wallet-browser-compat-routes.d.ts.map +1 -0
  127. package/dist/routes/wallet-browser-compat-routes.js +402 -0
  128. package/dist/routes/wallet-browser-compat-routes.js.map +1 -0
  129. package/dist/routes/wallet-bsc-core-routes.d.ts +15 -0
  130. package/dist/routes/wallet-bsc-core-routes.d.ts.map +1 -0
  131. package/dist/routes/wallet-bsc-core-routes.js +59 -0
  132. package/dist/routes/wallet-bsc-core-routes.js.map +1 -0
  133. package/dist/routes/wallet-compat-routes.d.ts +13 -0
  134. package/dist/routes/wallet-compat-routes.d.ts.map +1 -0
  135. package/dist/routes/wallet-compat-routes.js +206 -0
  136. package/dist/routes/wallet-compat-routes.js.map +1 -0
  137. package/dist/routes/wallet-core-routes.d.ts +16 -0
  138. package/dist/routes/wallet-core-routes.d.ts.map +1 -0
  139. package/dist/routes/wallet-core-routes.js +48 -0
  140. package/dist/routes/wallet-core-routes.js.map +1 -0
  141. package/dist/routes/wallet-trade-compat-routes.d.ts +11 -0
  142. package/dist/routes/wallet-trade-compat-routes.d.ts.map +1 -0
  143. package/dist/routes/wallet-trade-compat-routes.js +570 -0
  144. package/dist/routes/wallet-trade-compat-routes.js.map +1 -0
  145. package/dist/security/hydrate-wallet-keys-from-platform-store.d.ts +7 -0
  146. package/dist/security/hydrate-wallet-keys-from-platform-store.d.ts.map +1 -0
  147. package/dist/security/hydrate-wallet-keys-from-platform-store.js +43 -0
  148. package/dist/security/hydrate-wallet-keys-from-platform-store.js.map +1 -0
  149. package/dist/security/wallet-os-store-actions.d.ts +14 -0
  150. package/dist/security/wallet-os-store-actions.d.ts.map +1 -0
  151. package/dist/security/wallet-os-store-actions.js +63 -0
  152. package/dist/security/wallet-os-store-actions.js.map +1 -0
  153. package/dist/services/steward-credentials.d.ts +2 -0
  154. package/dist/services/steward-credentials.d.ts.map +1 -0
  155. package/dist/services/steward-credentials.js +2 -0
  156. package/dist/services/steward-credentials.js.map +1 -0
  157. package/dist/services/steward-evm-account.d.ts +75 -0
  158. package/dist/services/steward-evm-account.d.ts.map +1 -0
  159. package/dist/services/steward-evm-account.js +279 -0
  160. package/dist/services/steward-evm-account.js.map +1 -0
  161. package/dist/services/steward-evm-bridge.d.ts +36 -0
  162. package/dist/services/steward-evm-bridge.d.ts.map +1 -0
  163. package/dist/services/steward-evm-bridge.js +78 -0
  164. package/dist/services/steward-evm-bridge.js.map +1 -0
  165. package/dist/services/steward-sidecar/health-check.d.ts +2 -0
  166. package/dist/services/steward-sidecar/health-check.d.ts.map +1 -0
  167. package/dist/services/steward-sidecar/health-check.js +2 -0
  168. package/dist/services/steward-sidecar/health-check.js.map +1 -0
  169. package/dist/services/steward-sidecar/helpers.d.ts +2 -0
  170. package/dist/services/steward-sidecar/helpers.d.ts.map +1 -0
  171. package/dist/services/steward-sidecar/helpers.js +2 -0
  172. package/dist/services/steward-sidecar/helpers.js.map +1 -0
  173. package/dist/services/steward-sidecar/process-management.d.ts +2 -0
  174. package/dist/services/steward-sidecar/process-management.d.ts.map +1 -0
  175. package/dist/services/steward-sidecar/process-management.js +2 -0
  176. package/dist/services/steward-sidecar/process-management.js.map +1 -0
  177. package/dist/services/steward-sidecar/types.d.ts +2 -0
  178. package/dist/services/steward-sidecar/types.d.ts.map +1 -0
  179. package/dist/services/steward-sidecar/types.js +2 -0
  180. package/dist/services/steward-sidecar/types.js.map +1 -0
  181. package/dist/services/steward-sidecar/wallet-setup.d.ts +2 -0
  182. package/dist/services/steward-sidecar/wallet-setup.d.ts.map +1 -0
  183. package/dist/services/steward-sidecar/wallet-setup.js +2 -0
  184. package/dist/services/steward-sidecar/wallet-setup.js.map +1 -0
  185. package/dist/services/steward-sidecar.d.ts +2 -0
  186. package/dist/services/steward-sidecar.d.ts.map +1 -0
  187. package/dist/services/steward-sidecar.js +2 -0
  188. package/dist/services/steward-sidecar.js.map +1 -0
  189. package/dist/services/steward-wallet.d.ts +25 -0
  190. package/dist/services/steward-wallet.d.ts.map +1 -0
  191. package/dist/services/steward-wallet.js +333 -0
  192. package/dist/services/steward-wallet.js.map +1 -0
  193. package/dist/steward-ui-state.d.ts +14 -0
  194. package/dist/steward-ui-state.d.ts.map +1 -0
  195. package/dist/steward-ui-state.js +46 -0
  196. package/dist/steward-ui-state.js.map +1 -0
  197. package/dist/steward-view-bundle.d.ts +3 -0
  198. package/dist/steward-view-bundle.d.ts.map +1 -0
  199. package/dist/steward-view-bundle.js +7 -0
  200. package/dist/steward-view-bundle.js.map +1 -0
  201. package/dist/types/bsc-trade.d.ts +180 -0
  202. package/dist/types/bsc-trade.d.ts.map +1 -0
  203. package/dist/types/bsc-trade.js +1 -0
  204. package/dist/types/bsc-trade.js.map +1 -0
  205. package/dist/types/index.d.ts +3 -0
  206. package/dist/types/index.d.ts.map +1 -0
  207. package/dist/types/index.js +3 -0
  208. package/dist/types/index.js.map +1 -0
  209. package/dist/types/steward.d.ts +83 -0
  210. package/dist/types/steward.d.ts.map +1 -0
  211. package/dist/types/steward.js +1 -0
  212. package/dist/types/steward.js.map +1 -0
  213. package/dist/ui.d.ts +7 -0
  214. package/dist/ui.d.ts.map +1 -0
  215. package/dist/ui.js +7 -0
  216. package/dist/ui.js.map +1 -0
  217. package/dist/views/bundle.js +601 -0
  218. package/dist/views/bundle.js.map +1 -0
  219. package/package.json +8 -8
@@ -0,0 +1,570 @@
1
+ import { loadElizaConfig } from "@elizaos/agent/config/config";
2
+ import { ensureCompatApiAuthorized } from "@elizaos/app-core/api/auth";
3
+ import {
4
+ readCompatJsonBody
5
+ } from "@elizaos/app-core/api/compat-route-shared";
6
+ import {
7
+ sendJsonError as sendJsonErrorResponse,
8
+ sendJson as sendJsonResponse
9
+ } from "@elizaos/app-core/api/response";
10
+ import { logger } from "@elizaos/core";
11
+ import {
12
+ canUseLocalTradeExecution as _canUseLocalTradeExecution,
13
+ resolveTradePermissionMode as _resolveTradePermissionMode
14
+ } from "@elizaos/plugin-wallet";
15
+ import { StewardApiError } from "@stwd/sdk";
16
+ import * as ethers from "ethers";
17
+ import {
18
+ buildBscApproveUnsignedTx,
19
+ buildBscBuyUnsignedTx,
20
+ buildBscSellUnsignedTx,
21
+ buildBscTradeQuote,
22
+ resolveBscApprovalSpender,
23
+ resolvePrimaryBscRpcUrl
24
+ } from "../api/bsc-trade.js";
25
+ import { getWalletAddresses } from "../api/wallet.js";
26
+ import { resolveWalletRpcReadiness } from "../api/wallet-rpc.js";
27
+ import { recordWalletTradeLedgerEntry } from "../api/wallet-trading-profile.js";
28
+ import {
29
+ isStewardConfigured,
30
+ signTransactionWithOptionalSteward
31
+ } from "./steward-bridge.js";
32
+ const AGENT_AUTOMATION_HEADER = "x-elizaos-agent-action";
33
+ function isAgentAutomationRequest(req) {
34
+ const raw = req.headers[AGENT_AUTOMATION_HEADER];
35
+ return typeof raw === "string" && /^(1|true|yes|agent)$/i.test(raw.trim());
36
+ }
37
+ function resolveBscExecutionNetwork() {
38
+ if (process.env.ELIZA_WALLET_NETWORK?.trim().toLowerCase() === "testnet") {
39
+ const parsedChainId = Number.parseInt(
40
+ process.env.BSC_TESTNET_CHAIN_ID?.trim() ?? "97",
41
+ 10
42
+ );
43
+ return {
44
+ chainId: Number.isNaN(parsedChainId) ? 97 : parsedChainId,
45
+ explorerBaseUrl: "https://testnet.bscscan.com"
46
+ };
47
+ }
48
+ return {
49
+ chainId: 56,
50
+ explorerBaseUrl: "https://bscscan.com"
51
+ };
52
+ }
53
+ function resolveWalletExecutionMode(canSign, canExecuteLocally, hasStewardSigner) {
54
+ if (!canSign || !canExecuteLocally) {
55
+ return "user-sign";
56
+ }
57
+ return hasStewardSigner ? "steward" : "local-key";
58
+ }
59
+ async function sendLocalWalletTransaction(rpcUrl, tx) {
60
+ const evmKey = process.env.EVM_PRIVATE_KEY ?? "";
61
+ const provider = new ethers.JsonRpcProvider(rpcUrl);
62
+ try {
63
+ const wallet = new ethers.Wallet(
64
+ evmKey.startsWith("0x") ? evmKey : `0x${evmKey}`,
65
+ provider
66
+ );
67
+ const txResponse = await wallet.sendTransaction(tx);
68
+ return {
69
+ hash: txResponse.hash,
70
+ nonce: txResponse.nonce,
71
+ gasLimit: txResponse.gasLimit?.toString() ?? "0"
72
+ };
73
+ } finally {
74
+ provider.destroy();
75
+ }
76
+ }
77
+ function getStewardPolicyResults(error) {
78
+ if (error.data && typeof error.data === "object" && "results" in error.data && Array.isArray(error.data.results)) {
79
+ return error.data.results;
80
+ }
81
+ return [];
82
+ }
83
+ function isStewardPolicyRejection(error) {
84
+ return error instanceof StewardApiError && error.status === 403;
85
+ }
86
+ async function handleWalletTradeCompatRoutes(req, res, _state) {
87
+ const method = (req.method ?? "GET").toUpperCase();
88
+ const url = new URL(req.url ?? "/", "http://localhost");
89
+ if (method === "POST" && url.pathname === "/api/wallet/trade/execute") {
90
+ if (!ensureCompatApiAuthorized(req, res)) {
91
+ return true;
92
+ }
93
+ const body = await readCompatJsonBody(req, res);
94
+ if (body == null) {
95
+ return true;
96
+ }
97
+ const side = typeof body.side === "string" ? body.side : "";
98
+ const tokenAddress = typeof body.tokenAddress === "string" ? body.tokenAddress : "";
99
+ const amount = typeof body.amount === "string" ? body.amount : "";
100
+ const routeProvider = body.routeProvider === "0x" || body.routeProvider === "pancakeswap-v2" || body.routeProvider === "auto" ? body.routeProvider : void 0;
101
+ if (!side || !tokenAddress || !amount) {
102
+ sendJsonErrorResponse(
103
+ res,
104
+ 400,
105
+ "side, tokenAddress, and amount are required"
106
+ );
107
+ return true;
108
+ }
109
+ if (side !== "buy" && side !== "sell") {
110
+ sendJsonErrorResponse(res, 400, 'side must be "buy" or "sell"');
111
+ return true;
112
+ }
113
+ const config = loadElizaConfig();
114
+ const tradePermissionMode = _resolveTradePermissionMode(config);
115
+ const canExecuteLocally = _canUseLocalTradeExecution(
116
+ tradePermissionMode,
117
+ isAgentAutomationRequest(req)
118
+ );
119
+ const addresses = getWalletAddresses();
120
+ const walletAddress = addresses.evmAddress ?? null;
121
+ const hasLocalKey = Boolean(process.env.EVM_PRIVATE_KEY?.trim());
122
+ const hasStewardSigner = isStewardConfigured();
123
+ const canSign = hasLocalKey || hasStewardSigner;
124
+ const rpcReadiness = resolveWalletRpcReadiness(config);
125
+ const bscExecutionNetwork = resolveBscExecutionNetwork();
126
+ try {
127
+ const quote = await buildBscTradeQuote({
128
+ walletAddress,
129
+ rpcUrls: rpcReadiness.bscRpcUrls,
130
+ cloudManagedAccess: rpcReadiness.cloudManagedAccess,
131
+ request: {
132
+ side,
133
+ tokenAddress,
134
+ amount,
135
+ slippageBps: typeof body.slippageBps === "number" ? body.slippageBps : void 0,
136
+ routeProvider
137
+ }
138
+ });
139
+ const unsignedTx = quote.side === "buy" ? buildBscBuyUnsignedTx(
140
+ quote,
141
+ walletAddress,
142
+ typeof body.deadlineSeconds === "number" ? body.deadlineSeconds : void 0
143
+ ) : buildBscSellUnsignedTx(
144
+ quote,
145
+ walletAddress,
146
+ typeof body.deadlineSeconds === "number" ? body.deadlineSeconds : void 0
147
+ );
148
+ let unsignedApprovalTx;
149
+ let requiresApproval = false;
150
+ if (quote.side === "sell" && walletAddress) {
151
+ unsignedApprovalTx = buildBscApproveUnsignedTx(
152
+ quote.tokenAddress,
153
+ walletAddress,
154
+ resolveBscApprovalSpender(quote),
155
+ quote.quoteIn.amountWei
156
+ );
157
+ requiresApproval = true;
158
+ }
159
+ if (!canSign || !canExecuteLocally || body.confirm !== true) {
160
+ sendJsonResponse(res, 200, {
161
+ ok: true,
162
+ side: quote.side,
163
+ mode: resolveWalletExecutionMode(
164
+ canSign,
165
+ canExecuteLocally,
166
+ hasStewardSigner
167
+ ),
168
+ quote,
169
+ executed: false,
170
+ requiresUserSignature: true,
171
+ unsignedTx,
172
+ unsignedApprovalTx,
173
+ requiresApproval
174
+ });
175
+ return true;
176
+ }
177
+ const rpcUrl = resolvePrimaryBscRpcUrl({
178
+ rpcUrls: rpcReadiness.bscRpcUrls,
179
+ cloudManagedAccess: rpcReadiness.cloudManagedAccess
180
+ });
181
+ let approvalHash;
182
+ let finalHash = "";
183
+ let finalNonce = null;
184
+ let finalGasLimit = "0";
185
+ let finalMode = hasLocalKey ? "local-key" : "steward";
186
+ if (hasLocalKey && canExecuteLocally) {
187
+ if (!rpcUrl) {
188
+ sendJsonErrorResponse(
189
+ res,
190
+ 503,
191
+ "BSC RPC not configured for local execution"
192
+ );
193
+ return true;
194
+ }
195
+ if (requiresApproval && unsignedApprovalTx) {
196
+ const approvalResult = await sendLocalWalletTransaction(rpcUrl, {
197
+ to: unsignedApprovalTx.to,
198
+ data: unsignedApprovalTx.data,
199
+ value: BigInt(unsignedApprovalTx.valueWei),
200
+ chainId: unsignedApprovalTx.chainId
201
+ });
202
+ approvalHash = approvalResult.hash;
203
+ const provider = new ethers.JsonRpcProvider(rpcUrl);
204
+ try {
205
+ await provider.waitForTransaction(approvalHash, 1);
206
+ } finally {
207
+ provider.destroy();
208
+ }
209
+ }
210
+ const localExecution = await sendLocalWalletTransaction(rpcUrl, {
211
+ to: unsignedTx.to,
212
+ data: unsignedTx.data,
213
+ value: BigInt(unsignedTx.valueWei),
214
+ chainId: unsignedTx.chainId
215
+ });
216
+ finalHash = localExecution.hash;
217
+ finalNonce = localExecution.nonce;
218
+ finalGasLimit = localExecution.gasLimit;
219
+ } else {
220
+ finalMode = "steward";
221
+ if (requiresApproval && unsignedApprovalTx) {
222
+ const approvalResult = await signTransactionWithOptionalSteward({
223
+ evmAddress: walletAddress,
224
+ tx: {
225
+ to: unsignedApprovalTx.to,
226
+ data: unsignedApprovalTx.data,
227
+ value: unsignedApprovalTx.valueWei,
228
+ chainId: unsignedApprovalTx.chainId,
229
+ broadcast: true
230
+ }
231
+ });
232
+ if (approvalResult.mode === "steward" && approvalResult.pendingApproval) {
233
+ sendJsonResponse(res, 200, {
234
+ ok: true,
235
+ side: quote.side,
236
+ mode: "steward",
237
+ quote,
238
+ executed: false,
239
+ requiresUserSignature: false,
240
+ unsignedTx,
241
+ unsignedApprovalTx,
242
+ requiresApproval,
243
+ approval: {
244
+ status: "pending_approval",
245
+ policyResults: approvalResult.policyResults
246
+ }
247
+ });
248
+ return true;
249
+ }
250
+ approvalHash = "txHash" in approvalResult ? approvalResult.txHash : "";
251
+ if (approvalResult.mode === "steward" && rpcUrl) {
252
+ const provider = new ethers.JsonRpcProvider(rpcUrl);
253
+ try {
254
+ await provider.waitForTransaction(approvalHash, 1);
255
+ } finally {
256
+ provider.destroy();
257
+ }
258
+ }
259
+ }
260
+ const executionResult = await signTransactionWithOptionalSteward({
261
+ evmAddress: walletAddress,
262
+ tx: {
263
+ to: unsignedTx.to,
264
+ data: unsignedTx.data,
265
+ value: unsignedTx.valueWei,
266
+ chainId: unsignedTx.chainId,
267
+ broadcast: true
268
+ }
269
+ });
270
+ if (executionResult.mode === "steward" && executionResult.pendingApproval) {
271
+ sendJsonResponse(res, 200, {
272
+ ok: true,
273
+ side: quote.side,
274
+ mode: "steward",
275
+ quote,
276
+ executed: false,
277
+ requiresUserSignature: false,
278
+ unsignedTx,
279
+ unsignedApprovalTx,
280
+ requiresApproval,
281
+ approvalHash,
282
+ execution: {
283
+ status: "pending_approval",
284
+ policyResults: executionResult.policyResults
285
+ }
286
+ });
287
+ return true;
288
+ }
289
+ finalHash = "txHash" in executionResult ? executionResult.txHash : "";
290
+ }
291
+ try {
292
+ const tradeSource = body.source === "agent" || body.source === "manual" ? body.source : "manual";
293
+ recordWalletTradeLedgerEntry({
294
+ hash: finalHash,
295
+ source: tradeSource,
296
+ side: quote.side,
297
+ tokenAddress: quote.tokenAddress,
298
+ slippageBps: quote.slippageBps,
299
+ route: quote.route,
300
+ quoteIn: {
301
+ symbol: quote.quoteIn.symbol,
302
+ amount: quote.quoteIn.amount,
303
+ amountWei: quote.quoteIn.amountWei
304
+ },
305
+ quoteOut: {
306
+ symbol: quote.quoteOut.symbol,
307
+ amount: quote.quoteOut.amount,
308
+ amountWei: quote.quoteOut.amountWei
309
+ },
310
+ status: "pending",
311
+ confirmations: 0,
312
+ nonce: finalNonce,
313
+ blockNumber: null,
314
+ gasUsed: null,
315
+ effectiveGasPriceWei: null,
316
+ explorerUrl: `${bscExecutionNetwork.explorerBaseUrl}/tx/${finalHash}`
317
+ });
318
+ } catch (ledgerErr) {
319
+ logger.warn(
320
+ `[api] Failed to record trade ledger entry: ${ledgerErr instanceof Error ? ledgerErr.message : ledgerErr}`
321
+ );
322
+ }
323
+ sendJsonResponse(res, 200, {
324
+ ok: true,
325
+ side: quote.side,
326
+ mode: finalMode,
327
+ quote,
328
+ executed: true,
329
+ requiresUserSignature: false,
330
+ unsignedTx,
331
+ unsignedApprovalTx,
332
+ requiresApproval,
333
+ execution: {
334
+ hash: finalHash,
335
+ nonce: finalNonce,
336
+ gasLimit: finalGasLimit,
337
+ valueWei: unsignedTx.valueWei,
338
+ explorerUrl: `${bscExecutionNetwork.explorerBaseUrl}/tx/${finalHash}`,
339
+ blockNumber: null,
340
+ status: "pending",
341
+ approvalHash
342
+ }
343
+ });
344
+ } catch (err) {
345
+ if (isStewardPolicyRejection(err)) {
346
+ sendJsonResponse(res, 403, {
347
+ ok: false,
348
+ mode: "steward",
349
+ executed: false,
350
+ requiresUserSignature: false,
351
+ error: err.message,
352
+ execution: {
353
+ status: "rejected",
354
+ policyResults: getStewardPolicyResults(err)
355
+ }
356
+ });
357
+ return true;
358
+ }
359
+ sendJsonErrorResponse(
360
+ res,
361
+ 500,
362
+ `Trade execution failed: ${err instanceof Error ? err.message : "unknown error"}`
363
+ );
364
+ }
365
+ return true;
366
+ }
367
+ if (method === "POST" && url.pathname === "/api/wallet/transfer/execute") {
368
+ if (!ensureCompatApiAuthorized(req, res)) {
369
+ return true;
370
+ }
371
+ const body = await readCompatJsonBody(req, res);
372
+ if (body == null) {
373
+ return true;
374
+ }
375
+ const toAddressRaw = typeof body.toAddress === "string" ? body.toAddress.trim() : "";
376
+ const amount = typeof body.amount === "string" ? body.amount.trim() : "";
377
+ const assetSymbol = typeof body.assetSymbol === "string" ? body.assetSymbol.trim() : "";
378
+ if (!toAddressRaw || !amount || !assetSymbol) {
379
+ sendJsonErrorResponse(
380
+ res,
381
+ 400,
382
+ "toAddress, amount, and assetSymbol are required"
383
+ );
384
+ return true;
385
+ }
386
+ const config = loadElizaConfig();
387
+ const tradePermissionMode = _resolveTradePermissionMode(config);
388
+ const canExecuteLocally = _canUseLocalTradeExecution(
389
+ tradePermissionMode,
390
+ isAgentAutomationRequest(req)
391
+ );
392
+ const hasLocalKey = Boolean(process.env.EVM_PRIVATE_KEY?.trim());
393
+ const hasStewardSigner = isStewardConfigured();
394
+ const canSign = hasLocalKey || hasStewardSigner;
395
+ const addresses = getWalletAddresses();
396
+ const rpcReadiness = resolveWalletRpcReadiness(config);
397
+ const bscExecutionNetwork = resolveBscExecutionNetwork();
398
+ let toAddress;
399
+ try {
400
+ toAddress = ethers.getAddress(toAddressRaw);
401
+ } catch {
402
+ sendJsonErrorResponse(
403
+ res,
404
+ 400,
405
+ "Invalid toAddress \u2014 must be a valid EVM address"
406
+ );
407
+ return true;
408
+ }
409
+ const isBnb = assetSymbol.toUpperCase() === "BNB";
410
+ let decimals = 18;
411
+ if (typeof body.tokenAddress === "string" && body.tokenAddress.trim()) {
412
+ const provider = new ethers.JsonRpcProvider(
413
+ resolvePrimaryBscRpcUrl({
414
+ rpcUrls: rpcReadiness.bscRpcUrls,
415
+ cloudManagedAccess: rpcReadiness.cloudManagedAccess
416
+ }) ?? "https://bsc-dataseed1.binance.org/"
417
+ );
418
+ try {
419
+ const tokenContract = new ethers.Contract(
420
+ body.tokenAddress,
421
+ ["function decimals() view returns (uint8)"],
422
+ provider
423
+ );
424
+ decimals = Number(await tokenContract.decimals());
425
+ } finally {
426
+ provider.destroy();
427
+ }
428
+ }
429
+ const unsignedTx = {
430
+ chainId: bscExecutionNetwork.chainId,
431
+ from: addresses.evmAddress ?? null,
432
+ to: isBnb || typeof body.tokenAddress !== "string" ? toAddress : body.tokenAddress,
433
+ data: isBnb ? "0x" : new ethers.Interface([
434
+ "function transfer(address to, uint256 amount) returns (bool)"
435
+ ]).encodeFunctionData("transfer", [
436
+ toAddress,
437
+ ethers.parseUnits(amount, decimals)
438
+ ]),
439
+ valueWei: isBnb ? ethers.parseEther(amount).toString() : "0",
440
+ explorerUrl: bscExecutionNetwork.explorerBaseUrl,
441
+ assetSymbol,
442
+ amount,
443
+ tokenAddress: typeof body.tokenAddress === "string" ? body.tokenAddress : void 0
444
+ };
445
+ if (!canSign || !canExecuteLocally || body.confirm !== true) {
446
+ sendJsonResponse(res, 200, {
447
+ ok: true,
448
+ mode: resolveWalletExecutionMode(
449
+ canSign,
450
+ canExecuteLocally,
451
+ hasStewardSigner
452
+ ),
453
+ executed: false,
454
+ requiresUserSignature: true,
455
+ toAddress,
456
+ amount,
457
+ assetSymbol,
458
+ tokenAddress: unsignedTx.tokenAddress,
459
+ unsignedTx
460
+ });
461
+ return true;
462
+ }
463
+ const _rpcUrl = resolvePrimaryBscRpcUrl({
464
+ rpcUrls: rpcReadiness.bscRpcUrls,
465
+ cloudManagedAccess: rpcReadiness.cloudManagedAccess
466
+ });
467
+ try {
468
+ let finalHash = "";
469
+ let finalNonce = null;
470
+ let finalGasLimit = "0";
471
+ let finalMode = hasLocalKey ? "local-key" : "steward";
472
+ if (hasLocalKey && canExecuteLocally) {
473
+ if (!_rpcUrl) {
474
+ sendJsonErrorResponse(
475
+ res,
476
+ 503,
477
+ "BSC RPC not configured for local execution"
478
+ );
479
+ return true;
480
+ }
481
+ const localExecution = await sendLocalWalletTransaction(_rpcUrl, {
482
+ to: unsignedTx.to,
483
+ data: unsignedTx.data,
484
+ value: BigInt(unsignedTx.valueWei),
485
+ chainId: unsignedTx.chainId
486
+ });
487
+ finalHash = localExecution.hash;
488
+ finalNonce = localExecution.nonce;
489
+ finalGasLimit = localExecution.gasLimit;
490
+ } else {
491
+ finalMode = "steward";
492
+ const executionResult = await signTransactionWithOptionalSteward({
493
+ evmAddress: addresses.evmAddress,
494
+ tx: {
495
+ to: unsignedTx.to,
496
+ data: unsignedTx.data,
497
+ value: unsignedTx.valueWei,
498
+ chainId: unsignedTx.chainId,
499
+ broadcast: true
500
+ }
501
+ });
502
+ if (executionResult.mode === "steward" && executionResult.pendingApproval) {
503
+ sendJsonResponse(res, 200, {
504
+ ok: true,
505
+ mode: "steward",
506
+ executed: false,
507
+ requiresUserSignature: false,
508
+ toAddress,
509
+ amount,
510
+ assetSymbol,
511
+ tokenAddress: unsignedTx.tokenAddress,
512
+ unsignedTx,
513
+ execution: {
514
+ status: "pending_approval",
515
+ policyResults: executionResult.policyResults
516
+ }
517
+ });
518
+ return true;
519
+ }
520
+ finalHash = "txHash" in executionResult ? executionResult.txHash : "";
521
+ }
522
+ sendJsonResponse(res, 200, {
523
+ ok: true,
524
+ mode: finalMode,
525
+ executed: true,
526
+ requiresUserSignature: false,
527
+ toAddress,
528
+ amount,
529
+ assetSymbol,
530
+ tokenAddress: unsignedTx.tokenAddress,
531
+ unsignedTx,
532
+ execution: {
533
+ hash: finalHash,
534
+ nonce: finalNonce,
535
+ gasLimit: finalGasLimit,
536
+ valueWei: unsignedTx.valueWei,
537
+ explorerUrl: `${bscExecutionNetwork.explorerBaseUrl}/tx/${finalHash}`,
538
+ blockNumber: null,
539
+ status: "pending"
540
+ }
541
+ });
542
+ } catch (err) {
543
+ if (isStewardPolicyRejection(err)) {
544
+ sendJsonResponse(res, 403, {
545
+ ok: false,
546
+ mode: "steward",
547
+ executed: false,
548
+ requiresUserSignature: false,
549
+ error: err.message,
550
+ execution: {
551
+ status: "rejected",
552
+ policyResults: getStewardPolicyResults(err)
553
+ }
554
+ });
555
+ return true;
556
+ }
557
+ sendJsonErrorResponse(
558
+ res,
559
+ 500,
560
+ `Transfer failed: ${err instanceof Error ? err.message : "unknown error"}`
561
+ );
562
+ }
563
+ return true;
564
+ }
565
+ return false;
566
+ }
567
+ export {
568
+ handleWalletTradeCompatRoutes
569
+ };
570
+ //# sourceMappingURL=wallet-trade-compat-routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/routes/wallet-trade-compat-routes.ts"],"sourcesContent":["/**\n * Wallet trade / transfer compat routes.\n *\n * Handles:\n * POST /api/wallet/trade/execute — BSC DEX trade execution\n * POST /api/wallet/transfer/execute — token / BNB transfer execution\n */\nimport type http from \"node:http\";\nimport { loadElizaConfig } from \"@elizaos/agent/config/config\";\nimport { ensureCompatApiAuthorized } from \"@elizaos/app-core/api/auth\";\nimport {\n type CompatRuntimeState,\n readCompatJsonBody,\n} from \"@elizaos/app-core/api/compat-route-shared\";\nimport {\n sendJsonError as sendJsonErrorResponse,\n sendJson as sendJsonResponse,\n} from \"@elizaos/app-core/api/response\";\nimport { logger } from \"@elizaos/core\";\nimport {\n canUseLocalTradeExecution as _canUseLocalTradeExecution,\n resolveTradePermissionMode as _resolveTradePermissionMode,\n} from \"@elizaos/plugin-wallet\";\nimport { type PolicyResult, StewardApiError } from \"@stwd/sdk\";\nimport * as ethers from \"ethers\";\nimport {\n buildBscApproveUnsignedTx,\n buildBscBuyUnsignedTx,\n buildBscSellUnsignedTx,\n buildBscTradeQuote,\n resolveBscApprovalSpender,\n resolvePrimaryBscRpcUrl,\n} from \"../api/bsc-trade.js\";\nimport { getWalletAddresses } from \"../api/wallet.js\";\nimport { resolveWalletRpcReadiness } from \"../api/wallet-rpc.js\";\nimport { recordWalletTradeLedgerEntry } from \"../api/wallet-trading-profile.js\";\nimport {\n isStewardConfigured,\n signTransactionWithOptionalSteward,\n} from \"./steward-bridge.js\";\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst AGENT_AUTOMATION_HEADER = \"x-elizaos-agent-action\";\n\n// ---------------------------------------------------------------------------\n// Helpers (only used by trade / transfer routes)\n// ---------------------------------------------------------------------------\n\nfunction isAgentAutomationRequest(\n req: Pick<http.IncomingMessage, \"headers\">,\n): boolean {\n const raw = req.headers[AGENT_AUTOMATION_HEADER];\n return typeof raw === \"string\" && /^(1|true|yes|agent)$/i.test(raw.trim());\n}\n\nfunction resolveBscExecutionNetwork(): {\n chainId: number;\n explorerBaseUrl: string;\n} {\n if (process.env.ELIZA_WALLET_NETWORK?.trim().toLowerCase() === \"testnet\") {\n const parsedChainId = Number.parseInt(\n process.env.BSC_TESTNET_CHAIN_ID?.trim() ?? \"97\",\n 10,\n );\n return {\n chainId: Number.isNaN(parsedChainId) ? 97 : parsedChainId,\n explorerBaseUrl: \"https://testnet.bscscan.com\",\n };\n }\n\n return {\n chainId: 56,\n explorerBaseUrl: \"https://bscscan.com\",\n };\n}\n\nfunction resolveWalletExecutionMode(\n canSign: boolean,\n canExecuteLocally: boolean,\n hasStewardSigner: boolean,\n): \"local-key\" | \"steward\" | \"user-sign\" {\n if (!canSign || !canExecuteLocally) {\n return \"user-sign\";\n }\n\n return hasStewardSigner ? \"steward\" : \"local-key\";\n}\n\ninterface LocalSignedTransactionResult {\n hash: string;\n nonce: number;\n gasLimit: string;\n}\n\n/** Broadcast a signed tx using `EVM_PRIVATE_KEY` and a JSON-RPC provider (local execution path). */\nasync function sendLocalWalletTransaction(\n rpcUrl: string,\n tx: {\n to: string;\n data?: string;\n value: bigint;\n chainId: number;\n nonce?: number;\n },\n): Promise<LocalSignedTransactionResult> {\n const evmKey = process.env.EVM_PRIVATE_KEY ?? \"\";\n const provider = new ethers.JsonRpcProvider(rpcUrl);\n\n try {\n const wallet = new ethers.Wallet(\n evmKey.startsWith(\"0x\") ? evmKey : `0x${evmKey}`,\n provider,\n );\n const txResponse = await wallet.sendTransaction(tx);\n return {\n hash: txResponse.hash,\n nonce: txResponse.nonce,\n gasLimit: txResponse.gasLimit?.toString() ?? \"0\",\n };\n } finally {\n provider.destroy();\n }\n}\n\nfunction getStewardPolicyResults(error: StewardApiError): PolicyResult[] {\n if (\n error.data &&\n typeof error.data === \"object\" &&\n \"results\" in error.data &&\n Array.isArray(error.data.results)\n ) {\n return error.data.results as PolicyResult[];\n }\n\n return [];\n}\n\nfunction isStewardPolicyRejection(error: unknown): error is StewardApiError {\n return error instanceof StewardApiError && error.status === 403;\n}\n\n// ---------------------------------------------------------------------------\n// Route handler\n// ---------------------------------------------------------------------------\n\nexport async function handleWalletTradeCompatRoutes(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n _state: CompatRuntimeState,\n): Promise<boolean> {\n const method = (req.method ?? \"GET\").toUpperCase();\n const url = new URL(req.url ?? \"/\", \"http://localhost\");\n\n // ── POST /api/wallet/trade/execute ─────────────────────────────────────\n if (method === \"POST\" && url.pathname === \"/api/wallet/trade/execute\") {\n if (!ensureCompatApiAuthorized(req, res)) {\n return true;\n }\n\n const body = await readCompatJsonBody(req, res);\n if (body == null) {\n return true;\n }\n\n const side = typeof body.side === \"string\" ? body.side : \"\";\n const tokenAddress =\n typeof body.tokenAddress === \"string\" ? body.tokenAddress : \"\";\n const amount = typeof body.amount === \"string\" ? body.amount : \"\";\n const routeProvider =\n body.routeProvider === \"0x\" ||\n body.routeProvider === \"pancakeswap-v2\" ||\n body.routeProvider === \"auto\"\n ? body.routeProvider\n : undefined;\n\n if (!side || !tokenAddress || !amount) {\n sendJsonErrorResponse(\n res,\n 400,\n \"side, tokenAddress, and amount are required\",\n );\n return true;\n }\n\n if (side !== \"buy\" && side !== \"sell\") {\n sendJsonErrorResponse(res, 400, 'side must be \"buy\" or \"sell\"');\n return true;\n }\n\n const config = loadElizaConfig();\n const tradePermissionMode = _resolveTradePermissionMode(config);\n const canExecuteLocally = _canUseLocalTradeExecution(\n tradePermissionMode,\n isAgentAutomationRequest(req),\n );\n const addresses = getWalletAddresses();\n const walletAddress = addresses.evmAddress ?? null;\n const hasLocalKey = Boolean(process.env.EVM_PRIVATE_KEY?.trim());\n const hasStewardSigner = isStewardConfigured();\n const canSign = hasLocalKey || hasStewardSigner;\n const rpcReadiness = resolveWalletRpcReadiness(config);\n const bscExecutionNetwork = resolveBscExecutionNetwork();\n\n try {\n const quote = await buildBscTradeQuote({\n walletAddress,\n rpcUrls: rpcReadiness.bscRpcUrls,\n cloudManagedAccess: rpcReadiness.cloudManagedAccess,\n request: {\n side,\n tokenAddress,\n amount,\n slippageBps:\n typeof body.slippageBps === \"number\" ? body.slippageBps : undefined,\n routeProvider,\n },\n });\n\n const unsignedTx =\n quote.side === \"buy\"\n ? buildBscBuyUnsignedTx(\n quote,\n walletAddress,\n typeof body.deadlineSeconds === \"number\"\n ? body.deadlineSeconds\n : undefined,\n )\n : buildBscSellUnsignedTx(\n quote,\n walletAddress,\n typeof body.deadlineSeconds === \"number\"\n ? body.deadlineSeconds\n : undefined,\n );\n\n let unsignedApprovalTx:\n | ReturnType<typeof buildBscApproveUnsignedTx>\n | undefined;\n let requiresApproval = false;\n if (quote.side === \"sell\" && walletAddress) {\n unsignedApprovalTx = buildBscApproveUnsignedTx(\n quote.tokenAddress,\n walletAddress,\n resolveBscApprovalSpender(quote),\n quote.quoteIn.amountWei,\n );\n requiresApproval = true;\n }\n\n if (!canSign || !canExecuteLocally || body.confirm !== true) {\n sendJsonResponse(res, 200, {\n ok: true,\n side: quote.side,\n mode: resolveWalletExecutionMode(\n canSign,\n canExecuteLocally,\n hasStewardSigner,\n ),\n quote,\n executed: false,\n requiresUserSignature: true,\n unsignedTx,\n unsignedApprovalTx,\n requiresApproval,\n });\n return true;\n }\n\n const rpcUrl = resolvePrimaryBscRpcUrl({\n rpcUrls: rpcReadiness.bscRpcUrls,\n cloudManagedAccess: rpcReadiness.cloudManagedAccess,\n });\n\n let approvalHash: string | undefined;\n let finalHash = \"\";\n let finalNonce: number | null = null;\n let finalGasLimit = \"0\";\n let finalMode: \"local-key\" | \"steward\" = hasLocalKey\n ? \"local-key\"\n : \"steward\";\n\n if (hasLocalKey && canExecuteLocally) {\n if (!rpcUrl) {\n sendJsonErrorResponse(\n res,\n 503,\n \"BSC RPC not configured for local execution\",\n );\n return true;\n }\n\n if (requiresApproval && unsignedApprovalTx) {\n const approvalResult = await sendLocalWalletTransaction(rpcUrl, {\n to: unsignedApprovalTx.to,\n data: unsignedApprovalTx.data,\n value: BigInt(unsignedApprovalTx.valueWei),\n chainId: unsignedApprovalTx.chainId,\n });\n approvalHash = approvalResult.hash;\n const provider = new ethers.JsonRpcProvider(rpcUrl);\n try {\n await provider.waitForTransaction(approvalHash, 1);\n } finally {\n provider.destroy();\n }\n }\n\n const localExecution = await sendLocalWalletTransaction(rpcUrl, {\n to: unsignedTx.to,\n data: unsignedTx.data,\n value: BigInt(unsignedTx.valueWei),\n chainId: unsignedTx.chainId,\n });\n finalHash = localExecution.hash;\n finalNonce = localExecution.nonce;\n finalGasLimit = localExecution.gasLimit;\n } else {\n finalMode = \"steward\";\n if (requiresApproval && unsignedApprovalTx) {\n const approvalResult = await signTransactionWithOptionalSteward({\n evmAddress: walletAddress,\n tx: {\n to: unsignedApprovalTx.to,\n data: unsignedApprovalTx.data,\n value: unsignedApprovalTx.valueWei,\n chainId: unsignedApprovalTx.chainId,\n broadcast: true,\n },\n });\n\n if (\n approvalResult.mode === \"steward\" &&\n approvalResult.pendingApproval\n ) {\n sendJsonResponse(res, 200, {\n ok: true,\n side: quote.side,\n mode: \"steward\",\n quote,\n executed: false,\n requiresUserSignature: false,\n unsignedTx,\n unsignedApprovalTx,\n requiresApproval,\n approval: {\n status: \"pending_approval\",\n policyResults: approvalResult.policyResults,\n },\n });\n return true;\n }\n\n approvalHash =\n \"txHash\" in approvalResult ? approvalResult.txHash : \"\";\n\n if (approvalResult.mode === \"steward\" && rpcUrl) {\n const provider = new ethers.JsonRpcProvider(rpcUrl);\n try {\n await provider.waitForTransaction(approvalHash, 1);\n } finally {\n provider.destroy();\n }\n }\n }\n\n const executionResult = await signTransactionWithOptionalSteward({\n evmAddress: walletAddress,\n tx: {\n to: unsignedTx.to,\n data: unsignedTx.data,\n value: unsignedTx.valueWei,\n chainId: unsignedTx.chainId,\n broadcast: true,\n },\n });\n\n if (\n executionResult.mode === \"steward\" &&\n executionResult.pendingApproval\n ) {\n sendJsonResponse(res, 200, {\n ok: true,\n side: quote.side,\n mode: \"steward\",\n quote,\n executed: false,\n requiresUserSignature: false,\n unsignedTx,\n unsignedApprovalTx,\n requiresApproval,\n approvalHash,\n execution: {\n status: \"pending_approval\",\n policyResults: executionResult.policyResults,\n },\n });\n return true;\n }\n\n finalHash = \"txHash\" in executionResult ? executionResult.txHash : \"\";\n }\n\n try {\n const tradeSource =\n body.source === \"agent\" || body.source === \"manual\"\n ? body.source\n : \"manual\";\n\n recordWalletTradeLedgerEntry({\n hash: finalHash,\n source: tradeSource,\n side: quote.side,\n tokenAddress: quote.tokenAddress,\n slippageBps: quote.slippageBps,\n route: quote.route,\n quoteIn: {\n symbol: quote.quoteIn.symbol,\n amount: quote.quoteIn.amount,\n amountWei: quote.quoteIn.amountWei,\n },\n quoteOut: {\n symbol: quote.quoteOut.symbol,\n amount: quote.quoteOut.amount,\n amountWei: quote.quoteOut.amountWei,\n },\n status: \"pending\",\n confirmations: 0,\n nonce: finalNonce,\n blockNumber: null,\n gasUsed: null,\n effectiveGasPriceWei: null,\n explorerUrl: `${bscExecutionNetwork.explorerBaseUrl}/tx/${finalHash}`,\n });\n } catch (ledgerErr) {\n logger.warn(\n `[api] Failed to record trade ledger entry: ${ledgerErr instanceof Error ? ledgerErr.message : ledgerErr}`,\n );\n }\n\n sendJsonResponse(res, 200, {\n ok: true,\n side: quote.side,\n mode: finalMode,\n quote,\n executed: true,\n requiresUserSignature: false,\n unsignedTx,\n unsignedApprovalTx,\n requiresApproval,\n execution: {\n hash: finalHash,\n nonce: finalNonce,\n gasLimit: finalGasLimit,\n valueWei: unsignedTx.valueWei,\n explorerUrl: `${bscExecutionNetwork.explorerBaseUrl}/tx/${finalHash}`,\n blockNumber: null,\n status: \"pending\",\n approvalHash,\n },\n });\n } catch (err) {\n if (isStewardPolicyRejection(err)) {\n sendJsonResponse(res, 403, {\n ok: false,\n mode: \"steward\",\n executed: false,\n requiresUserSignature: false,\n error: err.message,\n execution: {\n status: \"rejected\",\n policyResults: getStewardPolicyResults(err),\n },\n });\n return true;\n }\n\n sendJsonErrorResponse(\n res,\n 500,\n `Trade execution failed: ${err instanceof Error ? err.message : \"unknown error\"}`,\n );\n }\n return true;\n }\n\n // ── POST /api/wallet/transfer/execute ──────────────────────────────────\n if (method === \"POST\" && url.pathname === \"/api/wallet/transfer/execute\") {\n if (!ensureCompatApiAuthorized(req, res)) {\n return true;\n }\n\n const body = await readCompatJsonBody(req, res);\n if (body == null) {\n return true;\n }\n\n const toAddressRaw =\n typeof body.toAddress === \"string\" ? body.toAddress.trim() : \"\";\n const amount = typeof body.amount === \"string\" ? body.amount.trim() : \"\";\n const assetSymbol =\n typeof body.assetSymbol === \"string\" ? body.assetSymbol.trim() : \"\";\n\n if (!toAddressRaw || !amount || !assetSymbol) {\n sendJsonErrorResponse(\n res,\n 400,\n \"toAddress, amount, and assetSymbol are required\",\n );\n return true;\n }\n\n const config = loadElizaConfig();\n const tradePermissionMode = _resolveTradePermissionMode(config);\n const canExecuteLocally = _canUseLocalTradeExecution(\n tradePermissionMode,\n isAgentAutomationRequest(req),\n );\n const hasLocalKey = Boolean(process.env.EVM_PRIVATE_KEY?.trim());\n const hasStewardSigner = isStewardConfigured();\n const canSign = hasLocalKey || hasStewardSigner;\n const addresses = getWalletAddresses();\n const rpcReadiness = resolveWalletRpcReadiness(config);\n const bscExecutionNetwork = resolveBscExecutionNetwork();\n\n let toAddress: string;\n try {\n toAddress = ethers.getAddress(toAddressRaw);\n } catch {\n sendJsonErrorResponse(\n res,\n 400,\n \"Invalid toAddress — must be a valid EVM address\",\n );\n return true;\n }\n\n const isBnb = assetSymbol.toUpperCase() === \"BNB\";\n let decimals = 18;\n if (typeof body.tokenAddress === \"string\" && body.tokenAddress.trim()) {\n const provider = new ethers.JsonRpcProvider(\n resolvePrimaryBscRpcUrl({\n rpcUrls: rpcReadiness.bscRpcUrls,\n cloudManagedAccess: rpcReadiness.cloudManagedAccess,\n }) ?? \"https://bsc-dataseed1.binance.org/\",\n );\n try {\n const tokenContract = new ethers.Contract(\n body.tokenAddress,\n [\"function decimals() view returns (uint8)\"],\n provider,\n );\n decimals = Number(await tokenContract.decimals());\n } finally {\n provider.destroy();\n }\n }\n\n const unsignedTx = {\n chainId: bscExecutionNetwork.chainId,\n from: addresses.evmAddress ?? null,\n to:\n isBnb || typeof body.tokenAddress !== \"string\"\n ? toAddress\n : body.tokenAddress,\n data: isBnb\n ? \"0x\"\n : new ethers.Interface([\n \"function transfer(address to, uint256 amount) returns (bool)\",\n ]).encodeFunctionData(\"transfer\", [\n toAddress,\n ethers.parseUnits(amount, decimals),\n ]),\n valueWei: isBnb ? ethers.parseEther(amount).toString() : \"0\",\n explorerUrl: bscExecutionNetwork.explorerBaseUrl,\n assetSymbol,\n amount,\n tokenAddress:\n typeof body.tokenAddress === \"string\" ? body.tokenAddress : undefined,\n };\n\n if (!canSign || !canExecuteLocally || body.confirm !== true) {\n sendJsonResponse(res, 200, {\n ok: true,\n mode: resolveWalletExecutionMode(\n canSign,\n canExecuteLocally,\n hasStewardSigner,\n ),\n executed: false,\n requiresUserSignature: true,\n toAddress,\n amount,\n assetSymbol,\n tokenAddress: unsignedTx.tokenAddress,\n unsignedTx,\n });\n return true;\n }\n\n const _rpcUrl = resolvePrimaryBscRpcUrl({\n rpcUrls: rpcReadiness.bscRpcUrls,\n cloudManagedAccess: rpcReadiness.cloudManagedAccess,\n });\n\n try {\n let finalHash = \"\";\n let finalNonce: number | null = null;\n let finalGasLimit = \"0\";\n let finalMode: \"local-key\" | \"steward\" = hasLocalKey\n ? \"local-key\"\n : \"steward\";\n\n if (hasLocalKey && canExecuteLocally) {\n if (!_rpcUrl) {\n sendJsonErrorResponse(\n res,\n 503,\n \"BSC RPC not configured for local execution\",\n );\n return true;\n }\n\n const localExecution = await sendLocalWalletTransaction(_rpcUrl, {\n to: unsignedTx.to,\n data: unsignedTx.data,\n value: BigInt(unsignedTx.valueWei),\n chainId: unsignedTx.chainId,\n });\n finalHash = localExecution.hash;\n finalNonce = localExecution.nonce;\n finalGasLimit = localExecution.gasLimit;\n } else {\n finalMode = \"steward\";\n const executionResult = await signTransactionWithOptionalSteward({\n evmAddress: addresses.evmAddress,\n tx: {\n to: unsignedTx.to,\n data: unsignedTx.data,\n value: unsignedTx.valueWei,\n chainId: unsignedTx.chainId,\n broadcast: true,\n },\n });\n\n if (\n executionResult.mode === \"steward\" &&\n executionResult.pendingApproval\n ) {\n sendJsonResponse(res, 200, {\n ok: true,\n mode: \"steward\",\n executed: false,\n requiresUserSignature: false,\n toAddress,\n amount,\n assetSymbol,\n tokenAddress: unsignedTx.tokenAddress,\n unsignedTx,\n execution: {\n status: \"pending_approval\",\n policyResults: executionResult.policyResults,\n },\n });\n return true;\n }\n\n finalHash = \"txHash\" in executionResult ? executionResult.txHash : \"\";\n }\n\n sendJsonResponse(res, 200, {\n ok: true,\n mode: finalMode,\n executed: true,\n requiresUserSignature: false,\n toAddress,\n amount,\n assetSymbol,\n tokenAddress: unsignedTx.tokenAddress,\n unsignedTx,\n execution: {\n hash: finalHash,\n nonce: finalNonce,\n gasLimit: finalGasLimit,\n valueWei: unsignedTx.valueWei,\n explorerUrl: `${bscExecutionNetwork.explorerBaseUrl}/tx/${finalHash}`,\n blockNumber: null,\n status: \"pending\",\n },\n });\n } catch (err) {\n if (isStewardPolicyRejection(err)) {\n sendJsonResponse(res, 403, {\n ok: false,\n mode: \"steward\",\n executed: false,\n requiresUserSignature: false,\n error: err.message,\n execution: {\n status: \"rejected\",\n policyResults: getStewardPolicyResults(err),\n },\n });\n return true;\n }\n\n sendJsonErrorResponse(\n res,\n 500,\n `Transfer failed: ${err instanceof Error ? err.message : \"unknown error\"}`,\n );\n }\n return true;\n }\n\n return false;\n}\n"],"mappings":"AAQA,SAAS,uBAAuB;AAChC,SAAS,iCAAiC;AAC1C;AAAA,EAEE;AAAA,OACK;AACP;AAAA,EACE,iBAAiB;AAAA,EACjB,YAAY;AAAA,OACP;AACP,SAAS,cAAc;AACvB;AAAA,EACE,6BAA6B;AAAA,EAC7B,8BAA8B;AAAA,OACzB;AACP,SAA4B,uBAAuB;AACnD,YAAY,YAAY;AACxB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,0BAA0B;AACnC,SAAS,iCAAiC;AAC1C,SAAS,oCAAoC;AAC7C;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAMP,MAAM,0BAA0B;AAMhC,SAAS,yBACP,KACS;AACT,QAAM,MAAM,IAAI,QAAQ,uBAAuB;AAC/C,SAAO,OAAO,QAAQ,YAAY,wBAAwB,KAAK,IAAI,KAAK,CAAC;AAC3E;AAEA,SAAS,6BAGP;AACA,MAAI,QAAQ,IAAI,sBAAsB,KAAK,EAAE,YAAY,MAAM,WAAW;AACxE,UAAM,gBAAgB,OAAO;AAAA,MAC3B,QAAQ,IAAI,sBAAsB,KAAK,KAAK;AAAA,MAC5C;AAAA,IACF;AACA,WAAO;AAAA,MACL,SAAS,OAAO,MAAM,aAAa,IAAI,KAAK;AAAA,MAC5C,iBAAiB;AAAA,IACnB;AAAA,EACF;AAEA,SAAO;AAAA,IACL,SAAS;AAAA,IACT,iBAAiB;AAAA,EACnB;AACF;AAEA,SAAS,2BACP,SACA,mBACA,kBACuC;AACvC,MAAI,CAAC,WAAW,CAAC,mBAAmB;AAClC,WAAO;AAAA,EACT;AAEA,SAAO,mBAAmB,YAAY;AACxC;AASA,eAAe,2BACb,QACA,IAOuC;AACvC,QAAM,SAAS,QAAQ,IAAI,mBAAmB;AAC9C,QAAM,WAAW,IAAI,OAAO,gBAAgB,MAAM;AAElD,MAAI;AACF,UAAM,SAAS,IAAI,OAAO;AAAA,MACxB,OAAO,WAAW,IAAI,IAAI,SAAS,KAAK,MAAM;AAAA,MAC9C;AAAA,IACF;AACA,UAAM,aAAa,MAAM,OAAO,gBAAgB,EAAE;AAClD,WAAO;AAAA,MACL,MAAM,WAAW;AAAA,MACjB,OAAO,WAAW;AAAA,MAClB,UAAU,WAAW,UAAU,SAAS,KAAK;AAAA,IAC/C;AAAA,EACF,UAAE;AACA,aAAS,QAAQ;AAAA,EACnB;AACF;AAEA,SAAS,wBAAwB,OAAwC;AACvE,MACE,MAAM,QACN,OAAO,MAAM,SAAS,YACtB,aAAa,MAAM,QACnB,MAAM,QAAQ,MAAM,KAAK,OAAO,GAChC;AACA,WAAO,MAAM,KAAK;AAAA,EACpB;AAEA,SAAO,CAAC;AACV;AAEA,SAAS,yBAAyB,OAA0C;AAC1E,SAAO,iBAAiB,mBAAmB,MAAM,WAAW;AAC9D;AAMA,eAAsB,8BACpB,KACA,KACA,QACkB;AAClB,QAAM,UAAU,IAAI,UAAU,OAAO,YAAY;AACjD,QAAM,MAAM,IAAI,IAAI,IAAI,OAAO,KAAK,kBAAkB;AAGtD,MAAI,WAAW,UAAU,IAAI,aAAa,6BAA6B;AACrE,QAAI,CAAC,0BAA0B,KAAK,GAAG,GAAG;AACxC,aAAO;AAAA,IACT;AAEA,UAAM,OAAO,MAAM,mBAAmB,KAAK,GAAG;AAC9C,QAAI,QAAQ,MAAM;AAChB,aAAO;AAAA,IACT;AAEA,UAAM,OAAO,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO;AACzD,UAAM,eACJ,OAAO,KAAK,iBAAiB,WAAW,KAAK,eAAe;AAC9D,UAAM,SAAS,OAAO,KAAK,WAAW,WAAW,KAAK,SAAS;AAC/D,UAAM,gBACJ,KAAK,kBAAkB,QACvB,KAAK,kBAAkB,oBACvB,KAAK,kBAAkB,SACnB,KAAK,gBACL;AAEN,QAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,QAAQ;AACrC;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAEA,QAAI,SAAS,SAAS,SAAS,QAAQ;AACrC,4BAAsB,KAAK,KAAK,8BAA8B;AAC9D,aAAO;AAAA,IACT;AAEA,UAAM,SAAS,gBAAgB;AAC/B,UAAM,sBAAsB,4BAA4B,MAAM;AAC9D,UAAM,oBAAoB;AAAA,MACxB;AAAA,MACA,yBAAyB,GAAG;AAAA,IAC9B;AACA,UAAM,YAAY,mBAAmB;AACrC,UAAM,gBAAgB,UAAU,cAAc;AAC9C,UAAM,cAAc,QAAQ,QAAQ,IAAI,iBAAiB,KAAK,CAAC;AAC/D,UAAM,mBAAmB,oBAAoB;AAC7C,UAAM,UAAU,eAAe;AAC/B,UAAM,eAAe,0BAA0B,MAAM;AACrD,UAAM,sBAAsB,2BAA2B;AAEvD,QAAI;AACF,YAAM,QAAQ,MAAM,mBAAmB;AAAA,QACrC;AAAA,QACA,SAAS,aAAa;AAAA,QACtB,oBAAoB,aAAa;AAAA,QACjC,SAAS;AAAA,UACP;AAAA,UACA;AAAA,UACA;AAAA,UACA,aACE,OAAO,KAAK,gBAAgB,WAAW,KAAK,cAAc;AAAA,UAC5D;AAAA,QACF;AAAA,MACF,CAAC;AAED,YAAM,aACJ,MAAM,SAAS,QACX;AAAA,QACE;AAAA,QACA;AAAA,QACA,OAAO,KAAK,oBAAoB,WAC5B,KAAK,kBACL;AAAA,MACN,IACA;AAAA,QACE;AAAA,QACA;AAAA,QACA,OAAO,KAAK,oBAAoB,WAC5B,KAAK,kBACL;AAAA,MACN;AAEN,UAAI;AAGJ,UAAI,mBAAmB;AACvB,UAAI,MAAM,SAAS,UAAU,eAAe;AAC1C,6BAAqB;AAAA,UACnB,MAAM;AAAA,UACN;AAAA,UACA,0BAA0B,KAAK;AAAA,UAC/B,MAAM,QAAQ;AAAA,QAChB;AACA,2BAAmB;AAAA,MACrB;AAEA,UAAI,CAAC,WAAW,CAAC,qBAAqB,KAAK,YAAY,MAAM;AAC3D,yBAAiB,KAAK,KAAK;AAAA,UACzB,IAAI;AAAA,UACJ,MAAM,MAAM;AAAA,UACZ,MAAM;AAAA,YACJ;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,UACA;AAAA,UACA,UAAU;AAAA,UACV,uBAAuB;AAAA,UACvB;AAAA,UACA;AAAA,UACA;AAAA,QACF,CAAC;AACD,eAAO;AAAA,MACT;AAEA,YAAM,SAAS,wBAAwB;AAAA,QACrC,SAAS,aAAa;AAAA,QACtB,oBAAoB,aAAa;AAAA,MACnC,CAAC;AAED,UAAI;AACJ,UAAI,YAAY;AAChB,UAAI,aAA4B;AAChC,UAAI,gBAAgB;AACpB,UAAI,YAAqC,cACrC,cACA;AAEJ,UAAI,eAAe,mBAAmB;AACpC,YAAI,CAAC,QAAQ;AACX;AAAA,YACE;AAAA,YACA;AAAA,YACA;AAAA,UACF;AACA,iBAAO;AAAA,QACT;AAEA,YAAI,oBAAoB,oBAAoB;AAC1C,gBAAM,iBAAiB,MAAM,2BAA2B,QAAQ;AAAA,YAC9D,IAAI,mBAAmB;AAAA,YACvB,MAAM,mBAAmB;AAAA,YACzB,OAAO,OAAO,mBAAmB,QAAQ;AAAA,YACzC,SAAS,mBAAmB;AAAA,UAC9B,CAAC;AACD,yBAAe,eAAe;AAC9B,gBAAM,WAAW,IAAI,OAAO,gBAAgB,MAAM;AAClD,cAAI;AACF,kBAAM,SAAS,mBAAmB,cAAc,CAAC;AAAA,UACnD,UAAE;AACA,qBAAS,QAAQ;AAAA,UACnB;AAAA,QACF;AAEA,cAAM,iBAAiB,MAAM,2BAA2B,QAAQ;AAAA,UAC9D,IAAI,WAAW;AAAA,UACf,MAAM,WAAW;AAAA,UACjB,OAAO,OAAO,WAAW,QAAQ;AAAA,UACjC,SAAS,WAAW;AAAA,QACtB,CAAC;AACD,oBAAY,eAAe;AAC3B,qBAAa,eAAe;AAC5B,wBAAgB,eAAe;AAAA,MACjC,OAAO;AACL,oBAAY;AACZ,YAAI,oBAAoB,oBAAoB;AAC1C,gBAAM,iBAAiB,MAAM,mCAAmC;AAAA,YAC9D,YAAY;AAAA,YACZ,IAAI;AAAA,cACF,IAAI,mBAAmB;AAAA,cACvB,MAAM,mBAAmB;AAAA,cACzB,OAAO,mBAAmB;AAAA,cAC1B,SAAS,mBAAmB;AAAA,cAC5B,WAAW;AAAA,YACb;AAAA,UACF,CAAC;AAED,cACE,eAAe,SAAS,aACxB,eAAe,iBACf;AACA,6BAAiB,KAAK,KAAK;AAAA,cACzB,IAAI;AAAA,cACJ,MAAM,MAAM;AAAA,cACZ,MAAM;AAAA,cACN;AAAA,cACA,UAAU;AAAA,cACV,uBAAuB;AAAA,cACvB;AAAA,cACA;AAAA,cACA;AAAA,cACA,UAAU;AAAA,gBACR,QAAQ;AAAA,gBACR,eAAe,eAAe;AAAA,cAChC;AAAA,YACF,CAAC;AACD,mBAAO;AAAA,UACT;AAEA,yBACE,YAAY,iBAAiB,eAAe,SAAS;AAEvD,cAAI,eAAe,SAAS,aAAa,QAAQ;AAC/C,kBAAM,WAAW,IAAI,OAAO,gBAAgB,MAAM;AAClD,gBAAI;AACF,oBAAM,SAAS,mBAAmB,cAAc,CAAC;AAAA,YACnD,UAAE;AACA,uBAAS,QAAQ;AAAA,YACnB;AAAA,UACF;AAAA,QACF;AAEA,cAAM,kBAAkB,MAAM,mCAAmC;AAAA,UAC/D,YAAY;AAAA,UACZ,IAAI;AAAA,YACF,IAAI,WAAW;AAAA,YACf,MAAM,WAAW;AAAA,YACjB,OAAO,WAAW;AAAA,YAClB,SAAS,WAAW;AAAA,YACpB,WAAW;AAAA,UACb;AAAA,QACF,CAAC;AAED,YACE,gBAAgB,SAAS,aACzB,gBAAgB,iBAChB;AACA,2BAAiB,KAAK,KAAK;AAAA,YACzB,IAAI;AAAA,YACJ,MAAM,MAAM;AAAA,YACZ,MAAM;AAAA,YACN;AAAA,YACA,UAAU;AAAA,YACV,uBAAuB;AAAA,YACvB;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,WAAW;AAAA,cACT,QAAQ;AAAA,cACR,eAAe,gBAAgB;AAAA,YACjC;AAAA,UACF,CAAC;AACD,iBAAO;AAAA,QACT;AAEA,oBAAY,YAAY,kBAAkB,gBAAgB,SAAS;AAAA,MACrE;AAEA,UAAI;AACF,cAAM,cACJ,KAAK,WAAW,WAAW,KAAK,WAAW,WACvC,KAAK,SACL;AAEN,qCAA6B;AAAA,UAC3B,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,MAAM,MAAM;AAAA,UACZ,cAAc,MAAM;AAAA,UACpB,aAAa,MAAM;AAAA,UACnB,OAAO,MAAM;AAAA,UACb,SAAS;AAAA,YACP,QAAQ,MAAM,QAAQ;AAAA,YACtB,QAAQ,MAAM,QAAQ;AAAA,YACtB,WAAW,MAAM,QAAQ;AAAA,UAC3B;AAAA,UACA,UAAU;AAAA,YACR,QAAQ,MAAM,SAAS;AAAA,YACvB,QAAQ,MAAM,SAAS;AAAA,YACvB,WAAW,MAAM,SAAS;AAAA,UAC5B;AAAA,UACA,QAAQ;AAAA,UACR,eAAe;AAAA,UACf,OAAO;AAAA,UACP,aAAa;AAAA,UACb,SAAS;AAAA,UACT,sBAAsB;AAAA,UACtB,aAAa,GAAG,oBAAoB,eAAe,OAAO,SAAS;AAAA,QACrE,CAAC;AAAA,MACH,SAAS,WAAW;AAClB,eAAO;AAAA,UACL,8CAA8C,qBAAqB,QAAQ,UAAU,UAAU,SAAS;AAAA,QAC1G;AAAA,MACF;AAEA,uBAAiB,KAAK,KAAK;AAAA,QACzB,IAAI;AAAA,QACJ,MAAM,MAAM;AAAA,QACZ,MAAM;AAAA,QACN;AAAA,QACA,UAAU;AAAA,QACV,uBAAuB;AAAA,QACvB;AAAA,QACA;AAAA,QACA;AAAA,QACA,WAAW;AAAA,UACT,MAAM;AAAA,UACN,OAAO;AAAA,UACP,UAAU;AAAA,UACV,UAAU,WAAW;AAAA,UACrB,aAAa,GAAG,oBAAoB,eAAe,OAAO,SAAS;AAAA,UACnE,aAAa;AAAA,UACb,QAAQ;AAAA,UACR;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH,SAAS,KAAK;AACZ,UAAI,yBAAyB,GAAG,GAAG;AACjC,yBAAiB,KAAK,KAAK;AAAA,UACzB,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,UAAU;AAAA,UACV,uBAAuB;AAAA,UACvB,OAAO,IAAI;AAAA,UACX,WAAW;AAAA,YACT,QAAQ;AAAA,YACR,eAAe,wBAAwB,GAAG;AAAA,UAC5C;AAAA,QACF,CAAC;AACD,eAAO;AAAA,MACT;AAEA;AAAA,QACE;AAAA,QACA;AAAA,QACA,2BAA2B,eAAe,QAAQ,IAAI,UAAU,eAAe;AAAA,MACjF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAGA,MAAI,WAAW,UAAU,IAAI,aAAa,gCAAgC;AACxE,QAAI,CAAC,0BAA0B,KAAK,GAAG,GAAG;AACxC,aAAO;AAAA,IACT;AAEA,UAAM,OAAO,MAAM,mBAAmB,KAAK,GAAG;AAC9C,QAAI,QAAQ,MAAM;AAChB,aAAO;AAAA,IACT;AAEA,UAAM,eACJ,OAAO,KAAK,cAAc,WAAW,KAAK,UAAU,KAAK,IAAI;AAC/D,UAAM,SAAS,OAAO,KAAK,WAAW,WAAW,KAAK,OAAO,KAAK,IAAI;AACtE,UAAM,cACJ,OAAO,KAAK,gBAAgB,WAAW,KAAK,YAAY,KAAK,IAAI;AAEnE,QAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,aAAa;AAC5C;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAEA,UAAM,SAAS,gBAAgB;AAC/B,UAAM,sBAAsB,4BAA4B,MAAM;AAC9D,UAAM,oBAAoB;AAAA,MACxB;AAAA,MACA,yBAAyB,GAAG;AAAA,IAC9B;AACA,UAAM,cAAc,QAAQ,QAAQ,IAAI,iBAAiB,KAAK,CAAC;AAC/D,UAAM,mBAAmB,oBAAoB;AAC7C,UAAM,UAAU,eAAe;AAC/B,UAAM,YAAY,mBAAmB;AACrC,UAAM,eAAe,0BAA0B,MAAM;AACrD,UAAM,sBAAsB,2BAA2B;AAEvD,QAAI;AACJ,QAAI;AACF,kBAAY,OAAO,WAAW,YAAY;AAAA,IAC5C,QAAQ;AACN;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAEA,UAAM,QAAQ,YAAY,YAAY,MAAM;AAC5C,QAAI,WAAW;AACf,QAAI,OAAO,KAAK,iBAAiB,YAAY,KAAK,aAAa,KAAK,GAAG;AACrE,YAAM,WAAW,IAAI,OAAO;AAAA,QAC1B,wBAAwB;AAAA,UACtB,SAAS,aAAa;AAAA,UACtB,oBAAoB,aAAa;AAAA,QACnC,CAAC,KAAK;AAAA,MACR;AACA,UAAI;AACF,cAAM,gBAAgB,IAAI,OAAO;AAAA,UAC/B,KAAK;AAAA,UACL,CAAC,0CAA0C;AAAA,UAC3C;AAAA,QACF;AACA,mBAAW,OAAO,MAAM,cAAc,SAAS,CAAC;AAAA,MAClD,UAAE;AACA,iBAAS,QAAQ;AAAA,MACnB;AAAA,IACF;AAEA,UAAM,aAAa;AAAA,MACjB,SAAS,oBAAoB;AAAA,MAC7B,MAAM,UAAU,cAAc;AAAA,MAC9B,IACE,SAAS,OAAO,KAAK,iBAAiB,WAClC,YACA,KAAK;AAAA,MACX,MAAM,QACF,OACA,IAAI,OAAO,UAAU;AAAA,QACnB;AAAA,MACF,CAAC,EAAE,mBAAmB,YAAY;AAAA,QAChC;AAAA,QACA,OAAO,WAAW,QAAQ,QAAQ;AAAA,MACpC,CAAC;AAAA,MACL,UAAU,QAAQ,OAAO,WAAW,MAAM,EAAE,SAAS,IAAI;AAAA,MACzD,aAAa,oBAAoB;AAAA,MACjC;AAAA,MACA;AAAA,MACA,cACE,OAAO,KAAK,iBAAiB,WAAW,KAAK,eAAe;AAAA,IAChE;AAEA,QAAI,CAAC,WAAW,CAAC,qBAAqB,KAAK,YAAY,MAAM;AAC3D,uBAAiB,KAAK,KAAK;AAAA,QACzB,IAAI;AAAA,QACJ,MAAM;AAAA,UACJ;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA,UAAU;AAAA,QACV,uBAAuB;AAAA,QACvB;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc,WAAW;AAAA,QACzB;AAAA,MACF,CAAC;AACD,aAAO;AAAA,IACT;AAEA,UAAM,UAAU,wBAAwB;AAAA,MACtC,SAAS,aAAa;AAAA,MACtB,oBAAoB,aAAa;AAAA,IACnC,CAAC;AAED,QAAI;AACF,UAAI,YAAY;AAChB,UAAI,aAA4B;AAChC,UAAI,gBAAgB;AACpB,UAAI,YAAqC,cACrC,cACA;AAEJ,UAAI,eAAe,mBAAmB;AACpC,YAAI,CAAC,SAAS;AACZ;AAAA,YACE;AAAA,YACA;AAAA,YACA;AAAA,UACF;AACA,iBAAO;AAAA,QACT;AAEA,cAAM,iBAAiB,MAAM,2BAA2B,SAAS;AAAA,UAC/D,IAAI,WAAW;AAAA,UACf,MAAM,WAAW;AAAA,UACjB,OAAO,OAAO,WAAW,QAAQ;AAAA,UACjC,SAAS,WAAW;AAAA,QACtB,CAAC;AACD,oBAAY,eAAe;AAC3B,qBAAa,eAAe;AAC5B,wBAAgB,eAAe;AAAA,MACjC,OAAO;AACL,oBAAY;AACZ,cAAM,kBAAkB,MAAM,mCAAmC;AAAA,UAC/D,YAAY,UAAU;AAAA,UACtB,IAAI;AAAA,YACF,IAAI,WAAW;AAAA,YACf,MAAM,WAAW;AAAA,YACjB,OAAO,WAAW;AAAA,YAClB,SAAS,WAAW;AAAA,YACpB,WAAW;AAAA,UACb;AAAA,QACF,CAAC;AAED,YACE,gBAAgB,SAAS,aACzB,gBAAgB,iBAChB;AACA,2BAAiB,KAAK,KAAK;AAAA,YACzB,IAAI;AAAA,YACJ,MAAM;AAAA,YACN,UAAU;AAAA,YACV,uBAAuB;AAAA,YACvB;AAAA,YACA;AAAA,YACA;AAAA,YACA,cAAc,WAAW;AAAA,YACzB;AAAA,YACA,WAAW;AAAA,cACT,QAAQ;AAAA,cACR,eAAe,gBAAgB;AAAA,YACjC;AAAA,UACF,CAAC;AACD,iBAAO;AAAA,QACT;AAEA,oBAAY,YAAY,kBAAkB,gBAAgB,SAAS;AAAA,MACrE;AAEA,uBAAiB,KAAK,KAAK;AAAA,QACzB,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,UAAU;AAAA,QACV,uBAAuB;AAAA,QACvB;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc,WAAW;AAAA,QACzB;AAAA,QACA,WAAW;AAAA,UACT,MAAM;AAAA,UACN,OAAO;AAAA,UACP,UAAU;AAAA,UACV,UAAU,WAAW;AAAA,UACrB,aAAa,GAAG,oBAAoB,eAAe,OAAO,SAAS;AAAA,UACnE,aAAa;AAAA,UACb,QAAQ;AAAA,QACV;AAAA,MACF,CAAC;AAAA,IACH,SAAS,KAAK;AACZ,UAAI,yBAAyB,GAAG,GAAG;AACjC,yBAAiB,KAAK,KAAK;AAAA,UACzB,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,UAAU;AAAA,UACV,uBAAuB;AAAA,UACvB,OAAO,IAAI;AAAA,UACX,WAAW;AAAA,YACT,QAAQ;AAAA,YACR,eAAe,wBAAwB,GAAG;AAAA,UAC5C;AAAA,QACF,CAAC;AACD,eAAO;AAAA,MACT;AAEA;AAAA,QACE;AAAA,QACA;AAAA,QACA,oBAAoB,eAAe,QAAQ,IAAI,UAAU,eAAe;AAAA,MAC1E;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;","names":[]}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Fills `process.env` wallet keys from the OS secret store when the key is
3
+ * unset/blank. Runs before upstream `startApiServer` merges `config.env`, so
4
+ * persisted config only fills gaps the store did not supply.
5
+ */
6
+ export declare function hydrateWalletKeysFromNodePlatformSecureStore(): Promise<void>;
7
+ //# sourceMappingURL=hydrate-wallet-keys-from-platform-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hydrate-wallet-keys-from-platform-store.d.ts","sourceRoot":"","sources":["../../src/security/hydrate-wallet-keys-from-platform-store.ts"],"names":[],"mappings":"AAgBA;;;;GAIG;AACH,wBAAsB,4CAA4C,IAAI,OAAO,CAAC,IAAI,CAAC,CA6BlF"}