Closed marcoscaceres closed 1 year ago
@marcoscaceres I'll be taking a stab at implementing the changes proposed in the open pull requests. I was told we'd create a working impl to trial before merging those. For that next iteration, we'll probably want a PR for this too?
Has there been any further discussion on this (sorry, I've been a bit out of the loop due to health reasons)
Sorry, just coming back to this @sublimator! I'll try to catch up on your comments now...
Error could be the payment pointer or wallet is invalid. This would allow the developer to recover by providing a different payment payment pointer or wallet address with new shared secret.
@AlexLakatos, can you investigate on the protocol side what happens when the above occurs?
Would we want some error detail surfaced?
@marcoscaceres The payment pointer holds an Interledger address, and a shared secret. When a connection is set up via STREAM, if either of those can't be reached, it should fail, and the error should be surfaced I think.
@sublimator I think that particular case is the one where a developer can do something about it. I.e. the payment pointer was invalid for some reason, change the payment pointer.
Another error might be that the monetization agent runs out of possible connections.
"interactive" - processing payments.
@AlexLakatos You said as soon as a money packet was actually sent (but not fulfilled) on the wire would be a good time to switch to interactive ?
@marcoscaceres
Given we won't need a "previous" state, and the state is accessible via monetization.state will the "statechange" event actually need a property to hold the latest state ?
Some notes on the old states/events:
Before we settled on just pending | started | stopped
there was some talk about adding a paused
state, but we didn't really want to have too many states. However, there is one case where you want to know the difference between paused
and stopped
, and that is when the tag has been removed. The stream with that id can no longer be resumed!
We hacked a finalized: boolean
property to the monetizationstop
event.
People use it for things like react hooks, to reset counter and the like state: https://github.com/dacioromero/react-hook-wm/blob/3752faa311036cb056937729b89dc0328354d043/src/has-paid.tsx#L5-L11 https://github.com/coilhq/web-monetization-projects/blob/ed3cfb702ed625b6d73bbb1a128e72a2acb085b8/packages/webmonetization-react/src/global.ts#L97-L109 (Wish Github would inline these here as it does if the link is to the same repo!)
Would/should the statechanged
events hold the paymentPointer/requestId ?
Given we won't need a "previous" state, and the state is accessible via monetization.state will the "statechange" event actually need a property to hold the latest state ?
no. You would just do:
let previous = navigator.monetization.state;
navigator.monetization.onstatechange = ev => {
console.log(`was: ${previous}`, `is now: `${navigator.monetization.state}`);
previous = navigator.monetization.state;
}
Or directly via the event: event.target.state
. (target is the monetization
instance).
However, there is one case where you want to know the difference between paused and stopped, and that is when the tag has been removed. The stream with that id can no longer be resumed!
Right, but the web page make the same determination:
// something like, "no monetization" or "monetization, but no href attribute"
document.querySelector("link[rel='monetization']") === null || !document.querySelector("link[rel='monetization']:not([href])")
the web page make the same determination:
We did something like that before finalized
was added yeah.
iirc we wanted to make sure that the new tag href
: requestId
1:1 mapping was intact
and it just seemed a bit more convenient than digging around in the DOM
In the new proposed model:
You have a SPA.
You are currently streaming with requestId A
, it's "interactive"
You dynamically switch out the payment pointer
You will get a statechange event to idle
?
idle
could mean the user has "paused" the stream (manually ? or once a single packet has been sent, it's considered forever interactive
after ? )
or it could mean that a new payment pointer has been set and the stream is gearing up
Within the handler, you could check the DOM payment pointer has changed against the paymentPointer from the last progress event ? What if you didn't actually get one ? (depending on definition of interactive
)
Need to head out now. Would like to continue down this line of thought.
If SPSP errors can be handled while the <link>
element is loading, then we might not need any state changes at all... That means that code would now look like this:
<link rel="monetization" href="https://some.endpoint">
<script>
const el = document.querySelector("link[rel='monetization']")
// SPSP JSON-parsed and loaded ok
el.addEventLinstener("load", ev => {});
// Couldn't load SPSP
el.addEventLinstener("error", ev => {});
// Monetization event
navigator.monetization.addEvenListener("monetization", ev => {})
</script>
And that's it...
I think we might need a more complete state machine to reflect the state changes that the document and the monetization agent can go through. There is a lot of IPC that goes on between the web page and the WM agent, so a more complete state machine will help us keep things sane.
We need to map this out, but I think:
<link disabled>
.We can surface these through
monetization.state
, and we should pair these with simple"statechange"
events paired with.onstatechange
.The "progress" events only fire when in the interactive state.