<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>xyz.tcheeric</groupId>
    <artifactId>imani-bom</artifactId>
    <version>0.1.85</version>
    <packaging>pom</packaging>
    <name>Imani BOM</name>
    <description>Bill of Materials (BOM) for the Imani platform — centralizes dependency versions across all projects</description>

    <properties>
        <java.version>21</java.version>
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.target>${java.version}</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

        <!-- Imani Platform Versions -->
        <imani-commons.version>0.1.2</imani-commons.version>
        <messaging-contracts.version>0.2.1</messaging-contracts.version>
        <imani-identity.version>0.1.3</imani-identity.version>
        <!-- 0.1.26 realigns wallet-lib's own cashu-voucher pin with the 0.10.0 declared
             below. 0.1.25 was built against 0.8.0, so consumers of this BOM linked
             0.8.0-compiled wallet classes against the 0.10.0 jar. Keep these in step. -->
        <!-- 0.1.33 carries the locked-voucher (P2PK) spend path — NUT-11 witness
             signing as a seam rather than a key, and VoucherResigner — plus the fix
             that lets the voucher ledger sign, and therefore publish, at all. -->
        <!-- 0.1.40 ENCRYPTS THE FLOAT AT REST, and migrates the proofs already in
             an existing one. Without it a gateway stores bearer secrets in the
             clear: the staging float's secret_enc column held readable NUT-10
             JSON that anyone with the volume, a snapshot or a backup could spend
             (imani-gateway-customer#74, #60). Encryption is off unless
             WALLET_PASSPHRASE is set, so adopting this BOM changes nothing until
             a consumer supplies one — but the FIRST start with a passphrase
             rewrites the float, so read the runbook before setting it. -->
        <!-- 0.2.0 closes 19 AppSec findings, 2 Critical: bearer proof secrets were
             logged at INFO in full (the "preview" sliced a string by a byte-array
             length), and a caller-supplied mint URL was unauthenticated SSRF into
             the gateway network whose response fed back into the crypto layer.

             BREAKING FOR LOCAL SETUPS: mint URLs resolving to loopback, link-local
             or RFC-1918 are now refused. docker-compose and integration
             environments point at exactly those, and must set
             -Dwallet.mint.allowInternalAddresses=true. Never set it anywhere
             reachable from outside — that flag is the whole of WALLET-02. -->
        <imani-wallet.version>0.3.1</imani-wallet.version>
        <!-- 0.7.0 adds claim / settleClaim / releaseClaim to ReceiveEscrowPort,
             which every implementor must provide. Consumers that have not
             written those methods must stay on 0.6.2 rather than picking this
             BOM up by accident: the interface really did change.

             The change was briefly built and installed as another 0.6.2, which
             overwrote the released jar in the local ~/.m2 and broke
             gateway-customer's main branch in code nobody had edited. Hence a
             new number for the new interface. -->
        <!-- 0.8.0 closes 14 AppSec findings. This is the contract library, so the
             break is that declared validation is now enforced: unbounded strings and
             collections on untrusted input, nested DTOs that were never
             cascade-validated, five request DTOs with no constraints at all, and URL
             components with no scheme or host constraint (the enabler half of the
             estate's SSRF findings). A request that a consumer's tests accepted may
             now be a 400 — that is the finding working. Because the gap lived here,
             no consumer ever saw it in its own diff. -->
        <!-- 0.8.1 corrects one of those bounds. The Cashu token ceiling was set to
             8192 characters, which is BELOW the size a real token is: a token carries
             one ~1840-character proof per set bit of the amount, so 1500 sat is seven
             proofs and 12870 characters. Vouchers minted successfully and were then
             refused at POST /api/v1/wallet/receive — the 2026-09-18 failed sells. The
             ceiling moved to 65536 and is still a bound. -->
        <imani-gateway-api.version>0.8.1</imani-gateway-api.version>
        <!-- 0.1.3 makes Nip98AuthFilter authenticate reads, not only writes. Until
             it, the no-Authorization branch rejected write methods only, so every GET
             on a protected prefix passed through unauthenticated on every gateway.
             Consumers that adopt this BOM version also pick up 0.1.1 (CRIT-1 event-id
             binding) and 0.1.2 (HIGH-3 URL binding) — all three gateways were pinning
             0.1.0 locally and had received neither. -->
        <!-- 0.2.0 closes 14 AppSec findings, 2 Critical, and this library is upstream
             of every gateway — so both Criticals were simultaneously true of the whole
             estate. SEC-01: every path-based security decision read the raw
             percent-encoded URI, so %2F and path parameters bypassed every protected
             prefix; 6 of 6 bypass variants were executed against the real filter and
             reached the handler with no Authorization header. SEC-02: X-Forwarded-Host
             is not stripped at the edge, so a captured NIP-98 event authenticated
             against a service it was never issued for.

             ADOPTING THIS REQUIRES CONFIGURATION. A service with no
             gateway.security.nip98.public-base-url now REFUSES TO START; set it to
             that service's own public origin, or set
             gateway.security.nip98.allow-insecure-header-url-binding=true to knowingly
             keep the bypass outside production. Separately, an edge shared secret under
             32 characters now DISABLES NapProxyAuthFilter and logs ERROR rather than
             being silently accepted, so X-Auth-Pubkey stops being honoured: watch for
             nap_proxy_auth_disabled at startup. The symptom otherwise is a service that
             boots, reports healthy, and refuses everyone. -->
        <imani-security.version>0.2.2</imani-security.version>
        <imani-nostrdb.version>0.1.4</imani-nostrdb.version>
        <!-- 0.6.0 is the current release (reposilite <release>0.6.0; published
             0.1.0, 0.1.1, 0.4.0, 0.6.0). It carries the authorization layer —
             AclResolver / PermissionRegistry / RoleDefinition and the
             @RequiresPermission / @RequiresRole / @RequiresSession guards — none
             of which exist in 0.1.0.

             Consumers had been overriding this individually (dalia, bottin) or
             silently running 0.1.0 (gateway-core resolved 0.1.1 only because it
             re-pinned all five artifacts itself). Declaring the real version
             here is what lets them stop.

             0.7.0 adds `supported_extensions` to AuthInitResponse and makes the record
             tolerate unknown fields. The second half is the reason to take it: Jackson
             throws on an unrecognised property by default, so a Java client talking to
             a TypeScript NAP server that advertises extensions failed with
             UnrecognizedPropertyException. Every additive field RFC §24.3 permits was a
             breaking change for this client until that fix. -->
        <nap-java.version>0.8.0</nap-java.version>
        <imani-merchant.version>0.2.0</imani-merchant.version>

        <!-- Cashu Library Versions -->
        <!-- Completes the P2PK_VOUCHER set that 0.1.60 began. cashu-lib 0.29.0 defines
             the composite NUT-10 kind, cashu-voucher 0.13.0 signs it, and cashu-mint
             0.35.0 enforces the voucher conditions and the P2PK witness together.

             0.1.60 carried only cashu-lib and nap-java because cashu-voucher imports
             this BOM to get its cashu-lib version, so the two could not be released in
             one step. That intermediate state is now closed: pin all three together and
             do not mix a 0.29.0 cashu-lib with a mint older than 0.35.0, which would
             dispatch the kind to a condition that never checks a witness.

             0.1.63 moves all of these for the 2026-09-05 security audit. They are one
             set because the fixes cross the boundaries: cashu-lib 0.30.0 rejects
             off-curve public keys and refuses to downgrade a locked secret to a bearer
             secret, and cashu-voucher 0.14.0 requires a registered issuer key before
             calling a signature valid. A consumer that took the voucher bump without the
             lib bump would verify voucher signatures against keys the library still
             accepts off-curve, so the issuer check would rest on a key type the crypto
             layer no longer trusts. cashu-mint 0.36.0 additionally fixes the audit
             Critical: P2PK proofs were never BDHKE-verified on /v1/swap.

             Note cashu-vault and cashu-wallet were pinned to cashu-lib 0.27.0 and
             cashu-ledger to 0.21.0 before this release, so none of them had received any
             library security fix (audit L-36). All three now build against 0.30.0. -->
        <cashu-lib.version>0.30.2</cashu-lib.version>
        <cashu-wallet.version>0.8.1</cashu-wallet.version>
        <!-- 0.14.1 stops a non-pubkey `p` tag costing the whole ledger event. A
             relay rejects the ENTIRE event when a `p` tag is not a 32-byte pubkey,
             and it does not tell the writer, so the gateway logged publish_success
             while the ledger stored nothing. -->
        <cashu-voucher.version>0.14.2</cashu-voucher.version>
        <cashu-ledger.version>0.7.1</cashu-ledger.version>
        <!-- The mint and the vault are declared here so a consumer of both cannot pin
             them independently and drift: the vault's hold_id schema (0.11.0) and the
             mint that writes it are one release pair. -->
        <cashu-mint.version>0.36.5</cashu-mint.version>
        <cashu-vault.version>0.12.1</cashu-vault.version>

        <!-- Nostr Java Versions -->
        <nostr-java.version>2.3.1</nostr-java.version>

        <!-- NsecBunker Java Versions -->
        <nsecbunker-java.version>0.2.0</nsecbunker-java.version>

        <!-- Nostrdb JNI Version -->
        <nostrdb-jni.version>0.2.2</nostrdb-jni.version>

        <!-- Spring Boot (imported as BOM) -->
        <spring-boot.version>3.5.16</spring-boot.version>

        <!-- Tomcat, overriding what Spring Boot pins.
             Boot 3.5.16 ships Tomcat 10.1.55, which is NOT enough: 10.1.55
             remains affected by three CRITICALs, including CVE-2026-65905 and
             CVE-2026-43512, both authentication bypasses. 10.1.58 is the first
             release clear of all of them (verified against OSV: 10.1.55, .56
             and .57 all report 3 CRITICAL). 10.1.58 itself was never published
             to Maven Central (the index skips from .57 to .59), so the
             advisories name a version nobody can actually depend on, and the
             real floor is 10.1.59.
             Spring Boot reads this exact property name, so setting it here
             re-versions the whole Tomcat family coherently.
             Remove this override once a Boot release ships >= 10.1.59. -->
        <tomcat.version>10.1.59</tomcat.version>

        <!-- Core Dependencies -->
        <!-- 1.84, not 1.83: CVE-2025-14813 (GOSTCTR) is fixed in 1.80.2,
             1.81.1 and 1.84 only. An open Snyk PR proposed 1.83, which OSV
             reports as carrying MORE vulnerabilities than the 1.81 it replaces
             (3 vs 2), so it would have looked like a fix and left the finding
             in place. -->
        <bcprov-jdk18on.version>1.84</bcprov-jdk18on.version>
        <commons-lang3.version>3.18.0</commons-lang3.version>
        <commons-text.version>1.12.0</commons-text.version>
        <slf4j.version>2.0.17</slf4j.version>
        <lombok.version>1.18.40</lombok.version>
        <picocli.version>4.7.6</picocli.version>

        <!-- Database -->
        <postgresql.version>42.7.7</postgresql.version>
        <h2.version>2.2.224</h2.version>
        <hikaricp.version>6.3.2</hikaricp.version>

        <!-- Resilience -->
        <resilience4j.version>2.1.0</resilience4j.version>

        <!-- Cryptography -->
        <argon2-jvm.version>2.11</argon2-jvm.version>

        <!-- Validation -->
        <jakarta-validation.version>3.1.0</jakarta-validation.version>
        <hibernate-validator.version>8.0.3.Final</hibernate-validator.version>
        <jakarta-el.version>4.0.2</jakarta-el.version>

        <!-- Logging -->
        <!-- Deliberately NOT set: Spring Boot versions logback, and it must
             version BOTH halves of the pair. This pinned logback-classic to
             1.5.18 while leaving logback-core to Boot, which moved to 1.5.34 on
             the 3.5.16 bump; the split pair threw
             NoSuchMethodError: LoggerContext.initCollisionMaps() at every
             Spring context load. A pin that covers one artifact of a
             tightly-coupled pair is worse than no pin.
        <logback.version>1.5.18</logback.version> -->
        <logstash-logback-encoder.version>8.0</logstash-logback-encoder.version>

        <!-- Observability -->
        <opentelemetry.version>1.44.1</opentelemetry.version>
        <opentelemetry-alpha.version>1.44.1-alpha</opentelemetry-alpha.version>
        <opentelemetry-semconv.version>1.30.1-alpha</opentelemetry-semconv.version>
        <micrometer.version>1.14.2</micrometer.version>

        <!-- Testing -->
        <junit.version>5.12.2</junit.version>
        <junit-platform.version>1.12.2</junit-platform.version>
        <assertj.version>3.27.4</assertj.version>
        <mockito.version>5.19.0</mockito.version>
        <byte-buddy.version>1.15.11</byte-buddy.version>
        <testcontainers.version>1.20.4</testcontainers.version>
        <jqwik.version>1.8.0</jqwik.version>
        <wiremock.version>3.9.1</wiremock.version>
        <awaitility.version>4.3.0</awaitility.version>
        <guava.version>33.4.8-jre</guava.version>

        <!-- Jackson. Tracks what Spring Boot ships, and must keep tracking it.
             These were pinned at 2.20.0/2.20, which silently overrode Boot's
             2.21.4 across nine artifacts: a local pin on a BOM-managed
             artifact never fails the build, it just wins. 2.20.0 carries five
             known advisories and 2.21.4 carries three, so the pin was holding
             consumers on the worse version.
             Open Snyk PRs proposing 2.20.1 do not help either: OSV reports the
             same five advisories against it.
             jackson-annotations versions SEPARATELY (2.21, not 2.21.4), as
             jackson-bom's own jackson.version.annotations property shows. -->
        <jackson.version>2.21.4</jackson.version>
        <jackson.annotations.version>2.21</jackson.annotations.version>

        <!-- Build Plugins -->
        <flyway.version>11.7.2</flyway.version>
        <jacoco.version>0.8.10</jacoco.version>
        <maven.surefire.plugin.version>3.5.2</maven.surefire.plugin.version>
        <maven.enforcer.plugin.version>3.4.1</maven.enforcer.plugin.version>
        <maven.shade.plugin.version>3.6.0</maven.shade.plugin.version>
        <maven.failsafe.plugin.version>3.2.5</maven.failsafe.plugin.version>
        <maven.jar.plugin.version>3.3.0</maven.jar.plugin.version>
        <jib-maven-plugin.version>3.4.6</jib-maven-plugin.version>

        <!-- Other -->
        <bip-utils.version>2.0.0</bip-utils.version>
        <expressly.version>5.0.0</expressly.version>
        <commons-logging.version>1.3.5</commons-logging.version>
        <undertow.version>2.3.18.Final</undertow.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <!-- Tomcat, pinned AHEAD of the Spring Boot import below.
                 Order is load-bearing: an imported BOM cannot be overridden by
                 a property here, because spring-boot-dependencies resolves
                 ${tomcat.version} against its OWN properties, not ours. The
                 only thing that wins is an explicit entry declared BEFORE the
                 import, since Maven takes the first declaration it sees.
                 Setting the property alone looks right and does nothing: it was
                 verified failing, resolving 10.1.55 in gateway-core.
                 Boot 3.5.16 ships 10.1.55, which is still affected by three
                 CRITICALs including two authentication bypasses. 10.1.59 is
                 the first PUBLISHED release clear of them: the advisories say
                 10.1.58, but that version was never pushed to Central. -->
            <dependency>
                <groupId>org.apache.tomcat.embed</groupId>
                <artifactId>tomcat-embed-core</artifactId>
                <version>${tomcat.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.tomcat.embed</groupId>
                <artifactId>tomcat-embed-el</artifactId>
                <version>${tomcat.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.tomcat.embed</groupId>
                <artifactId>tomcat-embed-websocket</artifactId>
                <version>${tomcat.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.tomcat</groupId>
                <artifactId>tomcat-annotations-api</artifactId>
                <version>${tomcat.version}</version>
            </dependency>

            <!-- Spring Boot BOM -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- JUnit BOM -->
            <dependency>
                <groupId>org.junit</groupId>
                <artifactId>junit-bom</artifactId>
                <version>${junit.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- OpenTelemetry BOM -->
            <dependency>
                <groupId>io.opentelemetry</groupId>
                <artifactId>opentelemetry-bom</artifactId>
                <version>${opentelemetry.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- Micrometer BOM -->
            <dependency>
                <groupId>io.micrometer</groupId>
                <artifactId>micrometer-bom</artifactId>
                <version>${micrometer.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- Testcontainers BOM -->
            <dependency>
                <groupId>org.testcontainers</groupId>
                <artifactId>testcontainers-bom</artifactId>
                <version>${testcontainers.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- ============================================================ -->
            <!-- Imani Platform Artifacts                                      -->
            <!-- ============================================================ -->
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>imani-commons</artifactId>
                <version>${imani-commons.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>messaging-contracts</artifactId>
                <version>${messaging-contracts.version}</version>
            </dependency>

            <!-- Identity Modules -->
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>identity-domain</artifactId>
                <version>${imani-identity.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>identity-api</artifactId>
                <version>${imani-identity.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>identity-application</artifactId>
                <version>${imani-identity.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>identity-infrastructure</artifactId>
                <version>${imani-identity.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>identity-storage-file</artifactId>
                <version>${imani-identity.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>identity-cli</artifactId>
                <version>${imani-identity.version}</version>
            </dependency>

            <!-- Wallet Modules -->
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>wallet-core-base</artifactId>
                <version>${imani-wallet.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>wallet-core-observability</artifactId>
                <version>${imani-wallet.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>wallet-core-cashu</artifactId>
                <version>${imani-wallet.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>wallet-core-nostr</artifactId>
                <version>${imani-wallet.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>wallet-core-app</artifactId>
                <version>${imani-wallet.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>wallet-nip-04</artifactId>
                <version>${imani-wallet.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>wallet-nip-17</artifactId>
                <version>${imani-wallet.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>wallet-nip-42</artifactId>
                <version>${imani-wallet.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>wallet-nip-44</artifactId>
                <version>${imani-wallet.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>wallet-nip-60</artifactId>
                <version>${imani-wallet.version}</version>
            </dependency>

            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>imani-gateway-api</artifactId>
                <version>${imani-gateway-api.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>imani-security</artifactId>
                <version>${imani-security.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>imani-nostrdb</artifactId>
                <version>${imani-nostrdb.version}</version>
            </dependency>

            <!-- Merchant Modules -->
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>merchant-domain</artifactId>
                <version>${imani-merchant.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>merchant-api</artifactId>
                <version>${imani-merchant.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>merchant-application</artifactId>
                <version>${imani-merchant.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>merchant-infrastructure</artifactId>
                <version>${imani-merchant.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>merchant-rest</artifactId>
                <version>${imani-merchant.version}</version>
            </dependency>

            <!-- NAP Java Modules -->
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>nap-core</artifactId>
                <version>${nap-java.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>nap-server</artifactId>
                <version>${nap-java.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>nap-jdbc</artifactId>
                <version>${nap-java.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>nap-client</artifactId>
                <version>${nap-java.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>nap-spring</artifactId>
                <version>${nap-java.version}</version>
            </dependency>

            <!-- ============================================================ -->
            <!-- Cashu Library Modules                                         -->
            <!-- ============================================================ -->
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>cashu-lib-entities</artifactId>
                <version>${cashu-lib.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>cashu-lib-crypto</artifactId>
                <version>${cashu-lib.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>cashu-lib-common</artifactId>
                <version>${cashu-lib.version}</version>
            </dependency>

            <!-- Cashu Wallet Modules -->
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>cashu-wallet-protocol</artifactId>
                <version>${cashu-wallet.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>cashu-wallet-client</artifactId>
                <version>${cashu-wallet.version}</version>
            </dependency>

            <!-- Cashu Vault Modules -->
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>cashu-vault-api</artifactId>
                <version>${cashu-vault.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>cashu-vault-jpa</artifactId>
                <version>${cashu-vault.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>cashu-vault-hashi</artifactId>
                <version>${cashu-vault.version}</version>
            </dependency>

            <!-- Cashu Mint Modules -->
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>cashu-mint-protocol</artifactId>
                <version>${cashu-mint.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>cashu-mint-rest</artifactId>
                <version>${cashu-mint.version}</version>
            </dependency>

            <!-- Cashu Voucher Modules -->
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>cashu-voucher-domain</artifactId>
                <version>${cashu-voucher.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>cashu-voucher-app</artifactId>
                <version>${cashu-voucher.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>cashu-voucher-nostr</artifactId>
                <version>${cashu-voucher.version}</version>
            </dependency>
            <!--
              New in cashu-voucher 0.10.0. Managed here for consistency with its three
              siblings; nothing depends on it yet. It is a pure SignedVoucher -> pass.json
              mapper (schema only — no certificates, no .pkpass container, no pass update
              web service), so adding it to the BOM commits no one to Apple Wallet.
            -->
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>cashu-voucher-pass</artifactId>
                <version>${cashu-voucher.version}</version>
            </dependency>

            <!-- Cashu Ledger Modules (spec 048 trace-event producer SDK) -->
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>cashu-ledger-trace-publisher</artifactId>
                <version>${cashu-ledger.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>cashu-ledger-trace-core</artifactId>
                <version>${cashu-ledger.version}</version>
            </dependency>

            <!-- ============================================================ -->
            <!-- Nostr Java 2.0 Modules                                        -->
            <!-- ============================================================ -->
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>nostr-java-core</artifactId>
                <version>${nostr-java.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>nostr-java-event</artifactId>
                <version>${nostr-java.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>nostr-java-identity</artifactId>
                <version>${nostr-java.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>nostr-java-client</artifactId>
                <version>${nostr-java.version}</version>
            </dependency>

            <!-- NsecBunker Java Modules -->
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>nsecbunker-core</artifactId>
                <version>${nsecbunker-java.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>nsecbunker-connection</artifactId>
                <version>${nsecbunker-java.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>nsecbunker-protocol</artifactId>
                <version>${nsecbunker-java.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>nsecbunker-admin</artifactId>
                <version>${nsecbunker-java.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>nsecbunker-client</artifactId>
                <version>${nsecbunker-java.version}</version>
            </dependency>
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>nsecbunker-account</artifactId>
                <version>${nsecbunker-java.version}</version>
            </dependency>

            <!-- Nostrdb JNI -->
            <dependency>
                <groupId>xyz.tcheeric</groupId>
                <artifactId>nostrdb-jni</artifactId>
                <version>${nostrdb-jni.version}</version>
            </dependency>

            <!-- ============================================================ -->
            <!-- Jackson (pinned to 2.20.0 for TokenV4 compatibility)          -->
            <!-- ============================================================ -->
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-core</artifactId>
                <version>${jackson.version}</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>${jackson.version}</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-annotations</artifactId>
                <version>${jackson.annotations.version}</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.datatype</groupId>
                <artifactId>jackson-datatype-jsr310</artifactId>
                <version>${jackson.version}</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.datatype</groupId>
                <artifactId>jackson-datatype-jdk8</artifactId>
                <version>${jackson.version}</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.dataformat</groupId>
                <artifactId>jackson-dataformat-cbor</artifactId>
                <version>${jackson.version}</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.dataformat</groupId>
                <artifactId>jackson-dataformat-toml</artifactId>
                <version>${jackson.version}</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.module</groupId>
                <artifactId>jackson-module-parameter-names</artifactId>
                <version>${jackson.version}</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.module</groupId>
                <artifactId>jackson-module-blackbird</artifactId>
                <version>${jackson.version}</version>
            </dependency>

            <!-- ============================================================ -->
            <!-- Core Dependencies                                             -->
            <!-- ============================================================ -->
            <dependency>
                <groupId>org.bouncycastle</groupId>
                <artifactId>bcprov-jdk18on</artifactId>
                <version>${bcprov-jdk18on.version}</version>
            </dependency>
            <!-- The same provider built for an older JDK. Nothing declares it,
                 but it arrives transitively through bip-utils -> bitcoinj-core
                 at 1.80, which CVE-2025-14813 affects just as it does jdk18on.
                 Managed at the same version so the two cannot drift: a
                 vulnerable crypto provider reaching the classpath by a path
                 nobody reads is precisely the case a BOM exists to close.
                 Measured in imani-wallet-lib, which resolved 1.80 while its
                 declared jdk18on was already 1.84. -->
            <dependency>
                <groupId>org.bouncycastle</groupId>
                <artifactId>bcprov-jdk15to18</artifactId>
                <version>${bcprov-jdk18on.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-lang3</artifactId>
                <version>${commons-lang3.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-text</artifactId>
                <version>${commons-text.version}</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>${slf4j.version}</version>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>info.picocli</groupId>
                <artifactId>picocli</artifactId>
                <version>${picocli.version}</version>
            </dependency>
            <dependency>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
                <version>${commons-logging.version}</version>
            </dependency>

            <!-- Database -->
            <dependency>
                <groupId>org.postgresql</groupId>
                <artifactId>postgresql</artifactId>
                <version>${postgresql.version}</version>
            </dependency>
            <dependency>
                <groupId>com.h2database</groupId>
                <artifactId>h2</artifactId>
                <version>${h2.version}</version>
            </dependency>
            <dependency>
                <groupId>com.zaxxer</groupId>
                <artifactId>HikariCP</artifactId>
                <version>${hikaricp.version}</version>
            </dependency>
            <dependency>
                <groupId>org.flywaydb</groupId>
                <artifactId>flyway-core</artifactId>
                <version>${flyway.version}</version>
            </dependency>
            <dependency>
                <groupId>org.flywaydb</groupId>
                <artifactId>flyway-database-postgresql</artifactId>
                <version>${flyway.version}</version>
            </dependency>

            <!-- Resilience -->
            <dependency>
                <groupId>io.github.resilience4j</groupId>
                <artifactId>resilience4j-retry</artifactId>
                <version>${resilience4j.version}</version>
            </dependency>
            <dependency>
                <groupId>io.github.resilience4j</groupId>
                <artifactId>resilience4j-circuitbreaker</artifactId>
                <version>${resilience4j.version}</version>
            </dependency>
            <dependency>
                <groupId>io.github.resilience4j</groupId>
                <artifactId>resilience4j-ratelimiter</artifactId>
                <version>${resilience4j.version}</version>
            </dependency>

            <!-- Cryptography -->
            <dependency>
                <groupId>de.mkammerer</groupId>
                <artifactId>argon2-jvm</artifactId>
                <version>${argon2-jvm.version}</version>
            </dependency>

            <!-- Validation -->
            <dependency>
                <groupId>jakarta.validation</groupId>
                <artifactId>jakarta.validation-api</artifactId>
                <version>${jakarta-validation.version}</version>
            </dependency>
            <dependency>
                <groupId>org.hibernate.validator</groupId>
                <artifactId>hibernate-validator</artifactId>
                <version>${hibernate-validator.version}</version>
            </dependency>
            <dependency>
                <groupId>org.glassfish</groupId>
                <artifactId>jakarta.el</artifactId>
                <version>${jakarta-el.version}</version>
            </dependency>

            <!-- Logging. logback-classic/-core are versioned by the Spring
                 Boot import, together; see the logback.version note above. -->
            <dependency>
                <groupId>net.logstash.logback</groupId>
                <artifactId>logstash-logback-encoder</artifactId>
                <version>${logstash-logback-encoder.version}</version>
            </dependency>

            <!-- Testing -->
            <dependency>
                <groupId>org.junit.jupiter</groupId>
                <artifactId>junit-jupiter</artifactId>
                <version>${junit.version}</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.junit.jupiter</groupId>
                <artifactId>junit-jupiter-engine</artifactId>
                <version>${junit.version}</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.junit.jupiter</groupId>
                <artifactId>junit-jupiter-api</artifactId>
                <version>${junit.version}</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.junit.platform</groupId>
                <artifactId>junit-platform-commons</artifactId>
                <version>${junit-platform.version}</version>
            </dependency>
            <dependency>
                <groupId>org.junit.platform</groupId>
                <artifactId>junit-platform-engine</artifactId>
                <version>${junit-platform.version}</version>
            </dependency>
            <dependency>
                <groupId>org.junit.platform</groupId>
                <artifactId>junit-platform-launcher</artifactId>
                <version>${junit-platform.version}</version>
            </dependency>
            <dependency>
                <groupId>org.assertj</groupId>
                <artifactId>assertj-core</artifactId>
                <version>${assertj.version}</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.mockito</groupId>
                <artifactId>mockito-core</artifactId>
                <version>${mockito.version}</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.mockito</groupId>
                <artifactId>mockito-junit-jupiter</artifactId>
                <version>${mockito.version}</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>net.bytebuddy</groupId>
                <artifactId>byte-buddy</artifactId>
                <version>${byte-buddy.version}</version>
            </dependency>
            <dependency>
                <groupId>net.bytebuddy</groupId>
                <artifactId>byte-buddy-agent</artifactId>
                <version>${byte-buddy.version}</version>
            </dependency>
            <dependency>
                <groupId>net.jqwik</groupId>
                <artifactId>jqwik</artifactId>
                <version>${jqwik.version}</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.wiremock</groupId>
                <artifactId>wiremock</artifactId>
                <version>${wiremock.version}</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.awaitility</groupId>
                <artifactId>awaitility</artifactId>
                <version>${awaitility.version}</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>com.google.guava</groupId>
                <artifactId>guava</artifactId>
                <version>${guava.version}</version>
                <scope>test</scope>
            </dependency>

            <!-- Other -->
            <dependency>
                <groupId>io.undertow</groupId>
                <artifactId>undertow-core</artifactId>
                <version>${undertow.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.13.0</version>
                    <configuration>
                        <parameters>true</parameters>
                        <annotationProcessorPaths>
                            <path>
                                <groupId>org.projectlombok</groupId>
                                <artifactId>lombok</artifactId>
                            </path>
                        </annotationProcessorPaths>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>${maven.surefire.plugin.version}</version>
                    <configuration>
                        <useModulePath>false</useModulePath>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.jacoco</groupId>
                    <artifactId>jacoco-maven-plugin</artifactId>
                    <version>${jacoco.version}</version>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-failsafe-plugin</artifactId>
                    <version>${maven.failsafe.plugin.version}</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>

    <distributionManagement>
        <repository>
            <id>reposilite-releases</id>
            <url>https://maven.398ja.xyz/releases</url>
        </repository>
        <snapshotRepository>
            <id>reposilite-snapshots</id>
            <url>https://maven.398ja.xyz/snapshots</url>
        </snapshotRepository>
    </distributionManagement>

    <repositories>
        <repository>
            <id>central</id>
            <url>https://repo.maven.apache.org/maven2</url>
            <releases><enabled>true</enabled></releases>
            <snapshots><enabled>false</enabled></snapshots>
        </repository>
        <repository>
            <id>reposilite-releases</id>
            <url>https://maven.398ja.xyz/releases</url>
        </repository>
        <repository>
            <id>reposilite-snapshots</id>
            <url>https://maven.398ja.xyz/snapshots</url>
        </repository>
    </repositories>

</project>
