Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
30 changes: 30 additions & 0 deletions .env.demo
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,33 @@ INDICIO_TEST_GENESIS='{"reqSignature":{},"txn":{"data":{"data":{"alias":"OpsNode
{"reqSignature":{},"txn":{"data":{"data":{"alias":"idlab-node01","blskey":"2fjJVi33U1tCTjW77cJaf1NLz7EzWkVNzR9BEQpVVK64MJpRKNUzt6k7Td2U8yqU5hGyAFH5N7ZymSB55TnpC3rJYLVTcGXZeXpmrQx3mwnXNyfTDnxfTpdQ1KMoFeZoDPZ8acfaH8GWeW2jL1qREE52tetBf4tXTeshmWzGkEN7r4y","blskey_pop":"RSjiM6dYUmN2rv2ca7dUCmEKrivq12rhxhXUKHdmSwUxbCmcijsgoERjYG7MqxhKLjSAJ5715K23fVEc6uK1kTenKmYCcCts8MLMAQG8Upb22nfgHJ3py8RwRoACeAjFF3myAMNRJJPhUdv96drJdwkGRv7f6JjvoB5KWVQYTNgheP","client_ip":"205.159.92.17","client_port":"9702","node_ip":"205.159.92.16","node_port":"9701","services":["VALIDATOR"]},"dest":"8czYgwmLDazVrBHuo53Tyx7Tw8ZhvnoC2BfhQGir4r8F"},"metadata":{"from":"PN8wFxLKjdkwyxoEEXwyz2"},"type":"0"},"txnMetadata":{"seqNo":5,"txnId":"9237eca7d2a203f6e1779f63064d2f22cf28e1bcd4e6fe5d791b15e82969acdc"},"ver":"1"}
{"reqSignature":{},"txn":{"data":{"data":{"alias":"lorica-identity-node1","blskey":"wUh24sVCQ8PHDgSb343g2eLxjD5vwxsrETfuV2sbwMNnYon9nhbaK5jcWTekvXtyiwxHxuiCCoZwKS97MQEAeC2oLbbMeKjYm212QwSnm7aKLEqTStXht35VqZvZLT7Q3mPQRYLjMGixdn4ocNHrBTMwPUQYycEqwaHWgE1ncDueXY","blskey_pop":"R2sMwF7UW6AaD4ALa1uB1YVPuP6JsdJ7LsUoViM9oySFqFt34C1x1tdHDysS9wwruzaaEFui6xNPqJ8eu3UBqcFKkoWhdsMqCALwe63ytxPwvtLtCffJLhHAcgrPC7DorXYdqhdG2cevdqc5oqFEAaKoFDBf12p5SsbbM4PYWCmVCb","client_ip":"35.225.220.151","client_port":"9702","node_ip":"35.224.26.110","node_port":"9701","services":["VALIDATOR"]},"dest":"k74ZsZuUaJEcB8RRxMwkCwdE5g1r9yzA3nx41qvYqYf"},"metadata":{"from":"Ex6hzsJFYzNJ7kzbfncNeU"},"type":"0"},"txnMetadata":{"seqNo":6,"txnId":"6880673ce4ae4a2352f103d2a6ae20469dd070f2027283a1da5e62a64a59d688"},"ver":"1"}
{"reqSignature":{},"txn":{"data":{"data":{"alias":"cysecure-itn","blskey":"GdCvMLkkBYevRFi93b6qaj9G2u1W6Vnbg8QhRD1chhrWR8vRE8x9x7KXVeUBPFf6yW5qq2JCfA2frc8SGni2RwjtTagezfwAwnorLhVJqS5ZxTi4pgcw6smebnt4zWVhTkh6ugDHEypHwNQBcw5WhBZcEJKgNbyVLnHok9ob6cfr3u","blskey_pop":"RbH9mY7M5p3UB3oj4sT1skYwMkxjoUnja8eTYfcm83VcNbxC9zR9pCiRhk4q1dJT3wkDBPGNKnk2p83vaJYLcgMuJtzoWoJAWAxjb3Mcq8Agf6cgQpBuzBq2uCzFPuQCAhDS4Kv9iwA6FsRnfvoeFTs1hhgSJVxQzDWMVTVAD9uCqu","client_ip":"35.169.19.171","client_port":"9702","node_ip":"54.225.56.21","node_port":"9701","services":["VALIDATOR"]},"dest":"4ETBDmHzx8iDQB6Xygmo9nNXtMgq9f6hxGArNhQ6Hh3u"},"metadata":{"from":"uSXXXEdBicPHMMhr3ddNF"},"type":"0"},"txnMetadata":{"seqNo":7,"txnId":"3c21718b07806b2f193b35953dda5b68b288efd551dce4467ce890703d5ba549"},"ver":"1"}'

