commit 086341c341a466b12909ed2f55a3f5bd7db0c761
parent f96966800d0a788f1640111a12bb2baf6f779e1e
Author: Florian Dold <dold@taler.net>
Date: Mon, 20 Jul 2026 02:03:50 +0200
db: add enumeration accessors for every store
Some stores could only be read by key or by parent. Every store is now
reachable through a listAll* accessor, for the coming converter.
Diffstat:
4 files changed, 429 insertions(+), 0 deletions(-)
diff --git a/packages/taler-wallet-core/src/dbtx-conformance-cases.ts b/packages/taler-wallet-core/src/dbtx-conformance-cases.ts
@@ -35,8 +35,10 @@ import {
TransactionIdStr,
TalerProtocolTimestamp,
} from "@gnu-taler/taler-util";
+import { MailboxConfiguration } from "@gnu-taler/taler-util";
import {
ConfigRecordKey,
+ DonationReceiptStatus,
DbPreciseTimestamp,
DbProtocolTimestamp,
DenominationVerificationStatus,
@@ -1468,6 +1470,182 @@ export const conformanceCases: ConformanceCase[] = [
},
{
+ // The database converter enumerates every store through these accessors,
+ // so a listAll* that misses records means rows silently absent from the
+ // converted database. One case per accessor would repeat the seeding;
+ // this seeds one record per store and checks each enumeration sees it.
+ name: "listAll accessors enumerate every store",
+ async run(t, runner) {
+ await runner.runReadWriteTx(async (tx) => {
+ await tx.upsertConfig({
+ key: ConfigRecordKey.TestLoopTx,
+ value: 7,
+ });
+ await tx.upsertCurrencyInfoEntry({
+ scopeInfoStr: "taler-si:global/TESTKUDOS",
+ currencySpec: {
+ name: "Test",
+ num_fractional_input_digits: 2,
+ num_fractional_normal_digits: 2,
+ num_fractional_trailing_zero_digits: 2,
+ alt_unit_names: { "0": "TESTKUDOS" },
+ },
+ source: "exchange",
+ });
+ await tx.upsertContractTerms({
+ h: ckh("ct-la"),
+ contractTermsRaw: { summary: "listall" },
+ });
+ await tx.upsertTombstone({ id: "tmb:test:la" });
+ await tx.upsertOperationRetry({
+ id: "task-la",
+ retryInfo: {
+ firstTry: tsPrecise(1),
+ nextRetry: tsPrecise(2),
+ retryCounter: 1,
+ },
+ });
+ await tx.upsertReserve(makeReserve("res-la"));
+ await tx.upsertMailboxConfiguration({
+ mailboxBaseUrl: "https://mb.example/",
+ } as MailboxConfiguration);
+ await tx.upsertExchangeBaseUrlFixup({
+ exchangeBaseUrl: "https://old.example/",
+ replacement: "https://new.example/",
+ });
+ await tx.upsertExchangeMigrationLog({
+ oldExchangeBaseUrl: "https://old.example/",
+ newExchangeBaseUrl: "https://new.example/",
+ timestamp: tsPrecise(3),
+ reason: "auto" as ExchangeMigrationReason,
+ });
+ await tx.upsertSlate(makeSlate("slate-la", "prop-la", 0, 0, 0));
+ await tx.upsertRecoupGroup(makeRecoupGroup("rec-la", "https://e1/"));
+ await tx.upsertDonationPlanchet({
+ donauBaseUrl: "https://donau.example/",
+ udiNonce: ckh("udi-la"),
+ donorTaxIdHash: ckh("tid-la"),
+ donorHashSalt: "salt-la",
+ donorTaxId: "tax-la",
+ donationYear: 2026,
+ proposalId: "prop-la",
+ udiIndex: 0,
+ blindedUdi: { cipher: "RSA", rsa_blinded_identifier: "blind" },
+ bks: ck("bks-la"),
+ donationUnitPubHash: ckh("dup-la"),
+ value: amt("TESTKUDOS:1"),
+ });
+ await tx.upsertDonationReceipt({
+ status: DonationReceiptStatus.DoneSubmitted,
+ donauBaseUrl: "https://donau.example/",
+ udiNonce: ckh("udi-la"),
+ proposalId: "prop-la",
+ donationYear: 2026,
+ donationUnitPubHash: ckh("dup-la"),
+ donationUnitSig: { cipher: "RSA", rsa_signature: "sig" },
+ donorTaxIdHash: ckh("tid-la"),
+ donorHashSalt: "salt-la",
+ donorTaxId: "tax-la",
+ value: amt("TESTKUDOS:1"),
+ udiIndex: 0,
+ });
+ await seedDenomFamily(tx, "https://e1/", 61);
+ await tx.upsertDenomination(
+ makeDenomination("https://e1/", "den-la", { familySerial: 61 }),
+ );
+ });
+
+ // Each enumeration must contain the seeded record; where the store was
+ // empty before, the length pins that nothing else appeared.
+ const r = runner;
+ t.equal(
+ (await r.runReadWriteTx((tx) => tx.listAllConfig())).length,
+ 1,
+ "config",
+ );
+ const ci = await r.runReadWriteTx((tx) => tx.listAllCurrencyInfo());
+ t.equal(ci.length, 1, "currencyInfo");
+ t.equal(
+ ci[0].scopeInfoStr,
+ "taler-si:global/TESTKUDOS",
+ "the storage key must round-trip opaquely",
+ );
+ t.equal(
+ (await r.runReadWriteTx((tx) => tx.listAllContractTerms())).length,
+ 1,
+ "contractTerms",
+ );
+ t.equal(
+ (await r.runReadWriteTx((tx) => tx.listAllTombstones()))[0]?.id,
+ "tmb:test:la",
+ "tombstones",
+ );
+ t.equal(
+ (await r.runReadWriteTx((tx) => tx.listAllOperationRetries()))[0]?.id,
+ "task-la",
+ "operationRetries",
+ );
+ t.equal(
+ (await r.runReadWriteTx((tx) => tx.listAllReserves())).length,
+ 1,
+ "reserves",
+ );
+ t.equal(
+ (await r.runReadWriteTx((tx) => tx.listAllMailboxConfigurations()))
+ .length,
+ 1,
+ "mailboxConfigurations",
+ );
+ t.equal(
+ (await r.runReadWriteTx((tx) => tx.listAllExchangeBaseUrlFixups()))[0]
+ ?.replacement,
+ "https://new.example/",
+ "exchangeBaseUrlFixups",
+ );
+ t.equal(
+ (
+ await r.runReadWriteTx((tx) =>
+ tx.listAllExchangeMigrationLogEntries(),
+ )
+ ).length,
+ 1,
+ "exchangeBaseUrlMigrationLog",
+ );
+ t.equal(
+ (await r.runReadWriteTx((tx) => tx.listAllSlates())).length,
+ 1,
+ "slates",
+ );
+ t.equal(
+ (await r.runReadWriteTx((tx) => tx.listAllRecoupGroups())).length,
+ 1,
+ "recoupGroups",
+ );
+ t.equal(
+ (await r.runReadWriteTx((tx) => tx.listAllDonationPlanchets())).length,
+ 1,
+ "donationPlanchets",
+ );
+ t.equal(
+ (await r.runReadWriteTx((tx) => tx.listAllDonationReceipts())).length,
+ 1,
+ "donationReceipts",
+ );
+ t.equal(
+ (await r.runReadWriteTx((tx) => tx.listAllDenominationFamilies()))
+ .length,
+ 1,
+ "denominationFamilies",
+ );
+ t.equal(
+ (await r.runReadWriteTx((tx) => tx.listAllDenominations())).length,
+ 1,
+ "denominations",
+ );
+ },
+ },
+
+ {
// Parent-delete behaviour has to be identical on both backends. sqlite
// declares ON DELETE CASCADE, IndexedDB has no constraints and must do it
// by hand; without a case here the two silently disagree, and the sqlite
diff --git a/packages/taler-wallet-core/src/dbtx-indexeddb.ts b/packages/taler-wallet-core/src/dbtx-indexeddb.ts
@@ -89,6 +89,7 @@ import {
import type {} from "./db-indexeddb.js";
import { WalletIndexedDbTransaction } from "./db-indexeddb.js";
import type {
+ WalletCurrencyInfoEntry,
WalletDbRecordCounts,
GetCurrencyInfoDbResult,
StoreCurrencyInfoDbRequest,
@@ -147,6 +148,18 @@ export class IdbWalletTransaction implements WalletDbTransaction {
await tx.config.put(record);
}
+ async listAllConfig(): Promise<ConfigRecord[]> {
+ return await this.tx.config.iter().toArray();
+ }
+
+ async listAllCurrencyInfo(): Promise<WalletCurrencyInfoEntry[]> {
+ return await this.tx.currencyInfo.iter().toArray();
+ }
+
+ async upsertCurrencyInfoEntry(entry: WalletCurrencyInfoEntry): Promise<void> {
+ await this.tx.currencyInfo.put(entry);
+ }
+
async upsertCurrencyInfo(req: StoreCurrencyInfoDbRequest): Promise<void> {
const tx = this.tx;
await tx.currencyInfo.put({
@@ -220,6 +233,10 @@ export class IdbWalletTransaction implements WalletDbTransaction {
return await tx.mailboxMessages.getAll();
}
+ async listAllMailboxConfigurations(): Promise<MailboxConfiguration[]> {
+ return await this.tx.mailboxConfigurations.iter().toArray();
+ }
+
async getMailboxConfiguration(
mailboxBaseUrl: string,
): Promise<MailboxConfiguration | undefined> {
@@ -341,6 +358,9 @@ export class IdbWalletTransaction implements WalletDbTransaction {
retryInfo: rec.retryInfo,
});
}
+ async listAllOperationRetries(): Promise<WalletOperationRetry[]> {
+ return await this.tx.operationRetries.iter().toArray();
+ }
async deleteOperationRetry(taskId: string): Promise<void> {
const tx = this.tx;
@@ -684,6 +704,16 @@ export class IdbWalletTransaction implements WalletDbTransaction {
await tx.exchangeBaseUrlFixups.put(rec);
}
+ async listAllExchangeBaseUrlFixups(): Promise<WalletExchangeBaseUrlFixup[]> {
+ return await this.tx.exchangeBaseUrlFixups.iter().toArray();
+ }
+
+ async listAllExchangeMigrationLogEntries(): Promise<
+ WalletExchangeMigrationLog[]
+ > {
+ return await this.tx.exchangeBaseUrlMigrationLog.iter().toArray();
+ }
+
async getExchangeMigrationLog(
oldExchangeBaseUrl: string,
newExchangeBaseUrl: string,
@@ -965,11 +995,43 @@ export class IdbWalletTransaction implements WalletDbTransaction {
await tx.slates.delete(tokenUsePub);
}
+ async listAllSlates(): Promise<WalletSlate[]> {
+ return await this.tx.slates.iter().toArray();
+ }
+
+ async listAllRecoupGroups(): Promise<WalletRecoupGroup[]> {
+ return await this.tx.recoupGroups.iter().toArray();
+ }
+
+ async listAllDonationPlanchets(): Promise<WalletDonationPlanchet[]> {
+ return await this.tx.donationPlanchets.iter().toArray();
+ }
+
+ async listAllDonationReceipts(): Promise<WalletDonationReceipt[]> {
+ return await this.tx.donationReceipts.iter().toArray();
+ }
+
+ async listAllDenominationFamilies(): Promise<WalletDenominationFamily[]> {
+ return await this.tx.denominationFamilies.iter().toArray();
+ }
+
+ async listAllDenominations(): Promise<WalletDenomination[]> {
+ return await this.tx.denominations.iter().toArray();
+ }
+
+ async listAllContractTerms(): Promise<WalletContractTerms[]> {
+ return await this.tx.contractTerms.iter().toArray();
+ }
+
async upsertTombstone(rec: WalletTombstone): Promise<void> {
const tx = this.tx;
await tx.tombstones.put(rec);
}
+ async listAllTombstones(): Promise<WalletTombstone[]> {
+ return await this.tx.tombstones.iter().toArray();
+ }
+
async getDonationSummary(
donauBaseUrl: string,
year: number,
@@ -1208,6 +1270,10 @@ export class IdbWalletTransaction implements WalletDbTransaction {
return await tx.reserves.indexes.byReservePub.get(reservePub);
}
+ async listAllReserves(): Promise<WalletReserve[]> {
+ return await this.tx.reserves.iter().toArray();
+ }
+
async upsertReserve(rec: WalletReserve): Promise<number> {
const tx = this.tx;
const res = await tx.reserves.put(rec);
diff --git a/packages/taler-wallet-core/src/dbtx-sqlite.ts b/packages/taler-wallet-core/src/dbtx-sqlite.ts
@@ -57,6 +57,7 @@ import {
StoreCurrencyInfoDbRequest,
WalletDbRecordCounts,
WalletDbTransaction,
+ WalletCurrencyInfoEntry,
} from "./dbtx.js";
import {
ConfigRecord,
@@ -504,6 +505,35 @@ export class SqliteWalletTransaction implements WalletDbTransaction {
return dbToJson(row.value);
}
+ async listAllConfig(): Promise<ConfigRecord[]> {
+ const rows = await this.all("SELECT value FROM config");
+ return rows.map((r) => dbToJson<ConfigRecord>(r.value));
+ }
+
+ async listAllCurrencyInfo(): Promise<WalletCurrencyInfoEntry[]> {
+ const rows = await this.all("SELECT * FROM currency_info");
+ return rows.map((r) => ({
+ scopeInfoStr: str(r.scope_info_str),
+ currencySpec: dbToJson(r.currency_spec),
+ source: str(r.source) as WalletCurrencyInfoEntry["source"],
+ }));
+ }
+
+ async upsertCurrencyInfoEntry(entry: WalletCurrencyInfoEntry): Promise<void> {
+ await this.run(
+ "INSERT INTO currency_info (scope_info_str, currency_spec, source)" +
+ " VALUES ($s, $spec, $src)" +
+ " ON CONFLICT(scope_info_str) DO UPDATE SET" +
+ " currency_spec = excluded.currency_spec," +
+ " source = excluded.source",
+ {
+ s: entry.scopeInfoStr,
+ spec: jsonToDb(entry.currencySpec),
+ src: entry.source,
+ },
+ );
+ }
+
async upsertConfig(record: ConfigRecord): Promise<void> {
await this.run(
"INSERT INTO config (key, value) VALUES ($key, $value)" +
@@ -545,6 +575,11 @@ export class SqliteWalletTransaction implements WalletDbTransaction {
});
}
+ async listAllTombstones(): Promise<WalletTombstone[]> {
+ const rows = await this.all("SELECT id FROM tombstones");
+ return rows.map((r) => ({ id: str(r.id) }));
+ }
+
// --------------------------------------------------- operation retries
async getOperationRetry(
@@ -577,6 +612,17 @@ export class SqliteWalletTransaction implements WalletDbTransaction {
);
}
+ async listAllOperationRetries(): Promise<WalletOperationRetry[]> {
+ const rows = await this.all(
+ "SELECT id, last_error, retry_info FROM operation_retries",
+ );
+ return rows.map((r) => ({
+ id: str(r.id),
+ lastError: dbToOptJson(r.last_error),
+ retryInfo: dbToJson(r.retry_info),
+ }));
+ }
+
async deleteOperationRetry(taskId: string): Promise<void> {
await this.run("DELETE FROM operation_retries WHERE id = $id", {
id: taskId,
@@ -647,6 +693,11 @@ export class SqliteWalletTransaction implements WalletDbTransaction {
return row ? this.rowToReserve(row) : undefined;
}
+ async listAllReserves(): Promise<WalletReserve[]> {
+ const rows = await this.all("SELECT * FROM reserves");
+ return rows.map((r) => this.rowToReserve(r));
+ }
+
private rowToReserve(row: ResultRow): WalletReserve {
return {
rowId: num(row.row_id),
@@ -854,6 +905,21 @@ export class SqliteWalletTransaction implements WalletDbTransaction {
}
}
+ async listAllDenominations(): Promise<WalletDenomination[]> {
+ const rows = await this.all("SELECT * FROM denominations");
+ return rows.map((r) => this.rowToDenomination(r));
+ }
+
+ async listAllContractTerms(): Promise<WalletContractTerms[]> {
+ const rows = await this.all(
+ "SELECT h, contract_terms_raw FROM contract_terms",
+ );
+ return rows.map((r) => ({
+ h: str(r.h),
+ contractTermsRaw: dbToJson(r.contract_terms_raw),
+ }));
+ }
+
private rowToDenomination(row: ResultRow): WalletDenomination {
const denom: WalletDenomination = {
exchangeBaseUrl: str(row.exchange_base_url),
@@ -1755,6 +1821,11 @@ export class SqliteWalletTransaction implements WalletDbTransaction {
// ----------------------------------------------- denomination families
+ async listAllDenominationFamilies(): Promise<WalletDenominationFamily[]> {
+ const rows = await this.all("SELECT * FROM denomination_families");
+ return rows.map((r) => this.rowToDenominationFamily(r));
+ }
+
private rowToDenominationFamily(row: ResultRow): WalletDenominationFamily {
return {
denominationFamilySerial: num(row.denomination_family_serial),
@@ -1882,6 +1953,14 @@ export class SqliteWalletTransaction implements WalletDbTransaction {
);
}
+ async listAllExchangeBaseUrlFixups(): Promise<WalletExchangeBaseUrlFixup[]> {
+ const rows = await this.all("SELECT * FROM exchange_base_url_fixups");
+ return rows.map((r) => ({
+ exchangeBaseUrl: str(r.exchange_base_url),
+ replacement: str(r.replacement),
+ }));
+ }
+
async getExchangeMigrationLog(
oldExchangeBaseUrl: string,
newExchangeBaseUrl: string,
@@ -1902,6 +1981,20 @@ export class SqliteWalletTransaction implements WalletDbTransaction {
};
}
+ async listAllExchangeMigrationLogEntries(): Promise<
+ WalletExchangeMigrationLog[]
+ > {
+ const rows = await this.all(
+ "SELECT * FROM exchange_base_url_migration_log",
+ );
+ return rows.map((r) => ({
+ oldExchangeBaseUrl: str(r.old_exchange_base_url),
+ newExchangeBaseUrl: str(r.new_exchange_base_url),
+ timestamp: dbTimestamp(r.timestamp),
+ reason: str(r.reason) as ExchangeMigrationReason,
+ }));
+ }
+
async upsertExchangeMigrationLog(
rec: WalletExchangeMigrationLog,
): Promise<void> {
@@ -3868,6 +3961,16 @@ export class SqliteWalletTransaction implements WalletDbTransaction {
return num(row?.n);
}
+ async listAllDonationPlanchets(): Promise<WalletDonationPlanchet[]> {
+ const rows = await this.all("SELECT * FROM donation_planchets");
+ return rows.map((r) => this.rowToDonationPlanchet(r));
+ }
+
+ async listAllDonationReceipts(): Promise<WalletDonationReceipt[]> {
+ const rows = await this.all("SELECT * FROM donation_receipts");
+ return rows.map((r) => this.rowToDonationReceipt(r));
+ }
+
private rowToDonationReceipt(row: ResultRow): WalletDonationReceipt {
return {
udiNonce: dbToCrock(row.udi_nonce),
@@ -4090,6 +4193,11 @@ export class SqliteWalletTransaction implements WalletDbTransaction {
}));
}
+ async listAllMailboxConfigurations(): Promise<MailboxConfiguration[]> {
+ const rows = await this.all("SELECT payload FROM mailbox_configurations");
+ return rows.map((r) => dbToJson<MailboxConfiguration>(r.payload));
+ }
+
async getMailboxConfiguration(
mailboxBaseUrl: string,
): Promise<MailboxConfiguration | undefined> {
@@ -4479,6 +4587,11 @@ export class SqliteWalletTransaction implements WalletDbTransaction {
};
}
+ async listAllSlates(): Promise<WalletSlate[]> {
+ const rows = await this.all("SELECT * FROM slates");
+ return rows.map((r) => this.rowToSlate(r));
+ }
+
async getSlate(
purchaseId: string,
choiceIndex: number,
@@ -4673,6 +4786,11 @@ export class SqliteWalletTransaction implements WalletDbTransaction {
};
}
+ async listAllRecoupGroups(): Promise<WalletRecoupGroup[]> {
+ const rows = await this.all("SELECT * FROM recoup_groups");
+ return rows.map((r) => this.rowToRecoupGroup(r));
+ }
+
async getRecoupGroup(
recoupGroupId: string,
): Promise<WalletRecoupGroup | undefined> {
diff --git a/packages/taler-wallet-core/src/dbtx.ts b/packages/taler-wallet-core/src/dbtx.ts
@@ -85,6 +85,20 @@ import {
WalletBankAccount,
WalletExchangeDetails,
} from "./db-common.js";
+/**
+ * A currency info record with its storage key.
+ *
+ * The scope string is kept opaque: stringifyScopeInfo has no exact inverse
+ * (parseScopeInfoShort reads a different format), so anything that needs to
+ * enumerate and re-store these records -- the database converter -- must
+ * round-trip the key without interpreting it.
+ */
+export interface WalletCurrencyInfoEntry {
+ scopeInfoStr: string;
+ currencySpec: CurrencySpecification;
+ source: "exchange" | "user" | "preset";
+}
+
export interface GetCurrencyInfoDbResult {
/**
* Currency specification.
@@ -133,6 +147,9 @@ export interface WalletDbTransaction {
/** Create or update a config record. */
upsertConfig(record: ConfigRecord): Promise<void>;
+ /** List every config record. */
+ listAllConfig(): Promise<ConfigRecord[]>;
+
/**
* Store currency info for a scope.
*
@@ -140,6 +157,17 @@ export interface WalletDbTransaction {
*/
upsertCurrencyInfo(req: StoreCurrencyInfoDbRequest): Promise<void>;
+ /** List every currency info record with its storage key. */
+ listAllCurrencyInfo(): Promise<WalletCurrencyInfoEntry[]>;
+
+ /**
+ * Store a currency info record under an existing storage key.
+ *
+ * For the converter; regular code uses upsertCurrencyInfo, which derives
+ * the key from a ScopeInfo.
+ */
+ upsertCurrencyInfoEntry(entry: WalletCurrencyInfoEntry): Promise<void>;
+
/** Store currency info for a scope, keeping any existing entry. */
insertCurrencyInfoUnlessExists(
req: StoreCurrencyInfoDbRequest,
@@ -174,6 +202,9 @@ export interface WalletDbTransaction {
/** Create or update a mailbox configuration. */
upsertMailboxConfiguration(mailboxConf: MailboxConfiguration): Promise<void>;
+ /** List every mailbox configuration. */
+ listAllMailboxConfigurations(): Promise<MailboxConfiguration[]>;
+
/** Get a purchase by proposal ID. */
getPurchase(proposalId: string): Promise<WalletPurchase | undefined>;
@@ -259,6 +290,9 @@ export interface WalletDbTransaction {
*/
upsertOperationRetry(rec: WalletOperationRetry): Promise<void>;
+ /** List the retry state of every task that has one. */
+ listAllOperationRetries(): Promise<WalletOperationRetry[]>;
+
/**
* Clear the retry state of a task.
*/
@@ -461,6 +495,9 @@ export interface WalletDbTransaction {
/** Record that an exchange base URL should be replaced. */
upsertExchangeBaseUrlFixup(rec: WalletExchangeBaseUrlFixup): Promise<void>;
+ /** List every pending base-URL fixup. */
+ listAllExchangeBaseUrlFixups(): Promise<WalletExchangeBaseUrlFixup[]>;
+
/** Get the log entry for a base-URL migration, if it has run. */
getExchangeMigrationLog(
oldExchangeBaseUrl: string,
@@ -470,6 +507,9 @@ export interface WalletDbTransaction {
/** Record that a base-URL migration has run. */
upsertExchangeMigrationLog(rec: WalletExchangeMigrationLog): Promise<void>;
+ /** List every base-URL migration log entry. */
+ listAllExchangeMigrationLogEntries(): Promise<WalletExchangeMigrationLog[]>;
+
/** Get exchange details by the (baseUrl, currency, masterPub) pointer. */
getExchangeDetailsByPointer(
exchangeBaseUrl: string,
@@ -621,6 +661,9 @@ export interface WalletDbTransaction {
/** Record a tombstone, marking a deleted transaction as not to be revived. */
upsertTombstone(rec: WalletTombstone): Promise<void>;
+ /** List every tombstone. */
+ listAllTombstones(): Promise<WalletTombstone[]>;
+
/** Get the donation summary for a donau, year and currency. */
getDonationSummary(
donauBaseUrl: string,
@@ -820,6 +863,9 @@ export interface WalletDbTransaction {
*/
listTokens(): Promise<WalletToken[]>;
+ /** List every slate. */
+ listAllSlates(): Promise<WalletSlate[]>;
+
/**
* Get a wallet token by its token use public key.
*/
@@ -970,6 +1016,27 @@ export interface WalletDbTransaction {
/** List all coin availability records. */
getCoinAvailabilities(): Promise<WalletCoinAvailability[]>;
+ /** List every reserve. */
+ listAllReserves(): Promise<WalletReserve[]>;
+
+ /** List every recoup group. */
+ listAllRecoupGroups(): Promise<WalletRecoupGroup[]>;
+
+ /** List every donation planchet. */
+ listAllDonationPlanchets(): Promise<WalletDonationPlanchet[]>;
+
+ /** List every donation receipt. */
+ listAllDonationReceipts(): Promise<WalletDonationReceipt[]>;
+
+ /** List every denomination family. */
+ listAllDenominationFamilies(): Promise<WalletDenominationFamily[]>;
+
+ /** List every denomination. */
+ listAllDenominations(): Promise<WalletDenomination[]>;
+
+ /** List every stored contract-terms record. */
+ listAllContractTerms(): Promise<WalletContractTerms[]>;
+
/** Get refresh groups in a non-final state. */
getActiveRefreshGroups(): Promise<WalletRefreshGroup[]>;