Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
8c41b9e
fix(wallet-toolbox): accept Postgres as a storage dbtype
shruggr Oct 1, 2026
91cb889
fix(wallet-toolbox): run Knex migrations on Postgres
shruggr Oct 1, 2026
c108944
fix(wallet-toolbox): run StorageKnex queries on Postgres
shruggr Oct 1, 2026
b2a519b
fix(wallet-toolbox): portable session merges and Postgres duplicate keys
shruggr Oct 1, 2026
a74f0a6
test(wallet-toolbox): run Knex suites against Postgres with RUNPOSTGRES
shruggr Oct 1, 2026
22cc4e1
docs(wallet-toolbox): document Postgres storage
shruggr Oct 1, 2026
2560eab
fix(wallet-toolbox): parse Postgres int8 per connection in StorageKnex
shruggr Oct 1, 2026
54fdec0
fix(wallet-toolbox): keep Postgres transactions usable under READ COM…
shruggr Oct 1, 2026
55a12b4
test(wallet-toolbox): pass the Knex suites with a second backend
shruggr Oct 1, 2026
cd226be
fix(wallet-toolbox): keep rejecting Postgres in ChaintracksStorageKnex
shruggr Oct 1, 2026
6896510
feat(wallet-toolbox): run adminStats and admin req review on Postgres
shruggr Oct 1, 2026
dabcb30
feat(wallet-toolbox): accept a Postgres connection in MonitorDaemon
shruggr Oct 1, 2026
be4c4e9
feat(wallet-toolbox): build Postgres migration indexes concurrently
shruggr Oct 1, 2026
f1afd77
ci(wallet-toolbox): run the Knex storage suites against Postgres
shruggr Oct 1, 2026
af8718c
chore(wallet-infra): sync the KnexPaymentReplayStore runtime copy
shruggr Oct 1, 2026
f3a7672
chore(wallet-toolbox): prepare 2.15.0 release notes for Postgres storage
shruggr Oct 1, 2026
2490a6c
docs(wallet-toolbox): regenerate API docs
shruggr Oct 1, 2026
768d8fb
docs(wallet-toolbox): describe Postgres migrations and monitor setup
shruggr Oct 1, 2026
b25dd09
Merge remote-tracking branch 'origin/main' into feat/storageknex-post…
shruggr Oct 1, 2026
357ab12
test(wallet-toolbox): use new rows in the TxLabelMap mismatch test
shruggr Oct 1, 2026
1255163
test(wallet-toolbox): age the req review fixture with the server clock
shruggr Oct 1, 2026
bb68b93
test(wallet-toolbox): trim trailing spaces from createAction2 databas…
shruggr Oct 1, 2026
1a98f8e
fix(wallet-toolbox): order paged StorageKnex queries by key
shruggr Oct 1, 2026
a77989f
docs(wallet-toolbox): explain identifier bindings in raw Postgres SQL
shruggr Oct 1, 2026
97b6d0a
chore(wallet-toolbox): drop release metadata and regenerated docs fro…
shruggr Oct 1, 2026
93f57b3
revert(wallet-toolbox): drop MonitorDaemon and operator Postgres options
shruggr Oct 1, 2026
3b1b45e
revert(wallet-toolbox): build migration indexes as before on Postgres
shruggr Oct 1, 2026
75cfbc8
revert(wallet-toolbox): keep admin req review MySQL-only
shruggr Oct 1, 2026
40a90ee
fix(wallet-toolbox): narrow StorageKnex Postgres handling
shruggr Oct 1, 2026
740ddd8
fix(wallet-toolbox): reject Postgres in ChaintracksStorageKnex after …
shruggr Oct 1, 2026
be24720
docs(wallet-toolbox): short Postgres note; drop @types/pg
shruggr Oct 1, 2026
65d856c
Merge branch 'main' into feat/storageknex-postgres
shruggr Oct 1, 2026
7275bc5
Merge branch 'main' into feat/storageknex-postgres
shruggr Oct 2, 2026
8f76e65
Merge remote-tracking branch 'origin/main' into feat/storageknex-post…
sirdeggen Oct 2, 2026
f5ed1d3
fix(ci): clear new Sonar findings in StorageKnex Postgres support
sirdeggen Oct 2, 2026
0543b64
Merge remote-tracking branch 'origin/main' into pass-ci-719
sirdeggen Oct 2, 2026
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
18 changes: 18 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,19 @@ jobs:
- { id: shard-4, shard: 4 }
- { id: sync-http-0, latency: 0 }
- { id: sync-http-1000, latency: 1000 }
services:
# The Knex storage suites also run against Postgres (RUNPOSTGRES).
postgres:
image: postgres@sha256:d5daad18926b71c3d663f358af0aea798670cb79fb550c106d19662a9d1627ef # 17-alpine
env:
POSTGRES_PASSWORD: ${{ github.run_id }}-${{ github.run_attempt }}
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready --host 127.0.0.1 --username postgres"
--health-interval 5s
--health-timeout 5s
--health-retries 30
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
Expand All @@ -989,11 +1002,16 @@ jobs:
env:
WALLET_SHARD: ${{ matrix.shard }}
SYNC_LATENCY: ${{ matrix.latency }}
POSTGRES_PASSWORD: ${{ github.run_id }}-${{ github.run_attempt }}
run: |
# The two real-HTTP latency scenarios run in independent processes;
# their global transport spies must never overlap in one Jest worker.
args=(--coverage --coverageDirectory=coverage/${{ matrix.id }})
if [ -n "$WALLET_SHARD" ]; then
export RUNPOSTGRES=1
POSTGRES_CONNECTION="$(jq -cn --arg password "$POSTGRES_PASSWORD" \
'{host: "127.0.0.1", port: 5432, user: "postgres", password: $password, database: "postgres"}')"
export POSTGRES_CONNECTION
args+=(--testPathIgnorePatterns='man.test.ts|bench.test.ts|test/monitor/Monitor.test.ts|client/test|mobile/test|src/storage/sync/syncTransferHttp.test.ts')
args+=(--shard="$WALLET_SHARD/4")
else
Expand Down
1 change: 1 addition & 0 deletions infra/wallet-infra/src/KnexPaymentReplayStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ function isDuplicate(error: unknown): boolean {
value.code === 'ER_DUP_ENTRY' ||
value.code === 'SQLITE_CONSTRAINT_PRIMARYKEY' ||
value.code === 'SQLITE_CONSTRAINT_UNIQUE' ||
value.code === '23505' ||
value.errno === 1062
)
}
Expand Down
14 changes: 14 additions & 0 deletions packages/wallet/wallet-toolbox/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,20 @@ store already left with unjournaled schema objects by an older version. Preserve
the database and verified backups and reconcile the exact schema and migration
journal before recovery; do not delete journal rows or wallet data blindly.

