aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-wallet-cli/src/integrationtests/test-wallet-dbless.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/taler-wallet-cli/src/integrationtests/test-wallet-dbless.ts')
-rw-r--r--packages/taler-wallet-cli/src/integrationtests/test-wallet-dbless.ts274
1 files changed, 12 insertions, 262 deletions
diff --git a/packages/taler-wallet-cli/src/integrationtests/test-wallet-dbless.ts b/packages/taler-wallet-cli/src/integrationtests/test-wallet-dbless.ts
index 9ff605df5..93c22af70 100644
--- a/packages/taler-wallet-cli/src/integrationtests/test-wallet-dbless.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-wallet-dbless.ts
@@ -17,277 +17,24 @@
/**
* Imports.
*/
+import { j2s } from "@gnu-taler/taler-util";
import {
- AmountJson,
- AmountLike,
- Amounts,
- AmountString,
- codecForBankWithdrawalOperationPostResponse,
- codecForDepositSuccess,
- codecForExchangeMeltResponse,
- codecForWithdrawResponse,
- DenominationPubKey,
- eddsaGetPublic,
- encodeCrock,
- ExchangeMeltRequest,
- ExchangeProtocolVersion,
- ExchangeWithdrawRequest,
- getRandomBytes,
- getTimestampNow,
- hashWire,
- j2s,
- Timestamp,
- UnblindedSignature,
-} from "@gnu-taler/taler-util";
-import {
- BankAccessApi,
- BankApi,
- BankServiceHandle,
+ checkReserve,
CryptoApi,
- DenominationRecord,
+ depositCoin,
downloadExchangeInfo,
- ExchangeInfo,
- getBankWithdrawalInfo,
- HttpRequestLibrary,
- isWithdrawableDenom,
+ findDenomOrThrow,
+ generateReserveKeypair,
NodeHttpLib,
OperationFailedError,
- readSuccessResponseJsonOrThrow,
+ refreshCoin,
SynchronousCryptoWorkerFactory,
+ topupReserveWithDemobank,
+ withdrawCoin,
} from "@gnu-taler/taler-wallet-core";
import { GlobalTestState } from "../harness/harness.js";
import { createSimpleTestkudosEnvironment } from "../harness/helpers.js";
-const httpLib = new NodeHttpLib();
-
-export interface ReserveKeypair {
- reservePub: string;
- reservePriv: string;
-}
-
-/**
- * Denormalized info about a coin.
- */
-export interface CoinInfo {
- coinPub: string;
- coinPriv: string;
- exchangeBaseUrl: string;
- denomSig: UnblindedSignature;
- denomPub: DenominationPubKey;
- denomPubHash: string;
- feeDeposit: string;
- feeRefresh: string;
-}
-
-export function generateReserveKeypair(): ReserveKeypair {
- const priv = getRandomBytes(32);
- const pub = eddsaGetPublic(priv);
- return {
- reservePriv: encodeCrock(priv),
- reservePub: encodeCrock(pub),
- };
-}
-
-async function topupReserveWithDemobank(
- reservePub: string,
- bankBaseUrl: string,
- exchangeInfo: ExchangeInfo,
- amount: AmountString,
-) {
- const bankHandle: BankServiceHandle = {
- baseUrl: bankBaseUrl,
- http: httpLib,
- };
- const bankUser = await BankApi.createRandomBankUser(bankHandle);
- const wopi = await BankAccessApi.createWithdrawalOperation(
- bankHandle,
- bankUser,
- amount,
- );
- const bankInfo = await getBankWithdrawalInfo(
- httpLib,
- wopi.taler_withdraw_uri,
- );
- const bankStatusUrl = bankInfo.extractedStatusUrl;
- if (!bankInfo.suggestedExchange) {
- throw Error("no suggested exchange");
- }
- const plainPaytoUris =
- exchangeInfo.wire.accounts.map((x) => x.payto_uri) ?? [];
- if (plainPaytoUris.length <= 0) {
- throw new Error();
- }
- const httpResp = await httpLib.postJson(bankStatusUrl, {
- reserve_pub: reservePub,
- selected_exchange: plainPaytoUris[0],
- });
- await readSuccessResponseJsonOrThrow(
- httpResp,
- codecForBankWithdrawalOperationPostResponse(),
- );
- await BankApi.confirmWithdrawalOperation(bankHandle, bankUser, wopi);
-}
-
-async function withdrawCoin(args: {
- http: HttpRequestLibrary;
- cryptoApi: CryptoApi;
- reserveKeyPair: ReserveKeypair;
- denom: DenominationRecord;
- exchangeBaseUrl: string;
-}): Promise<CoinInfo> {
- const { http, cryptoApi, reserveKeyPair, denom, exchangeBaseUrl } = args;
- const planchet = await cryptoApi.createPlanchet({
- coinIndex: 0,
- denomPub: denom.denomPub,
- feeWithdraw: denom.feeWithdraw,
- reservePriv: reserveKeyPair.reservePriv,
- reservePub: reserveKeyPair.reservePub,
- secretSeed: encodeCrock(getRandomBytes(32)),
- value: denom.value,
- });
-
- const reqBody: ExchangeWithdrawRequest = {
- denom_pub_hash: planchet.denomPubHash,
- reserve_sig: planchet.withdrawSig,
- coin_ev: planchet.coinEv,
- };
- const reqUrl = new URL(
- `reserves/${planchet.reservePub}/withdraw`,
- exchangeBaseUrl,
- ).href;
-
- const resp = await http.postJson(reqUrl, reqBody);
- const r = await readSuccessResponseJsonOrThrow(
- resp,
- codecForWithdrawResponse(),
- );
-
- const ubSig = await cryptoApi.unblindDenominationSignature({
- planchet,
- evSig: r.ev_sig,
- });
-
- return {
- coinPriv: planchet.coinPriv,
- coinPub: planchet.coinPub,
- denomSig: ubSig,
- denomPub: denom.denomPub,
- denomPubHash: denom.denomPubHash,
- feeDeposit: Amounts.stringify(denom.feeDeposit),
- feeRefresh: Amounts.stringify(denom.feeRefresh),
- exchangeBaseUrl: args.exchangeBaseUrl,
- };
-}
-
-function findDenomOrThrow(
- exchangeInfo: ExchangeInfo,
- amount: AmountString,
-): DenominationRecord {
- for (const d of exchangeInfo.keys.currentDenominations) {
- if (Amounts.cmp(d.value, amount) === 0 && isWithdrawableDenom(d)) {
- return d;
- }
- }
- throw new Error("no matching denomination found");
-}
-
-async function depositCoin(args: {
- http: HttpRequestLibrary;
- cryptoApi: CryptoApi;
- exchangeBaseUrl: string;
- coin: CoinInfo;
- amount: AmountString;
-}) {
- const { coin, http, cryptoApi } = args;
- const depositPayto = "payto://x-taler-bank/localhost/foo";
- const wireSalt = encodeCrock(getRandomBytes(16));
- const contractTermsHash = encodeCrock(getRandomBytes(64));
- const depositTimestamp = getTimestampNow();
- const refundDeadline = getTimestampNow();
- const merchantPub = encodeCrock(getRandomBytes(32));
- const dp = await cryptoApi.signDepositPermission({
- coinPriv: coin.coinPriv,
- coinPub: coin.coinPub,
- contractTermsHash,
- denomKeyType: coin.denomPub.cipher,
- denomPubHash: coin.denomPubHash,
- denomSig: coin.denomSig,
- exchangeBaseUrl: args.exchangeBaseUrl,
- feeDeposit: Amounts.parseOrThrow(coin.feeDeposit),
- merchantPub,
- spendAmount: Amounts.parseOrThrow(args.amount),
- timestamp: depositTimestamp,
- refundDeadline: refundDeadline,
- wireInfoHash: hashWire(depositPayto, wireSalt),
- });
- const requestBody = {
- contribution: Amounts.stringify(dp.contribution),
- merchant_payto_uri: depositPayto,
- wire_salt: wireSalt,
- h_contract_terms: contractTermsHash,
- ub_sig: coin.denomSig,
- timestamp: depositTimestamp,
- wire_transfer_deadline: getTimestampNow(),
- refund_deadline: refundDeadline,
- coin_sig: dp.coin_sig,
- denom_pub_hash: dp.h_denom,
- merchant_pub: merchantPub,
- };
- const url = new URL(`coins/${dp.coin_pub}/deposit`, dp.exchange_url);
- const httpResp = await http.postJson(url.href, requestBody);
- await readSuccessResponseJsonOrThrow(httpResp, codecForDepositSuccess());
-}
-
-async function refreshCoin(req: {
- http: HttpRequestLibrary;
- cryptoApi: CryptoApi;
- oldCoin: CoinInfo;
- newDenoms: DenominationRecord[];
-}): Promise<void> {
- const { cryptoApi, oldCoin, http } = req;
- const refreshSessionSeed = encodeCrock(getRandomBytes(32));
- const session = await cryptoApi.deriveRefreshSession({
- exchangeProtocolVersion: ExchangeProtocolVersion.V12,
- feeRefresh: Amounts.parseOrThrow(oldCoin.feeRefresh),
- kappa: 3,
- meltCoinDenomPubHash: oldCoin.denomPubHash,
- meltCoinPriv: oldCoin.coinPriv,
- meltCoinPub: oldCoin.coinPub,
- sessionSecretSeed: refreshSessionSeed,
- newCoinDenoms: req.newDenoms.map((x) => ({
- count: 1,
- denomPub: x.denomPub,
- feeWithdraw: x.feeWithdraw,
- value: x.value,
- })),
- });
-
- const meltReqBody: ExchangeMeltRequest = {
- coin_pub: oldCoin.coinPub,
- confirm_sig: session.confirmSig,
- denom_pub_hash: oldCoin.denomPubHash,
- denom_sig: oldCoin.denomSig,
- rc: session.hash,
- value_with_fee: Amounts.stringify(session.meltValueWithFee),
- };
-
- const reqUrl = new URL(
- `coins/${oldCoin.coinPub}/melt`,
- oldCoin.exchangeBaseUrl,
- );
-
- const resp = await http.postJson(reqUrl.href, meltReqBody);
-
- const meltResponse = await readSuccessResponseJsonOrThrow(
- resp,
- codecForExchangeMeltResponse(),
- );
-
- const norevealIndex = meltResponse.noreveal_index;
-
-
-}
-
/**
* Run test for basic, bank-integrated withdrawal and payment.
*/
@@ -307,6 +54,7 @@ export async function runWalletDblessTest(t: GlobalTestState) {
const reserveKeyPair = generateReserveKeypair();
await topupReserveWithDemobank(
+ http,
reserveKeyPair.reservePub,
bank.baseUrl,
exchangeInfo,
@@ -315,6 +63,8 @@ export async function runWalletDblessTest(t: GlobalTestState) {
await exchange.runWirewatchOnce();
+ await checkReserve(http, exchange.baseUrl, reserveKeyPair.reservePub);
+
const d1 = findDenomOrThrow(exchangeInfo, "TESTKUDOS:8");
const coin = await withdrawCoin({
@@ -338,7 +88,7 @@ export async function runWalletDblessTest(t: GlobalTestState) {
findDenomOrThrow(exchangeInfo, "TESTKUDOS:1"),
];
- const freshCoins = await refreshCoin({
+ await refreshCoin({
oldCoin: coin,
cryptoApi,
http,