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,75 @@
|
|
|
1
|
+
const WikiGuide = () => {
|
|
2
|
+
return (
|
|
3
|
+
<div className="space-y-6">
|
|
4
|
+
<section className="rounded-lg border border-slate-800 bg-slate-900/60 p-6">
|
|
5
|
+
<h1 className="text-2xl font-semibold text-slate-100">GNOMAN 2.0 Wiki</h1>
|
|
6
|
+
<p className="mt-3 text-sm text-slate-400">
|
|
7
|
+
Welcome to the GNOMAN 2.0 knowledge base. This in-app guide highlights the most common
|
|
8
|
+
workflows so you can remain focused on secure Safe operations without leaving the desktop
|
|
9
|
+
client.
|
|
10
|
+
</p>
|
|
11
|
+
</section>
|
|
12
|
+
|
|
13
|
+
<section className="rounded-lg border border-slate-800 bg-slate-900/60 p-6">
|
|
14
|
+
<h2 className="text-xl font-semibold text-slate-100">Getting Started</h2>
|
|
15
|
+
<ul className="mt-3 space-y-2 text-sm text-slate-400">
|
|
16
|
+
<li>
|
|
17
|
+
<span className="font-medium text-slate-200">Connect the backend:</span> Start the
|
|
18
|
+
Express server with <code className="rounded bg-slate-800 px-1 py-0.5">npm run dev:backend</code>{' '}
|
|
19
|
+
to unlock wallet and Safe orchestration APIs.
|
|
20
|
+
</li>
|
|
21
|
+
<li>
|
|
22
|
+
<span className="font-medium text-slate-200">Launch the renderer:</span> Use{' '}
|
|
23
|
+
<code className="rounded bg-slate-800 px-1 py-0.5">npm run dev:renderer</code> to preview
|
|
24
|
+
UI changes in the browser or desktop shell.
|
|
25
|
+
</li>
|
|
26
|
+
<li>
|
|
27
|
+
<span className="font-medium text-slate-200">Authenticate your workspace:</span> Activate
|
|
28
|
+
your offline license from <strong>Settings > Offline License Activation</strong> to enable
|
|
29
|
+
enterprise policy enforcement.
|
|
30
|
+
</li>
|
|
31
|
+
</ul>
|
|
32
|
+
</section>
|
|
33
|
+
|
|
34
|
+
<section className="rounded-lg border border-slate-800 bg-slate-900/60 p-6">
|
|
35
|
+
<h2 className="text-xl font-semibold text-slate-100">Wallet Management</h2>
|
|
36
|
+
<p className="mt-3 text-sm text-slate-400">
|
|
37
|
+
Generate or import wallets from the <strong>Wallets</strong> tab. GNOMAN 2.0 encrypts private
|
|
38
|
+
keys using AES-256-GCM before persisting them to disk. Always export encrypted backups after
|
|
39
|
+
onboarding a signing device.
|
|
40
|
+
</p>
|
|
41
|
+
<ul className="mt-3 list-inside list-disc space-y-1 text-sm text-slate-400">
|
|
42
|
+
<li>Use vanity search for predictable addresses without exposing seed phrases.</li>
|
|
43
|
+
<li>Store aliases in the active keyring service via the <strong>Keyring</strong> tab.</li>
|
|
44
|
+
<li>Keep hot wallets isolated by leveraging Safe modules and transaction holds.</li>
|
|
45
|
+
</ul>
|
|
46
|
+
</section>
|
|
47
|
+
|
|
48
|
+
<section className="rounded-lg border border-slate-800 bg-slate-900/60 p-6">
|
|
49
|
+
<h2 className="text-xl font-semibold text-slate-100">Safe Operations</h2>
|
|
50
|
+
<p className="mt-3 text-sm text-slate-400">
|
|
51
|
+
The <strong>Safes</strong> dashboard surfaces owners, module toggles, and pending
|
|
52
|
+
transactions. Enable the 24-hour hold policy to protect high-value actions and require a
|
|
53
|
+
secondary review window.
|
|
54
|
+
</p>
|
|
55
|
+
<p className="mt-3 text-sm text-slate-400">
|
|
56
|
+
Simulate execution flows inside the <strong>Sandbox</strong> to verify calldata before
|
|
57
|
+
requesting signatures. The sandbox proxies <code className="rounded bg-slate-800 px-1 py-0.5">callStatic</code>{' '}
|
|
58
|
+
invocations through the backend for deterministic results.
|
|
59
|
+
</p>
|
|
60
|
+
</section>
|
|
61
|
+
|
|
62
|
+
<section className="rounded-lg border border-slate-800 bg-slate-900/60 p-6">
|
|
63
|
+
<h2 className="text-xl font-semibold text-slate-100">Security Checklist</h2>
|
|
64
|
+
<ul className="mt-3 list-inside list-disc space-y-2 text-sm text-slate-400">
|
|
65
|
+
<li>Verify product registration and license compliance on every new workstation.</li>
|
|
66
|
+
<li>Audit connected RPC endpoints and rotate API keys regularly.</li>
|
|
67
|
+
<li>Enable OS-level full disk encryption so GNOMAN 2.0 secrets remain isolated.</li>
|
|
68
|
+
<li>Keep the Electron shell and backend dependencies patched to the latest releases.</li>
|
|
69
|
+
</ul>
|
|
70
|
+
</section>
|
|
71
|
+
</div>
|
|
72
|
+
);
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export default WikiGuide;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
@tailwind base;
|
|
2
|
+
@tailwind components;
|
|
3
|
+
@tailwind utilities;
|
|
4
|
+
|
|
5
|
+
body {
|
|
6
|
+
font-family: 'Inter', sans-serif;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
:root[data-theme='light'] body {
|
|
10
|
+
background-color: #f8fafc;
|
|
11
|
+
color: #0f172a;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
:root[data-theme='dark'] {
|
|
15
|
+
--panel-bg: rgba(15, 23, 42, 0.6);
|
|
16
|
+
--panel-border: rgba(148, 163, 184, 0.2);
|
|
17
|
+
--panel-text: #e2e8f0;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
:root[data-theme='light'] {
|
|
21
|
+
--panel-bg: rgba(255, 255, 255, 0.85);
|
|
22
|
+
--panel-border: rgba(15, 23, 42, 0.12);
|
|
23
|
+
--panel-text: #0f172a;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.theme-panel {
|
|
27
|
+
background-color: var(--panel-bg) !important;
|
|
28
|
+
border-color: var(--panel-border) !important;
|
|
29
|
+
color: var(--panel-text);
|
|
30
|
+
backdrop-filter: saturate(1.2) blur(8px);
|
|
31
|
+
transition: background-color 200ms ease, border-color 200ms ease, color 200ms ease;
|
|
32
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
type SafevaultValidationResult = {
|
|
2
|
+
ok: boolean;
|
|
3
|
+
reason?: string;
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
type SafevaultAPI = {
|
|
7
|
+
validateLicense: (key: string) => SafevaultValidationResult;
|
|
8
|
+
loadLicense: () => SafevaultValidationResult;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
declare global {
|
|
12
|
+
interface Window {
|
|
13
|
+
safevault: SafevaultAPI;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
const STORAGE_KEY = 'gnoman:backend-base-url';
|
|
2
|
+
const DEFAULT_PORT = 4399;
|
|
3
|
+
const DEFAULT_BASE_URL = `http://127.0.0.1:${DEFAULT_PORT}`;
|
|
4
|
+
const BACKEND_CHANGE_EVENT = 'gnoman:backend-change';
|
|
5
|
+
|
|
6
|
+
const normalizeBaseUrl = (url: string) => url.trim().replace(/\/+$/, '');
|
|
7
|
+
|
|
8
|
+
const readEnvBaseUrl = () => {
|
|
9
|
+
const env = import.meta.env.VITE_GNOMAN_BACKEND_URL;
|
|
10
|
+
if (typeof env === 'string' && env.trim().length > 0) {
|
|
11
|
+
return normalizeBaseUrl(env);
|
|
12
|
+
}
|
|
13
|
+
return null;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const getStoredBackendBaseUrl = () => {
|
|
17
|
+
try {
|
|
18
|
+
return localStorage.getItem(STORAGE_KEY);
|
|
19
|
+
} catch {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const getBackendBaseUrl = () => getStoredBackendBaseUrl() ?? readEnvBaseUrl() ?? DEFAULT_BASE_URL;
|
|
25
|
+
|
|
26
|
+
export const setBackendBaseUrl = (url: string) => {
|
|
27
|
+
const normalized = normalizeBaseUrl(url);
|
|
28
|
+
localStorage.setItem(STORAGE_KEY, normalized);
|
|
29
|
+
window.dispatchEvent(new CustomEvent(BACKEND_CHANGE_EVENT, { detail: normalized }));
|
|
30
|
+
return normalized;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const buildBackendUrl = (path: string) => {
|
|
34
|
+
const base = getBackendBaseUrl();
|
|
35
|
+
const suffix = path.startsWith('/') ? path : `/${path}`;
|
|
36
|
+
return `${base}${suffix}`;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const onBackendBaseUrlChange = (handler: (url: string) => void) => {
|
|
40
|
+
const listener = (event: Event) => {
|
|
41
|
+
if (event instanceof CustomEvent && typeof event.detail === 'string') {
|
|
42
|
+
handler(event.detail);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
window.addEventListener(BACKEND_CHANGE_EVENT, listener);
|
|
46
|
+
return () => window.removeEventListener(BACKEND_CHANGE_EVENT, listener);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export const probeBackend = async (url: string, timeoutMs = 1500) => {
|
|
50
|
+
const controller = new AbortController();
|
|
51
|
+
const timeoutId = window.setTimeout(() => controller.abort(), timeoutMs);
|
|
52
|
+
try {
|
|
53
|
+
const response = await fetch(`${normalizeBaseUrl(url)}/api/health`, {
|
|
54
|
+
cache: 'no-store',
|
|
55
|
+
signal: controller.signal
|
|
56
|
+
});
|
|
57
|
+
return response.ok;
|
|
58
|
+
} catch {
|
|
59
|
+
return false;
|
|
60
|
+
} finally {
|
|
61
|
+
window.clearTimeout(timeoutId);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
export const detectBackendBaseUrl = async (timeoutMs = 1500) => {
|
|
66
|
+
const candidates = new Set<string>();
|
|
67
|
+
const stored = getStoredBackendBaseUrl();
|
|
68
|
+
const env = readEnvBaseUrl();
|
|
69
|
+
if (stored) {
|
|
70
|
+
candidates.add(normalizeBaseUrl(stored));
|
|
71
|
+
}
|
|
72
|
+
if (env) {
|
|
73
|
+
candidates.add(env);
|
|
74
|
+
}
|
|
75
|
+
candidates.add(DEFAULT_BASE_URL);
|
|
76
|
+
candidates.add(`http://localhost:${DEFAULT_PORT}`);
|
|
77
|
+
if (typeof window !== 'undefined' && window.location?.hostname) {
|
|
78
|
+
const host = window.location.hostname;
|
|
79
|
+
candidates.add(`http://${host}:${DEFAULT_PORT}`);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
for (const candidate of candidates) {
|
|
83
|
+
if (await probeBackend(candidate, timeoutMs)) {
|
|
84
|
+
return normalizeBaseUrl(candidate);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../tsconfig.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"jsx": "react-jsx",
|
|
5
|
+
"allowJs": false,
|
|
6
|
+
"baseUrl": "./src",
|
|
7
|
+
"module": "ESNext",
|
|
8
|
+
"outDir": "./dist",
|
|
9
|
+
"types": ["vite/client", "react", "react-dom"]
|
|
10
|
+
},
|
|
11
|
+
"include": ["src", "../modules/sandbox/ui/**/*.tsx", "../modules/sandbox/types.ts", "../modules/sandbox/formBuilder.ts"],
|
|
12
|
+
"exclude": ["node_modules", "dist"]
|
|
13
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { defineConfig } from 'vite';
|
|
2
|
+
import react from '@vitejs/plugin-react';
|
|
3
|
+
|
|
4
|
+
export default defineConfig({
|
|
5
|
+
base: './',
|
|
6
|
+
plugins: [react()],
|
|
7
|
+
server: {
|
|
8
|
+
port: 5173,
|
|
9
|
+
strictPort: true,
|
|
10
|
+
fs: {
|
|
11
|
+
allow: ['..']
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
build: {
|
|
15
|
+
outDir: 'dist',
|
|
16
|
+
emptyOutDir: true,
|
|
17
|
+
manifest: true
|
|
18
|
+
}
|
|
19
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""Minimal requests-compatible shim built on urllib for GNOMAN."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from urllib.error import HTTPError, URLError
|
|
8
|
+
from urllib.request import Request, urlopen
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class Response:
|
|
13
|
+
body: bytes
|
|
14
|
+
status_code: int
|
|
15
|
+
url: str
|
|
16
|
+
|
|
17
|
+
def raise_for_status(self) -> None:
|
|
18
|
+
if 400 <= self.status_code:
|
|
19
|
+
raise HTTPError(self.url, self.status_code, "HTTP Error", hdrs=None, fp=None)
|
|
20
|
+
|
|
21
|
+
def json(self):
|
|
22
|
+
return json.loads(self.body.decode("utf-8"))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def get(url: str, timeout: int = 10) -> Response:
|
|
26
|
+
request = Request(url)
|
|
27
|
+
try:
|
|
28
|
+
with urlopen(request, timeout=timeout) as http_response:
|
|
29
|
+
body = http_response.read()
|
|
30
|
+
status = getattr(http_response, "status", 200)
|
|
31
|
+
except HTTPError as exc:
|
|
32
|
+
raise HTTPError(url, exc.code, exc.reason, exc.hdrs, exc.fp) from exc
|
|
33
|
+
except URLError as exc:
|
|
34
|
+
raise ConnectionError(str(exc)) from exc
|
|
35
|
+
return Response(body=body, status_code=status, url=url)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
if ! command -v xcodebuild >/dev/null 2>&1; then
|
|
5
|
+
echo "xcodebuild not found. Run this on macOS with Xcode installed."
|
|
6
|
+
exit 1
|
|
7
|
+
fi
|
|
8
|
+
|
|
9
|
+
npm run ios:sync
|
|
10
|
+
|
|
11
|
+
WORKSPACE="ios/App/App.xcworkspace"
|
|
12
|
+
SCHEME="App"
|
|
13
|
+
ARCHIVE_PATH="ios/build/GNOMAN.xcarchive"
|
|
14
|
+
EXPORT_PATH="ios/build/export"
|
|
15
|
+
EXPORT_OPTIONS="ios/ExportOptions.plist"
|
|
16
|
+
|
|
17
|
+
xcodebuild \
|
|
18
|
+
-workspace "$WORKSPACE" \
|
|
19
|
+
-scheme "$SCHEME" \
|
|
20
|
+
-configuration Release \
|
|
21
|
+
-destination "generic/platform=iOS" \
|
|
22
|
+
-archivePath "$ARCHIVE_PATH" \
|
|
23
|
+
archive
|
|
24
|
+
|
|
25
|
+
xcodebuild -exportArchive \
|
|
26
|
+
-archivePath "$ARCHIVE_PATH" \
|
|
27
|
+
-exportOptionsPlist "$EXPORT_OPTIONS" \
|
|
28
|
+
-exportPath "$EXPORT_PATH"
|
|
29
|
+
|
|
30
|
+
echo "IPA export complete at: $EXPORT_PATH"
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const assets = [
|
|
5
|
+
{
|
|
6
|
+
source: path.join(__dirname, '../backend/licenses/license_public.pem'),
|
|
7
|
+
target: path.join(__dirname, '../dist/backend/backend/licenses/license_public.pem')
|
|
8
|
+
}
|
|
9
|
+
];
|
|
10
|
+
|
|
11
|
+
const copyAsset = ({ source, target }) => {
|
|
12
|
+
if (!fs.existsSync(source)) {
|
|
13
|
+
console.warn(`Skipping missing backend asset: ${source}`);
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
18
|
+
fs.copyFileSync(source, target);
|
|
19
|
+
console.log(`Copied ${source} -> ${target}`);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
for (const asset of assets) {
|
|
23
|
+
copyAsset(asset);
|
|
24
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const sourceDir = path.resolve(__dirname, '..', 'renderer', 'dist');
|
|
5
|
+
const targetDir = path.resolve(__dirname, '..', 'dist', 'renderer');
|
|
6
|
+
const manifestKey = 'index.html';
|
|
7
|
+
|
|
8
|
+
if (!fs.existsSync(sourceDir)) {
|
|
9
|
+
console.warn('Renderer build output not found at', sourceDir);
|
|
10
|
+
process.exit(0);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
fs.rmSync(targetDir, { recursive: true, force: true });
|
|
14
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
15
|
+
|
|
16
|
+
const copyRecursive = (src, dest) => {
|
|
17
|
+
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
18
|
+
for (const entry of entries) {
|
|
19
|
+
const srcPath = path.join(src, entry.name);
|
|
20
|
+
const destPath = path.join(dest, entry.name);
|
|
21
|
+
if (entry.isDirectory()) {
|
|
22
|
+
fs.mkdirSync(destPath, { recursive: true });
|
|
23
|
+
copyRecursive(srcPath, destPath);
|
|
24
|
+
} else {
|
|
25
|
+
fs.copyFileSync(srcPath, destPath);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
copyRecursive(sourceDir, targetDir);
|
|
31
|
+
const rewriteIndexHtml = () => {
|
|
32
|
+
const manifestPath = path.join(sourceDir, '.vite', 'manifest.json');
|
|
33
|
+
if (!fs.existsSync(manifestPath)) {
|
|
34
|
+
console.warn('Renderer manifest not found at', manifestPath);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8'));
|
|
39
|
+
const entry = manifest[manifestKey];
|
|
40
|
+
|
|
41
|
+
if (!entry || !entry.file) {
|
|
42
|
+
throw new Error(`Renderer manifest missing bundle information for ${manifestKey}`);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const toRelative = (filePath) => {
|
|
46
|
+
if (filePath.startsWith('./')) {
|
|
47
|
+
return `./${filePath.slice(2)}`;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (filePath.startsWith('/')) {
|
|
51
|
+
return `./${filePath.slice(1)}`;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return `./${filePath}`;
|
|
55
|
+
};
|
|
56
|
+
const scriptPath = toRelative(entry.file);
|
|
57
|
+
const cssPaths = (entry.css ?? []).map((cssFile) => toRelative(cssFile));
|
|
58
|
+
|
|
59
|
+
const indexPath = path.join(targetDir, 'index.html');
|
|
60
|
+
if (!fs.existsSync(indexPath)) {
|
|
61
|
+
throw new Error('Renderer index.html was not copied to the build output.');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const removeTags = (html, pattern) => html.replace(pattern, '');
|
|
65
|
+
const scriptPattern = /<script\b[^>]*src="[^"]+"[^>]*><\/script>\s*/gi;
|
|
66
|
+
const stylesheetPattern = /<link\b[^>]*rel=["']stylesheet["'][^>]*>\s*/gi;
|
|
67
|
+
|
|
68
|
+
let html = fs.readFileSync(indexPath, 'utf-8');
|
|
69
|
+
html = removeTags(html, scriptPattern);
|
|
70
|
+
html = removeTags(html, stylesheetPattern);
|
|
71
|
+
|
|
72
|
+
const assetTags = [
|
|
73
|
+
...cssPaths.map((href) => ` <link rel="stylesheet" href="${href}">`),
|
|
74
|
+
` <script type="module" src="${scriptPath}"></script>`
|
|
75
|
+
].join('\n');
|
|
76
|
+
|
|
77
|
+
if (!html.includes('</head>')) {
|
|
78
|
+
throw new Error('Renderer index.html is missing a </head> tag.');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
html = html.replace('</head>', `\n${assetTags}\n </head>`);
|
|
82
|
+
fs.writeFileSync(indexPath, html, 'utf-8');
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
rewriteIndexHtml();
|
|
86
|
+
|
|
87
|
+
console.log('Copied renderer bundle to', targetDir);
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const { spawn } = require('child_process');
|
|
2
|
+
const electronPath = require('electron');
|
|
3
|
+
|
|
4
|
+
const sanitizeGtkModules = (envVar) => {
|
|
5
|
+
const modules = process.env[envVar];
|
|
6
|
+
|
|
7
|
+
if (!modules) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const sanitizedModules = modules
|
|
12
|
+
.split(':')
|
|
13
|
+
.map((moduleName) => moduleName.trim())
|
|
14
|
+
.filter((moduleName) => moduleName && moduleName !== 'colorreload-gtk-module');
|
|
15
|
+
|
|
16
|
+
if (sanitizedModules.length === 0) {
|
|
17
|
+
delete process.env[envVar];
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const normalized = sanitizedModules.join(':');
|
|
22
|
+
|
|
23
|
+
if (normalized !== modules) {
|
|
24
|
+
process.env[envVar] = normalized;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
if (process.platform === 'linux') {
|
|
29
|
+
sanitizeGtkModules('GTK_MODULES');
|
|
30
|
+
sanitizeGtkModules('GTK3_MODULES');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const child = spawn(electronPath, ['.'], {
|
|
34
|
+
stdio: 'inherit',
|
|
35
|
+
env: process.env
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
child.on('exit', (code, signal) => {
|
|
39
|
+
if (signal) {
|
|
40
|
+
process.kill(process.pid, signal);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
process.exit(code ?? 0);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
child.on('error', (error) => {
|
|
48
|
+
console.error('Failed to launch Electron:', error);
|
|
49
|
+
process.exit(1);
|
|
50
|
+
});
|
|
51
|
+
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
import crypto from 'crypto';
|
|
5
|
+
import { BackendUnavailableError, KeyringBackend } from './types';
|
|
6
|
+
|
|
7
|
+
const DEFAULT_FILE = process.env.GNOMAN_KEYRING_FILE ?? path.join(os.homedir(), '.gnoman', 'secrets.enc');
|
|
8
|
+
const DIR_MODE = 0o700;
|
|
9
|
+
const FILE_MODE = 0o600;
|
|
10
|
+
const HKDF_INFO = Buffer.from('gnoman-keyring-file', 'utf8');
|
|
11
|
+
const SALT_BYTES = 32;
|
|
12
|
+
const NONCE_BYTES = 12;
|
|
13
|
+
|
|
14
|
+
const serialize = (record: Record<string, string>) => JSON.stringify(record, null, 2);
|
|
15
|
+
|
|
16
|
+
const getPasswordMaterial = () => {
|
|
17
|
+
if (process.env.GNOMAN_KEYRING_PASSWORD) {
|
|
18
|
+
return process.env.GNOMAN_KEYRING_PASSWORD;
|
|
19
|
+
}
|
|
20
|
+
const userInfo = (() => {
|
|
21
|
+
try {
|
|
22
|
+
return os.userInfo().username;
|
|
23
|
+
} catch {
|
|
24
|
+
return 'unknown-user';
|
|
25
|
+
}
|
|
26
|
+
})();
|
|
27
|
+
return `${os.hostname()}|${userInfo}`;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const maskFilesystemError = (error: unknown): BackendUnavailableError => {
|
|
31
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
32
|
+
return new BackendUnavailableError(`File keyring unavailable: ${detail}`, 'file');
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
type PersistedPayload = {
|
|
36
|
+
version: 1;
|
|
37
|
+
salt: string;
|
|
38
|
+
nonce: string;
|
|
39
|
+
authTag: string;
|
|
40
|
+
data: string;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export class FileBackend implements KeyringBackend {
|
|
44
|
+
private readonly filePath: string;
|
|
45
|
+
|
|
46
|
+
private cache = new Map<string, string>();
|
|
47
|
+
|
|
48
|
+
private salt?: Buffer;
|
|
49
|
+
|
|
50
|
+
private initialized = false;
|
|
51
|
+
|
|
52
|
+
constructor(filePath = DEFAULT_FILE) {
|
|
53
|
+
this.filePath = filePath;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
private async ensureDirectory() {
|
|
57
|
+
const dir = path.dirname(this.filePath);
|
|
58
|
+
await fs.mkdir(dir, { recursive: true, mode: DIR_MODE });
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
private deriveKey(salt: Buffer): Buffer {
|
|
62
|
+
try {
|
|
63
|
+
const derived = crypto.hkdfSync('sha256', Buffer.from(getPasswordMaterial()), salt, HKDF_INFO, 32);
|
|
64
|
+
return Buffer.from(derived);
|
|
65
|
+
} catch (error) {
|
|
66
|
+
throw maskFilesystemError(error);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
private async loadFromDisk() {
|
|
71
|
+
try {
|
|
72
|
+
const raw = await fs.readFile(this.filePath, 'utf8');
|
|
73
|
+
const payload = JSON.parse(raw) as PersistedPayload;
|
|
74
|
+
const salt = Buffer.from(payload.salt, 'base64');
|
|
75
|
+
const nonce = Buffer.from(payload.nonce, 'base64');
|
|
76
|
+
const authTag = Buffer.from(payload.authTag, 'base64');
|
|
77
|
+
const encrypted = Buffer.from(payload.data, 'base64');
|
|
78
|
+
const key = this.deriveKey(salt);
|
|
79
|
+
const decipher = crypto.createDecipheriv('aes-256-gcm', key, nonce);
|
|
80
|
+
decipher.setAuthTag(authTag);
|
|
81
|
+
const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);
|
|
82
|
+
const record = JSON.parse(decrypted.toString('utf8')) as Record<string, string>;
|
|
83
|
+
this.cache = new Map(Object.entries(record));
|
|
84
|
+
this.salt = salt;
|
|
85
|
+
} catch (error) {
|
|
86
|
+
const nodeError = error as NodeJS.ErrnoException;
|
|
87
|
+
if (nodeError?.code === 'ENOENT') {
|
|
88
|
+
this.cache = new Map();
|
|
89
|
+
this.salt = undefined;
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
throw maskFilesystemError(error);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
private async persist() {
|
|
97
|
+
try {
|
|
98
|
+
await this.ensureDirectory();
|
|
99
|
+
const salt = this.salt ?? crypto.randomBytes(SALT_BYTES);
|
|
100
|
+
this.salt = salt;
|
|
101
|
+
const key = this.deriveKey(salt);
|
|
102
|
+
const nonce = crypto.randomBytes(NONCE_BYTES);
|
|
103
|
+
const cipher = crypto.createCipheriv('aes-256-gcm', key, nonce);
|
|
104
|
+
const plaintext = Buffer.from(serialize(Object.fromEntries(this.cache.entries())), 'utf8');
|
|
105
|
+
const encrypted = Buffer.concat([cipher.update(plaintext), cipher.final()]);
|
|
106
|
+
const authTag = cipher.getAuthTag();
|
|
107
|
+
const payload: PersistedPayload = {
|
|
108
|
+
version: 1,
|
|
109
|
+
salt: salt.toString('base64'),
|
|
110
|
+
nonce: nonce.toString('base64'),
|
|
111
|
+
authTag: authTag.toString('base64'),
|
|
112
|
+
data: encrypted.toString('base64')
|
|
113
|
+
};
|
|
114
|
+
await fs.writeFile(this.filePath, JSON.stringify(payload), { mode: FILE_MODE });
|
|
115
|
+
} catch (error) {
|
|
116
|
+
throw maskFilesystemError(error);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async initialize(): Promise<void> {
|
|
121
|
+
await this.loadFromDisk();
|
|
122
|
+
this.initialized = true;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
private async ensureReady() {
|
|
126
|
+
if (!this.initialized) {
|
|
127
|
+
await this.initialize();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
async get(key: string): Promise<string | null> {
|
|
132
|
+
await this.ensureReady();
|
|
133
|
+
return this.cache.get(key) ?? null;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
async set(key: string, value: string): Promise<void> {
|
|
137
|
+
await this.ensureReady();
|
|
138
|
+
this.cache.set(key, value);
|
|
139
|
+
await this.persist();
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
async delete(key: string): Promise<void> {
|
|
143
|
+
await this.ensureReady();
|
|
144
|
+
this.cache.delete(key);
|
|
145
|
+
await this.persist();
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
async list(): Promise<Record<string, string>> {
|
|
149
|
+
await this.ensureReady();
|
|
150
|
+
return Object.fromEntries(this.cache.entries());
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export default FileBackend;
|