-
Notifications
You must be signed in to change notification settings - Fork 1
session-flow: add session initiation/termination sections #17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,54 +1,214 @@ | ||
| <section id="session-flow"> | ||
| <h2>Session Flow</h2> | ||
| <h2>Session flow</h2> | ||
|
|
||
| <p> | ||
| This section describes the payment session flow that occurs when a user visits a [=web monetized website=]. | ||
| The session flow involves establishing a payment session, managing ongoing payments, and handling session lifecycle events. | ||
| </p> | ||
|
|
||
| <section> | ||
| <h3>Session lifecycle</h3> | ||
| <p> | ||
| This section defines when sessions are created and ended. It specifies the triggers that invoke the | ||
| [[[#session-initiation]]] and [[[#session-termination]]] algorithms defined later in this section. | ||
| </p> | ||
|
|
||
| <p> | ||
| When a {{Document}} becomes [=Document/fully active=], the user agent MUST | ||
| [=initiate document-wide sessions=]. | ||
| If a {{Document}} becomes not [=Document/fully active=], the user agent MUST | ||
| [=end sessions for document=] for it and all of its [=child navigables=]. | ||
| </p> | ||
|
|
||
| <p> | ||
| This section describes the payment session flow that occurs when a user visits a [=web monetized website=]. | ||
| The session flow involves establishing a payment session, managing ongoing payments, and handling session lifecycle events. | ||
| When the user starts interacting with a [=media element=], the user agent SHOULD | ||
| [=initiate media-scoped sessions=] given that element; when the user stops interacting, the user agent | ||
| SHOULD [=end sessions scoped to=] that element. | ||
| </p> | ||
|
|
||
| <h3>Session Flow Overview</h3> | ||
| <p> | ||
| When a user navigates to a web monetized website, the browser initiates a payment session flow that includes: | ||
| If any of the conditions defined in the | ||
| <a href="https://webmonetization.org/specification/#link-type-monetization">link fetch and processing timing</a> | ||
| cause a monetization link element to be reprocessed, the user agent MUST [=end session=] for the session | ||
| associated with that element (if any) and then [=initiate a session=] for that element. | ||
| </p> | ||
| <ul> | ||
| <li>Discovery of payment endpoints.</li> | ||
| <li>Session establishment.</li> | ||
| <li>Payment streaming.</li> | ||
| <li>Session management and cleanup.</li> | ||
| </ul> | ||
|
|
||
| <h3>Session Initiation</h3> | ||
| <p> | ||
| The payment session begins when the browser detects a monetization link element on a webpage. | ||
| The browser must validate the [=wallet address=] and establish a connection with the configured wallet. | ||
| The user agent maintains an [=active sessions list=] to track all currently running monetization sessions. | ||
| Each session in this list corresponds to a monetization link element and contains the information needed | ||
| to distribute payments to the website's wallet. | ||
| </p> | ||
|
|
||
| <p>To initiate a payment session, given a <var>walletAddress</var>:</p> | ||
| <ol> | ||
| <li>Validate the [=wallet address=] format.</li> | ||
| <li>Check if a wallet is configured and available.</li> | ||
| <li>Establish a payment session with the wallet.</li> | ||
| <li>Begin payment streaming to the [=wallet address=].</li> | ||
| </ol> | ||
| <dl> | ||
| <dt><dfn>active sessions list</dfn></dt> | ||
| <dd> | ||
| A user agent maintained ordered list of {{Session}} records created by [=initiate a session=]. | ||
| </dd> | ||
| </dl> | ||
| </section> | ||
|
|
||
| <h3>Payment Streaming</h3> | ||
| <section> | ||
| <h3>Session initiation</h3> | ||
| <p> | ||
| Once a session is established, the browser manages the ongoing payment stream according to the configured budget and rate limits. | ||
| This section defines the algorithms for initiating payment sessions at various scopes—document-wide, | ||
| media-scoped, or for individual monetization link elements. Session initiation discovers website wallet details, | ||
| negotiates authorization, creates an incoming payment, and registers a session record in the [=active sessions list=]. | ||
| </p> | ||
|
|
||
| <h3>Session Lifecycle Management</h3> | ||
| <div class="algorithm"> | ||
| <p>To <dfn>initiate document-wide sessions</dfn> given a |document:Document|, run these steps:</p> | ||
| <ol> | ||
| <li>If the result of [=get user wallet=] is null, then return.</li> | ||
| <li>[=initiate sessions scoped to=] the [^head^] element of |document|.</li> | ||
| <li>For each [=child navigable=] of |document|, recursively [=initiate document-wide sessions=].</li> | ||
| </ol> | ||
| </div> | ||
|
|
||
| <div class="algorithm"> | ||
| <p>To <dfn>initiate media-scoped sessions</dfn> given a |media:HTMLElement|, run these steps:</p> | ||
| <ol> | ||
| <li>If the result of [=get user wallet=] is null, then return.</li> | ||
| <li>[=initiate sessions scoped to=] |media|.</li> | ||
| </ol> | ||
| </div> | ||
|
|
||
| <div class="algorithm"> | ||
| <p>To <dfn>initiate sessions scoped to</dfn> the |root:HTMLElement|, run these steps:</p> | ||
| <ol> | ||
| <li>Let |document:Document| be the {{Node/ownerDocument}} of |root|.</li> | ||
| <li>If [=document monetization disabled=] given |document|, then return.</li> | ||
| <li>Let |linkElements:NodeList| be all [^link^] elements with `rel="monetization"` that are descendants of |root|.</li> | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we include There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it looks like initiate a session alg is the right place |
||
| <li>For each |linkElement:HTMLLinkElement| in |linkElements|, [=initiate a session=] given |linkElement|.</li> | ||
| </ol> | ||
| </div> | ||
|
|
||
| <div class="algorithm"> | ||
| <p>To <dfn>initiate a session</dfn>, given |linkElement:HTMLLinkElement|, perform the following steps:</p> | ||
| <ol> | ||
| <li>If |linkElement| has [^link/disabled^] attribute, then return.</li> | ||
| <li> | ||
| Let |websiteWalletAddress:DOMString| be the value of the {{HTMLLinkElement/href}} of |linkElement|. | ||
| </li> | ||
| <li> | ||
| If [=wallet monetization restricted=] given |document| and |websiteWalletAddress|, then return. | ||
| </li> | ||
| <li> | ||
| Let |websiteWalletDetails:WalletAddressDetails?| be the result of [=send a wallet address request=] with |websiteWalletAddress|. | ||
| </li> | ||
| <li> | ||
| If |websiteWalletDetails| is null, fire an `error` event on |linkElement| and return. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At what stage CSP is handled? Will a CSP error also result in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's part of [=wallet monetization restricted=] of the "initiate a session" alg. Not quite sure if we should keep silent or send an error. Do you want me to send an issue on this one? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's keep the same behavior as with other link tags. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. apparently it varies from browser to browser, it seems all are agree that error is reported in console such as "Content-Security-Policy: The page’s settings blocked a style (style-src-elem) at https://example.com/blocked.css from being applied because it violates the following directive: “style-src 'self'”, but nothing else in Firefox. Chromium fires error event. It's weird but apparently it's implementation dependent. Do you think we should reflect that somehow in the spec? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd rather file an interop bug and see what browsers agree on. But adding a note here would be good as well. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
right, do you know what's a typical procedure for this (cc'ing @lukewarlow ) |
||
| </li> | ||
| <li> | ||
| Fire a `load` event on |linkElement|. | ||
| </li> | ||
| <li> | ||
| Let |incomingPaymentGrant:Grant?| be the result of [=send an incoming payment grant request=] with |websiteWalletDetails|. | ||
| </li> | ||
| <li> | ||
| If |incomingPaymentGrant| is null, return. | ||
| </li> | ||
| <li> | ||
| Let |incomingPaymentId:DOMString?| be the result of [=send a create incoming payment request=] with |websiteWalletDetails|, and |incomingPaymentGrant|. | ||
| </li> | ||
| <li> | ||
| If |incomingPaymentId| is null, return. | ||
| </li> | ||
| <li> | ||
| Let |continueUri:DOMString| be |incomingPaymentGrant|.{{Grant/continue}}.{{Continue/uri}}. | ||
| </li> | ||
| <li> | ||
| Let |accessToken:DOMString| be |incomingPaymentGrant|.{{Grant/continue}}.{{Continue/access_token}}.{{ContinueAccessToken/value}}. | ||
| </li> | ||
| <li> | ||
| [=Send a cancel grant request=] with |continueUri| and |accessToken|. | ||
| <p class="note">The incoming payment grant is no longer needed after the payment bucket has been created. Canceling it ensures proper cleanup and revokes the authorization. Implementations should handle cancellation failures gracefully but can proceed with the session even if cancellation fails, as the grant will expire naturally.</p> | ||
| </li> | ||
| <li> | ||
| Let |session:Session| be a new {{Session}} with: | ||
| <ul> | ||
| <li>{{Session/linkElement}} set to |linkElement|</li> | ||
| <li>{{Session/walletDetails}} set to |websiteWalletDetails|</li> | ||
| <li>{{Session/incomingPaymentId}} set to |incomingPaymentId|</li> | ||
| </ul> | ||
| </li> | ||
| <li> | ||
| Append |session| to the [=active sessions list=]. | ||
| </li> | ||
| <li> | ||
| If this is the first active session, [=start payment streaming loop=]. | ||
| </li> | ||
| </ol> | ||
| </div> | ||
|
|
||
| <aside class="note" title="Session initiation summary"> | ||
| <p>The main [=initiate a session=] algorithm performs these key steps:</p> | ||
| <ol> | ||
| <li><strong>Preconditions:</strong> Verify user wallet exists and monetization is permitted</li> | ||
| <li><strong>Discovery:</strong> Request website wallet address details, | ||
| firing `load` event on success or `error` event on failure</li> | ||
| <li><strong>Authorization:</strong> Obtain an incoming payment grant to create payments on the website's wallet</li> | ||
| <li><strong>Payment setup:</strong> Create an incoming payment (payment bucket) on the website's wallet resource server</li> | ||
| <li><strong>Cleanup:</strong> Cancel the temporary incoming payment grant (no longer needed)</li> | ||
| <li><strong>Registration:</strong> Add the session to the active sessions list and | ||
| start the payment streaming loop if this is not yet started</li> | ||
| </ol> | ||
| </aside> | ||
| </section> | ||
|
|
||
| <section> | ||
| <h3>Session termination</h3> | ||
| <p> | ||
| The browser must handle various session lifecycle events including: | ||
| This section defines the algorithms for ending payment sessions at various scopes—document-wide, | ||
| media-scoped, or for individual monetization link elements. Session termination removes session records | ||
| from the [=active sessions list=] and cancels scheduled payment work. | ||
| </p> | ||
| <ul> | ||
| <li>Session pause and resume.</li> | ||
| <li>Tab focus changes.</li> | ||
| <li>Page navigation.</li> | ||
| <li>Wallet disconnection.</li> | ||
| <li>Budget exhaustion.</li> | ||
| </ul> | ||
|
|
||
| <h3>Error Handling</h3> | ||
| <div class="algorithm"> | ||
| <p>To <dfn>end sessions for document</dfn>, given a |document:Document|, run these steps:</p> | ||
| <ol> | ||
| <li>[=End sessions scoped to=] the [^head^] element of |document|.</li> | ||
| <li>For each [=child navigable=] of |document|, recursively [=end sessions for document=].</li> | ||
| </ol> | ||
| </div> | ||
|
|
||
| <div class="algorithm"> | ||
| <p>To <dfn>end sessions scoped to</dfn> the |root:HTMLElement|, run these steps:</p> | ||
| <ol> | ||
| <li>Let |linkElements:NodeList| be all [^link^] elements with `rel="monetization"` that are descendants of |root|.</li> | ||
| <li>For each |linkElement:HTMLLinkElement| in |linkElements|: | ||
| <ol> | ||
| <li>Let |session:Session| be the session record in the [=active sessions list=] whose {{HTMLLinkElement}} is |linkElement|, or null if none exists.</li> | ||
| <li>If |session| is not null, [=end session=] given |session|.</li> | ||
| </ol> | ||
| </li> | ||
| </ol> | ||
| </div> | ||
|
|
||
| <div class="algorithm"> | ||
| <p>To <dfn>end session</dfn>, given a session record |session:Session|, run these steps:</p> | ||
| <ol> | ||
| <li>Remove |session| from the [=active sessions list=].</li> | ||
| <li>The user agent MUST cancel any scheduled payment work for |session|.</li> | ||
| </ol> | ||
| </div> | ||
| </section> | ||
|
|
||
| <section> | ||
| <h3>Payment streaming</h3> | ||
| <p> | ||
| Once a session is established, the browser manages the ongoing payment stream according to the configured budget and rate limits. | ||
| </p> | ||
|
|
||
| <div class="algorithm"> | ||
| <p>To <dfn>start payment streaming loop</dfn>, run these steps:</p> | ||
| <ol> | ||
| <li> | ||
| </li> | ||
| </ol> | ||
| </div> | ||
|
|
||
| <p> | ||
| The session flow must gracefully handle various error conditions and provide appropriate feedback to both the website and the user. | ||
| The session flow must gracefully handle various error conditions and provide appropriate feedback to both the website and the user. | ||
| </p> | ||
| </section> | ||
| </section> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| <section id="monetization-status"> | ||
| <h2>Monetization status</h2> | ||
|
|
||
| <p> | ||
| User agents SHOULD provide controls to disable Web Monetization completely and on a per-[=origin=] | ||
| basis via a wallet management interface. User agents SHOULD provide a user interface that allows | ||
| users to view and adjust these preferences. | ||
| </p> | ||
|
|
||
| <p> | ||
| A website can disable Web Monetization for itself and/or its subdocuments by setting | ||
| the <a href="https://webmonetization.org/developers/permissions-policy-monetization/">`monetization`</a> | ||
| [=policy-controlled feature=]. | ||
| </p> | ||
|
|
||
| <p> | ||
| A website can also restrict Web Monetization to <a>wallet addresses</a> of certain [=origin=]s | ||
| by using the <a href="https://webmonetization.org/developers/csp-monetization-src/">`monetization-src`</a> | ||
asurkov marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| directive in the [=content security policy=]. | ||
| </p> | ||
|
|
||
| <section id="monetization-is-disabled"> | ||
| <h3>Document monetization restrictions</h3> | ||
|
|
||
| <p> | ||
| <dfn data-lt="document monetization disabled">Document monetization disabled</dfn> | ||
| given a |document:Document| if either of the following conditions apply: | ||
| </p> | ||
|
|
||
| <ul> | ||
| <li> | ||
| The user preferences specify that Web Monetization is either completely disabled or disabled specifically | ||
| for the [=Document/origin=] of the |document|. | ||
| </li> | ||
| <li> | ||
| The |document| is not [=allowed to use=] | ||
| the <a href="https://webmonetization.org/developers/permissions-policy-monetization/">`monetization`</a> | ||
| [=policy-controlled feature=]. | ||
| </li> | ||
| </ul> | ||
| </section> | ||
|
|
||
| <section id="monetization-is-disabled-for-wallet"> | ||
| <h3>Wallet address restrictions</h3> | ||
|
|
||
| <p> | ||
| <dfn data-lt="wallet monetization restricted">Wallet monetization restricted</dfn> | ||
| given a |document:Document| and a [=wallet address=] |walletAddress:DOMString| | ||
| if the <a href="https://webmonetization.org/developers/csp-monetization-src/">`monetization-src`</a> directive | ||
| in the [=content security policy=] of the |document| restricts the |walletAddress|'s [=origin=]. | ||
| </p> | ||
| </section> | ||
|
|
||
| <p class="note"> | ||
| These mechanisms provide multiple layers of control over Web Monetization: the user controls whether | ||
| monetization is enabled in their browser, the website can control whether monetization is allowed | ||
| via permissions policy, and the website can restrict which wallet addresses are allowed | ||
| via content security policy. All three mechanisms work together to ensure monetization only occurs when all parties consent. | ||
| </p> | ||
| </section> | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We would eventually need to define what counts as "interacting".
For video and audio elements, mostly simple when on tab. Otherwise, with video, we've picture-in-picture; and with audio, we've background audio.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed, shall I file an issue for this?