Skip to content

Commit 4f0ebea

Browse files
authored
feat(spec/ext) specify getWallet/onPayment (#664)
* feat(spec/ext) specify getWallet/onPayment * address comments
1 parent 9f50a06 commit 4f0ebea

4 files changed

Lines changed: 200 additions & 36 deletions

File tree

specification/extensions-api/section/events.html

Lines changed: 51 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
<h2>Events</h2>
33

44
<p>
5-
Events in this namespace are scoped to a {{ Document }},
6-
identified by its tab and frame. Each event callback receives a
7-
{{MonetizationInfo}} dictionary describing the affected document.
5+
Events in this namespace are scoped to a [[WebMonetization]]
6+
session. Each event callback receives a
7+
{{monetization/Session}} dictionary identifying the affected
8+
session and the document it belongs to.
89
</p>
910

1011
<section data-dfn-for="monetization">
@@ -15,21 +16,19 @@ <h3><dfn>onStarted</dfn></h3>
1516
)</pre>
1617

1718
<p>
18-
Fired when the first [[WebMonetization]] session becomes active
19-
in a document. Subsequent sessions starting in the same document
20-
do <em>not</em> re-fire this event.
19+
Fired when a [[WebMonetization]] session starts in a document.
2120
</p>
2221

2322
<h4>Parameters</h4>
2423
<dl>
2524
<dt><code>callback</code></dt>
2625
<dd>
2726
<p>The <code>callback</code> parameter looks like:</p>
28-
<pre>(info: {{MonetizationInfo}}) =&gt; void</pre>
27+
<pre>(session: {{monetization/Session}}) =&gt; void</pre>
2928
<dl>
30-
<dt><code>info</code></dt>
31-
<dd>The {{MonetizationInfo}} for the document where
32-
monetization started.</dd>
29+
<dt><code>session</code></dt>
30+
<dd>The {{monetization/Session}} for the session that
31+
started.</dd>
3332
</dl>
3433
</dd>
3534
</dl>
@@ -38,26 +37,26 @@ <h4>Parameters</h4>
3837
<section data-dfn-for="monetization">
3938
<h3><dfn>onStopped</dfn></h3>
4039

