commit bef888c4ebbf14c2c1894f8ad3d084191eb81bc8 parent a546f6d18f654dff9b308a21da91e668ad1735b5 Author: Florian Dold <florian@dold.me> Date: Sat, 18 Jul 2026 17:25:40 +0200 remove usages of deprecated payto helpers Diffstat:
38 files changed, 227 insertions(+), 210 deletions(-)
diff --git a/packages/taler-exchange-aml-webui/src/pages/DecisionWizard.tsx b/packages/taler-exchange-aml-webui/src/pages/DecisionWizard.tsx @@ -15,8 +15,9 @@ */ import { assertUnreachable, - parsePaytoUri, - PaytoUri, + Paytos, + PaytoType, + Result, TalerError, TranslatedString, } from "@gnu-taler/taler-util"; @@ -368,15 +369,14 @@ function Header({ const { i18n } = useTranslationContext(); const isNewAccount = !!newPayto; - let newPaytoParsed: PaytoUri | undefined; + let newPaytoParsed: Paytos.URI | undefined; const isNewAccountAWallet = newPayto === undefined ? undefined - : (newPaytoParsed = parsePaytoUri(newPayto)) === undefined + : (newPaytoParsed = Result.orUndefined(Paytos.fromString(newPayto))) === undefined ? undefined - : newPaytoParsed.isKnown && - (newPaytoParsed.targetType === "taler-reserve" || - newPaytoParsed.targetType === "taler-reserve-http"); + : newPaytoParsed.targetType === PaytoType.TalerReserve || + newPaytoParsed.targetType === PaytoType.TalerReserveHttp; const activeDecision = useAccountActiveDecision( isNewAccount ? undefined : account, diff --git a/packages/taler-exchange-aml-webui/src/pages/decision/Rules.tsx b/packages/taler-exchange-aml-webui/src/pages/decision/Rules.tsx @@ -25,8 +25,9 @@ import { KycRule, LegitimizationRuleSet, LimitOperationType, - parsePaytoUri, - PaytoUri, + Paytos, + PaytoType, + Result, TalerError, TranslatedString, } from "@gnu-taler/taler-util"; @@ -138,15 +139,14 @@ export function Rules({ newPayto }: { newPayto?: string }): VNode { const { config } = useExchangeApiContext(); const [request] = useCurrentDecisionRequest(); - let newPaytoParsed: PaytoUri | undefined; + let newPaytoParsed: Paytos.URI | undefined; const isNewAccountAWallet = newPayto === undefined ? undefined - : (newPaytoParsed = parsePaytoUri(newPayto)) === undefined + : (newPaytoParsed = Result.orUndefined(Paytos.fromString(newPayto))) === undefined ? undefined - : newPaytoParsed.isKnown && - (newPaytoParsed.targetType === "taler-reserve" || - newPaytoParsed.targetType === "taler-reserve-http"); + : newPaytoParsed.targetType === PaytoType.TalerReserve || + newPaytoParsed.targetType === PaytoType.TalerReserveHttp; // info may be undefined if this is a new account // for which we use the payto:// parameter diff --git a/packages/taler-harness/src/harness/harness.ts b/packages/taler-harness/src/harness/harness.ts @@ -67,7 +67,7 @@ import { hash, j2s, openPromise, - parsePaytoUri, + Paytos, stringToBytes, succeedOrThrow, } from "@gnu-taler/taler-util"; @@ -1898,7 +1898,7 @@ export class ExchangeService implements ExchangeServiceInterface { for (const acct of this.exchangeBankAccounts) { const paytoUri = acct.accountPaytoUri; - const p = parsePaytoUri(paytoUri); + const p = Result.orUndefined(Paytos.fromString(paytoUri)); if (!p) { throw Error(`invalid payto uri in exchange config: ${paytoUri}`); } @@ -1927,9 +1927,9 @@ export class ExchangeService implements ExchangeServiceInterface { ], ); - const accTargetType = p.targetType; + const accTargetType = p.targetType!; - const covered = accountTargetTypes.has(p.targetType); + const covered = accountTargetTypes.has(p.targetType!); if (!covered && !acct.skipWireFeeCreation) { const year = new Date().getFullYear(); diff --git a/packages/taler-harness/src/harness/tops.ts b/packages/taler-harness/src/harness/tops.ts @@ -33,7 +33,8 @@ import { MerchantAccountKycStatus, OfficerId, OfficerSession, - parsePaytoUriOrThrow, + Paytos, + Result, succeedOrThrow, TalerCorebankApiClient, TalerCoreBankHttpClient, @@ -876,9 +877,9 @@ export async function doTopsKycAuth( const depositPaytoUri = kycBody.kyc_data[0].payto_uri; t.assertTrue(kycBody.kyc_data[0].payto_kycauths != null); - const authTxPayto = parsePaytoUriOrThrow( + const authTxPayto = Result.unpack(Paytos.fromString( kycBody.kyc_data[0]?.payto_kycauths[0], - ); + )); const authTxMessage = authTxPayto?.params["message"]; t.assertTrue(typeof authTxMessage === "string"); t.assertTrue(authTxMessage.startsWith("KYC:")); diff --git a/packages/taler-harness/src/index.ts b/packages/taler-harness/src/index.ts @@ -55,7 +55,6 @@ import { hashFullPaytoUri, hashNormalizedPaytoUri, j2s, - parsePaytoUriOrThrow, randomBytes, rsaBlind, setGlobalLogLevelFromString, @@ -2115,7 +2114,7 @@ merchantCli accountPub: encodeCrock(merchantPub), accountSig: accountOwnerSig, paytoHash: encodeCrock( - hashNormalizedPaytoUri(parsePaytoUriOrThrow(payto_uri)), + hashNormalizedPaytoUri(payto_uri), ), }); return { diff --git a/packages/taler-harness/src/integrationtests/test-kyc-deposit-deposit-kyctransfer.ts b/packages/taler-harness/src/integrationtests/test-kyc-deposit-deposit-kyctransfer.ts @@ -20,7 +20,8 @@ import { Configuration, Logger, - parsePaytoUri, + Paytos, + Result, succeedOrThrow, TransactionMajorState, TransactionMinorState, @@ -130,7 +131,7 @@ export async function runKycDepositDepositKyctransferTest(t: GlobalTestState) { { const kycAuthCreditPayto = kycTx.creditPaytoUris[0]; t.assertTrue(!!kycAuthCreditPayto); - const p = parsePaytoUri(kycAuthCreditPayto); + const p = Result.orUndefined(Paytos.fromString(kycAuthCreditPayto)); t.assertTrue(!!p); t.assertAmountEquals(p.params["amount"], "TESTKUDOS:0.01"); } diff --git a/packages/taler-harness/src/integrationtests/test-kyc-merchant-activate-bank-account.ts b/packages/taler-harness/src/integrationtests/test-kyc-merchant-activate-bank-account.ts @@ -24,7 +24,8 @@ import { Logger, MerchantAccountKycRedirectsResponse, MerchantAccountKycStatus, - parsePaytoUri, + Paytos, + Result, succeedOrThrow, } from "@gnu-taler/taler-util"; import { readSuccessResponseJsonOrThrow } from "@gnu-taler/taler-util/http"; @@ -122,7 +123,7 @@ export async function runKycMerchantActivateBankAccountTest( const kycauthPayto = kycRespOne.kyc_data[0].payto_kycauths![0]; logger.info(`kycauth payto: ${kycauthPayto}`); - const p = parsePaytoUri(kycauthPayto); + const p = Result.orUndefined(Paytos.fromString(kycauthPayto)); const msgAccountPub = p?.params["message"]; t.assertTrue(!!accountPub); diff --git a/packages/taler-harness/src/integrationtests/test-merchant-kyc-auth-multi.ts b/packages/taler-harness/src/integrationtests/test-merchant-kyc-auth-multi.ts @@ -25,7 +25,8 @@ import { j2s, Logger, MerchantAccountKycStatus, - parsePaytoUriOrThrow, + Paytos, + Result, succeedOrThrow, TalerMerchantInstanceHttpClient, TalerProtocolDuration, @@ -128,7 +129,7 @@ async function doAccountKycAuth( t.assertTrue( myRow?.payto_kycauths != null && myRow.payto_kycauths.length == 1, ); - const authTxPayto = parsePaytoUriOrThrow(myRow.payto_kycauths[0]); + const authTxPayto = Result.unpack(Paytos.fromString(myRow.payto_kycauths[0])); const authTxMessage = authTxPayto?.params["message"]; t.assertTrue(typeof authTxMessage === "string"); t.assertTrue(authTxMessage.startsWith("KYC:")); diff --git a/packages/taler-harness/src/integrationtests/test-merchant-payto-reuse.ts b/packages/taler-harness/src/integrationtests/test-merchant-payto-reuse.ts @@ -26,7 +26,8 @@ import { j2s, Logger, MerchantAccountKycStatus, - parsePaytoUriOrThrow, + Paytos, + Result, PreparePayResultType, succeedOrThrow, TalerMerchantInstanceHttpClient, @@ -133,7 +134,7 @@ async function doAccountKycAuth( t.assertTrue( myRow?.payto_kycauths != null && myRow.payto_kycauths.length == 1, ); - const authTxPayto = parsePaytoUriOrThrow(myRow.payto_kycauths[0]); + const authTxPayto = Result.unpack(Paytos.fromString(myRow.payto_kycauths[0])); const authTxMessage = authTxPayto?.params["message"]; t.assertTrue(typeof authTxMessage === "string"); t.assertTrue(authTxMessage.startsWith("KYC:")); diff --git a/packages/taler-harness/src/integrationtests/test-tops-aml-basic.ts b/packages/taler-harness/src/integrationtests/test-tops-aml-basic.ts @@ -24,7 +24,8 @@ import { j2s, Logger, MerchantAccountKycStatus, - parsePaytoUriOrThrow, + Paytos, + Result, succeedOrThrow, TalerExchangeHttpClient, TalerMerchantInstanceHttpClient, @@ -86,9 +87,9 @@ export async function runTopsAmlBasicTest(t: GlobalTestState) { const depositPaytoUri = kycStatus.body.kyc_data[0].payto_uri; t.assertTrue(kycStatus.body.kyc_data[0].payto_kycauths != null); - const authTxPayto = parsePaytoUriOrThrow( + const authTxPayto = Result.unpack(Paytos.fromString( kycStatus.body.kyc_data[0]?.payto_kycauths[0], - ); + )); const authTxMessage = authTxPayto?.params["message"]; t.assertTrue(typeof authTxMessage === "string"); t.assertTrue(authTxMessage.startsWith("KYC:")); diff --git a/packages/taler-harness/src/integrationtests/test-tops-aml-custom-addr-postal.ts b/packages/taler-harness/src/integrationtests/test-tops-aml-custom-addr-postal.ts @@ -24,7 +24,8 @@ import { j2s, Logger, MerchantAccountKycStatus, - parsePaytoUriOrThrow, + Paytos, + Result, succeedOrThrow, TalerExchangeHttpClient, TalerMerchantInstanceHttpClient, @@ -79,9 +80,9 @@ export async function runTopsAmlCustomAddrPostalTest(t: GlobalTestState) { const depositPaytoUri = kycStatus.body.kyc_data[0].payto_uri; t.assertTrue(kycStatus.body.kyc_data[0].payto_kycauths != null); - const authTxPayto = parsePaytoUriOrThrow( + const authTxPayto = Result.unpack(Paytos.fromString( kycStatus.body.kyc_data[0]?.payto_kycauths[0], - ); + )); const authTxMessage = authTxPayto?.params["message"]; t.assertTrue(typeof authTxMessage === "string"); t.assertTrue(authTxMessage.startsWith("KYC:")); diff --git a/packages/taler-harness/src/integrationtests/test-tops-aml-custom-addr-sms.ts b/packages/taler-harness/src/integrationtests/test-tops-aml-custom-addr-sms.ts @@ -27,7 +27,8 @@ import { MerchantAccountKycStatus, OfficerId, OfficerSession, - parsePaytoUriOrThrow, + Paytos, + Result, succeedOrThrow, TalerExchangeHttpClient, TalerMerchantInstanceHttpClient, @@ -82,9 +83,9 @@ export async function runTopsAmlCustomAddrSmsTest(t: GlobalTestState) { const depositPaytoUri = kycStatus.body.kyc_data[0].payto_uri; t.assertTrue(kycStatus.body.kyc_data[0].payto_kycauths != null); - const authTxPayto = parsePaytoUriOrThrow( + const authTxPayto = Result.unpack(Paytos.fromString( kycStatus.body.kyc_data[0]?.payto_kycauths[0], - ); + )); const authTxMessage = authTxPayto?.params["message"]; t.assertTrue(typeof authTxMessage === "string"); t.assertTrue(authTxMessage.startsWith("KYC:")); diff --git a/packages/taler-harness/src/lint.ts b/packages/taler-harness/src/lint.ts @@ -38,7 +38,8 @@ import { codecForKeysManagementResponse, Configuration, decodeCrock, - parsePaytoUri, + Paytos, + Result, succeedOrThrow, TalerExchangeHttpClient, TalerProtocolTimestamp, @@ -654,12 +655,12 @@ export async function lintExchangeUrl(exchangeBaseUrl: string): Promise<void> { } let wireTypesSet = new Set<string>(); for (const acc of keysResp.accounts) { - const payto = parsePaytoUri(acc.payto_uri); + const payto = Result.orUndefined(Paytos.fromString(acc.payto_uri)); if (!payto) { reporter.reportError(`invalid account payto URI: ${acc.payto_uri}`); continue; } - wireTypesSet.add(payto?.targetType); + wireTypesSet.add(payto.targetType!); } for (const wireType of wireTypesSet) { let haveAccountFees = false; diff --git a/packages/taler-merchant-webui/src/components/form/InputPaytoForm.tsx b/packages/taler-merchant-webui/src/components/form/InputPaytoForm.tsx @@ -22,7 +22,8 @@ import { InternationalizationAPI, PaytoUri, TranslatedString, - parsePaytoUri, + Paytos, + Result, stringifyPaytoUri, } from "@gnu-taler/taler-util"; import { useTranslationContext } from "@gnu-taler/web-util/browser"; @@ -221,7 +222,7 @@ export function InputPaytoForm<T>({ const { config } = useSessionContext(); - const initialPayto = parsePaytoUri(initialValueStr ?? ""); + const initialPayto = Result.orUndefined(Paytos.fromString(initialValueStr ?? "")); const { i18n } = useTranslationContext(); const supportedWireMethods = @@ -241,7 +242,7 @@ export function InputPaytoForm<T>({ }; // FIXME: use new paytos API and EBICS is not supported - const paths = !initialPayto ? [] : initialPayto.targetPath.split("/"); + const paths = !initialPayto ? [] : initialPayto.fullPath.split("/"); const initialPath1 = paths.length >= 1 ? paths[0] : undefined; const initialPath2 = paths.length >= 2 ? paths[1] : undefined; const initial: Entity = diff --git a/packages/taler-merchant-webui/src/paths/instance/accounts/list/Table.tsx b/packages/taler-merchant-webui/src/paths/instance/accounts/list/Table.tsx @@ -22,10 +22,8 @@ import { assertUnreachable, HttpStatusCode, - parsePaytoUri, Paytos, PaytoType, - PaytoUri, Result, TalerMerchantApi, } from "@gnu-taler/taler-util"; @@ -181,7 +179,7 @@ function Table({ accounts, onDelete, onSelect }: TableProps): VNode { const { i18n } = useTranslationContext(); const emptyList: Record< PaytoType | "unknown", - { parsed: PaytoUri; acc: Entity }[] + { parsed: Paytos.URI; acc: Entity }[] > = { bitcoin: [], "x-taler-bank": [], @@ -194,14 +192,14 @@ function Table({ accounts, onDelete, onSelect }: TableProps): VNode { }; const accountsByType = accounts.reduce((prev, acc) => { - const parsed = parsePaytoUri(acc.payto_uri); + const parsed = Result.orUndefined(Paytos.fromString(acc.payto_uri)); if (!parsed) return prev; //skip if ( - parsed.targetType !== "bitcoin" && - parsed.targetType !== "taler-reserve" && - parsed.targetType !== "taler-reserve-http" && - parsed.targetType !== "x-taler-bank" && - parsed.targetType !== "iban" + parsed.targetType !== PaytoType.Bitcoin && + parsed.targetType !== PaytoType.TalerReserve && + parsed.targetType !== PaytoType.TalerReserveHttp && + parsed.targetType !== PaytoType.TalerBank && + parsed.targetType !== PaytoType.IBAN ) { prev["unknown"].push({ parsed, acc }); } else { diff --git a/packages/taler-util/src/qr.ts b/packages/taler-util/src/qr.ts @@ -18,7 +18,8 @@ * Imports. */ import { Amounts } from "./amounts.js"; -import { parsePaytoUri } from "./payto.js"; +import { Paytos, PaytoType } from "./payto.js"; +import { Result } from "./result.js"; type EncodeResult = { type: "ok"; qrContent: string } | { type: "skip" }; @@ -26,11 +27,11 @@ type EncodeResult = { type: "ok"; qrContent: string } | { type: "skip" }; * See "Schweizer Implementation Guidelines QR-Rechnung". */ function encodePaytoAsSwissQrBill(paytoUri: string): EncodeResult { - const parsedPayto = parsePaytoUri(paytoUri); + const parsedPayto = Result.orUndefined(Paytos.fromString(paytoUri)); if (!parsedPayto) { throw Error("invalid payto URI"); } - if (parsedPayto.targetType !== "iban") { + if (parsedPayto.targetType !== PaytoType.IBAN) { return { type: "skip" }; } let referenceType = "NON"; @@ -40,7 +41,7 @@ function encodePaytoAsSwissQrBill(paytoUri: string): EncodeResult { referenceValue = parsedPayto.params["ch-qrr"]; } const amountStr = parsedPayto.params["amount"]; - const targetPathParts = parsedPayto.targetPath.split("/"); + const targetPathParts = parsedPayto.fullPath.split("/"); const beneficiaryIban = targetPathParts[targetPathParts.length - 1]; const countryCode = beneficiaryIban.slice(0, 2).toUpperCase(); if (countryCode !== "CH") { @@ -99,15 +100,15 @@ function encodePaytoAsSwissQrBill(paytoUri: string): EncodeResult { * Initiation of a SEPA Credit Transfer". */ function encodePaytoAsEpcQr(paytoUri: string): EncodeResult { - const parsedPayto = parsePaytoUri(paytoUri); + const parsedPayto = Result.orUndefined(Paytos.fromString(paytoUri)); if (!parsedPayto) { throw Error("invalid payto URI"); } - if (parsedPayto.targetType !== "iban") { + if (parsedPayto.targetType !== PaytoType.IBAN) { return { type: "skip" }; } const amountStr = parsedPayto.params["amount"]; - const targetPathParts = parsedPayto.targetPath.split("/"); + const targetPathParts = parsedPayto.fullPath.split("/"); const beneficiaryIban = targetPathParts[targetPathParts.length - 1]; const countryCode = beneficiaryIban.slice(0, 2).toUpperCase(); switch (countryCode) { diff --git a/packages/taler-wallet-cli/src/index.ts b/packages/taler-wallet-cli/src/index.ts @@ -38,7 +38,7 @@ import { j2s, Logger, NotificationType, - parsePaytoUri, + Paytos, PreparePayResultType, Result, sampleWalletCoreTransactions, @@ -1827,7 +1827,7 @@ advancedCli .requiredArgument("paytoUri", clk.STRING) .requiredArgument("reservePub", clk.STRING) .action(async (args) => { - const p = parsePaytoUri(args.genSegwit.paytoUri); + const p = Result.orUndefined(Paytos.fromString(args.genSegwit.paytoUri)); console.log(p); }); diff --git a/packages/taler-wallet-core/src/balance.ts b/packages/taler-wallet-core/src/balance.ts @@ -73,7 +73,8 @@ import { GetBalanceDetailRequest, j2s, Logger, - parsePaytoUri, + Paytos, + Result, ScopeInfo, ScopeType, } from "@gnu-taler/taler-util"; @@ -1054,9 +1055,9 @@ export async function getBalanceDetail( continue; } details.wireInfo.accounts.forEach((a) => { - const payto = parsePaytoUri(a.payto_uri); - if (payto && !wires.includes(payto.targetType)) { - wires.push(payto.targetType); + const payto = Result.orUndefined(Paytos.fromString(a.payto_uri)); + if (payto && !wires.includes(payto.targetType!)) { + wires.push(payto.targetType!); } }); exchanges.push({ diff --git a/packages/taler-wallet-core/src/coinSelection.ts b/packages/taler-wallet-core/src/coinSelection.ts @@ -47,7 +47,8 @@ import { InsufficientBalanceHint, j2s, Logger, - parsePaytoUri, + Paytos, + Result, PayCoinSelection, PaymentInsufficientBalanceDetails, ScopeInfo, @@ -201,7 +202,7 @@ async function internalSelectPayCoins( > { let restrictWireMethod; if (req.depositPaytoUri) { - const parsedPayto = parsePaytoUri(req.depositPaytoUri); + const parsedPayto = Result.orUndefined(Paytos.fromString(req.depositPaytoUri)); if (!parsedPayto) { throw Error("invalid payto URI"); } @@ -845,7 +846,7 @@ export function findMatchingWire( | undefined { const accountRestrictions: Record<string, AccountRestriction[]> = {}; for (const acc of exchangeWireDetails.wireInfo.accounts) { - const pp = parsePaytoUri(acc.payto_uri); + const pp = Result.orUndefined(Paytos.fromString(acc.payto_uri)); checkLogicInvariant(!!pp); if (pp.targetType !== wireMethod) { continue; @@ -1467,7 +1468,7 @@ export async function getMaxDepositAmount( }, ); if (req.depositPaytoUri) { - const p = parsePaytoUri(req.depositPaytoUri); + const p = Result.orUndefined(Paytos.fromString(req.depositPaytoUri)); if (!p) { throw Error("invalid payto URI"); } diff --git a/packages/taler-wallet-core/src/dbless.ts b/packages/taler-wallet-core/src/dbless.ts @@ -51,7 +51,8 @@ import { hashDenomPub, hashWire, j2s, - parsePaytoUri, + Paytos, + Result, succeedOrThrow, } from "@gnu-taler/taler-util"; import { @@ -437,11 +438,11 @@ export async function createTestingReserve(args: { }): Promise<void> { const { http, corebankApiBaseUrl, amount, reservePub } = args; const paytoUri = args.exchangeInfo.keys.accounts[0].payto_uri; - const pt = parsePaytoUri(paytoUri); + const pt = Result.orUndefined(Paytos.fromString(paytoUri)); if (!pt) { throw Error("failed to parse payto URI"); } - const components = pt.targetPath.split("/"); + const components = pt.fullPath.split("/"); const creditorAcct = components[components.length - 1]; const fbReq = await http.fetch( new URL( diff --git a/packages/taler-wallet-core/src/deposits.ts b/packages/taler-wallet-core/src/deposits.ts @@ -78,7 +78,8 @@ import { hashNormalizedPaytoUri, hashWire, j2s, - parsePaytoUri, + Paytos, + Result, } from "@gnu-taler/taler-util"; import { readResponseJsonOrThrow, @@ -1498,14 +1499,14 @@ async function processDepositGroupTrack( } else if (track.type === "wired") { updatedTxStatus = DepositElementStatus.Wired; - const payto = parsePaytoUri(depositGroup.wire.payto_uri); + const payto = Result.orUndefined(Paytos.fromString(depositGroup.wire.payto_uri)); if (!payto) { throw Error(`unparsable payto: ${depositGroup.wire.payto_uri}`); } const fee = await getExchangeWireFee( wex, - payto.targetType, + payto.targetType!, exchangeBaseUrl, track.execution_time, ); @@ -2019,7 +2020,7 @@ export async function internalCheckDepositGroup( wex: WalletExecutionContext, req: CheckDepositRequest, ): Promise<CheckDepositResponse> { - const p = parsePaytoUri(req.depositPaytoUri); + const p = Result.orUndefined(Paytos.fromString(req.depositPaytoUri)); if (!p) { throw Error("invalid payto URI"); } @@ -2048,7 +2049,7 @@ export async function internalCheckDepositGroup( }), }, restrictScope: req.restrictScope, - restrictWireMethod: p.targetType, + restrictWireMethod: p.targetType!, depositPaytoUri: req.depositPaytoUri, contractTermsAmount: Amounts.parseOrThrow(req.amount), depositFeeLimit, @@ -2076,7 +2077,7 @@ export async function internalCheckDepositGroup( const effectiveDepositAmount = await getCounterpartyEffectiveDepositAmount( wex, - p.targetType, + p.targetType!, selCoins, ); @@ -2093,7 +2094,7 @@ export async function internalCheckDepositGroup( const fees = await getTotalFeesForDepositAmount( wex, - p.targetType, + p.targetType!, amount, selCoins, ); @@ -2110,7 +2111,7 @@ export async function createDepositGroup( wex: WalletExecutionContext, req: CreateDepositGroupRequest, ): Promise<CreateDepositGroupResponse> { - const depositPayto = parsePaytoUri(req.depositPaytoUri); + const depositPayto = Result.orUndefined(Paytos.fromString(req.depositPaytoUri)); if (!depositPayto) { throw Error("invalid payto URI"); } @@ -2141,7 +2142,7 @@ export async function createDepositGroup( })), }, restrictScope: req.restrictScope, - restrictWireMethod: depositPayto.targetType, + restrictWireMethod: depositPayto.targetType!, depositPaytoUri: req.depositPaytoUri, contractTermsAmount: amount, depositFeeLimit: amount, @@ -2209,7 +2210,7 @@ export async function createDepositGroup( })), amount: req.amount, max_fee: Amounts.stringify(amount), - wire_method: depositPayto.targetType, + wire_method: depositPayto.targetType!, timestamp: nowRounded, merchant_base_url: "", summary: "", @@ -2279,7 +2280,7 @@ export async function createDepositGroup( const counterpartyEffectiveDepositAmount = await getCounterpartyEffectiveDepositAmount( wex, - depositPayto.targetType, + depositPayto.targetType!, coins, ); diff --git a/packages/taler-wallet-core/src/exchanges.ts b/packages/taler-wallet-core/src/exchanges.ts @@ -107,7 +107,8 @@ import { j2s, makeErrorDetail, makeTalerErrorDetail, - parsePaytoUri, + Paytos, + Result, stringifyReservePaytoUri, stringifyScopeInfo, } from "@gnu-taler/taler-util"; @@ -2706,11 +2707,11 @@ export async function getExchangePaytoUri( }); const accounts = details?.wireInfo.accounts ?? []; for (const account of accounts) { - const res = parsePaytoUri(account.payto_uri); + const res = Result.orUndefined(Paytos.fromString(account.payto_uri)); if (!res) { continue; } - if (supportedTargetTypes.includes(res.targetType)) { + if (supportedTargetTypes.includes(res.targetType!)) { return account.payto_uri; } } diff --git a/packages/taler-wallet-core/src/testing.ts b/packages/taler-wallet-core/src/testing.ts @@ -39,7 +39,8 @@ import { j2s, Logger, NotificationType, - parsePaytoUri, + Paytos, + Result, PreparePayResultType, TalerCorebankApiClient, TestingWaitBalanceRequest, @@ -914,7 +915,7 @@ async function runIntegrationTest2Impl( let depositPayto = withdrawalRes.accountPaytoUri; - const parsedPayto = parsePaytoUri(depositPayto); + const parsedPayto = Result.orUndefined(Paytos.fromString(depositPayto)); if (!parsedPayto) { throw Error("invalid payto"); } diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts @@ -287,7 +287,7 @@ import { j2s, openPromise, parseIban, - parsePaytoUri, + PaytoType, performanceDelta, performanceNow, safeStringifyException, @@ -635,7 +635,7 @@ async function handleListBankAccounts( if (currency && r.currencies && !r.currencies.includes(currency)) { continue; } - const payto = parsePaytoUri(r.paytoUri); + const payto = Result.orUndefined(Paytos.fromString(r.paytoUri)); if (payto) { accounts.push({ bankAccountId: r.bankAccountId, @@ -1314,7 +1314,7 @@ async function handleGetBankingChoicesForPayto( wex: WalletExecutionContext, req: GetBankingChoicesForPaytoRequest, ): Promise<GetBankingChoicesForPaytoResponse> { - const parsedPayto = parsePaytoUri(req.paytoUri); + const parsedPayto = Result.orUndefined(Paytos.fromString(req.paytoUri)); if (!parsedPayto) { throw Error("invalid payto URI"); } @@ -1540,27 +1540,27 @@ async function handleGetDepositWireTypes( if (!usable) { continue; } - const parsedPayto = parsePaytoUri(acc.payto_uri); + const parsedPayto = Result.orUndefined(Paytos.fromString(acc.payto_uri)); if (!parsedPayto) { continue; } let preferredEntryType: "iban" | "bban" | undefined = undefined; - if (parsedPayto.targetType === "iban") { + if (parsedPayto.targetType === PaytoType.IBAN) { if (det.currency === "HUF") { preferredEntryType = "bban"; } else { preferredEntryType = "iban"; } } - if (parsedPayto.isKnown && parsedPayto.targetType === "x-taler-bank") { + if (parsedPayto.targetType === PaytoType.TalerBank) { if (!talerBankHostnames.includes(parsedPayto.host)) { talerBankHostnames.push(parsedPayto.host); } } - if (!wtSet.has(parsedPayto.targetType)) { - wtSet.add(parsedPayto.targetType); + if (!wtSet.has(parsedPayto.targetType!)) { + wtSet.add(parsedPayto.targetType!); wireTypeDetails.push({ - paymentTargetType: parsedPayto.targetType, + paymentTargetType: parsedPayto.targetType!, // Will possibly extended later by other exchanges // with the same wire type. talerBankHostnames, @@ -1603,19 +1603,19 @@ async function handleGetDepositWireTypesForCurrency( if (!usable) { continue; } - const parsedPayto = parsePaytoUri(acc.payto_uri); + const parsedPayto = Result.orUndefined(Paytos.fromString(acc.payto_uri)); if (!parsedPayto) { continue; } - if (parsedPayto.isKnown && parsedPayto.targetType === "x-taler-bank") { + if (parsedPayto.targetType === PaytoType.TalerBank) { if (!talerBankHostnames.includes(parsedPayto.host)) { talerBankHostnames.push(parsedPayto.host); } } - if (!wtSet.has(parsedPayto.targetType)) { - wtSet.add(parsedPayto.targetType); + if (!wtSet.has(parsedPayto.targetType!)) { + wtSet.add(parsedPayto.targetType!); wireTypeDetails.push({ - paymentTargetType: parsedPayto.targetType, + paymentTargetType: parsedPayto.targetType!, // Will possibly extended later by other exchanges // with the same wire type. talerBankHostnames, diff --git a/packages/taler-wallet-core/src/withdraw.ts b/packages/taler-wallet-core/src/withdraw.ts @@ -104,7 +104,7 @@ import { getRandomBytes, j2s, makeErrorDetail, - parsePaytoUri, + Paytos, succeedOrThrow, } from "@gnu-taler/taler-util"; import { @@ -3918,7 +3918,7 @@ export async function confirmWithdrawal( if (senderWire && !withdrawalGroup.isForeignAccount) { logger.info(`sender wire is ${senderWire}`); - const parsedSenderWire = parsePaytoUri(senderWire); + const parsedSenderWire = Result.orUndefined(Paytos.fromString(senderWire)); if (!parsedSenderWire) { throw Error("invalid payto URI"); } @@ -3927,7 +3927,7 @@ export async function confirmWithdrawal( logger.warn(`empty list of withdrawal accounts`); } for (const acc of withdrawalAccountList) { - const parsedExchangeWire = parsePaytoUri(acc.paytoUri); + const parsedExchangeWire = Result.orUndefined(Paytos.fromString(acc.paytoUri)); if (!parsedExchangeWire) { logger.warn( `unable to parse payto ${acc.paytoUri} of ${selectedExchange}`, diff --git a/packages/taler-wallet-webextension/src/components/HistoryItem.tsx b/packages/taler-wallet-webextension/src/components/HistoryItem.tsx @@ -24,7 +24,8 @@ import { WithdrawalType, TransactionMajorState, DenomLossEventType, - parsePaytoUri, + Paytos, + Result, assertUnreachable, } from "@gnu-taler/taler-util"; import { Fragment, h, VNode } from "preact"; @@ -156,9 +157,9 @@ export function HistoryItem(props: { tx: Transaction }): VNode { /> ); case TransactionType.Deposit: { - const payto = parsePaytoUri(tx.targetPaytoUri); + const payto = Result.orUndefined(Paytos.fromString(tx.targetPaytoUri)); const title = - payto === undefined || !payto.isKnown + payto === undefined ? tx.targetPaytoUri : payto.params["receiver-name"]; return ( diff --git a/packages/taler-wallet-webextension/src/components/Part.tsx b/packages/taler-wallet-webextension/src/components/Part.tsx @@ -15,8 +15,8 @@ */ import { - PaytoUri, - stringifyPaytoUri, + Paytos, + PaytoType, TranslatedString, } from "@gnu-taler/taler-util"; import { useTranslationContext } from "@gnu-taler/web-util/browser"; @@ -100,7 +100,7 @@ export function PartCollapsible({ text, title }: Props): VNode { } interface PropsPayto { - payto: PaytoUri; + payto: Paytos.URI; kind: Kind; big?: boolean; } @@ -109,27 +109,27 @@ export function PartPayto({ payto, kind, big }: PropsPayto): VNode { let text: VNode | undefined = undefined; let title = ""; const { i18n } = useTranslationContext(); - if (payto.isKnown) { - if (payto.targetType === "x-taler-bank") { + if (payto.targetType !== undefined) { + if (payto.targetType === PaytoType.TalerBank) { text = ( <a target="_bank" rel="noreferrer" href={payto.host}> {payto.account} </a> ); title = i18n.str`Bank account`; - } else if (payto.targetType === "bitcoin") { + } else if (payto.targetType === PaytoType.Bitcoin) { text = payto.segwitAddrs && payto.segwitAddrs.length > 0 ? ( <ul> - <li>{payto.targetPath}</li> + <li>{payto.fullPath}</li> <li>{payto.segwitAddrs[0]}</li> <li>{payto.segwitAddrs[1]}</li> </ul> ) : ( - <Fragment>{payto.targetPath}</Fragment> + <Fragment>{payto.fullPath}</Fragment> ); title = i18n.str`Bitcoin address`; - } else if (payto.targetType === "iban") { + } else if (payto.targetType === PaytoType.IBAN) { if (payto.bic) { text = ( <Fragment> @@ -144,7 +144,7 @@ export function PartPayto({ payto, kind, big }: PropsPayto): VNode { } } if (!text) { - text = <Fragment>{stringifyPaytoUri(payto)}</Fragment>; + text = <Fragment>{Paytos.toFullString(payto)}</Fragment>; title = "Payto URI"; } return ( diff --git a/packages/taler-wallet-webextension/src/cta/Deposit/Deposit.test.ts b/packages/taler-wallet-webextension/src/cta/Deposit/Deposit.test.ts @@ -25,7 +25,8 @@ import { AmountString, Amounts, ScopeType, - parsePaytoUri, + Paytos, + Result, } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import * as tests from "@gnu-taler/web-util/testing"; @@ -48,7 +49,9 @@ describe("Deposit CTA states", () => { }); const props = { - account: parsePaytoUri("payto://refund/asdasdas")!, + account: Result.orUndefined( + Paytos.fromString("payto://refund/asdasdas", { allowUnsupported: true }), + )!, scope: { type: ScopeType.Global as const, currency: "EUR", diff --git a/packages/taler-wallet-webextension/src/cta/Deposit/index.ts b/packages/taler-wallet-webextension/src/cta/Deposit/index.ts @@ -17,7 +17,7 @@ import { AmountJson, AmountString, - PaytoUri, + Paytos, ScopeInfo, } from "@gnu-taler/taler-util"; import { ErrorAlertView } from "../../components/CurrentAlerts.js"; @@ -29,7 +29,7 @@ import { useComponentState } from "./state.js"; import { ReadyView } from "./views.js"; export interface Props { - account: PaytoUri; + account: Paytos.URI; scope: ScopeInfo; cancel: () => Promise<void>; onSuccess: (tx: string) => Promise<void>; @@ -51,7 +51,7 @@ export namespace State { error: undefined; amount: AmountFieldHandler; fee: AmountJson; - account: PaytoUri; + account: Paytos.URI; cost: AmountJson; effective: AmountJson; confirm: ButtonHandler; diff --git a/packages/taler-wallet-webextension/src/cta/Deposit/state.ts b/packages/taler-wallet-webextension/src/cta/Deposit/state.ts @@ -14,7 +14,7 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { Amounts, stringifyPaytoUri } from "@gnu-taler/taler-util"; +import { Amounts, Paytos } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { alertFromError, useAlertContext } from "../../context/alert.js"; import { useBackendContext } from "../../context/backend.js"; @@ -37,7 +37,7 @@ export function useComponentState({ const hook = useAsyncAsHook(async () => { const deposit = await api.wallet.call(WalletApiOperation.CheckDeposit, { amount: amountStr, - depositPaytoUri: stringifyPaytoUri(account), + depositPaytoUri: Paytos.toFullString(account), }); return deposit; }, [amountStr]); @@ -67,7 +67,7 @@ export function useComponentState({ async function doDeposit(): Promise<void> { const resp = await api.wallet.call(WalletApiOperation.CreateDepositGroup, { amount: amountStr, - depositPaytoUri: stringifyPaytoUri(account), + depositPaytoUri: Paytos.toFullString(account), }); onSuccess(resp.transactionId); } diff --git a/packages/taler-wallet-webextension/src/cta/Deposit/stories.tsx b/packages/taler-wallet-webextension/src/cta/Deposit/stories.tsx @@ -19,7 +19,7 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { Amounts, parsePaytoUri } from "@gnu-taler/taler-util"; +import { Amounts, Paytos, Result } from "@gnu-taler/taler-util"; import * as tests from "@gnu-taler/web-util/testing"; import { ReadyView } from "./views.js"; @@ -33,7 +33,9 @@ export const Ready = tests.createExample(ReadyView, { amount: { value: Amounts.parseOrThrow("EUR:1"), }, - account: parsePaytoUri("payto://iban/DE1231231231")!, + account: Result.orUndefined( + Paytos.fromString("payto://iban/DE1231231231", { ignoreComponentError: true }), + )!, cost: Amounts.parseOrThrow("EUR:1.2"), effective: Amounts.parseOrThrow("EUR:1"), fee: Amounts.parseOrThrow("EUR:0.2"), diff --git a/packages/taler-wallet-webextension/src/wallet/Application.tsx b/packages/taler-wallet-webextension/src/wallet/Application.tsx @@ -29,7 +29,7 @@ import { TalerUris, TransactionIdStr, TranslatedString, - parsePaytoUri, + Paytos, parseScopeInfoShort, stringifyScopeInfoShort, } from "@gnu-taler/taler-util"; @@ -660,7 +660,7 @@ export function Application(): VNode { if (!s) { return <div>missing scope</div>; } - const p = parsePaytoUri(decodeCrockFromURI(account)); + const p = Result.orUndefined(Paytos.fromString(decodeCrockFromURI(account))); if (!p) { return <div>missing account</div>; } @@ -831,8 +831,8 @@ export function Application(): VNode { <Route path={Pages.paytoBanks.pattern} component={({ payto }: { payto: string }) => { - const pUri = parsePaytoUri( - decodeCrockFromURI(payto).toLowerCase(), + const pUri = Result.orUndefined( + Paytos.fromString(decodeCrockFromURI(payto).toLowerCase()), ); if (!pUri) { redirectTo(Pages.balanceHistory({})); @@ -848,8 +848,8 @@ export function Application(): VNode { <Route path={Pages.paytoQrs.pattern} component={({ payto }: { payto: string }) => { - const pUri = parsePaytoUri( - decodeCrockFromURI(payto).toLowerCase(), + const pUri = Result.orUndefined( + Paytos.fromString(decodeCrockFromURI(payto).toLowerCase()), ); if (!pUri) { redirectTo(Pages.balanceHistory({})); diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage/views.tsx b/packages/taler-wallet-webextension/src/wallet/DepositPage/views.tsx @@ -14,7 +14,7 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { Amounts, parsePaytoUri } from "@gnu-taler/taler-util"; +import { Amounts, Paytos, PaytoType, Result } from "@gnu-taler/taler-util"; import { useTranslationContext } from "@gnu-taler/web-util/browser"; import { Fragment, h, VNode } from "preact"; import { AmountField } from "../../components/AmountField.js"; @@ -48,7 +48,7 @@ export function NoEnoughBalanceView({ } function AccountDetails({ account }: { account: string }): VNode { - const p = parsePaytoUri(account); + const p = Result.orUndefined(Paytos.fromString(account)); if (!p) { return ( <dl> @@ -57,30 +57,30 @@ function AccountDetails({ account }: { account: string }): VNode { </dl> ); } - if (p.isKnown) { - if (p.targetType === "bitcoin") { + if (p.targetType !== undefined) { + if (p.targetType === PaytoType.Bitcoin) { return ( <dl> <dt>Bitcoin</dt> - <dd>{p.targetPath}</dd> + <dd>{p.fullPath}</dd> </dl> ); } - if (p.targetType === "x-taler-bank") { + if (p.targetType === PaytoType.TalerBank) { return ( <dl> <dt>Bank host</dt> - <dd>{p.targetPath.split("/")[0]}</dd> + <dd>{p.fullPath.split("/")[0]}</dd> <dt>Account name</dt> - <dd>{p.targetPath.split("/")[1]}</dd> + <dd>{p.fullPath.split("/")[1]}</dd> </dl> ); } - if (p.targetType === "iban") { + if (p.targetType === PaytoType.IBAN) { return ( <dl> <dt>IBAN</dt> - <dd>{p.targetPath}</dd> + <dd>{p.fullPath}</dd> </dl> ); } diff --git a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/views.tsx b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/views.tsx @@ -16,8 +16,10 @@ import { WalletBankAccountInfo, - parsePaytoUri, - stringifyPaytoUri, + Paytos, + PaytoType, + Result, + encodeCrock, assertUnreachable, } from "@gnu-taler/taler-util"; import { useTranslationContext } from "@gnu-taler/web-util/browser"; @@ -285,34 +287,34 @@ function RowExample({ } function describeAccount(paytoUri: string): string { - const p = parsePaytoUri(paytoUri); + const p = Result.orUndefined(Paytos.fromString(paytoUri)); if (!p) { return `(invalid)`; } - if (!p.isKnown) { - return stringifyPaytoUri(p); - } switch (p.targetType) { - case "iban": { + case PaytoType.IBAN: { return p.iban; } - case "taler-reserve-http": { - return `${p.reservePub}@${p.exchange}`; + case PaytoType.TalerReserveHttp: { + return `${encodeCrock(p.reservePub)}@${p.exchange}`; } - case "taler-reserve": { - return `${p.reservePub}@${p.exchange}`; + case PaytoType.TalerReserve: { + return `${encodeCrock(p.reservePub)}@${p.exchange}`; } - case "x-taler-bank": { + case PaytoType.TalerBank: { return `${p.account}@${p.host}`; } - case "cyclos": { - return `${p.account}@${p.host}`; + case PaytoType.Cyclos: { + return `${p.account}@${p.url}`; } - case "bitcoin": { + case PaytoType.Bitcoin: { return `${p.address}`; } - case "ethereum": { + case PaytoType.Ethereum: { return `${p.address}`; } + default: { + return paytoUri; + } } } diff --git a/packages/taler-wallet-webextension/src/wallet/ManageAccount/state.ts b/packages/taler-wallet-webextension/src/wallet/ManageAccount/state.ts @@ -15,9 +15,9 @@ */ import { - parsePaytoUri, + Paytos, + Result, PaytoString, - stringifyPaytoUri, WalletBankAccountInfo, WireTypeDetails, } from "@gnu-taler/taler-util"; @@ -110,14 +110,14 @@ export function useComponentState({ } }); - const uri = parsePaytoUri(payto); + const uri = Result.orUndefined(Paytos.fromString(payto)); const found = hook.response.accounts.findIndex((a) => a.paytoUri === payto) !== -1; async function addAccount(): Promise<void> { if (!uri || found) return; - const normalizedPayto = stringifyPaytoUri(uri); + const normalizedPayto = Paytos.toFullString(uri); await api.wallet.call(WalletApiOperation.AddBankAccount, { label, currencies: [scope.currency], @@ -138,8 +138,8 @@ export function useComponentState({ }; hook.response.accounts.forEach((acc) => { - const p = parsePaytoUri(acc.paytoUri)!; - accountByType[p.targetType].push(acc); + const p = Result.orUndefined(Paytos.fromString(acc.paytoUri))!; + accountByType[p.targetType!].push(acc); }); async function deleteAccount(account: WalletBankAccountInfo): Promise<void> { diff --git a/packages/taler-wallet-webextension/src/wallet/ManageAccount/views.tsx b/packages/taler-wallet-webextension/src/wallet/ManageAccount/views.tsx @@ -23,11 +23,8 @@ import { OperationOk, parseIban, ParseIbanError, - parsePaytoUri, + Result, Paytos, - PaytoUriBitcoin, - PaytoUriIBAN, - PaytoUriTalerBank, ResultError, TranslatedString, WalletBankAccountInfo, @@ -223,7 +220,7 @@ function IbanTable({ </thead> <tbody> {list.map((account) => { - const p = parsePaytoUri(account.paytoUri) as PaytoUriIBAN; + const p = Result.orUndefined(Paytos.fromString(account.paytoUri)) as Paytos.PaytoIBAN; return ( <tr key={account.label} @@ -308,7 +305,7 @@ function TalerBankTable({ </thead> <tbody> {list.map((account) => { - const p = parsePaytoUri(account.paytoUri) as PaytoUriTalerBank; + const p = Result.orUndefined(Paytos.fromString(account.paytoUri)) as Paytos.PaytoTalerBank; return ( <tr key={account.label}> <td>{account.label}</td> @@ -382,11 +379,11 @@ function BitcoinTable({ </thead> <tbody> {list.map((account) => { - const p = parsePaytoUri(account.paytoUri) as PaytoUriBitcoin; + const p = Result.orUndefined(Paytos.fromString(account.paytoUri)) as Paytos.PaytoBitcoin; return ( <tr key={account.label}> <td>{account.label}</td> - <td>{p.targetPath}</td> + <td>{p.fullPath}</td> {/* <td class="kyc"> {account.kycCompleted ? ( <SvgIcon diff --git a/packages/taler-wallet-webextension/src/wallet/SupportedBanksForAccount.tsx b/packages/taler-wallet-webextension/src/wallet/SupportedBanksForAccount.tsx @@ -13,7 +13,7 @@ You should have received a copy of the GNU General Public License along with GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { PaytoUri, stringifyPaytoUri } from "@gnu-taler/taler-util"; +import { Paytos } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { Loading, useTranslationContext } from "@gnu-taler/web-util/browser"; import { VNode, h } from "preact"; @@ -23,7 +23,7 @@ import { useBackendContext } from "../context/backend.js"; import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; interface Props { - account: PaytoUri; + account: Paytos.URI; } export function SupportedBanksForAccount({ account }: Props): VNode { @@ -31,7 +31,7 @@ export function SupportedBanksForAccount({ account }: Props): VNode { const { i18n } = useTranslationContext(); const state = useAsyncAsHook(() => { return api.wallet.call(WalletApiOperation.GetBankingChoicesForPayto, { - paytoUri: stringifyPaytoUri(account), + paytoUri: Paytos.toFullString(account), }); }); if (!state) { diff --git a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx @@ -25,11 +25,11 @@ import { MerchantInfo, NotificationType, OrderShortInfo, - parsePaytoUri, - PaytoUri, + Paytos, + PaytoType, + encodeCrock, Result, ScopeInfo, - stringifyPaytoUri, TalerErrorCode, TalerPreciseTimestamp, TalerUris, @@ -750,7 +750,7 @@ export function TransactionView({ } if (transaction.type === TransactionType.Deposit) { - const payto = parsePaytoUri(transaction.targetPaytoUri); + const payto = Result.orUndefined(Paytos.fromString(transaction.targetPaytoUri)); // const blockedByKycOrAml = // transaction.txState.minor === TransactionMinorState.KycAuthRequired; @@ -1991,33 +1991,31 @@ function Header({ ); } -function NicePayto({ payto }: { payto: PaytoUri }): VNode { - if (payto.isKnown) { - switch (payto.targetType) { - case "bitcoin": { - return <div>{payto.targetPath.substring(0, 20)}...</div>; - } - case "x-taler-bank": { - return <div>{payto.account}</div>; - } - case "iban": { - return <div>{payto.iban}</div>; - } - case "taler-reserve": { - return <div>{payto.reservePub}</div>; - } - case "taler-reserve-http": { - return <div>{payto.reservePub}</div>; - } - case "cyclos": { - return <div>{payto.account}</div>; - } - case "ethereum": { - return <div>{payto.address.substring(0, 20)}...</div>; - } +function NicePayto({ payto }: { payto: Paytos.URI }): VNode { + switch (payto.targetType) { + case PaytoType.Bitcoin: { + return <div>{payto.fullPath.substring(0, 20)}...</div>; } - } else { - return <div>{stringifyPaytoUri(payto).substring(0, 20)}...</div>; + case PaytoType.TalerBank: { + return <div>{payto.account}</div>; + } + case PaytoType.IBAN: { + return <div>{payto.iban}</div>; + } + case PaytoType.TalerReserve: { + return <div>{encodeCrock(payto.reservePub)}</div>; + } + case PaytoType.TalerReserveHttp: { + return <div>{encodeCrock(payto.reservePub)}</div>; + } + case PaytoType.Cyclos: { + return <div>{payto.account}</div>; + } + case PaytoType.Ethereum: { + return <div>{payto.address.substring(0, 20)}...</div>; + } + default: + return <div>{payto.fullPath.substring(0, 20)}...</div>; } }