remove deprecated auditor trust management
This commit is contained in:
parent
6affe04fe6
commit
cd9c3a143b
@ -1464,22 +1464,11 @@ export interface ExchangeWithdrawalDetails {
|
||||
*/
|
||||
selectedDenoms: DenomSelectionState;
|
||||
|
||||
/**
|
||||
* Does the wallet know about an auditor for
|
||||
* the exchange that the reserve.
|
||||
*/
|
||||
isAudited: boolean;
|
||||
|
||||
/**
|
||||
* Did the user already accept the current terms of service for the exchange?
|
||||
*/
|
||||
termsOfServiceAccepted: boolean;
|
||||
|
||||
/**
|
||||
* The exchange is trusted directly.
|
||||
*/
|
||||
isTrusted: boolean;
|
||||
|
||||
/**
|
||||
* The earliest deposit expiration of the selected coins.
|
||||
*/
|
||||
|
@ -139,8 +139,6 @@ export const CURRENT_DB_CONFIG_KEY = "currentMainDbName";
|
||||
*/
|
||||
export const WALLET_DB_MINOR_VERSION = 10;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Format of the operation status code: xyznnn
|
||||
*
|
||||
@ -293,61 +291,6 @@ export interface ReserveBankInfo {
|
||||
timestampBankConfirmed: TalerPreciseTimestamp | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Record that indicates the wallet trusts
|
||||
* a particular auditor.
|
||||
*/
|
||||
export interface AuditorTrustRecord {
|
||||
/**
|
||||
* Currency that we trust this auditor for.
|
||||
*/
|
||||
currency: string;
|
||||
|
||||
/**
|
||||
* Base URL of the auditor.
|
||||
*/
|
||||
auditorBaseUrl: string;
|
||||
|
||||
/**
|
||||
* Public key of the auditor.
|
||||
*/
|
||||
auditorPub: string;
|
||||
|
||||
/**
|
||||
* UIDs for the operation of adding this auditor
|
||||
* as a trusted auditor.
|
||||
*
|
||||
* (Used for backup/sync merging and tombstones.)
|
||||
*/
|
||||
uids: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Record to indicate trust for a particular exchange.
|
||||
*/
|
||||
export interface ExchangeTrustRecord {
|
||||
/**
|
||||
* Currency that we trust this exchange for.
|
||||
*/
|
||||
currency: string;
|
||||
|
||||
/**
|
||||
* Canonicalized exchange base URL.
|
||||
*/
|
||||
exchangeBaseUrl: string;
|
||||
|
||||
/**
|
||||
* Master public key of the exchange.
|
||||
*/
|
||||
exchangeMasterPub: string;
|
||||
|
||||
/**
|
||||
* UIDs for the operation of adding this exchange
|
||||
* as trusted.
|
||||
*/
|
||||
uids: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Status of a denomination.
|
||||
*/
|
||||
@ -2451,30 +2394,6 @@ export const WalletStoresV1 = {
|
||||
describeContents<ConfigRecord>({ keyPath: "key" }),
|
||||
{},
|
||||
),
|
||||
auditorTrust: describeStore(
|
||||
"auditorTrust",
|
||||
describeContents<AuditorTrustRecord>({
|
||||
keyPath: ["currency", "auditorBaseUrl"],
|
||||
}),
|
||||
{
|
||||
byAuditorPub: describeIndex("byAuditorPub", "auditorPub"),
|
||||
byUid: describeIndex("byUid", "uids", {
|
||||
multiEntry: true,
|
||||
}),
|
||||
},
|
||||
),
|
||||
exchangeTrust: describeStore(
|
||||
"exchangeTrust",
|
||||
describeContents<ExchangeTrustRecord>({
|
||||
keyPath: ["currency", "exchangeBaseUrl"],
|
||||
}),
|
||||
{
|
||||
byExchangeMasterPub: describeIndex(
|
||||
"byExchangeMasterPub",
|
||||
"exchangeMasterPub",
|
||||
),
|
||||
},
|
||||
),
|
||||
denominations: describeStore(
|
||||
"denominations",
|
||||
describeContents<DenominationRecord>({
|
||||
|
@ -107,10 +107,6 @@ export interface ExchangeOperations {
|
||||
}>,
|
||||
exchangeBaseUrl: string,
|
||||
): Promise<ExchangeDetailsRecord | undefined>;
|
||||
getExchangeTrust(
|
||||
ws: InternalWalletState,
|
||||
exchangeInfo: ExchangeEntryRecord,
|
||||
): Promise<TrustInfo>;
|
||||
updateExchangeFromUrl(
|
||||
ws: InternalWalletState,
|
||||
baseUrl: string,
|
||||
|
@ -281,7 +281,7 @@ export async function getAcceptableExchangeBaseUrls(
|
||||
const acceptableExchangeUrls = new Set<string>();
|
||||
const depositableExchangeUrls = new Set<string>();
|
||||
await ws.db
|
||||
.mktx((x) => [x.exchanges, x.exchangeDetails, x.auditorTrust])
|
||||
.mktx((x) => [x.exchanges, x.exchangeDetails])
|
||||
.runReadOnly(async (tx) => {
|
||||
// FIXME: We should have a DB index to look up all exchanges
|
||||
// for a particular auditor ...
|
||||
|
@ -972,54 +972,3 @@ export async function getExchangePaytoUri(
|
||||
)}`,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if and how an exchange is trusted and/or audited.
|
||||
*/
|
||||
export async function getExchangeTrust(
|
||||
ws: InternalWalletState,
|
||||
exchangeInfo: ExchangeEntryRecord,
|
||||
): Promise<TrustInfo> {
|
||||
let isTrusted = false;
|
||||
let isAudited = false;
|
||||
|
||||
return await ws.db
|
||||
.mktx((x) => [
|
||||
x.exchanges,
|
||||
x.exchangeDetails,
|
||||
x.exchangeTrust,
|
||||
x.auditorTrust,
|
||||
])
|
||||
.runReadOnly(async (tx) => {
|
||||
const exchangeDetails = await getExchangeDetails(
|
||||
tx,
|
||||
exchangeInfo.baseUrl,
|
||||
);
|
||||
|
||||
if (!exchangeDetails) {
|
||||
throw Error(`exchange ${exchangeInfo.baseUrl} details not available`);
|
||||
}
|
||||
const exchangeTrustRecord =
|
||||
await tx.exchangeTrust.indexes.byExchangeMasterPub.get(
|
||||
exchangeDetails.masterPublicKey,
|
||||
);
|
||||
if (
|
||||
exchangeTrustRecord &&
|
||||
exchangeTrustRecord.uids.length > 0 &&
|
||||
exchangeTrustRecord.currency === exchangeDetails.currency
|
||||
) {
|
||||
isTrusted = true;
|
||||
}
|
||||
|
||||
for (const auditor of exchangeDetails.auditors) {
|
||||
const auditorTrustRecord =
|
||||
await tx.auditorTrust.indexes.byAuditorPub.get(auditor.auditor_pub);
|
||||
if (auditorTrustRecord && auditorTrustRecord.uids.length > 0) {
|
||||
isAudited = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return { isTrusted, isAudited };
|
||||
});
|
||||
}
|
||||
|
@ -465,7 +465,6 @@ async function handlePendingMerge(
|
||||
x.reserves,
|
||||
x.exchanges,
|
||||
x.exchangeDetails,
|
||||
x.exchangeTrust,
|
||||
])
|
||||
.runReadWrite(async (tx) => {
|
||||
const peerInc = await tx.peerPushPaymentIncoming.get(
|
||||
|
@ -119,7 +119,6 @@ import {
|
||||
import {
|
||||
getExchangeDetails,
|
||||
getExchangePaytoUri,
|
||||
getExchangeTrust,
|
||||
updateExchangeFromUrl,
|
||||
} from "./exchanges.js";
|
||||
import {
|
||||
@ -722,7 +721,9 @@ interface WithdrawalBatchResult {
|
||||
batchResp: ExchangeWithdrawBatchResponse;
|
||||
}
|
||||
enum AmlStatus {
|
||||
normal= 0, pending = 1, fronzen = 2,
|
||||
normal = 0,
|
||||
pending = 1,
|
||||
fronzen = 2,
|
||||
}
|
||||
|
||||
async function handleKycRequired(
|
||||
@ -769,7 +770,9 @@ async function handleKycRequired(
|
||||
const kycStatus = await kycStatusRes.json();
|
||||
logger.info(`kyc status: ${j2s(kycStatus)}`);
|
||||
kycUrl = kycStatus.kyc_url;
|
||||
} else if (kycStatusRes.status === HttpStatusCode.UnavailableForLegalReasons) {
|
||||
} else if (
|
||||
kycStatusRes.status === HttpStatusCode.UnavailableForLegalReasons
|
||||
) {
|
||||
const kycStatus = await kycStatusRes.json();
|
||||
logger.info(`aml status: ${j2s(kycStatus)}`);
|
||||
amlStatus = kycStatus.aml_status;
|
||||
@ -805,11 +808,15 @@ async function handleKycRequired(
|
||||
requirementRow: uuidResp.requirement_row,
|
||||
};
|
||||
wg2.kycUrl = kycUrl;
|
||||
wg2.status = amlStatus === AmlStatus.normal || amlStatus === undefined ? WithdrawalGroupStatus.PendingKyc :
|
||||
amlStatus === AmlStatus.pending ? WithdrawalGroupStatus.PendingAml :
|
||||
amlStatus === AmlStatus.fronzen ? WithdrawalGroupStatus.SuspendedAml :
|
||||
assertUnreachable(amlStatus);
|
||||
|
||||
wg2.status =
|
||||
amlStatus === AmlStatus.normal || amlStatus === undefined
|
||||
? WithdrawalGroupStatus.PendingKyc
|
||||
: amlStatus === AmlStatus.pending
|
||||
? WithdrawalGroupStatus.PendingAml
|
||||
: amlStatus === AmlStatus.fronzen
|
||||
? WithdrawalGroupStatus.SuspendedAml
|
||||
: assertUnreachable(amlStatus);
|
||||
|
||||
await tx.withdrawalGroups.put(wg2);
|
||||
const newTxState = computeWithdrawalTransactionStatus(wg2);
|
||||
return {
|
||||
@ -919,31 +926,31 @@ async function processPlanchetExchangeBatchRequest(
|
||||
|
||||
// FIXME: handle individual error codes better!
|
||||
|
||||
const reqUrl = new URL(
|
||||
`reserves/${withdrawalGroup.reservePub}/batch-withdraw`,
|
||||
withdrawalGroup.exchangeBaseUrl,
|
||||
).href;
|
||||
const reqUrl = new URL(
|
||||
`reserves/${withdrawalGroup.reservePub}/batch-withdraw`,
|
||||
withdrawalGroup.exchangeBaseUrl,
|
||||
).href;
|
||||
|
||||
try {
|
||||
const resp = await ws.http.postJson(reqUrl, batchReq);
|
||||
if (resp.status === HttpStatusCode.UnavailableForLegalReasons) {
|
||||
await handleKycRequired(ws, withdrawalGroup, resp, 0, requestCoinIdxs);
|
||||
}
|
||||
const r = await readSuccessResponseJsonOrThrow(
|
||||
resp,
|
||||
codecForWithdrawBatchResponse(),
|
||||
);
|
||||
return {
|
||||
coinIdxs: requestCoinIdxs,
|
||||
batchResp: r,
|
||||
};
|
||||
} catch (e) {
|
||||
await storeCoinError(e, requestCoinIdxs[0]);
|
||||
return {
|
||||
batchResp: { ev_sigs: [] },
|
||||
coinIdxs: [],
|
||||
};
|
||||
try {
|
||||
const resp = await ws.http.postJson(reqUrl, batchReq);
|
||||
if (resp.status === HttpStatusCode.UnavailableForLegalReasons) {
|
||||
await handleKycRequired(ws, withdrawalGroup, resp, 0, requestCoinIdxs);
|
||||
}
|
||||
const r = await readSuccessResponseJsonOrThrow(
|
||||
resp,
|
||||
codecForWithdrawBatchResponse(),
|
||||
);
|
||||
return {
|
||||
coinIdxs: requestCoinIdxs,
|
||||
batchResp: r,
|
||||
};
|
||||
} catch (e) {
|
||||
await storeCoinError(e, requestCoinIdxs[0]);
|
||||
return {
|
||||
batchResp: { ev_sigs: [] },
|
||||
coinIdxs: [],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
async function processPlanchetVerifyAndStoreCoin(
|
||||
@ -1410,10 +1417,12 @@ async function processWithdrawalGroupPendingKyc(
|
||||
logger.info(`kyc status: ${j2s(kycStatus)}`);
|
||||
// FIXME: do we need to update the KYC url, or does it always stay constant?
|
||||
return { ready: false };
|
||||
} else if (kycStatusRes.status === HttpStatusCode.UnavailableForLegalReasons) {
|
||||
} else if (
|
||||
kycStatusRes.status === HttpStatusCode.UnavailableForLegalReasons
|
||||
) {
|
||||
const kycStatus = await kycStatusRes.json();
|
||||
logger.info(`aml status: ${j2s(kycStatus)}`);
|
||||
return {ready : false}
|
||||
return { ready: false };
|
||||
} else {
|
||||
throw Error(
|
||||
`unexpected response from kyc-check (${kycStatusRes.status})`,
|
||||
@ -1709,11 +1718,6 @@ export async function getExchangeWithdrawalInfo(
|
||||
exchangeWireAccounts.push(account.payto_uri);
|
||||
}
|
||||
|
||||
const { isTrusted, isAudited } = await ws.exchangeOps.getExchangeTrust(
|
||||
ws,
|
||||
exchange,
|
||||
);
|
||||
|
||||
let hasDenomWithAgeRestriction = false;
|
||||
|
||||
logger.trace("computing earliest deposit expiration");
|
||||
@ -1792,8 +1796,6 @@ export async function getExchangeWithdrawalInfo(
|
||||
exchangePaytoUris: paytoUris,
|
||||
exchangeWireAccounts,
|
||||
exchangeVersion: exchangeDetails.protocolVersionRange || "unknown",
|
||||
isAudited,
|
||||
isTrusted,
|
||||
numOfferedDenoms: possibleDenoms.length,
|
||||
selectedDenoms,
|
||||
// FIXME: delete this field / replace by something we can display to the user
|
||||
@ -2210,8 +2212,6 @@ export interface PrepareCreateWithdrawalGroupResult {
|
||||
withdrawalGroup: WithdrawalGroupRecord;
|
||||
transactionId: string;
|
||||
creationInfo?: {
|
||||
isTrusted: boolean;
|
||||
isAudited: boolean;
|
||||
amount: AmountJson;
|
||||
canonExchange: string;
|
||||
exchangeDetails: ExchangeDetailsRecord;
|
||||
@ -2306,10 +2306,6 @@ export async function internalPrepareCreateWithdrawalGroup(
|
||||
logger.trace(exchangeDetails);
|
||||
throw Error("exchange not updated");
|
||||
}
|
||||
const { isAudited, isTrusted } = await getExchangeTrust(
|
||||
ws,
|
||||
exchangeInfo.exchange,
|
||||
);
|
||||
const transactionId = constructTransactionIdentifier({
|
||||
tag: TransactionType.Withdrawal,
|
||||
withdrawalGroupId: withdrawalGroup.withdrawalGroupId,
|
||||
@ -2319,8 +2315,6 @@ export async function internalPrepareCreateWithdrawalGroup(
|
||||
withdrawalGroup,
|
||||
transactionId,
|
||||
creationInfo: {
|
||||
isAudited,
|
||||
isTrusted,
|
||||
canonExchange,
|
||||
amount,
|
||||
exchangeDetails,
|
||||
@ -2339,7 +2333,6 @@ export async function internalPerformCreateWithdrawalGroup(
|
||||
withdrawalGroups: typeof WalletStoresV1.withdrawalGroups;
|
||||
reserves: typeof WalletStoresV1.reserves;
|
||||
exchanges: typeof WalletStoresV1.exchanges;
|
||||
exchangeTrust: typeof WalletStoresV1.exchangeTrust;
|
||||
}>,
|
||||
prep: PrepareCreateWithdrawalGroupResult,
|
||||
): Promise<PerformCreateWithdrawalGroupResult> {
|
||||
@ -2347,7 +2340,7 @@ export async function internalPerformCreateWithdrawalGroup(
|
||||
if (!prep.creationInfo) {
|
||||
return { withdrawalGroup, transitionInfo: undefined };
|
||||
}
|
||||
const { isAudited, isTrusted, amount, canonExchange, exchangeDetails } =
|
||||
const { amount, canonExchange, exchangeDetails } =
|
||||
prep.creationInfo;
|
||||
|
||||
await tx.withdrawalGroups.add(withdrawalGroup);
|
||||
@ -2363,15 +2356,6 @@ export async function internalPerformCreateWithdrawalGroup(
|
||||
await tx.exchanges.put(exchange);
|
||||
}
|
||||
|
||||
if (!isAudited && !isTrusted) {
|
||||
await tx.exchangeTrust.put({
|
||||
currency: amount.currency,
|
||||
exchangeBaseUrl: canonExchange,
|
||||
exchangeMasterPub: exchangeDetails.masterPublicKey,
|
||||
uids: [encodeCrock(getRandomBytes(32))],
|
||||
});
|
||||
}
|
||||
|
||||
const oldTxState = {
|
||||
major: TransactionMajorState.None,
|
||||
minor: undefined,
|
||||
@ -2417,7 +2401,6 @@ export async function internalCreateWithdrawalGroup(
|
||||
x.reserves,
|
||||
x.exchanges,
|
||||
x.exchangeDetails,
|
||||
x.exchangeTrust,
|
||||
])
|
||||
.runReadWrite(async (tx) => {
|
||||
return await internalPerformCreateWithdrawalGroup(ws, tx, prep);
|
||||
@ -2563,7 +2546,6 @@ export async function createManualWithdrawal(
|
||||
x.withdrawalGroups,
|
||||
x.exchanges,
|
||||
x.exchangeDetails,
|
||||
x.exchangeTrust,
|
||||
])
|
||||
.runReadOnly(async (tx) => {
|
||||
return await getFundingPaytoUris(tx, withdrawalGroup.withdrawalGroupId);
|
||||
|
@ -121,7 +121,7 @@ import {
|
||||
DeleteStoredBackupRequest,
|
||||
TestingSetTimetravelRequest,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { AuditorTrustRecord, WalletContractData } from "./db.js";
|
||||
import { WalletContractData } from "./db.js";
|
||||
import {
|
||||
AddBackupProviderRequest,
|
||||
AddBackupProviderResponse,
|
||||
@ -260,7 +260,6 @@ export interface WalletConfig {
|
||||
*/
|
||||
builtin: {
|
||||
exchanges: string[];
|
||||
auditors: AuditorTrustRecord[];
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -199,7 +199,6 @@ import {
|
||||
downloadTosFromAcceptedFormat,
|
||||
getExchangeDetails,
|
||||
getExchangeRequestTimeout,
|
||||
getExchangeTrust,
|
||||
provideExchangeRecordInTx,
|
||||
updateExchangeFromUrl,
|
||||
updateExchangeFromUrlHandler,
|
||||
@ -527,7 +526,7 @@ async function runTaskLoop(
|
||||
*/
|
||||
async function fillDefaults(ws: InternalWalletState): Promise<void> {
|
||||
await ws.db
|
||||
.mktx((x) => [x.config, x.auditorTrust, x.exchanges, x.exchangeDetails])
|
||||
.mktx((x) => [x.config, x.exchanges, x.exchangeDetails])
|
||||
.runReadWrite(async (tx) => {
|
||||
const appliedRec = await tx.config.get("currencyDefaultsApplied");
|
||||
let alreadyApplied = appliedRec ? !!appliedRec.value : false;
|
||||
@ -535,10 +534,6 @@ async function fillDefaults(ws: InternalWalletState): Promise<void> {
|
||||
logger.trace("defaults already applied");
|
||||
return;
|
||||
}
|
||||
logger.info("importing default exchanges and auditors");
|
||||
for (const c of ws.config.builtin.auditors) {
|
||||
await tx.auditorTrust.put(c);
|
||||
}
|
||||
for (const baseUrl of ws.config.builtin.exchanges) {
|
||||
await addPresetExchangeEntry(tx, baseUrl);
|
||||
const now = AbsoluteTime.now();
|
||||
@ -1558,24 +1553,11 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>(
|
||||
return {};
|
||||
}
|
||||
case WalletApiOperation.ListCurrencies: {
|
||||
return await ws.db
|
||||
.mktx((x) => [x.auditorTrust, x.exchangeTrust])
|
||||
.runReadOnly(async (tx) => {
|
||||
const trustedAuditors = await tx.auditorTrust.iter().toArray();
|
||||
const trustedExchanges = await tx.exchangeTrust.iter().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,
|
||||
})),
|
||||
};
|
||||
});
|
||||
// FIXME: Remove / change to scoped currency approach.
|
||||
return {
|
||||
trustedAuditors: [],
|
||||
trustedExchanges: [],
|
||||
};
|
||||
}
|
||||
case WalletApiOperation.WithdrawFakebank: {
|
||||
const req = codecForWithdrawFakebankRequest().decode(payload);
|
||||
@ -1780,14 +1762,6 @@ export class Wallet {
|
||||
public static defaultConfig: Readonly<WalletConfig> = {
|
||||
builtin: {
|
||||
exchanges: ["https://exchange.demo.taler.net/"],
|
||||
auditors: [
|
||||
{
|
||||
currency: "KUDOS",
|
||||
auditorPub: "BW9DC48PHQY4NH011SHHX36DZZ3Q22Y6X7FZ1VD1CMZ2PTFZ6PN0",
|
||||
auditorBaseUrl: "https://auditor.demo.taler.net/",
|
||||
uids: ["5P25XF8TVQP9AW6VYGY2KV47WT5Y3ZXFSJAA570GJPX5SVJXKBVG"],
|
||||
},
|
||||
],
|
||||
},
|
||||
features: {
|
||||
allowHttp: false,
|
||||
@ -1860,7 +1834,6 @@ class InternalWalletStateImpl implements InternalWalletState {
|
||||
|
||||
exchangeOps: ExchangeOperations = {
|
||||
getExchangeDetails,
|
||||
getExchangeTrust,
|
||||
updateExchangeFromUrl,
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user