# ─── Data Purge — Record Deletion ────────────────────────────────────────────
# Automatically deletes credential/proof/session records after a configurable TTL.
# Two independent flows — enable one or both:
# Flow A (NATS): schedules deletion at offer-creation time via NATS JetStream
# Flow B (Cron): periodically scans DB and deletes records older than TTL

PURGE_ENABLED=false
PURGE_WEBHOOK_ENABLED=false

# ── Flow A: NATS (event-driven, requires NATS connection below) ───────────────
PURGE_NATS_ENABLED=false
PURGE_NATS_TTL_SECONDS=2592000

# ── Flow B: Cron (DB scan, no NATS required) ──────────────────────────────────
PURGE_CRON_ENABLED=false
PURGE_CRON_TTL_SECONDS=2592000
PURGE_CRON_SCHEDULE=0 * * * *

# ── Optional: per-type record filtering (default: all 4 types) ────────────────
# PURGE_DIDCOMM_CREDENTIAL=true
# PURGE_DIDCOMM_PROOF=true
# PURGE_OID4VC_ISSUANCE=true
# PURGE_OID4VC_VERIFICATION=true

# ─── NATS Connection (required for Flow A) ────────────────────────────────────
NATS_SERVERS=nats://localhost:4223
# Auth type — one of: nkey | creds | usernamePassword | none
NATS_AUTH_TYPE=nkey
NATS_NKEY_SEED=
32 changes: 32 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,35 @@ INDICIO_TEST_GENESIS=`{"reqSignature":{},"txn":{"data":{"data":{"alias":"OpsNode
{"reqSignature":{},"txn":{"data":{"data":{"alias":"idlab-node01","blskey":"2fjJVi33U1tCTjW77cJaf1NLz7EzWkVNzR9BEQpVVK64MJpRKNUzt6k7Td2U8yqU5hGyAFH5N7ZymSB55TnpC3rJYLVTcGXZeXpmrQx3mwnXNyfTDnxfTpdQ1KMoFeZoDPZ8acfaH8GWeW2jL1qREE52tetBf4tXTeshmWzGkEN7r4y","blskey_pop":"RSjiM6dYUmN2rv2ca7dUCmEKrivq12rhxhXUKHdmSwUxbCmcijsgoERjYG7MqxhKLjSAJ5715K23fVEc6uK1kTenKmYCcCts8MLMAQG8Upb22nfgHJ3py8RwRoACeAjFF3myAMNRJJPhUdv96drJdwkGRv7f6JjvoB5KWVQYTNgheP","client_ip":"205.159.92.17","client_port":"9702","node_ip":"205.159.92.16","node_port":"9701","services":["VALIDATOR"]},"dest":"8czYgwmLDazVrBHuo53Tyx7Tw8ZhvnoC2BfhQGir4r8F"},"metadata":{"from":"PN8wFxLKjdkwyxoEEXwyz2"},"type":"0"},"txnMetadata":{"seqNo":5,"txnId":"9237eca7d2a203f6e1779f63064d2f22cf28e1bcd4e6fe5d791b15e82969acdc"},"ver":"1"}
{"reqSignature":{},"txn":{"data":{"data":{"alias":"lorica-identity-node1","blskey":"wUh24sVCQ8PHDgSb343g2eLxjD5vwxsrETfuV2sbwMNnYon9nhbaK5jcWTekvXtyiwxHxuiCCoZwKS97MQEAeC2oLbbMeKjYm212QwSnm7aKLEqTStXht35VqZvZLT7Q3mPQRYLjMGixdn4ocNHrBTMwPUQYycEqwaHWgE1ncDueXY","blskey_pop":"R2sMwF7UW6AaD4ALa1uB1YVPuP6JsdJ7LsUoViM9oySFqFt34C1x1tdHDysS9wwruzaaEFui6xNPqJ8eu3UBqcFKkoWhdsMqCALwe63ytxPwvtLtCffJLhHAcgrPC7DorXYdqhdG2cevdqc5oqFEAaKoFDBf12p5SsbbM4PYWCmVCb","client_ip":"35.225.220.151","client_port":"9702","node_ip":"35.224.26.110","node_port":"9701","services":["VALIDATOR"]},"dest":"k74ZsZuUaJEcB8RRxMwkCwdE5g1r9yzA3nx41qvYqYf"},"metadata":{"from":"Ex6hzsJFYzNJ7kzbfncNeU"},"type":"0"},"txnMetadata":{"seqNo":6,"txnId":"6880673ce4ae4a2352f103d2a6ae20469dd070f2027283a1da5e62a64a59d688"},"ver":"1"}
{"reqSignature":{},"txn":{"data":{"data":{"alias":"cysecure-itn","blskey":"GdCvMLkkBYevRFi93b6qaj9G2u1W6Vnbg8QhRD1chhrWR8vRE8x9x7KXVeUBPFf6yW5qq2JCfA2frc8SGni2RwjtTagezfwAwnorLhVJqS5ZxTi4pgcw6smebnt4zWVhTkh6ugDHEypHwNQBcw5WhBZcEJKgNbyVLnHok9ob6cfr3u","blskey_pop":"RbH9mY7M5p3UB3oj4sT1skYwMkxjoUnja8eTYfcm83VcNbxC9zR9pCiRhk4q1dJT3wkDBPGNKnk2p83vaJYLcgMuJtzoWoJAWAxjb3Mcq8Agf6cgQpBuzBq2uCzFPuQCAhDS4Kv9iwA6FsRnfvoeFTs1hhgSJVxQzDWMVTVAD9uCqu","client_ip":"35.169.19.171","client_port":"9702","node_ip":"54.225.56.21","node_port":"9701","services":["VALIDATOR"]},"dest":"4ETBDmHzx8iDQB6Xygmo9nNXtMgq9f6hxGArNhQ6Hh3u"},"metadata":{"from":"uSXXXEdBicPHMMhr3ddNF"},"type":"0"},"txnMetadata":{"seqNo":7,"txnId":"3c21718b07806b2f193b35953dda5b68b288efd551dce4467ce890703d5ba549"},"ver":"1"}`
# ─── Data Purge ───────────────────────────────────────────────────────────────
# Automatically deletes records after a configurable TTL.
# Two independent flows — enable one or both:
# Flow A (NATS): schedules deletion at offer-creation time via NATS JetStream
# Flow B (Cron): periodically scans DB and deletes records older than TTL

