119 lines
4.7 KiB
JavaScript
119 lines
4.7 KiB
JavaScript
import { useMe } from '@/components/me'
|
|
import useVault from '@/components/vault/use-vault'
|
|
import { useCallback } from 'react'
|
|
import { canReceive, canSend, getStorageKey, saveWalletLocally, siftConfig, upsertWalletVariables } from './common'
|
|
import { useMutation } from '@apollo/client'
|
|
import { generateMutation } from './graphql'
|
|
import { REMOVE_WALLET } from '@/fragments/wallet'
|
|
import { useWalletLogger } from '@/components/wallet-logger'
|
|
import { useWallets } from '.'
|
|
import validateWallet from './validate'
|
|
|
|
export function useWalletConfigurator (wallet) {
|
|
const { me } = useMe()
|
|
const { reloadLocalWallets } = useWallets()
|
|
const { encrypt, isActive } = useVault()
|
|
const { logger } = useWalletLogger(wallet?.def)
|
|
const [upsertWallet] = useMutation(generateMutation(wallet?.def))
|
|
const [removeWallet] = useMutation(REMOVE_WALLET)
|
|
|
|
const _saveToServer = useCallback(async (serverConfig, clientConfig, validateLightning) => {
|
|
const variables = await upsertWalletVariables(
|
|
{ def: wallet.def, config: { ...serverConfig, ...clientConfig } },
|
|
isActive && encrypt,
|
|
{ validateLightning })
|
|
await upsertWallet({ variables })
|
|
}, [encrypt, isActive, wallet.def])
|
|
|
|
const _saveToLocal = useCallback(async (newConfig) => {
|
|
saveWalletLocally(wallet.def.name, newConfig, me?.id)
|
|
reloadLocalWallets()
|
|
}, [me?.id, wallet.def.name, reloadLocalWallets])
|
|
|
|
const _validate = useCallback(async (config, validateLightning = true) => {
|
|
const { serverWithShared, clientWithShared } = siftConfig(wallet.def.fields, config)
|
|
|
|
let clientConfig = clientWithShared
|
|
let serverConfig = serverWithShared
|
|
|
|
if (canSend({ def: wallet.def, config: clientConfig })) {
|
|
let transformedConfig = await validateWallet(wallet.def, clientWithShared, { skipGenerated: true })
|
|
if (transformedConfig) {
|
|
clientConfig = Object.assign(clientConfig, transformedConfig)
|
|
}
|
|
if (wallet.def.testSendPayment && validateLightning) {
|
|
transformedConfig = await wallet.def.testSendPayment(clientConfig, { me, logger })
|
|
if (transformedConfig) {
|
|
clientConfig = Object.assign(clientConfig, transformedConfig)
|
|
}
|
|
// validate again to ensure generated fields are valid
|
|
await validateWallet(wallet.def, clientConfig)
|
|
}
|
|
} else if (canReceive({ def: wallet.def, config: serverConfig })) {
|
|
const transformedConfig = await validateWallet(wallet.def, serverConfig)
|
|
if (transformedConfig) {
|
|
serverConfig = Object.assign(serverConfig, transformedConfig)
|
|
}
|
|
} else if (wallet.def.requiresConfig) {
|
|
throw new Error('configuration must be able to send or receive')
|
|
}
|
|
|
|
return { clientConfig, serverConfig }
|
|
}, [wallet])
|
|
|
|
const _detachFromServer = useCallback(async () => {
|
|
await removeWallet({ variables: { id: wallet.config.id } })
|
|
}, [wallet.config?.id])
|
|
|
|
const _detachFromLocal = useCallback(async () => {
|
|
window.localStorage.removeItem(getStorageKey(wallet.def.name, me?.id))
|
|
reloadLocalWallets()
|
|
}, [me?.id, wallet.def.name, reloadLocalWallets])
|
|
|
|
const save = useCallback(async (newConfig, validateLightning = true) => {
|
|
const { clientConfig, serverConfig } = await _validate(newConfig, validateLightning)
|
|
|
|
// if vault is active, encrypt and send to server regardless of wallet type
|
|
if (isActive) {
|
|
await _saveToServer(serverConfig, clientConfig, validateLightning)
|
|
await _detachFromLocal()
|
|
} else {
|
|
if (canSend({ def: wallet.def, config: clientConfig })) {
|
|
await _saveToLocal(clientConfig)
|
|
} else {
|
|
// if it previously had a client config, remove it
|
|
await _detachFromLocal()
|
|
}
|
|
if (canReceive({ def: wallet.def, config: serverConfig })) {
|
|
await _saveToServer(serverConfig, clientConfig, validateLightning)
|
|
} else if (wallet.config.id) {
|
|
// we previously had a server config
|
|
if (wallet.vaultEntries.length > 0) {
|
|
// we previously had a server config with vault entries, save it
|
|
await _saveToServer(serverConfig, clientConfig, validateLightning)
|
|
} else {
|
|
// we previously had a server config without vault entries, remove it
|
|
await _detachFromServer()
|
|
}
|
|
}
|
|
}
|
|
}, [isActive, wallet.def, _saveToServer, _saveToLocal, _validate,
|
|
_detachFromLocal, _detachFromServer])
|
|
|
|
const detach = useCallback(async () => {
|
|
if (isActive) {
|
|
// if vault is active, detach all wallets from server
|
|
await _detachFromServer()
|
|
} else {
|
|
if (wallet.config.id) {
|
|
await _detachFromServer()
|
|
}
|
|
|
|
// if vault is not active and has a client config, delete from local storage
|
|
await _detachFromLocal()
|
|
}
|
|
}, [isActive, _detachFromServer, _detachFromLocal])
|
|
|
|
return { save, detach }
|
|
}
|