Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support generated fields on serverside wallets #1769

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 15 additions & 9 deletions api/resolvers/wallet.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,19 @@ function injectResolvers (resolvers) {
})
}

const validData = await validateWallet(walletDef,
{ ...data, ...settings, vaultEntries: vaultEntries ?? existingVaultEntries },
{ serverSide: true })
if (validData) {
data && Object.keys(validData).filter(key => key in data).forEach(key => { data[key] = validData[key] })
settings && Object.keys(validData).filter(key => key in settings).forEach(key => { settings[key] = validData[key] })
const validate = async ({ data, settings, skipGenerated = false }) => {
const validData = await validateWallet(walletDef,
{ ...data, ...settings, vaultEntries: vaultEntries ?? existingVaultEntries },
{ serverSide: true, skipGenerated })
if (validData) {
data && Object.keys(validData).filter(key => key in data).forEach(key => { data[key] = validData[key] })
settings && Object.keys(validData).filter(key => key in settings).forEach(key => { settings[key] = validData[key] })
}
Copy link
Member Author

@riccardobl riccardobl Dec 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this becomes a function since we need to run it twice:

  • Before testCreateInvoice with skipGenerated=true (because we don't have the generated properties yet)
  • After testCreateInvoice with skipGenerated=false

}

const needsTest = walletDef.testCreateInvoice && validateLightning && canReceive({ def: walletDef, config: data })
await validate({ data, settings, skipGenerated: needsTest })

// wallet in shape of db row
const wallet = {
field: walletDef.walletField,
Expand All @@ -67,7 +72,7 @@ function injectResolvers (resolvers) {
wallet,
walletDef,
testCreateInvoice:
walletDef.testCreateInvoice && validateLightning && canReceive({ def: walletDef, config: data })
needsTest
? (data) => withTimeout(
walletDef.testCreateInvoice(data, {
logger,
Expand All @@ -79,7 +84,7 @@ function injectResolvers (resolvers) {
settings,
data,
vaultEntries
}, { logger, me, models })
}, { logger, me, models, validate })
}
}
console.groupEnd()
Expand Down Expand Up @@ -770,7 +775,7 @@ export const walletLogger = ({ wallet, models }) => {
}

async function upsertWallet (
{ wallet, walletDef, testCreateInvoice }, { settings, data, vaultEntries }, { logger, me, models }) {
{ wallet, walletDef, testCreateInvoice }, { settings, data, vaultEntries }, { logger, me, models, validate }) {
if (!me) {
throw new GqlAuthenticationError()
}
Expand All @@ -779,6 +784,7 @@ async function upsertWallet (
if (testCreateInvoice) {
try {
await testCreateInvoice(data)
await validate({ data, settings, skipGenerated: false })
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

validate again, since now we'll have the generated fields

} catch (err) {
const message = 'failed to create test invoice: ' + (err.message || err.toString?.())
logger.error(message)
Expand Down
2 changes: 1 addition & 1 deletion wallets/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export function useWalletConfigurator (wallet) {
throw err
}
} else if (canReceive({ def: wallet.def, config: serverConfig })) {
const transformedConfig = await validateWallet(wallet.def, serverConfig)
const transformedConfig = await validateWallet(wallet.def, serverConfig, { skipGenerated: true })
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the client needs to skip generated fields for receivers , because they are generated by the testCreateInvoice that runs serverside

if (transformedConfig) {
serverConfig = Object.assign(serverConfig, transformedConfig)
}
Expand Down
2 changes: 1 addition & 1 deletion wallets/validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ function composeWalletSchema (walletDef, serverSide, skipGenerated) {

if (clientOnly && serverSide) {
// For server-side validation, accumulate clientOnly fields as vaultEntries
vaultEntrySchemas[optional ? 'optional' : 'required'].push(vaultEntrySchema(name))
vaultEntrySchemas[(optional || generated) ? 'optional' : 'required'].push(vaultEntrySchema(name))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

every client-side generated field must be optional for server-side validation, otherwise if the user configures only the receiver part of a send&receiver wallet, the validation will fail because the non optional generated client-side fields are not compiled.

} else {
acc[name] = createFieldSchema(name, validate)

Expand Down
Loading