gnoman 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.cjs +24 -0
- package/.gnoman/contracts.json +4094 -0
- package/.gnoman/exec_package/runtime-debug.jsonl +45 -0
- package/.gnoman/holds.sqlite +0 -0
- package/.gnoman/license.json +7 -0
- package/.gnoman/safes.json +37 -0
- package/.gnoman/vanity-jobs.json +67 -0
- package/.gnoman/wallets.db +0 -0
- package/.prettierrc.json +6 -0
- package/CODex_TASKS.md +124 -0
- package/LICENSE.md +164 -0
- package/README.md +95 -0
- package/assets/GnoLogo.jpg +0 -0
- package/assets/self.png +0 -0
- package/backend/controllers/contractController.ts +49 -0
- package/backend/controllers/devToolsController.ts +76 -0
- package/backend/controllers/etherscanController.ts +59 -0
- package/backend/controllers/historyController.ts +7 -0
- package/backend/controllers/keyringController.ts +134 -0
- package/backend/controllers/robinhoodController.ts +80 -0
- package/backend/controllers/safeController.ts +167 -0
- package/backend/controllers/sandboxController.ts +63 -0
- package/backend/controllers/settingsController.ts +38 -0
- package/backend/controllers/walletController.ts +151 -0
- package/backend/index.ts +133 -0
- package/backend/licenses/license_public.pem +3 -0
- package/backend/licenses/verify_license.py +43 -0
- package/backend/routes/contractRoutes.ts +11 -0
- package/backend/routes/devToolsRoutes.ts +11 -0
- package/backend/routes/etherscanRoutes.ts +11 -0
- package/backend/routes/historyRoutes.ts +8 -0
- package/backend/routes/keyringRoutes.ts +25 -0
- package/backend/routes/licenseRoutes.ts +35 -0
- package/backend/routes/robinhoodRoutes.ts +22 -0
- package/backend/routes/runtimeRoutes.ts +29 -0
- package/backend/routes/safeRoutes.ts +28 -0
- package/backend/routes/sandboxRoutes.ts +17 -0
- package/backend/routes/settingsRoutes.ts +14 -0
- package/backend/routes/walletRoutes.ts +21 -0
- package/backend/services/chainlinkService.ts +65 -0
- package/backend/services/contractRegistryService.ts +205 -0
- package/backend/services/devToolsService.ts +251 -0
- package/backend/services/diagnosticsService.ts +350 -0
- package/backend/services/etherscanService.ts +152 -0
- package/backend/services/historyService.ts +89 -0
- package/backend/services/keyringAccessor.ts +4 -0
- package/backend/services/licenseService.ts +163 -0
- package/backend/services/onchain/abiRegistry.ts +57 -0
- package/backend/services/onchain/chainlinkClient.ts +56 -0
- package/backend/services/onchain/errors.ts +16 -0
- package/backend/services/onchain/etherscanClient.ts +94 -0
- package/backend/services/onchain/index.ts +76 -0
- package/backend/services/onchain/tenderlyRpcClient.ts +74 -0
- package/backend/services/onchain/types.ts +33 -0
- package/backend/services/onchainAutomationService.ts +424 -0
- package/backend/services/robinhood/auth.ts +42 -0
- package/backend/services/robinhood/client.ts +123 -0
- package/backend/services/robinhood/integrationService.ts +140 -0
- package/backend/services/robinhood/provider.ts +22 -0
- package/backend/services/robinhood/unofficialClient.ts +66 -0
- package/backend/services/rpcService.ts +44 -0
- package/backend/services/runtimeTelemetryService.ts +158 -0
- package/backend/services/safeConfigRepository.ts +205 -0
- package/backend/services/safeService.ts +588 -0
- package/backend/services/sandboxService.ts +157 -0
- package/backend/services/secureSettingsService.ts +45 -0
- package/backend/services/transactionHoldService.ts +223 -0
- package/backend/services/vanityService.ts +293 -0
- package/backend/services/walletService.ts +290 -0
- package/backend/services/walletStore.ts +179 -0
- package/backend/types/express-async-handler.d.ts +13 -0
- package/backend/types/keyring.d.ts +19 -0
- package/backend/utils/abiResolver.ts +208 -0
- package/backend/utils/http.ts +6 -0
- package/backend/utils/secretsResolver.ts +150 -0
- package/backend/utils/signer.ts +11 -0
- package/backend/workers/vanityWorker.ts +76 -0
- package/capacitor.config.ts +13 -0
- package/cli/gnoman.ts +424 -0
- package/contracts/OracleConsumer.sol +20 -0
- package/contracts/PriceFeedConsumer.sol +22 -0
- package/dist/backend/backend/controllers/contractController.js +41 -0
- package/dist/backend/backend/controllers/contractController.js.map +1 -0
- package/dist/backend/backend/controllers/devToolsController.js +63 -0
- package/dist/backend/backend/controllers/devToolsController.js.map +1 -0
- package/dist/backend/backend/controllers/etherscanController.js +53 -0
- package/dist/backend/backend/controllers/etherscanController.js.map +1 -0
- package/dist/backend/backend/controllers/historyController.js +12 -0
- package/dist/backend/backend/controllers/historyController.js.map +1 -0
- package/dist/backend/backend/controllers/keyringController.js +126 -0
- package/dist/backend/backend/controllers/keyringController.js.map +1 -0
- package/dist/backend/backend/controllers/robinhoodController.js +69 -0
- package/dist/backend/backend/controllers/robinhoodController.js.map +1 -0
- package/dist/backend/backend/controllers/safeController.js +137 -0
- package/dist/backend/backend/controllers/safeController.js.map +1 -0
- package/dist/backend/backend/controllers/sandboxController.js +48 -0
- package/dist/backend/backend/controllers/sandboxController.js.map +1 -0
- package/dist/backend/backend/controllers/settingsController.js +34 -0
- package/dist/backend/backend/controllers/settingsController.js.map +1 -0
- package/dist/backend/backend/controllers/walletController.js +140 -0
- package/dist/backend/backend/controllers/walletController.js.map +1 -0
- package/dist/backend/backend/index.js +119 -0
- package/dist/backend/backend/index.js.map +1 -0
- package/dist/backend/backend/routes/contractRoutes.js +44 -0
- package/dist/backend/backend/routes/contractRoutes.js.map +1 -0
- package/dist/backend/backend/routes/devToolsRoutes.js +44 -0
- package/dist/backend/backend/routes/devToolsRoutes.js.map +1 -0
- package/dist/backend/backend/routes/etherscanRoutes.js +44 -0
- package/dist/backend/backend/routes/etherscanRoutes.js.map +1 -0
- package/dist/backend/backend/routes/historyRoutes.js +41 -0
- package/dist/backend/backend/routes/historyRoutes.js.map +1 -0
- package/dist/backend/backend/routes/keyringRoutes.js +18 -0
- package/dist/backend/backend/routes/keyringRoutes.js.map +1 -0
- package/dist/backend/backend/routes/licenseRoutes.js +30 -0
- package/dist/backend/backend/routes/licenseRoutes.js.map +1 -0
- package/dist/backend/backend/routes/robinhoodRoutes.js +14 -0
- package/dist/backend/backend/routes/robinhoodRoutes.js.map +1 -0
- package/dist/backend/backend/routes/runtimeRoutes.js +26 -0
- package/dist/backend/backend/routes/runtimeRoutes.js.map +1 -0
- package/dist/backend/backend/routes/safeRoutes.js +61 -0
- package/dist/backend/backend/routes/safeRoutes.js.map +1 -0
- package/dist/backend/backend/routes/sandboxRoutes.js +50 -0
- package/dist/backend/backend/routes/sandboxRoutes.js.map +1 -0
- package/dist/backend/backend/routes/settingsRoutes.js +10 -0
- package/dist/backend/backend/routes/settingsRoutes.js.map +1 -0
- package/dist/backend/backend/routes/walletRoutes.js +54 -0
- package/dist/backend/backend/routes/walletRoutes.js.map +1 -0
- package/dist/backend/backend/services/chainlinkService.js +48 -0
- package/dist/backend/backend/services/chainlinkService.js.map +1 -0
- package/dist/backend/backend/services/contractRegistryService.js +138 -0
- package/dist/backend/backend/services/contractRegistryService.js.map +1 -0
- package/dist/backend/backend/services/devToolsService.js +213 -0
- package/dist/backend/backend/services/devToolsService.js.map +1 -0
- package/dist/backend/backend/services/diagnosticsService.js +286 -0
- package/dist/backend/backend/services/diagnosticsService.js.map +1 -0
- package/dist/backend/backend/services/etherscanService.js +125 -0
- package/dist/backend/backend/services/etherscanService.js.map +1 -0
- package/dist/backend/backend/services/historyService.js +75 -0
- package/dist/backend/backend/services/historyService.js.map +1 -0
- package/dist/backend/backend/services/keyringAccessor.js +40 -0
- package/dist/backend/backend/services/keyringAccessor.js.map +1 -0
- package/dist/backend/backend/services/licenseService.js +130 -0
- package/dist/backend/backend/services/licenseService.js.map +1 -0
- package/dist/backend/backend/services/onchain/abiRegistry.js +47 -0
- package/dist/backend/backend/services/onchain/abiRegistry.js.map +1 -0
- package/dist/backend/backend/services/onchain/chainlinkClient.js +43 -0
- package/dist/backend/backend/services/onchain/chainlinkClient.js.map +1 -0
- package/dist/backend/backend/services/onchain/errors.js +13 -0
- package/dist/backend/backend/services/onchain/errors.js.map +1 -0
- package/dist/backend/backend/services/onchain/etherscanClient.js +82 -0
- package/dist/backend/backend/services/onchain/etherscanClient.js.map +1 -0
- package/dist/backend/backend/services/onchain/index.js +79 -0
- package/dist/backend/backend/services/onchain/index.js.map +1 -0
- package/dist/backend/backend/services/onchain/tenderlyRpcClient.js +60 -0
- package/dist/backend/backend/services/onchain/tenderlyRpcClient.js.map +1 -0
- package/dist/backend/backend/services/onchain/types.js +14 -0
- package/dist/backend/backend/services/onchain/types.js.map +1 -0
- package/dist/backend/backend/services/onchainAutomationService.js +316 -0
- package/dist/backend/backend/services/onchainAutomationService.js.map +1 -0
- package/dist/backend/backend/services/robinhood/auth.js +26 -0
- package/dist/backend/backend/services/robinhood/auth.js.map +1 -0
- package/dist/backend/backend/services/robinhood/client.js +73 -0
- package/dist/backend/backend/services/robinhood/client.js.map +1 -0
- package/dist/backend/backend/services/robinhood/integrationService.js +119 -0
- package/dist/backend/backend/services/robinhood/integrationService.js.map +1 -0
- package/dist/backend/backend/services/robinhood/provider.js +17 -0
- package/dist/backend/backend/services/robinhood/provider.js.map +1 -0
- package/dist/backend/backend/services/robinhood/unofficialClient.js +61 -0
- package/dist/backend/backend/services/robinhood/unofficialClient.js.map +1 -0
- package/dist/backend/backend/services/rpcService.js +48 -0
- package/dist/backend/backend/services/rpcService.js.map +1 -0
- package/dist/backend/backend/services/runtimeTelemetryService.js +96 -0
- package/dist/backend/backend/services/runtimeTelemetryService.js.map +1 -0
- package/dist/backend/backend/services/safeConfigRepository.js +147 -0
- package/dist/backend/backend/services/safeConfigRepository.js.map +1 -0
- package/dist/backend/backend/services/safeService.js +527 -0
- package/dist/backend/backend/services/safeService.js.map +1 -0
- package/dist/backend/backend/services/sandboxService.js +135 -0
- package/dist/backend/backend/services/sandboxService.js.map +1 -0
- package/dist/backend/backend/services/secureSettingsService.js +50 -0
- package/dist/backend/backend/services/secureSettingsService.js.map +1 -0
- package/dist/backend/backend/services/transactionHoldService.js +184 -0
- package/dist/backend/backend/services/transactionHoldService.js.map +1 -0
- package/dist/backend/backend/services/vanityService.js +235 -0
- package/dist/backend/backend/services/vanityService.js.map +1 -0
- package/dist/backend/backend/services/walletService.js +202 -0
- package/dist/backend/backend/services/walletService.js.map +1 -0
- package/dist/backend/backend/services/walletStore.js +132 -0
- package/dist/backend/backend/services/walletStore.js.map +1 -0
- package/dist/backend/backend/utils/abiResolver.js +182 -0
- package/dist/backend/backend/utils/abiResolver.js.map +1 -0
- package/dist/backend/backend/utils/http.js +12 -0
- package/dist/backend/backend/utils/http.js.map +1 -0
- package/dist/backend/backend/utils/secretsResolver.js +137 -0
- package/dist/backend/backend/utils/secretsResolver.js.map +1 -0
- package/dist/backend/backend/utils/signer.js +15 -0
- package/dist/backend/backend/utils/signer.js.map +1 -0
- package/dist/backend/backend/workers/vanityWorker.js +63 -0
- package/dist/backend/backend/workers/vanityWorker.js.map +1 -0
- package/dist/backend/cli/gnoman.js +387 -0
- package/dist/backend/cli/gnoman.js.map +1 -0
- package/dist/backend/modules/sandbox/abiLoader.js +78 -0
- package/dist/backend/modules/sandbox/abiLoader.js.map +1 -0
- package/dist/backend/modules/sandbox/contractSimulator.js +205 -0
- package/dist/backend/modules/sandbox/contractSimulator.js.map +1 -0
- package/dist/backend/modules/sandbox/formBuilder.js +14 -0
- package/dist/backend/modules/sandbox/formBuilder.js.map +1 -0
- package/dist/backend/modules/sandbox/index.js +24 -0
- package/dist/backend/modules/sandbox/index.js.map +1 -0
- package/dist/backend/modules/sandbox/localFork.js +103 -0
- package/dist/backend/modules/sandbox/localFork.js.map +1 -0
- package/dist/backend/modules/sandbox/sandboxManager.js +130 -0
- package/dist/backend/modules/sandbox/sandboxManager.js.map +1 -0
- package/dist/backend/modules/sandbox/types.js +3 -0
- package/dist/backend/modules/sandbox/types.js.map +1 -0
- package/dist/backend/src/core/backends/fileBackend.js +136 -0
- package/dist/backend/src/core/backends/fileBackend.js.map +1 -0
- package/dist/backend/src/core/backends/memoryBackend.js +26 -0
- package/dist/backend/src/core/backends/memoryBackend.js.map +1 -0
- package/dist/backend/src/core/backends/systemBackend.js +86 -0
- package/dist/backend/src/core/backends/systemBackend.js.map +1 -0
- package/dist/backend/src/core/backends/types.js +12 -0
- package/dist/backend/src/core/backends/types.js.map +1 -0
- package/dist/backend/src/core/keyringManager.js +178 -0
- package/dist/backend/src/core/keyringManager.js.map +1 -0
- package/dist/backend/src/utils/abiResolver.js +180 -0
- package/dist/backend/src/utils/abiResolver.js.map +1 -0
- package/dist/backend/src/utils/runtimeObservability.js +78 -0
- package/dist/backend/src/utils/runtimeObservability.js.map +1 -0
- package/dist/backend/src/utils/secretsResolver.js +138 -0
- package/dist/backend/src/utils/secretsResolver.js.map +1 -0
- package/dist/cli/backend/services/diagnosticsService.js +286 -0
- package/dist/cli/backend/services/diagnosticsService.js.map +1 -0
- package/dist/cli/backend/services/keyringAccessor.js +40 -0
- package/dist/cli/backend/services/keyringAccessor.js.map +1 -0
- package/dist/cli/backend/services/rpcService.js +48 -0
- package/dist/cli/backend/services/rpcService.js.map +1 -0
- package/dist/cli/backend/services/runtimeTelemetryService.js +96 -0
- package/dist/cli/backend/services/runtimeTelemetryService.js.map +1 -0
- package/dist/cli/backend/services/walletService.js +202 -0
- package/dist/cli/backend/services/walletService.js.map +1 -0
- package/dist/cli/backend/services/walletStore.js +132 -0
- package/dist/cli/backend/services/walletStore.js.map +1 -0
- package/dist/cli/backend/utils/http.js +12 -0
- package/dist/cli/backend/utils/http.js.map +1 -0
- package/dist/cli/backend/utils/secretsResolver.js +137 -0
- package/dist/cli/backend/utils/secretsResolver.js.map +1 -0
- package/dist/cli/cli/gnoman.js +387 -0
- package/dist/cli/cli/gnoman.js.map +1 -0
- package/dist/cli/src/core/backends/fileBackend.js +136 -0
- package/dist/cli/src/core/backends/fileBackend.js.map +1 -0
- package/dist/cli/src/core/backends/memoryBackend.js +26 -0
- package/dist/cli/src/core/backends/memoryBackend.js.map +1 -0
- package/dist/cli/src/core/backends/systemBackend.js +86 -0
- package/dist/cli/src/core/backends/systemBackend.js.map +1 -0
- package/dist/cli/src/core/backends/types.js +12 -0
- package/dist/cli/src/core/backends/types.js.map +1 -0
- package/dist/cli/src/core/keyringManager.js +178 -0
- package/dist/cli/src/core/keyringManager.js.map +1 -0
- package/dist/cli/src/utils/abiResolver.js +180 -0
- package/dist/cli/src/utils/abiResolver.js.map +1 -0
- package/dist/cli/src/utils/runtimeObservability.js +78 -0
- package/dist/cli/src/utils/runtimeObservability.js.map +1 -0
- package/dist/cli/src/utils/secretsResolver.js +138 -0
- package/dist/cli/src/utils/secretsResolver.js.map +1 -0
- package/dist/main/backend/services/keyringAccessor.js +40 -0
- package/dist/main/backend/services/keyringAccessor.js.map +1 -0
- package/dist/main/backend/utils/http.js +12 -0
- package/dist/main/backend/utils/http.js.map +1 -0
- package/dist/main/main/ipcHandlers/index.js +26 -0
- package/dist/main/main/ipcHandlers/index.js.map +1 -0
- package/dist/main/main/keyring/keyringmanager.js +101 -0
- package/dist/main/main/keyring/keyringmanager.js.map +1 -0
- package/dist/main/main/main.js +224 -0
- package/dist/main/main/main.js.map +1 -0
- package/dist/main/main/preload/index.js +19 -0
- package/dist/main/main/preload/index.js.map +1 -0
- package/dist/main/main/preload/licenseBridge.js +105 -0
- package/dist/main/main/preload/licenseBridge.js.map +1 -0
- package/dist/main/src/core/backends/fileBackend.js +136 -0
- package/dist/main/src/core/backends/fileBackend.js.map +1 -0
- package/dist/main/src/core/backends/memoryBackend.js +26 -0
- package/dist/main/src/core/backends/memoryBackend.js.map +1 -0
- package/dist/main/src/core/backends/systemBackend.js +86 -0
- package/dist/main/src/core/backends/systemBackend.js.map +1 -0
- package/dist/main/src/core/backends/types.js +12 -0
- package/dist/main/src/core/backends/types.js.map +1 -0
- package/dist/main/src/core/keyringManager.js +178 -0
- package/dist/main/src/core/keyringManager.js.map +1 -0
- package/dist/main/src/utils/abiResolver.js +180 -0
- package/dist/main/src/utils/abiResolver.js.map +1 -0
- package/dist/main/src/utils/runtimeObservability.js +78 -0
- package/dist/main/src/utils/runtimeObservability.js.map +1 -0
- package/dist/main/src/utils/secretsResolver.js +138 -0
- package/dist/main/src/utils/secretsResolver.js.map +1 -0
- package/docs/development-guide.md +203 -0
- package/docs/etherscan-chainlink-integration.md +44 -0
- package/docs/gnoman-20-user-manual-STANDARD-PRINT-READY.pdf +0 -0
- package/docs/gnoman-20-user-manual-STANDARD.pdf +0 -0
- package/docs/license-dev-guide.md +106 -0
- package/docs/robinhood-integration.md +30 -0
- package/docs/system-audit-gpt-guide.md +208 -0
- package/docs/system-robustness-audit.md +50 -0
- package/docs/user-guide.md +73 -0
- package/docs/wiki/development-guide.md +203 -0
- package/docs/wiki/license-dev-guide.md +106 -0
- package/docs/wiki/user-guide.md +73 -0
- package/eslint.config.js +85 -0
- package/gnoman2.0/.eslintrc.cjs +24 -0
- package/gnoman2.0/.prettierrc.json +6 -0
- package/gnoman2.0/CODex_TASKS.md +124 -0
- package/gnoman2.0/LICENSE.md +164 -0
- package/gnoman2.0/README.md +95 -0
- package/gnoman2.0/assets/GnoLogo.jpg +0 -0
- package/gnoman2.0/assets/self.png +0 -0
- package/gnoman2.0/backend/controllers/contractController.ts +49 -0
- package/gnoman2.0/backend/controllers/devToolsController.ts +76 -0
- package/gnoman2.0/backend/controllers/etherscanController.ts +59 -0
- package/gnoman2.0/backend/controllers/historyController.ts +7 -0
- package/gnoman2.0/backend/controllers/keyringController.ts +134 -0
- package/gnoman2.0/backend/controllers/robinhoodController.ts +80 -0
- package/gnoman2.0/backend/controllers/safeController.ts +167 -0
- package/gnoman2.0/backend/controllers/sandboxController.ts +63 -0
- package/gnoman2.0/backend/controllers/settingsController.ts +38 -0
- package/gnoman2.0/backend/controllers/walletController.ts +151 -0
- package/gnoman2.0/backend/index.ts +133 -0
- package/gnoman2.0/backend/licenses/license_public.pem +3 -0
- package/gnoman2.0/backend/licenses/verify_license.py +43 -0
- package/gnoman2.0/backend/routes/contractRoutes.ts +11 -0
- package/gnoman2.0/backend/routes/devToolsRoutes.ts +11 -0
- package/gnoman2.0/backend/routes/etherscanRoutes.ts +11 -0
- package/gnoman2.0/backend/routes/historyRoutes.ts +8 -0
- package/gnoman2.0/backend/routes/keyringRoutes.ts +25 -0
- package/gnoman2.0/backend/routes/licenseRoutes.ts +35 -0
- package/gnoman2.0/backend/routes/robinhoodRoutes.ts +22 -0
- package/gnoman2.0/backend/routes/runtimeRoutes.ts +29 -0
- package/gnoman2.0/backend/routes/safeRoutes.ts +28 -0
- package/gnoman2.0/backend/routes/sandboxRoutes.ts +17 -0
- package/gnoman2.0/backend/routes/settingsRoutes.ts +14 -0
- package/gnoman2.0/backend/routes/walletRoutes.ts +21 -0
- package/gnoman2.0/backend/services/chainlinkService.ts +65 -0
- package/gnoman2.0/backend/services/contractRegistryService.ts +205 -0
- package/gnoman2.0/backend/services/devToolsService.ts +251 -0
- package/gnoman2.0/backend/services/diagnosticsService.ts +350 -0
- package/gnoman2.0/backend/services/etherscanService.ts +152 -0
- package/gnoman2.0/backend/services/historyService.ts +89 -0
- package/gnoman2.0/backend/services/keyringAccessor.ts +4 -0
- package/gnoman2.0/backend/services/licenseService.ts +163 -0
- package/gnoman2.0/backend/services/onchain/abiRegistry.ts +57 -0
- package/gnoman2.0/backend/services/onchain/chainlinkClient.ts +56 -0
- package/gnoman2.0/backend/services/onchain/errors.ts +16 -0
- package/gnoman2.0/backend/services/onchain/etherscanClient.ts +94 -0
- package/gnoman2.0/backend/services/onchain/index.ts +76 -0
- package/gnoman2.0/backend/services/onchain/tenderlyRpcClient.ts +74 -0
- package/gnoman2.0/backend/services/onchain/types.ts +33 -0
- package/gnoman2.0/backend/services/onchainAutomationService.ts +424 -0
- package/gnoman2.0/backend/services/robinhood/auth.ts +42 -0
- package/gnoman2.0/backend/services/robinhood/client.ts +123 -0
- package/gnoman2.0/backend/services/robinhood/integrationService.ts +140 -0
- package/gnoman2.0/backend/services/robinhood/provider.ts +22 -0
- package/gnoman2.0/backend/services/robinhood/unofficialClient.ts +66 -0
- package/gnoman2.0/backend/services/rpcService.ts +44 -0
- package/gnoman2.0/backend/services/runtimeTelemetryService.ts +158 -0
- package/gnoman2.0/backend/services/safeConfigRepository.ts +205 -0
- package/gnoman2.0/backend/services/safeService.ts +588 -0
- package/gnoman2.0/backend/services/sandboxService.ts +157 -0
- package/gnoman2.0/backend/services/secureSettingsService.ts +45 -0
- package/gnoman2.0/backend/services/transactionHoldService.ts +223 -0
- package/gnoman2.0/backend/services/vanityService.ts +293 -0
- package/gnoman2.0/backend/services/walletService.ts +290 -0
- package/gnoman2.0/backend/services/walletStore.ts +179 -0
- package/gnoman2.0/backend/types/express-async-handler.d.ts +13 -0
- package/gnoman2.0/backend/types/keyring.d.ts +19 -0
- package/gnoman2.0/backend/utils/abiResolver.ts +208 -0
- package/gnoman2.0/backend/utils/http.ts +6 -0
- package/gnoman2.0/backend/utils/secretsResolver.ts +150 -0
- package/gnoman2.0/backend/utils/signer.ts +11 -0
- package/gnoman2.0/backend/workers/vanityWorker.ts +76 -0
- package/gnoman2.0/capacitor.config.ts +13 -0
- package/gnoman2.0/cli/gnoman.ts +424 -0
- package/gnoman2.0/contracts/OracleConsumer.sol +20 -0
- package/gnoman2.0/contracts/PriceFeedConsumer.sol +22 -0
- package/gnoman2.0/docs/development-guide.md +203 -0
- package/gnoman2.0/docs/etherscan-chainlink-integration.md +44 -0
- package/gnoman2.0/docs/gnoman-20-user-manual-STANDARD-PRINT-READY.pdf +0 -0
- package/gnoman2.0/docs/gnoman-20-user-manual-STANDARD.pdf +0 -0
- package/gnoman2.0/docs/license-dev-guide.md +106 -0
- package/gnoman2.0/docs/robinhood-integration.md +30 -0
- package/gnoman2.0/docs/system-audit-gpt-guide.md +208 -0
- package/gnoman2.0/docs/system-robustness-audit.md +50 -0
- package/gnoman2.0/docs/user-guide.md +73 -0
- package/gnoman2.0/docs/wiki/development-guide.md +203 -0
- package/gnoman2.0/docs/wiki/license-dev-guide.md +106 -0
- package/gnoman2.0/docs/wiki/user-guide.md +73 -0
- package/gnoman2.0/eslint.config.js +85 -0
- package/gnoman2.0/gnomon/__init__.py +0 -0
- package/gnoman2.0/gnomon/api/__init__.py +0 -0
- package/gnoman2.0/gnomon/api/etherscan_tracker.py +72 -0
- package/gnoman2.0/gnomon/core/__init__.py +0 -0
- package/gnoman2.0/gnomon/core/safe_manager.py +111 -0
- package/gnoman2.0/gnomon/tests/test_abi_resolver.py +181 -0
- package/gnoman2.0/gnomon/tests/test_safe_persistence_and_etherscan.py +97 -0
- package/gnoman2.0/gnomon/utils/__init__.py +5 -0
- package/gnoman2.0/gnomon/utils/abi_resolver.py +255 -0
- package/gnoman2.0/ios/ExportOptions.plist +16 -0
- package/gnoman2.0/ios/README.md +33 -0
- package/gnoman2.0/jest.config.ts +18 -0
- package/gnoman2.0/keyring/__init__.py +17 -0
- package/gnoman2.0/licensingServer/package.json +23 -0
- package/gnoman2.0/licensingServer/src/config/keys.ts +84 -0
- package/gnoman2.0/licensingServer/src/index.ts +30 -0
- package/gnoman2.0/licensingServer/src/lib/canonicalize.ts +5 -0
- package/gnoman2.0/licensingServer/src/lib/crypto.ts +25 -0
- package/gnoman2.0/licensingServer/src/lib/validate.ts +62 -0
- package/gnoman2.0/licensingServer/src/middleware/auth.ts +20 -0
- package/gnoman2.0/licensingServer/src/routes/licenses.ts +110 -0
- package/gnoman2.0/licensingServer/tsconfig.json +12 -0
- package/gnoman2.0/main/ipcHandlers/index.ts +23 -0
- package/gnoman2.0/main/keyring/keyringmanager.ts +154 -0
- package/gnoman2.0/main/main.ts +234 -0
- package/gnoman2.0/main/preload/index.ts +31 -0
- package/gnoman2.0/main/preload/licenseBridge.ts +73 -0
- package/gnoman2.0/modules/sandbox/abiLoader.ts +78 -0
- package/gnoman2.0/modules/sandbox/contractSimulator.ts +241 -0
- package/gnoman2.0/modules/sandbox/formBuilder.ts +16 -0
- package/gnoman2.0/modules/sandbox/index.ts +6 -0
- package/gnoman2.0/modules/sandbox/localFork.ts +129 -0
- package/gnoman2.0/modules/sandbox/safe.abi.json +82 -0
- package/gnoman2.0/modules/sandbox/sandboxManager.ts +154 -0
- package/gnoman2.0/modules/sandbox/types.ts +84 -0
- package/gnoman2.0/modules/sandbox/ui/LogViewer.tsx +30 -0
- package/gnoman2.0/modules/sandbox/ui/ParameterForm.tsx +49 -0
- package/gnoman2.0/modules/sandbox/ui/SandboxPanel.tsx +568 -0
- package/gnoman2.0/package-lock.json +10904 -0
- package/gnoman2.0/package.json +82 -0
- package/gnoman2.0/renderer/components/LicenseScreen.tsx +134 -0
- package/gnoman2.0/renderer/index.html +12 -0
- package/gnoman2.0/renderer/package-lock.json +4104 -0
- package/gnoman2.0/renderer/package.json +35 -0
- package/gnoman2.0/renderer/postcss.config.cjs +6 -0
- package/gnoman2.0/renderer/src/App.tsx +229 -0
- package/gnoman2.0/renderer/src/context/KeyringContext.tsx +217 -0
- package/gnoman2.0/renderer/src/context/SafeContext.tsx +49 -0
- package/gnoman2.0/renderer/src/context/ThemeContext.tsx +60 -0
- package/gnoman2.0/renderer/src/context/WalletContext.tsx +50 -0
- package/gnoman2.0/renderer/src/context/main.tsx +18 -0
- package/gnoman2.0/renderer/src/main.tsx +18 -0
- package/gnoman2.0/renderer/src/pages/Contracts.tsx +482 -0
- package/gnoman2.0/renderer/src/pages/Dashboard.tsx +653 -0
- package/gnoman2.0/renderer/src/pages/DeveloperTools.tsx +270 -0
- package/gnoman2.0/renderer/src/pages/History.tsx +149 -0
- package/gnoman2.0/renderer/src/pages/Keyring.tsx +449 -0
- package/gnoman2.0/renderer/src/pages/Safes.tsx +1089 -0
- package/gnoman2.0/renderer/src/pages/Sandbox.tsx +146 -0
- package/gnoman2.0/renderer/src/pages/Settings.tsx +871 -0
- package/gnoman2.0/renderer/src/pages/Wallets.tsx +752 -0
- package/gnoman2.0/renderer/src/pages/WikiGuide.tsx +75 -0
- package/gnoman2.0/renderer/src/styles.css +32 -0
- package/gnoman2.0/renderer/src/types/gnoman.d.ts +9 -0
- package/gnoman2.0/renderer/src/types/license.ts +8 -0
- package/gnoman2.0/renderer/src/types/safevault.d.ts +17 -0
- package/gnoman2.0/renderer/src/utils/backend.ts +88 -0
- package/gnoman2.0/renderer/tailwind.config.cjs +8 -0
- package/gnoman2.0/renderer/tsconfig.json +13 -0
- package/gnoman2.0/renderer/tsconfig.node.json +9 -0
- package/gnoman2.0/renderer/vite.config.ts +19 -0
- package/gnoman2.0/requests/__init__.py +35 -0
- package/gnoman2.0/scripts/build-ios.sh +30 -0
- package/gnoman2.0/scripts/copyBackendAssets.js +24 -0
- package/gnoman2.0/scripts/copyRenderer.js +87 -0
- package/gnoman2.0/scripts/launchElectron.js +51 -0
- package/gnoman2.0/src/core/backends/fileBackend.ts +154 -0
- package/gnoman2.0/src/core/backends/memoryBackend.ts +27 -0
- package/gnoman2.0/src/core/backends/systemBackend.ts +66 -0
- package/gnoman2.0/src/core/backends/types.ts +17 -0
- package/gnoman2.0/src/core/keyringManager.ts +208 -0
- package/gnoman2.0/src/utils/abiCache/.gitkeep +0 -0
- package/gnoman2.0/src/utils/abiResolver.ts +200 -0
- package/gnoman2.0/src/utils/runtimeObservability.ts +110 -0
- package/gnoman2.0/src/utils/secretsResolver.ts +144 -0
- package/gnoman2.0/tests/chainlinkService.test.ts +32 -0
- package/gnoman2.0/tests/diagnosticsService.test.ts +68 -0
- package/gnoman2.0/tests/etherscanController.test.ts +99 -0
- package/gnoman2.0/tests/etherscanService.test.ts +116 -0
- package/gnoman2.0/tests/keyringManager.test.ts +135 -0
- package/gnoman2.0/tests/onchainToolkit.test.ts +71 -0
- package/gnoman2.0/tests/robinhoodClient.test.ts +54 -0
- package/gnoman2.0/tests/robinhoodController.test.ts +81 -0
- package/gnoman2.0/tests/robinhoodIntegrationService.test.ts +50 -0
- package/gnoman2.0/tests/safeServicePersistence.test.ts +81 -0
- package/gnoman2.0/tests/test_contract_sandbox/sandbox.test.js +407 -0
- package/gnoman2.0/tests/walletController.test.ts +57 -0
- package/gnoman2.0/tsconfig.backend.json +7 -0
- package/gnoman2.0/tsconfig.cli.json +7 -0
- package/gnoman2.0/tsconfig.json +18 -0
- package/gnoman2.0/tsconfig.main.json +7 -0
- package/gnomon/__init__.py +0 -0
- package/gnomon/__pycache__/__init__.cpython-310.pyc +0 -0
- package/gnomon/api/__init__.py +0 -0
- package/gnomon/api/__pycache__/__init__.cpython-310.pyc +0 -0
- package/gnomon/api/__pycache__/etherscan_tracker.cpython-310.pyc +0 -0
- package/gnomon/api/etherscan_tracker.py +72 -0
- package/gnomon/core/__init__.py +0 -0
- package/gnomon/core/safe_manager.py +111 -0
- package/gnomon/tests/__pycache__/test_safe_persistence_and_etherscan.cpython-310-pytest-8.3.3.pyc +0 -0
- package/gnomon/tests/test_abi_resolver.py +181 -0
- package/gnomon/tests/test_safe_persistence_and_etherscan.py +97 -0
- package/gnomon/utils/__init__.py +5 -0
- package/gnomon/utils/abi_resolver.py +255 -0
- package/ios/ExportOptions.plist +16 -0
- package/ios/README.md +33 -0
- package/jest.config.ts +18 -0
- package/keyring/__init__.py +17 -0
- package/launcher.sh +57 -0
- package/license.env +2 -0
- package/licensingServer/package.json +23 -0
- package/licensingServer/src/config/keys.ts +84 -0
- package/licensingServer/src/index.ts +30 -0
- package/licensingServer/src/lib/canonicalize.ts +5 -0
- package/licensingServer/src/lib/crypto.ts +25 -0
- package/licensingServer/src/lib/validate.ts +62 -0
- package/licensingServer/src/middleware/auth.ts +20 -0
- package/licensingServer/src/routes/licenses.ts +110 -0
- package/licensingServer/tsconfig.json +12 -0
- package/main/ipcHandlers/index.ts +23 -0
- package/main/keyring/keyringmanager.ts +154 -0
- package/main/main.ts +234 -0
- package/main/preload/index.ts +31 -0
- package/main/preload/licenseBridge.ts +73 -0
- package/modules/sandbox/abiLoader.ts +78 -0
- package/modules/sandbox/contractSimulator.ts +241 -0
- package/modules/sandbox/formBuilder.ts +16 -0
- package/modules/sandbox/index.ts +6 -0
- package/modules/sandbox/localFork.ts +129 -0
- package/modules/sandbox/safe.abi.json +82 -0
- package/modules/sandbox/sandboxManager.ts +154 -0
- package/modules/sandbox/types.ts +84 -0
- package/modules/sandbox/ui/LogViewer.tsx +30 -0
- package/modules/sandbox/ui/ParameterForm.tsx +49 -0
- package/modules/sandbox/ui/SandboxPanel.tsx +568 -0
- package/package.json +82 -0
- package/renderer/components/LicenseScreen.tsx +134 -0
- package/renderer/index.html +12 -0
- package/renderer/package-lock.json +4104 -0
- package/renderer/package.json +35 -0
- package/renderer/postcss.config.cjs +6 -0
- package/renderer/src/App.tsx +229 -0
- package/renderer/src/context/KeyringContext.tsx +217 -0
- package/renderer/src/context/SafeContext.tsx +49 -0
- package/renderer/src/context/ThemeContext.tsx +60 -0
- package/renderer/src/context/WalletContext.tsx +50 -0
- package/renderer/src/context/main.tsx +18 -0
- package/renderer/src/main.tsx +18 -0
- package/renderer/src/pages/Contracts.tsx +482 -0
- package/renderer/src/pages/Dashboard.tsx +653 -0
- package/renderer/src/pages/DeveloperTools.tsx +270 -0
- package/renderer/src/pages/History.tsx +149 -0
- package/renderer/src/pages/Keyring.tsx +449 -0
- package/renderer/src/pages/Safes.tsx +1089 -0
- package/renderer/src/pages/Sandbox.tsx +146 -0
- package/renderer/src/pages/Settings.tsx +871 -0
- package/renderer/src/pages/Wallets.tsx +752 -0
- package/renderer/src/pages/WikiGuide.tsx +75 -0
- package/renderer/src/styles.css +32 -0
- package/renderer/src/types/gnoman.d.ts +9 -0
- package/renderer/src/types/license.ts +8 -0
- package/renderer/src/types/safevault.d.ts +17 -0
- package/renderer/src/utils/backend.ts +88 -0
- package/renderer/tailwind.config.cjs +8 -0
- package/renderer/tsconfig.json +13 -0
- package/renderer/tsconfig.node.json +9 -0
- package/renderer/vite.config.ts +19 -0
- package/requests/__init__.py +35 -0
- package/requests/__pycache__/__init__.cpython-310.pyc +0 -0
- package/scripts/build-ios.sh +30 -0
- package/scripts/copyBackendAssets.js +24 -0
- package/scripts/copyRenderer.js +87 -0
- package/scripts/deployBackend.sh +24 -0
- package/scripts/launchElectron.js +51 -0
- package/src/core/backends/fileBackend.ts +154 -0
- package/src/core/backends/memoryBackend.ts +27 -0
- package/src/core/backends/systemBackend.ts +66 -0
- package/src/core/backends/types.ts +17 -0
- package/src/core/keyringManager.ts +208 -0
- package/src/utils/abiCache/.gitkeep +0 -0
- package/src/utils/abiResolver.ts +200 -0
- package/src/utils/runtimeObservability.ts +110 -0
- package/src/utils/secretsResolver.ts +144 -0
- package/tests/chainlinkService.test.ts +32 -0
- package/tests/diagnosticsService.test.ts +68 -0
- package/tests/etherscanController.test.ts +99 -0
- package/tests/etherscanService.test.ts +116 -0
- package/tests/keyringManager.test.ts +135 -0
- package/tests/onchainToolkit.test.ts +71 -0
- package/tests/robinhoodClient.test.ts +54 -0
- package/tests/robinhoodController.test.ts +81 -0
- package/tests/robinhoodIntegrationService.test.ts +50 -0
- package/tests/safeServicePersistence.test.ts +81 -0
- package/tests/test_contract_sandbox/sandbox.test.js +407 -0
- package/tests/walletController.test.ts +57 -0
- package/touch +14 -0
- package/tsconfig.backend.json +7 -0
- package/tsconfig.cli.json +7 -0
- package/tsconfig.json +18 -0
- package/tsconfig.main.json +7 -0
- package/webhook-shim.js +50 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import asyncHandler from 'express-async-handler';
|
|
2
|
+
import type { Request, Response } from 'express';
|
|
3
|
+
import { addContract, listContracts, removeContract } from '../services/contractRegistryService';
|
|
4
|
+
import { abiResolver } from '../utils/abiResolver';
|
|
5
|
+
import { getBalance } from '../services/rpcService';
|
|
6
|
+
|
|
7
|
+
export const listContractsHandler = asyncHandler(async (_req: Request, res: Response) => {
|
|
8
|
+
const records = listContracts();
|
|
9
|
+
const balances = await Promise.all(records.map((record) => getBalance(record.address)));
|
|
10
|
+
res.json(
|
|
11
|
+
records.map((record, index) => ({
|
|
12
|
+
...record,
|
|
13
|
+
balance: balances[index]
|
|
14
|
+
}))
|
|
15
|
+
);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
export const addContractHandler = asyncHandler(async (req: Request, res: Response) => {
|
|
19
|
+
const { address, name, network, tags, type, abi } = req.body as {
|
|
20
|
+
address: string;
|
|
21
|
+
name?: string;
|
|
22
|
+
network?: string;
|
|
23
|
+
tags?: string[];
|
|
24
|
+
type?: string;
|
|
25
|
+
abi?: string;
|
|
26
|
+
};
|
|
27
|
+
const record = addContract({ address, name, network, tags, type, abi });
|
|
28
|
+
res.status(201).json(record);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
export const removeContractHandler = asyncHandler(async (req: Request, res: Response) => {
|
|
32
|
+
const removed = removeContract(req.params.id);
|
|
33
|
+
if (!removed) {
|
|
34
|
+
res.status(404).json({ message: 'Contract not found' });
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
res.json(removed);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
export const resolveContractAbiHandler = asyncHandler(async (req: Request, res: Response) => {
|
|
42
|
+
const { chainId, address, contractName } = req.body as { chainId?: number; address?: string; contractName?: string };
|
|
43
|
+
if (!address?.trim()) {
|
|
44
|
+
res.status(400).json({ message: 'address is required.' });
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const result = await abiResolver.resolve(Number(chainId) || 1, address, contractName);
|
|
48
|
+
res.json(result);
|
|
49
|
+
});
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import asyncHandler from 'express-async-handler';
|
|
2
|
+
import type { Request, Response } from 'express';
|
|
3
|
+
import { decodePayload, discoverContract, estimateGasForFunction, fetchSourceCode, scanSourceCode } from '../services/devToolsService';
|
|
4
|
+
|
|
5
|
+
export const discoverContractHandler = asyncHandler(async (req: Request, res: Response) => {
|
|
6
|
+
const { address, chainId } = req.body as { address?: string; chainId?: number };
|
|
7
|
+
if (!address?.trim()) {
|
|
8
|
+
res.status(400).json({ message: 'address is required.' });
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
const payload = await discoverContract(address, chainId);
|
|
12
|
+
res.json(payload);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export const estimateGasHandler = asyncHandler(async (req: Request, res: Response) => {
|
|
16
|
+
const { address, chainId, functionSignature, args, from, value } = req.body as {
|
|
17
|
+
address?: string;
|
|
18
|
+
chainId?: number;
|
|
19
|
+
functionSignature?: string;
|
|
20
|
+
args?: string[];
|
|
21
|
+
from?: string;
|
|
22
|
+
value?: string;
|
|
23
|
+
};
|
|
24
|
+
if (!address?.trim() || !functionSignature?.trim()) {
|
|
25
|
+
res.status(400).json({ message: 'address and functionSignature are required.' });
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const payload = await estimateGasForFunction({
|
|
29
|
+
address,
|
|
30
|
+
chainId,
|
|
31
|
+
functionSignature,
|
|
32
|
+
args: Array.isArray(args) ? args : [],
|
|
33
|
+
from,
|
|
34
|
+
value
|
|
35
|
+
});
|
|
36
|
+
res.json(payload);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
export const scanContractHandler = asyncHandler(async (req: Request, res: Response) => {
|
|
40
|
+
const { address, chainId, sourceCode } = req.body as { address?: string; chainId?: number; sourceCode?: string };
|
|
41
|
+
let finalSource = sourceCode?.trim() ?? '';
|
|
42
|
+
let sourceName = 'manual';
|
|
43
|
+
if (!finalSource && address?.trim()) {
|
|
44
|
+
const fetched = await fetchSourceCode(address, chainId);
|
|
45
|
+
finalSource = fetched.sourceCode;
|
|
46
|
+
sourceName = fetched.contractName;
|
|
47
|
+
}
|
|
48
|
+
if (!finalSource) {
|
|
49
|
+
res.status(400).json({ message: 'Either address or sourceCode must be provided.' });
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const report = scanSourceCode(finalSource);
|
|
53
|
+
res.json({
|
|
54
|
+
sourceName,
|
|
55
|
+
findings: report.findings,
|
|
56
|
+
overallRiskScore: report.overallRiskScore
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
export const decodeHandler = asyncHandler(async (req: Request, res: Response) => {
|
|
61
|
+
const { mode, chainId, txHash, address, calldata, topics, eventData } = req.body as {
|
|
62
|
+
mode?: 'txHash' | 'rawCalldata' | 'eventLog';
|
|
63
|
+
chainId?: number;
|
|
64
|
+
txHash?: string;
|
|
65
|
+
address?: string;
|
|
66
|
+
calldata?: string;
|
|
67
|
+
topics?: string[];
|
|
68
|
+
eventData?: string;
|
|
69
|
+
};
|
|
70
|
+
if (!mode) {
|
|
71
|
+
res.status(400).json({ message: 'mode is required.' });
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const payload = await decodePayload({ mode, chainId, txHash, address, calldata, topics, eventData });
|
|
75
|
+
res.json(payload);
|
|
76
|
+
});
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import asyncHandler from 'express-async-handler';
|
|
2
|
+
import type { Request, Response } from 'express';
|
|
3
|
+
import { getGasOracle, getTxHistory } from '../services/etherscanService';
|
|
4
|
+
import { abiResolver } from '../utils/abiResolver';
|
|
5
|
+
|
|
6
|
+
const parseChainId = (value: unknown) => {
|
|
7
|
+
if (typeof value === 'number' && Number.isInteger(value) && value > 0) {
|
|
8
|
+
return value;
|
|
9
|
+
}
|
|
10
|
+
if (typeof value === 'string' && value.trim()) {
|
|
11
|
+
const parsed = Number.parseInt(value, 10);
|
|
12
|
+
if (Number.isInteger(parsed) && parsed > 0) {
|
|
13
|
+
return parsed;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return undefined;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const resolveContractAbi = asyncHandler(async (req: Request, res: Response) => {
|
|
20
|
+
const { address, chainId, abiNameHint } = req.body as {
|
|
21
|
+
address: string;
|
|
22
|
+
chainId?: number | string;
|
|
23
|
+
abiNameHint?: string;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
if (!address?.trim()) {
|
|
27
|
+
res.status(400).json({ message: 'address is required' });
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const resolvedChainId = parseChainId(chainId) ?? 1;
|
|
32
|
+
const result = await abiResolver.resolve(resolvedChainId, address, abiNameHint);
|
|
33
|
+
|
|
34
|
+
res.json({
|
|
35
|
+
address,
|
|
36
|
+
chainId: resolvedChainId,
|
|
37
|
+
...result,
|
|
38
|
+
itemCount: result.abi.length
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
export const resolveContractAbiFile = asyncHandler(async (req: Request, res: Response) => {
|
|
43
|
+
const chainId = parseChainId(req.query.chainId) ?? 1;
|
|
44
|
+
const abiNameHint = typeof req.query.abiNameHint === 'string' ? req.query.abiNameHint : undefined;
|
|
45
|
+
const result = await abiResolver.resolve(chainId, req.params.address, abiNameHint);
|
|
46
|
+
res.json({ address: req.params.address, chainId, filePath: result.cachePath, source: result.source, cached: result.cached });
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
export const getAddressTxHistory = asyncHandler(async (req: Request, res: Response) => {
|
|
50
|
+
const chainId = parseChainId(req.query.chainId);
|
|
51
|
+
const history = await getTxHistory(req.params.address, chainId);
|
|
52
|
+
res.json(history);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
export const getCurrentGasOracle = asyncHandler(async (req: Request, res: Response) => {
|
|
56
|
+
const chainId = parseChainId(req.query.chainId);
|
|
57
|
+
const oracle = await getGasOracle(chainId);
|
|
58
|
+
res.json(oracle);
|
|
59
|
+
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import asyncHandler from 'express-async-handler';
|
|
2
|
+
import type { Request, Response } from 'express';
|
|
3
|
+
import { getHistoryEntries } from '../services/historyService';
|
|
4
|
+
|
|
5
|
+
export const listHistory = asyncHandler(async (_req: Request, res: Response) => {
|
|
6
|
+
res.json(getHistoryEntries());
|
|
7
|
+
});
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import asyncHandler from 'express-async-handler';
|
|
2
|
+
import type { Request, Response } from 'express';
|
|
3
|
+
import keyringManager from '../services/keyringAccessor';
|
|
4
|
+
import type { KeyringBackendName } from '../../src/core/backends/types';
|
|
5
|
+
|
|
6
|
+
const AVAILABLE_BACKENDS: KeyringBackendName[] = ['system', 'file', 'memory'];
|
|
7
|
+
|
|
8
|
+
const maskValue = (value: string | null) => {
|
|
9
|
+
if (!value) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
if (value.length <= 4) {
|
|
13
|
+
return '*'.repeat(value.length);
|
|
14
|
+
}
|
|
15
|
+
return `${value.slice(0, 2)}***${value.slice(-2)}`;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const isBackendName = (value: unknown): value is KeyringBackendName =>
|
|
19
|
+
typeof value === 'string' && AVAILABLE_BACKENDS.includes(value as KeyringBackendName);
|
|
20
|
+
|
|
21
|
+
const resolveBackend = (req: Request): KeyringBackendName | undefined | null => {
|
|
22
|
+
const body = req.body as { service?: unknown; backend?: unknown } | undefined;
|
|
23
|
+
const query = req.query as { service?: unknown; backend?: unknown } | undefined;
|
|
24
|
+
const candidate = body?.service ?? body?.backend ?? query?.service ?? query?.backend ?? req.params.name;
|
|
25
|
+
if (candidate === undefined) {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
if (!isBackendName(candidate)) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
return candidate;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const ensureBackend = async (req: Request, res: Response) => {
|
|
35
|
+
const requested = resolveBackend(req);
|
|
36
|
+
if (requested === null) {
|
|
37
|
+
res.status(400).json({ message: 'Unsupported backend. Use system, file, or memory.' });
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
if (requested) {
|
|
41
|
+
await keyringManager.switchBackend(requested);
|
|
42
|
+
}
|
|
43
|
+
return keyringManager.currentBackend();
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export const listSecrets = asyncHandler(async (_req: Request, res: Response) => {
|
|
47
|
+
const active = await ensureBackend(_req, res);
|
|
48
|
+
if (!active) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const secrets = await keyringManager.list();
|
|
52
|
+
res.json({
|
|
53
|
+
service: active,
|
|
54
|
+
backend: active,
|
|
55
|
+
secrets: Object.entries(secrets).map(([key, value]) => ({
|
|
56
|
+
key,
|
|
57
|
+
maskedValue: maskValue(value)
|
|
58
|
+
}))
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const resolveKey = (req: Request) => req.params.key ?? (req.body as { key?: string }).key;
|
|
63
|
+
|
|
64
|
+
export const getSecret = asyncHandler(async (req: Request, res: Response) => {
|
|
65
|
+
const active = await ensureBackend(req, res);
|
|
66
|
+
if (!active) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const key = resolveKey(req);
|
|
70
|
+
if (typeof key !== 'string' || key.trim() === '') {
|
|
71
|
+
res.status(400).json({ message: 'key is required' });
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const value = await keyringManager.get(key);
|
|
75
|
+
if (value === null) {
|
|
76
|
+
res.status(404).json({ message: 'Secret not found' });
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
res.json({ key, value, backend: active, service: active });
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
export const setSecret = asyncHandler(async (req: Request, res: Response) => {
|
|
83
|
+
const active = await ensureBackend(req, res);
|
|
84
|
+
if (!active) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const key = resolveKey(req);
|
|
88
|
+
const { value } = req.body as { value?: string };
|
|
89
|
+
if (typeof key !== 'string' || key.trim() === '') {
|
|
90
|
+
res.status(400).json({ message: 'key is required' });
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
if (typeof value !== 'string') {
|
|
94
|
+
res.status(400).json({ message: 'value must be a string' });
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
await keyringManager.set(key, value);
|
|
98
|
+
res.json({
|
|
99
|
+
key,
|
|
100
|
+
backend: active,
|
|
101
|
+
service: active,
|
|
102
|
+
maskedValue: maskValue(value)
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
export const deleteSecret = asyncHandler(async (req: Request, res: Response) => {
|
|
107
|
+
const active = await ensureBackend(req, res);
|
|
108
|
+
if (!active) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const key = resolveKey(req);
|
|
112
|
+
if (typeof key !== 'string' || key.trim() === '') {
|
|
113
|
+
res.status(400).json({ message: 'key is required' });
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
await keyringManager.delete(key);
|
|
117
|
+
res.json({ key, backend: active, service: active, deleted: true });
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
export const getBackend = asyncHandler(async (_req: Request, res: Response) => {
|
|
121
|
+
const active = keyringManager.currentBackend();
|
|
122
|
+
res.json({ active, service: active, backend: active, available: AVAILABLE_BACKENDS });
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
export const switchBackend = asyncHandler(async (req: Request, res: Response) => {
|
|
126
|
+
const backend = resolveBackend(req);
|
|
127
|
+
if (!backend) {
|
|
128
|
+
res.status(400).json({ message: 'Unsupported backend. Use system, file, or memory.' });
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
await keyringManager.switchBackend(backend);
|
|
132
|
+
const active = keyringManager.currentBackend();
|
|
133
|
+
res.json({ active, service: active, backend: active, available: AVAILABLE_BACKENDS });
|
|
134
|
+
});
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import asyncHandler from 'express-async-handler';
|
|
2
|
+
import type { Request, Response } from 'express';
|
|
3
|
+
import {
|
|
4
|
+
cancelRobinhoodCryptoOrder,
|
|
5
|
+
getRobinhoodCryptoAccounts,
|
|
6
|
+
getRobinhoodCryptoConfigStatus,
|
|
7
|
+
getRobinhoodCryptoMarketData,
|
|
8
|
+
getRobinhoodCryptoOrderStatus,
|
|
9
|
+
purchaseRobinhoodCryptoWithCash,
|
|
10
|
+
setRobinhoodCryptoConfig,
|
|
11
|
+
validateRobinhoodCryptoAuth
|
|
12
|
+
} from '../services/robinhood/integrationService';
|
|
13
|
+
|
|
14
|
+
const USD_EDGE_GATE = 2000;
|
|
15
|
+
|
|
16
|
+
export const getCryptoCredentialsStatus = asyncHandler(async (_req: Request, res: Response) => {
|
|
17
|
+
const [status, auth] = await Promise.all([getRobinhoodCryptoConfigStatus(), validateRobinhoodCryptoAuth()]);
|
|
18
|
+
res.json({ ...status, auth });
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
export const setCryptoCredentials = asyncHandler(async (req: Request, res: Response) => {
|
|
22
|
+
const { apiKey, privateKey } = req.body as { apiKey?: string; privateKey?: string };
|
|
23
|
+
if (!apiKey?.trim()) {
|
|
24
|
+
res.status(400).json({ message: 'apiKey is required.' });
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
if (!privateKey?.trim()) {
|
|
28
|
+
res.status(400).json({ message: 'privateKey is required.' });
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
res.json(await setRobinhoodCryptoConfig(apiKey, privateKey));
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
export const placeCryptoCashOrder = asyncHandler(async (req: Request, res: Response) => {
|
|
35
|
+
const { symbol, cashAmount } = req.body as { symbol?: string; cashAmount?: number };
|
|
36
|
+
if (!symbol?.trim()) {
|
|
37
|
+
res.status(400).json({ message: 'symbol is required.' });
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const amount = Number(cashAmount);
|
|
41
|
+
if (!Number.isFinite(amount) || amount <= 0) {
|
|
42
|
+
res.status(400).json({ message: 'cashAmount must be a positive number.' });
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (amount < USD_EDGE_GATE) {
|
|
46
|
+
res.status(400).json({ message: `cashAmount must be at least ${USD_EDGE_GATE}.` });
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const order = await purchaseRobinhoodCryptoWithCash(symbol, amount);
|
|
50
|
+
res.status(201).json(order);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
export const getCryptoOrderStatus = asyncHandler(async (req: Request, res: Response) => {
|
|
54
|
+
const { orderId } = req.params;
|
|
55
|
+
if (!orderId?.trim()) {
|
|
56
|
+
res.status(400).json({ message: 'orderId is required.' });
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const status = await getRobinhoodCryptoOrderStatus(orderId);
|
|
60
|
+
res.json(status);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
export const cancelCryptoOrder = asyncHandler(async (req: Request, res: Response) => {
|
|
64
|
+
const { orderId } = req.params;
|
|
65
|
+
if (!orderId?.trim()) {
|
|
66
|
+
res.status(400).json({ message: 'orderId is required.' });
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const status = await cancelRobinhoodCryptoOrder(orderId);
|
|
70
|
+
res.json(status);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
export const getCryptoAccounts = asyncHandler(async (_req: Request, res: Response) => {
|
|
74
|
+
res.json(await getRobinhoodCryptoAccounts());
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
export const getCryptoMarketData = asyncHandler(async (req: Request, res: Response) => {
|
|
78
|
+
const symbol = String(req.query.symbol ?? 'BTC-USD');
|
|
79
|
+
res.json(await getRobinhoodCryptoMarketData(symbol));
|
|
80
|
+
});
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import asyncHandler from 'express-async-handler';
|
|
2
|
+
import type { Request, Response } from 'express';
|
|
3
|
+
import {
|
|
4
|
+
connectToSafe,
|
|
5
|
+
getOwners,
|
|
6
|
+
addOwner as addSafeOwner,
|
|
7
|
+
removeOwner as removeSafeOwner,
|
|
8
|
+
changeThreshold as changeSafeThreshold,
|
|
9
|
+
enableModule as enableSafeModule,
|
|
10
|
+
disableModule as disableSafeModule,
|
|
11
|
+
addDelegate as addSafeDelegate,
|
|
12
|
+
removeDelegate as removeSafeDelegate,
|
|
13
|
+
updateFallbackHandler as updateSafeFallbackHandler,
|
|
14
|
+
updateGuard as updateSafeGuard,
|
|
15
|
+
proposeTransaction as proposeSafeTransaction,
|
|
16
|
+
executeTransaction as executeSafeTransaction,
|
|
17
|
+
getSafeDetails as getSafeProfile,
|
|
18
|
+
syncSafeState as syncSafeStateService
|
|
19
|
+
} from '../services/safeService';
|
|
20
|
+
import { holdService } from '../services/transactionHoldService';
|
|
21
|
+
|
|
22
|
+
export const loadSafe = asyncHandler(async (req: Request, res: Response) => {
|
|
23
|
+
const { address, rpcUrl } = req.body as { address: string; rpcUrl?: string };
|
|
24
|
+
const safe = await connectToSafe(address, rpcUrl);
|
|
25
|
+
res.json(safe);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
export const listOwners = asyncHandler(async (req: Request, res: Response) => {
|
|
29
|
+
const owners = await getOwners(req.params.address);
|
|
30
|
+
res.json(owners);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
export const addOwner = asyncHandler(async (req: Request, res: Response) => {
|
|
34
|
+
const { owner, threshold } = req.body as { owner: string; threshold: number };
|
|
35
|
+
const result = await addSafeOwner(req.params.address, owner, threshold);
|
|
36
|
+
res.json(result);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
export const getSafeDetails = asyncHandler(async (req: Request, res: Response) => {
|
|
40
|
+
const safe = await getSafeProfile(req.params.address);
|
|
41
|
+
res.json(safe);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
export const syncSafeState = asyncHandler(async (req: Request, res: Response) => {
|
|
45
|
+
const safe = await syncSafeStateService(req.params.address);
|
|
46
|
+
const balance = await getSafeProfile(req.params.address).then((profile) => profile.balance);
|
|
47
|
+
res.json({
|
|
48
|
+
address: safe.address,
|
|
49
|
+
threshold: safe.threshold,
|
|
50
|
+
owners: safe.owners,
|
|
51
|
+
modules: safe.modules,
|
|
52
|
+
delegates: safe.delegates,
|
|
53
|
+
fallbackHandler: safe.fallbackHandler,
|
|
54
|
+
guard: safe.guard,
|
|
55
|
+
rpcUrl: safe.rpcUrl,
|
|
56
|
+
network: safe.network,
|
|
57
|
+
balance
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
export const removeOwner = asyncHandler(async (req: Request, res: Response) => {
|
|
62
|
+
const { threshold } = req.body as { threshold: number };
|
|
63
|
+
const result = await removeSafeOwner(req.params.address, req.params.ownerAddress, threshold);
|
|
64
|
+
res.json(result);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
export const changeThreshold = asyncHandler(async (req: Request, res: Response) => {
|
|
68
|
+
const { threshold } = req.body as { threshold: number };
|
|
69
|
+
const result = await changeSafeThreshold(req.params.address, threshold);
|
|
70
|
+
res.json(result);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
export const enableModule = asyncHandler(async (req: Request, res: Response) => {
|
|
74
|
+
const { module } = req.body as { module: string };
|
|
75
|
+
const result = await enableSafeModule(req.params.address, module);
|
|
76
|
+
res.json(result);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
export const disableModule = asyncHandler(async (req: Request, res: Response) => {
|
|
80
|
+
const result = await disableSafeModule(req.params.address, req.params.moduleAddress);
|
|
81
|
+
res.json(result);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
export const addDelegate = asyncHandler(async (req: Request, res: Response) => {
|
|
85
|
+
const { address, label } = req.body as { address: string; label?: string };
|
|
86
|
+
const payload = {
|
|
87
|
+
address,
|
|
88
|
+
label: label?.trim() ? label.trim() : 'Proposer',
|
|
89
|
+
since: new Date().toISOString()
|
|
90
|
+
};
|
|
91
|
+
const delegates = await addSafeDelegate(req.params.address, payload);
|
|
92
|
+
res.json(delegates);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
export const removeDelegate = asyncHandler(async (req: Request, res: Response) => {
|
|
96
|
+
const delegates = await removeSafeDelegate(req.params.address, req.params.delegateAddress);
|
|
97
|
+
res.json(delegates);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
export const updateFallbackHandler = asyncHandler(async (req: Request, res: Response) => {
|
|
101
|
+
const { handler } = req.body as { handler?: string };
|
|
102
|
+
const result = await updateSafeFallbackHandler(req.params.address, handler);
|
|
103
|
+
res.json(result);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
export const updateGuard = asyncHandler(async (req: Request, res: Response) => {
|
|
107
|
+
const { guard } = req.body as { guard?: string };
|
|
108
|
+
const result = await updateSafeGuard(req.params.address, guard);
|
|
109
|
+
res.json(result);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
export const proposeTransaction = asyncHandler(async (req: Request, res: Response) => {
|
|
113
|
+
const { tx, meta } = req.body as { tx: unknown; meta?: Record<string, unknown> };
|
|
114
|
+
const proposal = await proposeSafeTransaction(req.params.address, tx, meta);
|
|
115
|
+
res.json(proposal);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
export const executeTransaction = asyncHandler(async (req: Request, res: Response) => {
|
|
119
|
+
const { txHash } = req.params;
|
|
120
|
+
const { password } = req.body as { password?: string };
|
|
121
|
+
const hold = await holdService.getHold(txHash);
|
|
122
|
+
if (hold && !holdService.canExecute(hold)) {
|
|
123
|
+
res.status(423).json({ message: 'Transaction is still in hold period', hold });
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
const execution = await executeSafeTransaction(req.params.address, txHash, password);
|
|
127
|
+
if (hold) {
|
|
128
|
+
await holdService.markExecuted(txHash);
|
|
129
|
+
}
|
|
130
|
+
res.json(execution);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
export const toggleHold = asyncHandler(async (req: Request, res: Response) => {
|
|
134
|
+
const { enabled, holdHours = 24 } = req.body as { enabled: boolean; holdHours?: number };
|
|
135
|
+
const policy = await holdService.setHoldState(req.params.address, enabled, holdHours);
|
|
136
|
+
const summary = holdService.summarize(req.params.address);
|
|
137
|
+
const effective = await holdService.getEffectivePolicy(req.params.address);
|
|
138
|
+
res.json({ policy, summary, effective });
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
export const listHeldTransactions = asyncHandler(async (req: Request, res: Response) => {
|
|
142
|
+
const [transactions, summary, effective] = await Promise.all([
|
|
143
|
+
holdService.listHolds(req.params.address),
|
|
144
|
+
Promise.resolve(holdService.summarize(req.params.address)),
|
|
145
|
+
holdService.getEffectivePolicy(req.params.address)
|
|
146
|
+
]);
|
|
147
|
+
res.json({ records: transactions, summary, effective });
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
export const releaseTransactionHold = asyncHandler(async (req: Request, res: Response) => {
|
|
151
|
+
const hold = await holdService.releaseNow(req.params.txHash);
|
|
152
|
+
res.json(hold ?? { txHash: req.params.txHash, released: true });
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
export const getHoldPolicy = asyncHandler(async (req: Request, res: Response) => {
|
|
156
|
+
const [policy, summary, effective] = await Promise.all([
|
|
157
|
+
Promise.resolve(holdService.getHoldState(req.params.address)),
|
|
158
|
+
Promise.resolve(holdService.summarize(req.params.address)),
|
|
159
|
+
holdService.getEffectivePolicy(req.params.address)
|
|
160
|
+
]);
|
|
161
|
+
res.json({ policy, summary, effective });
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
export const listHoldPolicies = asyncHandler(async (_req: Request, res: Response) => {
|
|
165
|
+
const policies = holdService.listHoldPolicies();
|
|
166
|
+
res.json(policies);
|
|
167
|
+
});
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import asyncHandler from 'express-async-handler';
|
|
2
|
+
import type { Request, Response } from 'express';
|
|
3
|
+
import {
|
|
4
|
+
simulateCallStatic,
|
|
5
|
+
simulateContract,
|
|
6
|
+
simulateSafe,
|
|
7
|
+
getHistory,
|
|
8
|
+
clearHistory,
|
|
9
|
+
loadAbi,
|
|
10
|
+
listAbis,
|
|
11
|
+
startFork,
|
|
12
|
+
stopFork,
|
|
13
|
+
forkStatus
|
|
14
|
+
} from '../services/sandboxService';
|
|
15
|
+
|
|
16
|
+
export const callStaticSimulation = asyncHandler(async (req: Request, res: Response) => {
|
|
17
|
+
const result = await simulateCallStatic(req.body);
|
|
18
|
+
res.json(result);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
export const contractSimulation = asyncHandler(async (req: Request, res: Response) => {
|
|
22
|
+
const result = await simulateContract(req.body);
|
|
23
|
+
res.json(result);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
export const safeSimulation = asyncHandler(async (req: Request, res: Response) => {
|
|
27
|
+
const result = await simulateSafe(req.body);
|
|
28
|
+
res.json(result);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
export const loadAbiHandler = asyncHandler(async (req: Request, res: Response) => {
|
|
32
|
+
const metadata = loadAbi(req.body);
|
|
33
|
+
res.json(metadata);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
export const listAbisHandler = asyncHandler(async (_req: Request, res: Response) => {
|
|
37
|
+
res.json(listAbis());
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
export const historyHandler = asyncHandler(async (_req: Request, res: Response) => {
|
|
41
|
+
res.json(getHistory());
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
export const clearHistoryHandler = asyncHandler(async (_req: Request, res: Response) => {
|
|
45
|
+
clearHistory();
|
|
46
|
+
res.status(204).send();
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
export const startForkHandler = asyncHandler(async (req: Request, res: Response) => {
|
|
50
|
+
const { rpcUrl, blockNumber, port, command } = req.body;
|
|
51
|
+
const status = startFork(rpcUrl, blockNumber, port, command);
|
|
52
|
+
res.json(status);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
export const stopForkHandler = asyncHandler(async (_req: Request, res: Response) => {
|
|
56
|
+
const status = stopFork();
|
|
57
|
+
res.json(status);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
export const forkStatusHandler = asyncHandler(async (_req: Request, res: Response) => {
|
|
61
|
+
const status = forkStatus();
|
|
62
|
+
res.json(status);
|
|
63
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import asyncHandler from 'express-async-handler';
|
|
2
|
+
import type { Request, Response } from 'express';
|
|
3
|
+
import { getSecureSetting, setSecureSetting } from '../services/secureSettingsService';
|
|
4
|
+
import { runtimeObservability } from '../../src/utils/runtimeObservability';
|
|
5
|
+
|
|
6
|
+
interface HoldSettingsPayload {
|
|
7
|
+
enabled: boolean;
|
|
8
|
+
holdHours?: number;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const HOLD_KEY = 'SAFE_TX_HOLD_ENABLED';
|
|
12
|
+
|
|
13
|
+
export const getTransactionHoldSettings = asyncHandler(async (_req: Request, res: Response) => {
|
|
14
|
+
const settings = await getSecureSetting(HOLD_KEY, { enabled: true, holdHours: 24 });
|
|
15
|
+
res.json(settings);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
export const updateTransactionHoldSettings = asyncHandler(async (req: Request, res: Response) => {
|
|
19
|
+
const { enabled, holdHours = 24 } = req.body as HoldSettingsPayload;
|
|
20
|
+
if (typeof enabled !== 'boolean') {
|
|
21
|
+
res.status(400).json({ message: 'enabled must be a boolean' });
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const numericHours = Number(holdHours);
|
|
25
|
+
if (!Number.isFinite(numericHours)) {
|
|
26
|
+
res.status(400).json({ message: 'holdHours must be a number' });
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const normalizedHours = Math.max(1, Math.min(Math.round(numericHours), 24 * 14));
|
|
30
|
+
const payload = { enabled, holdHours: normalizedHours };
|
|
31
|
+
await setSecureSetting(HOLD_KEY, payload);
|
|
32
|
+
res.json(payload);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
export const getRuntimeObservability = asyncHandler(async (_req: Request, res: Response) => {
|
|
37
|
+
res.json(runtimeObservability.snapshot());
|
|
38
|
+
});
|