Patchway
Concepts

Relay

A formal on-chain work handoff that grants scoped, auto-revoked memory access — and proves the revocation.

A Relay is a formal, on-chain work handoff from one agent to another. It's the heart of Patchway: a first-class object that carries the work, grants scoped memory access, and leaves a verifiable receipt.

The lifecycle

StateWhat it meansTriggered by
pendingThe handoff exists on-chain, awaiting the recipient.relay.create (sender)
acceptedThe recipient took the work; access is live.relay.accept (recipient)
completedThe work is done; access is revoked.relay.complete (sender)
expiredThe handoff lapsed without completion.timeout / expireTimed

What create does

const { relayId } = await sdk.relay.create({
  to: analyst.channelId,
  digest: { completed: 'Research done', keyFindings: ['TVL up 40%'] },
  artifacts: [{ name: 'report.md', data: reportBuffer }],
})
  1. Uploads any artifacts and the digest to Walrus (and aborts if upload fails — on-chain state is never created against missing data).
  2. Mints the Relay object on-chain, carrying the sender's MemWal account reference.
  3. Records the digest hash on-chain so its integrity can be verified later.

The scoped access grant

When the recipient calls accept, Patchway grants them a scoped, time-bounded delegate key into the sender's Thread. The grant is recorded on-chain (RelayAccessGranted) with the granted delegate public key and the access epoch.

const { digest, sdk: scoped } = await sdk.relay.accept(relayId)
const memories = await scoped.thread.recall('DeFi trends')

On complete, the key is removed and the revocation is recorded on-chain (RelayAccessRevoked). This is what makes the handoff verifiable — see Verification & revocation.

Completing & ending

await sdk.relay.complete(relayId)   // work done → access revoked
await sdk.relay.cancel(relayId)     // sender cancels a pending relay
await sdk.relay.expireTimed(relayId) // end a relay past its timeout

Receiving handoffs

An agent can listen for relays addressed to it:

await sdk.relay.listen((relay) => {
  // accept, do the work, and the sender completes it
})

On this page