commit 29a3302916c400707d63555e0ba7bf00699779c6
parent f783f1dcec5450b70f219b590f4f6657d88afd5a
Author: Florian Dold <dold@taler.net>
Date: Mon, 20 Jul 2026 00:09:23 +0200
db: annotate the JSON-valued columns of the sqlite schema
TEXT columns holding JSON now name the type they decode to.
Diffstat:
1 file changed, 81 insertions(+), 0 deletions(-)
diff --git a/packages/taler-wallet-core/src/db-sqlite-schema.ts b/packages/taler-wallet-core/src/db-sqlite-schema.ts
@@ -261,6 +261,7 @@ CREATE TABLE IF NOT EXISTS config (
CREATE TABLE IF NOT EXISTS currency_info (
scope_info_str TEXT PRIMARY KEY,
+ -- JSON: CurrencySpecification
currency_spec TEXT NOT NULL,
source TEXT NOT NULL
);
@@ -280,6 +281,9 @@ CREATE TABLE IF NOT EXISTS contacts (
CREATE TABLE IF NOT EXISTS mailbox_messages (
origin_mailbox_base_url TEXT NOT NULL,
taler_uri TEXT NOT NULL,
+ -- JSON: Timestamp. Stored as a JSON document rather than as an INTEGER
+ -- microsecond timestamp like every other time in this schema, because the
+ -- record type exposes it whole and nothing queries or orders by it.
downloaded_at TEXT NOT NULL,
PRIMARY KEY (origin_mailbox_base_url, taler_uri)
);
@@ -291,6 +295,7 @@ CREATE TABLE IF NOT EXISTS mailbox_configurations (
CREATE TABLE IF NOT EXISTS contract_terms (
h TEXT PRIMARY KEY,
+ -- JSON: the raw contract terms, as received
contract_terms_raw TEXT NOT NULL
);
@@ -300,7 +305,9 @@ CREATE TABLE IF NOT EXISTS tombstones (
CREATE TABLE IF NOT EXISTS operation_retries (
id TEXT PRIMARY KEY,
+ -- JSON: TalerErrorDetail
last_error TEXT,
+ -- JSON: WalletRetryInfo
retry_info TEXT NOT NULL
);
@@ -328,6 +335,7 @@ CREATE INDEX IF NOT EXISTS reserves_by_reserve_pub
CREATE TABLE IF NOT EXISTS denominations (
exchange_base_url TEXT NOT NULL,
denom_pub_hash BLOB NOT NULL,
+ -- JSON: DenominationPubKey
denom_pub TEXT NOT NULL,
exchange_master_pub BLOB NOT NULL,
currency TEXT NOT NULL,
@@ -382,6 +390,7 @@ CREATE TABLE IF NOT EXISTS bank_accounts (
bank_account_id TEXT PRIMARY KEY,
payto_uri TEXT NOT NULL,
label TEXT,
+ -- JSON: string[]
currencies TEXT,
kyc_completed INTEGER NOT NULL
);
@@ -402,8 +411,11 @@ CREATE TABLE IF NOT EXISTS tokens (
token_family_hash BLOB,
valid_after INTEGER NOT NULL,
valid_before INTEGER NOT NULL,
+ -- JSON: UnblindedDenominationSignature
token_issue_sig TEXT NOT NULL,
+ -- JSON: TokenUseSig
token_use_sig TEXT,
+ -- JSON: TokenEnvelope
token_ev TEXT NOT NULL,
token_ev_hash BLOB NOT NULL,
blinding_key BLOB NOT NULL,
@@ -411,8 +423,11 @@ CREATE TABLE IF NOT EXISTS tokens (
slug TEXT NOT NULL,
name TEXT NOT NULL,
description TEXT NOT NULL,
+ -- JSON: MerchantContractTokenDetails
extra_data TEXT NOT NULL,
+ -- JSON: TokenIssuePublicKey
token_issue_pub TEXT NOT NULL,
+ -- JSON: translations, keyed by IETF language tag
description_i18n TEXT
);
CREATE INDEX IF NOT EXISTS tokens_by_issue_pub_hash
@@ -436,7 +451,9 @@ CREATE TABLE IF NOT EXISTS slates (
token_family_hash BLOB,
valid_after INTEGER NOT NULL,
valid_before INTEGER NOT NULL,
+ -- JSON: TokenUseSig
token_use_sig TEXT,
+ -- JSON: TokenEnvelope
token_ev TEXT NOT NULL,
token_ev_hash BLOB NOT NULL,
blinding_key BLOB NOT NULL,
@@ -444,8 +461,11 @@ CREATE TABLE IF NOT EXISTS slates (
slug TEXT NOT NULL,
name TEXT NOT NULL,
description TEXT NOT NULL,
+ -- JSON: MerchantContractTokenDetails
extra_data TEXT NOT NULL,
+ -- JSON: TokenIssuePublicKey
token_issue_pub TEXT NOT NULL,
+ -- JSON: translations, keyed by IETF language tag
description_i18n TEXT
);
CREATE INDEX IF NOT EXISTS slates_by_purchase_choice_output_repeat
@@ -456,8 +476,10 @@ CREATE TABLE IF NOT EXISTS refresh_sessions (
coin_index INTEGER NOT NULL,
session_public_seed BLOB,
amount_refresh_output TEXT NOT NULL,
+ -- JSON: { denomPubHash, count }[]
new_denoms TEXT NOT NULL,
noreveal_index INTEGER,
+ -- JSON: TalerErrorDetail
last_error TEXT,
PRIMARY KEY (refresh_group_id, coin_index)
);
@@ -468,8 +490,11 @@ CREATE TABLE IF NOT EXISTS recoup_groups (
operation_status INTEGER NOT NULL,
timestamp_started INTEGER NOT NULL,
timestamp_finished INTEGER,
+ -- JSON: string[]
coin_pubs TEXT NOT NULL,
+ -- JSON: boolean[]
recoup_finished_per_coin TEXT NOT NULL,
+ -- JSON: CoinRefreshRequest[]
schedule_refresh_coins TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS recoup_groups_by_status
@@ -500,6 +525,7 @@ CREATE TABLE IF NOT EXISTS donation_planchets (
donation_year INTEGER NOT NULL,
proposal_id TEXT NOT NULL,
udi_index INTEGER NOT NULL,
+ -- JSON: BlindedUniqueDonationIdentifier
blinded_udi TEXT NOT NULL,
bks BLOB NOT NULL,
donation_unit_pub_hash BLOB NOT NULL,
@@ -515,6 +541,7 @@ CREATE TABLE IF NOT EXISTS donation_receipts (
proposal_id TEXT NOT NULL,
donation_year INTEGER NOT NULL,
donation_unit_pub_hash BLOB NOT NULL,
+ -- JSON: DonationReceiptSignature
donation_unit_sig TEXT NOT NULL,
donor_tax_id_hash BLOB NOT NULL,
-- TEXT, not BLOB: see the note in donation_planchets.
@@ -535,7 +562,9 @@ CREATE TABLE IF NOT EXISTS purchases (
repurchase_proposal_id TEXT,
purchase_status INTEGER NOT NULL,
abort_refresh_group_id TEXT,
+ -- JSON: TalerErrorDetail
abort_reason TEXT,
+ -- JSON: TalerErrorDetail
fail_reason TEXT,
nonce_priv BLOB NOT NULL,
nonce_pub BLOB NOT NULL,
@@ -546,7 +575,9 @@ CREATE TABLE IF NOT EXISTS purchases (
-- write and re-inserted on read, so the indexed value cannot drift from
-- the payload. Same rule as withdrawal_groups.taler_withdraw_uri.
download_fulfillment_url TEXT,
+ -- JSON: WalletPurchasePayInfo
pay_info TEXT,
+ -- JSON: string[]
pending_removed_coin_pubs TEXT,
timestamp_first_successful_pay INTEGER,
merchant_pay_sig BLOB,
@@ -600,8 +631,10 @@ CREATE TABLE IF NOT EXISTS deposit_groups (
merchant_priv BLOB NOT NULL,
nonce_priv BLOB NOT NULL,
nonce_pub BLOB NOT NULL,
+ -- JSON: { payto_uri, salt }
wire TEXT NOT NULL,
contract_terms_hash BLOB NOT NULL,
+ -- JSON: WalletCoinSelection
pay_coin_selection TEXT,
pay_coin_selection_uid TEXT,
total_pay_cost TEXT NOT NULL,
@@ -610,14 +643,21 @@ CREATE TABLE IF NOT EXISTS deposit_groups (
timestamp_finished INTEGER,
timestamp_last_deposit_attempt INTEGER,
operation_status INTEGER NOT NULL,
+ -- JSON: DepositElementStatus[]
status_per_coin TEXT,
+ -- JSON: Record<string, WalletDepositInfoPerExchange>
info_per_exchange TEXT,
abort_refresh_group_id TEXT,
+ -- JSON: TalerErrorDetail
abort_reason TEXT,
+ -- JSON: TalerErrorDetail
fail_reason TEXT,
+ -- JSON: WalletDepositKycInfo
kyc_info TEXT,
+ -- JSON: TransferOptionRaw[]
kyc_auth_transfer_options TEXT,
kyc_auth_transfer_expiry INTEGER,
+ -- JSON: wire transfer tracking, keyed by signature
tracking_state TEXT
);
CREATE INDEX IF NOT EXISTS deposit_groups_by_status
@@ -629,13 +669,20 @@ CREATE TABLE IF NOT EXISTS refresh_groups (
currency TEXT NOT NULL,
reason TEXT NOT NULL,
originating_transaction_id TEXT,
+ -- JSON: string[]
old_coin_pubs TEXT NOT NULL,
+ -- JSON: AmountString[]
input_per_coin TEXT NOT NULL,
+ -- JSON: AmountString[]
expected_output_per_coin TEXT NOT NULL,
+ -- JSON: Record<string, WalletRefreshGroupPerExchangeInfo>
info_per_exchange TEXT,
+ -- JSON: RefreshCoinStatus[]
status_per_coin TEXT NOT NULL,
+ -- JSON: ExchangeRefundRequest, keyed by index
refund_requests TEXT NOT NULL,
timestamp_created INTEGER NOT NULL,
+ -- JSON: TalerErrorDetail
fail_reason TEXT,
timestamp_finished INTEGER
);
@@ -647,6 +694,7 @@ CREATE INDEX IF NOT EXISTS refresh_groups_by_originating_transaction
CREATE TABLE IF NOT EXISTS denom_loss_events (
denom_loss_event_id TEXT PRIMARY KEY,
currency TEXT NOT NULL,
+ -- JSON: string[]
denom_pub_hashes TEXT NOT NULL,
status INTEGER NOT NULL,
timestamp_created INTEGER NOT NULL,
@@ -662,9 +710,11 @@ CREATE INDEX IF NOT EXISTS denom_loss_events_by_status
CREATE TABLE IF NOT EXISTS peer_push_debit (
purse_pub BLOB PRIMARY KEY,
exchange_base_url TEXT NOT NULL,
+ -- JSON: ScopeInfo
restrict_scope TEXT,
amount TEXT NOT NULL,
total_cost TEXT NOT NULL,
+ -- JSON: DbPeerPushPaymentCoinSelection
coin_sel TEXT,
contract_terms_hash BLOB NOT NULL,
purse_priv BLOB NOT NULL,
@@ -676,7 +726,9 @@ CREATE TABLE IF NOT EXISTS peer_push_debit (
purse_expiration INTEGER NOT NULL,
timestamp_created INTEGER NOT NULL,
abort_refresh_group_id TEXT,
+ -- JSON: TalerErrorDetail
abort_reason TEXT,
+ -- JSON: TalerErrorDetail
fail_reason TEXT,
status INTEGER NOT NULL
);
@@ -693,7 +745,9 @@ CREATE TABLE IF NOT EXISTS peer_push_credit (
estimated_amount_effective TEXT NOT NULL,
contract_terms_hash BLOB NOT NULL,
status INTEGER NOT NULL,
+ -- JSON: TalerErrorDetail
abort_reason TEXT,
+ -- JSON: TalerErrorDetail
fail_reason TEXT,
withdrawal_group_id TEXT,
currency TEXT,
@@ -725,8 +779,11 @@ CREATE TABLE IF NOT EXISTS peer_pull_debit (
status INTEGER NOT NULL,
total_cost_estimated TEXT NOT NULL,
abort_refresh_group_id TEXT,
+ -- JSON: TalerErrorDetail
abort_reason TEXT,
+ -- JSON: TalerErrorDetail
fail_reason TEXT,
+ -- JSON: PeerPullPaymentCoinSelection
coin_sel TEXT
);
CREATE INDEX IF NOT EXISTS peer_pull_debit_by_status
@@ -758,7 +815,9 @@ CREATE TABLE IF NOT EXISTS peer_pull_credit (
kyc_last_rule_gen INTEGER,
kyc_last_aml_review INTEGER,
kyc_last_deny INTEGER,
+ -- JSON: TalerErrorDetail
abort_reason TEXT,
+ -- JSON: TalerErrorDetail
fail_reason TEXT,
withdrawal_group_id TEXT
);
@@ -785,6 +844,7 @@ CREATE INDEX IF NOT EXISTS transactions_meta_by_status
CREATE TABLE IF NOT EXISTS exchanges (
base_url TEXT PRIMARY KEY,
preset_currency_hint TEXT,
+ -- JSON: CurrencySpecification
preset_currency_spec TEXT,
preset_type TEXT,
last_withdrawal INTEGER,
@@ -797,6 +857,7 @@ CREATE TABLE IF NOT EXISTS exchanges (
details_pointer_update_clock INTEGER,
entry_status INTEGER NOT NULL,
update_status INTEGER NOT NULL,
+ -- JSON: TalerErrorDetail
unavailable_reason TEXT,
cachebreak_next_update INTEGER,
tos_current_etag TEXT,
@@ -827,18 +888,26 @@ CREATE TABLE IF NOT EXISTS exchange_details (
exchange_base_url TEXT NOT NULL,
master_public_key BLOB NOT NULL,
currency TEXT NOT NULL,
+ -- JSON: ExchangeAuditor[]
auditors TEXT NOT NULL,
protocol_version_range TEXT NOT NULL,
tiny_amount TEXT NOT NULL,
+ -- JSON: TalerProtocolDuration
reserve_closing_delay TEXT NOT NULL,
shopping_url TEXT,
+ -- JSON: ExchangeGlobalFees[]
global_fees TEXT NOT NULL,
+ -- JSON: WireInfo
wire_info TEXT NOT NULL,
age_mask INTEGER,
+ -- JSON: AmountString[]
wallet_balance_limits TEXT,
+ -- JSON: AccountLimit[]
hard_limits TEXT,
+ -- JSON: ZeroLimitedOperation[]
zero_limits TEXT,
bank_compliance_language TEXT,
+ -- JSON: TalerProtocolDuration
default_peer_push_expiration TEXT
);
-- The pointer identifies at most one details row.
@@ -905,6 +974,7 @@ CREATE TABLE IF NOT EXISTS withdrawal_groups (
-- Promoted so the whole PeerPullCredit variant needs no JSON at all.
contract_priv BLOB,
bank_info TEXT,
+ -- JSON: WithdrawalExchangeAccountDetails[]
exchange_credit_accounts TEXT,
is_foreign_account INTEGER,
kyc_payto_hash BLOB,
@@ -914,6 +984,7 @@ CREATE TABLE IF NOT EXISTS withdrawal_groups (
kyc_last_rule_gen INTEGER,
kyc_last_aml_review INTEGER,
kyc_last_deny INTEGER,
+ -- JSON: TalerProtocolDuration
kyc_withdrawal_delay TEXT,
secret_seed BLOB NOT NULL,
reserve_pub BLOB NOT NULL,
@@ -927,8 +998,11 @@ CREATE TABLE IF NOT EXISTS withdrawal_groups (
reserve_balance_amount TEXT,
raw_withdrawal_amount TEXT,
effective_withdrawal_amount TEXT,
+ -- JSON: DenomSelectionState
denoms_sel TEXT,
+ -- JSON: TalerErrorDetail
abort_reason TEXT,
+ -- JSON: TalerErrorDetail
fail_reason TEXT,
-- Variant correctness lives here rather than in a side table: bank_info and
-- taler_withdraw_uri are present exactly for the bank-integrated variant.
@@ -952,12 +1026,15 @@ CREATE TABLE IF NOT EXISTS planchets (
withdrawal_group_id TEXT NOT NULL,
coin_idx INTEGER NOT NULL,
planchet_status INTEGER NOT NULL,
+ -- JSON: TalerErrorDetail
last_error TEXT,
denom_pub_hash BLOB NOT NULL,
blinding_key BLOB NOT NULL,
withdraw_sig BLOB NOT NULL,
+ -- JSON: CoinEnvelope
coin_ev TEXT NOT NULL,
coin_ev_hash BLOB NOT NULL,
+ -- JSON: AgeCommitmentProof
age_commitment_proof TEXT
);
CREATE UNIQUE INDEX IF NOT EXISTS planchets_by_group_and_index
@@ -970,6 +1047,7 @@ CREATE TABLE IF NOT EXISTS coins (
coin_priv BLOB NOT NULL,
exchange_base_url TEXT NOT NULL,
denom_pub_hash BLOB NOT NULL,
+ -- JSON: UnblindedDenominationSignature
denom_sig TEXT NOT NULL,
blinding_key BLOB NOT NULL,
coin_ev_hash BLOB NOT NULL,
@@ -981,7 +1059,9 @@ CREATE TABLE IF NOT EXISTS coins (
-- Absent for coins without age restriction; the record type spells this
-- as a required property that may hold undefined, so the mapper always
-- sets the key.
+ -- JSON: AgeCommitmentProof
age_commitment_proof TEXT,
+ -- JSON: WalletCoinSource
coin_source TEXT NOT NULL,
source_transaction_id TEXT
);
@@ -1016,6 +1096,7 @@ CREATE INDEX IF NOT EXISTS coin_availability_by_exchange_age_fresh
CREATE TABLE IF NOT EXISTS coin_history (
coin_pub BLOB PRIMARY KEY,
+ -- JSON: WalletCoinHistoryItem[]
history TEXT NOT NULL
);