Skip to content
Payvol

Payvol Observe

See your own money arrive. Nobody else has to.

Observe turns settlements on your own participant into records you can match. No relay, no public index, and no third party watching your payments in order to tell you about them.

Read the adapter contract See all modules

@payvol/coreyour nodeno relay In development

The code exists and runs in this repository. It is not published yet, so there is nothing to install.

Where it actually is

On Canton, the answer is not sitting where you would look for it.

Other networks let you scan a public index for a reference and find your payment. Canton has no such index, by design. And once a transfer is accepted, the identifier is no longer on an active contract at all: it survives in the participant's update history, which is a different thing to read and a different thing to keep.

Read the stream, not the contracts

Before the accept, the identifier travels with the transfer. After it, the contract is gone and only the update history still carries it. An adapter that queries active contracts finds nothing and reports nothing, which looks exactly like a payment that never arrived.

Evidence has a lifetime

Write before the window closes

Update history is pruned. An adapter must write its own record while the window is open, and a record produced after it closed is marked missing evidence rather than unmatched, because those two mean different things to whoever reads them.

Three parties can read it, and no more

We fetched the same settlement as four different parties. The payer, the payee and the instrument registry can read the identifier. A party that took no part reads nothing. The registry is a signatory of the template, so this is structural rather than a choice of ours.

Nobody stands between you and your ledger

No middle

A relay would have to see every payment it forwards. An index would have to be told about yours. On Canton you already have an authorised view of everything you are party to, so the honest design is to read it and add nothing in between.

Read from packages/payvol-conformance/fixtures/visibility-devnet.json at rows.length (four parties fetched, three of them could read the identifier)

How it works

Follow, normalise, keep.

01

Follow

  • Subscribe to the participant's update stream
  • Resume from the last offset you recorded
  • Handle several legs inside one update as separate sightings

02

Normalise

  • Read the identifier out of the settlement metadata
  • Take the effective settlement time, not the time you saw it
  • Qualify the asset by its registry, never by a bare string
  • Record where the response came from, and hash it

03

Keep

  • Persist the record before the history window closes
  • Emit it locally for whatever matches it
  • Flag missing evidence when you started too late

Three ways to find out you were paid

Only one of them keeps the payment yours.

01

Scan an index

the public chain habit

Watch a shared index for a reference that belongs to you. It works where every transaction is public, which is exactly the property Canton was built not to have.

A model this network does not offer

02

Trust a relay

somebody watches for you

A service subscribes on your behalf and notifies you. Convenient, and it means a third party now holds a record of every payment you receive, plus an outage that becomes yours.

Privacy and uptime, both borrowed

03

Read your own view

Payvol Observe

Your participant already receives everything you are party to. The adapter reads that stream, writes its own record, and asks nobody for permission or help.

The payment stays between the parties

Boundaries

What Observe deliberately does not do.

Most of these are things a hosted service would do for you, which is precisely why this module does not.

It does not run a node for you Observe reads a participant you already operate or already have access to. Running Canton infrastructure is a different business and not one we are in.
It does not index the network Only what your participant is party to. There is no crawler, no aggregate view, and no way to ask it about somebody else's payment.
It does not decide what a sighting means Observe records what arrived. Whether that satisfies an invoice is the next module question, and a deliberately separate one.
It does not produce portable proof A record says this participant saw this settlement at this time. It is evidence for you and your auditor, not a certificate a third party can verify on its own.

For operations teams

A stream in, records out, nothing in between.

Point the adapter at your participant, give it somewhere to write, and it produces a record for every settlement you are party to, whether or not it carries an identifier.

See it replay a settlement What matches it

import { recordFromUpdate, windowCovers } from '@payvol/core/draft02'

// one record per sighting, identifier or not
const seen = recordFromUpdate(rawUpdate, {
  observationId, observedAt, metadataKeys,
})

// a sighting that is missing a required field says which,
// rather than being dropped
seen.ok       // false
seen.missing  // ['digest']

// started too late, and the history window had already closed
windowCovers(window, deadline)  // false

Watch a settlement land.

The app replays a captured settlement from DevNet, end to end, with the identifier read back out of it.

Open it in the app See the other modules