From 4217de95a511936c2ec0910459a4b9354c50c6d1 Mon Sep 17 00:00:00 2001 From: Joel Carter Date: Fri, 20 Sep 2024 16:11:44 -0500 Subject: [PATCH] Use common helper for finding party secrets --- .../getPartySecretSignedValidator.ts | 48 +++++++++++++++++++ .../common/SecretValidators/index.ts | 1 + .../src/Escrow/validators/common/index.ts | 1 + .../Escrow/validators/escrow/buyerSecret.ts | 31 +----------- .../Escrow/validators/escrow/sellerSecret.ts | 29 +---------- 5 files changed, 54 insertions(+), 56 deletions(-) create mode 100644 packages/payload/packages/payments/src/Escrow/validators/common/SecretValidators/getPartySecretSignedValidator.ts create mode 100644 packages/payload/packages/payments/src/Escrow/validators/common/SecretValidators/index.ts diff --git a/packages/payload/packages/payments/src/Escrow/validators/common/SecretValidators/getPartySecretSignedValidator.ts b/packages/payload/packages/payments/src/Escrow/validators/common/SecretValidators/getPartySecretSignedValidator.ts new file mode 100644 index 000000000..2f01cf32c --- /dev/null +++ b/packages/payload/packages/payments/src/Escrow/validators/common/SecretValidators/getPartySecretSignedValidator.ts @@ -0,0 +1,48 @@ +import type { Hash } from '@xylabs/hex' +import { BoundWitnessValidator } from '@xyo-network/boundwitness-validator' +import type { + AsyncPayloadValidationFunction, Payload, WithMeta, +} from '@xyo-network/payload-model' + +import type { + EscrowParty, EscrowPartySecret, EscrowTerms, +} from '../../../Terms/index.ts' +import { findEscrowPartySecretSignatures } from '../../../util/index.ts' + +/** + * Returns the log prefix for the party + * @param party The party + * @returns The log prefix for the party + */ +const getLogPrefix = (party: EscrowParty) => { + const partySecret: EscrowPartySecret = party === 'seller' ? 'sellerSecret' : 'buyerSecret' + return `EscrowTerms.${partySecret}` +} + +/** + * Returns a function that validates the escrow terms for the existence of the party secret signed by the party + * @param dictionary Payload dictionary of the escrow terms + * @returns A function that validates the escrow terms for the existence of the party secret signed by the party + */ +export const getPartySecretSignedValidator = (dictionary: Record>, party: EscrowParty): AsyncPayloadValidationFunction => { + const partySecret: EscrowPartySecret = party === 'seller' ? 'sellerSecret' : 'buyerSecret' + return async (terms: EscrowTerms): Promise => { + // Party-signed party secret BWs + const buyerSecretBWs = findEscrowPartySecretSignatures(terms, dictionary, party) + + // If there are no BWs, return false + if (buyerSecretBWs.length === 0) { + console.log(`${getLogPrefix(party)}: No BoundWitnesses supplied for ${partySecret}: ${terms[partySecret]}`) + return false + } + + // Ensure each BW supplied for the party secret is valid + const errors = await Promise.all(buyerSecretBWs.map(bw => new BoundWitnessValidator(bw).validate())) + const validBoundWitnesses = errors.every(errors => errors.length === 0) + if (!validBoundWitnesses) { + console.log(`${getLogPrefix(party)}: Invalid BoundWitnesses supplied for ${partySecret}: ${terms[partySecret]}`) + return false + } + return true + } +} diff --git a/packages/payload/packages/payments/src/Escrow/validators/common/SecretValidators/index.ts b/packages/payload/packages/payments/src/Escrow/validators/common/SecretValidators/index.ts new file mode 100644 index 000000000..cc2afb66e --- /dev/null +++ b/packages/payload/packages/payments/src/Escrow/validators/common/SecretValidators/index.ts @@ -0,0 +1 @@ +export * from './getPartySecretSignedValidator.ts' diff --git a/packages/payload/packages/payments/src/Escrow/validators/common/index.ts b/packages/payload/packages/payments/src/Escrow/validators/common/index.ts index f59c0fcd1..7b42e818a 100644 --- a/packages/payload/packages/payments/src/Escrow/validators/common/index.ts +++ b/packages/payload/packages/payments/src/Escrow/validators/common/index.ts @@ -1,2 +1,3 @@ export * from './ModuleInstanceValidators/index.ts' +export * from './SecretValidators/index.ts' export * from './TemporalValidators/index.ts' diff --git a/packages/payload/packages/payments/src/Escrow/validators/escrow/buyerSecret.ts b/packages/payload/packages/payments/src/Escrow/validators/escrow/buyerSecret.ts index 0d4157831..25b966892 100644 --- a/packages/payload/packages/payments/src/Escrow/validators/escrow/buyerSecret.ts +++ b/packages/payload/packages/payments/src/Escrow/validators/escrow/buyerSecret.ts @@ -1,12 +1,11 @@ import { assertEx } from '@xylabs/assert' import type { Hash } from '@xylabs/hex' -import { isBoundWitnessWithMeta } from '@xyo-network/boundwitness-model' -import { BoundWitnessValidator } from '@xyo-network/boundwitness-validator' import type { AsyncPayloadValidationFunction, Payload, SyncPayloadValidationFunction, WithMeta, } from '@xyo-network/payload-model' import type { EscrowTerms } from '../../Terms/index.ts' +import { getPartySecretSignedValidator } from '../common/index.ts' const name = 'EscrowTerms.buyerSecret' @@ -46,31 +45,5 @@ export const getBuyerSecretSuppliedValidator = (dictionary: Record>): AsyncPayloadValidationFunction => { - return async (terms: EscrowTerms): Promise => { - const buyer = assertEx(terms.buyer, () => `${name}: No buyer: ${terms.buyer}`) - const buyerSecret = assertEx(terms.buyerSecret, () => `${name}: No buyerSecret: ${terms.buyerSecret}`) - // Buyer-signed buyer secrets - const buyerSecretBWs = Object.values(dictionary) - // Find all BoundWitnesses - .filter(isBoundWitnessWithMeta) - // That contain the buyer secret - .filter(bw => bw.payload_hashes.includes(buyerSecret)) - // That are signed by all the buyers - .filter(bw => buyer.every(buyerAddress => bw.addresses.includes(buyerAddress))) - - // If there are no buyerSecret BWs, return false - if (buyerSecretBWs.length === 0) { - console.log(`${name}: No BoundWitnesses supplied for buyerSecret: ${buyerSecret}`) - return false - } - - // Ensure each BW supplied for the buyerSecret is valid - const errors = await Promise.all(buyerSecretBWs.map(bw => new BoundWitnessValidator(bw).validate())) - const validBoundWitnesses = errors.every(errors => errors.length === 0) - if (!validBoundWitnesses) { - console.log(`${name}: Invalid BoundWitnesses supplied for buyerSecret: ${buyerSecret}`) - return false - } - return true - } + return getPartySecretSignedValidator(dictionary, 'buyer') } diff --git a/packages/payload/packages/payments/src/Escrow/validators/escrow/sellerSecret.ts b/packages/payload/packages/payments/src/Escrow/validators/escrow/sellerSecret.ts index d6dfbaa5c..ad6370ee6 100644 --- a/packages/payload/packages/payments/src/Escrow/validators/escrow/sellerSecret.ts +++ b/packages/payload/packages/payments/src/Escrow/validators/escrow/sellerSecret.ts @@ -7,6 +7,7 @@ import type { } from '@xyo-network/payload-model' import type { EscrowTerms } from '../../Terms/index.ts' +import { getPartySecretSignedValidator } from '../common/index.ts' const name = 'EscrowTerms.sellerSecret' @@ -46,31 +47,5 @@ export const getSellerSecretSuppliedValidator = (dictionary: Record>): AsyncPayloadValidationFunction => { - return async (terms: EscrowTerms): Promise => { - const seller = assertEx(terms.seller, () => `${name}: No seller: ${terms.seller}`) - const sellerSecret = assertEx(terms.sellerSecret, () => `${name}: No sellerSecret: ${terms.sellerSecret}`) - // Seller-signed seller secrets - const sellerSecretBWs = Object.values(dictionary) - // Find all BoundWitnesses - .filter(isBoundWitnessWithMeta) - // That contain the seller secret - .filter(bw => bw.payload_hashes.includes(sellerSecret)) - // That are signed by all the sellers - .filter(bw => seller.every(sellerAddress => bw.addresses.includes(sellerAddress))) - - // If there are no sellerSecret BWs, return false - if (sellerSecretBWs.length === 0) { - console.log(`${name}: No BoundWitnesses supplied for sellerSecret: ${sellerSecret}`) - return false - } - - // Ensure each BW supplied for the sellerSecret is valid - const errors = await Promise.all(sellerSecretBWs.map(bw => new BoundWitnessValidator(bw).validate())) - const validBoundWitnesses = errors.every(errors => errors.length === 0) - if (!validBoundWitnesses) { - console.log(`${name}: Invalid BoundWitnesses supplied for sellerSecret: ${sellerSecret}`) - return false - } - return true - } + return getPartySecretSignedValidator(dictionary, 'seller') }