41-
<pre>browser.monetization.onStopped.addListener(
40+
<pre class="example">browser.monetization.onStopped.addListener(
4241
callback: function,
4342
)</pre>
4443

4544
<p>
46-
Fired when the last [[WebMonetization]] session in a document
47-
has ended. This occurs when the tab is closed, the document
48-
navigates away, or all sessions are explicitly stopped.
45+
Fired when a [[WebMonetization]] session ends. This occurs when
46+
the tab is closed, the document navigates away, or the session
47+
is explicitly stopped.
4948
</p>
5049

5150
<h4>Parameters</h4>
5251
<dl>
5352
<dt><code>callback</code></dt>
5453
<dd>
5554
<p>The <code>callback</code> parameter looks like:</p>
56-
<pre>(info: {{MonetizationInfo}}) =&gt; void</pre>
55+
<pre>(session: {{monetization/Session}}) =&gt; void</pre>
5756
<dl>
58-
<dt><code>info</code></dt>
59-
<dd>The {{MonetizationInfo}} for the document where
60-
monetization stopped.</dd>
57+
<dt><code>session</code></dt>
58+
<dd>The {{monetization/Session}} for the session that
59+
stopped.</dd>
6160
</dl>
6261
</dd>
6362
</dl>
@@ -67,13 +66,40 @@ <h4>Parameters</h4>
6766
<h3>Event ordering</h3>
6867

6968
<p>
70-
For a given document, an {{monetization/onStarted}} event is always
71-
delivered before any corresponding {{monetization/onStopped}} event.
72-
If a document has multiple concurrent sessions, intermediate
73-
session starts and stops do not produce additional events.
74-
Only the transition from zero to one active session
75-
({{monetization/onStarted}}) and from one to zero active sessions
76-
({{monetization/onStopped}}) fire events.
69+
For a given session, an {{monetization/onStarted}} event is
70+
always delivered before the corresponding
71+
{{monetization/onStopped}} event. A document with multiple
72+
concurrent sessions receives a separate
73+
{{monetization/onStarted}} and {{monetization/onStopped}} pair
74+
for each session.
7775
</p>
7876
</section>
77+
78+
<section data-dfn-for="monetization">
79+
<h3><dfn>onPayment</dfn></h3>
80+
81+
<pre class="example">browser.monetization.onPayment.addListener(
82+
callback: function,
83+
)</pre>
84+
85+
<p>
86+
Fired when a payment is sent for a monetization session. The
87+
updated budget balance can be retrieved via
88+
{{monetization/getWallet()}}.
89+
</p>
90+
91+
<h4>Parameters</h4>
92+
<dl>
93+
<dt><code>callback</code></dt>
94+
<dd>
95+
<p>The <code>callback</code> parameter looks like:</p>
96+
<pre>(session: {{monetization/Session}}) =&gt; void</pre>
97+
<dl>
98+
<dt><code>session</code></dt>
99+
<dd>The {{monetization/Session}} for the session that
100+
triggered the payment.</dd>
101+
</dl>
102+
</dd>
103+
</dl>
104+
</section>
79105
</section>

specification/extensions-api/section/interfaces.html

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,40 @@ <h2>The <code>monetization</code> namespace</h2>
33

44
<p>
55
The <dfn>monetization</dfn> namespace is the entry point for the
6-
Web Monetization Extensions API. It exposes events that allow
7-
extensions to observe monetization session state changes within
8-
documents.
6+
Web Monetization Extensions API. It exposes methods for querying
7+
wallet state and budget balance, and events that allow extensions
8+
to observe monetization session lifecycle and payment activity.
9+
</p>
10+
11+
<p class="note">
12+
The full <code>chrome.monetization</code> API includes additional
13+
methods for wallet connection management and session history that
14+
are available only to the browser's built-in WebUI. This
15+
specification covers the subset exposed to privileged browser
16+
extensions.
917
</p>
1018

1119
<pre class="idl">
1220
[Exposed=Window]
1321
namespace monetization {
22+
Promise&lt;Wallet?&gt; getWallet();
23+
1424
readonly attribute EventHandler onStarted;
1525
readonly attribute EventHandler onStopped;
26+
readonly attribute EventHandler onPayment;
1627
};
1728
</pre>
29+
30+
<section data-dfn-for="monetization">
31+
<h3>Methods</h3>
32+
33+
<section>
34+
<h4><dfn>getWallet()</dfn></h4>
35+
<p>
36+
Returns the connected user wallet, including its current
37+
budget balance. Resolves with <code>null</code> if no wallet
38+
is connected.
39+
</p>
40+
</section>
41+
</section>
1842
</section>

specification/extensions-api/section/types.html

Lines changed: 110 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,115 @@
11
<section id="types">
22
<h2>Types</h2>
33

4-
<section data-dfn-for="MonetizationInfo">
5-
<h3><dfn>MonetizationInfo</dfn></h3>
4+
<p class="note">
5+
Type names defined here are scoped under the
6+
<a>monetization</a> namespace. Implementations expose them as
7+
namespace-scoped dictionaries on `chrome.monetization`
8+
(for example, {{monetization/Wallet}} corresponds to
9+
`chrome.monetization.Wallet`).
10+
</p>
11+
12+
<section data-dfn-for="monetization/Wallet">
13+
<h3><dfn data-dfn-for="monetization">Wallet</dfn></h3>
614

715
<p>
8-
Describes the document where a monetization state change occurred.
16+
Describes the connected user wallet, including its current
17+
budget balance.
918
</p>
1019

1120
<pre class="idl">
12-
dictionary MonetizationInfo {
21+
enum ReconnectReason {
22+
"unauthorized"
23+
};
24+
25+
dictionary Wallet {
26+
required DOMString address;
27+
required DOMString name;
28+
required DOMString currency;
29+
required DOMString initialBalance;
30+
required DOMString remainingBalance;
31+
DOMString? renewDate;
32+
ReconnectReason? reconnectReason;
33+
};
34+
</pre>
35+
36+
<h4>Properties</h4>
37+
<dl>
38+
<dt><dfn>address</dfn></dt>
39+
<dd>
40+
The canonical wallet address URL, as returned in the `id`
41+
field of the Open Payments wallet address resource. This is
42+
the resolved address (e.g.
43+
`"https://ilp.example.com/123456/usd"`), which may differ
44+
from the URL the user originally entered (such as a
45+
`.well-known/pay` shortcut).
46+
</dd>
47+
48+
<dt><dfn>name</dfn></dt>
49+
<dd>
50+
A human-readable name for the wallet.
51+
</dd>
52+
53+
<dt><dfn>currency</dfn></dt>
54+
<dd>
55+
An ISO 4217 currency code (e.g. `"USD"`).
56+
</dd>
57+
58+
<dt><dfn>initialBalance</dfn></dt>
59+
<dd>
60+
A decimal string representing the total budget allocated for
61+
the current billing period (e.g. `"10.00"`).
62+
</dd>
63+
64+
<dt><dfn>remainingBalance</dfn></dt>
65+
<dd>
66+
A decimal string representing the budget remaining for the
67+
current billing period (e.g. `"7.50"`).
68+
</dd>
69+
70+
<dt><dfn>renewDate</dfn></dt>
71+
<dd>
72+
An ISO 8601 date string indicating when the budget next renews.
73+
Absent when the budget does not renew monthly.
74+
</dd>
75+
76+
<dt><dfn>reconnectReason</dfn></dt>
77+
<dd>
78+
When present, indicates that the wallet must be reconnected
79+
before it can be used, and conveys the reason. When absent,
80+
the wallet is usable. Possible values:
81+
<dl>
82+
<dt>`"unauthorized"`</dt>
83+
<dd>
84+
The stored access token is no longer valid (for example,
85+
it has expired or been revoked).
86+
</dd>
87+
</dl>
88+
</dd>
89+
</dl>
90+
91+
<p class="note">
92+
The {{Wallet/currency}}, {{Wallet/initialBalance}}, and
93+
{{Wallet/remainingBalance}} members use the same conventions as the
94+
`currency` and `value` members of the {{PaymentCurrencyAmount}}
95+
dictionary defined in [[payment-request]] (and the
96+
`MonetizationCurrencyAmount` interface in [[WebMonetization]]).
97+
</p>
98+
</section>
99+
100+
<section data-dfn-for="monetization/Session">
101+
<h3><dfn data-dfn-for="monetization">Session</dfn></h3>
102+
103+
<p>
104+
Identifies a monetization session and the document it belongs to.
105+
</p>
106+
107+
<pre class="idl">
108+
dictionary Session {
13109
required long tabId;
14110
required long frameId;
15-
required DOMString url;
111+
required long sessionId;
112+
required DOMString walletAddress;
16113
};
17114
</pre>
18115

@@ -26,12 +123,17 @@ <h4>Properties</h4>
26123
<dt><dfn>frameId</dfn></dt>
27124
<dd>
28125
The identifier of the frame within the tab.
29-
<code>0</code> denotes the top-level (main) frame.
126+
`0` denotes the top-level (main) frame.
127+
</dd>
128+
129+
<dt><dfn>sessionId</dfn></dt>
130+
<dd>
131+
The identifier of the monetization session.
30132
</dd>
31133

32-
<dt><dfn>url</dfn></dt>
134+
<dt><dfn>walletAddress</dfn></dt>
33135
<dd>
34-
The URL of the monetized document.
136+
The wallet address being paid by this session.
35137
</dd>
36138
</dl>
37139
</section>

specification/flows/section/storage.html

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@ <h3>Storage operations</h3>
9595
<li>Set |storage|'s {{Storage/wallet}} to |walletAddressDetails|.</li>
9696
<li>[=Persist storage=] with |storage|.</li>
9797
</ol>
98+
<p class="note">
99+
Each invocation of this algorithm establishes a new wallet connection. Implementations
100+
that track per-connection payment history SHOULD associate sessions and payments with
101+
the credential record created during this connection, so that balance computations are
102+
scoped to the active connection only.
103+
</p>
98104
</div>
99105

100106
<div class="algorithm">
@@ -166,6 +172,12 @@ <h3>Storage operations</h3>
166172
<li>[=Persist storage=] with |storage|.</li>
167173
</ol>
168174
<p class="note">Removes all wallet-related state (grant tokens, authentication keys, wallet address details). Budget limits MAY be retained; implementations can also clear {{Storage/maxRateOfPay}} if the user requests a full reset.</p>
175+
<p class="note">
176+
Implementations that track payment history SHOULD treat each wallet connection as an
177+
independent scope. When a user disconnects and later reconnects (even to the same wallet address),
178+
the new connection starts with a fresh spending balance. Previous connection data MAY be
179+
retained for historical display but MUST NOT affect the active connection's balance computation.
180+
</p>
169181
</div>
170182

171183
<div class="algorithm">

0 commit comments

Comments
 (0)