wallet-core: more DB cleanup
This commit is contained in:
parent
2ae952cdfa
commit
4898f50db7
@ -527,22 +527,6 @@ export interface OrderShortInfo {
|
|||||||
*/
|
*/
|
||||||
summary_i18n?: InternationalizedString;
|
summary_i18n?: InternationalizedString;
|
||||||
|
|
||||||
/**
|
|
||||||
* List of products that are part of the order
|
|
||||||
*/
|
|
||||||
products: Product[] | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Time indicating when the order should be delivered.
|
|
||||||
* May be overwritten by individual products.
|
|
||||||
*/
|
|
||||||
delivery_date?: TalerProtocolTimestamp;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delivery location for (all!) products.
|
|
||||||
*/
|
|
||||||
delivery_location?: Location;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* URL of the fulfillment, given by the merchant
|
* URL of the fulfillment, given by the merchant
|
||||||
*/
|
*/
|
||||||
@ -724,7 +708,6 @@ export const codecForOrderShortInfo = (): Codec<OrderShortInfo> =>
|
|||||||
.property("fulfillmentUrl", codecOptional(codecForString()))
|
.property("fulfillmentUrl", codecOptional(codecForString()))
|
||||||
.property("merchant", codecForMerchantInfo())
|
.property("merchant", codecForMerchantInfo())
|
||||||
.property("orderId", codecForString())
|
.property("orderId", codecForString())
|
||||||
.property("products", codecOptional(codecForList(codecForProduct())))
|
|
||||||
.property("summary", codecForString())
|
.property("summary", codecForString())
|
||||||
.property("summary_i18n", codecOptional(codecForInternationalizedString()))
|
.property("summary_i18n", codecOptional(codecForInternationalizedString()))
|
||||||
.build("OrderShortInfo");
|
.build("OrderShortInfo");
|
||||||
|
@ -959,11 +959,7 @@ export const nativeCryptoR: TalerCryptoInterfaceR = {
|
|||||||
req: DenominationValidationRequest,
|
req: DenominationValidationRequest,
|
||||||
): Promise<ValidationResult> {
|
): Promise<ValidationResult> {
|
||||||
const { masterPub, denom } = req;
|
const { masterPub, denom } = req;
|
||||||
const value: AmountJson = {
|
const value: AmountJson = Amounts.parseOrThrow(denom.value);
|
||||||
currency: denom.currency,
|
|
||||||
fraction: denom.amountFrac,
|
|
||||||
value: denom.amountVal,
|
|
||||||
};
|
|
||||||
const p = buildSigPS(TalerSignaturePurpose.MASTER_DENOMINATION_KEY_VALIDITY)
|
const p = buildSigPS(TalerSignaturePurpose.MASTER_DENOMINATION_KEY_VALIDITY)
|
||||||
.put(decodeCrock(masterPub))
|
.put(decodeCrock(masterPub))
|
||||||
.put(timestampRoundedToBuffer(denom.stampStart))
|
.put(timestampRoundedToBuffer(denom.stampStart))
|
||||||
|
@ -28,56 +28,53 @@ import {
|
|||||||
} from "@gnu-taler/idb-bridge";
|
} from "@gnu-taler/idb-bridge";
|
||||||
import {
|
import {
|
||||||
AgeCommitmentProof,
|
AgeCommitmentProof,
|
||||||
AmountJson,
|
|
||||||
AmountString,
|
AmountString,
|
||||||
|
Amounts,
|
||||||
|
AttentionInfo,
|
||||||
|
Codec,
|
||||||
CoinEnvelope,
|
CoinEnvelope,
|
||||||
|
CoinPublicKeyString,
|
||||||
CoinRefreshRequest,
|
CoinRefreshRequest,
|
||||||
CoinStatus,
|
CoinStatus,
|
||||||
MerchantContractTerms,
|
DenomSelectionState,
|
||||||
DenominationInfo,
|
DenominationInfo,
|
||||||
DenominationPubKey,
|
DenominationPubKey,
|
||||||
DenomSelectionState,
|
|
||||||
EddsaPublicKeyString,
|
EddsaPublicKeyString,
|
||||||
EddsaSignatureString,
|
EddsaSignatureString,
|
||||||
ExchangeAuditor,
|
ExchangeAuditor,
|
||||||
ExchangeGlobalFees,
|
ExchangeGlobalFees,
|
||||||
|
HashCodeString,
|
||||||
InternationalizedString,
|
InternationalizedString,
|
||||||
Location,
|
Logger,
|
||||||
|
MerchantContractTerms,
|
||||||
MerchantInfo,
|
MerchantInfo,
|
||||||
PayCoinSelection,
|
PayCoinSelection,
|
||||||
PeerContractTerms,
|
PeerContractTerms,
|
||||||
Product,
|
|
||||||
RefreshReason,
|
RefreshReason,
|
||||||
TalerErrorDetail,
|
TalerErrorDetail,
|
||||||
|
TalerPreciseTimestamp,
|
||||||
TalerProtocolDuration,
|
TalerProtocolDuration,
|
||||||
TalerProtocolTimestamp,
|
TalerProtocolTimestamp,
|
||||||
TransactionIdStr,
|
TransactionIdStr,
|
||||||
UnblindedSignature,
|
UnblindedSignature,
|
||||||
WireInfo,
|
WireInfo,
|
||||||
HashCodeString,
|
|
||||||
Amounts,
|
|
||||||
AttentionInfo,
|
|
||||||
Logger,
|
|
||||||
CoinPublicKeyString,
|
|
||||||
TalerPreciseTimestamp,
|
|
||||||
codecForAny,
|
codecForAny,
|
||||||
Codec,
|
|
||||||
} from "@gnu-taler/taler-util";
|
} from "@gnu-taler/taler-util";
|
||||||
|
import { RetryInfo, TaskIdentifiers } from "./operations/common.js";
|
||||||
import {
|
import {
|
||||||
DbAccess,
|
DbAccess,
|
||||||
DbReadOnlyTransaction,
|
DbReadOnlyTransaction,
|
||||||
DbReadWriteTransaction,
|
DbReadWriteTransaction,
|
||||||
describeContents,
|
|
||||||
describeIndex,
|
|
||||||
describeStore,
|
|
||||||
GetReadWriteAccess,
|
GetReadWriteAccess,
|
||||||
IndexDescriptor,
|
IndexDescriptor,
|
||||||
openDatabase,
|
|
||||||
StoreDescriptor,
|
StoreDescriptor,
|
||||||
StoreNames,
|
StoreNames,
|
||||||
StoreWithIndexes,
|
StoreWithIndexes,
|
||||||
|
describeContents,
|
||||||
|
describeIndex,
|
||||||
|
describeStore,
|
||||||
|
openDatabase,
|
||||||
} from "./util/query.js";
|
} from "./util/query.js";
|
||||||
import { RetryInfo, TaskIdentifiers } from "./operations/common.js";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This file contains the database schema of the Taler wallet together
|
* This file contains the database schema of the Taler wallet together
|
||||||
@ -109,6 +106,9 @@ import { RetryInfo, TaskIdentifiers } from "./operations/common.js";
|
|||||||
store.
|
store.
|
||||||
- More object stores should have an "id" primary key,
|
- More object stores should have an "id" primary key,
|
||||||
as this makes referencing less expensive.
|
as this makes referencing less expensive.
|
||||||
|
- Coin selections should probably go into a separate object store.
|
||||||
|
- Some records should be split up into an extra "details" record
|
||||||
|
that we don't always need to iterate over.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -323,12 +323,14 @@ export interface DenomFees {
|
|||||||
* Denomination record as stored in the wallet's database.
|
* Denomination record as stored in the wallet's database.
|
||||||
*/
|
*/
|
||||||
export interface DenominationRecord {
|
export interface DenominationRecord {
|
||||||
|
/**
|
||||||
|
* Currency of the denomination.
|
||||||
|
*
|
||||||
|
* Stored separately as we have an index on it.
|
||||||
|
*/
|
||||||
currency: string;
|
currency: string;
|
||||||
|
|
||||||
// FIXME: Use binary encoding of amount instead?
|
value: AmountString;
|
||||||
amountVal: number;
|
|
||||||
|
|
||||||
amountFrac: number;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The denomination public key.
|
* The denomination public key.
|
||||||
@ -407,14 +409,6 @@ export interface DenominationRecord {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export namespace DenominationRecord {
|
export namespace DenominationRecord {
|
||||||
export function getValue(d: DenominationRecord): AmountJson {
|
|
||||||
return {
|
|
||||||
currency: d.currency,
|
|
||||||
fraction: d.amountFrac,
|
|
||||||
value: d.amountVal,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function toDenomInfo(d: DenominationRecord): DenominationInfo {
|
export function toDenomInfo(d: DenominationRecord): DenominationInfo {
|
||||||
return {
|
return {
|
||||||
denomPub: d.denomPub,
|
denomPub: d.denomPub,
|
||||||
@ -427,7 +421,7 @@ export namespace DenominationRecord {
|
|||||||
stampExpireLegal: d.stampExpireLegal,
|
stampExpireLegal: d.stampExpireLegal,
|
||||||
stampExpireWithdraw: d.stampExpireWithdraw,
|
stampExpireWithdraw: d.stampExpireWithdraw,
|
||||||
stampStart: d.stampStart,
|
stampStart: d.stampStart,
|
||||||
value: Amounts.stringify(DenominationRecord.getValue(d)),
|
value: Amounts.stringify(d.value),
|
||||||
exchangeBaseUrl: d.exchangeBaseUrl,
|
exchangeBaseUrl: d.exchangeBaseUrl,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -1056,9 +1050,6 @@ export interface AllowedExchangeInfo {
|
|||||||
* processing in the wallet.
|
* processing in the wallet.
|
||||||
*/
|
*/
|
||||||
export interface WalletContractData {
|
export interface WalletContractData {
|
||||||
products?: Product[];
|
|
||||||
summaryI18n: { [lang_tag: string]: string } | undefined;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fulfillment URL, or the empty string if the order has no fulfillment URL.
|
* Fulfillment URL, or the empty string if the order has no fulfillment URL.
|
||||||
*
|
*
|
||||||
@ -1076,6 +1067,7 @@ export interface WalletContractData {
|
|||||||
orderId: string;
|
orderId: string;
|
||||||
merchantBaseUrl: string;
|
merchantBaseUrl: string;
|
||||||
summary: string;
|
summary: string;
|
||||||
|
summaryI18n: { [lang_tag: string]: string } | undefined;
|
||||||
autoRefund: TalerProtocolDuration | undefined;
|
autoRefund: TalerProtocolDuration | undefined;
|
||||||
maxWireFee: AmountString;
|
maxWireFee: AmountString;
|
||||||
wireFeeAmortization: number;
|
wireFeeAmortization: number;
|
||||||
@ -1087,8 +1079,6 @@ export interface WalletContractData {
|
|||||||
wireInfoHash: string;
|
wireInfoHash: string;
|
||||||
maxDepositFee: AmountString;
|
maxDepositFee: AmountString;
|
||||||
minimumAge?: number;
|
minimumAge?: number;
|
||||||
deliveryDate: TalerProtocolTimestamp | undefined;
|
|
||||||
deliveryLocation: Location | undefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum PurchaseStatus {
|
export enum PurchaseStatus {
|
||||||
@ -2095,8 +2085,7 @@ export interface OperationRetryRecord {
|
|||||||
*/
|
*/
|
||||||
export interface CoinAvailabilityRecord {
|
export interface CoinAvailabilityRecord {
|
||||||
currency: string;
|
currency: string;
|
||||||
amountVal: number;
|
value: AmountString;
|
||||||
amountFrac: number;
|
|
||||||
denomPubHash: string;
|
denomPubHash: string;
|
||||||
exchangeBaseUrl: string;
|
exchangeBaseUrl: string;
|
||||||
|
|
||||||
|
@ -159,11 +159,7 @@ export async function withdrawCoin(args: {
|
|||||||
reservePriv: reserveKeyPair.reservePriv,
|
reservePriv: reserveKeyPair.reservePriv,
|
||||||
reservePub: reserveKeyPair.reservePub,
|
reservePub: reserveKeyPair.reservePub,
|
||||||
secretSeed: encodeCrock(getRandomBytes(32)),
|
secretSeed: encodeCrock(getRandomBytes(32)),
|
||||||
value: {
|
value: Amounts.parseOrThrow(denom.value),
|
||||||
currency: denom.currency,
|
|
||||||
fraction: denom.amountFrac,
|
|
||||||
value: denom.amountVal,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const reqBody: ExchangeWithdrawRequest = {
|
const reqBody: ExchangeWithdrawRequest = {
|
||||||
@ -211,11 +207,7 @@ export function findDenomOrThrow(
|
|||||||
): DenominationRecord {
|
): DenominationRecord {
|
||||||
const denomselAllowLate = options.denomselAllowLate ?? false;
|
const denomselAllowLate = options.denomselAllowLate ?? false;
|
||||||
for (const d of exchangeInfo.keys.currentDenominations) {
|
for (const d of exchangeInfo.keys.currentDenominations) {
|
||||||
const value: AmountJson = {
|
const value: AmountJson = Amounts.parseOrThrow(d.value);
|
||||||
currency: d.currency,
|
|
||||||
fraction: d.amountFrac,
|
|
||||||
value: d.amountVal,
|
|
||||||
};
|
|
||||||
if (
|
if (
|
||||||
Amounts.cmp(value, amount) === 0 &&
|
Amounts.cmp(value, amount) === 0 &&
|
||||||
isWithdrawableDenom(d, denomselAllowLate)
|
isWithdrawableDenom(d, denomselAllowLate)
|
||||||
@ -303,11 +295,7 @@ export async function refreshCoin(req: {
|
|||||||
denomPub: x.denomPub,
|
denomPub: x.denomPub,
|
||||||
denomPubHash: x.denomPubHash,
|
denomPubHash: x.denomPubHash,
|
||||||
feeWithdraw: x.fees.feeWithdraw,
|
feeWithdraw: x.fees.feeWithdraw,
|
||||||
value: Amounts.stringify({
|
value: x.value,
|
||||||
currency: x.currency,
|
|
||||||
fraction: x.amountFrac,
|
|
||||||
value: x.amountVal,
|
|
||||||
}),
|
|
||||||
})),
|
})),
|
||||||
meltCoinMaxAge: oldCoin.maxAge,
|
meltCoinMaxAge: oldCoin.maxAge,
|
||||||
});
|
});
|
||||||
|
@ -133,11 +133,7 @@ export async function getBalancesInsideTransaction(
|
|||||||
const b = initBalance(ca.currency);
|
const b = initBalance(ca.currency);
|
||||||
const count = ca.visibleCoinCount ?? 0;
|
const count = ca.visibleCoinCount ?? 0;
|
||||||
for (let i = 0; i < count; i++) {
|
for (let i = 0; i < count; i++) {
|
||||||
b.available = Amounts.add(b.available, {
|
b.available = Amounts.add(b.available, ca.value).amount;
|
||||||
currency: ca.currency,
|
|
||||||
fraction: ca.amountFrac,
|
|
||||||
value: ca.amountVal,
|
|
||||||
}).amount;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -408,11 +404,7 @@ export async function getMerchantPaymentBalanceDetails(
|
|||||||
if (ca.currency != req.currency) {
|
if (ca.currency != req.currency) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const singleCoinAmount: AmountJson = {
|
const singleCoinAmount: AmountJson = Amounts.parseOrThrow(ca.value);
|
||||||
currency: ca.currency,
|
|
||||||
fraction: ca.amountFrac,
|
|
||||||
value: ca.amountVal,
|
|
||||||
};
|
|
||||||
const coinAmount: AmountJson = Amounts.mult(
|
const coinAmount: AmountJson = Amounts.mult(
|
||||||
singleCoinAmount,
|
singleCoinAmount,
|
||||||
ca.freshCoinCount,
|
ca.freshCoinCount,
|
||||||
@ -530,11 +522,7 @@ export async function getPeerPaymentBalanceDetailsInTx(
|
|||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const singleCoinAmount: AmountJson = {
|
const singleCoinAmount: AmountJson = Amounts.parseOrThrow(ca.value);
|
||||||
currency: ca.currency,
|
|
||||||
fraction: ca.amountFrac,
|
|
||||||
value: ca.amountVal,
|
|
||||||
};
|
|
||||||
const coinAmount: AmountJson = Amounts.mult(
|
const coinAmount: AmountJson = Amounts.mult(
|
||||||
singleCoinAmount,
|
singleCoinAmount,
|
||||||
ca.freshCoinCount,
|
ca.freshCoinCount,
|
||||||
|
@ -26,7 +26,6 @@ import {
|
|||||||
CoinRefreshRequest,
|
CoinRefreshRequest,
|
||||||
CoinStatus,
|
CoinStatus,
|
||||||
Duration,
|
Duration,
|
||||||
ErrorInfoSummary,
|
|
||||||
ExchangeEntryStatus,
|
ExchangeEntryStatus,
|
||||||
ExchangeListItem,
|
ExchangeListItem,
|
||||||
ExchangeTosStatus,
|
ExchangeTosStatus,
|
||||||
@ -34,9 +33,11 @@ import {
|
|||||||
getErrorDetailFromException,
|
getErrorDetailFromException,
|
||||||
j2s,
|
j2s,
|
||||||
Logger,
|
Logger,
|
||||||
|
makeErrorDetail,
|
||||||
NotificationType,
|
NotificationType,
|
||||||
OperationErrorInfo,
|
OperationErrorInfo,
|
||||||
RefreshReason,
|
RefreshReason,
|
||||||
|
TalerError,
|
||||||
TalerErrorCode,
|
TalerErrorCode,
|
||||||
TalerErrorDetail,
|
TalerErrorDetail,
|
||||||
TombstoneIdStr,
|
TombstoneIdStr,
|
||||||
@ -44,32 +45,31 @@ import {
|
|||||||
TransactionType,
|
TransactionType,
|
||||||
WalletNotification,
|
WalletNotification,
|
||||||
} from "@gnu-taler/taler-util";
|
} from "@gnu-taler/taler-util";
|
||||||
|
import { CryptoApiStoppedError } from "../crypto/workers/crypto-dispatcher.js";
|
||||||
import {
|
import {
|
||||||
WalletStoresV1,
|
|
||||||
CoinRecord,
|
|
||||||
ExchangeDetailsRecord,
|
|
||||||
ExchangeEntryRecord,
|
|
||||||
BackupProviderRecord,
|
BackupProviderRecord,
|
||||||
|
CoinRecord,
|
||||||
DepositGroupRecord,
|
DepositGroupRecord,
|
||||||
PeerPullPaymentIncomingRecord,
|
ExchangeDetailsRecord,
|
||||||
|
ExchangeEntryDbRecordStatus,
|
||||||
|
ExchangeEntryDbUpdateStatus,
|
||||||
|
ExchangeEntryRecord,
|
||||||
PeerPullCreditRecord,
|
PeerPullCreditRecord,
|
||||||
PeerPushPaymentIncomingRecord,
|
PeerPullPaymentIncomingRecord,
|
||||||
PeerPushDebitRecord,
|
PeerPushDebitRecord,
|
||||||
|
PeerPushPaymentIncomingRecord,
|
||||||
PurchaseRecord,
|
PurchaseRecord,
|
||||||
RecoupGroupRecord,
|
RecoupGroupRecord,
|
||||||
RefreshGroupRecord,
|
RefreshGroupRecord,
|
||||||
RewardRecord,
|
RewardRecord,
|
||||||
|
WalletStoresV1,
|
||||||
WithdrawalGroupRecord,
|
WithdrawalGroupRecord,
|
||||||
ExchangeEntryDbUpdateStatus,
|
|
||||||
ExchangeEntryDbRecordStatus,
|
|
||||||
} from "../db.js";
|
} from "../db.js";
|
||||||
import { makeErrorDetail, TalerError } from "@gnu-taler/taler-util";
|
|
||||||
import { InternalWalletState } from "../internal-wallet-state.js";
|
import { InternalWalletState } from "../internal-wallet-state.js";
|
||||||
import { checkDbInvariant, checkLogicInvariant } from "../util/invariants.js";
|
|
||||||
import { GetReadOnlyAccess, GetReadWriteAccess } from "../util/query.js";
|
|
||||||
import { CryptoApiStoppedError } from "../crypto/workers/crypto-dispatcher.js";
|
|
||||||
import { PendingTaskType, TaskId } from "../pending-types.js";
|
import { PendingTaskType, TaskId } from "../pending-types.js";
|
||||||
import { assertUnreachable } from "../util/assertUnreachable.js";
|
import { assertUnreachable } from "../util/assertUnreachable.js";
|
||||||
|
import { checkDbInvariant, checkLogicInvariant } from "../util/invariants.js";
|
||||||
|
import { GetReadOnlyAccess, GetReadWriteAccess } from "../util/query.js";
|
||||||
import { constructTransactionIdentifier } from "./transactions.js";
|
import { constructTransactionIdentifier } from "./transactions.js";
|
||||||
|
|
||||||
const logger = new Logger("operations/common.ts");
|
const logger = new Logger("operations/common.ts");
|
||||||
@ -144,8 +144,7 @@ export async function makeCoinAvailable(
|
|||||||
if (!car) {
|
if (!car) {
|
||||||
car = {
|
car = {
|
||||||
maxAge: ageRestriction,
|
maxAge: ageRestriction,
|
||||||
amountFrac: denom.amountFrac,
|
value: denom.value,
|
||||||
amountVal: denom.amountVal,
|
|
||||||
currency: denom.currency,
|
currency: denom.currency,
|
||||||
denomPubHash: denom.denomPubHash,
|
denomPubHash: denom.denomPubHash,
|
||||||
exchangeBaseUrl: denom.exchangeBaseUrl,
|
exchangeBaseUrl: denom.exchangeBaseUrl,
|
||||||
|
@ -1539,7 +1539,7 @@ async function getTotalFeesForDepositAmount(
|
|||||||
.iter(coin.exchangeBaseUrl)
|
.iter(coin.exchangeBaseUrl)
|
||||||
.filter((x) =>
|
.filter((x) =>
|
||||||
Amounts.isSameCurrency(
|
Amounts.isSameCurrency(
|
||||||
DenominationRecord.getValue(x),
|
x.value,
|
||||||
pcs.coinContributions[i],
|
pcs.coinContributions[i],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -443,8 +443,7 @@ async function downloadExchangeKeysInfo(
|
|||||||
exchangeMasterPub: exchangeKeysJsonUnchecked.master_public_key,
|
exchangeMasterPub: exchangeKeysJsonUnchecked.master_public_key,
|
||||||
isOffered: true,
|
isOffered: true,
|
||||||
isRevoked: false,
|
isRevoked: false,
|
||||||
amountFrac: value.fraction,
|
value: Amounts.stringify(value),
|
||||||
amountVal: value.value,
|
|
||||||
currency: value.currency,
|
currency: value.currency,
|
||||||
stampExpireDeposit: denomIn.stamp_expire_deposit,
|
stampExpireDeposit: denomIn.stamp_expire_deposit,
|
||||||
stampExpireLegal: denomIn.stamp_expire_legal,
|
stampExpireLegal: denomIn.stamp_expire_legal,
|
||||||
|
@ -174,12 +174,12 @@ export async function getTotalPaymentCost(
|
|||||||
.iter(coin.exchangeBaseUrl)
|
.iter(coin.exchangeBaseUrl)
|
||||||
.filter((x) =>
|
.filter((x) =>
|
||||||
Amounts.isSameCurrency(
|
Amounts.isSameCurrency(
|
||||||
DenominationRecord.getValue(x),
|
x.value,
|
||||||
pcs.coinContributions[i],
|
pcs.coinContributions[i],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
const amountLeft = Amounts.sub(
|
const amountLeft = Amounts.sub(
|
||||||
DenominationRecord.getValue(denom),
|
denom.value,
|
||||||
pcs.coinContributions[i],
|
pcs.coinContributions[i],
|
||||||
).amount;
|
).amount;
|
||||||
const refreshCost = getTotalRefreshCost(
|
const refreshCost = getTotalRefreshCost(
|
||||||
|
@ -108,16 +108,8 @@ export async function getTotalPeerPaymentCost(
|
|||||||
}
|
}
|
||||||
const allDenoms = await tx.denominations.indexes.byExchangeBaseUrl
|
const allDenoms = await tx.denominations.indexes.byExchangeBaseUrl
|
||||||
.iter(coin.exchangeBaseUrl)
|
.iter(coin.exchangeBaseUrl)
|
||||||
.filter((x) =>
|
.filter((x) => Amounts.isSameCurrency(x.value, pcs[i].contribution));
|
||||||
Amounts.isSameCurrency(
|
const amountLeft = Amounts.sub(denom.value, pcs[i].contribution).amount;
|
||||||
DenominationRecord.getValue(x),
|
|
||||||
pcs[i].contribution,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
const amountLeft = Amounts.sub(
|
|
||||||
DenominationRecord.getValue(denom),
|
|
||||||
pcs[i].contribution,
|
|
||||||
).amount;
|
|
||||||
const refreshCost = getTotalRefreshCost(
|
const refreshCost = getTotalRefreshCost(
|
||||||
allDenoms,
|
allDenoms,
|
||||||
DenominationRecord.toDenomInfo(denom),
|
DenominationRecord.toDenomInfo(denom),
|
||||||
|
@ -134,11 +134,7 @@ export function getTotalRefreshCost(
|
|||||||
const resultingAmount = Amounts.add(
|
const resultingAmount = Amounts.add(
|
||||||
Amounts.zeroOfCurrency(withdrawAmount.currency),
|
Amounts.zeroOfCurrency(withdrawAmount.currency),
|
||||||
...withdrawDenoms.selectedDenoms.map(
|
...withdrawDenoms.selectedDenoms.map(
|
||||||
(d) =>
|
(d) => Amounts.mult(denomMap[d.denomPubHash].value, d.count).amount,
|
||||||
Amounts.mult(
|
|
||||||
DenominationRecord.getValue(denomMap[d.denomPubHash]),
|
|
||||||
d.count,
|
|
||||||
).amount,
|
|
||||||
),
|
),
|
||||||
).amount;
|
).amount;
|
||||||
const totalCost = Amounts.sub(amountLeft, resultingAmount).amount;
|
const totalCost = Amounts.sub(amountLeft, resultingAmount).amount;
|
||||||
@ -1200,11 +1196,7 @@ export async function autoRefresh(
|
|||||||
if (AbsoluteTime.isExpired(executeThreshold)) {
|
if (AbsoluteTime.isExpired(executeThreshold)) {
|
||||||
refreshCoins.push({
|
refreshCoins.push({
|
||||||
coinPub: coin.coinPub,
|
coinPub: coin.coinPub,
|
||||||
amount: Amounts.stringify({
|
amount: denom.value,
|
||||||
value: denom.amountVal,
|
|
||||||
fraction: denom.amountFrac,
|
|
||||||
currency: denom.currency,
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const checkThreshold = getAutoRefreshCheckThreshold(denom);
|
const checkThreshold = getAutoRefreshCheckThreshold(denom);
|
||||||
|
@ -884,7 +884,6 @@ async function buildTransactionForPurchase(
|
|||||||
const info: OrderShortInfo = {
|
const info: OrderShortInfo = {
|
||||||
merchant: contractData.merchant,
|
merchant: contractData.merchant,
|
||||||
orderId: contractData.orderId,
|
orderId: contractData.orderId,
|
||||||
products: contractData.products,
|
|
||||||
summary: contractData.summary,
|
summary: contractData.summary,
|
||||||
summary_i18n: contractData.summaryI18n,
|
summary_i18n: contractData.summaryI18n,
|
||||||
contractTermsHash: contractData.contractTermsHash,
|
contractTermsHash: contractData.contractTermsHash,
|
||||||
|
@ -78,8 +78,7 @@ test("withdrawal selection bug repro", (t) => {
|
|||||||
},
|
},
|
||||||
verificationStatus: DenominationVerificationStatus.Unverified,
|
verificationStatus: DenominationVerificationStatus.Unverified,
|
||||||
currency: "KUDOS",
|
currency: "KUDOS",
|
||||||
amountFrac: 0,
|
value: "KUDOS:1000",
|
||||||
amountVal: 1000,
|
|
||||||
listIssueDate: { t_s: 0 },
|
listIssueDate: { t_s: 0 },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -133,8 +132,7 @@ test("withdrawal selection bug repro", (t) => {
|
|||||||
t_s: 1585229388,
|
t_s: 1585229388,
|
||||||
},
|
},
|
||||||
verificationStatus: DenominationVerificationStatus.Unverified,
|
verificationStatus: DenominationVerificationStatus.Unverified,
|
||||||
amountFrac: 0,
|
value: "KUDOS:10",
|
||||||
amountVal: 10,
|
|
||||||
currency: "KUDOS",
|
currency: "KUDOS",
|
||||||
listIssueDate: { t_s: 0 },
|
listIssueDate: { t_s: 0 },
|
||||||
},
|
},
|
||||||
@ -188,8 +186,7 @@ test("withdrawal selection bug repro", (t) => {
|
|||||||
t_s: 1585229388,
|
t_s: 1585229388,
|
||||||
},
|
},
|
||||||
verificationStatus: DenominationVerificationStatus.Unverified,
|
verificationStatus: DenominationVerificationStatus.Unverified,
|
||||||
amountFrac: 0,
|
value: "KUDOS:5",
|
||||||
amountVal: 5,
|
|
||||||
currency: "KUDOS",
|
currency: "KUDOS",
|
||||||
listIssueDate: { t_s: 0 },
|
listIssueDate: { t_s: 0 },
|
||||||
},
|
},
|
||||||
@ -244,8 +241,7 @@ test("withdrawal selection bug repro", (t) => {
|
|||||||
t_s: 1585229388,
|
t_s: 1585229388,
|
||||||
},
|
},
|
||||||
verificationStatus: DenominationVerificationStatus.Unverified,
|
verificationStatus: DenominationVerificationStatus.Unverified,
|
||||||
amountFrac: 0,
|
value: "KUDOS:1",
|
||||||
amountVal: 1,
|
|
||||||
currency: "KUDOS",
|
currency: "KUDOS",
|
||||||
listIssueDate: { t_s: 0 },
|
listIssueDate: { t_s: 0 },
|
||||||
},
|
},
|
||||||
@ -299,8 +295,11 @@ test("withdrawal selection bug repro", (t) => {
|
|||||||
t_s: 1585229388,
|
t_s: 1585229388,
|
||||||
},
|
},
|
||||||
verificationStatus: DenominationVerificationStatus.Unverified,
|
verificationStatus: DenominationVerificationStatus.Unverified,
|
||||||
amountFrac: 10000000,
|
value: Amounts.stringify({
|
||||||
amountVal: 0,
|
currency: "KUDOS",
|
||||||
|
fraction: 10000000,
|
||||||
|
value: 0,
|
||||||
|
}),
|
||||||
currency: "KUDOS",
|
currency: "KUDOS",
|
||||||
listIssueDate: { t_s: 0 },
|
listIssueDate: { t_s: 0 },
|
||||||
},
|
},
|
||||||
@ -354,8 +353,7 @@ test("withdrawal selection bug repro", (t) => {
|
|||||||
t_s: 1585229388,
|
t_s: 1585229388,
|
||||||
},
|
},
|
||||||
verificationStatus: DenominationVerificationStatus.Unverified,
|
verificationStatus: DenominationVerificationStatus.Unverified,
|
||||||
amountFrac: 0,
|
value: "KUDOS:2",
|
||||||
amountVal: 2,
|
|
||||||
currency: "KUDOS",
|
currency: "KUDOS",
|
||||||
listIssueDate: { t_s: 0 },
|
listIssueDate: { t_s: 0 },
|
||||||
},
|
},
|
||||||
|
@ -699,25 +699,17 @@ export function selectWithdrawalDenominations(
|
|||||||
let totalWithdrawCost = Amounts.zeroOfCurrency(amountAvailable.currency);
|
let totalWithdrawCost = Amounts.zeroOfCurrency(amountAvailable.currency);
|
||||||
|
|
||||||
denoms = denoms.filter((d) => isWithdrawableDenom(d, denomselAllowLate));
|
denoms = denoms.filter((d) => isWithdrawableDenom(d, denomselAllowLate));
|
||||||
denoms.sort((d1, d2) =>
|
denoms.sort((d1, d2) => Amounts.cmp(d2.value, d1.value));
|
||||||
Amounts.cmp(
|
|
||||||
DenominationRecord.getValue(d2),
|
|
||||||
DenominationRecord.getValue(d1),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
for (const d of denoms) {
|
for (const d of denoms) {
|
||||||
const cost = Amounts.add(
|
const cost = Amounts.add(d.value, d.fees.feeWithdraw).amount;
|
||||||
DenominationRecord.getValue(d),
|
|
||||||
d.fees.feeWithdraw,
|
|
||||||
).amount;
|
|
||||||
const res = Amounts.divmod(remaining, cost);
|
const res = Amounts.divmod(remaining, cost);
|
||||||
const count = res.quotient;
|
const count = res.quotient;
|
||||||
remaining = Amounts.sub(remaining, Amounts.mult(cost, count).amount).amount;
|
remaining = Amounts.sub(remaining, Amounts.mult(cost, count).amount).amount;
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
totalCoinValue = Amounts.add(
|
totalCoinValue = Amounts.add(
|
||||||
totalCoinValue,
|
totalCoinValue,
|
||||||
Amounts.mult(DenominationRecord.getValue(d), count).amount,
|
Amounts.mult(d.value, count).amount,
|
||||||
).amount;
|
).amount;
|
||||||
totalWithdrawCost = Amounts.add(
|
totalWithdrawCost = Amounts.add(
|
||||||
totalWithdrawCost,
|
totalWithdrawCost,
|
||||||
@ -766,30 +758,22 @@ export function selectForcedWithdrawalDenominations(
|
|||||||
let totalWithdrawCost = Amounts.zeroOfCurrency(amountAvailable.currency);
|
let totalWithdrawCost = Amounts.zeroOfCurrency(amountAvailable.currency);
|
||||||
|
|
||||||
denoms = denoms.filter((d) => isWithdrawableDenom(d, denomselAllowLate));
|
denoms = denoms.filter((d) => isWithdrawableDenom(d, denomselAllowLate));
|
||||||
denoms.sort((d1, d2) =>
|
denoms.sort((d1, d2) => Amounts.cmp(d2.value, d1.value));
|
||||||
Amounts.cmp(
|
|
||||||
DenominationRecord.getValue(d2),
|
|
||||||
DenominationRecord.getValue(d1),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
for (const fds of forcedDenomSel.denoms) {
|
for (const fds of forcedDenomSel.denoms) {
|
||||||
const count = fds.count;
|
const count = fds.count;
|
||||||
const denom = denoms.find((x) => {
|
const denom = denoms.find((x) => {
|
||||||
return Amounts.cmp(DenominationRecord.getValue(x), fds.value) == 0;
|
return Amounts.cmp(x.value, fds.value) == 0;
|
||||||
});
|
});
|
||||||
if (!denom) {
|
if (!denom) {
|
||||||
throw Error(
|
throw Error(
|
||||||
`unable to find denom for forced selection (value ${fds.value})`,
|
`unable to find denom for forced selection (value ${fds.value})`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const cost = Amounts.add(
|
const cost = Amounts.add(denom.value, denom.fees.feeWithdraw).amount;
|
||||||
DenominationRecord.getValue(denom),
|
|
||||||
denom.fees.feeWithdraw,
|
|
||||||
).amount;
|
|
||||||
totalCoinValue = Amounts.add(
|
totalCoinValue = Amounts.add(
|
||||||
totalCoinValue,
|
totalCoinValue,
|
||||||
Amounts.mult(DenominationRecord.getValue(denom), count).amount,
|
Amounts.mult(denom.value, count).amount,
|
||||||
).amount;
|
).amount;
|
||||||
totalWithdrawCost = Amounts.add(
|
totalWithdrawCost = Amounts.add(
|
||||||
totalWithdrawCost,
|
totalWithdrawCost,
|
||||||
|
@ -321,7 +321,7 @@ function buildCoinInfoFromDenom(
|
|||||||
AbsoluteTime.fromProtocolTimestamp(denom.stampExpireDeposit),
|
AbsoluteTime.fromProtocolTimestamp(denom.stampExpireDeposit),
|
||||||
),
|
),
|
||||||
totalAvailable: total,
|
totalAvailable: total,
|
||||||
value: DenominationRecord.getValue(denom),
|
value: Amounts.parseOrThrow(denom.value),
|
||||||
maxAge,
|
maxAge,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -915,11 +915,7 @@ async function dumpCoins(ws: InternalWalletState): Promise<CoinDumpJson> {
|
|||||||
coin_pub: c.coinPub,
|
coin_pub: c.coinPub,
|
||||||
denom_pub: denomInfo.denomPub,
|
denom_pub: denomInfo.denomPub,
|
||||||
denom_pub_hash: c.denomPubHash,
|
denom_pub_hash: c.denomPubHash,
|
||||||
denom_value: Amounts.stringify({
|
denom_value: denom.value,
|
||||||
value: denom.amountVal,
|
|
||||||
currency: denom.currency,
|
|
||||||
fraction: denom.amountFrac,
|
|
||||||
}),
|
|
||||||
exchange_base_url: c.exchangeBaseUrl,
|
exchange_base_url: c.exchangeBaseUrl,
|
||||||
refresh_parent_coin_pub: refreshParentCoinPub,
|
refresh_parent_coin_pub: refreshParentCoinPub,
|
||||||
withdrawal_reserve_pub: withdrawalReservePub,
|
withdrawal_reserve_pub: withdrawalReservePub,
|
||||||
@ -1876,35 +1872,27 @@ class InternalWalletStateImpl implements InternalWalletState {
|
|||||||
return computeRefundTransactionState(rec);
|
return computeRefundTransactionState(rec);
|
||||||
}
|
}
|
||||||
case TransactionType.PeerPullCredit:
|
case TransactionType.PeerPullCredit:
|
||||||
const rec = await tx.peerPullCredit.get(
|
const rec = await tx.peerPullCredit.get(parsedTxId.pursePub);
|
||||||
parsedTxId.pursePub,
|
|
||||||
);
|
|
||||||
if (!rec) {
|
if (!rec) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
return computePeerPullCreditTransactionState(rec);
|
return computePeerPullCreditTransactionState(rec);
|
||||||
case TransactionType.PeerPullDebit: {
|
case TransactionType.PeerPullDebit: {
|
||||||
const rec = await tx.peerPullDebit.get(
|
const rec = await tx.peerPullDebit.get(parsedTxId.peerPullDebitId);
|
||||||
parsedTxId.peerPullDebitId,
|
|
||||||
);
|
|
||||||
if (!rec) {
|
if (!rec) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
return computePeerPullDebitTransactionState(rec);
|
return computePeerPullDebitTransactionState(rec);
|
||||||
}
|
}
|
||||||
case TransactionType.PeerPushCredit: {
|
case TransactionType.PeerPushCredit: {
|
||||||
const rec = await tx.peerPushCredit.get(
|
const rec = await tx.peerPushCredit.get(parsedTxId.peerPushCreditId);
|
||||||
parsedTxId.peerPushCreditId,
|
|
||||||
);
|
|
||||||
if (!rec) {
|
if (!rec) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
return computePeerPushCreditTransactionState(rec);
|
return computePeerPushCreditTransactionState(rec);
|
||||||
}
|
}
|
||||||
case TransactionType.PeerPushDebit: {
|
case TransactionType.PeerPushDebit: {
|
||||||
const rec = await tx.peerPushDebit.get(
|
const rec = await tx.peerPushDebit.get(parsedTxId.pursePub);
|
||||||
parsedTxId.pursePub,
|
|
||||||
);
|
|
||||||
if (!rec) {
|
if (!rec) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user