diff --git a/api/resolvers/wallet.js b/api/resolvers/wallet.js index 5621d946b..ff1f1782e 100644 --- a/api/resolvers/wallet.js +++ b/api/resolvers/wallet.js @@ -786,7 +786,7 @@ async function upsertWallet ( } } - const { id, enabled, priority, ...walletData } = data + const { id, enabled, priority, ...recvConfig } = data const txs = [] @@ -806,13 +806,13 @@ async function upsertWallet ( data: { enabled, priority, - // client only wallets has no walletData - ...(Object.keys(walletData).length > 0 + // client only wallets have no receive config and thus don't have their own table + ...(Object.keys(recvConfig).length > 0 ? { [wallet.field]: { - update: { - where: { walletId: Number(id) }, - data: walletData + upsert: { + create: recvConfig, + update: recvConfig } } } @@ -851,8 +851,8 @@ async function upsertWallet ( priority, userId: me.id, type: wallet.type, - // client only wallets has no walletData - ...(Object.keys(walletData).length > 0 ? { [wallet.field]: { create: walletData } } : {}), + // client only wallets have no receive config and thus don't have their own table + ...(Object.keys(recvConfig).length > 0 ? { [wallet.field]: { create: recvConfig } } : {}), ...(vaultEntries ? { vaultEntries: { @@ -876,7 +876,7 @@ async function upsertWallet ( ) } - if (canReceive({ def: walletDef, config: walletData })) { + if (canReceive({ def: walletDef, config: recvConfig })) { txs.push( models.walletLog.createMany({ data: { diff --git a/components/boost-button.js b/components/boost-button.js index 499353d0d..80b578f32 100644 --- a/components/boost-button.js +++ b/components/boost-button.js @@ -26,7 +26,7 @@ export default function Boost ({ item, className, ...props }) { item={item} As={oprops =>
setTimeout(resolve, 2000)) return { allSuccessful, noteId } + } finally { + nostr.close() } } while (failedRelays.length > 0) diff --git a/components/vault/use-vault-configurator.js b/components/vault/use-vault-configurator.js index 7f087a1c0..a3269f5a4 100644 --- a/components/vault/use-vault-configurator.js +++ b/components/vault/use-vault-configurator.js @@ -37,7 +37,7 @@ export function useVaultConfigurator ({ onVaultKeySet, beforeDisconnectVault } = beforeDisconnectVault?.() await remove('key') keyReactiveVar(null) - }, [remove, keyReactiveVar]) + }, [remove, keyReactiveVar, beforeDisconnectVault]) useEffect(() => { if (!me) return @@ -94,6 +94,17 @@ export function useVaultConfigurator ({ onVaultKeySet, beforeDisconnectVault } = await updateVaultKey({ variables: { entries, hash: vaultKey.hash }, + update: (cache, { data }) => { + cache.modify({ + id: `User:${me.id}`, + fields: { + privates: (existing) => ({ + ...existing, + vaultKeyHash: vaultKey.hash + }) + } + }) + }, onError: (error) => { const errorCode = error.graphQLErrors[0]?.extensions?.code if (errorCode === E_VAULT_KEY_EXISTS) { @@ -110,7 +121,7 @@ export function useVaultConfigurator ({ onVaultKeySet, beforeDisconnectVault } = console.error('error setting vault key', e) toaster.danger(e.message) } - }, [getVaultEntries, updateVaultKey, set, get, remove, onVaultKeySet, keyReactiveVar]) + }, [getVaultEntries, updateVaultKey, set, get, remove, onVaultKeySet, keyReactiveVar, me?.id]) return { key, setVaultKey, clearVault, disconnectVault } } diff --git a/docker-compose.yml b/docker-compose.yml index 40406609c..4ad545418 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -268,6 +268,7 @@ services: CLI: "bitcoin-cli" CLI_ARGS: "-chain=regtest -rpcport=${RPC_PORT} -rpcuser=${RPC_USER} -rpcpassword=${RPC_PASS}" ofelia.enabled: "true" + ofelia.group: "payments" ofelia.job-exec.minecron.schedule: "@every 1m" ofelia.job-exec.minecron.command: > bash -c ' @@ -363,6 +364,7 @@ services: CLI: "lncli" CLI_USER: "lnd" ofelia.enabled: "true" + ofelia.group: "payments" ofelia.job-exec.sn_channel_cron.schedule: "@every 1m" ofelia.job-exec.sn_channel_cron.command: > su lnd -c bash -c " @@ -462,6 +464,7 @@ services: CLI: "lncli" CLI_USER: "lnd" ofelia.enabled: "true" + ofelia.group: "payments" ofelia.job-exec.lnd_channel_cron.schedule: "@every 1m" ofelia.job-exec.lnd_channel_cron.command: > su lnd -c bash -c " @@ -551,13 +554,14 @@ services: CLI_USER: "clightning" CLI_ARGS: "--regtest" ofelia.enabled: "true" + ofelia.group: "wallets" ofelia.job-exec.cln_channel_cron.schedule: "@every 1m" ofelia.job-exec.cln_channel_cron.command: > su clightning -c bash -c " + lightning-cli --regtest connect $ROUTER_LND_PUBKEY@router_lnd:9735 if [ $$(lightning-cli --regtest getinfo | jq '.num_active_channels + .num_pending_channels') -ge 3 ]; then exit 0 else - lightning-cli --regtest connect $ROUTER_LND_PUBKEY@router_lnd:9735 lightning-cli --regtest fundchannel id=$ROUTER_LND_PUBKEY feerate=1000perkb \\ amount=1000000000 push_msat=500000000000 minconf=0 fi @@ -610,6 +614,7 @@ services: CLI_USER: "root" CLI_ARGS: "-p pass" ofelia.enabled: "true" + ofelia.group: "wallets" ofelia.job-exec.eclair_channel_cron.schedule: "@every 1m" ofelia.job-exec.eclair_channel_cron.command: > bash -c " @@ -670,6 +675,7 @@ services: labels: CLI: "lncli" CLI_USER: "lnd" + ofelia.group: "payments" cpu_shares: "${CPU_SHARES_MODERATE}" channdler: image: mcuadros/ofelia:latest @@ -680,8 +686,23 @@ services: - bitcoin - sn_lnd - lnd + - router_lnd + restart: unless-stopped + command: daemon --docker -f label=com.docker.compose.project=${COMPOSE_PROJECT_NAME} -f label=ofelia.group=payments + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + cpu_shares: "${CPU_SHARES_LOW}" + walletscron: + image: mcuadros/ofelia:latest + container_name: walletscron + profiles: + - wallets + depends_on: + - router_lnd + - eclair + - cln restart: unless-stopped - command: daemon --docker -f label=com.docker.compose.project=${COMPOSE_PROJECT_NAME} + command: daemon --docker -f label=com.docker.compose.project=${COMPOSE_PROJECT_NAME} -f label=ofelia.group=wallets volumes: - /var/run/docker.sock:/var/run/docker.sock:ro cpu_shares: "${CPU_SHARES_LOW}" diff --git a/lib/nostr.js b/lib/nostr.js index 077e658b1..349d2efe0 100644 --- a/lib/nostr.js +++ b/lib/nostr.js @@ -34,7 +34,7 @@ export default class Nostr { * @type {NDK} */ _ndk = null - + static globalInstance = null constructor ({ privKey, defaultSigner, relays, nip46token, supportNip07 = false, ...ndkOptions } = {}) { this._ndk = new NDK({ explicitRelayUrls: relays, @@ -47,6 +47,16 @@ export default class Nostr { }) } + /** + * @type {NDK} + */ + static get () { + if (!Nostr.globalInstance) { + Nostr.globalInstance = new Nostr() + } + return Nostr.globalInstance + } + /** * @type {NDK} */ @@ -151,6 +161,16 @@ export default class Nostr { return { error } } } + + /** + * Close all relay connections + */ + close () { + const pool = this.ndk.pool + for (const relay of pool.urls()) { + pool.removeRelay(relay) + } + } } export function hexToBech32 (hex, prefix = 'npub') { diff --git a/wallets/nwc/index.js b/wallets/nwc/index.js index 3d0e212cf..1597d4195 100644 --- a/wallets/nwc/index.js +++ b/wallets/nwc/index.js @@ -36,8 +36,8 @@ export const card = { subtitle: 'use Nostr Wallet Connect for payments' } -async function getNwc (nwcUrl, { signal }) { - const ndk = new Nostr().ndk +async function getNwc (nostr, nwcUrl, { signal }) { + const ndk = nostr.ndk const { walletPubkey, secret, relayUrls } = parseNwcUrl(nwcUrl) const nwc = new NDKNwc({ ndk, @@ -66,9 +66,9 @@ async function getNwc (nwcUrl, { signal }) { * @returns - the result of the nwc function */ export async function nwcTryRun (fun, { nwcUrl }, { signal }) { - let nwc + const nostr = new Nostr() try { - nwc = await getNwc(nwcUrl, { signal }) + const nwc = await getNwc(nostr, nwcUrl, { signal }) const { error, result } = await fun(nwc) if (error) throw new Error(error.message || error.code) return result @@ -76,17 +76,7 @@ export async function nwcTryRun (fun, { nwcUrl }, { signal }) { if (e.error) throw new Error(e.error.message || e.error.code) throw e } finally { - if (nwc) close(nwc) - } -} - -/** - * Close all relay connections of the NDKNwc instance - * @param {NDKNwc} nwc - */ -async function close (nwc) { - for (const relay of nwc.relaySet.relays) { - nwc.ndk.pool.removeRelay(relay.url) + nostr.close() } } diff --git a/worker/nostr.js b/worker/nostr.js index fe2201262..cc59c98be 100644 --- a/worker/nostr.js +++ b/worker/nostr.js @@ -45,8 +45,9 @@ export async function nip57 ({ data: { hash }, boss, lnd, models }) { } console.log('zap note', e, relays) - const signer = Nostr.getSigner({ privKey: process.env.NOSTR_PRIVATE_KEY }) - await Nostr.publish(e, { + const nostr = Nostr.get() + const signer = nostr.getSigner({ privKey: process.env.NOSTR_PRIVATE_KEY }) + await nostr.publish(e, { relays, signer, timeout: 1000