diff --git a/packages/taler-harness/src/harness/harness.ts b/packages/taler-harness/src/harness/harness.ts index 940e4258a..c9202c60e 100644 --- a/packages/taler-harness/src/harness/harness.ts +++ b/packages/taler-harness/src/harness/harness.ts @@ -51,8 +51,8 @@ import { stringToBytes, TalerError, TalerProtocolDuration, - TipCreateConfirmation, - TipCreateRequest, + RewardCreateConfirmation, + RewardCreateRequest, TippingReserveStatus, WalletNotification, } from "@gnu-taler/taler-util"; @@ -1751,8 +1751,8 @@ export namespace MerchantPrivateApi { export async function giveTip( merchantService: MerchantServiceInterface, instance: string, - req: TipCreateRequest, - ): Promise { + req: RewardCreateRequest, + ): Promise { const reqUrl = new URL( `private/tips`, merchantService.makeInstanceBaseUrl(instance), diff --git a/packages/taler-harness/src/integrationtests/test-age-restrictions-merchant.ts b/packages/taler-harness/src/integrationtests/test-age-restrictions-merchant.ts index c4db7022d..919097deb 100644 --- a/packages/taler-harness/src/integrationtests/test-age-restrictions-merchant.ts +++ b/packages/taler-harness/src/integrationtests/test-age-restrictions-merchant.ts @@ -191,12 +191,12 @@ export async function runAgeRestrictionsMerchantTest(t: GlobalTestState) { const walletTipping = new WalletCli(t, "age-tipping"); - const ptr = await walletTipping.client.call(WalletApiOperation.PrepareTip, { - talerTipUri: tip.taler_tip_uri, + const ptr = await walletTipping.client.call(WalletApiOperation.PrepareReward, { + talerRewardUri: tip.taler_reward_uri, }); - await walletTipping.client.call(WalletApiOperation.AcceptTip, { - walletTipId: ptr.walletTipId, + await walletTipping.client.call(WalletApiOperation.AcceptReward, { + walletRewardId: ptr.walletRewardId, }); await walletTipping.runUntilDone(); diff --git a/packages/taler-harness/src/integrationtests/test-tipping.ts b/packages/taler-harness/src/integrationtests/test-tipping.ts index ff6fc9ceb..332f702d7 100644 --- a/packages/taler-harness/src/integrationtests/test-tipping.ts +++ b/packages/taler-harness/src/integrationtests/test-tipping.ts @@ -99,17 +99,17 @@ export async function runTippingTest(t: GlobalTestState) { console.log("created tip", tip); const doTip = async (): Promise => { - const ptr = await wallet.client.call(WalletApiOperation.PrepareTip, { - talerTipUri: tip.taler_tip_uri, + const ptr = await wallet.client.call(WalletApiOperation.PrepareReward, { + talerRewardUri: tip.taler_reward_uri, }); console.log(ptr); - t.assertAmountEquals(ptr.tipAmountRaw, "TESTKUDOS:5"); - t.assertAmountEquals(ptr.tipAmountEffective, "TESTKUDOS:4.85"); + t.assertAmountEquals(ptr.rewardAmountRaw, "TESTKUDOS:5"); + t.assertAmountEquals(ptr.rewardAmountEffective, "TESTKUDOS:4.85"); - await wallet.client.call(WalletApiOperation.AcceptTip, { - walletTipId: ptr.walletTipId, + await wallet.client.call(WalletApiOperation.AcceptReward, { + walletRewardId: ptr.walletRewardId, }); await wallet.runUntilDone(); @@ -127,7 +127,7 @@ export async function runTippingTest(t: GlobalTestState) { console.log("Transactions:", JSON.stringify(txns, undefined, 2)); - t.assertDeepEqual(txns.transactions[0].type, "tip"); + t.assertDeepEqual(txns.transactions[0].type, "reward"); t.assertDeepEqual(txns.transactions[0].txState.major, TransactionMajorState.Done); t.assertAmountEquals( txns.transactions[0].amountEffective, diff --git a/packages/taler-util/src/backup-types.ts b/packages/taler-util/src/backup-types.ts index 2920838dd..0211ff740 100644 --- a/packages/taler-util/src/backup-types.ts +++ b/packages/taler-util/src/backup-types.ts @@ -499,7 +499,7 @@ export interface BackupRecoupGroup { export enum BackupCoinSourceType { Withdraw = "withdraw", Refresh = "refresh", - Tip = "tip", + Reward = "reward", } /** @@ -546,7 +546,7 @@ export interface BackupRefreshCoinSource { * Metadata about a coin obtained from a tip. */ export interface BackupTipCoinSource { - type: BackupCoinSourceType.Tip; + type: BackupCoinSourceType.Reward; /** * Wallet's identifier for the tip that this coin diff --git a/packages/taler-util/src/http-impl.node.ts b/packages/taler-util/src/http-impl.node.ts index 639043201..07648a28d 100644 --- a/packages/taler-util/src/http-impl.node.ts +++ b/packages/taler-util/src/http-impl.node.ts @@ -183,7 +183,16 @@ export class HttpLibImpl implements HttpRequestLibrary { resolve(resp); }); res.on("error", (e) => { - reject(e); + const err = TalerError.fromDetail( + TalerErrorCode.WALLET_UNEXPECTED_REQUEST_ERROR, + { + requestUrl: url, + requestMethod: method, + httpStatusCode: 0, + }, + `Error in HTTP response handler: ${e.message}`, + ); + reject(err); }); }; @@ -197,7 +206,16 @@ export class HttpLibImpl implements HttpRequestLibrary { } req.on("error", (e: Error) => { - reject(e); + const err = TalerError.fromDetail( + TalerErrorCode.WALLET_UNEXPECTED_REQUEST_ERROR, + { + requestUrl: url, + requestMethod: method, + httpStatusCode: 0, + }, + `Error in HTTP request: ${e.message}`, + ); + reject(err); }); if (reqBody) { diff --git a/packages/taler-util/src/merchant-api-types.ts b/packages/taler-util/src/merchant-api-types.ts index d7a5cf576..9f00173f2 100644 --- a/packages/taler-util/src/merchant-api-types.ts +++ b/packages/taler-util/src/merchant-api-types.ts @@ -290,22 +290,22 @@ export interface ReserveStatusEntry { active: boolean; } -export interface TipCreateConfirmation { +export interface RewardCreateConfirmation { // Unique tip identifier for the tip that was created. - tip_id: string; + reward_id: string; // taler://tip URI for the tip - taler_tip_uri: string; + taler_reward_uri: string; // URL that will directly trigger processing // the tip when the browser is redirected to it - tip_status_url: string; + reward_status_url: string; - // when does the tip expire - tip_expiration: AbsoluteTime; + // when does the reward expire + reward_expiration: AbsoluteTime; } -export interface TipCreateRequest { +export interface RewardCreateRequest { // Amount that the customer should be tipped amount: AmountString; diff --git a/packages/taler-util/src/transactions-types.ts b/packages/taler-util/src/transactions-types.ts index a498d3471..2d278e3e8 100644 --- a/packages/taler-util/src/transactions-types.ts +++ b/packages/taler-util/src/transactions-types.ts @@ -186,7 +186,7 @@ export type Transaction = | TransactionWithdrawal | TransactionPayment | TransactionRefund - | TransactionTip + | TransactionReward | TransactionRefresh | TransactionDeposit | TransactionPeerPullCredit @@ -201,7 +201,7 @@ export enum TransactionType { Payment = "payment", Refund = "refund", Refresh = "refresh", - Tip = "tip", + Reward = "reward", Deposit = "deposit", PeerPushDebit = "peer-push-debit", PeerPushCredit = "peer-push-credit", @@ -591,8 +591,8 @@ export interface TransactionRefund extends TransactionCommon { paymentInfo: RefundPaymentInfo | undefined; } -export interface TransactionTip extends TransactionCommon { - type: TransactionType.Tip; +export interface TransactionReward extends TransactionCommon { + type: TransactionType.Reward; // Raw amount of the tip, without extra fees that apply amountRaw: AmountString; diff --git a/packages/taler-util/src/wallet-types.ts b/packages/taler-util/src/wallet-types.ts index 5151b8aae..38e5787ba 100644 --- a/packages/taler-util/src/wallet-types.ts +++ b/packages/taler-util/src/wallet-types.ts @@ -605,7 +605,7 @@ export interface PrepareTipResult { * * @deprecated use transactionId instead */ - walletTipId: string; + walletRewardId: string; /** * Tip transaction ID. @@ -620,13 +620,13 @@ export interface PrepareTipResult { /** * Amount that the merchant gave. */ - tipAmountRaw: AmountString; + rewardAmountRaw: AmountString; /** * Amount that arrived at the wallet. * Might be lower than the raw amount due to fees. */ - tipAmountEffective: AmountString; + rewardAmountEffective: AmountString; /** * Base URL of the merchant backend giving then tip. @@ -654,14 +654,14 @@ export interface AcceptTipResponse { export const codecForPrepareTipResult = (): Codec => buildCodecForObject() .property("accepted", codecForBoolean()) - .property("tipAmountRaw", codecForAmountString()) - .property("tipAmountEffective", codecForAmountString()) + .property("rewardAmountRaw", codecForAmountString()) + .property("rewardAmountEffective", codecForAmountString()) .property("exchangeBaseUrl", codecForString()) .property("merchantBaseUrl", codecForString()) .property("expirationTimestamp", codecForTimestamp) - .property("walletTipId", codecForString()) + .property("walletRewardId", codecForString()) .property("transactionId", codecForString()) - .build("PrepareTipResult"); + .build("PrepareRewardResult"); export interface BenchmarkResult { time: { [s: string]: number }; @@ -1933,23 +1933,23 @@ export const codecForStartRefundQueryRequest = .property("transactionId", codecForTransactionIdStr()) .build("StartRefundQueryRequest"); -export interface PrepareTipRequest { - talerTipUri: string; +export interface PrepareRewardRequest { + talerRewardUri: string; } -export const codecForPrepareTipRequest = (): Codec => - buildCodecForObject() - .property("talerTipUri", codecForString()) - .build("PrepareTipRequest"); +export const codecForPrepareRewardRequest = (): Codec => + buildCodecForObject() + .property("talerRewardUri", codecForString()) + .build("PrepareRewardRequest"); -export interface AcceptTipRequest { - walletTipId: string; +export interface AcceptRewardRequest { + walletRewardId: string; } -export const codecForAcceptTipRequest = (): Codec => - buildCodecForObject() - .property("walletTipId", codecForString()) - .build("AcceptTipRequest"); +export const codecForAcceptTipRequest = (): Codec => + buildCodecForObject() + .property("walletRewardId", codecForString()) + .build("AcceptRewardRequest"); export interface FailTransactionRequest { transactionId: TransactionIdStr; diff --git a/packages/taler-wallet-cli/src/index.ts b/packages/taler-wallet-cli/src/index.ts index 4e56a40f4..a34f6be03 100644 --- a/packages/taler-wallet-cli/src/index.ts +++ b/packages/taler-wallet-cli/src/index.ts @@ -652,12 +652,12 @@ walletCli }); break; case TalerUriAction.Tip: { - const res = await wallet.client.call(WalletApiOperation.PrepareTip, { - talerTipUri: uri, + const res = await wallet.client.call(WalletApiOperation.PrepareReward, { + talerRewardUri: uri, }); console.log("tip status", res); - await wallet.client.call(WalletApiOperation.AcceptTip, { - walletTipId: res.walletTipId, + await wallet.client.call(WalletApiOperation.AcceptReward, { + walletRewardId: res.walletRewardId, }); break; } diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts index 6a7a26f2f..3d2878d93 100644 --- a/packages/taler-wallet-core/src/db.ts +++ b/packages/taler-wallet-core/src/db.ts @@ -677,7 +677,7 @@ export interface PlanchetRecord { export enum CoinSourceType { Withdraw = "withdraw", Refresh = "refresh", - Tip = "tip", + Reward = "reward", } export interface WithdrawCoinSource { @@ -705,13 +705,13 @@ export interface RefreshCoinSource { oldCoinPub: string; } -export interface TipCoinSource { - type: CoinSourceType.Tip; - walletTipId: string; +export interface RewardCoinSource { + type: CoinSourceType.Reward; + walletRewardId: string; coinIndex: number; } -export type CoinSource = WithdrawCoinSource | RefreshCoinSource | TipCoinSource; +export type CoinSource = WithdrawCoinSource | RefreshCoinSource | RewardCoinSource; /** * CoinRecord as stored in the "coins" data store @@ -815,9 +815,9 @@ export interface CoinAllocation { } /** - * Status of a tip we got from a merchant. + * Status of a reward we got from a merchant. */ -export interface TipRecord { +export interface RewardRecord { /** * Has the user accepted the tip? Only after the tip has been accepted coins * withdrawn from the tip may be used. @@ -827,17 +827,17 @@ export interface TipRecord { /** * The tipped amount. */ - tipAmountRaw: AmountString; + rewardAmountRaw: AmountString; /** * Effect on the balance (including fees etc). */ - tipAmountEffective: AmountString; + rewardAmountEffective: AmountString; /** * Timestamp, the tip can't be picked up anymore after this deadline. */ - tipExpiration: TalerProtocolTimestamp; + rewardExpiration: TalerProtocolTimestamp; /** * The exchange that will sign our coins, chosen by the merchant. @@ -863,7 +863,7 @@ export interface TipRecord { /** * Tip ID chosen by the wallet. */ - walletTipId: string; + walletRewardId: string; /** * Secret seed used to derive planchets for this tip. @@ -871,9 +871,9 @@ export interface TipRecord { secretSeed: string; /** - * The merchant's identifier for this tip. + * The merchant's identifier for this reward. */ - merchantTipId: string; + merchantRewardId: string; createdTimestamp: TalerPreciseTimestamp; @@ -888,10 +888,10 @@ export interface TipRecord { */ pickedUpTimestamp: TalerPreciseTimestamp | undefined; - status: TipRecordStatus; + status: RewardRecordStatus; } -export enum TipRecordStatus { +export enum RewardRecordStatus { PendingPickup = 10, SuspendidPickup = 20, @@ -1420,7 +1420,7 @@ export interface KycPendingInfo { } /** * Group of withdrawal operations that need to be executed. - * (Either for a normal withdrawal or from a tip.) + * (Either for a normal withdrawal or from a reward.) * * The withdrawal group record is only created after we know * the coin selection we want to withdraw. @@ -2480,12 +2480,12 @@ export const WalletStoresV1 = { ]), }, ), - tips: describeStore( - "tips", - describeContents({ keyPath: "walletTipId" }), + rewards: describeStore( + "rewards", + describeContents({ keyPath: "walletRewardId" }), { - byMerchantTipIdAndBaseUrl: describeIndex("byMerchantTipIdAndBaseUrl", [ - "merchantTipId", + byMerchantTipIdAndBaseUrl: describeIndex("byMerchantRewardIdAndBaseUrl", [ + "merchantRewardId", "merchantBaseUrl", ]), byStatus: describeIndex("byStatus", "status", { @@ -2935,22 +2935,6 @@ export const walletDbFixups: FixupDescription[] = [ }); }, }, - { - name: "TipRecordRecord_status_add", - async fn(tx): Promise { - await tx.tips.iter().forEachAsync(async (r) => { - // Remove legacy transactions that don't have the totalCost field yet. - if (r.status == null) { - if (r.pickedUpTimestamp) { - r.status = TipRecordStatus.Done; - } else { - r.status = TipRecordStatus.PendingPickup; - } - await tx.tips.put(r); - } - }); - }, - }, { name: "CoinAvailabilityRecord_visibleCoinCount_add", async fn(tx): Promise { diff --git a/packages/taler-wallet-core/src/operations/backup/export.ts b/packages/taler-wallet-core/src/operations/backup/export.ts index 21ba5dc37..c9446a05f 100644 --- a/packages/taler-wallet-core/src/operations/backup/export.ts +++ b/packages/taler-wallet-core/src/operations/backup/export.ts @@ -96,7 +96,7 @@ export async function exportBackup( x.purchases, x.refreshGroups, x.backupProviders, - x.tips, + x.rewards, x.recoupGroups, x.withdrawalGroups, ]) @@ -184,12 +184,12 @@ export async function exportBackup( }); }); - await tx.tips.iter().forEach((tip) => { + await tx.rewards.iter().forEach((tip) => { backupTips.push({ exchange_base_url: tip.exchangeBaseUrl, merchant_base_url: tip.merchantBaseUrl, - merchant_tip_id: tip.merchantTipId, - wallet_tip_id: tip.walletTipId, + merchant_tip_id: tip.merchantRewardId, + wallet_tip_id: tip.walletRewardId, next_url: tip.next_url, secret_seed: tip.secretSeed, selected_denoms: tip.denomsSel.selectedDenoms.map((x) => ({ @@ -199,8 +199,8 @@ export async function exportBackup( timestamp_finished: tip.pickedUpTimestamp, timestamp_accepted: tip.acceptedTimestamp, timestamp_created: tip.createdTimestamp, - timestamp_expiration: tip.tipExpiration, - tip_amount_raw: Amounts.stringify(tip.tipAmountRaw), + timestamp_expiration: tip.rewardExpiration, + tip_amount_raw: Amounts.stringify(tip.rewardAmountRaw), selected_denoms_uid: tip.denomSelUid, }); }); @@ -244,11 +244,11 @@ export async function exportBackup( refresh_group_id: coin.coinSource.refreshGroupId, }; break; - case CoinSourceType.Tip: + case CoinSourceType.Reward: bcs = { - type: BackupCoinSourceType.Tip, + type: BackupCoinSourceType.Reward, coin_index: coin.coinSource.coinIndex, - wallet_tip_id: coin.coinSource.walletTipId, + wallet_tip_id: coin.coinSource.walletRewardId, }; break; case CoinSourceType.Withdraw: diff --git a/packages/taler-wallet-core/src/operations/backup/import.ts b/packages/taler-wallet-core/src/operations/backup/import.ts index b161aa8f2..a53b624e8 100644 --- a/packages/taler-wallet-core/src/operations/backup/import.ts +++ b/packages/taler-wallet-core/src/operations/backup/import.ts @@ -56,7 +56,7 @@ import { WithdrawalGroupStatus, WithdrawalRecordType, RefreshOperationStatus, - TipRecordStatus, + RewardRecordStatus, } from "../../db.js"; import { InternalWalletState } from "../../internal-wallet-state.js"; import { assertUnreachable } from "../../util/assertUnreachable.js"; @@ -250,11 +250,11 @@ export async function importCoin( refreshGroupId: backupCoin.coin_source.refresh_group_id, }; break; - case BackupCoinSourceType.Tip: + case BackupCoinSourceType.Reward: coinSource = { - type: CoinSourceType.Tip, + type: CoinSourceType.Reward, coinIndex: backupCoin.coin_source.coin_index, - walletTipId: backupCoin.coin_source.wallet_tip_id, + walletRewardId: backupCoin.coin_source.wallet_tip_id, }; break; case BackupCoinSourceType.Withdraw: @@ -311,7 +311,7 @@ export async function importBackup( x.purchases, x.refreshGroups, x.backupProviders, - x.tips, + x.rewards, x.recoupGroups, x.withdrawalGroups, x.tombstones, @@ -812,13 +812,13 @@ export async function importBackup( for (const backupTip of backupBlob.tips) { const ts = constructTombstone({ - tag: TombstoneTag.DeleteTip, + tag: TombstoneTag.DeleteReward, walletTipId: backupTip.wallet_tip_id, }); if (tombstoneSet.has(ts)) { continue; } - const existingTip = await tx.tips.get(backupTip.wallet_tip_id); + const existingTip = await tx.rewards.get(backupTip.wallet_tip_id); if (!existingTip) { const tipAmountRaw = Amounts.parseOrThrow(backupTip.tip_amount_raw); const denomsSel = await getDenomSelStateFromBackup( @@ -827,22 +827,22 @@ export async function importBackup( backupTip.exchange_base_url, backupTip.selected_denoms, ); - await tx.tips.put({ + await tx.rewards.put({ acceptedTimestamp: backupTip.timestamp_accepted, createdTimestamp: backupTip.timestamp_created, denomsSel, next_url: backupTip.next_url, exchangeBaseUrl: backupTip.exchange_base_url, merchantBaseUrl: backupTip.exchange_base_url, - merchantTipId: backupTip.merchant_tip_id, + merchantRewardId: backupTip.merchant_tip_id, pickedUpTimestamp: backupTip.timestamp_finished, secretSeed: backupTip.secret_seed, - tipAmountEffective: Amounts.stringify(denomsSel.totalCoinValue), - tipAmountRaw: Amounts.stringify(tipAmountRaw), - tipExpiration: backupTip.timestamp_expiration, - walletTipId: backupTip.wallet_tip_id, + rewardAmountEffective: Amounts.stringify(denomsSel.totalCoinValue), + rewardAmountRaw: Amounts.stringify(tipAmountRaw), + rewardExpiration: backupTip.timestamp_expiration, + walletRewardId: backupTip.wallet_tip_id, denomSelUid: backupTip.selected_denoms_uid, - status: TipRecordStatus.Done, // FIXME! + status: RewardRecordStatus.Done, // FIXME! }); } } @@ -863,8 +863,8 @@ export async function importBackup( } else if (type === TombstoneTag.DeleteRefund) { // Nothing required, will just prevent display // in the transactions list - } else if (type === TombstoneTag.DeleteTip) { - await tx.tips.delete(rest[0]); + } else if (type === TombstoneTag.DeleteReward) { + await tx.rewards.delete(rest[0]); } else if (type === TombstoneTag.DeleteWithdrawalGroup) { await tx.withdrawalGroups.delete(rest[0]); } else { diff --git a/packages/taler-wallet-core/src/operations/common.ts b/packages/taler-wallet-core/src/operations/common.ts index cc16a4704..7a8b78b53 100644 --- a/packages/taler-wallet-core/src/operations/common.ts +++ b/packages/taler-wallet-core/src/operations/common.ts @@ -57,7 +57,7 @@ import { PurchaseRecord, RecoupGroupRecord, RefreshGroupRecord, - TipRecord, + RewardRecord, WithdrawalGroupRecord, } from "../db.js"; import { makeErrorDetail, TalerError } from "@gnu-taler/taler-util"; @@ -293,10 +293,10 @@ function convertTaskToTransactionId( tag: TransactionType.Refresh, refreshGroupId: parsedTaskId.refreshGroupId, }); - case PendingTaskType.TipPickup: + case PendingTaskType.RewardPickup: return constructTransactionIdentifier({ - tag: TransactionType.Tip, - walletTipId: parsedTaskId.walletTipId, + tag: TransactionType.Reward, + walletRewardId: parsedTaskId.walletRewardId, }); case PendingTaskType.PeerPushDebit: return constructTransactionIdentifier({ @@ -515,7 +515,7 @@ export enum TombstoneTag { DeleteWithdrawalGroup = "delete-withdrawal-group", DeleteReserve = "delete-reserve", DeletePayment = "delete-payment", - DeleteTip = "delete-tip", + DeleteReward = "delete-reward", DeleteRefreshGroup = "delete-refresh-group", DeleteDepositGroup = "delete-deposit-group", DeleteRefund = "delete-refund", @@ -601,7 +601,9 @@ export function runLongpollAsync( }; res = await reqFn(cts.token); } catch (e) { - await storePendingTaskError(ws, retryTag, getErrorDetailFromException(e)); + const errDetail = getErrorDetailFromException(e); + logger.warn(`got error during long-polling: ${j2s(errDetail)}`); + await storePendingTaskError(ws, retryTag, errDetail); return; } finally { delete ws.activeLongpoll[retryTag]; @@ -622,7 +624,7 @@ export type ParsedTombstone = | { tag: TombstoneTag.DeleteRefund; refundGroupId: string } | { tag: TombstoneTag.DeleteReserve; reservePub: string } | { tag: TombstoneTag.DeleteRefreshGroup; refreshGroupId: string } - | { tag: TombstoneTag.DeleteTip; walletTipId: string } + | { tag: TombstoneTag.DeleteReward; walletTipId: string } | { tag: TombstoneTag.DeletePayment; proposalId: string }; export function constructTombstone(p: ParsedTombstone): TombstoneIdStr { @@ -637,7 +639,7 @@ export function constructTombstone(p: ParsedTombstone): TombstoneIdStr { return `tmb:${p.tag}:${p.proposalId}` as TombstoneIdStr; case TombstoneTag.DeleteRefreshGroup: return `tmb:${p.tag}:${p.refreshGroupId}` as TombstoneIdStr; - case TombstoneTag.DeleteTip: + case TombstoneTag.DeleteReward: return `tmb:${p.tag}:${p.walletTipId}` as TombstoneIdStr; default: assertUnreachable(p); @@ -810,7 +812,7 @@ export type ParsedTaskIdentifier = | { tag: PendingTaskType.PeerPushDebit; pursePub: string } | { tag: PendingTaskType.Purchase; proposalId: string } | { tag: PendingTaskType.Recoup; recoupGroupId: string } - | { tag: PendingTaskType.TipPickup; walletTipId: string } + | { tag: PendingTaskType.RewardPickup; walletRewardId: string } | { tag: PendingTaskType.Refresh; refreshGroupId: string }; export function parseTaskIdentifier(x: string): ParsedTaskIdentifier { @@ -844,8 +846,8 @@ export function parseTaskIdentifier(x: string): ParsedTaskIdentifier { return { tag: type, recoupGroupId: rest[0] }; case PendingTaskType.Refresh: return { tag: type, refreshGroupId: rest[0] }; - case PendingTaskType.TipPickup: - return { tag: type, walletTipId: rest[0] }; + case PendingTaskType.RewardPickup: + return { tag: type, walletRewardId: rest[0] }; case PendingTaskType.Withdraw: return { tag: type, withdrawalGroupId: rest[0] }; default: @@ -877,8 +879,8 @@ export function constructTaskIdentifier(p: ParsedTaskIdentifier): TaskId { return `${p.tag}:${p.recoupGroupId}` as TaskId; case PendingTaskType.Refresh: return `${p.tag}:${p.refreshGroupId}` as TaskId; - case PendingTaskType.TipPickup: - return `${p.tag}:${p.walletTipId}` as TaskId; + case PendingTaskType.RewardPickup: + return `${p.tag}:${p.walletRewardId}` as TaskId; case PendingTaskType.Withdraw: return `${p.tag}:${p.withdrawalGroupId}` as TaskId; default: @@ -899,8 +901,8 @@ export namespace TaskIdentifiers { export function forExchangeCheckRefresh(exch: ExchangeRecord): TaskId { return `${PendingTaskType.ExchangeCheckRefresh}:${exch.baseUrl}` as TaskId; } - export function forTipPickup(tipRecord: TipRecord): TaskId { - return `${PendingTaskType.TipPickup}:${tipRecord.walletTipId}` as TaskId; + export function forTipPickup(tipRecord: RewardRecord): TaskId { + return `${PendingTaskType.RewardPickup}:${tipRecord.walletRewardId}` as TaskId; } export function forRefresh(refreshGroupRecord: RefreshGroupRecord): TaskId { return `${PendingTaskType.Refresh}:${refreshGroupRecord.refreshGroupId}` as TaskId; diff --git a/packages/taler-wallet-core/src/operations/pending.ts b/packages/taler-wallet-core/src/operations/pending.ts index 870437e2e..cc9217d67 100644 --- a/packages/taler-wallet-core/src/operations/pending.ts +++ b/packages/taler-wallet-core/src/operations/pending.ts @@ -32,7 +32,7 @@ import { PeerPushPaymentIncomingStatus, PeerPullPaymentInitiationStatus, WithdrawalGroupStatus, - TipRecordStatus, + RewardRecordStatus, DepositOperationStatus, } from "../db.js"; import { @@ -232,17 +232,17 @@ async function gatherDepositPending( async function gatherTipPending( ws: InternalWalletState, tx: GetReadOnlyAccess<{ - tips: typeof WalletStoresV1.tips; + rewards: typeof WalletStoresV1.rewards; operationRetries: typeof WalletStoresV1.operationRetries; }>, now: AbsoluteTime, resp: PendingOperationsResponse, ): Promise { const range = GlobalIDB.KeyRange.bound( - TipRecordStatus.PendingPickup, - TipRecordStatus.PendingPickup, + RewardRecordStatus.PendingPickup, + RewardRecordStatus.PendingPickup, ); - await tx.tips.indexes.byStatus.iter(range).forEachAsync(async (tip) => { + await tx.rewards.indexes.byStatus.iter(range).forEachAsync(async (tip) => { // FIXME: The tip record needs a proper status field! if (tip.pickedUpTimestamp) { return; @@ -252,13 +252,13 @@ async function gatherTipPending( const timestampDue = retryRecord?.retryInfo.nextRetry ?? AbsoluteTime.now(); if (tip.acceptedTimestamp) { resp.pendingOperations.push({ - type: PendingTaskType.TipPickup, + type: PendingTaskType.RewardPickup, ...getPendingCommon(ws, opId, timestampDue), givesLifeness: true, timestampDue: retryRecord?.retryInfo.nextRetry ?? AbsoluteTime.now(), merchantBaseUrl: tip.merchantBaseUrl, - tipId: tip.walletTipId, - merchantTipId: tip.merchantTipId, + tipId: tip.walletRewardId, + merchantTipId: tip.merchantRewardId, }); } }); @@ -494,7 +494,7 @@ export async function getPendingOperations( x.refreshGroups, x.coins, x.withdrawalGroups, - x.tips, + x.rewards, x.purchases, x.planchets, x.depositGroups, diff --git a/packages/taler-wallet-core/src/operations/recoup.ts b/packages/taler-wallet-core/src/operations/recoup.ts index dea2d4b16..abeca1119 100644 --- a/packages/taler-wallet-core/src/operations/recoup.ts +++ b/packages/taler-wallet-core/src/operations/recoup.ts @@ -82,7 +82,7 @@ async function putGroupAsFinished( await tx.recoupGroups.put(recoupGroup); } -async function recoupTipCoin( +async function recoupRewardCoin( ws: InternalWalletState, recoupGroupId: string, coinIdx: number, @@ -482,8 +482,8 @@ async function processRecoup( const cs = coin.coinSource; switch (cs.type) { - case CoinSourceType.Tip: - return recoupTipCoin(ws, recoupGroupId, coinIdx, coin); + case CoinSourceType.Reward: + return recoupRewardCoin(ws, recoupGroupId, coinIdx, coin); case CoinSourceType.Refresh: return recoupRefreshCoin(ws, recoupGroupId, coinIdx, coin, cs); case CoinSourceType.Withdraw: diff --git a/packages/taler-wallet-core/src/operations/tip.ts b/packages/taler-wallet-core/src/operations/reward.ts similarity index 72% rename from packages/taler-wallet-core/src/operations/tip.ts rename to packages/taler-wallet-core/src/operations/reward.ts index e56fb1e8d..58c745780 100644 --- a/packages/taler-wallet-core/src/operations/tip.ts +++ b/packages/taler-wallet-core/src/operations/reward.ts @@ -48,8 +48,8 @@ import { CoinRecord, CoinSourceType, DenominationRecord, - TipRecord, - TipRecordStatus, + RewardRecord, + RewardRecordStatus, } from "../db.js"; import { makeErrorDetail } from "@gnu-taler/taler-util"; import { InternalWalletState } from "../internal-wallet-state.js"; @@ -84,31 +84,31 @@ const logger = new Logger("operations/tip.ts"); /** * Get the (DD37-style) transaction status based on the - * database record of a tip. + * database record of a reward. */ -export function computeTipTransactionStatus( - tipRecord: TipRecord, +export function computeRewardTransactionStatus( + tipRecord: RewardRecord, ): TransactionState { switch (tipRecord.status) { - case TipRecordStatus.Done: + case RewardRecordStatus.Done: return { major: TransactionMajorState.Done, }; - case TipRecordStatus.Aborted: + case RewardRecordStatus.Aborted: return { major: TransactionMajorState.Aborted, }; - case TipRecordStatus.PendingPickup: + case RewardRecordStatus.PendingPickup: return { major: TransactionMajorState.Pending, minor: TransactionMinorState.Pickup, }; - case TipRecordStatus.DialogAccept: + case RewardRecordStatus.DialogAccept: return { major: TransactionMajorState.Dialog, minor: TransactionMinorState.Proposed, }; - case TipRecordStatus.SuspendidPickup: + case RewardRecordStatus.SuspendidPickup: return { major: TransactionMajorState.Pending, minor: TransactionMinorState.Pickup, @@ -119,18 +119,18 @@ export function computeTipTransactionStatus( } export function computeTipTransactionActions( - tipRecord: TipRecord, + tipRecord: RewardRecord, ): TransactionAction[] { switch (tipRecord.status) { - case TipRecordStatus.Done: + case RewardRecordStatus.Done: return [TransactionAction.Delete]; - case TipRecordStatus.Aborted: + case RewardRecordStatus.Aborted: return [TransactionAction.Delete]; - case TipRecordStatus.PendingPickup: + case RewardRecordStatus.PendingPickup: return [TransactionAction.Suspend, TransactionAction.Fail]; - case TipRecordStatus.SuspendidPickup: + case RewardRecordStatus.SuspendidPickup: return [TransactionAction.Resume, TransactionAction.Fail]; - case TipRecordStatus.DialogAccept: + case RewardRecordStatus.DialogAccept: return [TransactionAction.Abort]; default: assertUnreachable(tipRecord.status); @@ -147,9 +147,9 @@ export async function prepareTip( } let tipRecord = await ws.db - .mktx((x) => [x.tips]) + .mktx((x) => [x.rewards]) .runReadOnly(async (tx) => { - return tx.tips.indexes.byMerchantTipIdAndBaseUrl.get([ + return tx.rewards.indexes.byMerchantTipIdAndBaseUrl.get([ res.merchantTipId, res.merchantBaseUrl, ]); @@ -194,44 +194,44 @@ export async function prepareTip( const secretSeed = encodeCrock(getRandomBytes(64)); const denomSelUid = encodeCrock(getRandomBytes(32)); - const newTipRecord: TipRecord = { - walletTipId: walletTipId, + const newTipRecord: RewardRecord = { + walletRewardId: walletTipId, acceptedTimestamp: undefined, - status: TipRecordStatus.DialogAccept, - tipAmountRaw: Amounts.stringify(amount), - tipExpiration: tipPickupStatus.expiration, + status: RewardRecordStatus.DialogAccept, + rewardAmountRaw: Amounts.stringify(amount), + rewardExpiration: tipPickupStatus.expiration, exchangeBaseUrl: tipPickupStatus.exchange_url, next_url: tipPickupStatus.next_url, merchantBaseUrl: res.merchantBaseUrl, createdTimestamp: TalerPreciseTimestamp.now(), - merchantTipId: res.merchantTipId, - tipAmountEffective: Amounts.stringify(selectedDenoms.totalCoinValue), + merchantRewardId: res.merchantTipId, + rewardAmountEffective: Amounts.stringify(selectedDenoms.totalCoinValue), denomsSel: selectedDenoms, pickedUpTimestamp: undefined, secretSeed, denomSelUid, }; await ws.db - .mktx((x) => [x.tips]) + .mktx((x) => [x.rewards]) .runReadWrite(async (tx) => { - await tx.tips.put(newTipRecord); + await tx.rewards.put(newTipRecord); }); tipRecord = newTipRecord; } const transactionId = constructTransactionIdentifier({ - tag: TransactionType.Tip, - walletTipId: tipRecord.walletTipId, + tag: TransactionType.Reward, + walletRewardId: tipRecord.walletRewardId, }); const tipStatus: PrepareTipResult = { accepted: !!tipRecord && !!tipRecord.acceptedTimestamp, - tipAmountRaw: Amounts.stringify(tipRecord.tipAmountRaw), + rewardAmountRaw: Amounts.stringify(tipRecord.rewardAmountRaw), exchangeBaseUrl: tipRecord.exchangeBaseUrl, merchantBaseUrl: tipRecord.merchantBaseUrl, - expirationTimestamp: tipRecord.tipExpiration, - tipAmountEffective: Amounts.stringify(tipRecord.tipAmountEffective), - walletTipId: tipRecord.walletTipId, + expirationTimestamp: tipRecord.rewardExpiration, + rewardAmountEffective: Amounts.stringify(tipRecord.rewardAmountEffective), + walletRewardId: tipRecord.walletRewardId, transactionId, }; @@ -243,25 +243,25 @@ export async function processTip( walletTipId: string, ): Promise { const tipRecord = await ws.db - .mktx((x) => [x.tips]) + .mktx((x) => [x.rewards]) .runReadOnly(async (tx) => { - return tx.tips.get(walletTipId); + return tx.rewards.get(walletTipId); }); if (!tipRecord) { return TaskRunResult.finished(); } switch (tipRecord.status) { - case TipRecordStatus.Aborted: - case TipRecordStatus.DialogAccept: - case TipRecordStatus.Done: - case TipRecordStatus.SuspendidPickup: + case RewardRecordStatus.Aborted: + case RewardRecordStatus.DialogAccept: + case RewardRecordStatus.Done: + case RewardRecordStatus.SuspendidPickup: return TaskRunResult.finished(); } const transactionId = constructTransactionIdentifier({ - tag: TransactionType.Tip, - walletTipId, + tag: TransactionType.Reward, + walletRewardId: walletTipId, }); const denomsForWithdraw = tipRecord.denomsSel; @@ -300,7 +300,7 @@ export async function processTip( } const tipStatusUrl = new URL( - `tips/${tipRecord.merchantTipId}/pickup`, + `tips/${tipRecord.merchantRewardId}/pickup`, tipRecord.merchantBaseUrl, ); @@ -384,9 +384,9 @@ export async function processTip( coinPriv: planchet.coinPriv, coinPub: planchet.coinPub, coinSource: { - type: CoinSourceType.Tip, + type: CoinSourceType.Reward, coinIndex: i, - walletTipId: walletTipId, + walletRewardId: walletTipId, }, sourceTransactionId: transactionId, denomPubHash: denom.denomPubHash, @@ -401,20 +401,20 @@ export async function processTip( } const transitionInfo = await ws.db - .mktx((x) => [x.coins, x.coinAvailability, x.denominations, x.tips]) + .mktx((x) => [x.coins, x.coinAvailability, x.denominations, x.rewards]) .runReadWrite(async (tx) => { - const tr = await tx.tips.get(walletTipId); + const tr = await tx.rewards.get(walletTipId); if (!tr) { return; } - if (tr.status !== TipRecordStatus.PendingPickup) { + if (tr.status !== RewardRecordStatus.PendingPickup) { return; } - const oldTxState = computeTipTransactionStatus(tr); + const oldTxState = computeRewardTransactionStatus(tr); tr.pickedUpTimestamp = TalerPreciseTimestamp.now(); - tr.status = TipRecordStatus.Done; - await tx.tips.put(tr); - const newTxState = computeTipTransactionStatus(tr); + tr.status = RewardRecordStatus.Done; + await tx.rewards.put(tr); + const newTxState = computeRewardTransactionStatus(tr); for (const cr of newCoinRecords) { await makeCoinAvailable(ws, tx, cr); } @@ -432,26 +432,26 @@ export async function acceptTip( walletTipId: string, ): Promise { const transactionId = constructTransactionIdentifier({ - tag: TransactionType.Tip, - walletTipId, + tag: TransactionType.Reward, + walletRewardId: walletTipId, }); const dbRes = await ws.db - .mktx((x) => [x.tips]) + .mktx((x) => [x.rewards]) .runReadWrite(async (tx) => { - const tipRecord = await tx.tips.get(walletTipId); + const tipRecord = await tx.rewards.get(walletTipId); if (!tipRecord) { logger.error("tip not found"); return; } - if (tipRecord.status != TipRecordStatus.DialogAccept) { + if (tipRecord.status != RewardRecordStatus.DialogAccept) { logger.warn("Unable to accept tip in the current state"); return { tipRecord }; } - const oldTxState = computeTipTransactionStatus(tipRecord); + const oldTxState = computeRewardTransactionStatus(tipRecord); tipRecord.acceptedTimestamp = TalerPreciseTimestamp.now(); - tipRecord.status = TipRecordStatus.PendingPickup; - await tx.tips.put(tipRecord); - const newTxState = computeTipTransactionStatus(tipRecord); + tipRecord.status = RewardRecordStatus.PendingPickup; + await tx.rewards.put(tipRecord); + const newTxState = computeRewardTransactionStatus(tipRecord); return { tipRecord, transitionInfo: { oldTxState, newTxState } }; }); @@ -465,53 +465,53 @@ export async function acceptTip( return { transactionId: constructTransactionIdentifier({ - tag: TransactionType.Tip, - walletTipId: walletTipId, + tag: TransactionType.Reward, + walletRewardId: walletTipId, }), next_url: tipRecord.next_url, }; } -export async function suspendTipTransaction( +export async function suspendRewardTransaction( ws: InternalWalletState, - walletTipId: string, + walletRewardId: string, ): Promise { const taskId = constructTaskIdentifier({ - tag: PendingTaskType.TipPickup, - walletTipId, + tag: PendingTaskType.RewardPickup, + walletRewardId: walletRewardId, }); const transactionId = constructTransactionIdentifier({ - tag: TransactionType.Tip, - walletTipId, + tag: TransactionType.Reward, + walletRewardId: walletRewardId, }); stopLongpolling(ws, taskId); const transitionInfo = await ws.db - .mktx((x) => [x.tips]) + .mktx((x) => [x.rewards]) .runReadWrite(async (tx) => { - const tipRec = await tx.tips.get(walletTipId); + const tipRec = await tx.rewards.get(walletRewardId); if (!tipRec) { - logger.warn(`transaction tip ${walletTipId} not found`); + logger.warn(`transaction tip ${walletRewardId} not found`); return; } - let newStatus: TipRecordStatus | undefined = undefined; + let newStatus: RewardRecordStatus | undefined = undefined; switch (tipRec.status) { - case TipRecordStatus.Done: - case TipRecordStatus.SuspendidPickup: - case TipRecordStatus.Aborted: - case TipRecordStatus.DialogAccept: + case RewardRecordStatus.Done: + case RewardRecordStatus.SuspendidPickup: + case RewardRecordStatus.Aborted: + case RewardRecordStatus.DialogAccept: break; - case TipRecordStatus.PendingPickup: - newStatus = TipRecordStatus.SuspendidPickup; + case RewardRecordStatus.PendingPickup: + newStatus = RewardRecordStatus.SuspendidPickup; break; default: assertUnreachable(tipRec.status); } if (newStatus != null) { - const oldTxState = computeTipTransactionStatus(tipRec); + const oldTxState = computeRewardTransactionStatus(tipRec); tipRec.status = newStatus; - const newTxState = computeTipTransactionStatus(tipRec); - await tx.tips.put(tipRec); + const newTxState = computeRewardTransactionStatus(tipRec); + await tx.rewards.put(tipRec); return { oldTxState, newTxState, @@ -525,43 +525,43 @@ export async function suspendTipTransaction( export async function resumeTipTransaction( ws: InternalWalletState, - walletTipId: string, + walletRewardId: string, ): Promise { const taskId = constructTaskIdentifier({ - tag: PendingTaskType.TipPickup, - walletTipId, + tag: PendingTaskType.RewardPickup, + walletRewardId: walletRewardId, }); const transactionId = constructTransactionIdentifier({ - tag: TransactionType.Tip, - walletTipId, + tag: TransactionType.Reward, + walletRewardId: walletRewardId, }); stopLongpolling(ws, taskId); const transitionInfo = await ws.db - .mktx((x) => [x.tips]) + .mktx((x) => [x.rewards]) .runReadWrite(async (tx) => { - const tipRec = await tx.tips.get(walletTipId); - if (!tipRec) { - logger.warn(`transaction tip ${walletTipId} not found`); + const rewardRec = await tx.rewards.get(walletRewardId); + if (!rewardRec) { + logger.warn(`transaction reward ${walletRewardId} not found`); return; } - let newStatus: TipRecordStatus | undefined = undefined; - switch (tipRec.status) { - case TipRecordStatus.Done: - case TipRecordStatus.PendingPickup: - case TipRecordStatus.Aborted: - case TipRecordStatus.DialogAccept: + let newStatus: RewardRecordStatus | undefined = undefined; + switch (rewardRec.status) { + case RewardRecordStatus.Done: + case RewardRecordStatus.PendingPickup: + case RewardRecordStatus.Aborted: + case RewardRecordStatus.DialogAccept: break; - case TipRecordStatus.SuspendidPickup: - newStatus = TipRecordStatus.PendingPickup; + case RewardRecordStatus.SuspendidPickup: + newStatus = RewardRecordStatus.PendingPickup; break; default: - assertUnreachable(tipRec.status); + assertUnreachable(rewardRec.status); } if (newStatus != null) { - const oldTxState = computeTipTransactionStatus(tipRec); - tipRec.status = newStatus; - const newTxState = computeTipTransactionStatus(tipRec); - await tx.tips.put(tipRec); + const oldTxState = computeRewardTransactionStatus(rewardRec); + rewardRec.status = newStatus; + const newTxState = computeRewardTransactionStatus(rewardRec); + await tx.rewards.put(rewardRec); return { oldTxState, newTxState, @@ -582,43 +582,43 @@ export async function failTipTransaction( export async function abortTipTransaction( ws: InternalWalletState, - walletTipId: string, + walletRewardId: string, ): Promise { const taskId = constructTaskIdentifier({ - tag: PendingTaskType.TipPickup, - walletTipId, + tag: PendingTaskType.RewardPickup, + walletRewardId: walletRewardId, }); const transactionId = constructTransactionIdentifier({ - tag: TransactionType.Tip, - walletTipId, + tag: TransactionType.Reward, + walletRewardId: walletRewardId, }); stopLongpolling(ws, taskId); const transitionInfo = await ws.db - .mktx((x) => [x.tips]) + .mktx((x) => [x.rewards]) .runReadWrite(async (tx) => { - const tipRec = await tx.tips.get(walletTipId); + const tipRec = await tx.rewards.get(walletRewardId); if (!tipRec) { - logger.warn(`transaction tip ${walletTipId} not found`); + logger.warn(`transaction tip ${walletRewardId} not found`); return; } - let newStatus: TipRecordStatus | undefined = undefined; + let newStatus: RewardRecordStatus | undefined = undefined; switch (tipRec.status) { - case TipRecordStatus.Done: - case TipRecordStatus.Aborted: - case TipRecordStatus.PendingPickup: - case TipRecordStatus.DialogAccept: + case RewardRecordStatus.Done: + case RewardRecordStatus.Aborted: + case RewardRecordStatus.PendingPickup: + case RewardRecordStatus.DialogAccept: break; - case TipRecordStatus.SuspendidPickup: - newStatus = TipRecordStatus.Aborted; + case RewardRecordStatus.SuspendidPickup: + newStatus = RewardRecordStatus.Aborted; break; default: assertUnreachable(tipRec.status); } if (newStatus != null) { - const oldTxState = computeTipTransactionStatus(tipRec); + const oldTxState = computeRewardTransactionStatus(tipRec); tipRec.status = newStatus; - const newTxState = computeTipTransactionStatus(tipRec); - await tx.tips.put(tipRec); + const newTxState = computeRewardTransactionStatus(tipRec); + await tx.rewards.put(tipRec); return { oldTxState, newTxState, diff --git a/packages/taler-wallet-core/src/operations/transactions.ts b/packages/taler-wallet-core/src/operations/transactions.ts index 868f00de7..a16809b36 100644 --- a/packages/taler-wallet-core/src/operations/transactions.ts +++ b/packages/taler-wallet-core/src/operations/transactions.ts @@ -58,7 +58,7 @@ import { RefreshGroupRecord, RefreshOperationStatus, RefundGroupRecord, - TipRecord, + RewardRecord, WalletContractData, WithdrawalGroupRecord, WithdrawalGroupStatus, @@ -107,11 +107,11 @@ import { import { abortTipTransaction, failTipTransaction, - computeTipTransactionStatus, + computeRewardTransactionStatus, resumeTipTransaction, - suspendTipTransaction, + suspendRewardTransaction, computeTipTransactionActions, -} from "./tip.js"; +} from "./reward.js"; import { abortWithdrawalTransaction, augmentPaytoUrisForWithdrawal, @@ -187,7 +187,7 @@ function shouldSkipSearch( */ const txOrder: { [t in TransactionType]: number } = { [TransactionType.Withdrawal]: 1, - [TransactionType.Tip]: 2, + [TransactionType.Reward]: 2, [TransactionType.Payment]: 3, [TransactionType.PeerPullCredit]: 4, [TransactionType.PeerPullDebit]: 5, @@ -284,12 +284,12 @@ export async function getTransactionById( throw Error(`no tx for refresh`); } - case TransactionType.Tip: { - const tipId = parsedTx.walletTipId; + case TransactionType.Reward: { + const tipId = parsedTx.walletRewardId; return await ws.db - .mktx((x) => [x.tips, x.operationRetries]) + .mktx((x) => [x.rewards, x.operationRetries]) .runReadWrite(async (tx) => { - const tipRecord = await tx.tips.get(tipId); + const tipRecord = await tx.rewards.get(tipId); if (!tipRecord) throw Error("not found"); const retries = await tx.operationRetries.get( @@ -818,21 +818,21 @@ function buildTransactionForDeposit( } function buildTransactionForTip( - tipRecord: TipRecord, + tipRecord: RewardRecord, ort?: OperationRetryRecord, ): Transaction { checkLogicInvariant(!!tipRecord.acceptedTimestamp); return { - type: TransactionType.Tip, - txState: computeTipTransactionStatus(tipRecord), + type: TransactionType.Reward, + txState: computeRewardTransactionStatus(tipRecord), txActions: computeTipTransactionActions(tipRecord), - amountEffective: Amounts.stringify(tipRecord.tipAmountEffective), - amountRaw: Amounts.stringify(tipRecord.tipAmountRaw), + amountEffective: Amounts.stringify(tipRecord.rewardAmountEffective), + amountRaw: Amounts.stringify(tipRecord.rewardAmountRaw), timestamp: tipRecord.acceptedTimestamp, transactionId: constructTransactionIdentifier({ - tag: TransactionType.Tip, - walletTipId: tipRecord.walletTipId, + tag: TransactionType.Reward, + walletRewardId: tipRecord.walletRewardId, }), merchantBaseUrl: tipRecord.merchantBaseUrl, ...(ort?.lastError ? { error: ort.lastError } : {}), @@ -945,7 +945,7 @@ export async function getTransactions( x.purchases, x.contractTerms, x.recoupGroups, - x.tips, + x.rewards, x.tombstones, x.withdrawalGroups, x.refreshGroups, @@ -1200,11 +1200,11 @@ export async function getTransactions( ); }); - tx.tips.iter().forEachAsync(async (tipRecord) => { + tx.rewards.iter().forEachAsync(async (tipRecord) => { if ( shouldSkipCurrency( transactionsRequest, - Amounts.parseOrThrow(tipRecord.tipAmountRaw).currency, + Amounts.parseOrThrow(tipRecord.rewardAmountRaw).currency, ) ) { return; @@ -1267,7 +1267,7 @@ export type ParsedTransactionIdentifier = | { tag: TransactionType.PeerPushDebit; pursePub: string } | { tag: TransactionType.Refresh; refreshGroupId: string } | { tag: TransactionType.Refund; refundGroupId: string } - | { tag: TransactionType.Tip; walletTipId: string } + | { tag: TransactionType.Reward; walletRewardId: string } | { tag: TransactionType.Withdrawal; withdrawalGroupId: string } | { tag: TransactionType.InternalWithdrawal; withdrawalGroupId: string }; @@ -1291,8 +1291,8 @@ export function constructTransactionIdentifier( return `txn:${pTxId.tag}:${pTxId.refreshGroupId}` as TransactionIdStr; case TransactionType.Refund: return `txn:${pTxId.tag}:${pTxId.refundGroupId}` as TransactionIdStr; - case TransactionType.Tip: - return `txn:${pTxId.tag}:${pTxId.walletTipId}` as TransactionIdStr; + case TransactionType.Reward: + return `txn:${pTxId.tag}:${pTxId.walletRewardId}` as TransactionIdStr; case TransactionType.Withdrawal: return `txn:${pTxId.tag}:${pTxId.withdrawalGroupId}` as TransactionIdStr; case TransactionType.InternalWithdrawal: @@ -1346,10 +1346,10 @@ export function parseTransactionIdentifier( tag: TransactionType.Refund, refundGroupId: rest[0], }; - case TransactionType.Tip: + case TransactionType.Reward: return { - tag: TransactionType.Tip, - walletTipId: rest[0], + tag: TransactionType.Reward, + walletRewardId: rest[0], }; case TransactionType.Withdrawal: return { @@ -1427,10 +1427,10 @@ export async function retryTransaction( stopLongpolling(ws, taskId); break; } - case TransactionType.Tip: { + case TransactionType.Reward: { const taskId = constructTaskIdentifier({ - tag: PendingTaskType.TipPickup, - walletTipId: parsedTx.walletTipId, + tag: PendingTaskType.RewardPickup, + walletRewardId: parsedTx.walletRewardId, }); await resetPendingTaskTimeout(ws, taskId); stopLongpolling(ws, taskId); @@ -1522,8 +1522,8 @@ export async function suspendTransaction( break; case TransactionType.Refund: throw Error("refund transactions can't be suspended or resumed"); - case TransactionType.Tip: - await suspendTipTransaction(ws, tx.walletTipId); + case TransactionType.Reward: + await suspendRewardTransaction(ws, tx.walletRewardId); break; default: assertUnreachable(tx); @@ -1551,8 +1551,8 @@ export async function failTransaction( return; case TransactionType.Refund: throw Error("can't do cancel-aborting on refund transaction"); - case TransactionType.Tip: - await failTipTransaction(ws, tx.walletTipId); + case TransactionType.Reward: + await failTipTransaction(ws, tx.walletRewardId); return; case TransactionType.Refresh: await failRefreshGroup(ws, tx.refreshGroupId); @@ -1613,8 +1613,8 @@ export async function resumeTransaction( break; case TransactionType.Refund: throw Error("refund transactions can't be suspended or resumed"); - case TransactionType.Tip: - await resumeTipTransaction(ws, tx.walletTipId); + case TransactionType.Reward: + await resumeTipTransaction(ws, tx.walletRewardId); break; } } @@ -1763,16 +1763,16 @@ export async function deleteTransaction( return; } - case TransactionType.Tip: { - const tipId = parsedTx.walletTipId; + case TransactionType.Reward: { + const tipId = parsedTx.walletRewardId; await ws.db - .mktx((x) => [x.tips, x.tombstones]) + .mktx((x) => [x.rewards, x.tombstones]) .runReadWrite(async (tx) => { - const tipRecord = await tx.tips.get(tipId); + const tipRecord = await tx.rewards.get(tipId); if (tipRecord) { - await tx.tips.delete(tipId); + await tx.rewards.delete(tipId); await tx.tombstones.put({ - id: TombstoneTag.DeleteTip + ":" + tipId, + id: TombstoneTag.DeleteReward + ":" + tipId, }); } }); @@ -1856,8 +1856,8 @@ export async function abortTransaction( case TransactionType.Deposit: await abortDepositGroup(ws, txId.depositGroupId); break; - case TransactionType.Tip: - await abortTipTransaction(ws, txId.walletTipId); + case TransactionType.Reward: + await abortTipTransaction(ws, txId.walletRewardId); break; case TransactionType.Refund: throw Error("can't abort refund transactions"); diff --git a/packages/taler-wallet-core/src/pending-types.ts b/packages/taler-wallet-core/src/pending-types.ts index 3bb6636ee..82eb542a7 100644 --- a/packages/taler-wallet-core/src/pending-types.ts +++ b/packages/taler-wallet-core/src/pending-types.ts @@ -33,7 +33,7 @@ export enum PendingTaskType { Purchase = "purchase", Refresh = "refresh", Recoup = "recoup", - TipPickup = "tip-pickup", + RewardPickup = "reward-pickup", Withdraw = "withdraw", Deposit = "deposit", Backup = "backup", @@ -144,7 +144,7 @@ export interface PendingRefreshTask { * The wallet is picking up a tip that the user has accepted. */ export interface PendingTipPickupTask { - type: PendingTaskType.TipPickup; + type: PendingTaskType.RewardPickup; tipId: string; merchantBaseUrl: string; merchantTipId: string; diff --git a/packages/taler-wallet-core/src/wallet-api-types.ts b/packages/taler-wallet-core/src/wallet-api-types.ts index e395237cf..eaa99a6c3 100644 --- a/packages/taler-wallet-core/src/wallet-api-types.ts +++ b/packages/taler-wallet-core/src/wallet-api-types.ts @@ -29,7 +29,7 @@ import { AcceptExchangeTosRequest, AcceptManualWithdrawalRequest, AcceptManualWithdrawalResult, - AcceptTipRequest, + AcceptRewardRequest, AcceptTipResponse, AcceptWithdrawalResponse, AddExchangeRequest, @@ -85,8 +85,8 @@ import { PreparePeerPushCreditRequest, PreparePeerPushCreditResponse, PrepareRefundRequest, - PrepareTipRequest, - PrepareTipResult, + PrepareRewardRequest as PrepareRewardRequest, + PrepareTipResult as PrepareRewardResult, RecoveryLoadRequest, RetryTransactionRequest, SetCoinSuspendedRequest, @@ -178,8 +178,8 @@ export enum WalletApiOperation { DumpCoins = "dumpCoins", SetCoinSuspended = "setCoinSuspended", ForceRefresh = "forceRefresh", - PrepareTip = "prepareTip", - AcceptTip = "acceptTip", + PrepareReward = "prepareReward", + AcceptReward = "acceptReward", ExportBackup = "exportBackup", AddBackupProvider = "addBackupProvider", RemoveBackupProvider = "removeBackupProvider", @@ -507,23 +507,23 @@ export type StartRefundQueryOp = { response: EmptyObject; }; -// group: Tipping +// group: Rewards /** - * Query and store information about a tip. + * Query and store information about a reward. */ export type PrepareTipOp = { - op: WalletApiOperation.PrepareTip; - request: PrepareTipRequest; - response: PrepareTipResult; + op: WalletApiOperation.PrepareReward; + request: PrepareRewardRequest; + response: PrepareRewardResult; }; /** - * Accept a tip. + * Accept a reward. */ export type AcceptTipOp = { - op: WalletApiOperation.AcceptTip; - request: AcceptTipRequest; + op: WalletApiOperation.AcceptReward; + request: AcceptRewardRequest; response: AcceptTipResponse; }; @@ -1023,8 +1023,8 @@ export type WalletOperations = { [WalletApiOperation.ForceRefresh]: ForceRefreshOp; [WalletApiOperation.DeleteTransaction]: DeleteTransactionOp; [WalletApiOperation.RetryTransaction]: RetryTransactionOp; - [WalletApiOperation.PrepareTip]: PrepareTipOp; - [WalletApiOperation.AcceptTip]: AcceptTipOp; + [WalletApiOperation.PrepareReward]: PrepareTipOp; + [WalletApiOperation.AcceptReward]: AcceptTipOp; [WalletApiOperation.StartRefundQueryForUri]: StartRefundQueryForUriOp; [WalletApiOperation.StartRefundQuery]: StartRefundQueryOp; [WalletApiOperation.ListCurrencies]: ListCurrenciesOp; diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts index f8bbd21fc..4a83db856 100644 --- a/packages/taler-wallet-core/src/wallet.ts +++ b/packages/taler-wallet-core/src/wallet.ts @@ -93,7 +93,7 @@ import { codecForPreparePeerPullPaymentRequest, codecForPreparePeerPushCreditRequest, codecForPrepareRefundRequest, - codecForPrepareTipRequest, + codecForPrepareRewardRequest, codecForResumeTransaction, codecForRetryTransactionRequest, codecForSetCoinSuspendedRequest, @@ -249,10 +249,10 @@ import { } from "./operations/testing.js"; import { acceptTip, - computeTipTransactionStatus, + computeRewardTransactionStatus, prepareTip, processTip, -} from "./operations/tip.js"; +} from "./operations/reward.js"; import { abortTransaction, deleteTransaction, @@ -329,7 +329,7 @@ async function callOperationHandler( return await processRefreshGroup(ws, pending.refreshGroupId); case PendingTaskType.Withdraw: return await processWithdrawalGroup(ws, pending.withdrawalGroupId); - case PendingTaskType.TipPickup: + case PendingTaskType.RewardPickup: return await processTip(ws, pending.tipId); case PendingTaskType.Purchase: return await processPurchase(ws, pending.proposalId); @@ -1350,9 +1350,9 @@ async function dispatchRequestInternal( refreshGroupId, }; } - case WalletApiOperation.PrepareTip: { - const req = codecForPrepareTipRequest().decode(payload); - return await prepareTip(ws, req.talerTipUri); + case WalletApiOperation.PrepareReward: { + const req = codecForPrepareRewardRequest().decode(payload); + return await prepareTip(ws, req.talerRewardUri); } case WalletApiOperation.StartRefundQueryForUri: { const req = codecForPrepareRefundRequest().decode(payload); @@ -1370,9 +1370,9 @@ async function dispatchRequestInternal( await startQueryRefund(ws, txIdParsed.proposalId); return {}; } - case WalletApiOperation.AcceptTip: { + case WalletApiOperation.AcceptReward: { const req = codecForAcceptTipRequest().decode(payload); - return await acceptTip(ws, req.walletTipId); + return await acceptTip(ws, req.walletRewardId); } case WalletApiOperation.ExportBackupPlain: { return exportBackup(ws); @@ -1884,12 +1884,12 @@ class InternalWalletStateImpl implements InternalWalletState { } return computeRefreshTransactionState(rec); } - case TransactionType.Tip: { - const rec = await tx.tips.get(parsedTxId.walletTipId); + case TransactionType.Reward: { + const rec = await tx.rewards.get(parsedTxId.walletRewardId); if (!rec) { return undefined; } - return computeTipTransactionStatus(rec); + return computeRewardTransactionStatus(rec); } default: assertUnreachable(parsedTxId); diff --git a/packages/taler-wallet-webextension/src/components/HistoryItem.tsx b/packages/taler-wallet-webextension/src/components/HistoryItem.tsx index a0ce04460..e072d2581 100644 --- a/packages/taler-wallet-webextension/src/components/HistoryItem.tsx +++ b/packages/taler-wallet-webextension/src/components/HistoryItem.tsx @@ -134,7 +134,7 @@ export function HistoryItem(props: { tx: Transaction }): VNode { } /> ); - case TransactionType.Tip: + case TransactionType.Reward: return ( { - if (!talerTipUri) throw Error("ERROR_NO-URI-FOR-TIP"); - const tip = await api.wallet.call(WalletApiOperation.PrepareTip, { - talerTipUri, + if (!talerRewardUri) throw Error("ERROR_NO-URI-FOR-TIP"); + const tip = await api.wallet.call(WalletApiOperation.PrepareReward, { + talerRewardUri, }); return { tip }; }); @@ -63,8 +63,8 @@ export function useComponentState({ const { tip } = tipInfo.response; const doAccept = async (): Promise => { - const res = await api.wallet.call(WalletApiOperation.AcceptTip, { - walletTipId: tip.walletTipId, + const res = await api.wallet.call(WalletApiOperation.AcceptReward, { + walletRewardId: tip.walletRewardId, }); //FIX: this may not be seen since we are moving to the success also @@ -75,7 +75,7 @@ export function useComponentState({ const baseInfo = { merchantBaseUrl: tip.merchantBaseUrl, exchangeBaseUrl: tip.exchangeBaseUrl, - amount: Amounts.parseOrThrow(tip.tipAmountEffective), + amount: Amounts.parseOrThrow(tip.rewardAmountEffective), error: undefined, cancel: { onClick: pushAlertOnError(onCancel), diff --git a/packages/taler-wallet-webextension/src/cta/Tip/stories.tsx b/packages/taler-wallet-webextension/src/cta/Reward/stories.tsx similarity index 100% rename from packages/taler-wallet-webextension/src/cta/Tip/stories.tsx rename to packages/taler-wallet-webextension/src/cta/Reward/stories.tsx diff --git a/packages/taler-wallet-webextension/src/cta/Tip/test.ts b/packages/taler-wallet-webextension/src/cta/Reward/test.ts similarity index 90% rename from packages/taler-wallet-webextension/src/cta/Tip/test.ts rename to packages/taler-wallet-webextension/src/cta/Reward/test.ts index e0b6210a2..6d7bad0c8 100644 --- a/packages/taler-wallet-webextension/src/cta/Tip/test.ts +++ b/packages/taler-wallet-webextension/src/cta/Reward/test.ts @@ -62,17 +62,17 @@ describe("Tip CTA states", () => { it("should be ready for accepting the tip", async () => { const { handler, TestingContext } = createWalletApiMock(); - handler.addWalletCallResponse(WalletApiOperation.PrepareTip, undefined, { + handler.addWalletCallResponse(WalletApiOperation.PrepareReward, undefined, { accepted: false, exchangeBaseUrl: "exchange url", merchantBaseUrl: "merchant url", - tipAmountEffective: "EUR:1", - walletTipId: "tip_id", + rewardAmountEffective: "EUR:1", + walletRewardId: "tip_id", transactionId: "txn:tip:ABC1234", expirationTimestamp: { t_s: 1, }, - tipAmountRaw: "", + rewardAmountRaw: "", }); const props: Props = { @@ -100,23 +100,23 @@ describe("Tip CTA states", () => { expect(state.exchangeBaseUrl).eq("exchange url"); if (state.accept.onClick === undefined) expect.fail(); - handler.addWalletCallResponse(WalletApiOperation.AcceptTip); + handler.addWalletCallResponse(WalletApiOperation.AcceptReward); state.accept.onClick(); handler.addWalletCallResponse( - WalletApiOperation.PrepareTip, + WalletApiOperation.PrepareReward, undefined, { accepted: true, exchangeBaseUrl: "exchange url", merchantBaseUrl: "merchant url", - tipAmountEffective: "EUR:1", - walletTipId: "tip_id", + rewardAmountEffective: "EUR:1", + walletRewardId: "tip_id", transactionId: "txn:tip:ABC1234", expirationTimestamp: { t_s: 1, }, - tipAmountRaw: "", + rewardAmountRaw: "", }, ); }, @@ -137,17 +137,17 @@ describe("Tip CTA states", () => { it.skip("should be ignored after clicking the ignore button", async () => { const { handler, TestingContext } = createWalletApiMock(); - handler.addWalletCallResponse(WalletApiOperation.PrepareTip, undefined, { + handler.addWalletCallResponse(WalletApiOperation.PrepareReward, undefined, { exchangeBaseUrl: "exchange url", merchantBaseUrl: "merchant url", - tipAmountEffective: "EUR:1", - walletTipId: "tip_id", + rewardAmountEffective: "EUR:1", + walletRewardId: "tip_id", transactionId: "txn:tip:ABC1234", accepted: false, expirationTimestamp: { t_s: 1, }, - tipAmountRaw: "", + rewardAmountRaw: "", }); const props: Props = { @@ -184,17 +184,17 @@ describe("Tip CTA states", () => { it("should render accepted if the tip has been used previously", async () => { const { handler, TestingContext } = createWalletApiMock(); - handler.addWalletCallResponse(WalletApiOperation.PrepareTip, undefined, { + handler.addWalletCallResponse(WalletApiOperation.PrepareReward, undefined, { accepted: true, exchangeBaseUrl: "exchange url", merchantBaseUrl: "merchant url", - tipAmountEffective: "EUR:1", - walletTipId: "tip_id", + rewardAmountEffective: "EUR:1", + walletRewardId: "tip_id", transactionId: "txn:tip:ABC1234", expirationTimestamp: { t_s: 1, }, - tipAmountRaw: "", + rewardAmountRaw: "", }); const props: Props = { diff --git a/packages/taler-wallet-webextension/src/cta/Tip/views.tsx b/packages/taler-wallet-webextension/src/cta/Reward/views.tsx similarity index 100% rename from packages/taler-wallet-webextension/src/cta/Tip/views.tsx rename to packages/taler-wallet-webextension/src/cta/Reward/views.tsx diff --git a/packages/taler-wallet-webextension/src/cta/index.stories.ts b/packages/taler-wallet-webextension/src/cta/index.stories.ts index 84863f84f..06b11ef6d 100644 --- a/packages/taler-wallet-webextension/src/cta/index.stories.ts +++ b/packages/taler-wallet-webextension/src/cta/index.stories.ts @@ -22,7 +22,7 @@ export * as a1 from "./Deposit/stories.jsx"; export * as a3 from "./Payment/stories.jsx"; export * as a4 from "./Refund/stories.jsx"; -export * as a5 from "./Tip/stories.jsx"; +export * as a5 from "./Reward/stories.js"; export * as a6 from "./Withdraw/stories.jsx"; export * as a8 from "./InvoiceCreate/stories.js"; export * as a9 from "./InvoicePay/stories.js"; diff --git a/packages/taler-wallet-webextension/src/wallet/Application.tsx b/packages/taler-wallet-webextension/src/wallet/Application.tsx index d8cb22bf0..98515aac0 100644 --- a/packages/taler-wallet-webextension/src/wallet/Application.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Application.tsx @@ -58,7 +58,7 @@ import { PaymentPage } from "../cta/Payment/index.js"; import { PaymentTemplatePage } from "../cta/PaymentTemplate/index.js"; import { RecoveryPage } from "../cta/Recovery/index.js"; import { RefundPage } from "../cta/Refund/index.js"; -import { TipPage } from "../cta/Tip/index.js"; +import { TipPage } from "../cta/Reward/index.js"; import { TransferCreatePage } from "../cta/TransferCreate/index.js"; import { TransferPickupPage } from "../cta/TransferPickup/index.js"; import { diff --git a/packages/taler-wallet-webextension/src/wallet/History.stories.tsx b/packages/taler-wallet-webextension/src/wallet/History.stories.tsx index 149c8c1f4..1ddb24b02 100644 --- a/packages/taler-wallet-webextension/src/wallet/History.stories.tsx +++ b/packages/taler-wallet-webextension/src/wallet/History.stories.tsx @@ -34,7 +34,7 @@ import { TransactionPeerPushDebit, TransactionRefresh, TransactionRefund, - TransactionTip, + TransactionReward, TransactionType, TransactionWithdrawal, WithdrawalType, @@ -113,9 +113,9 @@ const exampleData = { } as TransactionRefresh, tip: { ...commonTransaction(), - type: TransactionType.Tip, + type: TransactionType.Reward, merchantBaseUrl: "http://ads.merchant.taler.net/", - } as TransactionTip, + } as TransactionReward, refund: { ...commonTransaction(), type: TransactionType.Refund, diff --git a/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx b/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx index f2e3982f6..3ba3ac591 100644 --- a/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx @@ -37,7 +37,7 @@ import { TransactionPeerPushDebit, TransactionRefresh, TransactionRefund, - TransactionTip, + TransactionReward, TransactionType, TransactionWithdrawal, WithdrawalDetails, @@ -138,7 +138,7 @@ const exampleData = { } as TransactionRefresh, tip: { ...commonTransaction, - type: TransactionType.Tip, + type: TransactionType.Reward, // merchant: { // name: "the merchant", // logo: merchantIcon, @@ -146,7 +146,7 @@ const exampleData = { // email: "contact@merchant.taler", // }, merchantBaseUrl: "http://merchant.taler", - } as TransactionTip, + } as TransactionReward, refund: { ...commonTransaction, type: TransactionType.Refund, diff --git a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx index 8d564a275..e54137016 100644 --- a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx @@ -745,7 +745,7 @@ export function TransactionView({ ); } - if (transaction.type === TransactionType.Tip) { + if (transaction.type === TransactionType.Reward) { return (