# Master switch — set to true to activate purge system
PURGE_ENABLED=
# Set to false to skip webhook calls after deletion (default: true)
PURGE_WEBHOOK_ENABLED=

# ── Flow A: NATS (requires NATS_SERVERS below) ────────────────────────────────
PURGE_NATS_ENABLED=
PURGE_NATS_TTL_SECONDS= # seconds from offer creation to deletion (e.g. 2592000 = 30 days)

# ── Flow B: Cron (DB scan, no NATS required) ──────────────────────────────────
PURGE_CRON_ENABLED=
PURGE_CRON_TTL_SECONDS= # records older than this (createdAt) are deleted (e.g. 2592000 = 30 days)
PURGE_CRON_SCHEDULE= # cron expression for scan frequency (e.g. 0 * * * * = hourly)

# ── Optional: per-type record filtering ───────────────────────────────────────
# Uncomment to restrict purge to specific record types (default: all types enabled)
# PURGE_DIDCOMM_CREDENTIAL=true
# PURGE_DIDCOMM_PROOF=true
# PURGE_OID4VC_ISSUANCE=true
# PURGE_OID4VC_VERIFICATION=true

# ─── NATS Connection (required for Flow A) ────────────────────────────────────
NATS_SERVERS=
# Auth type — one of: nkey | creds | usernamePassword | none
NATS_AUTH_TYPE=
NATS_NKEY_SEED= # required when NATS_AUTH_TYPE=nkey # required when NATS_AUTH_TYPE=usernamePassword
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@
"express-rate-limit": "^7.5.0",
"joi": "^17.13.3",
"jsonwebtoken": "^9.0.2",
"nats": "^2.29.3",
"node-cron": "^4.2.1",
"node-fetch": "2",
"patch-package": "^8.0.0",
"reflect-metadata": "^0.2.2",
Expand All @@ -97,6 +99,7 @@
"@types/jsonwebtoken": "^9.0.9",
"@types/multer": "^1.4.12",
"@types/node": "^20.17.0",
"@types/node-cron": "^3.0.11",
"@types/ref-array-di": "^1.2.8",
"@types/ref-struct-di": "^1.1.12",
"@types/supertest": "^6.0.3",
Expand Down
31 changes: 31 additions & 0 deletions src/cliAgent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@

