wallet: implement exchange protocol v9

This commit is contained in:
Florian Dold 2021-11-17 10:23:22 +01:00
parent a994009d2f
commit 9f0429cb2f
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
23 changed files with 619 additions and 170 deletions

View File

@ -11,6 +11,6 @@
"@linaria/esbuild": "^3.0.0-beta.13", "@linaria/esbuild": "^3.0.0-beta.13",
"@linaria/shaker": "^3.0.0-beta.13", "@linaria/shaker": "^3.0.0-beta.13",
"esbuild": "^0.12.29", "esbuild": "^0.12.29",
"prettier": "^2.2.1" "prettier": "^2.4.1"
} }
} }

View File

@ -53,6 +53,7 @@
/** /**
* Imports. * Imports.
*/ */
import { DenominationPubKey, UnblindedSignature } from "./talerTypes.js";
import { Duration, Timestamp } from "./time.js"; import { Duration, Timestamp } from "./time.js";
/** /**
@ -440,7 +441,7 @@ export interface BackupCoin {
/** /**
* Unblinded signature by the exchange. * Unblinded signature by the exchange.
*/ */
denom_sig: string; denom_sig: UnblindedSignature;
/** /**
* Amount that's left on the coin. * Amount that's left on the coin.
@ -831,7 +832,7 @@ export interface BackupDenomination {
/** /**
* The denomination public key. * The denomination public key.
*/ */
denom_pub: string; denom_pub: DenominationPubKey;
/** /**
* Fee for withdrawing. * Fee for withdrawing.

View File

@ -94,7 +94,7 @@ export function canonicalJson(obj: any): string {
/** /**
* Lexically compare two strings. * Lexically compare two strings.
*/ */
export function strcmp(s1: string, s2: string): number { export function strcmp(s1: string, s2: string): -1 | 0 | 1 {
if (s1 < s2) { if (s1 < s2) {
return -1; return -1;
} }
@ -124,4 +124,3 @@ export function j2s(x: any): string {
export function notEmpty<T>(value: T | null | undefined): value is T { export function notEmpty<T>(value: T | null | undefined): value is T {
return value !== null && value !== undefined; return value !== null && value !== undefined;
} }

View File

@ -24,6 +24,7 @@
import * as nacl from "./nacl-fast.js"; import * as nacl from "./nacl-fast.js";
import { kdf } from "./kdf.js"; import { kdf } from "./kdf.js";
import bigint from "big-integer"; import bigint from "big-integer";
import { DenominationPubKey } from "./talerTypes.js";
export function getRandomBytes(n: number): Uint8Array { export function getRandomBytes(n: number): Uint8Array {
return nacl.randomBytes(n); return nacl.randomBytes(n);
@ -348,6 +349,20 @@ export function hash(d: Uint8Array): Uint8Array {
return nacl.hash(d); return nacl.hash(d);
} }
export function hashDenomPub(pub: DenominationPubKey): Uint8Array {
if (pub.cipher !== 1) {
throw Error("unsupported cipher");
}
const pubBuf = decodeCrock(pub.rsa_public_key);
const hashInputBuf = new ArrayBuffer(pubBuf.length + 4 + 4);
const uint8ArrayBuf = new Uint8Array(hashInputBuf);
const dv = new DataView(hashInputBuf);
dv.setUint32(0, pub.age_mask ?? 0);
dv.setUint32(4, pub.cipher);
uint8ArrayBuf.set(pubBuf, 8);
return nacl.hash(uint8ArrayBuf);
}
export function eddsaSign(msg: Uint8Array, eddsaPriv: Uint8Array): Uint8Array { export function eddsaSign(msg: Uint8Array, eddsaPriv: Uint8Array): Uint8Array {
const pair = nacl.crypto_sign_keyPair_fromSeed(eddsaPriv); const pair = nacl.crypto_sign_keyPair_fromSeed(eddsaPriv);
return nacl.sign_detached(msg, pair.secretKey); return nacl.sign_detached(msg, pair.secretKey);

View File

@ -59,7 +59,7 @@ export class Denomination {
/** /**
* Public signing key of the denomination. * Public signing key of the denomination.
*/ */
denom_pub: string; denom_pub: DenominationPubKey;
/** /**
* Fee for withdrawing. * Fee for withdrawing.
@ -158,7 +158,7 @@ export interface RecoupRequest {
/** /**
* Signature over the coin public key by the denomination. * Signature over the coin public key by the denomination.
*/ */
denom_sig: string; denom_sig: UnblindedSignature;
/** /**
* Coin public key of the coin we want to refund. * Coin public key of the coin we want to refund.
@ -198,6 +198,11 @@ export interface RecoupConfirmation {
old_coin_pub?: string; old_coin_pub?: string;
} }
export interface UnblindedSignature {
cipher: DenomKeyType.Rsa;
rsa_signature: string;
}
/** /**
* Deposit permission for a single coin. * Deposit permission for a single coin.
*/ */
@ -213,7 +218,7 @@ export interface CoinDepositPermission {
/** /**
* Signature made by the denomination public key. * Signature made by the denomination public key.
*/ */
ub_sig: string; ub_sig: UnblindedSignature;
/** /**
* The denomination public key associated with this coin. * The denomination public key associated with this coin.
*/ */
@ -779,8 +784,38 @@ export class TipPickupGetResponse {
expiration: Timestamp; expiration: Timestamp;
} }
export enum DenomKeyType {
Rsa = 1,
ClauseSchnorr = 2,
}
export interface RsaBlindedDenominationSignature {
cipher: DenomKeyType.Rsa;
blinded_rsa_signature: string;
}
export interface CSBlindedDenominationSignature {
cipher: DenomKeyType.ClauseSchnorr;
}
export type BlindedDenominationSignature =
| RsaBlindedDenominationSignature
| CSBlindedDenominationSignature;
export const codecForBlindedDenominationSignature = () =>
buildCodecForUnion<BlindedDenominationSignature>()
.discriminateOn("cipher")
.alternative(1, codecForRsaBlindedDenominationSignature())
.build("BlindedDenominationSignature");
export const codecForRsaBlindedDenominationSignature = () =>
buildCodecForObject<RsaBlindedDenominationSignature>()
.property("cipher", codecForConstNumber(1))
.property("blinded_rsa_signature", codecForString())
.build("RsaBlindedDenominationSignature");
export class WithdrawResponse { export class WithdrawResponse {
ev_sig: string; ev_sig: BlindedDenominationSignature;
} }
/** /**
@ -792,7 +827,7 @@ export interface CoinDumpJson {
/** /**
* The coin's denomination's public key. * The coin's denomination's public key.
*/ */
denom_pub: string; denom_pub: DenominationPubKey;
/** /**
* Hash of denom_pub. * Hash of denom_pub.
*/ */
@ -875,7 +910,7 @@ export interface ExchangeMeltResponse {
} }
export interface ExchangeRevealItem { export interface ExchangeRevealItem {
ev_sig: string; ev_sig: BlindedDenominationSignature;
} }
export interface ExchangeRevealResponse { export interface ExchangeRevealResponse {
@ -994,6 +1029,30 @@ export interface BankWithdrawalOperationPostResponse {
transfer_done: boolean; transfer_done: boolean;
} }
export type DenominationPubKey = RsaDenominationPubKey | CsDenominationPubKey;
export interface RsaDenominationPubKey {
cipher: 1;
rsa_public_key: string;
age_mask?: number;
}
export interface CsDenominationPubKey {
cipher: 2;
}
export const codecForDenominationPubKey = () =>
buildCodecForUnion<DenominationPubKey>()
.discriminateOn("cipher")
.alternative(1, codecForRsaDenominationPubKey())
.build("DenominationPubKey");
export const codecForRsaDenominationPubKey = () =>
buildCodecForObject<RsaDenominationPubKey>()
.property("cipher", codecForConstNumber(1))
.property("rsa_public_key", codecForString())
.build("DenominationPubKey");
export const codecForBankWithdrawalOperationPostResponse = (): Codec<BankWithdrawalOperationPostResponse> => export const codecForBankWithdrawalOperationPostResponse = (): Codec<BankWithdrawalOperationPostResponse> =>
buildCodecForObject<BankWithdrawalOperationPostResponse>() buildCodecForObject<BankWithdrawalOperationPostResponse>()
.property("transfer_done", codecForBoolean()) .property("transfer_done", codecForBoolean())
@ -1008,7 +1067,7 @@ export type CoinPublicKeyString = string;
export const codecForDenomination = (): Codec<Denomination> => export const codecForDenomination = (): Codec<Denomination> =>
buildCodecForObject<Denomination>() buildCodecForObject<Denomination>()
.property("value", codecForString()) .property("value", codecForString())
.property("denom_pub", codecForString()) .property("denom_pub", codecForDenominationPubKey())
.property("fee_withdraw", codecForString()) .property("fee_withdraw", codecForString())
.property("fee_deposit", codecForString()) .property("fee_deposit", codecForString())
.property("fee_refresh", codecForString()) .property("fee_refresh", codecForString())
@ -1242,7 +1301,7 @@ export const codecForRecoupConfirmation = (): Codec<RecoupConfirmation> =>
export const codecForWithdrawResponse = (): Codec<WithdrawResponse> => export const codecForWithdrawResponse = (): Codec<WithdrawResponse> =>
buildCodecForObject<WithdrawResponse>() buildCodecForObject<WithdrawResponse>()
.property("ev_sig", codecForString()) .property("ev_sig", codecForBlindedDenominationSignature())
.build("WithdrawResponse"); .build("WithdrawResponse");
export const codecForMerchantPayResponse = (): Codec<MerchantPayResponse> => export const codecForMerchantPayResponse = (): Codec<MerchantPayResponse> =>
@ -1260,7 +1319,7 @@ export const codecForExchangeMeltResponse = (): Codec<ExchangeMeltResponse> =>
export const codecForExchangeRevealItem = (): Codec<ExchangeRevealItem> => export const codecForExchangeRevealItem = (): Codec<ExchangeRevealItem> =>
buildCodecForObject<ExchangeRevealItem>() buildCodecForObject<ExchangeRevealItem>()
.property("ev_sig", codecForString()) .property("ev_sig", codecForBlindedDenominationSignature())
.build("ExchangeRevealItem"); .build("ExchangeRevealItem");
export const codecForExchangeRevealResponse = (): Codec<ExchangeRevealResponse> => export const codecForExchangeRevealResponse = (): Codec<ExchangeRevealResponse> =>

View File

@ -48,6 +48,8 @@ import {
AmountString, AmountString,
codecForContractTerms, codecForContractTerms,
ContractTerms, ContractTerms,
DenominationPubKey,
UnblindedSignature,
} from "./talerTypes.js"; } from "./talerTypes.js";
import { OrderShortInfo, codecForOrderShortInfo } from "./transactionsTypes.js"; import { OrderShortInfo, codecForOrderShortInfo } from "./transactionsTypes.js";
import { BackupRecovery } from "./backupTypes.js"; import { BackupRecovery } from "./backupTypes.js";
@ -454,7 +456,7 @@ export interface PlanchetCreationResult {
coinPriv: string; coinPriv: string;
reservePub: string; reservePub: string;
denomPubHash: string; denomPubHash: string;
denomPub: string; denomPub: DenominationPubKey;
blindingKey: string; blindingKey: string;
withdrawSig: string; withdrawSig: string;
coinEv: string; coinEv: string;
@ -467,7 +469,7 @@ export interface PlanchetCreationRequest {
coinIndex: number; coinIndex: number;
value: AmountJson; value: AmountJson;
feeWithdraw: AmountJson; feeWithdraw: AmountJson;
denomPub: string; denomPub: DenominationPubKey;
reservePub: string; reservePub: string;
reservePriv: string; reservePriv: string;
} }
@ -514,7 +516,7 @@ export interface DepositInfo {
feeDeposit: AmountJson; feeDeposit: AmountJson;
wireInfoHash: string; wireInfoHash: string;
denomPubHash: string; denomPubHash: string;
denomSig: string; denomSig: UnblindedSignature;
} }
export interface ExchangesListRespose { export interface ExchangesListRespose {

View File

@ -58,7 +58,7 @@
"rollup-plugin-sourcemaps": "^0.6.3", "rollup-plugin-sourcemaps": "^0.6.3",
"source-map-resolve": "^0.6.0", "source-map-resolve": "^0.6.0",
"typedoc": "^0.20.16", "typedoc": "^0.20.16",
"typescript": "^4.1.3" "typescript": "^4.4.4"
}, },
"dependencies": { "dependencies": {
"@gnu-taler/idb-bridge": "workspace:*", "@gnu-taler/idb-bridge": "workspace:*",

View File

@ -27,13 +27,13 @@
/** /**
* Imports. * Imports.
*/ */
import { AmountJson } from "@gnu-taler/taler-util"; import { AmountJson, DenominationPubKey } from "@gnu-taler/taler-util";
export interface RefreshNewDenomInfo { export interface RefreshNewDenomInfo {
count: number; count: number;
value: AmountJson; value: AmountJson;
feeWithdraw: AmountJson; feeWithdraw: AmountJson;
denomPub: string; denomPub: DenominationPubKey;
} }
/** /**
@ -117,7 +117,7 @@ export interface DerivedRefreshSession {
export interface DeriveTipRequest { export interface DeriveTipRequest {
secretSeed: string; secretSeed: string;
denomPub: string; denomPub: DenominationPubKey;
planchetIndex: number; planchetIndex: number;
} }

View File

@ -35,7 +35,9 @@ import {
import { import {
buildSigPS, buildSigPS,
CoinDepositPermission, CoinDepositPermission,
DenomKeyType,
FreshCoin, FreshCoin,
hashDenomPub,
RecoupRequest, RecoupRequest,
RefreshPlanchetInfo, RefreshPlanchetInfo,
TalerSignaturePurpose, TalerSignaturePurpose,
@ -152,17 +154,20 @@ export class CryptoImplementation {
* reserve. * reserve.
*/ */
createPlanchet(req: PlanchetCreationRequest): PlanchetCreationResult { createPlanchet(req: PlanchetCreationRequest): PlanchetCreationResult {
if (req.denomPub.cipher !== 1) {
throw Error("unsupported cipher");
}
const reservePub = decodeCrock(req.reservePub); const reservePub = decodeCrock(req.reservePub);
const reservePriv = decodeCrock(req.reservePriv); const reservePriv = decodeCrock(req.reservePriv);
const denomPub = decodeCrock(req.denomPub); const denomPubRsa = decodeCrock(req.denomPub.rsa_public_key);
const derivedPlanchet = setupWithdrawPlanchet( const derivedPlanchet = setupWithdrawPlanchet(
decodeCrock(req.secretSeed), decodeCrock(req.secretSeed),
req.coinIndex, req.coinIndex,
); );
const coinPubHash = hash(derivedPlanchet.coinPub); const coinPubHash = hash(derivedPlanchet.coinPub);
const ev = rsaBlind(coinPubHash, derivedPlanchet.bks, denomPub); const ev = rsaBlind(coinPubHash, derivedPlanchet.bks, denomPubRsa);
const amountWithFee = Amounts.add(req.value, req.feeWithdraw).amount; const amountWithFee = Amounts.add(req.value, req.feeWithdraw).amount;
const denomPubHash = hash(denomPub); const denomPubHash = hashDenomPub(req.denomPub);
const evHash = hash(ev); const evHash = hash(ev);
const withdrawRequest = buildSigPS( const withdrawRequest = buildSigPS(
@ -182,7 +187,10 @@ export class CryptoImplementation {
coinPriv: encodeCrock(derivedPlanchet.coinPriv), coinPriv: encodeCrock(derivedPlanchet.coinPriv),
coinPub: encodeCrock(derivedPlanchet.coinPub), coinPub: encodeCrock(derivedPlanchet.coinPub),
coinValue: req.value, coinValue: req.value,
denomPub: encodeCrock(denomPub), denomPub: {
cipher: 1,
rsa_public_key: encodeCrock(denomPubRsa),
},
denomPubHash: encodeCrock(denomPubHash), denomPubHash: encodeCrock(denomPubHash),
reservePub: encodeCrock(reservePub), reservePub: encodeCrock(reservePub),
withdrawSig: encodeCrock(sig), withdrawSig: encodeCrock(sig),
@ -195,8 +203,11 @@ export class CryptoImplementation {
* Create a planchet used for tipping, including the private keys. * Create a planchet used for tipping, including the private keys.
*/ */
createTipPlanchet(req: DeriveTipRequest): DerivedTipPlanchet { createTipPlanchet(req: DeriveTipRequest): DerivedTipPlanchet {
if (req.denomPub.cipher !== 1) {
throw Error("unsupported cipher");
}
const fc = setupTipPlanchet(decodeCrock(req.secretSeed), req.planchetIndex); const fc = setupTipPlanchet(decodeCrock(req.secretSeed), req.planchetIndex);
const denomPub = decodeCrock(req.denomPub); const denomPub = decodeCrock(req.denomPub.rsa_public_key);
const coinPubHash = hash(fc.coinPub); const coinPubHash = hash(fc.coinPub);
const ev = rsaBlind(coinPubHash, fc.bks, denomPub); const ev = rsaBlind(coinPubHash, fc.bks, denomPub);
@ -319,14 +330,9 @@ export class CryptoImplementation {
sig: string, sig: string,
masterPub: string, masterPub: string,
): boolean { ): boolean {
const h = kdf( const paytoHash = hash(stringToBytes(paytoUri + "\0"));
64,
stringToBytes("exchange-wire-signature"),
stringToBytes(paytoUri + "\0"),
new Uint8Array(0),
);
const p = buildSigPS(TalerSignaturePurpose.MASTER_WIRE_DETAILS) const p = buildSigPS(TalerSignaturePurpose.MASTER_WIRE_DETAILS)
.put(h) .put(paytoHash)
.build(); .build();
return eddsaVerify(p, decodeCrock(sig), decodeCrock(masterPub)); return eddsaVerify(p, decodeCrock(sig), decodeCrock(masterPub));
} }
@ -385,8 +391,11 @@ export class CryptoImplementation {
* and deposit permissions for each given coin. * and deposit permissions for each given coin.
*/ */
signDepositPermission(depositInfo: DepositInfo): CoinDepositPermission { signDepositPermission(depositInfo: DepositInfo): CoinDepositPermission {
// FIXME: put extensions here if used
const hExt = new Uint8Array(64);
const d = buildSigPS(TalerSignaturePurpose.WALLET_COIN_DEPOSIT) const d = buildSigPS(TalerSignaturePurpose.WALLET_COIN_DEPOSIT)
.put(decodeCrock(depositInfo.contractTermsHash)) .put(decodeCrock(depositInfo.contractTermsHash))
.put(hExt)
.put(decodeCrock(depositInfo.wireInfoHash)) .put(decodeCrock(depositInfo.wireInfoHash))
.put(decodeCrock(depositInfo.denomPubHash)) .put(decodeCrock(depositInfo.denomPubHash))
.put(timestampRoundedToBuffer(depositInfo.timestamp)) .put(timestampRoundedToBuffer(depositInfo.timestamp))
@ -394,7 +403,6 @@ export class CryptoImplementation {
.put(amountToBuffer(depositInfo.spendAmount)) .put(amountToBuffer(depositInfo.spendAmount))
.put(amountToBuffer(depositInfo.feeDeposit)) .put(amountToBuffer(depositInfo.feeDeposit))
.put(decodeCrock(depositInfo.merchantPub)) .put(decodeCrock(depositInfo.merchantPub))
.put(decodeCrock(depositInfo.coinPub))
.build(); .build();
const coinSig = eddsaSign(d, decodeCrock(depositInfo.coinPriv)); const coinSig = eddsaSign(d, decodeCrock(depositInfo.coinPriv));
@ -404,7 +412,10 @@ export class CryptoImplementation {
contribution: Amounts.stringify(depositInfo.spendAmount), contribution: Amounts.stringify(depositInfo.spendAmount),
h_denom: depositInfo.denomPubHash, h_denom: depositInfo.denomPubHash,
exchange_url: depositInfo.exchangeBaseUrl, exchange_url: depositInfo.exchangeBaseUrl,
ub_sig: depositInfo.denomSig, ub_sig: {
cipher: DenomKeyType.Rsa,
rsa_signature: depositInfo.denomSig.rsa_signature,
},
}; };
return s; return s;
} }
@ -455,8 +466,10 @@ export class CryptoImplementation {
for (const denomSel of newCoinDenoms) { for (const denomSel of newCoinDenoms) {
for (let i = 0; i < denomSel.count; i++) { for (let i = 0; i < denomSel.count; i++) {
const r = decodeCrock(denomSel.denomPub); if (denomSel.denomPub.cipher !== 1) {
sessionHc.update(r); throw Error("unsupported cipher");
}
sessionHc.update(hashDenomPub(denomSel.denomPub));
} }
} }
@ -495,7 +508,10 @@ export class CryptoImplementation {
blindingFactor = fresh.bks; blindingFactor = fresh.bks;
} }
const pubHash = hash(coinPub); const pubHash = hash(coinPub);
const denomPub = decodeCrock(denomSel.denomPub); if (denomSel.denomPub.cipher !== 1) {
throw Error("unsupported cipher");
}
const denomPub = decodeCrock(denomSel.denomPub.rsa_public_key);
const ev = rsaBlind(pubHash, blindingFactor, denomPub); const ev = rsaBlind(pubHash, blindingFactor, denomPub);
const planchet: RefreshPlanchetInfo = { const planchet: RefreshPlanchetInfo = {
blindingKey: encodeCrock(blindingFactor), blindingKey: encodeCrock(blindingFactor),

View File

@ -28,6 +28,7 @@ import {
Auditor, Auditor,
CoinDepositPermission, CoinDepositPermission,
ContractTerms, ContractTerms,
DenominationPubKey,
Duration, Duration,
ExchangeSignKeyJson, ExchangeSignKeyJson,
InternationalizedString, InternationalizedString,
@ -36,6 +37,7 @@ import {
RefreshReason, RefreshReason,
TalerErrorDetails, TalerErrorDetails,
Timestamp, Timestamp,
UnblindedSignature,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { RetryInfo } from "./util/retries.js"; import { RetryInfo } from "./util/retries.js";
import { PayCoinSelection } from "./util/coinSelection.js"; import { PayCoinSelection } from "./util/coinSelection.js";
@ -310,7 +312,7 @@ export interface DenominationRecord {
/** /**
* The denomination public key. * The denomination public key.
*/ */
denomPub: string; denomPub: DenominationPubKey;
/** /**
* Hash of the denomination public key. * Hash of the denomination public key.
@ -578,7 +580,8 @@ export interface PlanchetRecord {
denomPubHash: string; denomPubHash: string;
denomPub: string; // FIXME: maybe too redundant?
denomPub: DenominationPubKey;
blindingKey: string; blindingKey: string;
@ -668,7 +671,7 @@ export interface CoinRecord {
/** /**
* Key used by the exchange used to sign the coin. * Key used by the exchange used to sign the coin.
*/ */
denomPub: string; denomPub: DenominationPubKey;
/** /**
* Hash of the public key that signs the coin. * Hash of the public key that signs the coin.
@ -678,7 +681,7 @@ export interface CoinRecord {
/** /**
* Unblinded signature by the exchange. * Unblinded signature by the exchange.
*/ */
denomSig: string; denomSig: UnblindedSignature;
/** /**
* Amount that's left on the coin. * Amount that's left on the coin.

View File

@ -93,7 +93,7 @@ export async function guardOperationException<T>(
): Promise<T> { ): Promise<T> {
try { try {
return await op(); return await op();
} catch (e) { } catch (e: any) {
if (e instanceof OperationFailedAndReportedError) { if (e instanceof OperationFailedAndReportedError) {
throw e; throw e;
} }

View File

@ -202,7 +202,7 @@ export interface CompletedCoin {
* as the async crypto worker communication would auto-close the database transaction. * as the async crypto worker communication would auto-close the database transaction.
*/ */
export interface BackupCryptoPrecomputedData { export interface BackupCryptoPrecomputedData {
denomPubToHash: Record<string, string>; rsaDenomPubToHash: Record<string, string>;
coinPrivToCompletedCoin: Record<string, CompletedCoin>; coinPrivToCompletedCoin: Record<string, CompletedCoin>;
proposalNoncePrivToPub: { [priv: string]: string }; proposalNoncePrivToPub: { [priv: string]: string };
proposalIdToContractTermsHash: { [proposalId: string]: string }; proposalIdToContractTermsHash: { [proposalId: string]: string };
@ -330,8 +330,13 @@ export async function importBackup(
} }
for (const backupDenomination of backupExchangeDetails.denominations) { for (const backupDenomination of backupExchangeDetails.denominations) {
if (backupDenomination.denom_pub.cipher !== 1) {
throw Error("unsupported cipher");
}
const denomPubHash = const denomPubHash =
cryptoComp.denomPubToHash[backupDenomination.denom_pub]; cryptoComp.rsaDenomPubToHash[
backupDenomination.denom_pub.rsa_public_key
];
checkLogicInvariant(!!denomPubHash); checkLogicInvariant(!!denomPubHash);
const existingDenom = await tx.denominations.get([ const existingDenom = await tx.denominations.get([
backupExchangeDetails.base_url, backupExchangeDetails.base_url,

View File

@ -40,6 +40,7 @@ import {
ConfirmPayResultType, ConfirmPayResultType,
durationFromSpec, durationFromSpec,
getTimestampNow, getTimestampNow,
hashDenomPub,
HttpStatusCode, HttpStatusCode,
j2s, j2s,
Logger, Logger,
@ -57,10 +58,7 @@ import {
import { gunzipSync, gzipSync } from "fflate"; import { gunzipSync, gzipSync } from "fflate";
import { InternalWalletState } from "../../common.js"; import { InternalWalletState } from "../../common.js";
import { kdf } from "@gnu-taler/taler-util"; import { kdf } from "@gnu-taler/taler-util";
import { import { secretbox, secretbox_open } from "@gnu-taler/taler-util";
secretbox,
secretbox_open,
} from "@gnu-taler/taler-util";
import { import {
bytesToString, bytesToString,
decodeCrock, decodeCrock,
@ -162,13 +160,16 @@ async function computeBackupCryptoData(
): Promise<BackupCryptoPrecomputedData> { ): Promise<BackupCryptoPrecomputedData> {
const cryptoData: BackupCryptoPrecomputedData = { const cryptoData: BackupCryptoPrecomputedData = {
coinPrivToCompletedCoin: {}, coinPrivToCompletedCoin: {},
denomPubToHash: {}, rsaDenomPubToHash: {},
proposalIdToContractTermsHash: {}, proposalIdToContractTermsHash: {},
proposalNoncePrivToPub: {}, proposalNoncePrivToPub: {},
reservePrivToPub: {}, reservePrivToPub: {},
}; };
for (const backupExchangeDetails of backupContent.exchange_details) { for (const backupExchangeDetails of backupContent.exchange_details) {
for (const backupDenom of backupExchangeDetails.denominations) { for (const backupDenom of backupExchangeDetails.denominations) {
if (backupDenom.denom_pub.cipher !== 1) {
throw Error("unsupported cipher");
}
for (const backupCoin of backupDenom.coins) { for (const backupCoin of backupDenom.coins) {
const coinPub = encodeCrock( const coinPub = encodeCrock(
eddsaGetPublic(decodeCrock(backupCoin.coin_priv)), eddsaGetPublic(decodeCrock(backupCoin.coin_priv)),
@ -176,16 +177,16 @@ async function computeBackupCryptoData(
const blindedCoin = rsaBlind( const blindedCoin = rsaBlind(
hash(decodeCrock(backupCoin.coin_priv)), hash(decodeCrock(backupCoin.coin_priv)),
decodeCrock(backupCoin.blinding_key), decodeCrock(backupCoin.blinding_key),
decodeCrock(backupDenom.denom_pub), decodeCrock(backupDenom.denom_pub.rsa_public_key),
); );
cryptoData.coinPrivToCompletedCoin[backupCoin.coin_priv] = { cryptoData.coinPrivToCompletedCoin[backupCoin.coin_priv] = {
coinEvHash: encodeCrock(hash(blindedCoin)), coinEvHash: encodeCrock(hash(blindedCoin)),
coinPub, coinPub,
}; };
} }
cryptoData.denomPubToHash[backupDenom.denom_pub] = encodeCrock( cryptoData.rsaDenomPubToHash[
hash(decodeCrock(backupDenom.denom_pub)), backupDenom.denom_pub.rsa_public_key
); ] = encodeCrock(hashDenomPub(backupDenom.denom_pub));
} }
for (const backupReserve of backupExchangeDetails.reserves) { for (const backupReserve of backupExchangeDetails.reserves) {
cryptoData.reservePrivToPub[backupReserve.reserve_priv] = encodeCrock( cryptoData.reservePrivToPub[backupReserve.reserve_priv] = encodeCrock(

View File

@ -25,6 +25,7 @@ import {
ContractTerms, ContractTerms,
CreateDepositGroupRequest, CreateDepositGroupRequest,
CreateDepositGroupResponse, CreateDepositGroupResponse,
decodeCrock,
durationFromSpec, durationFromSpec,
getTimestampNow, getTimestampNow,
Logger, Logger,
@ -106,7 +107,7 @@ function hashWire(paytoUri: string, salt: string): string {
const r = kdf( const r = kdf(
64, 64,
stringToBytes(paytoUri + "\0"), stringToBytes(paytoUri + "\0"),
stringToBytes(salt + "\0"), decodeCrock(salt),
stringToBytes("merchant-wire-signature"), stringToBytes("merchant-wire-signature"),
); );
return encodeCrock(r); return encodeCrock(r);
@ -213,8 +214,8 @@ async function processDepositGroupImpl(
const url = new URL(`coins/${perm.coin_pub}/deposit`, perm.exchange_url); const url = new URL(`coins/${perm.coin_pub}/deposit`, perm.exchange_url);
const httpResp = await ws.http.postJson(url.href, { const httpResp = await ws.http.postJson(url.href, {
contribution: Amounts.stringify(perm.contribution), contribution: Amounts.stringify(perm.contribution),
wire: depositGroup.wire, merchant_payto_uri: depositGroup.wire.payto_uri,
h_wire: depositGroup.contractTermsRaw.h_wire, wire_salt: depositGroup.wire.salt,
h_contract_terms: depositGroup.contractTermsHash, h_contract_terms: depositGroup.contractTermsHash,
ub_sig: perm.ub_sig, ub_sig: perm.ub_sig,
timestamp: depositGroup.contractTermsRaw.timestamp, timestamp: depositGroup.contractTermsRaw.timestamp,
@ -355,7 +356,7 @@ export async function createDepositGroup(
const timestampRound = timestampTruncateToSecond(timestamp); const timestampRound = timestampTruncateToSecond(timestamp);
const noncePair = await ws.cryptoApi.createEddsaKeypair(); const noncePair = await ws.cryptoApi.createEddsaKeypair();
const merchantPair = await ws.cryptoApi.createEddsaKeypair(); const merchantPair = await ws.cryptoApi.createEddsaKeypair();
const wireSalt = encodeCrock(getRandomBytes(64)); const wireSalt = encodeCrock(getRandomBytes(16));
const wireHash = hashWire(req.depositPaytoUri, wireSalt); const wireHash = hashWire(req.depositPaytoUri, wireSalt);
const contractTerms: ContractTerms = { const contractTerms: ContractTerms = {
auditors: [], auditors: [],

View File

@ -39,6 +39,7 @@ import {
URL, URL,
TalerErrorDetails, TalerErrorDetails,
Timestamp, Timestamp,
hashDenomPub,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { decodeCrock, encodeCrock, hash } from "@gnu-taler/taler-util"; import { decodeCrock, encodeCrock, hash } from "@gnu-taler/taler-util";
import { CryptoApi } from "../crypto/workers/cryptoApi.js"; import { CryptoApi } from "../crypto/workers/cryptoApi.js";
@ -78,7 +79,7 @@ function denominationRecordFromKeys(
listIssueDate: Timestamp, listIssueDate: Timestamp,
denomIn: Denomination, denomIn: Denomination,
): DenominationRecord { ): DenominationRecord {
const denomPubHash = encodeCrock(hash(decodeCrock(denomIn.denom_pub))); const denomPubHash = encodeCrock(hashDenomPub(denomIn.denom_pub));
const d: DenominationRecord = { const d: DenominationRecord = {
denomPub: denomIn.denom_pub, denomPub: denomIn.denom_pub,
denomPubHash, denomPubHash,
@ -472,25 +473,28 @@ async function updateExchangeFromUrlImpl(
let tosFound: ExchangeTosDownloadResult | undefined; let tosFound: ExchangeTosDownloadResult | undefined;
//Remove this when exchange supports multiple content-type in accept header //Remove this when exchange supports multiple content-type in accept header
if (acceptedFormat) for (const format of acceptedFormat) { if (acceptedFormat)
for (const format of acceptedFormat) {
const resp = await downloadExchangeWithTermsOfService( const resp = await downloadExchangeWithTermsOfService(
baseUrl, baseUrl,
ws.http, ws.http,
timeout, timeout,
format format,
); );
if (resp.tosContentType === format) { if (resp.tosContentType === format) {
tosFound = resp tosFound = resp;
break break;
} }
} }
// If none of the specified format was found try text/plain // If none of the specified format was found try text/plain
const tosDownload = tosFound !== undefined ? tosFound : const tosDownload =
await downloadExchangeWithTermsOfService( tosFound !== undefined
? tosFound
: await downloadExchangeWithTermsOfService(
baseUrl, baseUrl,
ws.http, ws.http,
timeout, timeout,
"text/plain" "text/plain",
); );
let recoupGroupId: string | undefined = undefined; let recoupGroupId: string | undefined = undefined;

View File

@ -14,7 +14,12 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/ */
import { encodeCrock, getRandomBytes, HttpStatusCode } from "@gnu-taler/taler-util"; import {
DenomKeyType,
encodeCrock,
getRandomBytes,
HttpStatusCode,
} from "@gnu-taler/taler-util";
import { import {
CoinRecord, CoinRecord,
CoinSourceType, CoinSourceType,
@ -599,10 +604,17 @@ async function refreshReveal(
continue; continue;
} }
const pc = derived.planchetsForGammas[norevealIndex][newCoinIndex]; const pc = derived.planchetsForGammas[norevealIndex][newCoinIndex];
const denomSig = await ws.cryptoApi.rsaUnblind( if (denom.denomPub.cipher !== 1) {
reveal.ev_sigs[newCoinIndex].ev_sig, throw Error("cipher unsupported");
}
const evSig = reveal.ev_sigs[newCoinIndex].ev_sig;
if (evSig.cipher !== DenomKeyType.Rsa) {
throw Error("unsupported cipher");
}
const denomSigRsa = await ws.cryptoApi.rsaUnblind(
evSig.blinded_rsa_signature,
pc.blindingKey, pc.blindingKey,
denom.denomPub, denom.denomPub.rsa_public_key,
); );
const coin: CoinRecord = { const coin: CoinRecord = {
blindingKey: pc.blindingKey, blindingKey: pc.blindingKey,
@ -611,7 +623,10 @@ async function refreshReveal(
currentAmount: denom.value, currentAmount: denom.value,
denomPub: denom.denomPub, denomPub: denom.denomPub,
denomPubHash: denom.denomPubHash, denomPubHash: denom.denomPubHash,
denomSig, denomSig: {
cipher: DenomKeyType.Rsa,
rsa_signature: denomSigRsa,
},
exchangeBaseUrl: oldCoin.exchangeBaseUrl, exchangeBaseUrl: oldCoin.exchangeBaseUrl,
status: CoinStatus.Fresh, status: CoinStatus.Fresh,
coinSource: { coinSource: {

View File

@ -30,6 +30,7 @@ import {
codecForTipResponse, codecForTipResponse,
Logger, Logger,
URL, URL,
DenomKeyType,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { DerivedTipPlanchet } from "../crypto/cryptoTypes.js"; import { DerivedTipPlanchet } from "../crypto/cryptoTypes.js";
import { import {
@ -322,16 +323,20 @@ async function processTipImpl(
const planchet = planchets[i]; const planchet = planchets[i];
checkLogicInvariant(!!planchet); checkLogicInvariant(!!planchet);
const denomSig = await ws.cryptoApi.rsaUnblind( if (denom.denomPub.cipher !== 1) {
throw Error("unsupported cipher");
}
const denomSigRsa = await ws.cryptoApi.rsaUnblind(
blindedSig, blindedSig,
planchet.blindingKey, planchet.blindingKey,
denom.denomPub, denom.denomPub.rsa_public_key,
); );
const isValid = await ws.cryptoApi.rsaVerify( const isValid = await ws.cryptoApi.rsaVerify(
planchet.coinPub, planchet.coinPub,
denomSig, denomSigRsa,
denom.denomPub, denom.denomPub.rsa_public_key,
); );
if (!isValid) { if (!isValid) {
@ -364,7 +369,7 @@ async function processTipImpl(
currentAmount: denom.value, currentAmount: denom.value,
denomPub: denom.denomPub, denomPub: denom.denomPub,
denomPubHash: denom.denomPubHash, denomPubHash: denom.denomPubHash,
denomSig: denomSig, denomSig: { cipher: DenomKeyType.Rsa, rsa_signature: denomSigRsa },
exchangeBaseUrl: tipRecord.exchangeBaseUrl, exchangeBaseUrl: tipRecord.exchangeBaseUrl,
status: CoinStatus.Fresh, status: CoinStatus.Fresh,
suspended: false, suspended: false,

View File

@ -28,8 +28,11 @@ test("withdrawal selection bug repro", (t) => {
const denoms: DenominationRecord[] = [ const denoms: DenominationRecord[] = [
{ {
denomPub: denomPub: {
cipher: 1,
rsa_public_key:
"040000XT67C8KBD6B75TTQ3SK8FWXMNQW4372T3BDDGPAMB9RFCA03638W8T3F71WFEFK9NP32VKYVNFXPYRWQ1N1HDKV5J0DFEKHBPJCYSWCBJDRNWD7G8BN8PT97FA9AMV75MYEK4X54D1HGJ207JSVJBGFCATSPNTEYNHEQF1F220W00TBZR1HNPDQFD56FG0DJQ9KGHM8EC33H6AY9YN9CNX5R3Z4TZ4Q23W47SBHB13H6W74FQJG1F50X38VRSC4SR8RWBAFB7S4K8D2H4NMRFSQT892A3T0BTBW7HM5C0H2CK6FRKG31F7W9WP1S29013K5CXYE55CT8TH6N8J9B780R42Y5S3ZB6J6E9H76XBPSGH4TGYSR2VZRB98J417KCQMZKX1BB67E7W5KVE37TC9SJ904002", "040000XT67C8KBD6B75TTQ3SK8FWXMNQW4372T3BDDGPAMB9RFCA03638W8T3F71WFEFK9NP32VKYVNFXPYRWQ1N1HDKV5J0DFEKHBPJCYSWCBJDRNWD7G8BN8PT97FA9AMV75MYEK4X54D1HGJ207JSVJBGFCATSPNTEYNHEQF1F220W00TBZR1HNPDQFD56FG0DJQ9KGHM8EC33H6AY9YN9CNX5R3Z4TZ4Q23W47SBHB13H6W74FQJG1F50X38VRSC4SR8RWBAFB7S4K8D2H4NMRFSQT892A3T0BTBW7HM5C0H2CK6FRKG31F7W9WP1S29013K5CXYE55CT8TH6N8J9B780R42Y5S3ZB6J6E9H76XBPSGH4TGYSR2VZRB98J417KCQMZKX1BB67E7W5KVE37TC9SJ904002",
},
denomPubHash: denomPubHash:
"Q21FQSSG4FXNT96Z14CHXM8N1RZAG9GPHAV8PRWS0PZAAVWH7PBW6R97M2CH19KKP65NNSWXY7B6S53PT3CBM342E357ZXDDJ8RDVW8", "Q21FQSSG4FXNT96Z14CHXM8N1RZAG9GPHAV8PRWS0PZAAVWH7PBW6R97M2CH19KKP65NNSWXY7B6S53PT3CBM342E357ZXDDJ8RDVW8",
exchangeBaseUrl: "https://exchange.demo.taler.net/", exchangeBaseUrl: "https://exchange.demo.taler.net/",
@ -79,8 +82,12 @@ test("withdrawal selection bug repro", (t) => {
listIssueDate: { t_ms: 0 }, listIssueDate: { t_ms: 0 },
}, },
{ {
denomPub: denomPub: {
cipher: 1,
rsa_public_key:
"040000Y63CF78QFPKRY77BRK9P557Q1GQWX3NCZ3HSYSK0Z7TT0KGRA7N4SKBKEHSTVHX1Z9DNXMJR4EXSY1TXCKV0GJ3T3YYC6Z0JNMJFVYQAV4FX5J90NZH1N33MZTV8HS9SMNAA9S6K73G4P99GYBB01B0P6M1KXZ5JRDR7VWBR3MEJHHGJ6QBMCJR3NWJRE3WJW9PRY8QPQ2S7KFWTWRESH2DBXCXWBD2SRN6P9YX8GRAEMFEGXC9V5GVJTEMH6ZDGNXFPWZE3JVJ2Q4N9GDYKBCHZCJ7M7M2RJ9ZV4Y64NAN9BT6XDC68215GKKRHTW1BBF1MYY6AR3JCTT9HYAM923RMVQR3TAEB7SDX8J76XRZWYH3AGJCZAQGMN5C8SSH9AHQ9RNQJQ15CN45R37X4YNFJV904002", "040000Y63CF78QFPKRY77BRK9P557Q1GQWX3NCZ3HSYSK0Z7TT0KGRA7N4SKBKEHSTVHX1Z9DNXMJR4EXSY1TXCKV0GJ3T3YYC6Z0JNMJFVYQAV4FX5J90NZH1N33MZTV8HS9SMNAA9S6K73G4P99GYBB01B0P6M1KXZ5JRDR7VWBR3MEJHHGJ6QBMCJR3NWJRE3WJW9PRY8QPQ2S7KFWTWRESH2DBXCXWBD2SRN6P9YX8GRAEMFEGXC9V5GVJTEMH6ZDGNXFPWZE3JVJ2Q4N9GDYKBCHZCJ7M7M2RJ9ZV4Y64NAN9BT6XDC68215GKKRHTW1BBF1MYY6AR3JCTT9HYAM923RMVQR3TAEB7SDX8J76XRZWYH3AGJCZAQGMN5C8SSH9AHQ9RNQJQ15CN45R37X4YNFJV904002",
},
denomPubHash: denomPubHash:
"447WA23SCBATMABHA0793F92MYTBYVPYMMQHCPKMKVY5P7RZRFMQ6VRW0Y8HRA7177GTBT0TBT08R21DZD129AJ995H9G09XBFE55G8", "447WA23SCBATMABHA0793F92MYTBYVPYMMQHCPKMKVY5P7RZRFMQ6VRW0Y8HRA7177GTBT0TBT08R21DZD129AJ995H9G09XBFE55G8",
exchangeBaseUrl: "https://exchange.demo.taler.net/", exchangeBaseUrl: "https://exchange.demo.taler.net/",
@ -130,8 +137,11 @@ test("withdrawal selection bug repro", (t) => {
listIssueDate: { t_ms: 0 }, listIssueDate: { t_ms: 0 },
}, },
{ {
denomPub: denomPub: {
cipher: 1,
rsa_public_key:
"040000YDESWC2B962DA4WK356SC50MA3N9KV0ZSGY3RC48JCTY258W909C7EEMT5BTC5KZ5T4CERCZ141P9QF87EK2BD1XEEM5GB07MB3H19WE4CQGAS8X84JBWN83PQGQXVMWE5HFA992KMGHC566GT9ZS2QPHZB6X89C4A80Z663PYAAPXP728VHAKATGNNBQ01ZZ2XD1CH9Y38YZBSPJ4K7GB2J76GBCYAVD9ENHDVWXJAXYRPBX4KSS5TXRR3K5NEN9ZV3AJD2V65K7ABRZDF5D5V1FJZZMNJ5XZ4FEREEKEBV9TDFPGJTKDEHEC60K3DN24DAATRESDJ1ZYYSYSRCAT4BT2B62ARGVMJTT5N2R126DRW9TGRWCW0ZAF2N2WET1H4NJEW77X0QT46Z5R3MZ0XPHD04002", "040000YDESWC2B962DA4WK356SC50MA3N9KV0ZSGY3RC48JCTY258W909C7EEMT5BTC5KZ5T4CERCZ141P9QF87EK2BD1XEEM5GB07MB3H19WE4CQGAS8X84JBWN83PQGQXVMWE5HFA992KMGHC566GT9ZS2QPHZB6X89C4A80Z663PYAAPXP728VHAKATGNNBQ01ZZ2XD1CH9Y38YZBSPJ4K7GB2J76GBCYAVD9ENHDVWXJAXYRPBX4KSS5TXRR3K5NEN9ZV3AJD2V65K7ABRZDF5D5V1FJZZMNJ5XZ4FEREEKEBV9TDFPGJTKDEHEC60K3DN24DAATRESDJ1ZYYSYSRCAT4BT2B62ARGVMJTT5N2R126DRW9TGRWCW0ZAF2N2WET1H4NJEW77X0QT46Z5R3MZ0XPHD04002",
},
denomPubHash: denomPubHash:
"JS61DTKAFM0BX8Q4XV3ZSKB921SM8QK745Z2AFXTKFMBHHFNBD8TQ5ETJHFNDGBGX22FFN2A2ERNYG1SGSDQWNQHQQ2B14DBVJYJG8R", "JS61DTKAFM0BX8Q4XV3ZSKB921SM8QK745Z2AFXTKFMBHHFNBD8TQ5ETJHFNDGBGX22FFN2A2ERNYG1SGSDQWNQHQQ2B14DBVJYJG8R",
exchangeBaseUrl: "https://exchange.demo.taler.net/", exchangeBaseUrl: "https://exchange.demo.taler.net/",
@ -181,8 +191,12 @@ test("withdrawal selection bug repro", (t) => {
listIssueDate: { t_ms: 0 }, listIssueDate: { t_ms: 0 },
}, },
{ {
denomPub: denomPub: {
cipher: 1,
rsa_public_key:
"040000YG3T1ADB8DVA6BD3EPV6ZHSHTDW35DEN4VH1AE6CSB7P1PSDTNTJG866PHF6QB1CCWYCVRGA0FVBJ9Q0G7KV7AD9010GDYBQH0NNPHW744MTNXVXWBGGGRGQGYK4DTYN1DSWQ1FZNDSZZPB5BEKG2PDJ93NX2JTN06Y8QMS2G734Z9XHC10EENBG2KVB7EJ3CM8PV1T32RC7AY62F3496E8D8KRHJQQTT67DSGMNKK86QXVDTYW677FG27DP20E8XY3M6FQD53NDJ1WWES91401MV1A3VXVPGC76GZVDD62W3WTJ1YMKHTTA3MRXX3VEAAH3XTKDN1ER7X6CZPMYTF8VK735VP2B2TZGTF28TTW4FZS32SBS64APCDF6SZQ427N5538TJC7SRE71YSP5ET8GS904002", "040000YG3T1ADB8DVA6BD3EPV6ZHSHTDW35DEN4VH1AE6CSB7P1PSDTNTJG866PHF6QB1CCWYCVRGA0FVBJ9Q0G7KV7AD9010GDYBQH0NNPHW744MTNXVXWBGGGRGQGYK4DTYN1DSWQ1FZNDSZZPB5BEKG2PDJ93NX2JTN06Y8QMS2G734Z9XHC10EENBG2KVB7EJ3CM8PV1T32RC7AY62F3496E8D8KRHJQQTT67DSGMNKK86QXVDTYW677FG27DP20E8XY3M6FQD53NDJ1WWES91401MV1A3VXVPGC76GZVDD62W3WTJ1YMKHTTA3MRXX3VEAAH3XTKDN1ER7X6CZPMYTF8VK735VP2B2TZGTF28TTW4FZS32SBS64APCDF6SZQ427N5538TJC7SRE71YSP5ET8GS904002",
},
denomPubHash: denomPubHash:
"8T51NEY81VMPQ180EQ5WR0YH7GMNNT90W55Q0514KZM18AZT71FHJGJHQXGK0WTA7ACN1X2SD0S53XPBQ1A9KH960R48VCVVM6E3TH8", "8T51NEY81VMPQ180EQ5WR0YH7GMNNT90W55Q0514KZM18AZT71FHJGJHQXGK0WTA7ACN1X2SD0S53XPBQ1A9KH960R48VCVVM6E3TH8",
exchangeBaseUrl: "https://exchange.demo.taler.net/", exchangeBaseUrl: "https://exchange.demo.taler.net/",
@ -232,8 +246,11 @@ test("withdrawal selection bug repro", (t) => {
listIssueDate: { t_ms: 0 }, listIssueDate: { t_ms: 0 },
}, },
{ {
denomPub: denomPub: {
cipher: 1,
rsa_public_key:
"040000ZC0G60E9QQ5PD81TSDWD9GV5Y6P8Z05NSPA696DP07NGQQVSRQXBA76Q6PRB0YFX295RG4MTQJXAZZ860ET307HSC2X37XAVGQXRVB8Q4F1V7NP5ZEVKTX75DZK1QRAVHEZGQYKSSH6DBCJNQF6V9WNQF3GEYVA4KCBHA7JF772KHXM9642C28Z0AS4XXXV2PABAN5C8CHYD5H7JDFNK3920W5Q69X0BS84XZ4RE2PW6HM1WZ6KGZ3MKWWWCPKQ1FSFABRBWKAB09PF563BEBXKY6M38QETPH5EDWGANHD0SC3QV0WXYVB7BNHNNQ0J5BNV56K563SYHM4E5ND260YRJSYA1GN5YSW2B1J5T1A1EBNYF2DN6JNJKWXWEQ42G5YS17ZSZ5EWDRA9QKV8EGTCNAD04002", "040000ZC0G60E9QQ5PD81TSDWD9GV5Y6P8Z05NSPA696DP07NGQQVSRQXBA76Q6PRB0YFX295RG4MTQJXAZZ860ET307HSC2X37XAVGQXRVB8Q4F1V7NP5ZEVKTX75DZK1QRAVHEZGQYKSSH6DBCJNQF6V9WNQF3GEYVA4KCBHA7JF772KHXM9642C28Z0AS4XXXV2PABAN5C8CHYD5H7JDFNK3920W5Q69X0BS84XZ4RE2PW6HM1WZ6KGZ3MKWWWCPKQ1FSFABRBWKAB09PF563BEBXKY6M38QETPH5EDWGANHD0SC3QV0WXYVB7BNHNNQ0J5BNV56K563SYHM4E5ND260YRJSYA1GN5YSW2B1J5T1A1EBNYF2DN6JNJKWXWEQ42G5YS17ZSZ5EWDRA9QKV8EGTCNAD04002",
},
denomPubHash: denomPubHash:
"A41HW0Q2H9PCNMEWW0C0N45QAYVXZ8SBVRRAHE4W6X24SV1TH38ANTWDT80JXEBW9Z8PVPGT9GFV2EYZWJ5JW5W1N34NFNKHQSZ1PFR", "A41HW0Q2H9PCNMEWW0C0N45QAYVXZ8SBVRRAHE4W6X24SV1TH38ANTWDT80JXEBW9Z8PVPGT9GFV2EYZWJ5JW5W1N34NFNKHQSZ1PFR",
exchangeBaseUrl: "https://exchange.demo.taler.net/", exchangeBaseUrl: "https://exchange.demo.taler.net/",
@ -283,8 +300,11 @@ test("withdrawal selection bug repro", (t) => {
listIssueDate: { t_ms: 0 }, listIssueDate: { t_ms: 0 },
}, },
{ {
denomPub: denomPub: {
cipher: 1,
rsa_public_key:
"040000ZSK2PMVY6E3NBQ52KXMW029M60F4BWYTDS0FZSD0PE53CNZ9H6TM3GQK1WRTEKQ5GRWJ1J9DY6Y42SP47QVT1XD1G0W05SQ5F3F7P5KSWR0FJBJ9NZBXQEVN8Q4JRC94X3JJ3XV3KBYTZ2HTDFV28C3H2SRR0XGNZB4FY85NDZF1G4AEYJJ9QB3C0V8H70YB8RV3FKTNH7XS4K4HFNZHJ5H9VMX5SM9Z2DX37HA5WFH0E2MJBVVF2BWWA5M0HPPSB365RAE2AMD42Q65A96WD80X27SB2ZNQZ8WX0K13FWF85GZ6YNYAJGE1KGN06JDEKE9QD68Z651D7XE8V6664TVVC8M68S7WD0DSXMJQKQ0BNJXNDE29Q7MRX6DA3RW0PZ44B3TKRK0294FPVZTNSTA6XF04002", "040000ZSK2PMVY6E3NBQ52KXMW029M60F4BWYTDS0FZSD0PE53CNZ9H6TM3GQK1WRTEKQ5GRWJ1J9DY6Y42SP47QVT1XD1G0W05SQ5F3F7P5KSWR0FJBJ9NZBXQEVN8Q4JRC94X3JJ3XV3KBYTZ2HTDFV28C3H2SRR0XGNZB4FY85NDZF1G4AEYJJ9QB3C0V8H70YB8RV3FKTNH7XS4K4HFNZHJ5H9VMX5SM9Z2DX37HA5WFH0E2MJBVVF2BWWA5M0HPPSB365RAE2AMD42Q65A96WD80X27SB2ZNQZ8WX0K13FWF85GZ6YNYAJGE1KGN06JDEKE9QD68Z651D7XE8V6664TVVC8M68S7WD0DSXMJQKQ0BNJXNDE29Q7MRX6DA3RW0PZ44B3TKRK0294FPVZTNSTA6XF04002",
},
denomPubHash: denomPubHash:
"F5NGBX33DTV4595XZZVK0S2MA1VMXFEJQERE5EBP5DS4QQ9EFRANN7YHWC1TKSHT2K6CQWDBRES8D3DWR0KZF5RET40B4AZXZ0RW1ZG", "F5NGBX33DTV4595XZZVK0S2MA1VMXFEJQERE5EBP5DS4QQ9EFRANN7YHWC1TKSHT2K6CQWDBRES8D3DWR0KZF5RET40B4AZXZ0RW1ZG",
exchangeBaseUrl: "https://exchange.demo.taler.net/", exchangeBaseUrl: "https://exchange.demo.taler.net/",

View File

@ -41,6 +41,7 @@ import {
URL, URL,
WithdrawUriInfoResponse, WithdrawUriInfoResponse,
VersionMatchResult, VersionMatchResult,
DenomKeyType,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { import {
CoinRecord, CoinRecord,
@ -495,7 +496,7 @@ async function processPlanchetExchangeRequest(
]); ]);
if (!denom) { if (!denom) {
console.error("db inconsistent: denom for planchet not found"); logger.error("db inconsistent: denom for planchet not found");
return; return;
} }
@ -589,16 +590,26 @@ async function processPlanchetVerifyAndStoreCoin(
const { planchet, exchangeBaseUrl } = d; const { planchet, exchangeBaseUrl } = d;
const denomSig = await ws.cryptoApi.rsaUnblind( const planchetDenomPub = planchet.denomPub;
resp.ev_sig, if (planchetDenomPub.cipher !== DenomKeyType.Rsa) {
throw Error("cipher not supported");
}
const evSig = resp.ev_sig;
if (evSig.cipher !== DenomKeyType.Rsa) {
throw Error("unsupported cipher");
}
const denomSigRsa = await ws.cryptoApi.rsaUnblind(
evSig.blinded_rsa_signature,
planchet.blindingKey, planchet.blindingKey,
planchet.denomPub, planchetDenomPub.rsa_public_key,
); );
const isValid = await ws.cryptoApi.rsaVerify( const isValid = await ws.cryptoApi.rsaVerify(
planchet.coinPub, planchet.coinPub,
denomSig, denomSigRsa,
planchet.denomPub, planchetDenomPub.rsa_public_key,
); );
if (!isValid) { if (!isValid) {
@ -629,7 +640,10 @@ async function processPlanchetVerifyAndStoreCoin(
currentAmount: planchet.coinValue, currentAmount: planchet.coinValue,
denomPub: planchet.denomPub, denomPub: planchet.denomPub,
denomPubHash: planchet.denomPubHash, denomPubHash: planchet.denomPubHash,
denomSig, denomSig: {
cipher: DenomKeyType.Rsa,
rsa_signature: denomSigRsa,
},
coinEvHash: planchet.coinEvHash, coinEvHash: planchet.coinEvHash,
exchangeBaseUrl: exchangeBaseUrl, exchangeBaseUrl: exchangeBaseUrl,
status: CoinStatus.Fresh, status: CoinStatus.Fresh,
@ -728,7 +742,9 @@ export async function updateWithdrawalDenoms(
batchIdx++, current++ batchIdx++, current++
) { ) {
const denom = denominations[current]; const denom = denominations[current];
if (denom.verificationStatus === DenominationVerificationStatus.Unverified) { if (
denom.verificationStatus === DenominationVerificationStatus.Unverified
) {
logger.trace( logger.trace(
`Validating denomination (${current + 1}/${ `Validating denomination (${current + 1}/${
denominations.length denominations.length
@ -745,7 +761,8 @@ export async function updateWithdrawalDenoms(
); );
denom.verificationStatus = DenominationVerificationStatus.VerifiedBad; denom.verificationStatus = DenominationVerificationStatus.VerifiedBad;
} else { } else {
denom.verificationStatus = DenominationVerificationStatus.VerifiedGood; denom.verificationStatus =
DenominationVerificationStatus.VerifiedGood;
} }
updatedDenominations.push(denom); updatedDenominations.push(denom);
} }

View File

@ -33,7 +33,10 @@ function fakeAci(current: string, feeDeposit: string): AvailableCoinInfo {
return { return {
availableAmount: a(current), availableAmount: a(current),
coinPub: "foobar", coinPub: "foobar",
denomPub: "foobar", denomPub: {
cipher: 1,
rsa_public_key: "foobar",
},
feeDeposit: a(feeDeposit), feeDeposit: a(feeDeposit),
exchangeBaseUrl: "https://example.com/", exchangeBaseUrl: "https://example.com/",
}; };

View File

@ -23,7 +23,7 @@
/** /**
* Imports. * Imports.
*/ */
import { AmountJson, Amounts } from "@gnu-taler/taler-util"; import { AmountJson, Amounts, DenominationPubKey } from "@gnu-taler/taler-util";
import { strcmp, Logger } from "@gnu-taler/taler-util"; import { strcmp, Logger } from "@gnu-taler/taler-util";
const logger = new Logger("coinSelection.ts"); const logger = new Logger("coinSelection.ts");
@ -72,7 +72,7 @@ export interface AvailableCoinInfo {
/** /**
* Coin's denomination public key. * Coin's denomination public key.
*/ */
denomPub: string; denomPub: DenominationPubKey;
/** /**
* Amount still remaining (typically the full amount, * Amount still remaining (typically the full amount,
@ -206,6 +206,21 @@ function tallyFees(
}; };
} }
function denomPubCmp(
p1: DenominationPubKey,
p2: DenominationPubKey,
): -1 | 0 | 1 {
if (p1.cipher < p2.cipher) {
return -1;
} else if (p1.cipher > p2.cipher) {
return +1;
}
if (p1.cipher !== 1 || p2.cipher !== 1) {
throw Error("unsupported cipher");
}
return strcmp(p1.rsa_public_key, p2.rsa_public_key);
}
/** /**
* Given a list of candidate coins, select coins to spend under the merchant's * Given a list of candidate coins, select coins to spend under the merchant's
* constraints. * constraints.
@ -272,7 +287,7 @@ export function selectPayCoins(
(o1, o2) => (o1, o2) =>
-Amounts.cmp(o1.availableAmount, o2.availableAmount) || -Amounts.cmp(o1.availableAmount, o2.availableAmount) ||
Amounts.cmp(o1.feeDeposit, o2.feeDeposit) || Amounts.cmp(o1.feeDeposit, o2.feeDeposit) ||
strcmp(o1.denomPub, o2.denomPub), denomPubCmp(o1.denomPub, o2.denomPub),
); );
// FIXME: Here, we should select coins in a smarter way. // FIXME: Here, we should select coins in a smarter way.

View File

@ -387,6 +387,7 @@ async function runTaskLoop(
} catch (e) { } catch (e) {
if (e instanceof OperationFailedAndReportedError) { if (e instanceof OperationFailedAndReportedError) {
logger.warn("operation processed resulted in reported error"); logger.warn("operation processed resulted in reported error");
logger.warn(`reporred error was: ${j2s(e.operationError)}`);
} else { } else {
logger.error("Uncaught exception", e); logger.error("Uncaught exception", e);
ws.notify({ ws.notify({
@ -929,7 +930,7 @@ async function dispatchRequestInternal(
} }
const components = pt.targetPath.split("/"); const components = pt.targetPath.split("/");
const creditorAcct = components[components.length - 1]; const creditorAcct = components[components.length - 1];
logger.info(`making testbank transfer to '${creditorAcct}''`) logger.info(`making testbank transfer to '${creditorAcct}''`);
const fbReq = await ws.http.postJson( const fbReq = await ws.http.postJson(
new URL(`${creditorAcct}/admin/add-incoming`, req.bank).href, new URL(`${creditorAcct}/admin/add-incoming`, req.bank).href,
{ {

View File

@ -7,12 +7,12 @@ importers:
'@linaria/esbuild': ^3.0.0-beta.13 '@linaria/esbuild': ^3.0.0-beta.13
'@linaria/shaker': ^3.0.0-beta.13 '@linaria/shaker': ^3.0.0-beta.13
esbuild: ^0.12.29 esbuild: ^0.12.29
prettier: ^2.2.1 prettier: ^2.4.1
devDependencies: devDependencies:
'@linaria/esbuild': 3.0.0-beta.13 '@linaria/esbuild': 3.0.0-beta.13
'@linaria/shaker': 3.0.0-beta.13 '@linaria/shaker': 3.0.0-beta.13
esbuild: 0.12.29 esbuild: 0.12.29
prettier: 2.2.1 prettier: 2.4.1
packages/anastasis-core: packages/anastasis-core:
specifiers: specifiers:
@ -255,7 +255,7 @@ importers:
source-map-support: ^0.5.19 source-map-support: ^0.5.19
tslib: ^2.1.0 tslib: ^2.1.0
typedoc: ^0.20.16 typedoc: ^0.20.16
typescript: ^4.1.3 typescript: ^4.4.4
dependencies: dependencies:
'@gnu-taler/idb-bridge': link:../idb-bridge '@gnu-taler/idb-bridge': link:../idb-bridge
'@gnu-taler/taler-util': link:../taler-util '@gnu-taler/taler-util': link:../taler-util
@ -269,11 +269,11 @@ importers:
'@ava/typescript': 1.1.1 '@ava/typescript': 1.1.1
'@gnu-taler/pogen': link:../pogen '@gnu-taler/pogen': link:../pogen
'@microsoft/api-extractor': 7.13.0 '@microsoft/api-extractor': 7.13.0
'@typescript-eslint/eslint-plugin': 4.14.0_980e7d90d2d08155204a38366bd3b934 '@typescript-eslint/eslint-plugin': 4.14.0_4f40ec8f9ae74407a8c29890901bb23f
'@typescript-eslint/parser': 4.14.0_eslint@7.18.0+typescript@4.1.3 '@typescript-eslint/parser': 4.14.0_eslint@7.18.0+typescript@4.4.4
ava: 3.15.0 ava: 3.15.0
eslint: 7.18.0 eslint: 7.18.0
eslint-config-airbnb-typescript: 12.0.0_aa91c0ea1e61103ae60b9cd49dfd9775 eslint-config-airbnb-typescript: 12.0.0_b55a7168bd2ecdf8767ddb224d20fd7e
eslint-plugin-import: 2.22.1_eslint@7.18.0 eslint-plugin-import: 2.22.1_eslint@7.18.0
eslint-plugin-jsx-a11y: 6.4.1_eslint@7.18.0 eslint-plugin-jsx-a11y: 6.4.1_eslint@7.18.0
eslint-plugin-react: 7.22.0_eslint@7.18.0 eslint-plugin-react: 7.22.0_eslint@7.18.0
@ -286,8 +286,8 @@ importers:
rollup: 2.59.0 rollup: 2.59.0
rollup-plugin-sourcemaps: 0.6.3_57eeb328ceff0756ae1d32f4d22d60f9 rollup-plugin-sourcemaps: 0.6.3_57eeb328ceff0756ae1d32f4d22d60f9
source-map-resolve: 0.6.0 source-map-resolve: 0.6.0
typedoc: 0.20.16_typescript@4.1.3 typedoc: 0.20.16_typescript@4.4.4
typescript: 4.1.3 typescript: 4.4.4
packages/taler-wallet-embedded: packages/taler-wallet-embedded:
specifiers: specifiers:
@ -498,6 +498,11 @@ packages:
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dev: true dev: true
/@babel/compat-data/7.16.4:
resolution: {integrity: sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q==}
engines: {node: '>=6.9.0'}
dev: true
/@babel/core/7.12.9: /@babel/core/7.12.9:
resolution: {integrity: sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ==} resolution: {integrity: sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
@ -717,6 +722,18 @@ packages:
semver: 6.3.0 semver: 6.3.0
dev: true dev: true
/@babel/helper-compilation-targets/7.16.3:
resolution: {integrity: sha512-vKsoSQAyBmxS35JUOOt+07cLc6Nk/2ljLIHwmq2/NM6hdioUaqEXq/S+nXvbvXbZkNDlWOymPanJGOc4CBjSJA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0
dependencies:
'@babel/compat-data': 7.16.4
'@babel/helper-validator-option': 7.14.5
browserslist: 4.18.1
semver: 6.3.0
dev: true
/@babel/helper-create-class-features-plugin/7.15.0_@babel+core@7.13.16: /@babel/helper-create-class-features-plugin/7.15.0_@babel+core@7.13.16:
resolution: {integrity: sha512-MdmDXgvTIi4heDVX/e9EFfeGpugqm9fobBVg/iioE8kueXrOHdRDe36FAY7SnE9xXLVeYCoJR/gdrBEIHRC83Q==} resolution: {integrity: sha512-MdmDXgvTIi4heDVX/e9EFfeGpugqm9fobBVg/iioE8kueXrOHdRDe36FAY7SnE9xXLVeYCoJR/gdrBEIHRC83Q==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
@ -934,6 +951,23 @@ packages:
- supports-color - supports-color
dev: true dev: true
/@babel/helper-define-polyfill-provider/0.3.0:
resolution: {integrity: sha512-7hfT8lUljl/tM3h+izTX/pO3W3frz2ok6Pk+gzys8iJqDfZrZy2pXjRTZAvG2YmfHun1X4q8/UZRLatMfqc5Tg==}
peerDependencies:
'@babel/core': ^7.4.0-0
dependencies:
'@babel/helper-compilation-targets': 7.16.3
'@babel/helper-module-imports': 7.16.0
'@babel/helper-plugin-utils': 7.14.5
'@babel/traverse': 7.16.3
debug: 4.3.2
lodash.debounce: 4.0.8
resolve: 1.20.0
semver: 6.3.0
transitivePeerDependencies:
- supports-color
dev: true
/@babel/helper-explode-assignable-expression/7.14.5: /@babel/helper-explode-assignable-expression/7.14.5:
resolution: {integrity: sha512-Htb24gnGJdIGT4vnRKMdoXiOIlqOLmdiUYpAQ0mYfgVT/GDm8GOYhgi4GL+hMKrkiPRohO4ts34ELFsGAPQLDQ==} resolution: {integrity: sha512-Htb24gnGJdIGT4vnRKMdoXiOIlqOLmdiUYpAQ0mYfgVT/GDm8GOYhgi4GL+hMKrkiPRohO4ts34ELFsGAPQLDQ==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
@ -1099,6 +1133,17 @@ packages:
- supports-color - supports-color
dev: true dev: true
/@babel/helper-remap-async-to-generator/7.16.4:
resolution: {integrity: sha512-vGERmmhR+s7eH5Y/cp8PCVzj4XEjerq8jooMfxFdA5xVtAk9Sh4AQsrWgiErUEBjtGrBtOFKDUcWQFW4/dFwMA==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/helper-annotate-as-pure': 7.16.0
'@babel/helper-wrap-function': 7.16.0
'@babel/types': 7.16.0
transitivePeerDependencies:
- supports-color
dev: true
/@babel/helper-replace-supers/7.15.0: /@babel/helper-replace-supers/7.15.0:
resolution: {integrity: sha512-6O+eWrhx+HEra/uJnifCwhwMd6Bp5+ZfZeJwbqUTuqkhIT6YcRhiZCOOFChRypOIe0cV46kFrRBlm+t5vHCEaA==} resolution: {integrity: sha512-6O+eWrhx+HEra/uJnifCwhwMd6Bp5+ZfZeJwbqUTuqkhIT6YcRhiZCOOFChRypOIe0cV46kFrRBlm+t5vHCEaA==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
@ -1206,7 +1251,7 @@ packages:
dependencies: dependencies:
'@babel/helper-function-name': 7.16.0 '@babel/helper-function-name': 7.16.0
'@babel/template': 7.16.0 '@babel/template': 7.16.0
'@babel/traverse': 7.16.0 '@babel/traverse': 7.16.3
'@babel/types': 7.16.0 '@babel/types': 7.16.0
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -1280,6 +1325,12 @@ packages:
hasBin: true hasBin: true
dev: true dev: true
/@babel/parser/7.16.4:
resolution: {integrity: sha512-6V0qdPUaiVHH3RtZeLIsc+6pDhbYzHR8ogA8w+f+Wc77DuXto19g2QUwveINoS34Uw+W8/hQDGJCx+i4n7xcng==}
engines: {node: '>=6.0.0'}
hasBin: true
dev: true
/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/7.16.2: /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/7.16.2:
resolution: {integrity: sha512-h37CvpLSf8gb2lIJ2CgC3t+EjFbi0t8qS7LCS1xcJIlEXE4czlofwaW7W1HA8zpgOCzI9C1nmoqNR1zWkk0pQg==} resolution: {integrity: sha512-h37CvpLSf8gb2lIJ2CgC3t+EjFbi0t8qS7LCS1xcJIlEXE4czlofwaW7W1HA8zpgOCzI9C1nmoqNR1zWkk0pQg==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
@ -1401,6 +1452,19 @@ packages:
- supports-color - supports-color
dev: true dev: true
/@babel/plugin-proposal-async-generator-functions/7.16.4:
resolution: {integrity: sha512-/CUekqaAaZCQHleSK/9HajvcD/zdnJiKRiuUFq8ITE+0HsPzquf53cpFiqAwl/UfmJbR6n5uGPQSPdrmKOvHHg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
'@babel/helper-plugin-utils': 7.14.5
'@babel/helper-remap-async-to-generator': 7.16.4
'@babel/plugin-syntax-async-generators': 7.8.4
transitivePeerDependencies:
- supports-color
dev: true
/@babel/plugin-proposal-class-properties/7.14.5_@babel+core@7.13.16: /@babel/plugin-proposal-class-properties/7.14.5_@babel+core@7.13.16:
resolution: {integrity: sha512-q/PLpv5Ko4dVc1LYMpCY7RVAAO4uk55qPwrIuJ5QJ8c6cVuAmhu7I/49JOppXL6gXf7ZHzpRVEUZdYoPLM04Gg==} resolution: {integrity: sha512-q/PLpv5Ko4dVc1LYMpCY7RVAAO4uk55qPwrIuJ5QJ8c6cVuAmhu7I/49JOppXL6gXf7ZHzpRVEUZdYoPLM04Gg==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
@ -1860,11 +1924,11 @@ packages:
peerDependencies: peerDependencies:
'@babel/core': ^7.0.0-0 '@babel/core': ^7.0.0-0
dependencies: dependencies:
'@babel/compat-data': 7.16.0 '@babel/compat-data': 7.16.4
'@babel/helper-compilation-targets': 7.16.0 '@babel/helper-compilation-targets': 7.16.3
'@babel/helper-plugin-utils': 7.14.5 '@babel/helper-plugin-utils': 7.14.5
'@babel/plugin-syntax-object-rest-spread': 7.8.3 '@babel/plugin-syntax-object-rest-spread': 7.8.3
'@babel/plugin-transform-parameters': 7.16.0 '@babel/plugin-transform-parameters': 7.16.3
dev: true dev: true
/@babel/plugin-proposal-object-rest-spread/7.16.0_@babel+core@7.16.0: /@babel/plugin-proposal-object-rest-spread/7.16.0_@babel+core@7.16.0:
@ -2864,7 +2928,7 @@ packages:
dependencies: dependencies:
'@babel/helper-module-imports': 7.16.0 '@babel/helper-module-imports': 7.16.0
'@babel/helper-plugin-utils': 7.14.5 '@babel/helper-plugin-utils': 7.14.5
'@babel/helper-remap-async-to-generator': 7.16.0 '@babel/helper-remap-async-to-generator': 7.16.4
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
dev: true dev: true
@ -3821,6 +3885,15 @@ packages:
'@babel/helper-plugin-utils': 7.14.5 '@babel/helper-plugin-utils': 7.14.5
dev: true dev: true
/@babel/plugin-transform-parameters/7.16.3:
resolution: {integrity: sha512-3MaDpJrOXT1MZ/WCmkOFo7EtmVVC8H4EUZVrHvFOsmwkk4lOjQj8rzv8JKUZV4YoQKeoIgk07GO+acPU9IMu/w==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
'@babel/helper-plugin-utils': 7.14.5
dev: true
/@babel/plugin-transform-property-literals/7.14.5_@babel+core@7.13.16: /@babel/plugin-transform-property-literals/7.14.5_@babel+core@7.13.16:
resolution: {integrity: sha512-r1uilDthkgXW8Z1vJz2dKYLV1tuw2xsbrp3MrZmD99Wh9vsfKoob+JTgri5VUb/JqyKRXotlOtwgu4stIYCmnw==} resolution: {integrity: sha512-r1uilDthkgXW8Z1vJz2dKYLV1tuw2xsbrp3MrZmD99Wh9vsfKoob+JTgri5VUb/JqyKRXotlOtwgu4stIYCmnw==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
@ -4065,17 +4138,17 @@ packages:
'@babel/helper-plugin-utils': 7.14.5 '@babel/helper-plugin-utils': 7.14.5
dev: true dev: true
/@babel/plugin-transform-runtime/7.16.0: /@babel/plugin-transform-runtime/7.16.4:
resolution: {integrity: sha512-zlPf1/XFn5+vWdve3AAhf+Sxl+MVa5VlwTwWgnLx23u4GlatSRQJ3Eoo9vllf0a9il3woQsT4SK+5Z7c06h8ag==} resolution: {integrity: sha512-pru6+yHANMTukMtEZGC4fs7XPwg35v8sj5CIEmE+gEkFljFiVJxEWxx/7ZDkTK+iZRYo1bFXBtfIN95+K3cJ5A==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
peerDependencies: peerDependencies:
'@babel/core': ^7.0.0-0 '@babel/core': ^7.0.0-0
dependencies: dependencies:
'@babel/helper-module-imports': 7.16.0 '@babel/helper-module-imports': 7.16.0
'@babel/helper-plugin-utils': 7.14.5 '@babel/helper-plugin-utils': 7.14.5
babel-plugin-polyfill-corejs2: 0.2.3 babel-plugin-polyfill-corejs2: 0.3.0
babel-plugin-polyfill-corejs3: 0.3.0 babel-plugin-polyfill-corejs3: 0.4.0
babel-plugin-polyfill-regenerator: 0.2.3 babel-plugin-polyfill-regenerator: 0.3.0
semver: 6.3.0 semver: 6.3.0
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -4741,6 +4814,90 @@ packages:
- supports-color - supports-color
dev: true dev: true
/@babel/preset-env/7.16.4:
resolution: {integrity: sha512-v0QtNd81v/xKj4gNKeuAerQ/azeNn/G1B1qMLeXOcV8+4TWlD2j3NV1u8q29SDFBXx/NBq5kyEAO+0mpRgacjA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
'@babel/compat-data': 7.16.4
'@babel/helper-compilation-targets': 7.16.3
'@babel/helper-plugin-utils': 7.14.5
'@babel/helper-validator-option': 7.14.5
'@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.16.2
'@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.16.0
'@babel/plugin-proposal-async-generator-functions': 7.16.4
'@babel/plugin-proposal-class-properties': 7.16.0
'@babel/plugin-proposal-class-static-block': 7.16.0
'@babel/plugin-proposal-dynamic-import': 7.16.0
'@babel/plugin-proposal-export-namespace-from': 7.16.0
'@babel/plugin-proposal-json-strings': 7.16.0
'@babel/plugin-proposal-logical-assignment-operators': 7.16.0
'@babel/plugin-proposal-nullish-coalescing-operator': 7.16.0
'@babel/plugin-proposal-numeric-separator': 7.16.0
'@babel/plugin-proposal-object-rest-spread': 7.16.0
'@babel/plugin-proposal-optional-catch-binding': 7.16.0
'@babel/plugin-proposal-optional-chaining': 7.16.0
'@babel/plugin-proposal-private-methods': 7.16.0
'@babel/plugin-proposal-private-property-in-object': 7.16.0
'@babel/plugin-proposal-unicode-property-regex': 7.16.0
'@babel/plugin-syntax-async-generators': 7.8.4
'@babel/plugin-syntax-class-properties': 7.12.13
'@babel/plugin-syntax-class-static-block': 7.14.5
'@babel/plugin-syntax-dynamic-import': 7.8.3
'@babel/plugin-syntax-export-namespace-from': 7.8.3
'@babel/plugin-syntax-json-strings': 7.8.3
'@babel/plugin-syntax-logical-assignment-operators': 7.10.4
'@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3
'@babel/plugin-syntax-numeric-separator': 7.10.4
'@babel/plugin-syntax-object-rest-spread': 7.8.3
'@babel/plugin-syntax-optional-catch-binding': 7.8.3
'@babel/plugin-syntax-optional-chaining': 7.8.3
'@babel/plugin-syntax-private-property-in-object': 7.14.5
'@babel/plugin-syntax-top-level-await': 7.14.5
'@babel/plugin-transform-arrow-functions': 7.16.0
'@babel/plugin-transform-async-to-generator': 7.16.0
'@babel/plugin-transform-block-scoped-functions': 7.16.0
'@babel/plugin-transform-block-scoping': 7.16.0
'@babel/plugin-transform-classes': 7.16.0
'@babel/plugin-transform-computed-properties': 7.16.0
'@babel/plugin-transform-destructuring': 7.16.0
'@babel/plugin-transform-dotall-regex': 7.16.0
'@babel/plugin-transform-duplicate-keys': 7.16.0
'@babel/plugin-transform-exponentiation-operator': 7.16.0
'@babel/plugin-transform-for-of': 7.16.0
'@babel/plugin-transform-function-name': 7.16.0
'@babel/plugin-transform-literals': 7.16.0
'@babel/plugin-transform-member-expression-literals': 7.16.0
'@babel/plugin-transform-modules-amd': 7.16.0
'@babel/plugin-transform-modules-commonjs': 7.16.0
'@babel/plugin-transform-modules-systemjs': 7.16.0
'@babel/plugin-transform-modules-umd': 7.16.0
'@babel/plugin-transform-named-capturing-groups-regex': 7.16.0
'@babel/plugin-transform-new-target': 7.16.0
'@babel/plugin-transform-object-super': 7.16.0
'@babel/plugin-transform-parameters': 7.16.3
'@babel/plugin-transform-property-literals': 7.16.0
'@babel/plugin-transform-regenerator': 7.16.0
'@babel/plugin-transform-reserved-words': 7.16.0
'@babel/plugin-transform-shorthand-properties': 7.16.0
'@babel/plugin-transform-spread': 7.16.0
'@babel/plugin-transform-sticky-regex': 7.16.0
'@babel/plugin-transform-template-literals': 7.16.0
'@babel/plugin-transform-typeof-symbol': 7.16.0
'@babel/plugin-transform-unicode-escapes': 7.16.0
'@babel/plugin-transform-unicode-regex': 7.16.0
'@babel/preset-modules': 0.1.5
'@babel/types': 7.16.0
babel-plugin-polyfill-corejs2: 0.3.0
babel-plugin-polyfill-corejs3: 0.4.0
babel-plugin-polyfill-regenerator: 0.3.0
core-js-compat: 3.19.1
semver: 6.3.0
transitivePeerDependencies:
- supports-color
dev: true
/@babel/preset-modules/0.1.4_@babel+core@7.13.16: /@babel/preset-modules/0.1.4_@babel+core@7.13.16:
resolution: {integrity: sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==} resolution: {integrity: sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==}
peerDependencies: peerDependencies:
@ -4919,6 +5076,13 @@ packages:
regenerator-runtime: 0.13.9 regenerator-runtime: 0.13.9
dev: true dev: true
/@babel/runtime/7.16.3:
resolution: {integrity: sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ==}
engines: {node: '>=6.9.0'}
dependencies:
regenerator-runtime: 0.13.9
dev: true
/@babel/template/7.14.5: /@babel/template/7.14.5:
resolution: {integrity: sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==} resolution: {integrity: sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
@ -4971,6 +5135,23 @@ packages:
- supports-color - supports-color
dev: true dev: true
/@babel/traverse/7.16.3:
resolution: {integrity: sha512-eolumr1vVMjqevCpwVO99yN/LoGL0EyHiLO5I043aYQvwOJ9eR5UsZSClHVCzfhBduMAsSzgA/6AyqPjNayJag==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/code-frame': 7.16.0
'@babel/generator': 7.16.0
'@babel/helper-function-name': 7.16.0
'@babel/helper-hoist-variables': 7.16.0
'@babel/helper-split-export-declaration': 7.16.0
'@babel/parser': 7.16.4
'@babel/types': 7.16.0
debug: 4.3.2
globals: 11.12.0
transitivePeerDependencies:
- supports-color
dev: true
/@babel/types/7.15.0: /@babel/types/7.15.0:
resolution: {integrity: sha512-OBvfqnllOIdX4ojTHpwZbpvz4j3EWyjkZEdmjH0/cgsd6QOdSgU8rLSk6ard/pcW7rlmjdVSX/AWOaORR1uNOQ==} resolution: {integrity: sha512-OBvfqnllOIdX4ojTHpwZbpvz4j3EWyjkZEdmjH0/cgsd6QOdSgU8rLSk6ard/pcW7rlmjdVSX/AWOaORR1uNOQ==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
@ -5765,9 +5946,9 @@ packages:
'@babel/core': '>=7' '@babel/core': '>=7'
dependencies: dependencies:
'@babel/generator': 7.16.0 '@babel/generator': 7.16.0
'@babel/plugin-transform-runtime': 7.16.0 '@babel/plugin-transform-runtime': 7.16.4
'@babel/plugin-transform-template-literals': 7.16.0 '@babel/plugin-transform-template-literals': 7.16.0
'@babel/preset-env': 7.16.0 '@babel/preset-env': 7.16.4
'@linaria/babel-preset': 3.0.0-beta.13 '@linaria/babel-preset': 3.0.0-beta.13
'@linaria/logger': 3.0.0-beta.3 '@linaria/logger': 3.0.0-beta.3
'@linaria/preeval': 3.0.0-beta.13 '@linaria/preeval': 3.0.0-beta.13
@ -5897,7 +6078,7 @@ packages:
resolve: 1.17.0 resolve: 1.17.0
semver: 7.3.4 semver: 7.3.4
source-map: 0.6.1 source-map: 0.6.1
typescript: 4.1.3 typescript: 4.1.6
dev: true dev: true
/@microsoft/tsdoc/0.12.24: /@microsoft/tsdoc/0.12.24:
@ -10194,7 +10375,7 @@ packages:
'@types/yargs-parser': 20.2.1 '@types/yargs-parser': 20.2.1
dev: true dev: true
/@typescript-eslint/eslint-plugin/4.14.0_980e7d90d2d08155204a38366bd3b934: /@typescript-eslint/eslint-plugin/4.14.0_4f40ec8f9ae74407a8c29890901bb23f:
resolution: {integrity: sha512-IJ5e2W7uFNfg4qh9eHkHRUCbgZ8VKtGwD07kannJvM5t/GU8P8+24NX8gi3Hf5jST5oWPY8kyV1s/WtfiZ4+Ww==} resolution: {integrity: sha512-IJ5e2W7uFNfg4qh9eHkHRUCbgZ8VKtGwD07kannJvM5t/GU8P8+24NX8gi3Hf5jST5oWPY8kyV1s/WtfiZ4+Ww==}
engines: {node: ^10.12.0 || >=12.0.0} engines: {node: ^10.12.0 || >=12.0.0}
peerDependencies: peerDependencies:
@ -10205,8 +10386,8 @@ packages:
typescript: typescript:
optional: true optional: true
dependencies: dependencies:
'@typescript-eslint/experimental-utils': 4.14.0_eslint@7.18.0+typescript@4.1.3 '@typescript-eslint/experimental-utils': 4.14.0_eslint@7.18.0+typescript@4.4.4
'@typescript-eslint/parser': 4.14.0_eslint@7.18.0+typescript@4.1.3 '@typescript-eslint/parser': 4.14.0_eslint@7.18.0+typescript@4.4.4
'@typescript-eslint/scope-manager': 4.14.0 '@typescript-eslint/scope-manager': 4.14.0
debug: 4.3.1 debug: 4.3.1
eslint: 7.18.0 eslint: 7.18.0
@ -10214,8 +10395,8 @@ packages:
lodash: 4.17.20 lodash: 4.17.20
regexpp: 3.1.0 regexpp: 3.1.0
semver: 7.3.4 semver: 7.3.4
tsutils: 3.19.1_typescript@4.1.3 tsutils: 3.19.1_typescript@4.4.4
typescript: 4.1.3 typescript: 4.4.4
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
dev: true dev: true
@ -10262,7 +10443,7 @@ packages:
- typescript - typescript
dev: true dev: true
/@typescript-eslint/experimental-utils/4.14.0_eslint@7.18.0+typescript@4.1.3: /@typescript-eslint/experimental-utils/4.14.0_eslint@7.18.0+typescript@4.4.4:
resolution: {integrity: sha512-6i6eAoiPlXMKRbXzvoQD5Yn9L7k9ezzGRvzC/x1V3650rUk3c3AOjQyGYyF9BDxQQDK2ElmKOZRD0CbtdkMzQQ==} resolution: {integrity: sha512-6i6eAoiPlXMKRbXzvoQD5Yn9L7k9ezzGRvzC/x1V3650rUk3c3AOjQyGYyF9BDxQQDK2ElmKOZRD0CbtdkMzQQ==}
engines: {node: ^10.12.0 || >=12.0.0} engines: {node: ^10.12.0 || >=12.0.0}
peerDependencies: peerDependencies:
@ -10271,7 +10452,7 @@ packages:
'@types/json-schema': 7.0.7 '@types/json-schema': 7.0.7
'@typescript-eslint/scope-manager': 4.14.0 '@typescript-eslint/scope-manager': 4.14.0
'@typescript-eslint/types': 4.14.0 '@typescript-eslint/types': 4.14.0
'@typescript-eslint/typescript-estree': 4.14.0_typescript@4.1.3 '@typescript-eslint/typescript-estree': 4.14.0_typescript@4.4.4
eslint: 7.18.0 eslint: 7.18.0
eslint-scope: 5.1.1 eslint-scope: 5.1.1
eslint-utils: 2.1.0 eslint-utils: 2.1.0
@ -10298,7 +10479,7 @@ packages:
- typescript - typescript
dev: true dev: true
/@typescript-eslint/parser/4.14.0_eslint@7.18.0+typescript@4.1.3: /@typescript-eslint/parser/4.14.0_eslint@7.18.0+typescript@4.4.4:
resolution: {integrity: sha512-sUDeuCjBU+ZF3Lzw0hphTyScmDDJ5QVkyE21pRoBo8iDl7WBtVFS+WDN3blY1CH3SBt7EmYCw6wfmJjF0l/uYg==} resolution: {integrity: sha512-sUDeuCjBU+ZF3Lzw0hphTyScmDDJ5QVkyE21pRoBo8iDl7WBtVFS+WDN3blY1CH3SBt7EmYCw6wfmJjF0l/uYg==}
engines: {node: ^10.12.0 || >=12.0.0} engines: {node: ^10.12.0 || >=12.0.0}
peerDependencies: peerDependencies:
@ -10310,15 +10491,15 @@ packages:
dependencies: dependencies:
'@typescript-eslint/scope-manager': 4.14.0 '@typescript-eslint/scope-manager': 4.14.0
'@typescript-eslint/types': 4.14.0 '@typescript-eslint/types': 4.14.0
'@typescript-eslint/typescript-estree': 4.14.0_typescript@4.1.3 '@typescript-eslint/typescript-estree': 4.14.0_typescript@4.4.4
debug: 4.3.1 debug: 4.3.1
eslint: 7.18.0 eslint: 7.18.0
typescript: 4.1.3 typescript: 4.4.4
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
dev: true dev: true
/@typescript-eslint/parser/4.4.1_eslint@7.18.0+typescript@4.1.3: /@typescript-eslint/parser/4.4.1_eslint@7.18.0+typescript@4.4.4:
resolution: {integrity: sha512-S0fuX5lDku28Au9REYUsV+hdJpW/rNW0gWlc4SXzF/kdrRaAVX9YCxKpziH7djeWT/HFAjLZcnY7NJD8xTeUEg==} resolution: {integrity: sha512-S0fuX5lDku28Au9REYUsV+hdJpW/rNW0gWlc4SXzF/kdrRaAVX9YCxKpziH7djeWT/HFAjLZcnY7NJD8xTeUEg==}
engines: {node: ^10.12.0 || >=12.0.0} engines: {node: ^10.12.0 || >=12.0.0}
peerDependencies: peerDependencies:
@ -10330,10 +10511,10 @@ packages:
dependencies: dependencies:
'@typescript-eslint/scope-manager': 4.4.1 '@typescript-eslint/scope-manager': 4.4.1
'@typescript-eslint/types': 4.4.1 '@typescript-eslint/types': 4.4.1
'@typescript-eslint/typescript-estree': 4.4.1_typescript@4.1.3 '@typescript-eslint/typescript-estree': 4.4.1_typescript@4.4.4
debug: 4.3.1 debug: 4.3.1
eslint: 7.18.0 eslint: 7.18.0
typescript: 4.1.3 typescript: 4.4.4
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
dev: true dev: true
@ -10418,7 +10599,7 @@ packages:
- supports-color - supports-color
dev: true dev: true
/@typescript-eslint/typescript-estree/4.14.0_typescript@4.1.3: /@typescript-eslint/typescript-estree/4.14.0_typescript@4.4.4:
resolution: {integrity: sha512-wRjZ5qLao+bvS2F7pX4qi2oLcOONIB+ru8RGBieDptq/SudYwshveORwCVU4/yMAd4GK7Fsf8Uq1tjV838erag==} resolution: {integrity: sha512-wRjZ5qLao+bvS2F7pX4qi2oLcOONIB+ru8RGBieDptq/SudYwshveORwCVU4/yMAd4GK7Fsf8Uq1tjV838erag==}
engines: {node: ^10.12.0 || >=12.0.0} engines: {node: ^10.12.0 || >=12.0.0}
peerDependencies: peerDependencies:
@ -10434,13 +10615,13 @@ packages:
is-glob: 4.0.1 is-glob: 4.0.1
lodash: 4.17.20 lodash: 4.17.20
semver: 7.3.4 semver: 7.3.4
tsutils: 3.19.1_typescript@4.1.3 tsutils: 3.19.1_typescript@4.4.4
typescript: 4.1.3 typescript: 4.4.4
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
dev: true dev: true
/@typescript-eslint/typescript-estree/4.4.1_typescript@4.1.3: /@typescript-eslint/typescript-estree/4.4.1_typescript@4.4.4:
resolution: {integrity: sha512-wP/V7ScKzgSdtcY1a0pZYBoCxrCstLrgRQ2O9MmCUZDtmgxCO/TCqOTGRVwpP4/2hVfqMz/Vw1ZYrG8cVxvN3g==} resolution: {integrity: sha512-wP/V7ScKzgSdtcY1a0pZYBoCxrCstLrgRQ2O9MmCUZDtmgxCO/TCqOTGRVwpP4/2hVfqMz/Vw1ZYrG8cVxvN3g==}
engines: {node: ^10.12.0 || >=12.0.0} engines: {node: ^10.12.0 || >=12.0.0}
peerDependencies: peerDependencies:
@ -10456,8 +10637,8 @@ packages:
is-glob: 4.0.1 is-glob: 4.0.1
lodash: 4.17.20 lodash: 4.17.20
semver: 7.3.4 semver: 7.3.4
tsutils: 3.19.1_typescript@4.1.3 tsutils: 3.19.1_typescript@4.4.4
typescript: 4.1.3 typescript: 4.4.4
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
dev: true dev: true
@ -11644,6 +11825,18 @@ packages:
- supports-color - supports-color
dev: true dev: true
/babel-plugin-polyfill-corejs2/0.3.0:
resolution: {integrity: sha512-wMDoBJ6uG4u4PNFh72Ty6t3EgfA91puCuAwKIazbQlci+ENb/UU9A3xG5lutjUIiXCIn1CY5L15r9LimiJyrSA==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
'@babel/compat-data': 7.16.4
'@babel/helper-define-polyfill-provider': 0.3.0
semver: 6.3.0
transitivePeerDependencies:
- supports-color
dev: true
/babel-plugin-polyfill-corejs3/0.1.7_@babel+core@7.15.0: /babel-plugin-polyfill-corejs3/0.1.7_@babel+core@7.15.0:
resolution: {integrity: sha512-u+gbS9bbPhZWEeyy1oR/YaaSpod/KDT07arZHb80aTpl8H5ZBq+uN1nN9/xtX7jQyfLdPfoqI4Rue/MQSWJquw==} resolution: {integrity: sha512-u+gbS9bbPhZWEeyy1oR/YaaSpod/KDT07arZHb80aTpl8H5ZBq+uN1nN9/xtX7jQyfLdPfoqI4Rue/MQSWJquw==}
peerDependencies: peerDependencies:
@ -11715,6 +11908,17 @@ packages:
- supports-color - supports-color
dev: true dev: true
/babel-plugin-polyfill-corejs3/0.4.0:
resolution: {integrity: sha512-YxFreYwUfglYKdLUGvIF2nJEsGwj+RhWSX/ije3D2vQPOXuyMLMtg/cCGMDpOA7Nd+MwlNdnGODbd2EwUZPlsw==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
'@babel/helper-define-polyfill-provider': 0.3.0
core-js-compat: 3.19.1
transitivePeerDependencies:
- supports-color
dev: true
/babel-plugin-polyfill-regenerator/0.2.2_@babel+core@7.13.16: /babel-plugin-polyfill-regenerator/0.2.2_@babel+core@7.13.16:
resolution: {integrity: sha512-Goy5ghsc21HgPDFtzRkSirpZVW35meGoTmTOb2bxqdl60ghub4xOidgNTHaZfQ2FaxQsKmwvXtOAkcIS4SMBWg==} resolution: {integrity: sha512-Goy5ghsc21HgPDFtzRkSirpZVW35meGoTmTOb2bxqdl60ghub4xOidgNTHaZfQ2FaxQsKmwvXtOAkcIS4SMBWg==}
peerDependencies: peerDependencies:
@ -11758,6 +11962,16 @@ packages:
- supports-color - supports-color
dev: true dev: true
/babel-plugin-polyfill-regenerator/0.3.0:
resolution: {integrity: sha512-dhAPTDLGoMW5/84wkgwiLRwMnio2i1fUe53EuvtKMv0pn2p3S8OCoV1xAzfJPl0KOX7IB89s2ib85vbYiea3jg==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
'@babel/helper-define-polyfill-provider': 0.3.0
transitivePeerDependencies:
- supports-color
dev: true
/babel-plugin-syntax-jsx/6.18.0: /babel-plugin-syntax-jsx/6.18.0:
resolution: {integrity: sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=} resolution: {integrity: sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=}
dev: true dev: true
@ -12156,6 +12370,18 @@ packages:
picocolors: 1.0.0 picocolors: 1.0.0
dev: true dev: true
/browserslist/4.18.1:
resolution: {integrity: sha512-8ScCzdpPwR2wQh8IT82CA2VgDwjHyqMovPBZSNH54+tm4Jk2pCuv90gmAdH6J84OCRWi0b4gMe6O6XPXuJnjgQ==}
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true
dependencies:
caniuse-lite: 1.0.30001280
electron-to-chromium: 1.3.899
escalade: 3.1.1
node-releases: 2.0.1
picocolors: 1.0.0
dev: true
/bser/2.1.1: /bser/2.1.1:
resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==}
dependencies: dependencies:
@ -12394,6 +12620,10 @@ packages:
resolution: {integrity: sha512-psUNoaG1ilknZPxi8HuhQWobuhLqtYSRUxplfVkEJdgZNB9TETVYGSBtv4YyfAdGvE6gn2eb0ztiXqHoWJcGnw==} resolution: {integrity: sha512-psUNoaG1ilknZPxi8HuhQWobuhLqtYSRUxplfVkEJdgZNB9TETVYGSBtv4YyfAdGvE6gn2eb0ztiXqHoWJcGnw==}
dev: true dev: true
/caniuse-lite/1.0.30001280:
resolution: {integrity: sha512-kFXwYvHe5rix25uwueBxC569o53J6TpnGu0BEEn+6Lhl2vsnAumRFWEBhDft1fwyo6m1r4i+RqA4+163FpeFcA==}
dev: true
/capture-exit/2.0.0: /capture-exit/2.0.0:
resolution: {integrity: sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==} resolution: {integrity: sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==}
engines: {node: 6.* || 8.* || >= 10.*} engines: {node: 6.* || 8.* || >= 10.*}
@ -13052,7 +13282,7 @@ packages:
/core-js-compat/3.19.1: /core-js-compat/3.19.1:
resolution: {integrity: sha512-Q/VJ7jAF/y68+aUsQJ/afPOewdsGkDtcMb40J8MbuWKlK3Y+wtHq8bTHKPj2WKWLIqmS5JhHs4CzHtz6pT2W6g==} resolution: {integrity: sha512-Q/VJ7jAF/y68+aUsQJ/afPOewdsGkDtcMb40J8MbuWKlK3Y+wtHq8bTHKPj2WKWLIqmS5JhHs4CzHtz6pT2W6g==}
dependencies: dependencies:
browserslist: 4.17.6 browserslist: 4.18.1
semver: 7.0.0 semver: 7.0.0
dev: true dev: true
@ -14141,6 +14371,10 @@ packages:
resolution: {integrity: sha512-5iD1zgyPpFER4kJ716VsA4MxQ6x405dxdFNCEK2mITL075VHO5ResjY0xzQUZguCww/KlBxCA6JmBA9sDt1PRw==} resolution: {integrity: sha512-5iD1zgyPpFER4kJ716VsA4MxQ6x405dxdFNCEK2mITL075VHO5ResjY0xzQUZguCww/KlBxCA6JmBA9sDt1PRw==}
dev: true dev: true
/electron-to-chromium/1.3.899:
resolution: {integrity: sha512-w16Dtd2zl7VZ4N4Db+FIa7n36sgPGCKjrKvUUmp5ialsikvcQLjcJR9RWnlYNxIyEHLdHaoIZEqKsPxU9MdyBg==}
dev: true
/element-resize-detector/1.2.3: /element-resize-detector/1.2.3:
resolution: {integrity: sha512-+dhNzUgLpq9ol5tyhoG7YLoXL3ssjfFW+0gpszXPwRU6NjGr1fVHMEAF8fVzIiRJq57Nre0RFeIjJwI8Nh2NmQ==} resolution: {integrity: sha512-+dhNzUgLpq9ol5tyhoG7YLoXL3ssjfFW+0gpszXPwRU6NjGr1fVHMEAF8fVzIiRJq57Nre0RFeIjJwI8Nh2NmQ==}
dependencies: dependencies:
@ -14546,13 +14780,13 @@ packages:
object.entries: 1.1.3 object.entries: 1.1.3
dev: true dev: true
/eslint-config-airbnb-typescript/12.0.0_aa91c0ea1e61103ae60b9cd49dfd9775: /eslint-config-airbnb-typescript/12.0.0_b55a7168bd2ecdf8767ddb224d20fd7e:
resolution: {integrity: sha512-TUCVru1Z09eKnVAX5i3XoNzjcCOU3nDQz2/jQGkg1jVYm+25fKClveziSl16celfCq+npU0MBPW/ZnXdGFZ9lw==} resolution: {integrity: sha512-TUCVru1Z09eKnVAX5i3XoNzjcCOU3nDQz2/jQGkg1jVYm+25fKClveziSl16celfCq+npU0MBPW/ZnXdGFZ9lw==}
peerDependencies: peerDependencies:
'@typescript-eslint/eslint-plugin': ^4.4.1 '@typescript-eslint/eslint-plugin': ^4.4.1
dependencies: dependencies:
'@typescript-eslint/eslint-plugin': 4.14.0_980e7d90d2d08155204a38366bd3b934 '@typescript-eslint/eslint-plugin': 4.14.0_4f40ec8f9ae74407a8c29890901bb23f
'@typescript-eslint/parser': 4.4.1_eslint@7.18.0+typescript@4.1.3 '@typescript-eslint/parser': 4.4.1_eslint@7.18.0+typescript@4.4.4
eslint-config-airbnb: 18.2.0_8b932c4aedefa0fbb298d8c6e2d8003e eslint-config-airbnb: 18.2.0_8b932c4aedefa0fbb298d8c6e2d8003e
eslint-config-airbnb-base: 14.2.0_d4477e7d44043beb7952cd76bd313965 eslint-config-airbnb-base: 14.2.0_d4477e7d44043beb7952cd76bd313965
transitivePeerDependencies: transitivePeerDependencies:
@ -16140,7 +16374,7 @@ packages:
source-map: 0.6.1 source-map: 0.6.1
wordwrap: 1.0.0 wordwrap: 1.0.0
optionalDependencies: optionalDependencies:
uglify-js: 3.12.5 uglify-js: 3.14.3
dev: true dev: true
/har-schema/2.0.0: /har-schema/2.0.0:
@ -18774,7 +19008,7 @@ packages:
/jsonfile/4.0.0: /jsonfile/4.0.0:
resolution: {integrity: sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=} resolution: {integrity: sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=}
optionalDependencies: optionalDependencies:
graceful-fs: 4.2.8 graceful-fs: 4.2.4
dev: true dev: true
/jsonfile/6.1.0: /jsonfile/6.1.0:
@ -18949,7 +19183,7 @@ packages:
resolution: {integrity: sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=} resolution: {integrity: sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=}
engines: {node: '>=4'} engines: {node: '>=4'}
dependencies: dependencies:
graceful-fs: 4.2.4 graceful-fs: 4.2.8
parse-json: 2.2.0 parse-json: 2.2.0
pify: 2.3.0 pify: 2.3.0
strip-bom: 3.0.0 strip-bom: 3.0.0
@ -21794,6 +22028,12 @@ packages:
hasBin: true hasBin: true
dev: true dev: true
/prettier/2.4.1:
resolution: {integrity: sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==}
engines: {node: '>=10.13.0'}
hasBin: true
dev: true
/pretty-bytes/4.0.2: /pretty-bytes/4.0.2:
resolution: {integrity: sha1-sr+C5zUNZcbDOqlaqlpPYyf2HNk=} resolution: {integrity: sha1-sr+C5zUNZcbDOqlaqlpPYyf2HNk=}
engines: {node: '>=4'} engines: {node: '>=4'}
@ -22643,7 +22883,7 @@ packages:
/regenerator-transform/0.14.5: /regenerator-transform/0.14.5:
resolution: {integrity: sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==} resolution: {integrity: sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==}
dependencies: dependencies:
'@babel/runtime': 7.16.0 '@babel/runtime': 7.16.3
dev: true dev: true
/regex-not/1.0.2: /regex-not/1.0.2:
@ -24827,14 +25067,14 @@ packages:
/tslib/2.3.1: /tslib/2.3.1:
resolution: {integrity: sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==} resolution: {integrity: sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==}
/tsutils/3.19.1_typescript@4.1.3: /tsutils/3.19.1_typescript@4.4.4:
resolution: {integrity: sha512-GEdoBf5XI324lu7ycad7s6laADfnAqCw6wLGI+knxvw9vsIYBaJfYdmeCEG3FMMUiSm3OGgNb+m6utsWf5h9Vw==} resolution: {integrity: sha512-GEdoBf5XI324lu7ycad7s6laADfnAqCw6wLGI+knxvw9vsIYBaJfYdmeCEG3FMMUiSm3OGgNb+m6utsWf5h9Vw==}
engines: {node: '>= 6'} engines: {node: '>= 6'}
peerDependencies: peerDependencies:
typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta'
dependencies: dependencies:
tslib: 1.14.1 tslib: 1.14.1
typescript: 4.1.3 typescript: 4.4.4
dev: true dev: true
/tsutils/3.21.0_typescript@4.4.4: /tsutils/3.21.0_typescript@4.4.4:
@ -24959,12 +25199,39 @@ packages:
typescript: 4.1.3 typescript: 4.1.3
dev: true dev: true
/typedoc/0.20.16_typescript@4.4.4:
resolution: {integrity: sha512-xqIL8lT6ZE3QpP0GN30ckeTR05NSEkrP2pXQlNhC0OFkbvnjqJtDUcWSmCO15BuYyu4qsEbZT+tKYFEAt9Jxew==}
engines: {node: '>= 10.8.0'}
hasBin: true
peerDependencies:
typescript: 3.9.x || 4.0.x || 4.1.x
dependencies:
colors: 1.4.0
fs-extra: 9.1.0
handlebars: 4.7.6
lodash: 4.17.20
lunr: 2.3.9
marked: 1.2.7
minimatch: 3.0.4
progress: 2.0.3
shelljs: 0.8.4
shiki: 0.2.7
typedoc-default-themes: 0.12.4
typescript: 4.4.4
dev: true
/typescript/4.1.3: /typescript/4.1.3:
resolution: {integrity: sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==} resolution: {integrity: sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==}
engines: {node: '>=4.2.0'} engines: {node: '>=4.2.0'}
hasBin: true hasBin: true
dev: true dev: true
/typescript/4.1.6:
resolution: {integrity: sha512-pxnwLxeb/Z5SP80JDRzVjh58KsM6jZHRAOtTpS7sXLS4ogXNKC9ANxHHZqLLeVHZN35jCtI4JdmLLbLiC1kBow==}
engines: {node: '>=4.2.0'}
hasBin: true
dev: true
/typescript/4.2.3: /typescript/4.2.3:
resolution: {integrity: sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw==} resolution: {integrity: sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw==}
engines: {node: '>=4.2.0'} engines: {node: '>=4.2.0'}
@ -24989,8 +25256,8 @@ packages:
hasBin: true hasBin: true
dev: true dev: true
/uglify-js/3.12.5: /uglify-js/3.14.3:
resolution: {integrity: sha512-SgpgScL4T7Hj/w/GexjnBHi3Ien9WS1Rpfg5y91WXMj9SY997ZCQU76mH4TpLwwfmMvoOU8wiaRkIf6NaH3mtg==} resolution: {integrity: sha512-mic3aOdiq01DuSVx0TseaEzMIVqebMZ0Z3vaeDhFEh9bsc24hV1TFvN74reA2vs08D0ZWfNjAcJ3UbVLaBss+g==}
engines: {node: '>=0.8.0'} engines: {node: '>=0.8.0'}
hasBin: true hasBin: true
dev: true dev: true