### Postgres storage

`StorageKnex` runs on Postgres through the knex `pg` client. Install `pg` in the
application and pass a Postgres knex:

```ts
import { knex as makeKnex } from 'knex'

const knex = makeKnex({ client: 'pg', connection: { host, port, user, password, database } })
const storage = new StorageKnex({ ...StorageKnex.defaultOptions(), chain: 'main', knex })
```

`ChaintracksStorageKnex` and `adminStats` do not support Postgres.

## Overview

The Wallet Toolbox is the reference implementation of the BRC-100 wallet interface. It connects the BSV SDK's cryptographic primitives to real storage backends, network services, and signing flows so that application developers don't have to wire these layers together themselves.
Expand Down
1 change: 1 addition & 0 deletions packages/wallet/wallet-toolbox/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@
"fs-extra": "^11.4.0",
"jest": "^30.5.1",
"oxlint": "^1.83.0",
"pg": "^8.23.0",
"picocolors": "^1.1.1",
"ts-jest": "^29.4.12",
"ts-node": "^10.9.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { DBType } from '../../../../storage/StorageReader'
import { BulkHeaderFileInfo } from '../util/BulkHeaderFile'
import { HeightRange } from '../util/HeightRange'
import { Chain } from '../../../../sdk/types'
import { WERR_INVALID_OPERATION, WERR_INVALID_PARAMETER } from '../../../../sdk/WERR_errors'
import { WERR_INVALID_OPERATION, WERR_INVALID_PARAMETER, WERR_NOT_IMPLEMENTED } from '../../../../sdk/WERR_errors'
import { determineDBType } from '../../../../storage/schema/KnexMigrations'
import { normalizeBulkHeaderFileInfo, normalizeBulkHeaderFileSequence } from '../util/BulkFileDataManager'

Expand Down Expand Up @@ -94,6 +94,9 @@ export class ChaintracksStorageKnex extends ChaintracksStorageBase implements Ch
}
if (!this.isAvailable) {
this._dbtype = await determineDBType(this.knex)
// Chaintracks storage supports SQLite and MySQL only.
if (this._dbtype === 'Postgres')
throw new WERR_NOT_IMPLEMENTED('ChaintracksStorageKnex does not support Postgres.')
await super.makeAvailable()
// Connect the bulk data file manager to the table provided by this storage class.
await this.bulkManager.setStorage(this, this.log)
Expand Down
Loading
Loading