Remember, at any time you can read the full Plugin API Documentation on GitHub.
The plugin will emit four key events:
start
stop
pending
progress
You can listen for each of these from your game code because the Game Web Monetization Plugin is an Event Emitter. This means you can use the following methods directly on the plugin:
once('event-name', eventHandler, context);
on('event-name', eventHandler, context);
off('event-name', eventHandler, context);
If you prefer to be more verbose, you can use addListener
instead of on
and removeListener
instead of off
. We will use the short version in the following code.
The START Event
This event is emitted when Web Monetization API is successfully started.
To use it, you can bind your own listener to the GameWebMonetization.START
event:
gameWebMonetization.on(GameWebMonetization.START, (event) => {
// Your handler
});
Tip: Remember to do this before calling start()
on the plugin!
To test this, let's make it log out some information to the console when the event fires, so we can observe what it returns in our browser Dev Tools:
Add the following code to your main.js
file, before you call gameWebMonetization.start()
:
gameWebMonetization.on(GameWebMonetization.START, (event) => {
console.log(event);
});
If you now test this, you should see the following in your Dev Tools console:
The event handler is sent an object that contains the following properties:
property | details |
---|---|
paymentPointer |
Your payment account URL. The same value is used as the content in your tag. |
requestId |
This value is identical to the session ID/monetization ID (UUID v4) generated by the user agent . |
You may have noticed we've been sent both paymentPointer
and a requestId
.
You can use the start
event to know that your game is being monetized. At this point you could show a message to the player, thanking them, or perhaps unlocking some extra content.
Important: Every time you change the browser window, or swap to another browser tab, the monetization stops. When the player returns to the window, the start
event will be fired again. So be aware of this flow in your game code and handle it appropriately.
isMonetized
The start
event is useful to know when monetization begins, but what if you want to check if your game is monetized or not somewhere deeper in your code?
For this, you can use the isMonetized
boolean property.
This property can be checked at any point in your game and provides a simple true/false response to the question "Has this player monetized my game?"
Let's test this by modifying our main.js
to console log the state of the property before and after the start
event:
var gameWebMonetization = new GameWebMonetization({
paymentPointer: '$ilp.uphold.com/zdXzL8aWJ4ii'
});
gameWebMonetization.start();
// New code:
console.log('Is monetized? ', gameWebMonetization.isMonetized);
// New code:
gameWebMonetization.on(GameWebMonetization.START, (event) => {
console.log('[inside event start] - Is monetized? ', gameWebMonetization.isMonetized);
});
If you test this code you'll see that before the monetization starts the property is false
and it switches to true
after the start
event has fired:
You you can check the isMonetized
property at any point in your game. It is kept up to date internally by the plugin, so is safe to use to perhaps award the player a special prize or in-game benefit.
Knowing the current State
The plugin goes through different states in its life-cycle:
- started - The plugin has been successfully started and is monetising your content.
- stopped - The plugin is currently stopped and not monetising your content.
- pending - The plugin has been asked to start and is currently trying to negotiate the start-up, but hasn't yet completed this step.
To know the current state you can query the state
property.
Let's do the same as we did with isMonetized
to view the state
. Here is an updated main.js
to test this:
import { GameWebMonetization } from './GameWebMonetization.js';
var gameWebMonetization = new GameWebMonetization({
paymentPointer: '$ilp.uphold.com/zdXzL8aWJ4ii'
});
gameWebMonetization.start();
// New code
console.log('The state: ', gameWebMonetization.state);
gameWebMonetization.on(GameWebMonetization.START, (event) => {
// New code
console.log('[inside event start] - The state: ', gameWebMonetization.state);
});
And in the console you will see the following:
Access to the plugins state is handy for internal debugging.
The PENDING Event
This event is emitted while the Web Monetization API is preparing to start to monetize your site. This happens after you call the start
method on the plugin. The API will enter a state of 'pending', meaning it's currently negotiating to start with your Payment Pointer, but hasn't finished doing so yet. If the negotiation is successful, then the plugin will emit its START
event.
Let's edit our main.js
to demonstrate this state:
import { GameWebMonetization } from './GameWebMonetization.js';
var gameWebMonetization = new GameWebMonetization({
paymentPointer: '$ilp.uphold.com/zdXzL8aWJ4ii'
});
gameWebMonetization.start();
console.log('The state: ', gameWebMonetization.state);
// New code
gameWebMonetization.on(GameWebMonetization.PENDING, (event) => {
console.log('[inside event pending] - The state: ', gameWebMonetization.state);
});
gameWebMonetization.on(GameWebMonetization.START, (event) => {
console.log('[inside event start] - The state: ', gameWebMonetization.state);
});
If we go to the browser we will see the following:
Looking at the console logs you can see the API flow in action.
If there is a problem connecting to your Payment Pointer then the flow would be PENDING
followed by the STOP
event. If the connection was successful the flow would be PENDING
followed by the START
event.
If there is a network error, for example wifi drops out, while the request is still PENDING
then it will remain in this state indefinitely, never reaching the STOP
event. So always use the isMonetized
boolean in your game code to be aware of the current state of monetization.
The PROGRESS Event
When the Web Monetization API successfully connects to your Payment Pointer it will start to stream micropayments into your wallet. Each time this happens it will fire a PROGRESS
event.
This event contains lots of useful data, including how much was just streamed to your wallet and you can use it in your game to keep track of the payment stream, or perhaps use it to visually show a special animation or similar.
You can use the event like this:
gameWebMonetization.on(GameWebMonetization.PROGRESS, (event) => {
console.log('Progress: ', event);
});
Add the above into your main.js
and check it from a browser. Open the console to view the output:
This event gives us lots of useful properties:
property | details |
---|---|
paymentPointer |
Your payment account URL. The same value is used as the content in your tag. |
requestId |
This value is identical to the session ID/monetization ID (UUID v4) generated by the user agent. |
amount |
The destination amount received as specified in the Interledger protocol (ILP) packet. |
assetCode |
The code (typically three characters) identifying the amount's unit. A unit, for example, could be a currency (USD, XRP). |
assetScale |
The number of places past the decimal for the amount. For example, if you have USD with an asset scale of two, then the minimum divisible unit is cents. |
receipt |
base64-encoded STREAM receipt issued by the Web Monetization receiver to the Web Monetization provider as proof of the total amount received in the stream. |
totalAmount |
the sum of what has been received with the current paymentPointer, if the paymentPointer is changed this amount will be reset. |
As you can see, that's a lot of handy data!
Perhaps the most interesting properties are assetCode
and totalAmount
. The assetCode
is the type of currency we are receiving, in this case it is the XRP crypto currency. Even though your wallet may not be set for XRP this is the main currency Uphold transfers in. Don't worry, though, you will receive your actual desired currency in your wallet. If you are using a provider other than Uphold, then you should see that the currency matches that set in your wallet.
The totalAmount
is the amount of income that we have obtained so far from the player during this play session. This counter is reset if the page containing your game is refreshed. It doesn't persist longer than a single play session.
As its name implies, the PROGRESS
event helps you keep track of the monetization process at all times. Because the stream of payments to your wallet is constant this event is fired many times. During testing we saw it fired every 2 seconds that the game was running, but the actual frequency may be higher or lower than this. So be careful with what your game does as a result of this event!
Rather than hooking this event to say an in-game animation, you may be better off aggregating the information within it, then using that from your own timed in-game events.
The total
property
As we saw, the PROGRESS
event gives us lots of handy data. The plugin offers you a total
property that keeps track of the total amount of payments a player has streamed to your wallet during their play session.
This value persists even if they tab out to another application and then come back to your game.
You can access the total
at any point via the plugin instance:
const currentTotal = gameWebMonetization.total;
The currency of the total
will vary based on the wallet service you are using. Uphold, as we're using here, uses XRP and then converts it into your chosen currency their end. However, other wallet services will transmit via the Interledger protocol in the actual currency of your wallet.
This currency can be obtained via the assetCode
property sent by the PROGRESS
event. If it doesn't match that of your wallet, it's likely using XRP as an exchange currency. You can work out how much you've actually received, in your chosen currency, by using the assetScale
property.
The STOP Event
Finally, we have the STOP
event. This event is emitted when the API enters a stopped state. This could be from you calling the plugins stop
method, or by the user stopping the payment via their browser by performing an action such as switching to another browser tab or window.
You listen for it in the same way as the other events. Let's modify our main.js
to handle this:
gameWebMonetization.on(GameWebMonetization.STOP, (event) => {
console.log('[inside event stop] - The state: ', gameWebMonetization.state);
});
Once the event handler is created it will be emitted if we call the stop
method, or switch to another browser tab.
Try running the above and then swapping in and out of the tab a few times. You should see a STOP
event for each time you do this:
Alternatively, we could fake this action by using setTimeout
to call the stop
method for us, like in the following code:
gameWebMonetization.on(GameWebMonetization.STOP, (receive) => {
console.log('[inside event stop] - The state: ', gameWebMonetization.state);
});
setTimeout(() => {
gameWebMonetization.stop();
}, 5000);
Now, if you go to the console you will see that the progress event is emitted and then the plugin stops after 5 seconds.
You can use the STOP
event to know when monetization has stopped. Just remember that it's entirely possible it will start again, i.e. if they swapped tab or application.
Change the Payment Pointer
If you need to change the Payment Pointer your game is using, you can call the changePaymentPointer
method.
Simply call the method and pass it a new configuration object:
gameWebMonetization.changePaymentPointer({
paymentPointer: '$ilp.uphold.com/ziW6E7iwKUkp',
pointerName: "Alice"
});
gameWebMonetization.restart();
Calling changePaymentPointer()
only prepares the plugin for the change, but doesn't make it. For that, you need to call the restart()
method, as in the example code above.
Payment Pointers can also be provided as a weighted array. This allows you to take advantage of probabilistic revenue sharing, which we'll cover in the next part of the tutorial.