diff --git a/demo/src/Witness.ts b/demo/src/Witness.ts index 66b841b102..5f6ce2d3cf 100644 --- a/demo/src/Witness.ts +++ b/demo/src/Witness.ts @@ -3,6 +3,7 @@ import type { Transport } from '@aries-framework/core' import type { ValueTransferConfig } from '@aries-framework/core' import { ValueTransferRole } from '@aries-framework/core' +import { createVerifiableNotes } from '@sicpa-dlab/value-transfer-protocol-ts' import { BaseAgent } from './BaseAgent' import { Output } from './OutputClass' @@ -27,6 +28,7 @@ export class Witness extends BaseAgent { role: ValueTransferRole.Witness, getterTransport: Witness.getterTransport, giverTransport: Witness.giverTransport, + verifiableNotes: createVerifiableNotes(10), } const witness = new Witness('witness', undefined, Witness.transports, valueTransferConfig) await witness.initializeAgent() diff --git a/packages/core/src/modules/value-transfer/services/ValueTransferService.ts b/packages/core/src/modules/value-transfer/services/ValueTransferService.ts index 1f5593c376..47b7991fd5 100644 --- a/packages/core/src/modules/value-transfer/services/ValueTransferService.ts +++ b/packages/core/src/modules/value-transfer/services/ValueTransferService.ts @@ -5,7 +5,7 @@ import type { Transport } from '../../routing/types' import type { ValueTransferStateChangedEvent } from '../ValueTransferEvents' import type { ValueTransferRecord, ValueTransferTags } from '../repository' -import { PartyState, ValueTransfer, Wallet, WitnessState } from '@sicpa-dlab/value-transfer-protocol-ts' +import { PartyState, ValueTransfer, VerifiableNote, Wallet, WitnessState } from '@sicpa-dlab/value-transfer-protocol-ts' import { firstValueFrom, ReplaySubject } from 'rxjs' import { first, map, timeout } from 'rxjs/operators' import { Lifecycle, scoped } from 'tsyringe' @@ -77,26 +77,40 @@ export class ValueTransferService { const publicDid = await this.didService.findPublicDid() if (config.role === ValueTransferRole.Witness) { - const state = await this.witnessStateRepository.findSingleByQuery({}) - if (state) return + const record = await this.witnessStateRepository.findSingleByQuery({}) - if (!publicDid) { - throw new AriesFrameworkError( - 'Witness public DID not found. Please set `publicDidSeed` field in the agent config.' - ) - } + if (!record) { + if (!publicDid) { + throw new AriesFrameworkError( + 'Witness public DID not found. Please set `publicDidSeed` field in the agent config.' + ) + } - const record = new WitnessStateRecord({ - publicDid: publicDid.id, - witnessState: new WitnessState(), - }) - await this.witnessStateRepository.save(record) - return - } - if (config.role === ValueTransferRole.Getter || ValueTransferRole.Giver) { - const state = await this.valueTransferStateRepository.findSingleByQuery({}) + const partyStateHashes = ValueTransferService.calculateInitialPartyStateHashes(new Set(config.verifiableNotes)) + + const record = new WitnessStateRecord({ + publicDid: publicDid.id, + witnessState: new WitnessState(partyStateHashes), + }) + + await this.witnessStateRepository.save(record) + } else { + if (!record.witnessState.partyStateHashes.size) { + const partyStateHashes = ValueTransferService.calculateInitialPartyStateHashes( + new Set(config.verifiableNotes) + ) + + for (const hash of partyStateHashes) { + record.witnessState.partyStateHashes.add(hash) + } + + await this.witnessStateRepository.update(record) + } + } + } else if (config.role === ValueTransferRole.Giver) { + const record = await this.valueTransferStateRepository.findSingleByQuery({}) - if (!state) { + if (!record) { let wallet = new Wallet() if (config.verifiableNotes?.length) { @@ -108,16 +122,28 @@ export class ValueTransferService { publicDid: publicDid?.id, partyState: new PartyState(new Uint8Array(), wallet), }) + await this.valueTransferStateRepository.save(record) } else { if (config.verifiableNotes?.length) { - if (!state.partyState.wallet.amount()) { - state.partyState.wallet.receiveNotes(new Set(config.verifiableNotes)) + if (!record.partyState.wallet.amount()) { + record.partyState.wallet.receiveNotes(new Set(config.verifiableNotes)) } - await this.valueTransferStateRepository.update(state) + await this.valueTransferStateRepository.update(record) } } + } else if (config.role === ValueTransferRole.Getter) { + const record = await this.valueTransferStateRepository.findSingleByQuery({}) + + if (!record) { + const record = new ValueTransferStateRecord({ + publicDid: publicDid?.id, + partyState: new PartyState(new Uint8Array(), new Wallet()), + }) + + await this.valueTransferStateRepository.save(record) + } } } @@ -293,4 +319,17 @@ export class ValueTransferService { payload: { record: record, previousState }, }) } + + private static calculateInitialPartyStateHashes(verifiableNotes: Set) { + const partyStateHashes = new Set() + + let giverWallet = new Wallet() + giverWallet = giverWallet.receiveNotes(new Set(verifiableNotes))[1] + partyStateHashes.add(giverWallet.rootHash()) + + let getterWallet = new Wallet() + partyStateHashes.add(getterWallet.rootHash()) + + return partyStateHashes + } }