Skip to content

Commit e0c2255

Browse files
authored
session-flow: add session payment algorithms structure (#22)
1 parent b77efe9 commit e0c2255

File tree

2 files changed

+119
-8
lines changed

2 files changed

+119
-8
lines changed

section/algorithms.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -711,7 +711,7 @@ <h4>Create outgoing payment</h4>
711711
given |userWalletAddressDetails:WalletAddressDetails|,
712712
|incomingPaymentId:DOMString|,
713713
|debitAmountValue:DOMString|,
714-
|outgoingPaymentGrant:Grant|, perform the following steps.
714+
and |outgoingPaymentGrant:Grant|, perform the following steps.
715715
<ol>
716716
<li>
717717
Let |resourceServer:URL| be the result of running [=URL parser=] with

section/session-flow.html

Lines changed: 118 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@ <h3>Session lifecycle</h3>
4444
<dd>
4545
A user agent maintained ordered list of {{Session}} records created by [=initiate a session=].
4646
</dd>
47+
<dt><dfn>current session iterator</dfn></dt>
48+
<dd>
49+
A user agent maintained iterator that points to the next {{Session}} in the [=active sessions list=] to be processed for payment.
50+
This iterator is used to implement round-robin session processing,
51+
ensuring fair distribution of payment attempts across all active sessions.
52+
When the [=active sessions list=] is empty, the iterator is set to a special <dfn>end iterator</dfn> value
53+
that represents a position past the last element in the list.
54+
</dd>
4755
</dl>
4856
</section>
4957

@@ -135,7 +143,11 @@ <h3>Session initiation</h3>
135143
Append |session| to the [=active sessions list=].
136144
</li>
137145
<li>
138-
If this is the first active session, [=start payment streaming loop=].
146+
If this is the first active session:
147+
<ol>
148+
<li>Set the [=current session iterator=] to point to |session|.</li>
149+
<li>[=Schedule payment streaming tick=].</li>
150+
</ol>
139151
</li>
140152
</ol>
141153
</div>
@@ -187,7 +199,18 @@ <h3>Session termination</h3>
187199
<div class="algorithm">
188200
<p>To <dfn>end session</dfn>, given a session record |session:Session|, run these steps:</p>
189201
<ol>
190-
<li>Remove |session| from the [=active sessions list=].</li>
202+
<li>If |session| is the only session in the [=active sessions list=]:
203+
<ol>
204+
<li>Remove |session| from the [=active sessions list=].</li>
205+
<li>Set the [=current session iterator=] to the [=end iterator=].</li>
206+
</ol>
207+
</li>
208+
<li>Otherwise:
209+
<ol>
210+
<li>If the [=current session iterator=] points to |session|, [=select next session for payment=].</li>
211+
<li>Remove |session| from the [=active sessions list=].</li>
212+
</ol>
213+
</li>
191214
<li>The user agent MUST cancel any scheduled payment work for |session|.</li>
192215
</ol>
193216
</div>
@@ -200,15 +223,103 @@ <h3>Payment streaming</h3>
200223
</p>
201224

202225
<div class="algorithm">
203-
<p>To <dfn>start payment streaming loop</dfn>, run these steps:</p>
226+
<p>To <dfn>schedule payment streaming tick</dfn>, run these steps:</p>
204227
<ol>
205-
<li>
228+
<li>Let |userWallet:UserWallet| be the result of [=get user wallet=].</li>
229+
<li>If |userWallet| is null, then return.</li>
230+
<li>If the [=active sessions list=] is empty, then return.</li>
231+
<li>Let |delay:DOMHighResTimeStamp| be the result of [=compute payment delay=].</li>
232+
<li>Schedule a task that, after |delay| has elapsed, will [=run payment streaming tick=].</li>
233+
</ol>
234+
</div>
235+
236+
<div class="algorithm">
237+
<p>To <dfn>run payment streaming tick</dfn>, run these steps:</p>
238+
<ol>
239+
<li>If the [=active sessions list=] is empty, then return.</li>
240+
<li>Let |session:Session| be the session pointed to by the [=current session iterator=].</li>
241+
<li>[=Select next session for payment=].</li>
242+
<li>[=Process session for payment=] given |session|.</li>
243+
</ol>
244+
</div>
245+
246+
<div class="algorithm">
247+
<p>To <dfn>select next session for payment</dfn>, run these steps:</p>
248+
<ol>
249+
<li>If the [=active sessions list=] is empty, then set the [=current session iterator=] to the [=end iterator=].</li>
250+
<li>Otherwise, if the [=current session iterator=] is not at the [=end iterator=],
251+
then advance the [=current session iterator=] to the next session in the [=active sessions list=].</li>
252+
<li>If the [=current session iterator=] is at the [=end iterator=],
253+
then set the [=current session iterator=] to point to the first session in the [=active sessions list=].</li>
254+
</ol>
255+
</div>
256+
257+
<div class="algorithm">
258+
<p>To <dfn>process session for payment</dfn>, given |session:Session|, run these steps:</p>
259+
<ol>
260+
<li>Let |userWallet:UserWallet| be the result of [=get user wallet=].</li>
261+
<li>If |userWallet| is null, then return.</li>
262+
<li>If |session| is not in the [=active sessions list=], then return.</li>
263+
<li>Let |amount:PaymentCurrencyAmount| be the result of [=compute payment amount=] given |session|.</li>
264+
<li>Let |amountValue:DOMString| be |amount|'s {{PaymentCurrencyAmount/value}}.</li>
265+
<li>Let |userWalletGrant:Grant| be |userWallet|'s {{UserWallet/outgoingPaymentGrant}}.</li>
266+
<li>Let |result:OutgoingPaymentResult| be the result of [=send a create outgoing payment request=]
267+
with |userWallet|'s {{UserWallet/walletAddressDetails}}, |session|'s {{Session/incomingPaymentId}},
268+
|amountValue|, and |userWalletGrant|.</li>
269+
<li>If |result| is {{OutgoingPaymentResult/"success"}}:
270+
<ol>
271+
<li>[=Fire monetization event=] given |session|, |amount|, and |userWallet|.</li>
272+
<li>[=Schedule payment streaming tick=].</li>
273+
<li>Return.</li>
274+
</ol>
275+
</li>
276+
<li>Otherwise:
277+
<ol>
278+
<li>TODO: Handle token rotation and other failure cases.</li>
279+
</ol>
206280
</li>
207281
</ol>
208282
</div>
209283

210-
<p>
211-
The session flow must gracefully handle various error conditions and provide appropriate feedback to both the website and the user.
212-
</p>
284+
<div class="algorithm">
285+
<p>To <dfn>fire monetization event</dfn>, given |session:Session|, |amount:PaymentCurrencyAmount|, and |userWallet:UserWallet|, run these steps:</p>
286+
<ol>
287+
<li>Let |assetScale:long| be |userWallet|.{{UserWallet/walletAddressDetails}}.{{WalletAddressDetails/assetScale}}.</li>
288+
<li>Let |assetCode:DOMString| be |userWallet|.{{UserWallet/walletAddressDetails}}.{{WalletAddressDetails/assetCode}}.</li>
289+
<li>Let |decimalAmount:DOMString| be the result of [=convert scaled amount to decimal=] given |amount|.{{PaymentCurrencyAmount/value}} and |assetScale|.</li>
290+
<li>Fire a [=monetization event=] on |session|.{{Session/linkElement}} with:
291+
<ul>
292+
<li>{{MonetizationEvent/amountSent}}.{{MonetizationCurrencyAmount/currency}} set to |assetCode|</li>
293+
<li>{{MonetizationEvent/amountSent}}.{{MonetizationCurrencyAmount/value}} set to |decimalAmount|</li>
294+
<li>{{MonetizationEvent/paymentPointer}} set to |session|.{{Session/walletDetails}}.{{WalletAddressDetails/id}}</li>
295+
<li>{{MonetizationEvent/incomingPayment}} set to |session|.{{Session/incomingPaymentId}}</li>
296+
</ul>
297+
</li>
298+
</ol>
299+
</div>
300+
301+
<div class="algorithm">
302+
<p>To <dfn>compute payment amount</dfn>, given |session:Session|, run these steps:</p>
303+
<ol>
304+
<li>TODO</li>
305+
</ol>
306+
</div>
307+
308+
<div class="algorithm">
309+
<p>To <dfn>compute payment delay</dfn>, run these steps:</p>
310+
<ol>
311+
<li>TODO</li>
312+
</ol>
313+
</div>
314+
315+
<div class="algorithm">
316+
<p>To <dfn>convert scaled amount to decimal</dfn>, given |scaledAmount:long long| and |assetScale:long|, run these steps:</p>
317+
<ol>
318+
<li>Let |divisor:double| be <code>Math.pow(10, |assetScale|)</code>.</li>
319+
<li>Let |decimalValue:double| be |scaledAmount| divided by |divisor|.</li>
320+
<li>Return a string representation of |decimalValue| formatted with |assetScale| decimal places.</li>
321+
</ol>
322+
<p class="note">For example, <code>convert scaled amount to decimal(100, 2)</code> returns <code>"1.00"</code>.</p>
323+
</div>
213324
</section>
214325
</section>

0 commit comments

Comments
 (0)