import { IndicioAcceptanceMechanism, IndicioTransactionAuthorAgreement, Network, NetworkName } from './enums'
import { setupServer } from './server'
import { buildPurgeConfig } from './purge/PurgeTypes'
import { validatePurgeConfig } from './purge/PurgeConfigValidator'
import { initPurgeSchedulers, stopPurgeSchedulers, getNatsPurgeScheduler, getCronPurgeScheduler } from './purge/PurgeSchedulerFactory'
import { generateSecretKey } from './utils/helpers'
import { TsLogger } from './utils/logger'
import {
Expand Down Expand Up @@ -361,7 +364,8 @@
// return secretKey
// }


export async function runRestAgent(restConfig: AriesRestConfig) {

Check failure on line 368 in src/cliAgent.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this function to reduce its Cognitive Complexity from 18 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=credebl_afj-controller&issues=AZ2w4X0BMEXeMQGEoSGF&open=AZ2w4X0BMEXeMQGEoSGF&pullRequest=363
const {
endpoints,
schemaFileServerURL,
Expand Down Expand Up @@ -556,7 +560,34 @@

logger.info(`*** API Key: ${apiKey}`)

// Start purge schedulers if enabled (NATS and Cron are independent)
const purgeConfig = buildPurgeConfig()
if (purgeConfig) {
await validatePurgeConfig(purgeConfig)
initPurgeSchedulers(purgeConfig.natsConfig.enabled, purgeConfig.cronConfig.enabled)

const purgeWebhookUrl = purgeConfig.webhookEnabled ? webhookUrl : undefined

if (purgeConfig.natsConfig.enabled) {
await getNatsPurgeScheduler()!.start(agent, purgeConfig, purgeWebhookUrl)
}

if (purgeConfig.cronConfig.enabled) {
await getCronPurgeScheduler()!.start(agent, purgeConfig, purgeWebhookUrl)
}
}

app.listen(adminPort, () => {
logger.info(`Successfully started server on port ${adminPort}`)
})

// Graceful shutdown
const shutdown = async () => {
agent.config.logger.info('[Shutdown] Stopping services...')
await stopPurgeSchedulers()
process.exit(0)
}

process.on('SIGTERM', shutdown)
process.on('SIGINT', shutdown)
}
5 changes: 5 additions & 0 deletions src/controllers/didcomm/credentials/CredentialController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import { injectable } from 'tsyringe'

import { SCOPES } from '../../../enums'
import ErrorHandlingService from '../../../errorHandlingService'
import { SchedulePurge } from '../../../purge/decorators/SchedulePurge'
import { PurgeRecordType } from '../../../purge/PurgeTypes'
import { AgentType } from '../../../types'
import { CredentialExchangeRecordExample, RecordId } from '../../examples'
import {
Expand Down Expand Up @@ -163,6 +165,7 @@ export class CredentialController extends Controller {
*/
@Example<DidCommCredentialExchangeRecordProps>(CredentialExchangeRecordExample)
@Post('/create-offer')
@SchedulePurge(PurgeRecordType.DIDCOMM_CREDENTIAL, (r) => (r as any)?.id)
public async createOffer(@Request() request: Req, @Body() createOfferOptions: CreateOfferOptions) {
try {
const offer = await request.agent.modules.didcomm.credentials.offerCredential(createOfferOptions)
Expand All @@ -173,6 +176,7 @@ export class CredentialController extends Controller {
}

@Post('/create-offer-oob')
@SchedulePurge(PurgeRecordType.DIDCOMM_CREDENTIAL, (r) => (r as any)?.credentialExchangeRecordId)
public async createOfferOob(@Request() request: Req, @Body() outOfBandOption: CreateOfferOobOptions) {
try {
let invitationDid: string | undefined
Expand Down Expand Up @@ -230,6 +234,7 @@ export class CredentialController extends Controller {
}),
outOfBandRecord: outOfBandRecord.toJSON(),
outOfBandRecordId: outOfBandRecord.id,
credentialExchangeRecordId: offerOob.credentialExchangeRecord.id,
credentialRequestThId: offerOob.credentialExchangeRecord.threadId,
invitationDid,
}
Expand Down
5 changes: 5 additions & 0 deletions src/controllers/didcomm/proofs/ProofController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import { injectable } from 'tsyringe'

import { SCOPES } from '../../../enums'
import ErrorHandlingService from '../../../errorHandlingService'
import { SchedulePurge } from '../../../purge/decorators/SchedulePurge'
import { PurgeRecordType } from '../../../purge/PurgeTypes'
import { ProofRecordExample, RecordId } from '../../examples'
import {
AcceptProofProposal,
Expand Down Expand Up @@ -118,6 +120,7 @@ export class ProofController extends Controller {
*/
@Post('/request-proof')
@Example<DidCommProofExchangeRecordProps>(ProofRecordExample)
@SchedulePurge(PurgeRecordType.DIDCOMM_PROOF, (r) => (r as any)?.id)
public async requestProof(@Request() request: Req, @Body() requestProofOptions: RequestProofOptions) {
try {
const requestProofPayload = {
Expand All @@ -143,6 +146,7 @@ export class ProofController extends Controller {
*/
@Post('create-request-oob')
@Example<DidCommProofExchangeRecordProps>(ProofRecordExample)
@SchedulePurge(PurgeRecordType.DIDCOMM_PROOF, (r) => (r as any)?.proofRecordId)
public async createRequest(@Request() request: Req, @Body() createRequestOptions: CreateProofRequestOobOptions) {
try {
let routing: DidCommRouting
Expand Down Expand Up @@ -200,6 +204,7 @@ export class ProofController extends Controller {
}),
outOfBandRecord: outOfBandRecord.toJSON(),
invitationDid,
proofRecordId: proof.proofRecord.id,
proofRecordThId: proof.proofRecord.threadId,
proofMessageId: proof.message.thread?.threadId || proof.message.threadId || proof.message.id,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { injectable } from 'tsyringe'
import { SCOPES } from '../../../enums'
// eslint-disable-next-line import/order
import ErrorHandlingService from '../../../errorHandlingService'
import { SchedulePurge } from '../../../purge/decorators/SchedulePurge'
import { PurgeRecordType } from '../../../purge/PurgeTypes'

// import { AgentWithRootOrTenant } from '../../types/agent'
import { OpenId4VcIssuanceSessionsCreateOffer } from '../types/issuer.types'
Expand All @@ -26,6 +28,7 @@ export class IssuanceSessionsController extends Controller {
* Creates a credential offer with the specified credential configurations and authorization type.
*/
@Post('/create-credential-offer')
@SchedulePurge(PurgeRecordType.OID4VC_ISSUANCE, (r) => (r as any)?.issuanceSession?.id)
public async createCredentialOffer(@Request() request: Req, @Body() options: OpenId4VcIssuanceSessionsCreateOffer) {
try {
return await issuanceSessionService.createCredentialOffer(options, request)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { injectable } from 'tsyringe'

import { SCOPES } from '../../../enums'
import ErrorHandlingService from '../../../errorHandlingService'
import { SchedulePurge } from '../../../purge/decorators/SchedulePurge'
import { PurgeRecordType } from '../../../purge/PurgeTypes'
import { CreateAuthorizationRequest, OpenId4VCDCQLVerificationSessionRecord } from '../types/verifier.types'

import { VerificationSessionsService } from './verification-sessions.service'
Expand All @@ -21,6 +23,7 @@ export class VerificationSessionsController extends Controller {
* Create an authorization request, acting as a Relying Party (RP)
*/
@Post('/create-presentation-request')
@SchedulePurge(PurgeRecordType.OID4VC_VERIFICATION, (r) => (r as any)?.verificationSession?.id)
public async createProofRequest(
@Request() request: Req,
@Body() createAuthorizationRequest: CreateAuthorizationRequest,
Expand Down
46 changes: 46 additions & 0 deletions src/purge/PurgeConfigValidator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { connect } from 'nats'

import { buildNatsAuthenticator } from '../utils/NatsAuthenticator'
import type { NatsConfig, PurgeConfig } from './PurgeTypes'

export async function validatePurgeConfig(config: PurgeConfig): Promise<void> {
const { natsConfig, cronConfig } = config

if (!natsConfig.enabled && !cronConfig.enabled) {
throw new Error(
'[Purge] PURGE_ENABLED=true but neither PURGE_NATS_ENABLED nor PURGE_CRON_ENABLED is set to true. ' +
'Enable at least one mode.',
)
}

if (natsConfig.enabled) {
await verifyNatsJetStream(natsConfig.nats)
}
}

async function verifyNatsJetStream(nats: NatsConfig): Promise<void> {
let nc: Awaited<ReturnType<typeof connect>> | null = null

try {
nc = await connect({
servers: nats.servers,
...buildNatsAuthenticator(nats),
timeout: 5000,
maxReconnectAttempts: 0,
})
} catch (err: any) {
throw new Error(
`[Purge] PURGE_NATS_ENABLED=true but cannot connect to NATS at ${nats.servers.join(', ')}: ${err?.message}`,
)
}

try {
await nc.jetstreamManager()
} catch (err: any) {
throw new Error(
`[Purge] Connected to NATS but JetStream is not enabled. Start NATS with the -js flag. Error: ${err?.message}`,
)
} finally {
await nc.close()
}
}
46 changes: 46 additions & 0 deletions src/purge/PurgeConstants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { PurgeRecordType } from './PurgeTypes'

export const PURGE_STREAM = 'PURGE'

// Schedule and execution subjects must be in the same stream for Nats-Schedule-Target to work
export const PURGE_SCHEDULER_SUBJECTS: Record<PurgeRecordType, string> = {
[PurgeRecordType.DIDCOMM_CREDENTIAL]: 'purge.schedule.didcomm.credential',
[PurgeRecordType.DIDCOMM_PROOF]: 'purge.schedule.didcomm.proof',
[PurgeRecordType.OID4VC_ISSUANCE]: 'purge.schedule.oid4vc.issuance',
[PurgeRecordType.OID4VC_VERIFICATION]: 'purge.schedule.oid4vc.verification',
}

export const PURGE_EXECUTION_SUBJECTS: Record<PurgeRecordType, string> = {
[PurgeRecordType.DIDCOMM_CREDENTIAL]: 'purge.execute.didcomm.credential',
[PurgeRecordType.DIDCOMM_PROOF]: 'purge.execute.didcomm.proof',
[PurgeRecordType.OID4VC_ISSUANCE]: 'purge.execute.oid4vc.issuance',
[PurgeRecordType.OID4VC_VERIFICATION]: 'purge.execute.oid4vc.verification',
}

export const PURGE_CONSUMER_NAMES: Record<PurgeRecordType, string> = {
[PurgeRecordType.DIDCOMM_CREDENTIAL]: 'purge-worker-didcomm-credential',
[PurgeRecordType.DIDCOMM_PROOF]: 'purge-worker-didcomm-proof',
[PurgeRecordType.OID4VC_ISSUANCE]: 'purge-worker-oid4vc-issuance',
[PurgeRecordType.OID4VC_VERIFICATION]: 'purge-worker-oid4vc-verification',
}

// Added to ttlSeconds when computing stream max_age — covers worker processing time after fire
export const PURGE_STREAM_BUFFER_NS = 7 * 24 * 60 * 60 * 1_000_000_000

export const PURGE_CONSUMER_ACK_WAIT_NS = 30 * 1_000_000_000

export const PURGE_CONSUMER_MAX_DELIVER = 3

export const PURGE_CONSUMER_BACKOFF_NS = [
5_000_000_000, // 5s
30_000_000_000, // 30s
]

export const PURGE_WEBHOOK_PATHS: Record<PurgeRecordType, string> = {
[PurgeRecordType.DIDCOMM_CREDENTIAL]: '/purge/didcomm-credential',
[PurgeRecordType.DIDCOMM_PROOF]: '/purge/didcomm-proof',
[PurgeRecordType.OID4VC_ISSUANCE]: '/purge/oid4vc-issuance',
[PurgeRecordType.OID4VC_VERIFICATION]: '/purge/oid4vc-verification',
}

export const PURGE_WEBHOOK_RETRY_DELAYS_MS = [1000, 5000, 30000]
Loading