diff --git a/docker-compose.yml b/docker-compose.yml index fc3497f1..b5fca886 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -45,6 +45,7 @@ services: - KC_KEYMASTER_PORT=4226 - KC_GATEKEEPER_URL=http://gatekeeper:4224 - KC_ENCRYPTED_PASSPHRASE=${KC_ENCRYPTED_PASSPHRASE} + - KC_WALLET_CACHE=${KC_WALLET_CACHE} volumes: - ./data:/app/keymaster/data user: "${KC_UID}:${KC_GID}" @@ -82,6 +83,7 @@ services: image: keychainmdip/satoshi-mediator environment: - KC_GATEKEEPER_URL=http://gatekeeper:4224 + - KC_KEYMASTER_URL=http://keymaster:4226 - KC_NODE_ID=${KC_NODE_ID} - KC_ENCRYPTED_PASSPHRASE=${KC_ENCRYPTED_PASSPHRASE} - KC_SAT_CHAIN=TFTC @@ -104,6 +106,7 @@ services: depends_on: - tftc-node - gatekeeper + - keymaster tbtc-node: image: keychainmdip/bitcoin-core:v28.0 @@ -117,6 +120,7 @@ services: image: keychainmdip/satoshi-mediator environment: - KC_GATEKEEPER_URL=http://gatekeeper:4224 + - KC_KEYMASTER_URL=http://keymaster:4226 - KC_NODE_ID=${KC_NODE_ID} - KC_ENCRYPTED_PASSPHRASE=${KC_ENCRYPTED_PASSPHRASE} - KC_SAT_CHAIN=TBTC @@ -139,6 +143,7 @@ services: depends_on: - tbtc-node - gatekeeper + - keymaster ipfs-mediator: build: diff --git a/packages/keymaster/package.json b/packages/keymaster/package.json index dc556262..0d5d5b7d 100644 --- a/packages/keymaster/package.json +++ b/packages/keymaster/package.json @@ -8,6 +8,7 @@ "./sdk": "./src/keymaster-sdk.js", "./db/json": "./src/db-wallet-json.js", "./db/json/enc": "./src/db-wallet-json-enc.js", + "./db/cache": "./src/db-wallet-cache.js", "./db/web": "./src/db-wallet-web.js" }, "scripts": { diff --git a/packages/keymaster/src/db-wallet-cache.js b/packages/keymaster/src/db-wallet-cache.js new file mode 100644 index 00000000..247fd448 --- /dev/null +++ b/packages/keymaster/src/db-wallet-cache.js @@ -0,0 +1,19 @@ +let baseWallet; +let cachedWallet; + +export function setWallet(wallet) { + baseWallet = wallet; +} + +export function saveWallet(wallet, overwrite = false) { + cachedWallet = wallet; + return baseWallet.saveWallet(wallet, overwrite); +} + +export function loadWallet() { + if (!cachedWallet) { + cachedWallet = baseWallet.loadWallet(); + } + + return cachedWallet; +} diff --git a/packages/keymaster/src/keymaster-sdk.js b/packages/keymaster/src/keymaster-sdk.js index 2de66a52..bbbfa012 100644 --- a/packages/keymaster/src/keymaster-sdk.js +++ b/packages/keymaster/src/keymaster-sdk.js @@ -316,6 +316,16 @@ export async function resolveDID(name) { } } +export async function createAsset(data, options = {}) { + try { + const response = await axios.post(`${URL}/api/v1/assets`, { data, options }); + return response.data.did; + } + catch (error) { + throwError(error); + } +} + export async function resolveAsset(name) { try { const response = await axios.get(`${URL}/api/v1/assets/${name}`); diff --git a/sample.env b/sample.env index 9290e878..d59c42ee 100644 --- a/sample.env +++ b/sample.env @@ -11,8 +11,9 @@ KC_GATEKEEPER_REGISTRIES=hyperswarm,TBTC,TFTC KC_GATEKEEPER_PORT=4224 KC_GATEKEEPER_GC_INTERVAL=60 -# Wallet -# KC_ENCRYPTED_PASSPHRASE= +# Keymaster +KC_ENCRYPTED_PASSPHRASE= +KC_WALLET_CACHE=false # CLI KC_GATEKEEPER_URL=http://localhost:4224 diff --git a/scripts/admin-cli.js b/scripts/admin-cli.js index 5a7459ba..ccc4a7db 100644 --- a/scripts/admin-cli.js +++ b/scripts/admin-cli.js @@ -8,7 +8,7 @@ import * as wallet from '@mdip/keymaster/db/json'; import * as cipher from '@mdip/cipher/node'; dotenv.config(); -const gatekeeperURL = process.env.KC_CLI_GATEKEEPER_URL || 'http://localhost:4224'; +const gatekeeperURL = process.env.KC_GATEKEEPER_URL || 'http://localhost:4224'; program .version('1.0.0') diff --git a/scripts/keychain-cli.js b/scripts/keychain-cli.js index 41e712f9..c7d72b1d 100644 --- a/scripts/keychain-cli.js +++ b/scripts/keychain-cli.js @@ -7,6 +7,7 @@ import * as keymaster_lib from '@mdip/keymaster/lib'; import * as keymaster_sdk from '@mdip/keymaster/sdk'; import * as db_wallet_json from '@mdip/keymaster/db/json'; import * as db_wallet_enc from '@mdip/keymaster/db/json/enc'; +import * as db_wallet_cache from '@mdip/keymaster/db/cache'; import * as cipher from '@mdip/cipher/node'; dotenv.config(); @@ -16,6 +17,7 @@ const gatekeeperURL = process.env.KC_GATEKEEPER_URL || 'http://localhost:4224'; const keymasterURL = process.env.KC_KEYMASTER_URL; const keymasterPassphrase = process.env.KC_ENCRYPTED_PASSPHRASE; +const walletCache = process.env.KC_WALLET_CACHE ? process.env.KC_WALLET_CACHE === 'true' : false; const UPDATE_OK = "OK"; const UPDATE_FAILED = "Update failed"; @@ -1031,6 +1033,11 @@ function getDBWallet() { wallet = db_wallet_enc; } + if (walletCache) { + db_wallet_cache.setWallet(wallet); + wallet = db_wallet_cache; + } + return wallet; } diff --git a/services/keymaster/server/src/config.js b/services/keymaster/server/src/config.js index 50775c9c..ebc6cd9c 100644 --- a/services/keymaster/server/src/config.js +++ b/services/keymaster/server/src/config.js @@ -6,6 +6,7 @@ const config = { gatekeeperURL: process.env.KC_GATEKEEPER_URL || 'http://localhost:4224', keymasterPort: process.env.KC_KEYMASTER_PORT ? parseInt(process.env.KC_KEYMASTER_PORT) : 4226, keymasterPassphrase: process.env.KC_ENCRYPTED_PASSPHRASE, + walletCache: process.env.KC_WALLET_CACHE ? process.env.KC_WALLET_CACHE === 'true' : false, }; export default config; diff --git a/services/keymaster/server/src/keymaster-api.js b/services/keymaster/server/src/keymaster-api.js index b813e9ad..0d1d11be 100644 --- a/services/keymaster/server/src/keymaster-api.js +++ b/services/keymaster/server/src/keymaster-api.js @@ -6,6 +6,7 @@ import * as gatekeeper from '@mdip/gatekeeper/sdk'; import * as keymaster from '@mdip/keymaster/lib'; import * as wallet_json from '@mdip/keymaster/db/json'; import * as wallet_enc from '@mdip/keymaster/db/json/enc'; +import * as wallet_cache from '@mdip/keymaster/db/cache'; import * as cipher from '@mdip/cipher/node'; import config from './config.js'; const app = express(); @@ -574,8 +575,8 @@ v1router.post('/schemas/:id/template/', async (req, res) => { v1router.post('/assets/', async (req, res) => { try { - const { asset, options } = req.body; - const did = await keymaster.createAsset(asset, options); + const { data, options } = req.body; + const did = await keymaster.createAsset(data, options); res.json({ did }); } catch (error) { res.status(500).send({ error: error.toString() }); @@ -698,6 +699,11 @@ app.listen(port, async () => { wallet = wallet_enc; } + if (config.walletCache) { + wallet_cache.setWallet(wallet); + wallet = wallet_cache; + } + await keymaster.start({ gatekeeper, wallet, cipher }); console.log(`keymaster server running on port ${port}`); diff --git a/services/mediators/satoshi/src/config.js b/services/mediators/satoshi/src/config.js index 67366e43..567f8f2f 100644 --- a/services/mediators/satoshi/src/config.js +++ b/services/mediators/satoshi/src/config.js @@ -5,6 +5,7 @@ dotenv.config(); const config = { nodeID: process.env.KC_NODE_ID, gatekeeperURL: process.env.KC_GATEKEEPER_URL || 'http://localhost:4224', + keymasterURL: process.env.KC_KEYMASTER_URL, keymasterPassphrase: process.env.KC_ENCRYPTED_PASSPHRASE, chain: process.env.KC_SAT_CHAIN || 'BTC', network: process.env.KC_SAT_NETWORK || 'mainnet', diff --git a/services/mediators/satoshi/src/satoshi-mediator.js b/services/mediators/satoshi/src/satoshi-mediator.js index f2013092..63710ba1 100644 --- a/services/mediators/satoshi/src/satoshi-mediator.js +++ b/services/mediators/satoshi/src/satoshi-mediator.js @@ -1,7 +1,8 @@ import fs from 'fs'; import BtcClient from 'bitcoin-core'; import * as gatekeeper from '@mdip/gatekeeper/sdk'; -import * as keymaster from '@mdip/keymaster/lib'; +import * as keymaster_lib from '@mdip/keymaster/lib'; +import * as keymaster_sdk from '@mdip/keymaster/sdk'; import * as wallet_json from '@mdip/keymaster/db/json'; import * as wallet_enc from '@mdip/keymaster/db/json/enc'; import * as cipher from '@mdip/cipher/node'; @@ -9,6 +10,7 @@ import config from './config.js'; import { InvalidParameterError } from '@mdip/common/errors'; const REGISTRY = config.chain; +let keymaster; const client = new BtcClient({ network: config.network, @@ -132,8 +134,6 @@ async function importBatch(item) { return; } - console.log(JSON.stringify(item, null, 4)); - const batch = []; for (let i = 0; i < queue.length; i++) { @@ -151,8 +151,6 @@ async function importBatch(item) { }); } - // console.log(JSON.stringify(batch, null, 4)); - try { item.imported = await gatekeeper.importBatch(batch); item.processed = await gatekeeper.processEvents(); @@ -338,9 +336,10 @@ async function anchorBatch() { } const batch = await gatekeeper.getQueue(REGISTRY); - console.log(JSON.stringify(batch, null, 4)); if (batch.length > 0) { + console.log(JSON.stringify(batch, null, 4)); + const did = await keymaster.createAsset({ batch }, { registry: 'hyperswarm', controller: config.nodeID }); const txid = await createOpReturnTxn(did); @@ -367,7 +366,7 @@ async function anchorBatch() { } } else { - console.log('empty batch'); + console.log(`empty ${REGISTRY} queue`); } } @@ -502,15 +501,29 @@ async function main() { chatty: true, }); - let wallet = wallet_json; + if (config.keymasterURL) { + keymaster = keymaster_sdk; + await keymaster.start({ + url: config.keymasterURL, + waitUntilReady: true, + intervalSeconds: 5, + chatty: true, + }); + } + else { + keymaster = keymaster_lib; + + let wallet = wallet_json; + + if (config.keymasterPassphrase) { + wallet_enc.setPassphrase(config.keymasterPassphrase); + wallet_enc.setWallet(wallet); + wallet = wallet_enc; + } - if (config.keymasterPassphrase) { - wallet_enc.setPassphrase(config.keymasterPassphrase); - wallet_enc.setWallet(wallet); - wallet = wallet_enc; + await keymaster.start({ gatekeeper, wallet, cipher }); } - await keymaster.start({ gatekeeper, wallet, cipher }); await waitForNodeID(); if (config.importInterval > 0) {