From 4267e3410a8dbe1e50594957ebfd2efc3bffa29c Mon Sep 17 00:00:00 2001 From: Radu-Cristian Popa Date: Sun, 14 Jul 2024 09:12:07 +0300 Subject: [PATCH 1/4] Update monetization event payload (detail -> details) --- src/background/services/paymentSession.ts | 15 +++++++++------ src/content/polyfill.ts | 4 ++-- src/content/services/monetizationTagManager.ts | 4 ++-- src/shared/messages.ts | 2 +- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/background/services/paymentSession.ts b/src/background/services/paymentSession.ts index 55acb2e7..2a1aa103 100644 --- a/src/background/services/paymentSession.ts +++ b/src/background/services/paymentSession.ts @@ -11,6 +11,7 @@ import { convert, sleep } from '@/shared/helpers' import { transformBalance } from '@/popup/lib/utils' import { TabState } from './tabState' import type { Tabs } from 'webextension-polyfill' +import { MonetizationEventPayload } from '@/shared/messages' const DEFAULT_INTERVAL_MS = 1000 const HOUR_MS = 3600 * 1000 @@ -166,12 +167,9 @@ export class PaymentSession { outgoingPayment = undefined - sendMonetizationEvent({ - tabId: this.tabId, - frameId: this.frameId, - payload: { + const monetizationEventPayload: MonetizationEventPayload = { requestId: this.requestId, - detail: { + details: { amountSent: { currency: receiveAmount.assetCode, value: transformBalance( @@ -183,6 +181,11 @@ export class PaymentSession { paymentPointer: this.receiver.id } } + + sendMonetizationEvent({ + tabId: this.tabId, + frameId: this.frameId, + payload: monetizationEventPayload }) // TO DO: find a better source of truth for deciding if overpaying is applicable @@ -283,7 +286,7 @@ export class PaymentSession { frameId: this.frameId, payload: { requestId: this.requestId, - detail: { + details: { amountSent: { currency: receiveAmount.assetCode, value: transformBalance( diff --git a/src/content/polyfill.ts b/src/content/polyfill.ts index acd8c650..68ece957 100644 --- a/src/content/polyfill.ts +++ b/src/content/polyfill.ts @@ -67,7 +67,7 @@ import type { MonetizationEventPayload } from '@/shared/messages' constructor( type: 'monetization', - eventInitDict: MonetizationEventPayload['detail'] + eventInitDict: MonetizationEventPayload['details'] ) { super(type, { bubbles: true }) const { amountSent, incomingPayment, paymentPointer } = eventInitDict @@ -97,7 +97,7 @@ import type { MonetizationEventPayload } from '@/shared/messages' window.addEventListener( '__wm_ext_monetization', - (event: CustomEvent) => { + (event: CustomEvent) => { if (!(event.target instanceof HTMLLinkElement)) return if (!event.target.isConnected) return diff --git a/src/content/services/monetizationTagManager.ts b/src/content/services/monetizationTagManager.ts index 77598373..004e69da 100644 --- a/src/content/services/monetizationTagManager.ts +++ b/src/content/services/monetizationTagManager.ts @@ -73,13 +73,13 @@ export class MonetizationTagManager extends EventEmitter { tag.dispatchEvent(new Event('error')) } - dispatchMonetizationEvent({ requestId, detail }: MonetizationEventPayload) { + dispatchMonetizationEvent({ requestId, details }: MonetizationEventPayload) { this.monetizationTags.forEach((tagDetails, tag) => { if (tagDetails.requestId !== requestId) return tag.dispatchEvent( new CustomEvent('__wm_ext_monetization', { - detail: mozClone(detail, this.document), + detail: mozClone(details, this.document), bubbles: true }) ) diff --git a/src/shared/messages.ts b/src/shared/messages.ts index 3e337547..91527660 100644 --- a/src/shared/messages.ts +++ b/src/shared/messages.ts @@ -137,7 +137,7 @@ export enum BackgroundToContentAction { export interface MonetizationEventPayload { requestId: string - detail: { + details: { amountSent: PaymentCurrencyAmount incomingPayment: OutgoingPayment['receiver'] paymentPointer: WalletAddress['id'] From 25864839d07f7e461e97ec253a233b0bb9b659f5 Mon Sep 17 00:00:00 2001 From: Radu-Cristian Popa Date: Sun, 14 Jul 2024 09:16:24 +0300 Subject: [PATCH 2/4] Store monetization event details when overpaying --- src/background/services/paymentSession.ts | 7 +++++-- src/background/services/tabState.ts | 14 +++++++++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/background/services/paymentSession.ts b/src/background/services/paymentSession.ts index 2a1aa103..aa7befa5 100644 --- a/src/background/services/paymentSession.ts +++ b/src/background/services/paymentSession.ts @@ -193,8 +193,11 @@ export class PaymentSession { this.tabState.saveOverpaying( this.tab, this.url, - this.receiver.id, - this.intervalInMs + { + walletAddressId: this.receiver.id, + monetizationEvent: monetizationEventPayload, + intervalInMs: this.intervalInMs + } ) } diff --git a/src/background/services/tabState.ts b/src/background/services/tabState.ts index 5600ef6e..4fa52fc8 100644 --- a/src/background/services/tabState.ts +++ b/src/background/services/tabState.ts @@ -1,10 +1,17 @@ import { Tabs } from 'webextension-polyfill' type State = { + monetizationEvent: MonetizationEventPayload lastPaymentTimestamp: number expiresAtTimestamp: number } +interface SaveOverpayingDetails { + walletAddressId: string, + monetizationEvent: MonetizationEventPayload, + intervalInMs: number +} + export class TabState { private state = new WeakMap>() @@ -33,9 +40,9 @@ export class TabState { saveOverpaying( tab: Tabs.Tab, url: string, - walletAddressId: string, - intervalInMs: number + details: SaveOverpayingDetails ): void { + const {intervalInMs, walletAddressId, monetizationEvent } = details if (!intervalInMs) return const now = Date.now() @@ -45,8 +52,9 @@ export class TabState { const state = this.state.get(tab)?.get(key) if (!state) { - const tabState = this.state.get(tab) || new Map() + const tabState = this.state.get(tab) || new Map() tabState.set(key, { + monetizationEvent, expiresAtTimestamp: expiresAtTimestamp, lastPaymentTimestamp: now }) From ab82dc72ae33efb43607a31252f5ad97fb156c8b Mon Sep 17 00:00:00 2001 From: Radu-Cristian Popa Date: Sun, 14 Jul 2024 09:21:45 +0300 Subject: [PATCH 3/4] Send last monetization event when overpaying --- src/background/services/paymentSession.ts | 59 +++++++++++++---------- src/background/services/tabState.ts | 24 +++++---- src/shared/messages.ts | 12 +++-- 3 files changed, 55 insertions(+), 40 deletions(-) diff --git a/src/background/services/paymentSession.ts b/src/background/services/paymentSession.ts index aa7befa5..59fe00ed 100644 --- a/src/background/services/paymentSession.ts +++ b/src/background/services/paymentSession.ts @@ -11,7 +11,7 @@ import { convert, sleep } from '@/shared/helpers' import { transformBalance } from '@/popup/lib/utils' import { TabState } from './tabState' import type { Tabs } from 'webextension-polyfill' -import { MonetizationEventPayload } from '@/shared/messages' +import type { MonetizationEventDetails } from '@/shared/messages' const DEFAULT_INTERVAL_MS = 1000 const HOUR_MS = 3600 * 1000 @@ -128,12 +128,23 @@ export class PaymentSession { let outgoingPayment: OutgoingPayment | undefined - const waitTime = this.tabState.getOverpayingWaitTime( + const { waitTime, monetizationEvent } = this.tabState.getOverpayingWaitTime( this.tab, this.url, this.receiver.id ) + if (monetizationEvent) { + sendMonetizationEvent({ + tabId: this.tabId, + frameId: this.frameId, + payload: { + requestId: this.requestId, + details: monetizationEvent + } + }) + } + await sleep(waitTime) while (this.active) { @@ -167,38 +178,34 @@ export class PaymentSession { outgoingPayment = undefined - const monetizationEventPayload: MonetizationEventPayload = { - requestId: this.requestId, - details: { - amountSent: { - currency: receiveAmount.assetCode, - value: transformBalance( - receiveAmount.value, - receiveAmount.assetScale - ) - }, - incomingPayment, - paymentPointer: this.receiver.id - } - } + const monetizationEventDetails: MonetizationEventDetails = { + amountSent: { + currency: receiveAmount.assetCode, + value: transformBalance( + receiveAmount.value, + receiveAmount.assetScale + ) + }, + incomingPayment, + paymentPointer: this.receiver.id + } sendMonetizationEvent({ tabId: this.tabId, frameId: this.frameId, - payload: monetizationEventPayload + payload: { + requestId: this.requestId, + details: monetizationEventDetails + } }) // TO DO: find a better source of truth for deciding if overpaying is applicable if (this.intervalInMs > 1000) { - this.tabState.saveOverpaying( - this.tab, - this.url, - { - walletAddressId: this.receiver.id, - monetizationEvent: monetizationEventPayload, - intervalInMs: this.intervalInMs - } - ) + this.tabState.saveOverpaying(this.tab, this.url, { + walletAddressId: this.receiver.id, + monetizationEvent: monetizationEventDetails, + intervalInMs: this.intervalInMs + }) } await sleep(this.intervalInMs) diff --git a/src/background/services/tabState.ts b/src/background/services/tabState.ts index 4fa52fc8..73cd3be3 100644 --- a/src/background/services/tabState.ts +++ b/src/background/services/tabState.ts @@ -1,15 +1,16 @@ -import { Tabs } from 'webextension-polyfill' +import type { MonetizationEventDetails } from '@/shared/messages' +import type { Tabs } from 'webextension-polyfill' type State = { - monetizationEvent: MonetizationEventPayload + monetizationEvent: MonetizationEventDetails lastPaymentTimestamp: number expiresAtTimestamp: number } interface SaveOverpayingDetails { - walletAddressId: string, - monetizationEvent: MonetizationEventPayload, - intervalInMs: number + walletAddressId: string + monetizationEvent: MonetizationEventDetails + intervalInMs: number } export class TabState { @@ -25,16 +26,21 @@ export class TabState { tab: Tabs.Tab, url: string, walletAddressId: string - ): number { + ): { waitTime: number; monetizationEvent?: MonetizationEventDetails } { const key = this.getOverpayingStateKey(url, walletAddressId) const state = this.state.get(tab)?.get(key) const now = Date.now() if (state && state.expiresAtTimestamp > now) { - return state.expiresAtTimestamp - now + return { + waitTime: state.expiresAtTimestamp - now, + monetizationEvent: state.monetizationEvent + } } - return 0 + return { + waitTime: 0 + } } saveOverpaying( @@ -42,7 +48,7 @@ export class TabState { url: string, details: SaveOverpayingDetails ): void { - const {intervalInMs, walletAddressId, monetizationEvent } = details + const { intervalInMs, walletAddressId, monetizationEvent } = details if (!intervalInMs) return const now = Date.now() diff --git a/src/shared/messages.ts b/src/shared/messages.ts index 91527660..b3a08820 100644 --- a/src/shared/messages.ts +++ b/src/shared/messages.ts @@ -135,13 +135,15 @@ export enum BackgroundToContentAction { EMIT_TOGGLE_WM = 'EMIT_TOGGLE_WM' } +export interface MonetizationEventDetails { + amountSent: PaymentCurrencyAmount + incomingPayment: OutgoingPayment['receiver'] + paymentPointer: WalletAddress['id'] +} + export interface MonetizationEventPayload { requestId: string - details: { - amountSent: PaymentCurrencyAmount - incomingPayment: OutgoingPayment['receiver'] - paymentPointer: WalletAddress['id'] - } + details: MonetizationEventDetails } export interface EmitToggleWMPayload { From 037080f350020a418263c4115ef2eb9b508c96de Mon Sep 17 00:00:00 2001 From: Radu-Cristian Popa Date: Sun, 14 Jul 2024 09:24:19 +0300 Subject: [PATCH 4/4] Better name for `tabState` method --- src/background/services/paymentSession.ts | 2 +- src/background/services/tabState.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/background/services/paymentSession.ts b/src/background/services/paymentSession.ts index 59fe00ed..20fbcbf9 100644 --- a/src/background/services/paymentSession.ts +++ b/src/background/services/paymentSession.ts @@ -128,7 +128,7 @@ export class PaymentSession { let outgoingPayment: OutgoingPayment | undefined - const { waitTime, monetizationEvent } = this.tabState.getOverpayingWaitTime( + const { waitTime, monetizationEvent } = this.tabState.getOverpayingDetails( this.tab, this.url, this.receiver.id diff --git a/src/background/services/tabState.ts b/src/background/services/tabState.ts index 73cd3be3..f989a22c 100644 --- a/src/background/services/tabState.ts +++ b/src/background/services/tabState.ts @@ -22,7 +22,7 @@ export class TabState { return `${url}:${walletAddressId}` } - getOverpayingWaitTime( + getOverpayingDetails( tab: Tabs.Tab, url: string, walletAddressId: string