add UIDs for deletion tombstones to auditor/exchange trust management
This commit is contained in:
parent
0299e719ce
commit
851ac5602c
@ -933,3 +933,16 @@ export const codecForWithdrawUriInfoResponse = (): Codec<WithdrawUriInfoResponse
|
|||||||
.property("defaultExchangeBaseUrl", codecOptional(codecForString()))
|
.property("defaultExchangeBaseUrl", codecOptional(codecForString()))
|
||||||
.property("possibleExchanges", codecForList(codecForExchangeListItem()))
|
.property("possibleExchanges", codecForList(codecForExchangeListItem()))
|
||||||
.build("WithdrawUriInfoResponse");
|
.build("WithdrawUriInfoResponse");
|
||||||
|
|
||||||
|
export interface WalletCurrencyInfo {
|
||||||
|
trustedAuditors: {
|
||||||
|
currency: string;
|
||||||
|
auditorPub: string;
|
||||||
|
auditorBaseUrl: string;
|
||||||
|
}[];
|
||||||
|
trustedExchanges: {
|
||||||
|
currency: string;
|
||||||
|
exchangeMasterPub: string;
|
||||||
|
exchangeBaseUrl: string;
|
||||||
|
}[];
|
||||||
|
}
|
@ -357,7 +357,12 @@ export interface AuditorRecord {
|
|||||||
expirationStamp: number;
|
expirationStamp: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AuditorTrustInfo {
|
export interface AuditorTrustRecord {
|
||||||
|
/**
|
||||||
|
* Currency that we trust this auditor for.
|
||||||
|
*/
|
||||||
|
currency: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base URL of the auditor.
|
* Base URL of the auditor.
|
||||||
*/
|
*/
|
||||||
@ -375,7 +380,12 @@ export interface AuditorTrustInfo {
|
|||||||
uids: string[];
|
uids: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ExchangeTrustInfo {
|
export interface ExchangeTrustRecord {
|
||||||
|
/**
|
||||||
|
* Currency that we trust this exchange for.
|
||||||
|
*/
|
||||||
|
currency: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Canonicalized exchange base URL.
|
* Canonicalized exchange base URL.
|
||||||
*/
|
*/
|
||||||
@ -393,31 +403,6 @@ export interface ExchangeTrustInfo {
|
|||||||
uids: string[];
|
uids: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Information about a currency as displayed in the wallet's database.
|
|
||||||
*/
|
|
||||||
export interface CurrencyRecord {
|
|
||||||
/**
|
|
||||||
* Name of the currency.
|
|
||||||
*/
|
|
||||||
name: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Number of fractional digits to show when rendering the currency.
|
|
||||||
*/
|
|
||||||
fractionalDigits: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Auditors that the wallet trusts for this currency.
|
|
||||||
*/
|
|
||||||
auditors: AuditorTrustInfo[];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Exchanges that the wallet trusts for this currency.
|
|
||||||
*/
|
|
||||||
exchanges: ExchangeTrustInfo[];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Status of a denomination.
|
* Status of a denomination.
|
||||||
*/
|
*/
|
||||||
@ -1775,10 +1760,44 @@ class DenominationsStore extends Store<"denominations", DenominationRecord> {
|
|||||||
>(this, "exchangeBaseUrlIndex", "exchangeBaseUrl");
|
>(this, "exchangeBaseUrlIndex", "exchangeBaseUrl");
|
||||||
}
|
}
|
||||||
|
|
||||||
class CurrenciesStore extends Store<"currencies", CurrencyRecord> {
|
class AuditorTrustStore extends Store<"auditorTrust", AuditorTrustRecord> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("currencies", { keyPath: "name" });
|
super("auditorTrust", {
|
||||||
|
keyPath: ["currency", "auditorBaseUrl", "auditorPub"],
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
auditorPubIndex = new Index<
|
||||||
|
"auditorTrust",
|
||||||
|
"auditorPubIndex",
|
||||||
|
string,
|
||||||
|
AuditorTrustRecord
|
||||||
|
>(this, "auditorPubIndex", "auditorPub");
|
||||||
|
uidIndex = new Index<"auditorTrust", "uidIndex", string, AuditorTrustRecord>(
|
||||||
|
this,
|
||||||
|
"uidIndex",
|
||||||
|
"uids",
|
||||||
|
{ multiEntry: true },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ExchangeTrustStore extends Store<"exchangeTrust", ExchangeTrustRecord> {
|
||||||
|
constructor() {
|
||||||
|
super("exchangeTrust", {
|
||||||
|
keyPath: ["currency", "exchangeBaseUrl", "exchangePub"],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
exchangeMasterPubIndex = new Index<
|
||||||
|
"exchangeTrust",
|
||||||
|
"exchangeMasterPubIndex",
|
||||||
|
string,
|
||||||
|
ExchangeTrustRecord
|
||||||
|
>(this, "exchangeMasterPubIndex", "exchangePub");
|
||||||
|
uidIndex = new Index<
|
||||||
|
"exchangeTrust",
|
||||||
|
"uidIndex",
|
||||||
|
string,
|
||||||
|
ExchangeTrustRecord
|
||||||
|
>(this, "uidIndex", "uids", { multiEntry: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
class ConfigStore extends Store<"config", ConfigRecord<any>> {
|
class ConfigStore extends Store<"config", ConfigRecord<any>> {
|
||||||
@ -1891,7 +1910,8 @@ class TombstonesStore extends Store<"tombstones", TombstoneRecord> {
|
|||||||
export const Stores = {
|
export const Stores = {
|
||||||
coins: new CoinsStore(),
|
coins: new CoinsStore(),
|
||||||
config: new ConfigStore(),
|
config: new ConfigStore(),
|
||||||
currencies: new CurrenciesStore(),
|
auditorTrustStore: new AuditorTrustStore(),
|
||||||
|
exchangeTrustStore: new ExchangeTrustStore(),
|
||||||
denominations: new DenominationsStore(),
|
denominations: new DenominationsStore(),
|
||||||
exchanges: new ExchangesStore(),
|
exchanges: new ExchangesStore(),
|
||||||
proposals: new ProposalsStore(),
|
proposals: new ProposalsStore(),
|
||||||
|
68
packages/taler-wallet-core/src/operations/currencies.ts
Normal file
68
packages/taler-wallet-core/src/operations/currencies.ts
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
This file is part of GNU Taler
|
||||||
|
(C) 2021 Taler Systems S.A.
|
||||||
|
|
||||||
|
GNU Taler is free software; you can redistribute it and/or modify it under the
|
||||||
|
terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 3, or (at your option) any later version.
|
||||||
|
|
||||||
|
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Imports.
|
||||||
|
*/
|
||||||
|
import { ExchangeRecord, Stores } from "../db.js";
|
||||||
|
import { Logger } from "../index.js";
|
||||||
|
import { InternalWalletState } from "./state.js";
|
||||||
|
|
||||||
|
const logger = new Logger("currencies.ts");
|
||||||
|
|
||||||
|
export interface TrustInfo {
|
||||||
|
isTrusted: boolean;
|
||||||
|
isAudited: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if and how an exchange is trusted and/or audited.
|
||||||
|
*/
|
||||||
|
export async function getExchangeTrust(
|
||||||
|
ws: InternalWalletState,
|
||||||
|
exchangeInfo: ExchangeRecord,
|
||||||
|
): Promise<TrustInfo> {
|
||||||
|
let isTrusted = false;
|
||||||
|
let isAudited = false;
|
||||||
|
const exchangeDetails = exchangeInfo.details;
|
||||||
|
if (!exchangeDetails) {
|
||||||
|
throw Error(`exchange ${exchangeInfo.baseUrl} details not available`);
|
||||||
|
}
|
||||||
|
const exchangeTrustRecord = await ws.db.getIndexed(
|
||||||
|
Stores.exchangeTrustStore.exchangeMasterPubIndex,
|
||||||
|
exchangeDetails.masterPublicKey,
|
||||||
|
);
|
||||||
|
if (
|
||||||
|
exchangeTrustRecord &&
|
||||||
|
exchangeTrustRecord.uids.length > 0 &&
|
||||||
|
exchangeTrustRecord.currency === exchangeDetails.currency
|
||||||
|
) {
|
||||||
|
isTrusted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auditor of exchangeDetails.auditors) {
|
||||||
|
const auditorTrustRecord = await ws.db.getIndexed(
|
||||||
|
Stores.auditorTrustStore.auditorPubIndex,
|
||||||
|
auditor.auditor_pub,
|
||||||
|
);
|
||||||
|
if (auditorTrustRecord && auditorTrustRecord.uids.length > 0) {
|
||||||
|
isAudited = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { isTrusted, isAudited };
|
||||||
|
}
|
@ -527,43 +527,6 @@ async function updateExchangeFromUrlImpl(
|
|||||||
return updatedExchange;
|
return updatedExchange;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if and how an exchange is trusted and/or audited.
|
|
||||||
*/
|
|
||||||
export async function getExchangeTrust(
|
|
||||||
ws: InternalWalletState,
|
|
||||||
exchangeInfo: ExchangeRecord,
|
|
||||||
): Promise<{ isTrusted: boolean; isAudited: boolean }> {
|
|
||||||
let isTrusted = false;
|
|
||||||
let isAudited = false;
|
|
||||||
const exchangeDetails = exchangeInfo.details;
|
|
||||||
if (!exchangeDetails) {
|
|
||||||
throw Error(`exchange ${exchangeInfo.baseUrl} details not available`);
|
|
||||||
}
|
|
||||||
const currencyRecord = await ws.db.get(
|
|
||||||
Stores.currencies,
|
|
||||||
exchangeDetails.currency,
|
|
||||||
);
|
|
||||||
if (currencyRecord) {
|
|
||||||
for (const trustedExchange of currencyRecord.exchanges) {
|
|
||||||
if (
|
|
||||||
trustedExchange.exchangeMasterPub === exchangeDetails.masterPublicKey
|
|
||||||
) {
|
|
||||||
isTrusted = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const trustedAuditor of currencyRecord.auditors) {
|
|
||||||
for (const exchangeAuditor of exchangeDetails.auditors) {
|
|
||||||
if (trustedAuditor.auditorPub === exchangeAuditor.auditor_pub) {
|
|
||||||
isAudited = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return { isTrusted, isAudited };
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getExchangePaytoUri(
|
export async function getExchangePaytoUri(
|
||||||
ws: InternalWalletState,
|
ws: InternalWalletState,
|
||||||
|
@ -38,7 +38,6 @@ import {
|
|||||||
ReserveRecordStatus,
|
ReserveRecordStatus,
|
||||||
ReserveBankInfo,
|
ReserveBankInfo,
|
||||||
ReserveRecord,
|
ReserveRecord,
|
||||||
CurrencyRecord,
|
|
||||||
WithdrawalGroupRecord,
|
WithdrawalGroupRecord,
|
||||||
} from "../db.js";
|
} from "../db.js";
|
||||||
import {
|
import {
|
||||||
@ -158,31 +157,9 @@ export async function createReserve(
|
|||||||
throw Error("exchange not updated");
|
throw Error("exchange not updated");
|
||||||
}
|
}
|
||||||
const { isAudited, isTrusted } = await getExchangeTrust(ws, exchangeInfo);
|
const { isAudited, isTrusted } = await getExchangeTrust(ws, exchangeInfo);
|
||||||
let currencyRecord = await ws.db.get(
|
|
||||||
Stores.currencies,
|
|
||||||
exchangeDetails.currency,
|
|
||||||
);
|
|
||||||
if (!currencyRecord) {
|
|
||||||
currencyRecord = {
|
|
||||||
auditors: [],
|
|
||||||
exchanges: [],
|
|
||||||
fractionalDigits: 2,
|
|
||||||
name: exchangeDetails.currency,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isAudited && !isTrusted) {
|
|
||||||
currencyRecord.exchanges.push({
|
|
||||||
exchangeBaseUrl: req.exchange,
|
|
||||||
exchangeMasterPub: exchangeDetails.masterPublicKey,
|
|
||||||
uids: [encodeCrock(getRandomBytes(32))],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const cr: CurrencyRecord = currencyRecord;
|
|
||||||
|
|
||||||
const resp = await ws.db.runWithWriteTransaction(
|
const resp = await ws.db.runWithWriteTransaction(
|
||||||
[Stores.currencies, Stores.reserves, Stores.bankWithdrawUris],
|
[Stores.exchangeTrustStore, Stores.reserves, Stores.bankWithdrawUris],
|
||||||
async (tx) => {
|
async (tx) => {
|
||||||
// Check if we have already created a reserve for that bankWithdrawStatusUrl
|
// Check if we have already created a reserve for that bankWithdrawStatusUrl
|
||||||
if (reserveRecord.bankInfo?.statusUrl) {
|
if (reserveRecord.bankInfo?.statusUrl) {
|
||||||
@ -207,7 +184,14 @@ export async function createReserve(
|
|||||||
talerWithdrawUri: reserveRecord.bankInfo.statusUrl,
|
talerWithdrawUri: reserveRecord.bankInfo.statusUrl,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
await tx.put(Stores.currencies, cr);
|
if (!isAudited && !isAudited) {
|
||||||
|
await tx.put(Stores.exchangeTrustStore, {
|
||||||
|
currency: reserveRecord.currency,
|
||||||
|
exchangeBaseUrl: reserveRecord.exchangeBaseUrl,
|
||||||
|
exchangeMasterPub: exchangeDetails.masterPublicKey,
|
||||||
|
uids: [encodeCrock(getRandomBytes(32))],
|
||||||
|
});
|
||||||
|
}
|
||||||
await tx.put(Stores.reserves, reserveRecord);
|
await tx.put(Stores.reserves, reserveRecord);
|
||||||
const r: CreateReserveResponse = {
|
const r: CreateReserveResponse = {
|
||||||
exchange: canonExchange,
|
exchange: canonExchange,
|
||||||
|
@ -82,7 +82,6 @@ export async function getTransactions(
|
|||||||
|
|
||||||
await ws.db.runWithReadTransaction(
|
await ws.db.runWithReadTransaction(
|
||||||
[
|
[
|
||||||
Stores.currencies,
|
|
||||||
Stores.coins,
|
Stores.coins,
|
||||||
Stores.denominations,
|
Stores.denominations,
|
||||||
Stores.exchanges,
|
Stores.exchanges,
|
||||||
|
@ -51,7 +51,7 @@ import {
|
|||||||
} from "@gnu-taler/taler-util";
|
} from "@gnu-taler/taler-util";
|
||||||
import { InternalWalletState } from "./state";
|
import { InternalWalletState } from "./state";
|
||||||
import { Logger } from "../util/logging";
|
import { Logger } from "../util/logging";
|
||||||
import { updateExchangeFromUrl, getExchangeTrust } from "./exchanges";
|
import { updateExchangeFromUrl } from "./exchanges";
|
||||||
import {
|
import {
|
||||||
WALLET_EXCHANGE_PROTOCOL_VERSION,
|
WALLET_EXCHANGE_PROTOCOL_VERSION,
|
||||||
WALLET_BANK_INTEGRATION_PROTOCOL_VERSION,
|
WALLET_BANK_INTEGRATION_PROTOCOL_VERSION,
|
||||||
@ -76,6 +76,7 @@ import { TalerErrorCode } from "@gnu-taler/taler-util";
|
|||||||
import { updateRetryInfoTimeout, initRetryInfo } from "../util/retries";
|
import { updateRetryInfoTimeout, initRetryInfo } from "../util/retries";
|
||||||
import { compare } from "@gnu-taler/taler-util";
|
import { compare } from "@gnu-taler/taler-util";
|
||||||
import { walletCoreDebugFlags } from "../util/debugFlags.js";
|
import { walletCoreDebugFlags } from "../util/debugFlags.js";
|
||||||
|
import { getExchangeTrust } from "./currencies.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logger for this file.
|
* Logger for this file.
|
||||||
@ -882,14 +883,6 @@ export async function getExchangeWithdrawalInfo(
|
|||||||
.iterIndex(Stores.denominations.exchangeBaseUrlIndex, baseUrl)
|
.iterIndex(Stores.denominations.exchangeBaseUrlIndex, baseUrl)
|
||||||
.filter((d) => d.isOffered);
|
.filter((d) => d.isOffered);
|
||||||
|
|
||||||
const trustedAuditorPubs = [];
|
|
||||||
const currencyRecord = await ws.db.get(Stores.currencies, amount.currency);
|
|
||||||
if (currencyRecord) {
|
|
||||||
trustedAuditorPubs.push(
|
|
||||||
...currencyRecord.auditors.map((a) => a.auditorPub),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let versionMatch;
|
let versionMatch;
|
||||||
if (exchangeDetails.protocolVersion) {
|
if (exchangeDetails.protocolVersion) {
|
||||||
versionMatch = LibtoolVersion.compare(
|
versionMatch = LibtoolVersion.compare(
|
||||||
@ -935,7 +928,8 @@ export async function getExchangeWithdrawalInfo(
|
|||||||
numOfferedDenoms: possibleDenoms.length,
|
numOfferedDenoms: possibleDenoms.length,
|
||||||
overhead: Amounts.sub(amount, selectedDenoms.totalWithdrawCost).amount,
|
overhead: Amounts.sub(amount, selectedDenoms.totalWithdrawCost).amount,
|
||||||
selectedDenoms,
|
selectedDenoms,
|
||||||
trustedAuditorPubs,
|
// FIXME: delete this field / replace by something we can display to the user
|
||||||
|
trustedAuditorPubs: [],
|
||||||
versionMatch,
|
versionMatch,
|
||||||
walletVersion: WALLET_EXCHANGE_PROTOCOL_VERSION,
|
walletVersion: WALLET_EXCHANGE_PROTOCOL_VERSION,
|
||||||
wireFees: exchangeWireInfo,
|
wireFees: exchangeWireInfo,
|
||||||
|
@ -26,6 +26,7 @@ import {
|
|||||||
BackupRecovery,
|
BackupRecovery,
|
||||||
codecForAny,
|
codecForAny,
|
||||||
TalerErrorCode,
|
TalerErrorCode,
|
||||||
|
WalletCurrencyInfo,
|
||||||
} from "@gnu-taler/taler-util";
|
} from "@gnu-taler/taler-util";
|
||||||
import { CryptoWorkerFactory } from "./crypto/workers/cryptoApi";
|
import { CryptoWorkerFactory } from "./crypto/workers/cryptoApi";
|
||||||
import {
|
import {
|
||||||
@ -56,7 +57,6 @@ import {
|
|||||||
import {
|
import {
|
||||||
acceptExchangeTermsOfService,
|
acceptExchangeTermsOfService,
|
||||||
getExchangePaytoUri,
|
getExchangePaytoUri,
|
||||||
getExchangeTrust,
|
|
||||||
updateExchangeFromUrl,
|
updateExchangeFromUrl,
|
||||||
} from "./operations/exchanges";
|
} from "./operations/exchanges";
|
||||||
import {
|
import {
|
||||||
@ -99,9 +99,9 @@ import {
|
|||||||
processWithdrawGroup,
|
processWithdrawGroup,
|
||||||
} from "./operations/withdraw";
|
} from "./operations/withdraw";
|
||||||
import {
|
import {
|
||||||
|
AuditorTrustRecord,
|
||||||
CoinRecord,
|
CoinRecord,
|
||||||
CoinSourceType,
|
CoinSourceType,
|
||||||
CurrencyRecord,
|
|
||||||
DenominationRecord,
|
DenominationRecord,
|
||||||
ExchangeRecord,
|
ExchangeRecord,
|
||||||
PurchaseRecord,
|
PurchaseRecord,
|
||||||
@ -179,20 +179,15 @@ import { AsyncCondition } from "./util/promiseUtils";
|
|||||||
import { Database } from "./util/query";
|
import { Database } from "./util/query";
|
||||||
import { Duration, durationMin } from "@gnu-taler/taler-util";
|
import { Duration, durationMin } from "@gnu-taler/taler-util";
|
||||||
import { TimerGroup } from "./util/timer";
|
import { TimerGroup } from "./util/timer";
|
||||||
|
import { getExchangeTrust } from "./operations/currencies.js";
|
||||||
|
|
||||||
const builtinCurrencies: CurrencyRecord[] = [
|
const builtinAuditors: AuditorTrustRecord[] = [
|
||||||
{
|
|
||||||
auditors: [
|
|
||||||
{
|
{
|
||||||
|
currency: "KUDOS",
|
||||||
auditorPub: "BW9DC48PHQY4NH011SHHX36DZZ3Q22Y6X7FZ1VD1CMZ2PTFZ6PN0",
|
auditorPub: "BW9DC48PHQY4NH011SHHX36DZZ3Q22Y6X7FZ1VD1CMZ2PTFZ6PN0",
|
||||||
auditorBaseUrl: "https://auditor.demo.taler.net/",
|
auditorBaseUrl: "https://auditor.demo.taler.net/",
|
||||||
uids: ["5P25XF8TVQP9AW6VYGY2KV47WT5Y3ZXFSJAA570GJPX5SVJXKBVG"],
|
uids: ["5P25XF8TVQP9AW6VYGY2KV47WT5Y3ZXFSJAA570GJPX5SVJXKBVG"],
|
||||||
},
|
},
|
||||||
],
|
|
||||||
exchanges: [],
|
|
||||||
fractionalDigits: 2,
|
|
||||||
name: "KUDOS",
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const logger = new Logger("wallet.ts");
|
const logger = new Logger("wallet.ts");
|
||||||
@ -484,7 +479,7 @@ export class Wallet {
|
|||||||
*/
|
*/
|
||||||
async fillDefaults(): Promise<void> {
|
async fillDefaults(): Promise<void> {
|
||||||
await this.db.runWithWriteTransaction(
|
await this.db.runWithWriteTransaction(
|
||||||
[Stores.config, Stores.currencies],
|
[Stores.config, Stores.auditorTrustStore],
|
||||||
async (tx) => {
|
async (tx) => {
|
||||||
let applied = false;
|
let applied = false;
|
||||||
await tx.iter(Stores.config).forEach((x) => {
|
await tx.iter(Stores.config).forEach((x) => {
|
||||||
@ -493,8 +488,8 @@ export class Wallet {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (!applied) {
|
if (!applied) {
|
||||||
for (const c of builtinCurrencies) {
|
for (const c of builtinAuditors) {
|
||||||
await tx.put(Stores.currencies, c);
|
await tx.put(Stores.auditorTrustStore, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -676,7 +671,6 @@ export class Wallet {
|
|||||||
return await this.db.iter(Stores.exchanges).toArray();
|
return await this.db.iter(Stores.exchanges).toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async getExchanges(): Promise<ExchangesListRespose> {
|
async getExchanges(): Promise<ExchangesListRespose> {
|
||||||
const exchanges: (ExchangeListItem | undefined)[] = await this.db
|
const exchanges: (ExchangeListItem | undefined)[] = await this.db
|
||||||
.iter(Stores.exchanges)
|
.iter(Stores.exchanges)
|
||||||
@ -702,13 +696,25 @@ export class Wallet {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async getCurrencies(): Promise<CurrencyRecord[]> {
|
async getCurrencies(): Promise<WalletCurrencyInfo> {
|
||||||
return await this.db.iter(Stores.currencies).toArray();
|
const trustedAuditors = await this.db
|
||||||
}
|
.iter(Stores.auditorTrustStore)
|
||||||
|
.toArray();
|
||||||
async updateCurrency(currencyRecord: CurrencyRecord): Promise<void> {
|
const trustedExchanges = await this.db
|
||||||
logger.trace("updating currency to", currencyRecord);
|
.iter(Stores.exchangeTrustStore)
|
||||||
await this.db.put(Stores.currencies, currencyRecord);
|
.toArray();
|
||||||
|
return {
|
||||||
|
trustedAuditors: trustedAuditors.map((x) => ({
|
||||||
|
currency: x.currency,
|
||||||
|
auditorBaseUrl: x.auditorBaseUrl,
|
||||||
|
auditorPub: x.auditorPub,
|
||||||
|
})),
|
||||||
|
trustedExchanges: trustedExchanges.map((x) => ({
|
||||||
|
currency: x.currency,
|
||||||
|
exchangeBaseUrl: x.exchangeBaseUrl,
|
||||||
|
exchangeMasterPub: x.exchangeMasterPub,
|
||||||
|
})),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async getReserves(exchangeBaseUrl?: string): Promise<ReserveRecord[]> {
|
async getReserves(exchangeBaseUrl?: string): Promise<ReserveRecord[]> {
|
||||||
|
Loading…
Reference in New Issue
Block a user