diff options
Diffstat (limited to 'packages')
| -rw-r--r-- | packages/taler-wallet-cli/src/index.ts | 109 | ||||
| -rw-r--r-- | packages/taler-wallet-core/src/db.ts | 4 | ||||
| -rw-r--r-- | packages/taler-wallet-core/src/operations/exchanges.ts | 58 | ||||
| -rw-r--r-- | packages/taler-wallet-core/src/wallet.ts | 2 | 
4 files changed, 105 insertions, 68 deletions
| diff --git a/packages/taler-wallet-cli/src/index.ts b/packages/taler-wallet-cli/src/index.ts index 249198e3c..b50e11883 100644 --- a/packages/taler-wallet-cli/src/index.ts +++ b/packages/taler-wallet-cli/src/index.ts @@ -314,48 +314,42 @@ walletCli      logger.info("finished handling API request");    }); -walletCli -  .subcommand("", "pending", { help: "Show pending operations." }) -  .action(async (args) => { -    await withWallet(args, async (wallet) => { -      const pending = await wallet.client.call( -        WalletApiOperation.GetPendingOperations, -        {}, -      ); -      console.log(JSON.stringify(pending, undefined, 2)); -    }); -  }); - -walletCli -  .subcommand("transactions", "transactions", { help: "Show transactions." }) +const transactionsCli = walletCli +  .subcommand("transactions", "transactions", { help: "Manage transactions." })    .maybeOption("currency", ["--currency"], clk.STRING) -  .maybeOption("search", ["--search"], clk.STRING) -  .action(async (args) => { -    await withWallet(args, async (wallet) => { -      const pending = await wallet.client.call( -        WalletApiOperation.GetTransactions, -        { -          currency: args.transactions.currency, -          search: args.transactions.search, -        }, -      ); -      console.log(JSON.stringify(pending, undefined, 2)); -    }); +  .maybeOption("search", ["--search"], clk.STRING); + +// Default action +transactionsCli.action(async (args) => { +  await withWallet(args, async (wallet) => { +    const pending = await wallet.client.call( +      WalletApiOperation.GetTransactions, +      { +        currency: args.transactions.currency, +        search: args.transactions.search, +      }, +    ); +    console.log(JSON.stringify(pending, undefined, 2));    }); +}); -walletCli -  .subcommand("runPendingOpt", "run-pending", { -    help: "Run pending operations.", +transactionsCli +  .subcommand("deleteTransaction", "delete", { +    help: "Permanently delete a transaction from the transaction list.", +  }) +  .requiredArgument("transactionId", clk.STRING, { +    help: "Identifier of the transaction to delete",    }) -  .flag("forceNow", ["-f", "--force-now"])    .action(async (args) => {      await withWallet(args, async (wallet) => { -      await wallet.ws.runPending(args.runPendingOpt.forceNow); +      await wallet.client.call(WalletApiOperation.DeleteTransaction, { +        transactionId: args.deleteTransaction.transactionId, +      });      });    }); -walletCli -  .subcommand("retryTransaction", "retry-transaction", { +transactionsCli +  .subcommand("retryTransaction", "retry", {      help: "Retry a transaction.",    })    .requiredArgument("transactionId", clk.STRING) @@ -388,21 +382,6 @@ walletCli    });  walletCli -  .subcommand("deleteTransaction", "delete-transaction", { -    help: "Permanently delete a transaction from the transaction list.", -  }) -  .requiredArgument("transactionId", clk.STRING, { -    help: "Identifier of the transaction to delete", -  }) -  .action(async (args) => { -    await withWallet(args, async (wallet) => { -      await wallet.client.call(WalletApiOperation.DeleteTransaction, { -        transactionId: args.deleteTransaction.transactionId, -      }); -    }); -  }); - -walletCli    .subcommand("withdraw", "withdraw", {      help: "Withdraw with a taler://withdraw/ URI",    }) @@ -604,17 +583,26 @@ exchangesCli  exchangesCli    .subcommand("exchangesTosCmd", "tos", { -    help: "Show terms of service.", +    help: "Show/request terms of service.",    })    .requiredArgument("url", clk.STRING, {      help: "Base URL of the exchange.",    }) +  .maybeOption("contentTypes", ["--content-type"], clk.STRING)    .action(async (args) => { +    let acceptedFormat: string[] | undefined = undefined; +    if (args.exchangesTosCmd.contentTypes) { +      const split = args.exchangesTosCmd.contentTypes +        .split(",") +        .map((x) => x.trim()); +      acceptedFormat = split; +    }      await withWallet(args, async (wallet) => {        const tosResult = await wallet.client.call(          WalletApiOperation.GetExchangeTos,          {            exchangeBaseUrl: args.exchangesTosCmd.url, +          acceptedFormat,          },        );        console.log(JSON.stringify(tosResult, undefined, 2)); @@ -765,6 +753,29 @@ advancedCli    });  advancedCli +  .subcommand("runPendingOpt", "run-pending", { +    help: "Run pending operations.", +  }) +  .flag("forceNow", ["-f", "--force-now"]) +  .action(async (args) => { +    await withWallet(args, async (wallet) => { +      await wallet.ws.runPending(args.runPendingOpt.forceNow); +    }); +  }); + +advancedCli +  .subcommand("", "pending", { help: "Show pending operations." }) +  .action(async (args) => { +    await withWallet(args, async (wallet) => { +      const pending = await wallet.client.call( +        WalletApiOperation.GetPendingOperations, +        {}, +      ); +      console.log(JSON.stringify(pending, undefined, 2)); +    }); +  }); + +advancedCli    .subcommand("bench1", "bench1", {      help: "Run the 'bench1' benchmark",    }) diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts index 59980621f..aa74e327f 100644 --- a/packages/taler-wallet-core/src/db.ts +++ b/packages/taler-wallet-core/src/db.ts @@ -521,7 +521,7 @@ export interface ExchangeRecord {     * Should usually not change.  Only changes when the     * exchange advertises a different master public key and/or     * currency. -   *  +   *     * FIXME: Use a rowId here?     */    detailsPointer: ExchangeDetailsPointer | undefined; @@ -1364,7 +1364,7 @@ export interface WithdrawalGroupRecord {    /**     * Wire information (as payto URI) for the bank account that     * transferred funds for this reserve. -   *  +   *     * FIXME: Doesn't this belong to the bankAccounts object store?     */    senderWire?: string; diff --git a/packages/taler-wallet-core/src/operations/exchanges.ts b/packages/taler-wallet-core/src/operations/exchanges.ts index 142bedd83..d0da2e948 100644 --- a/packages/taler-wallet-core/src/operations/exchanges.ts +++ b/packages/taler-wallet-core/src/operations/exchanges.ts @@ -134,6 +134,7 @@ export async function downloadExchangeWithTermsOfService(    timeout: Duration,    contentType: string,  ): Promise<ExchangeTosDownloadResult> { +  logger.info(`downloading exchange tos (type ${contentType})`);    const reqUrl = new URL("terms", exchangeBaseUrl);    const headers = {      Accept: contentType, @@ -524,7 +525,9 @@ export async function downloadTosFromAcceptedFormat(          break;        }      } -  if (tosFound !== undefined) return tosFound; +  if (tosFound !== undefined) { +    return tosFound; +  }    // If none of the specified format was found try text/plain    return await downloadExchangeWithTermsOfService(      baseUrl, @@ -557,7 +560,7 @@ export async function updateExchangeFromUrl(   */  export async function updateExchangeFromUrlHandler(    ws: InternalWalletState, -  baseUrl: string, +  exchangeBaseUrl: string,    options: {      forceNow?: boolean;      cancellationToken?: CancellationToken; @@ -569,19 +572,21 @@ export async function updateExchangeFromUrlHandler(    }>  > {    const forceNow = options.forceNow ?? false; -  logger.info(`updating exchange info for ${baseUrl}, forced: ${forceNow}`); +  logger.info( +    `updating exchange info for ${exchangeBaseUrl}, forced: ${forceNow}`, +  );    const now = AbsoluteTime.now(); -  baseUrl = canonicalizeBaseUrl(baseUrl); +  exchangeBaseUrl = canonicalizeBaseUrl(exchangeBaseUrl);    let isNewExchange = true;    const { exchange, exchangeDetails } = await ws.db      .mktx((x) => [x.exchanges, x.exchangeDetails])      .runReadWrite(async (tx) => { -      let oldExch = await tx.exchanges.get(baseUrl); +      let oldExch = await tx.exchanges.get(exchangeBaseUrl);        if (oldExch) {          isNewExchange = false;        } -      return provideExchangeRecordInTx(ws, tx, baseUrl, now); +      return provideExchangeRecordInTx(ws, tx, exchangeBaseUrl, now);      });    if ( @@ -600,11 +605,15 @@ export async function updateExchangeFromUrlHandler(    const timeout = getExchangeRequestTimeout(); -  const keysInfo = await downloadExchangeKeysInfo(baseUrl, ws.http, timeout); +  const keysInfo = await downloadExchangeKeysInfo( +    exchangeBaseUrl, +    ws.http, +    timeout, +  );    logger.info("updating exchange /wire info");    const wireInfoDownload = await downloadExchangeWireInfo( -    baseUrl, +    exchangeBaseUrl,      ws.http,      timeout,    ); @@ -632,15 +641,15 @@ export async function updateExchangeFromUrlHandler(    logger.info("finished validating exchange /wire info"); +  // We download the text/plain version here, +  // because that one needs to exist, and we +  // will get the current etag from the response.    const tosDownload = await downloadTosFromAcceptedFormat(      ws, -    baseUrl, +    exchangeBaseUrl,      timeout,      ["text/plain"],    ); -  const tosHasBeenAccepted = -    exchangeDetails?.tosAccepted && -    exchangeDetails.tosAccepted.etag === tosDownload.tosEtag;    let recoupGroupId: string | undefined; @@ -651,6 +660,7 @@ export async function updateExchangeFromUrlHandler(    const updated = await ws.db      .mktx((x) => [        x.exchanges, +      x.exchangeTos,        x.exchangeDetails,        x.exchangeSignkeys,        x.denominations, @@ -659,13 +669,13 @@ export async function updateExchangeFromUrlHandler(        x.recoupGroups,      ])      .runReadWrite(async (tx) => { -      const r = await tx.exchanges.get(baseUrl); +      const r = await tx.exchanges.get(exchangeBaseUrl);        if (!r) { -        logger.warn(`exchange ${baseUrl} no longer present`); +        logger.warn(`exchange ${exchangeBaseUrl} no longer present`);          return;        }        let existingDetails = await getExchangeDetails(tx, r.baseUrl); -      let acceptedTosEtag = undefined; +      let acceptedTosEtag: string | undefined = undefined;        if (!existingDetails) {          detailsPointerChanged = true;        } @@ -708,6 +718,21 @@ export async function updateExchangeFromUrlHandler(        const drRowId = await tx.exchangeDetails.put(newDetails);        checkDbInvariant(typeof drRowId.key === "number"); +      let tosRecord = await tx.exchangeTos.get([ +        exchangeBaseUrl, +        tosDownload.tosEtag, +      ]); + +      if (!tosRecord || tosRecord.etag !== existingTosAccepted?.etag) { +        tosRecord = { +          etag: tosDownload.tosEtag, +          exchangeBaseUrl, +          termsOfServiceContentType: tosDownload.tosContentType, +          termsOfServiceText: tosDownload.tosText, +        }; +        await tx.exchangeTos.put(tosRecord); +      } +        for (const sk of keysInfo.signingKeys) {          // FIXME: validate signing keys before inserting them          await tx.exchangeSignKeys.put({ @@ -726,7 +751,7 @@ export async function updateExchangeFromUrlHandler(        );        for (const currentDenom of keysInfo.currentDenominations) {          const oldDenom = await tx.denominations.get([ -          baseUrl, +          exchangeBaseUrl,            currentDenom.denomPubHash,          ]);          if (oldDenom) { @@ -802,6 +827,7 @@ export async function updateExchangeFromUrlHandler(            newlyRevokedCoinPubs,          );        } +        return {          exchange: r,          exchangeDetails: newDetails, diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts index 7839f3dab..d97e5ba80 100644 --- a/packages/taler-wallet-core/src/wallet.ts +++ b/packages/taler-wallet-core/src/wallet.ts @@ -631,7 +631,7 @@ async function getExchangeTosStatusDetails(    return {      acceptedVersion: exchangeDetails.tosAccepted?.etag, -    content: exchangeTos.termsOfServiceContentType, +    content: exchangeTos.termsOfServiceText,      contentType: exchangeTos.termsOfServiceContentType,      currentVersion: exchangeTos.etag,    }; | 
