taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

commit b4d1c980d688c68628b0293b2f313c28990cf17f
parent d5b68895e9545d3482eaf7ac5f38069dcb111a3a
Author: Florian Dold <florian@dold.me>
Date:   Thu, 30 Jul 2026 19:17:04 +0200

util: add paytoFromTransferSubject helper

Diffstat:
Mpackages/taler-util/src/payto.ts | 35++++++++++++++++++++++++++++++++---
Mpackages/taler-wallet-core/src/common.ts | 30+++++++++++++-----------------
2 files changed, 45 insertions(+), 20 deletions(-)

diff --git a/packages/taler-util/src/payto.ts b/packages/taler-util/src/payto.ts @@ -15,22 +15,25 @@ */ import { BitcoinBech32 } from "./bech32.js"; -import { BitcoinSewgit } from "./segwit_addr.js"; import { generateFakeSegwitAddress } from "./bitcoin.js"; import { Codec, Context, DecodingError, renderContext } from "./codec.js"; import { assertUnreachable, TalerError } from "./errors.js"; -import { TalerErrorCode } from "./taler-error-codes.js"; import { IbanString, parseIban, ParseIbanError } from "./iban.js"; -import { AmountString } from "./index.node.js"; +import { AmountString, j2s, Logger } from "./index.node.js"; import { Result, ResultError, ResultOk } from "./result.js"; +import { BitcoinSewgit } from "./segwit_addr.js"; import { decodeCrock, encodeCrock, hashTruncate32, stringToBytes, } from "./taler-crypto.js"; +import { TalerErrorCode } from "./taler-error-codes.js"; +import { TransferSubject } from "./types-taler-prepared-transfer.js"; import { URLSearchParams } from "./url.js"; +const logger = new Logger("payto.ts"); + export type PaytoString = string; const PAYTO_PREFIX = "payto://"; @@ -1031,3 +1034,29 @@ function createSearchParams(paramList: [string, string][]): string { .map(([key, value]) => `${rfc3986(key)}=${rfc3986(value)}`) .join("&"); } + +export function paytoFromTransferSubject( + basePayto: string, + opt: TransferSubject, +): string | undefined { + switch (opt.type) { + case "SIMPLE": { + return addPaytoQueryParams(basePayto, { + message: opt.subject, + amount: opt.credit_amount, + }); + } + case "URI": { + return undefined; + } + case "CH_QR_BILL": { + return addPaytoQueryParams(basePayto, { + "ch-qrr": opt.qr_reference_number, + amount: opt.credit_amount, + }); + } + default: + logger.warn(`Unsupported transfer subject: ${j2s(opt)}`); + return undefined; + } +} diff --git a/packages/taler-wallet-core/src/common.ts b/packages/taler-wallet-core/src/common.ts @@ -31,8 +31,9 @@ import { ExchangeTosStatus, ExchangeUpdateStatus, ExchangeWireAccount, + HostPortPath, Logger, - ObservabilityEventType, + Paytos, RefreshReason, TalerError, TalerErrorCode, @@ -52,29 +53,28 @@ import { assertUnreachable, checkDbInvariant, checkLogicInvariant, + decodeCrock, durationMul, getQrCodesForPayto, j2s, + paytoFromTransferSubject, succeedOrThrow, - decodeCrock, - HostPortPath, - Paytos, } from "@gnu-taler/taler-util"; import { HttpRequestOptions, HttpResponse } from "@gnu-taler/taler-util/http"; import { DbPreciseTimestamp, ExchangeEntryDbRecordStatus, ExchangeEntryDbUpdateStatus, - timestampPreciseToDb, - WalletRetryInfo, - WalletCoinHistory, WalletCoin, + WalletCoinHistory, WalletDepositGroup, + WalletExchangeEntry, + WalletPurchase, WalletRecoupGroup, WalletRefreshGroup, + WalletRetryInfo, WalletWithdrawalGroup, - WalletPurchase, - WalletExchangeEntry, + timestampPreciseToDb, } from "./db-common.js"; import { PeerPullCreditRecord, @@ -1223,10 +1223,8 @@ export async function prepareTransferOptionsRaw( for (const opt of resp.subjects) { switch (opt.type) { case "SIMPLE": { - const myPayto = addPaytoQueryParams(acct.payto_uri, { - message: opt.subject, - amount: transferAmount, - }); + const myPayto = paytoFromTransferSubject(acct.payto_uri, opt); + checkLogicInvariant(!!myPayto); options.push({ type: "payto", paytoUri: myPayto, @@ -1242,10 +1240,8 @@ export async function prepareTransferOptionsRaw( break; } case "CH_QR_BILL": { - const myPayto = addPaytoQueryParams(acct.payto_uri, { - "ch-qrr": opt.qr_reference_number, - amount: transferAmount, - }); + const myPayto = paytoFromTransferSubject(acct.payto_uri, opt); + checkLogicInvariant(!!myPayto); options.push({ type: "ch-qr-bill", paytoUri: myPayto,