QR scanning is an engaging way to have users interact with payloads, especially in physical mediums. It is simple, quick, and versatile.
Benefits of QR Scanning:
Use Cases: QR scanning is common in retail scenarios or multi-device interactions. It is perfect for physical interaction, Point-of-sale terminals, or when users interact across devices (desktop to mobile).
Multi-Device Scenarios: In cases like desktop to mobile, users can scan the QR code on the desktop screen with their mobile device. Typically, there's no need for a return URL as the desktop browser can pick up the results.
How It Works: Generate a QR code for the payload using Xumm. Users scan this QR code with the Xumm app to access and interact with the payload.
User Perspective:
For end users, QR scanning is intuitive and engaging. They scan the QR code with their mobile device and are immediately taken to the payload in the Xumm app. This method is particularly effective in retail environments or when users operate across multiple devices.
Mobile (iOS/Android)
Mobile payload delivery is essential for a seamless experience in mobile applications.
Payload delivery from your native iOS / Android app happens through "Deep Links".
Deep Linking allows your mobile app to communicate directly with the Xumm app, enabling users to interact with payloads effortlessly.
For a detailed guide on implementing mobile payload delivery through Deep Linking, please refer to the Deep Linking page.
Desktop browser
For web applications accessed through desktop browsers, Xumm provides an optimized delivery method.
This includes options like QR code scanning and deep linking, adapted for larger screens.
If you can't already identify the user, refer to the QR Scanning
If you have already identified the user and obtained a user_token, refer to the Push
Limitations
Xumm.helpers { … }
Examples / User stories
SDK (syntax)
Developers can use the Xumm SDK to easily interact with the Xumm platform. This section contains the technical documentation for the Javascript/TypeScript API (objects, methods, arguments).
Developer Education
If you want to learn more about the XRP Ledger first (concepts, transaction types, etc.) we have a great resource for you at https://learn.xumm.dev:
Payloads (sign requests)
Xumm Payloads: creating, delivering, and utilizing incomplete XRP Ledger transactions as a Sign Request to end users.
The difference between XRP Ledger Transaction JSON and a Xumm Payload is that the XRP Ledger JSON needs to be complete and signed locally, while a Xumm Payload can contain an incomplete transaction.
The incomplete transaction, referred to as a Transaction Template, can be delivered to Xumm users allowing end users to view the Payload in the form of a "Sign Request": a transaction to sign and submit, or reject.
Xumm will then add the missing fields like the signer account, network Fee, Account Sequence, based on the context the user provides.
Xumm Payloads use the exact same syntax as the XRP Ledger JSON transaction format.
Workflow
Xumm's workflow is designed to streamline the process of transaction signing and interaction with the XRP Ledger.
Here's a step-by-step guide to understanding and implementing Xumm's workflow in your application:
Create a Payload: Start by using Xumm's API to create a payload. A payload is essentially a transaction template containing all the details for the transaction you want the User to sign.
Deliver the Payload to the User: Once the payload is created, you need to deliver it to the User for signing. Xumm offers multiple delivery options, including push notifications, QR codes, and deep links. Choose the method that best suits your application.
Deep Linking
Deep linking in Xumm enables developers to provide a seamless user experience by swiftly guiding users to interact with payloads.
Deep Links are a well known flow to allow users to automatically launch and open another app in a specific state. Xumm allows for a Deep Link workflow, where your application (browser based or native) can trigger Xumm to open and immediately show your sign request.
Benefits of Deep Linking:
Status updates
Xumm's Payload status updates bridge the gap between your application and the end user by providing real-time feedback on payload interactions.
Overview
When users interact with payloads, Xumm provides real-time status updates and results (e.g., rejected, signed with signature). These updates allow you to make your application user interface reflect the status of the interaction with the user, and return sign request results to your application.
Signature verification
Signature verification is crucial for ensuring the integrity and authenticity of the data received. It involves verifying that the data was sent by Xumm and has not been tampered with.
If you want to make sure a WebHook received by your platform has been sent by the Xumm platform, verify the signature the platform sends in an HTTP header.
Every WebHook call contains a signature to verify the authenticity. It sends an HMAC using your application secret as a key. Sample verification in NodeJS:
Payload Return URL
After a user signs a payload, a user can return to a URL (your website / app).
The Return URL (return_url) determines where the user is sent when the payload is signed. If none is given, the user will simply be displayed Close button in Xumm. Otherwise, the user will be presented a button which launches the Return URL.
Warning! iOS and Android do not allow the user to return to the browser tab they came from (if your flow starts in a browser). Make sure you restore state based on the payload / session / custom identifier or custom metadata assigned to the payload.
Tx Explorer(s)
To easily link to transaction explorers, you can link to the Xumm explorer launchpad and allow users to pick their preferred explorer.
Don't keep a list of explorer links youself: you can easily rely on our explorer launchpad URL.
When using TX Hash
The network param can be mainnet, xahau
API Call (polling)
Polling, or repeated API calls, is a common method to fetch updates. However, in Xumm, it's not the recommended approach due to rate limits.
Instead of polling, consider these efficient alternatives:
Webhooks: Once a payload is resolved, Xumm can send a WebHook to your platform, eliminating the need for constant polling. Learn more: .
Websocket Subscription: Use Websocket to receive live status updates. Learn more: .
Special Transaction Types
In Xaman, you can use all XRPL transaction types when sending a JSON transaction payload. However, some special transaction types are unique to Xaman, or require some extra info to use them.
Xumm.environment { … }
Information
ott
Sign Requests (payloads)
A sign request in Xumm is a prompt to approve a transaction or action on the XRP Ledger. This page will show you how you can create a Sign Request, and how you can deliver the request to the end user.
getNftokenDetail( … )
Get NFT Token details. Only available in JWT context. Please fetch your NFT info from other NFT data sources if possible.
This method is only available when using the SDK in a JWT context!
The getNftokenDetail method allows you to get basic XLS20 token information as fetched/parsed/cached for you by the XUMM backend.
Note: it's best to retrieve these results yourself instead of relying on the XUMM platform to get live XRPL transaction information!
Returns:
PaymentChannelAuthorize
To authorize a Payment Channel, an off ledger "receipt" must be signed. This is implemented in Xaman through a 'Pseudo Transaction' with TransactionType `PaymentChannelAuthorize`.
PaymentChannelAuthorize is normally a 'Command' or locally signed object. Implemented in Xumm as a TransactionType (which it actually isn't, also: the resulting signed blob can never be submitted to an XRPL node as is). For more information, see:
Sample PayChan transactions (gist):
getRails()
Fetch the available (known) networks and network parameters.
The getRails method allows you to get the network information for all networks known to Xumm.
Returns:
Test Tools
Trying to get your OAuth2 / OpenID integration to work? There are a couple of tools to help you test things.
Transaction types
Xumm supports a wide range of transaction types to cater to various use cases on the XRPL. Here's what you need to know:
Standard Transaction Types: Xumm accepts all mainnet XRPL transaction types.
Exception: Transaction types for non-voted in amendments may be unavailable
getHookHash( … )
Get meta information for a known Hook, by specifying the Hook Hash (64 hex chars)
Sdk.getHookHash(hookHash: string)
The getHookHash method allows you to get meta information for a specific Hook hash (64 hex chars)
Returns:
ping()
Contact the Xumm platform to check for connectivity and valid auth.
The ping method allows you to verify API access (valid credentials) and returns some info on your XUMM APP:
Returns :
Xumm.off(event, fn)
See
Xumm.ping()
Can be used to check connectivity / JWT (credential) validity & to obtain basic information about the calling credentials.
Sample response
getHookHashes()
Get the meta information for all known Hooks. Object returned contains Hook hash as key, meta as value.
Sdk.getHookHashes()
The getHookHashes allows you to get all meta information for all Hooks known to Xumm.
Returns:
getRates( … )
Get aggregated exchange rates vs. XRP for most fiat & crypto assets.
The getRates method allows you to get the exchange rates for an XRP <> requested pair. The source information is aggregated from several data providers.
Example response
To easily test a payload, you can enter the Transaction JSON template on this page and try to create a payload:
https://xumm.dev/signing-tool
Your application crafts the XRPL transaction template. The difference between a regular XRPL JSON transaction and a Xumm transaction template is that you can leave out some fields (or leave them blank) as the Xumm app on the device of the end user will fill them automatically.
Your application backend will send the transaction template to the Xumm API / SDK. Your application will receive a unique Payload ID that contains your Sign Request.
Typical fields Xumm provides:
Fee will be automatically filled with the appropriate network fee, but when set in the Payload, Xumm will respect your provided fee.
Sequence will be automatically filled with the Account sequence of the account interacting with your payload.
Account will be automatically filled with the account interacting with your payload.
User Interaction: The User will interact with the payload through the Xumm app. They have the option to either sign or reject the transaction.
Retrieve the Result: After the User has interacted with the payload, your application needs to retrieve the result Status updates. This can be done by fetching the result from Xumm's API. The result will indicate whether the User signed or rejected the transaction.
Interact with the XRP Ledger: If the User signed the transaction, your application can now interact with the XRP Ledger to finalize the transaction. This involves submitting the signed transaction to the XRP Ledger and handling any responses or confirmations.
Provide Feedback to the User: Finally, provide appropriate Feedback based on the transaction's outcome. This could be a confirmation message for a successful transaction or an error message if something went wrong.
By following these steps, you can effectively integrate Xumm's workflow into your application and leverage its features for secure and streamlined transactions on the XRP Ledger.
When to Use: Opt for deep linking when you want to minimize user steps and create a fluid transition between your app and Xumm.
Device Compatibility: Deep linking works when the origin (your app or browser) and Xumm are on the same device (iOS/Android).
Link Creation: Generate a deep link that opens Xumm with the payload ready for interaction, making interactions more seamless while keeping users engaged.
Return URL: Set a return URL in the payload to redirect users back to your app or browser post-interaction, maintaining a smooth flow.
Note for Web Origins:
For web origins, users return to the default browser, not necessarily the original tab. In order to make this smooth, handle session restoration to ensure continuity.
User Perspective:
For end users, deep linking is a breeze. They tap a link, interact with the payload in Xumm, and return to your app effortlessly.
Real-Time Status Updates
Keep track of user interactions with the payload.
Update the UI to reflect statuses like "opened" or "signed".
They provide status but not the final resolved data (for security reasons, resolved data like signatures can only be separately fetched from the Xumm platform).
Websocket Usage
Receive real-time updates in your front-end and back-end.
Frontend: Keep the user informed about the status.
Backend: Determine when you can fetch final results.
This ensures responsiveness and keeps the end-user informed.
Fetching End Results
Webhook: Once the payload is resolved, a Webhook can be sent to your platform for backend processing. For more on WebHooks, see Webhooks.
Understanding the end user's workflow/experience is vital. The real-time status updates and Webhooks are not just technical tools but communication channels between your application and the user.
By effectively using these features, you ensure an engaging and informed experience for the user.
jwt
openid
bearer
Promises (state)
ready
retrieving
success
retrieved
Payment Channel signature types (non-transaction, receipt) are not yet supported (to be added in Xumm 2.5.0)
Limited Transaction Types:: Some transaction types, such as setting a Regular Key or setting a Signer List (multisign), require special permission for user security reasons:
Setting a Regular Key
Setting a Signer List (multisign)
Excessive polling can lead to your application being temporarily rate limited, disrupting your service. If your application has been rate limited, you will receive a notification email later the same day on the e-mail address entered in the application details in the Xumm Developer Console.
Note: the PaymentChannelAuthorize transaction type is useful when you want to authorize a payment channel without submitting a transaction to the XRPL.
Payload (Sign Request Push). Any application can send Sign Requests with a push notification after the user interacted with the app at least once.
Backend integration: the Webhook & Payload get will contain a user token after the user decided to interact by signing a payload.
xApp & Browser (Web3) integrations obtain a user token after xApp open / Sign In.\
- A user token is valid for 30 days (default, can be extended on a per app basis if good reasons are provided). Every time the user interacts with the app again, the 30 day cycle will reset.
- When creating a new payload (sign request), the user token can be specified in the payload, after which the user will receive a push notification, and the sign request will present itself in the Event List of the user.
- Users can revoke the user token validity in Xumm (Settings - 3rd party apps - Revoke)
- A user token is user & app bound, meaning the same user token can only be used by the API credentials it was originally extended to.
Custom xApp push events. Custom xApp push events are permissioned.
Notification with link to xApp
Notification with link to xApp & Event in Event list with link to xApp
Verify a user token (or multiple), to see if the token is still valid (not expired, not revoked) and can be used to deliver sign requests to user(s)
The verifyUserTokens (or single token: verifyUserToken) method allows you to verify one or more User Tokens obtained from previous sign requests. This allows you to detect if you will be able to push your next Sign Request to specific users.
const someToken = '691d5ae8-968b-44c8-8835-f25da1214f35')
const tokenValidity = Sdk.verifyUserTokens([
someToken,
'b12b59a8-83c8-4bc0-8acb-1d1d743871f1',
'51313be2-5887-4ae8-9fda-765775a59e51'
])
if ((await Sdk.verifyUserToken(someToken).active) {
// Push, use `user_token` in payload
} else {
// QR or Redirect (deeplink) flow
}
Get the curated assets (shortlist in Xumm) for Trust Lines
The getCuratedAssets method allows you to get the list of trusted issuers and IOU's. This is the same list used to populate the "Add Asset" button at the XUMM home screan.
Xumm must be on the network the transaction is present on
When a payload is created using the Xumm SDK in an xApp flow, the return URL is ignoded as the user will return to the xApp post signing, where an SDK event will be triggered.
Replacement variables
You can add the following replacement tags in your Return URL. They will be replaced with the appropriate values by Xumm.
{id} will be replaced with the xumm payload UUID.
{cid} will be replaced with the optional custom payload identifier.
{txid} will be replaced with the signed transaction hash.
{txblob} will be replaced with the signed transaction HEX blob.
Routing / origin logic
If both the app and web return URL values are present, and if they are identical, the XUMM platform will execute logic to see if the user is coming from a browser tab (local device or remote, e.g. desktop browser). If so, and if the origin browser window is still active, only the origin browser window will redirect, and the app won't. Else (if the browser window is not active anymore) XUMM will redirect to the return URL.
This behaviour prevents a double redirect (both on mobile and on desktop / browser window).
Sample payload body
and any other key from the
rails
endpoint
- also available in our SDK:
When using CTID
CTID is a more efficient way to link to transactions, as they contain the ledger index, transaction index in that ledger and the NetworkID.
Therefore, any JSON value you'd use to sign and send to an XRPL node can be sent to the Xumm SDK/API, with the (signing) account fields being added/filled being the only major difference.
All fields and values in the JSON transaction template sent to the Xumm SDK/API are passed on as-is, except for the following:
Account: If this field is part of the transaction template, it will be completely ignored, as the Account will be automatically filled based on the account the end user uses to sign the transaction with in the Xumm app.
Sequence: Based on the account used to sign by the end user in the Xumm app, the Sequence will be automatically filled by Xumm.
2. Payload Options
Configure Payload Options: Configure the payload options to customize the transaction request. Refer to the for detailed information on the available options.
3. User Token (Optional)
If you are using a backend flow, you can optionally include a user token. This token is specific to the user and can be used for personalized transactions.
4. Submit the Payload
Submit the payload to Xumm through the Xumm SDK or API. You can also use alternative language SDKs for this step. This initiates the transaction signing process.
5. Handle Client Interaction
The client, a mobile app, xApp, or desktop application, will interact with the payload. Implement logic to handle this interaction and guide the user through the signing process.
6. Resolve the Transaction
The user will either sign or reject the transaction. Your application should be ready to handle both outcomes and take appropriate action.
7. Retrieve Payload Results
After resolution, retrieve the payload results to understand the outcome of the transaction. You can use WebHooks, and WebSockets or verify through the SDK/API.
8. On-Ledger Verification
Finally, verify the transaction on the XRP Ledger. You can use libraries like or for on-ledger verification. Ensure to check for delivered_amount and other relevant fields.
Understanding and implementing Xumm's transaction lifecycle is crucial for creating secure and efficient transactions on the XRP Ledger through the Xumm platform.
Webhooks
Webhooks are HTTP callbacks that allow you to receive notifications when a Payload (Sign Request) has been resolved (rejected or signed).
Webhooks are essential for asynchronous communication and can trigger specific actions in your application based on events in Xumm.
If you entered a valid Webhook URL in your Application Settings at the Xumm Xumm Developer Console, your application would receive an HTTP POST containing a JSON body with limited details for the given payload.
Please note a Webhook will not contain the entire payload: to get the entire payload, you should GET the payload using an SDK/API call.
A sample webhook looks like this:
If a user token (userToken.user_token) is issued and you plan on payload delivery using push notifications in the future, your application could/should store the token. See
Use the payloadResponse.payload_uuidv4 to confirm and get payload outcome using an SDK/API call.
Expected result / retry
If your backend does not respond within 15 seconds, or responds with a non 200 HTTP status code, the Xumm platform will retry the webhook four more times (bringing the max. total attempts at five).
The first retry will take place after 10 seconds. The next after 60 seconds. Then two more retries will take place at a 600 second (10 minute) interval.
Safety
If you want to make sure the Webhook your application received came from the Xumm platform, there are two things you can do:
Send a GET for the payload to get the full payload using the SDK/API to the Xumm platform:
Verify the signature we send in a HTTP Header when we deliver the Webhook: \
Rate limits
To prevent excessive load on our platform, the Xumm platform applies rate limits. The limits depend on the type of consumer (regular API, SDK, JWT) and endpoint(s).
On average, the Xumm platform allows API consumers to make between 60~200 calls per minute. These numbers depend on the load on the platform and the use of the API consumer.
Some endpoints have lower limits, e.g.:
POST a Payload (sign request) on average allows for sending 30 payloads per minute
Fetching TXs (no need to use our platform, best use a native XRPL WebSocket connection): 60 requests per minute
KYC status: 600 calls per minute
Account metadata: 120 calls per minute
To make sure you are not hitting the API limits, every call to our API returns two response headers:
X-RateLimit-Limit (e.g.: 30)
These numbers are not guarantees: they are averages and can be adjusted by our platform on the fly, based on your overall API call behaviour & end user interaction(s).
Raising API limits
If there are good reasons to assign elevated API limits, we're happy to have a discussion to hear about the reasons how your application consumes the Xumm API, and why your application needs higher limits. Please .
API limits will only be raised if:
Your app does not use polling techniques: to retrieve the status of a payload, use the websocket we provide for status updates (or the createAndSubscribe / subscribe method provided by the SDK: / ). Backend applications can also use a webhook: .
(If your app is an xApp) - Your app respects the xApp \
Payload Delivery
Payload delivery in Xumm is a crucial step in the transaction lifecycle. It involves delivering the payload to the user for signing.
What is a Payload?
In Xumm, a payload is a sign request sent by applications or developers to users for interaction. Users review the payload and decide to reject or accept by signing.
Delivery Methods
Xumm offers various payload delivery methods:
Deep Linking: Open the Xumm app with the payload already loaded.
QR Code Scanning: Users scan a QR code to access the payload.
Push Notifications: Send payloads as push notifications.
Status Updates
After delivering a payload, tracking its status is vital to know whether the user has interacted with it. Xumm provides mechanisms for obtaining notifications and results of payload interactions. You can learn more about this in the section.
Moving Forward
Now that you have an overview of what payload delivery entails in Xumm, you can delve into the specifics of each delivery method.
Protocol specific checks
The XRP Ledger Protocol has several protocol-related things to check in your app/implementation to make the experience for end users better. Please take these things into account:
Sample POS lifecycle
SignIn
The `SignIn` payload is a "Pseudo transaction type": an off ledger transaction specific to Xaman, which can be used to identify a user and obtain a token to push sign requests to the end user.
Note that the SignIn transaction type is already embedded in the Xaman SDK and OAuth flows. You only need the SignIn transaction type if you are manually building your own integrations (e.g. API integrations:Backend (SDK / API))
The SignIn transaction type is Xaman specific, signature only, can never be submitted. When sending a JSON transaction payload, you can use all XRPL transaction types, including a Xumm-specific "pseudo transaction type": SignIn.
The payload for a SignIn transaction can look like this:
After the user signs your SignIn request, the server-to-server call (to your configured Webhook location) will receive the signed transaction containing the signed transaction HEX blob.
You can verify the signature using the verify-xrpl-signature package:
Note: The SignIn transaction type is particularly useful when you want to authenticate a user without performing any transaction on the XRPL.
Payment Request Link
To route users to a simple payment request, all you need to use is a URL / QR containing that URL, crafted with the right parameters.
To offer users a direct payment link, you can send them straight to a URL (deeplink) or QR containing that same URL. The URL already contains destination, network, currency & other parameters.
Note: Payment Requests will request for the given asset to be delivered to the given destination account. The Xaman user will be offered an interface where they can choose to send any asset they own that can satisfy delivering the requested amount. This means that if you verify the transaction recieved, you must take into account that the transaction can contain an asset sent by the user that differs from the asset delivered to you.
Example URLs
A simple payment on Xahau for 2 XAH (native asset) to the rwietse... account:
A payment on the XRP Ledger for 2 $RLUSD to the rwietse... account:
Variants (universal)
If the user does not have Xaman installed, the above links will automatically fall back to a regular webpage showing the payment request information & download links to Xaman. If you however want to craft a link / QR that is not Xaman specific, you can use a protocol prefix which can be claimed by any XRPL supporting app in the ecosystem. The downside is that if one does not have a supporting app installed, there is no graceful fallback webpage.
Instead of prefixing with https://xaman.app/detect/request you can prefix with the xrpl:// protocol handler:
Parameters
amount - The amount in native asset or issued currency to request - can be omitted, the user can then enter the amount
network - The network the transaction should be sent on, can be XRPL or XAHAU, can be omitted, defaults to XRPL
App Developers
For App/Platform developers, there's an easy JS lib. to decode strings & parse them into normalised objects to support payment requests (and other ecosystem data formats):
Backend (SDK / API)
Use your API key and secret obtained from the Xumm Developer Console & off you go. Using our SDK's, or building your own integration on top of our well documented APIs.
Backend integration intro here...
Sample code
import{Xumm}from"xumm"
const{Xumm}=require('xumm
Connecting localhost to xAppBuilder
With xAppBuilder, you can now conveniently connect your localhost for an efficient and real-time development experience. This video provides an overview of connecting your localhost.
Step 1: Create Your xApp
Begin by opening your preferred code editor (in this case, we are using VS Code). Establish a project folder, and within this, create an index.html file. Type some text between the body tag.
Next, install the Live Server extension for VS Code.
Then, initiate the Live Server by clicking the 'Go Live' button/link located in the bottom right corner of VS Code. Take note of the port number that is displayed.
Step 2: Make Your Website or Web Service Globally Accessible
In your terminal, execute the command npm install -g localtunnel. If you encounter a permission error, use sudo npm install -g localtunnel.
Following this, run lt --port 5500, making sure to replace '5500' with the port number noted in Step 1.
The terminal will output a unique URL. Copy this, and open it in your browser. Here, submit your IP address (if you are unsure of your IP, a quick Google search of 'whatsmyip' will provide it).
For further information about this package, you can refer to the official .
Step 3: Set Up Your Xumm Developer Console Account
Navigate to the and create an xApp account.
Paste the URL acquired in Step 2 into the 'WebApp URL' section. In the 'Debug Device ID' section, enter your device ID (which can be found by navigating through Xumm -> settings -> advanced -> Device ID).
Step 4: Access Your xApp on xAppBuilder
Open xAppBuilder and scan the provided QR code using Xumm. Afterward, click on the xApp within xAppBuilder.
Now, when you make and save changes to your code in the VS code editor, these changes will be reflected in xAppBuilder, allowing for real-time modifications and testing.
User identification payloads
When building your own backend integration, you can request a user to sign a Sign Request with a "SignIn" transaction type. This is a pseudo transaction type allowing a user to confirm their r-address
A SignIn transaction will never be submitted to the XRP ledger, as it is an invalid transaction type (XUMM specific pseudo transaction type).
A sign SignIn sign request can be as simple as this:
{
"txjson": {
"TransactionType": "SignIn"
}
}
All Xumm payload options are valid for a SignIn transaction.
After the user signs your SignIn request, the server to server call (to your configured Webhook location) will receive the signed transaction containing the signed transaction HEX blob.
Response
When the user signs the Sign Request, you will get a signed transaction (that has never been submitted to the XRP Ledger).
You can now get the account address and some basic public account information from the payload details, and assign this information to your own local dataset, like a session.
Verify the signature
If you want to you can run your own signature verification on the signed SignIn pseudo transaction our platform returns to you. Of course the Xumm platform also verified the signature for you. Would you like to check yourself as well, we have created this package
Verify Payload signature
You can fetch the corresponding payload to verify the signature, to make sure it's signed by the account you expected to sign the payload.
If you want the actual blob and signature for the user signed in with the Xumm OAuth2 flow:
Get the JWT contents
Get the payload from the JWT (that's the Sign In payload)
Get that payload with the SDK
Check the payload data, the response.hex property holds the signed TX Blob
Now you can verify the signature using the xrpl-verify-signature package, or using any native method capable of verifying XRP Ledger signatures:
Backend
A sign request in Xumm is a prompt to approve a transaction or action on the XRP Ledger. This page will show you how you can create a Sign Request, and how you can deliver the request to the end user.
When creating Sign Requests from a backend environment, the Xumm SDK is called with your API Key & Secret. A payload can be opened by any user. A user will not get notified about a payload, unless if they interacted with the payload through a deeplink or scanning the Payload QR code.
If you want to deliver backend created Sign Requests to a user & the user is identified by your application, you have to provide a user_token to the payload. The user_token can be obtained after the user interacted with your application & signed a payload. See: Push
For more information about the object contents to be used for Payloads & the return URL replacement variables, see:
To decide where the user is sent after signing the payload, please read:
Xaman SDK (Intro)
Developers can use the Xaman SDK to easily integrate with the Xaman platform. This allows for easy & secure end user interaction. With your application & the XRP Ledger.
JavaScript/TypeScript
NPM
The Xaman Javascript/TypeScript SDK can be found on npm:
CDN
The latest version of the Xumm SDK is always available at:
Please note the CDN URL is heavily cached (edge and headers, so client side). If you are expecting a new version of the SDK to load, consider cleaning local cache and adding a random (e.g. your build hash) as a URL Query param to the URL to force URL uniqueness.
Code samples
See
Warning (legacy packages)
Previously there were three different packages:
xumm-sdkfor backend interaction
Networks
The Xumm API/SDK is designed to be network-independent, providing flexibility for developers and end users. This means that the end user determines the network on which transactions occur.
However, a payload can include a forced network identifier to specify a particular network. When a user signs a payload, the result includes information about the network the user was on when signing, allowing developers to track and manage transactions across different networks.
If your payload contains a NetworkID, it is only valid for the given network. Xumm will ask a user to switch to the given network (starting Xumm 2.6.0)
Key Points:
Network Independence: The Xumm API/SDK operates independently of the network, giving the end user the freedom to choose their preferred network in the Xumm app.
Network Information in Results: The results of a signed payload include information about the network the user was on at the time of signing.
Forced Network Identifier: A user can be on any network while signing. You must check for the expected result in the Payload results. Alternatively, you can include a forced network identifier in a payload to specify a particular network.
xAppBuilder 🏗️
Introducing xAppBuilder, an advanced tool specifically designed to streamline the creation and debugging process of xApps for Xumm.
Seamless xApp Emulation
This is where xAppBuilder shines - it seamlessly emulates your xApp directly on your local development environment.
What does this mean for you? Instant, real-time feedback on your code modifications. Every tweak you save in your IDE, you can immediately see its effect on the emulated xApp.
xAppBuilder transforms these challenges into a smooth, manageable process.
Simplified OTT Replay
One Time Tokens (OTTs) and replay tokens can often present challenges, particularly for those new to xApp development.
xAppBuilder assists in addressing this issue by offering an automatic fetching feature for OTT and Replay OTT, reducing development time and allowing developers to concentrate more on enhancing the functionality of their xApp.
Real-Time Debugging
Debugging becomes a breeze with xAppBuilder. How? With live console logs of your xApp, spotting and fixing bugs is a more efficient process.
These real-time logs help you to monitor and understand your xApp's performance and behavior better.
Get Started with xAppBuilder
Ready to level up your xApp development process? xAppBuilder is now live for Linux on the , , and . Check out the demo video and download the tool today!
For more about xApps and Xumm, visit our . Here's to smoother, faster, and more efficient xApp development. Happy building, developers! 🏗️ 🛠️
Development & Debugging
Debugging your xApp is tricky: it runs on your phone. How to access the logs?
The easiest way to debug your xApps is by using our xApp Developer App for desktop (Mac, Windows, Linux): xAppBuilder 🏗️
Some things that may help debugging your xApp:
Remote JS Console
Using you can drop one line (script) in your page's <head> and get realtime access to the remote console (bi-directional).
Replay OTT's
If you open your own xApp using the device you added in the Xumm Developer Console as debug device (using the Device Identifier), the OTT (one time token) can be replayed when visiting from the same IP address.
Note: Replaying OTT's only works if you force your browser to identify with the user agent xumm/xapp. In the Chrome Developer Console, on the Network tab, click the "Radio antenna signal" icon and uncheck "Use browser default" next to User agent.
Make sure your device (Xumm - Settings - Advanced) is whitelisted as Debug Identifier in the Xumm Developer Console
Make sure your phone and computer are visiting from the same public IP address (e.g. by having them both on the same WiFi and internet connection
Obtain your OTT in the xApp: it's the value of the xAppToken query parameter. Your xApp is being called with https://your-url/?xAppToken=...
You will now see your xApp in your browser.
Use your local dev URL as xApp URL
Use a tool like ngrok () or localtunnel.me () to temporarily publish your local development URL to a publicly available URL you can use to access your xApp during live debug/development.
CORS (xApp)
CORS restricts access to resources on different domains to ensure privacy and security, allowing website owners to control access. As xApps run inside Xumm, allowing CORS is required for xApps.
Troubleshooting
If an xApp integration doesn't allow for running commands, and the console shows messages like "Couldn't connect to host", problems are a result of the same cause: CORS issues.
The SDK can't reach Xumm (the app), so:
"Could not contact Xumm host" error appears, and:
For example: the openSignRequest trigger doesn't fire, the Sign Request doesn't open, and:
Xumm keeps on trying, and is stalling the init. to see if the host can be reached - yielding "Attempt n » Retry" console messages (just to make sure it isn't a timing issue).
Find the cause
Check the following things:
Are you getting this messages from your frontend console, or backend (node?)
Do you have CORS setup correctly? (Allow iframe loading, allow CORS (origin: *)
Does your app run over http (instead of https with a valid certificate?)
While #3 and #4 should be valid, we've seen some Android phones where this prevented the integration from working. We use ngrok to work around the local http and non standard port development issues.
\
CORS (Browser)
CORS (Cross-Origin Resource Sharing) is a security feature that restricts a web page from accessing resources from another domain. Xumm allows for CORS calls to JWT endpoints.
CORS (Cross-Origin Resource Sharing) is a mechanism that allows a web page from one origin (domain) to access resources from another origin. In other words, it is a security feature implemented by web browsers that restricts a web page from making requests to a different domain than the one that served the web page.
The Xumm API endpoints allowcross origin requests: we want your web application to be able to make calls to the Xumm platform using the credential (JWT) you have received when a user logged in.
If you are using the Javascript/TypeScript SDK () the SDK will automatically make sure you are calling the right CORS enabled endpoints when a user signed in through the SDK.
If you are building your own, custom implementation, you will have to make sure you are calling the : only our JWT (JSON Web Token) routes allow for cross origin calls, and serve the right headers to allow your browser to do so.
Develop & Test
When building xApps, there are some tools to make building & sharing your xApp easier.
While developing your xApp, you may want to easily test & debug your web application. You may even benefit from live reaload during development. You can expose your local development environment with a tool like https://ngrok.io or https://localtunnel.me and configure your public URL as your xApp URL.
You can get access to the remote browser console using the techniques explained in the Development & Debugging article.
If you want to share your xApp with a small group of testers or team members, you can ask them for their Xumm Device Identifier (Xumm - Settings - Advanced). You can add up to 10 Device Identifiers as xApp testers, so they can open your sandboxed xApp.
Warning! If you have multiple xApps (e.g. a live version & a test version, pointing to your development URL) please make sure to use the right API Key, otherwise your app can't communicate with the Xumm backend. Also note things like are API Key & user bound.
When you want to develop in your local browser instead of in Xumm, please see the "OTT Replay" section in the article.
We are currently working on a Desktop xApp Development Application so you can develop & test locally 🎉 (Work in progress, more good things are coming)
Xumm.user { … }
Returns information about the signed in user (in case of xApp or Web3 flow).
This method only applies to the xApp & Web3 (browser) flow. Backend flows (using API Key & API Secret) have no user context.
The following properties are part of the user object. Every property is a Promise that is resolved when the user is signed in.
account - r-address
picture - Profile picture or Hashicon URL
name - Account name (if present) - e.g. Xumm Pro account name
domain - Domain name (if present) for account
source - Information source (e.g. a specific explorer)
networkType - Enum, e.g. MAINNET, TESTNET, ... the user is connected to
networkEndpoint - WebSocket endpoint to connect to the network
blocked - If the account is on a blacklist (e.g. because of scams)
kycApproved - If the account owner went through opt in KYC with Xumm
proSubscription - If the account has a Xumm Pro subscription
profile - Xumm Pro Profile slug (URL)
token - User Token for future sign request Push delivery
The token field contains a user_token; this token is specific to both the application (SDK) credentials and the end user. It grants you access to asynchronously send notifications to the end user (for 30 days, unless granted long living tokens).
When your application creates a payload for the end user to sign using the SDK session (or JWT), a user will always receive a push notification.
If you want to asynchronously create a payload on your backend using the flow, you can include this token in the user_token field of the payload.
xApps
xApps are custom applications that run within the Xumm environment. As a developer working with xApps, delivering payloads is crucial for a seamless user experience.
Delivering Payloads within xApps
Delivering payloads within xApps is about efficiency and user experience. Since the user is already engaged with your xApp inside Xumm, delivering the payload directly within the xApp streamlines the process. This minimizes context switching for the user and keeps them focused on the task at hand.
How to Deliver Payloads within xApps
Create a Payload: First, you need to create a payload with the transaction details. This payload is essentially a sign request you want the user to interact with. See:
Use Xumm SDK: To deliver the payload within your xApp, use the Xumm SDK. The SDK provides functions allowing you to seamlessly integrate the payload within your xApp. See:
Once integrated, the payload will be displayed to the user within your xApp. The user can then review and interact with the payload without leaving the xApp.
"Pay With Anything"
Xaman allows you to easily craft a payload (Sign Request) that will always deliver the currency and amount you want to receive, while allowing the Xaman user to pay with anything (any asset they have)
It's as simple as that. Xaman sees Amount, Xaman sees pathfinding in the option and done!
You will always get what you asked for, user can pay with anything. delivered_amount is always your preferred currency from Amount.
The Sign Request (user facing)
When a payload like above is opened by the user, they will have to wait a few seconds for the XRP Ledger to finish a Pathfinding request, to see which assets the user posesses that can satisfy delivering the requested amount (with in-line, in-transaction, atomic conversion of the asset the user sends to the asset you want to receive).
First few seconds
After paths are found
scanQr()
Scan a QR code
Syntax
xumm.xapp.scanQr()
xumm.xapp.on('qr', data => {
console.log('QR', data)
})
Response
Returns an event: qr. Use to subscribe to the return data.
close({ … })
Close the xApp
Parameters
The refreshEvents param. is optional. If passed (and true) the Event list will be forcefully refreshed (updated) when the xApp closes. This can be useful if the xApp closes programatically after e.g. resolving (cancelling) or signing a Sign Request.
{ refreshEvents: true }
Syntax
openSignRequest({ … })
Open a Sign Request (payload) created with Xumm.payload.create
Returns an event: payload. Use to subscribe to the return data.
getTransaction( … )
Fetch an XRPL transaction & metadata. Please don't use this method unless absolutely necessary: please set up your own connection to an XRPL node to fetch this information.
The getTransaction method allows you to get the transaction outcome (mainnet) live from the XRP ledger, as fetched for you by the XUMM backend.
Note: it's best to retrieve these results yourself instead of relying on the XUMM platform to get live XRPL transaction information! You can use the xrpl-txdata package to do this:
Warning! This command is permissioned. To use it in your xApp, please contact Xumm Support, explain the user flow & use case and share your API key so we can discuss granting your xApp this permission.
Parameters
The provided value of the xApp property should be a valid xApp identifier.
Syntax
Your own backend (Auth)
Xumm xApps yield a JWT that can be used to make subsequent calls from the user context to the Xumm API's. You can also use this JWT for your own backend.
If you want to identify a Xumm xApp user with your own backend, you can rely on the xApp JWT's issued by Xumm: the secret used to sign the JWT is your own Xumm application secret (HMAC, HS256).
This makes it really convenient to obtain three things at once, making calls to your own backend with an Autorization: Bearer {The Xumm JWT} header:
Push
Delivering Sign Requests using a push notification can be a very convenient way for end users to interact with your application: they don't even have to scan a QR code.
and are signed in with user context, so payloads created in those environments will automatically be pushed to the signed-in user.
This means if you're using the xApp / Browser (Web3) flow, you do not have to specify the user_token as the payloads created from the xApp / Browser (Web3) flow are automatically pushed to the signed-in user.
If you are building a backend integration, the flow is slightly different.
Xumm UI interaction
Using the Xumm SDK in xApps, you can trigger native Xumm interaction & receive events from Xumm in your xApp.
xApps are WebApps. They are opened in Xumm for a great user experience. They add value (tooling, wizards) for end users, using Sign Requests to help users perform tasks on the XRPL.
To add value for end users, your xApp will most likely implement some of the features Xumm offers natively in your xApp. E.g. open the QR scanner, Account Destination Picker, or start a Sign Request flow. Then to receive the response from these native Xumm flows in your xApp (WebApp).
Your xApp can trigger specific actions in Xumm:
These actions can be sent form your xApp (frontend Javascript) context, and will trigger functionality native to the Xumm app:
Style guide
When building xApps, it makes a lot of sense to stick to the design (colour palette, font, etc.) as used by Xumm to offer the best user experience to xApp users.
Font family
The main application uses the font-family: proxima-nova, sans-serif. Only when using this font for your (web) xApp to be embedded in XUMM, use this stylesheet:
When offering your application anywhere else than as embedded (web) xApp, check your licensing needs and requirements for the use of Proxima Nova.
xAppBuilder FAQ
Frequently Asked Questions
Q: I do not see my xApp in the xAppBuilder. What should I do?
A: Ensure your Device ID has been entered in the Debug Device ID section.
Step 1: Retrieve your Device ID from Xumm by going to Xumm -> Settings -> Advanced -> Device ID (double tap to copy it).
subscribe( … )
Returning non-void in the callback function passed to the Sdk.payload.subscribe() method
Manually calling <PayloadSubscription>.resolve() on the object returned by the Sdk.payload.subscribe() method
createAndSubscribe( … )
The object is basically a object with the created payload results in the created property:
All information that applies on Sdk.payload.create() and Sdk.payload.subscribe() applies. / . For the contents of a Payload, see the .
Differences are:
The input for a
Simple Sign Request
See this code in action:
Native Apps
When building a native app (iOS / Android / React Native / Capacitor / ...) you can leverage "Sign In with Xumm" and offloading transaction signing to Xumm as well. This uses application deep links.
The process to integrate Sign In with Xumm and transaction signing by Xumm with your own native app is actually quite similar to either the flow: it uses OAuth2 (PKCE or Implicit flow) or the flow.
Combined with "Deep Links", your application sending off the user to Xumm will happen with a simple app-redirect. After the user interacted with your sign request, Xumm will return the user to the Return URL: the URL you added to your sign request payload to be opened post-signing.
If your application registers a Deep Link URL as well, and you pass that URL to Xumm as the payload Return URL, the user will be redirected back to your app. To match state, you can add information to the Deep Link URL Xumm sends the user to.
getKycStatus( … )
Get the KYC status for users, based on a user_token issued by a successful sign request.
The getKycStatus return the KYC status of a user based on a user_token, issued after the user signed a Sign Request (from your app) before (see Payloads - Intro).
If a user token specified is invalid, revoked, expired, etc. the method will always return NONE, just like when a user didn't go through KYC. You cannot distinct a non-KYC'd user from an invalid token.
Alternatively, KYC status can be retrieved for an XPRL account address: the address selected in XUMM when the session KYC was initiated by.
... or using an account address:
selectDestination({ … })
Open the Destination Picker: select/find/scan (QR) an XRPL destination account by r-address, slug or PayString
Parameters
If you want to request the destination address only, skipping the "Destination Tag" required check & input, you can provide the ignoreDestinationTag param. If not provided (or false) Xumm will chech if the destination account requires a Destination Tag and ask the user to input one.
get( … )
To get payload details, status and if resolved & signed: results (transaction, transaction hash, etc.) you can get() a payload.
Note! Please don't use polling! The XUMM API offers Webhooks (configure your Webhook endpoint in the ) or use a subscription to receive live payload updates (for non-SDK users: ).
You can get() a payload by:
Xumm.payload { … }
Payloads are the primary reason for the XUMM API (thus this SDK) to exist.
An XRPL transaction "template" can be posted to the XUMM API. Your transaction tample to sign (so: your "sign request") will be persisted at the XUMM API backend. We now call it a a Payload. XUMM app user(s) can open the Payload (sign request) by scanning a QR code, opening deeplink or receiving push notification and resolve (reject or sign) on their own device.
A payload can contain an XRPL transaction template. Some properties may be omitted, as they will be added by the XUMM app when a user signs a transaction. A simple payload may look like this:
As you can see the payload looks like a regular XRPL transaction, wrapped in an txjson object, omitting the mandatory Account
ready()
When using the native Xumm loader screen for your xApp (until your xApp is ready, fully hydrated, booted, etc.) you call this method to remove the Xumm loading screen.
This feature is available in Xumm 2.5.0 and higher.
To prevent showing a double loader (first the Xumm xApp loader, then your xApp's loader while hydrating / booting) you have to . The xApp will then show the Xumm native loader, until your application calls the ready() method on the Xumm SDK.
cancel( … )
To cancel a payload, provide a payload UUID (string), a <XummPayload> (by performing a Sdk.payload.get() first) or a <CreatedPayload> (by using the response of a Sdk.payload.create() call). By cancelling an existing payload, the payload will be marked as expired and can no longer be opened by users.
Please note: if a user already opened the payload in XUMM APP, the payload cannot be cancelled: the user may still be resolving the payload in the XUMM App, and should have a chance to complete that process.
A response (generic API types ) looks like:
Network Information in OTT Data: xApp OTT data also includes network information, providing additional resources for developers to manage transactions.
User Experience: The choice of the network result in loss of goods or funds: imagine getting paid on Testnet, while delivering actual sold goods expecting a mainnet payment. It's important to consider this in your application development process.
Does your app run over https on a non standard (non TCP 443) port?
Some web server configurations don't allow CORS to work on a subdomain. Try running on a FQDN
LastLedgerSequence: If a valid ledger index is entered in the LastLedgerSequence field, it will be passed on unchanged to the Xumm app. However, if avalue < 32570 is entered, the Xumm app will automatically calculate the{current ledger index} + the given amount of ledgers, where {current ledger index} is based on the most recent closed ledger index at the moment the end user taps the button to accept & sign the sign request.
dt - The Destination Tag to send to - can be omitted
invoiceid - The InvoiceID to send, must be formatted in HEX according to the InvoiceID length specifications (64 hex chars) - usually omitted
issuer - The issuing account, only required combined with currency for requests in issued currencies
currency - The currency code, must be in three-char ALPHA notation or HEX notation for issued currencies with asset codes > 3 char length. Only required in combination with issuer for payments in issued assets.
Now open your public xApp URL with /force appended, and include the xApp Token. E.g. if your xApp launch URL is:
https://xumm.app/detect/xapp:sandbox.abcd1234
... You open (in your browser):
https://xumm.app/detect/xapp:sandbox.abcd1234/force?xAppToken=...
Handle Status Updates: Implement logic to handle status updates. This includes whether the user signed or rejected the payload. Xumm SDK provides functions that allow you to receive status updates and take appropriate actions based on the user's response, see: on(xAppEvent, fn)
Once an account has successfully completed the XUMM KYC flow, the KYC flag will be applied to the account even if the identity document used to KYC expired. The flag shows that the account was once KYC'd by a real person with a real identity document.
Please note that the KYC flag provided by XUMM can't be seen as a "all good, let's go ahead" flag: it should be used as one of the data points to determine if an account can be trusted. There are situations where the KYC flag is still true, but an account can no longer be trusted. Eg. when account keys are compromised and the account is now controlled by a 3rd party. While unlikely, depending on the level of trust required for your application you may want to mitigate against these kinds of fraud.
Instead of providing a txjson transaction, a transaction formatted as HEX blob (string) can be provided in a txblob property.
You obtain basic user information, like the r-address and network the user is connected to, as this information is encoded in the JWT.
You can verify the authenticity of the JWT, as it is signed with your own Xumm API Secret.
You can make calls from the user context to the Xumm backend with this JWT (for as long as it is valid: 24h).
Every time when a user opens your xApp, a new JWT is issued, valid for 24h.
Please note: if you are using the OAuth2 flow instead of an xApp to obtain your JWT, you can verify the OAuth2 issued RS256 JWT using the certificate info publised as per OpenID specifications: https://oauth2.xumm.app/certs
How to validate a JWT
When using the JWT for authorization, you need to validate it before you can make sure that the user is who they say they are. This is a brief explanation in how to verify the JWT using a npm package called jsonwebtoken and the bearer provided by the Xumm SDK.
You can obtain the JWT associated with the OTT by initiating the Xumm SDK:
Then get the bearer by awaiting the environment:
This bearer is the JWT. You must check if the JWT is valid.
First, run:
After this, use the code underneath to verify the JWT. You'll need the xApp API Secret to sign the JWT and check it's validity.
If your application features user sign-in (to identify your user) and you obtained a user_token from a previously signed payload from this specific user, you can add the user_token to the next payload to deliver the payload through a push notification.
The first interaction (to obtain the user_token) will always involve either: showing a QR code for the user to scan with the Xumm app or a deep link to the Xumm app to sign a payload.
A payload containing a user token looks like this:
After posting the payload the Xumm SDK/API, the response will confirm push notification delivery:
User token expiration
The issued user token expires 30 days after the last successfully signed payload of your application by the Xumm user using the same issued user token. If there's a good reason for your application to have longer living user tokens, please contact Xumm Support and explain your use case.
Obtaining the `user_token`
From a webhook
After the end user resolves the sign request by signing, the configured application Webhook URL will receive a JSON body per POST request containing the accessToken section:
From a resolved Payload
When you get the payload results, the application.issued_user_token contains the user token.
To prevent showing a double loader (first the Xumm xApp loader, then your xApp's loader while hydrating / booting) you can enable the "Xumm Loader Screen" option in the Xumm Developer Console (xApp tab). See ready()
Your xApp can also receive events (data) from Xumm:
Certain actions in Xumm will trigger an event so your xApp can retrieve data or act based on the event (details below):
For all events emitted in your xApp (like the async follow up data of an xApp UI action triggered), see the xApp event handler: on(xAppEvent, fn)
The subscription will be closed by either:
Status updates can be processed by providing a callback function to the Sdk.payload.subscribe() method. Alternatively, the (by the Sdk.payload.subscribe() method) returned raw websocket can be used to listen for WebSocket onmessage events.
More information about the status update events & sample event data: Status updates
The payload is opened by a XUMM App user (webpage)
The payload is opened by a XUMM App user (in the app)
Payload expiration updates (remaining time in seconds)
The payload was resolved by rejecting
The payload was resolved by accepting (signing)
To subscribe to live payload status updates, the XUMM SDK can setup a WebSocket connection and monitor live status events. Emitted events include:
Payload subscriptions: live updates
If a callback function is not provided, the subscription will stay active until the <PayloadSubscription>.resolve() method is called manually, eg. based on handling <PayloadSubscription>.websocket.onmessage events.
When a callback function is provided, for every payload specific event the callback function will be called with <SubscriptionCallbackParams>.
The <SubscriptionCallbackParams>.data property contains parsed JSON containing event information.
Either by calling <SubscriptionCallbackParams>.resolve() or by returning a non-void value in the callback function the subscription will be ended, and the <PayloadSubscription>.resolved promise will resolve with the value returned or passed to the <SubscriptionCallbackParams>.resolve() method.
Resolving (by returning non-void in the callback or calling resolve() manually) closes the WebSocket client the XUMM SDK sets up 'under the hood'.
If a payload can't be fetched (eg. doesn't exist), null will be returned, unless a second param (boolean) is provided to get the SDK to throw an Error in case a payload can't be retrieved:
First your app loads, fetches, etc. Then you have all the information you need to render & show your app, and you call:
Exception flows
The xApp doesn't load, to be able to debug the app needs to be displayed (e.g. reverse proxy 502 error or some other app error, preventing the SDK's ready() call being made).
With Xumm in Developer Mode, the Xumm loading screen shows a 'Proceed to xApp' button at the Xumm loader screen, below the spinner. This way you can dismiss the Xumm loader and view the underlying problem.
The xApp takes very long to load or doesn't load at all: users are confronted with a long wait.
If the ready() method in the Xumm SDK isn't called within ~6 seconds a label + button is made visible: "xApp is slow to respond..." [Contact Developer].
This button then opens the Support URL for the xApp as entered in the Developer Console.
const jwt = require('jsonwebtoken')
const apiKey = '' // Your Xumm API key here
const apiSecret = '' // Your Xumm API secret (BACKEND ONLY!)
const bearer = await xumm.environment.bearer
try {
// If decoded comes back as an object, the JWT is valid.
// Otherwise, the catch block is activated
const decoded = jwt.verify(bearer, apiSecret);
// For extra security, check if the decoded JWT contains
// the client_id of your xApp, e.g. the API Key from the developer console
if(decoded.client_id === apiKey) {
// JWT is valid and signed for this client (client_id matched)
} else {
// Valid JWT, but for another client? There's something
// wrong with an otherwise valid JWT.
}
} catch (error) {
// Handle your error here and inform the user that their access is denied.
}
xumm.payload.createAndSubscribe({
TransactionType: 'Payment',
Destination: 'rfHn6cB5mmqZ6fHZ4fdemCDSxqLTijgMwo',
Amount: String(1000000) // one million drops, 1 XRP
}, eventMessage => {
if (Object.keys(eventMessage.data).indexOf('opened') > -1) {
// Update the UI? The payload was opened.
}
if (Object.keys(eventMessage.data).indexOf('signed') > -1) {
// The `signed` property is present, true (signed) / false (rejected)
return eventMessage
}
})
.then(({ created, resolved }) => {
console.log('Payload URL:', created.next.always)
console.log('Payload QR:', created.refs.qr_png)
return resolved // Return payload promise for the next `then`
})
.then(payload => console.log('Payload resolved', payload))
// This is where you can do `xumm.payload.get(...)` to fetch details
Starting XUMM version 1.1 four colour palettes are available. The colour the app is running in will be passed to the xApp in the style parameter, see the xapp/ott/:token documentation (applies to the SDK as well).
Used colour palette codes:
LIGHT
DARK
MOONLIGHT
ROYAL
Your xApp launch URL will receive a GET parameter (query param) named xAppStyle containing the colour palette name as active on the client device. If your xApp URL is eg.:
... the URL opened will be:
Standard CSS stylesheets
The four available themes are shipped as Bootstrap (version 4.5) rolled stylesheets, ready to use. You can include a Bootstrap 4.5 stylesheet by pointing to:
The {theme} element should be replaced by the theme name in lower case notation.
SPA / Front-end app only
To load the right stylesheet dynamically in an environment without a backend, consider using this script in your <head>:
Colours
Step 2: Visit Xumm Developer Console, select your application, navigate to the xApp section, and paste the Device ID you copied in Step 1 into the Debug Device ID section.
If you are not the owner of the xApp, you will need to ask the owner to input your Device ID in the Guest Device IDs section.
Q: Why are some of my xApps shown in gray at the end of the xApp list in xAppBuilder?
A: These xApps are ones you have not actively used, and their session has expired. To start a new session, open the xApp in Xumm and quit. Next, click on the "Refetch" link in xAppBuilder. This should fetch the active session of your xApp into xAppBuilder.
Q: How can I open the xApp on xAppBuilder with a different context / r-address?
A: Start by opening the xApp in Xumm with the different context / r-address, which will create a new session for the new context / r-address. Then return to xAppBuilder and click on the "Refetch" link. The new context / r-address should now be listed in the context dropdown menu.
Q: How do I exit / close the xAppBuilder?
A: On MacOS, hover over the top left corner to find the close, minimize, and maximize buttons. On Windows and Linux, click on the x symbol in the top right corner.
For Mac users, you can also use Shift + Click on the tray icon to exit.
Switching Network
Q: How can I access my xApp from a different network within xAppBuilder?
A: First, switch to your desired network in Xumm. Next, open the relevant xApp within Xumm — this action generates the OTT for replay. Following this, click on the 'Refetch' button(top left corner) in xAppBuilder and open the xApp in xAppBuilder.
It's important to note that xAppBuilder doesn't connect to any specific network by itself. The connection relies on the most recent OTT of your xApp. For instance, if you last accessed your xApp on the Testnet and subsequently open it in xAppBuilder, it will connect to the Testnet.
If the network hasn't switched, ensure that you're accessing the xApp within xAppBuilder using the same account (raddress) as the one you recently used in Xumm OR maybe you forgot to click on the 'Refetch' button.
Verify Network in xAppBuilder\
Location of the URL after switching networks
\
Integration
Sign In & obtain JWT
If you just want to authorize/identify a user with his/her r-address, the OAuth2 "Identify" flow suffices: you send off the user to a Sign In URL with a return URL and the user will return to your application with a JWT (JSON Web Token) you can use to call the Xumm API to get the user identification information (r-address). For more information, see Identity (OAuth2, OpenID).
If you are building a native app and you want to easily allow users to sign in with Xumm, you can use the OAuth2 Implicit flow like this:
Register a deeplink or deeplink protocol for your app, e.g. yourapp://signin
Add your deeplink / protocol URL to the Xumm Developer Console as a valid Return URL.
Redirect your user to:
https://oauth2.xumm.app/auth?client_id={apikey}&redirect_uri=yourapp://signin&response_type=token
Now, when the user signed in, Xumm redirects the user to your app, to the redirect_uri, with URL Query Parameters appended containing a JWT in the access_token field.
You can now use (you can construct the Xumm() with this JWT.
Sign In & Sign Requests
If you also want to send Sign Requests to users & you don't want the user to re-authorize the JWT every 24h, you can generate Sign Requests yourself, in which case the flow you will use is the Backend (SDK / API)flow. You craft your Sign In Payload:User identification payloads yourself, obtain a User Token after which you can generate user bound sign requests.
This workflow requires a backend on your end, where our application communicates to your backend to generate the Sign Requests. You need a backend for this, as you do not want to expose your Xumm API keys in your compiled application.
Please do not include your Xumm API Secret in your native app build. Native apps can be decompiled and you do not want your API Secret to be abused by third parties.
import{Xumm}from"xumm"constSdk=newXumm(process.env.XUMM_KEY,process.envconstpong=awaitSdk?.ping()constpayload=awaitSdk.payload?.create({custom_meta:{instruction:"Sign request from "+pong?.application.name,},txjson:{TransactionType:"SignIn",},})console.log(payload)
You focus on building your cool app. We make sure your app & Xaman users can interact. Safely & smoothly.
Welcome to the Xaman Developer Docs!Xaman is a powerful platform designed to make your interaction with the XRP Ledger (XRPL) seamless. Whether you are an experienced developer or just getting started, Xaman offers a range of features, including xApps, payloads, transaction signing, and much more.This documentation will guide you through the essentials to get you up and running in no time.
While app users can simply use the Xaman app to manage their XRP ledger accounts, balances and transactions, the true power of Xaman can be experienced through the Xaman SDK, using our platform made available for developers.
Want to dive straight in? You're one click away from the
Ways to interact
The Xaman SDK can be used to interact with Xaman users. An example can be a "sign request", where the user is asked to sign a transaction, identification (sign in) or a user interface presented in Xaman (xApp).
What are you going to build? Read more about specific user & developer flows:
Packages
The Xaman SDK offers a ready to use Javascript & Typescript SDK for all frontend and backend projects. With only minor differences depending on the environment you are using the SDK in, the SDK is the most convenient way to interact with Xaman users & the Xaman ecosystem.
If you are not working in a environment and prefer to build your own backend implementation, you can use our or use one of our SDKs for , or
Language
Maintenance
Package
Getting started
Xaman allows developers and app users to "meet up".
While app users can simply use the Xaman application interact with the XRP Ledger with their accounts, balances and transactions, the true power of Xaman is unleashed through the platform available for developers.
This way users can interact with third party tools & platforms in the most secure and convenient way, while developers don't have to worry about wallet & key management.
Concept
XRP Ledger transactions are traditionally user initiated: users open their wallet, enter the destination, amount, etc. and then you submit a transaction. This is referred to as a Push Transaction.
In retail / e-commerce & third party interaction scenarios, the ideal flow is inverted: a Pull Transaction. The third party environment wants the user to sign a specific transaction, and a transaction to sign is offered to the user.
This is where the Xaman platform comes in. An XRP Ledger transaction template can be delivered to the end user through the Xaman platform. This is called a Sign Request.
Interaction
The most convenient way to interact with the Xaman platform is through the JavaScript/TypeScript SDK: . There are also some other SDKs available for Backend use in other languages:
Language
Maintenance
Package
The Xaman platform allows for easy integration in your application & workflow. Make sure to check the documentation for your environment:
Terminology
Essential terms and concepts to help you better understand and utilize the powerful features of the Xaman Wallet platform.
Xaman
The self custodial wallet application for iOS and Android developed by XRPL Labs. The app can be used by end users to manage their XRP Ledger account(s) and interact with the "Xaman Platform" (see below) through "Sign Requests" (see below).
Xumm
The previous name of Xaman, Xaman is formerly known as Xumm (and has rebranded). Some references in these docs may still point to our old name.
Xumm Platform
The platform your application and the Xaman app (iOS/Android) interact with. For developers, the platform offers the ability to send "Sign Requests" (see below) to the platform's "API" (see below). The Sign Request can then be interacted with by Xaman app users.
Xaman API
Websocket
Websockets provide real-time payload updates
All payloads get assigned a payload-specific Websocket URL. You can connect to this socket from the client side of your application to receive live status updates (if the user opens the payload on their device and the user resolves the payload).
The pushed information contains minimal information; it is meant to trigger your application to fetch more information from your application's backend.
If a payload doesn't exist, the Websocket connection will receive an {"message":"..."} update, and the socket will be closed. If the payload has expired, the connection will receive a {"expired":true"} message.
If the payload exists and did not expire, the connection will start with a message containing the remaining seconds until expiration: {"expires_in_seconds":51}. This message will be sent every 15 seconds for keepalive reasons. If the connection is still active when the payload expires, a {"expired":true"} message will be sent. The connection will be kept alive, leaving it up to the client to disconnect.
Expiration
The expiration should be handled as an OPEN/SCAN BEFORE, not a RESOLVE BEFORE. If the end user opens the payload (from the push notification, deep link, or QR scanning) but it didn't resolve before expiration, they will not receive a notification and will still be able to resolve it as if the payload hadn't expired.
When the user resolves after the expiration moment, the webhook and callback will handle the response as they would when the payload wasn't expired.
Websocket Events
Websocket events to expect
Event
JSON
WARNING! Do not just rely on a `signed: true` indication! If you receive a websocket message with `signed: true` indication, always fetch the payload to confirm that all payment details are as expected.
Sample
The Websocket payload resolve message looks like:
The payload information the Websocket connection delivers does not contain the entire payload object. It should be considered a trigger to GET the entire payload using an SDK/API call:
Browser ("Web3")
Building a web app? Running as a client side SPA (single page webapp) or server side rendered? React Native / VueJS / VanillaJS / etc.: you can integrate with the Xumm ecosystem using our SDK.
The Xumm SDK can run fully client side: either as part of your compiled web app or using plain HTML and Javascript using our ready to use browserified version.
Using the Xumm SDK, you can easily add "Sign in with Xumm" capabilities to your web app. You don't even need a backend. You get the full "Web3" experience (sign in with a blockchain account) with our "Web2" compatible stack (see: Identity (OAuth2, OpenID) / Native Apps).
Make sure to add the return URL (also known as redirect URL) in the Xumm on the application home page in the "Origin/Redirect URIs (one per line)" field.
Capabilities
Using the Xumm SDK in your web project, you get:
Sign in with a QR code for when loaded on a desktop
Deeplink (redirect to Xumm, back to your web app) on mobile
Basic user information: XRP Ledger account address, icon (hashicon or even avatar), connected chain (mainnet, testnet, ..) & some basic information about the end user's environment (currency, language, ...)
Sample code
Please note the xumm.authorize() and xumm.logout() methods:
More links
For the SDK documentation (objects, methods), see the SDK section: . For a simple demo of the Xumm SDK in a React Native environment, check this sample repository:
xApps ("dApps")
Build your own web app to live in-app, inside Xumm for all Xumm users. Build an xApp. Use your favourite tools & frameworks for the client side code (HTML, CSS, JS, etc.
xApps are web apps. They are offered to users as integrated apps, opened in Xumm for a great user experience. They add value (tools, apps, wizards, ...) for end users. They receive context information when opened, and can interact with some of the native Xumm features & users through Sign Requests.
xApps have extra special permissions, allowing the xApp (web app) to interact with some of the native Xumm features:
They receive context (user account selected in Xumm when opened, Xumm theme, input params, account type (eg. Tangem / ...)
They can trigger overlay Sign Requests and receive callback info
They can trigger the QR scanner and receive scanned QR data
Opening xApps
xApps can be opened (triggered) in lots of ways:
In the Xumm shortlist (we feature some apps, they get replaced by frequently used apps by the user)
From the xApp directory
By opening a deeplink (browser / from within another app)
To prevent showing a double loader (first the Xumm xApp loader, then your xApp's loader while hydrating / booting) you can enable the "Xumm Loader Screen" option in the Xumm Developer Console (xApp tab).
See
Advanced ways to open xApps
By attaching an xApp memo to an XRPL TX (so the Event list will show there's an xApp attached to the TX)
Using push notifications
From the Event list, as an xApp session pushed to a Xumm user
xApp example use cases
Trading interface (offloads signing to Xumm)
Admission ticket checking
NFT marketplaces / viewers
Sample code
Implementation checklist
This article presents a concise implementation checklist for developers using Xumm. By following these steps, you can ensure a smooth and secure integration whilst optimizing the user experience.
Fetch Payload Results: Trigger your application to fetch payload results after receiving a Webhook callback.
Inspect Payload Output: Confirm meta.resolved and meta.signed are both true in the payload output.
Identify Dispatched Node Type: Ensure response.dispatched_nodetype is "MAINNET" for real payments.
Validate Transaction ID: Validate the response.txid value on the ledger.
Examine Delivered Amount: Confirm the meta.delivered_amount equals the expected payment amount.
Use xrpl-txdata Package: Establish a connection to the XRP Ledger, fetch the transaction by hash, and cross-verify transaction details with the XRPL ledger.
Network Independence: Use the Xumm API/SDK, which operates independently of the network, to allow users the freedom of network choice.
Network Information: Ensure the results of a signed payload include the network the user was on during the signing.
Forced Network Identifier: Check for the expected result in the Payload results or specify a particular network using a forced network identifier in a payload.
Secure Your Webhooks: Implement appropriate security measures.
xApp Creation & Audit: Anyone can create sandbox xApps, but public release requires an audit by XRPL Labs for user safety, compliance, and value addition.
User Experience: xApps must be self-explanatory, prevent dangerous mistakes, and provide a unique experience tailored to Xumm users.
Technical & Styling Standards: xApps must meet Xumm's technical guidelines and respect or have unique styling.
create( … )
To create a payload, a txjson XRPL transaction can be provided. Alternatively, a transaction formatted as HEX blob (string) can be provided in a txblob property.
Example contents of a payload
Take a look at the and possible replacement variables for the Return URLs.
The response of a Sdk.payload.create() operation, looks like this:
The next.always URL is the URL to send the end user to, to scan a QR code or automatically open the XUMM app (if on mobile). If a user_token has been provided as part of the payload data provided to Sdk.payload.create(), you can see if the payload has been pushed to the end user. A button "didn't receive a push notification" could then take the user to the next.no_push_msg_received URL. The
Alternatively user routing / instruction flows can be custom built using the QR information provided in the refs object, and a subscription for live status updates (opened, signed, etc.) using a WebSocket client can be setup by connecting to the refs.websocket_status URL. Please note: this SDK already offers subscriptions. There's no need to setup your own WebSocket client:
Object
TrustSet Link/QR
If you simply want to offer users a static link / QR code to sign a specific XRPL transaction, you can craft a link (to be offered directly or as contents of a QR code) for users to click / scan.
Offering a direct link / QR code to a payload does not come with the advantages of creating a Payloads (sign requests) of getting live feedback & webhooks based on the user's engagement.
The advantage of a simple Sign Link / QR is that you can craft the link / QR once, and it will be available for all users without further code implementations.
Simple Sign Link/QR is available for the following transaction type(s)
TrustSet (adding a Trust Line, a.k.a. adding a Token)
Crafting the link / QR contents
Example QR:
xApp
A sign request in Xumm is a prompt to approve a transaction or action on the XRP Ledger. This page will show you how you can create a Sign Request, and how you can deliver the request to the end user.
xApps are natively aware of the end user context, so a Sign Request payload can easily be served with the xumm.xapp.openSignRequest method:
For more information about the object contents to be used for Payloads & the return URL replacement variables, see:
The endpoints providing features to developers & integrated applications. The API endpoint reference can be found here: https://xumm.readme.io/reference but a more convenient way to interact with the Xaman Platform is through our SDK's (packages): https://docs.xumm.dev/#packages
Developer Console
The Developer Console is where you can get your credentials (API Key & secret) and configure your Xaman platform integration. You can find the Xaman Developer Console at https://apps.xumm.dev
When you send a call to the Xumm Platform to ask a user to sign a transaction, you are creating a "Sign Request". You are delivering a "Payload" (see below) to the Xumm platform, containing the transaction template you would like the user to sign & possibly some options. You obtain a unique UUID (identifier) to the Sign Request to get real time status updates, Webhooks upon status change & when signed: the on ledger Transaction Hash and signed transaction.
Payload
The Payload (JSON formatted) is part of a Sign Request. It contains the Transaction Template to offer to the end user to sign. The Payload matches the formatting, fields & properties of native XRP Ledger transactions, except for the fact that some fields (like Fee, Account, Sequence) can be omitted as Xaman can add these for you.
xApp
An xApp is a Web App (HTML, JS, CSS) that can be opened inside Xaman by users, straight from and in Xaman. See xApps ("dApps")
Frontend
When referred to Frontend, we refer to your frontend: the HTML/JS/CSS application you are building, where you are integrating Xaman as xApps ("dApps")or Browser ("Web3") application.
Backend
When referred to Backend, we refer to your backend application. If you are building an xApp or Web3 (Browser) app, you may not have and may not need your own backend. If you are building a backend integration (e.g. headless application, backend for your own Frontend application), please see Backend (SDK / API)
SDK
The most convenient way to interact with the Xaman Platform is through our SDK's (packages): https://docs.xumm.dev/#packages
JWT
JSON Web Token: the authorization bearer as provided by Xaman when using the xApps ("dApps") or Browser ("Web3") flow. Valid for 24h, bound to the Xum App user, you can call the Xaman platform to create Sign Requests & more.
OTT
"One Time Token", specific to xApps. Automatically handled for you when using our Javascript/Typescript SDK.
<html lang="en">
<body>
<h1 id="accountaddress">...</h1>
<button id="signinbutton" onclick="xumm.authorize()">Login</button>
<button id="logoutbutton" onclick="xumm.logout()">Logout</button>
<script src="https://xumm.app/assets/cdn/xumm.min.js"></script>
<script>
var xumm = new Xumm('your-api-key')
xumm.on("ready", () => console.log("Ready (e.g. hide loading state of page)"))
// We rely on promises in the `success` event: fired again if a user
// logs out and logs back in again (resets all promises)
xumm.on("success", async () => {
xumm.user.account.then(account => {
document.getElementById('accountaddress').innerText = account
})
})
xumm.on("logout", async () => {
document.getElementById('accountaddress').innerText = '...'
})
</script>
</body>
</html>
<html lang="en">
<body>
<h1 id="accountaddress">...</h1>
<script src="https://xumm.app/assets/cdn/xumm.min.js"></script>
<script>
var xumm = new Xumm('your-api-key')
xumm.on("ready", () => console.log("Ready (e.g. hide loading state of xApp)"))
// Account can't change (like Web3 logout/login) so we can rely on the promise
xumm.user.account.then(account => {
document.getElementById('accountaddress').innerText = account
})
</script>
</body>
</html>
When a payload (Sign Request) has been created and opened in your xApp, you probably want to be informed if the payload has been signed or rejected, then to check the payload results and act on the results. You can do so by subscribing to the payload event, see: Xumm.on(event, fn)
How to authorize when communicating with the Xumm platform depends on your workflow.
Authorization
Backend
When communicating with the Xumm platform from your backend environment, you will need a API Key and API Secret. They can be obtained from our , and are to be passed in the x-api-key and x-api-secret headers to our platform.
Frontend (browser, client side)
can use our , in which case the entire authorization is abstracted away. Under the hood, the user will go through an OAuth2-flow and a JWT (JSON Web Token) is obtained from our platform. This token is valid for 24 hours and user context bound.
If you are building your own frontend implementation, any OAuth2 (Implicit and PKCE flows both supported) client will do. See
Never use an API Secret obtained from the Developer Dashboard in a frontend environment! Anyone in possession of your API Secret (x-api-secret) can create payloads (Sign Requests) on behalf of your application. If abused, this can immensely damage the reputation of your application.
xApp
are loaded with several URL Query Paramters added, one of which is the xAppToken parameter. This parameter contains what we refer to as the "OTT", the "One Time Token". This token can be resolved by your application to a JSON response containing:
user context information
a JWT, JSON Web Token, allowing you to make subsequent calls to our platform
If you use our , this entire authorization flow is abstracted away by our SDK; the SDK (in the xApp, client side) will automatically resolve the xApp Token ("OTT") and use the JWT to make subsequent calls to our platform.
Native application
Any OAuth2 (Implicit and PKCE flows both supported) client will do. can redirect the user to our platform (to be redirected to the Xumm app) to sign in after which the client will be redirected back to your application (if your application supports deep links). You will obtain a JWT (JSON Web Token) to communicate to our platform from the user context. See:
Credentials
Backend
PKCE / JWT
xApps
Secure Payment Verification
Once a payment has been sent and the payload resolved on Xumm, some checks are performed to ensure secure payment verification. This document walks you through verifying a payment transaction on Xumm.
Payload Completion and Verification
After a payload completes its lifecycle, which includes creation, user interaction, transaction signing, and transaction submission to the XRP Ledger by Xumm, your application will receive (if configured) a Webhook callback.
This callback should trigger your application to fetch the payload results. It is highly advisable to fetch the payload results again on your "thank you" or "return" page in case you did not persist the payload results after receiving a Webhook.
Verifying Payment Transactions
Here are the steps to verify that you have indeed received a payment:
Check Payload Output: Verify if the Payload output contains meta.resolved. This value should be true. Otherwise, the payload is still pending or has been abandoned by the user. Also, check if the Payload output contains meta.signed. This value should be true, indicating that the user signed the transaction.
Check Response Dispatched Node Type: Verify the response.dispatched_nodetype
Fetching Transaction Details
You can fetch transaction details using the XRPL Transaction Data fetcher or the JSON RPC (HTTP POST) method at .
Utilizing (flow+code) the xrpl-txdata Package (JS/TS) for Transaction Verification
After sending a Sign Request () to Xumm, you receive a response with the signed transaction hash (: payloadResponse.txid, : txid).
You're in luck if you immediately check this transaction hash on the XRP Ledger, and it's already in a validated ledger. However, if the transaction hasn't been included in a closed ledger, you might encounter a "Not Found" error, while if you had checked a few seconds later, you'd have found the transaction.
To streamline this process, use the xrpl-txdata NPM package (JS/TS). This package simplifies:
Establishing a redundant (multi-node, failover) and reliable (auto-timeout, auto-retry) connection to the XRP Ledger
Fetching a transaction by hash
Optionally, monitoring the XRP Ledger (all closed ledgers, all the transactions in those ledgers) and waiting for a specified time (seconds).
Once your transaction is found, the package returns the transaction outcome and validated balance changes.
Here's how to use it in JavaScript:
Good Practice: Cross-verify with the XRPL
It is always a good practice to cross-verify with the XRPL for absolute certainty. Using the tx method, you can fetch transaction details directly from the XRPL ledger.
More information on how to do this can be found in the .
The Batch feature allows multiple transactions to be packaged together and executed as a single atomic transaction. Create and submit a batch of up to 8 transactions that succeed or fail atomically.
The Batch transaction type can be submitted through the Xaman API as any regular Sign Request (payload). It requires:
TransactionType "Batch"
Flags
Requirements
xApps are WebApps, embedded in Xumm for a great user experience. They add value (tooling, wizards) for end users, using Sign Requests and their Web UI to help users perform tasks on the XRPL and beyond.
Anyone can create sandbox xApp
Only you can use your own sandbox xApp from a specific Xumm installation you can whitelist after activating xApp features.
Browser
A sign request in Xumm is a prompt to approve a transaction or action on the XRP Ledger. This page will show you how you can create a Sign Request, and how you can deliver the request to the end user.
When working with Xumm sign in & payloads in the browser, there are two flows to consider. Your application should deal with both flows.
User is on mobile, Xumm is installed
User is on desktop, Xumm is on their phone
Xumm.on(event, fn)
Events fired by the SDK per environment. For the order of events, see the section per environment after the table with events.
Event
Environment
Meaning
xumm.on('payload', data => {
if (data?.uuid) {
xumm.payload.get(data.uuid).then(payload => {
// Payload contains the full paylaod data
})
}
})
xumm.on('payload', data => {
if (data?.uuid) {
const payload = await xumm.payload.get(data.uuid)
// Payload contains the full paylaod data
}
})
as integer, with one of the processing methods allowed for a Batch transaction:
ALLORNOTHING (tfAllOrNothing), Flag integer value: 65536
ONLYONE (tfOnlyOne), Flag integer value: 131072
UNTILFAILURE (tfUntilFailure), Flag integer value: 262144
INDEPENDENT (tfIndependent), Flag integer value: 524288
RawTransactions containing the inner transactions of the batch. Note that every single inner transaction needs to:
Have Fee at a string containing the value "0"
Have SigningPubkey as empty string ""
Have the Flags field contain the flag indicating it is an inner Batch transaction: 1073741824
Multiple 'inner' signers
One of the amazing features of Batch is the ability to atomically have multiple parties interact. Combined with ALLORNOTHING on the upper Batch, this allows for fully atomic transactions between multiple parties, where either every participant gets what they agreed to, or none of them do.
To use this feature, every individual party involved in the inner 'RawTransactions' need to provide a signature for the entire batch, then to be combined in the parent Batch. At this point any account (even one not participating in the inner Batch transactions) can bundle and submit, as the combined inner batch participant's transactions will satisfy the signing requirements.
Normally, the Batch transaction would require a formatted object with signers and signatures to be added to the Batch transaction in the BatchSigners field, as per XRPL's Batch specification.
To make it easier to deal with multiple inner signers, when using the Xaman SDK / API you can gather individual signer's transactions and then combine using only the Payload UUID's (or signed transaction blobs), at which point Xaman will 'unfurl' the information to craft a valid Batch transaction with multiple signers.
The workflow woud be as follows:
1. Multiple participants in `RawTransactions`
Craft the Batch transaction with the RawTransactions containing all transactions to be approved (signed) by different participants. At this stage the r-addresses for the individual transactions must already be known (see: SignIn). The overall Batch may look like below.
At this stage the upper Batch Transaction can have the Sequence/Ticket , Fee, and Account fields omitted. They don't have to be known yet, as they can be added later when the inner transactions are signed and any account can submit the bundle.
2. Gather individual inner transaction sigatures
As can be seen in the proposed JSON transaction above, two signers will need to approve the transaction:
rnMsCBhSWeK3ngU7JWkejHsYZs3UVWqNoQ
r38xHAWRdc5enrYsHKQxUzHf6javKrV3i4
Each participant can now be presented with the Batch to be approved, where the signer is pre-filled, and thus enforced. The payload will have to be created with submit: false as we don't want to try to submit, we just want to get a signature from the Batch participant.
This means if someone with Xaman installed without the specific account present with signing permissions, Xaman will reject the sign request.
Payload (sign request):
The same routine has then to be walked through for other signers.
3. Combine the inner transaction signatures and submit the Batch
Every Sign Request in the previous steps (per signer) is assigned an uuid. Gather those who are signed succesfully by the inner Batch transactions participants, to be combined (bundled) later to submit the Batch transaction. Now a specific signer is not required and submit can be true .
Note! While the official Batch spec requires a full signer object to be present in the BatchSigners field, Xaman accepts three different notations:
Conform native XRPL implementation: BatchSigners formatted object, containing an STArray with multiple signer pubkeys + their signature
Xaman specific (more convenient): the signed TX blob (as string) - this works for TX blobs signed by Xaman, or by any other XRPL signing implementation.
Xaman specific (most convenient): the signed Payload UUID - this works only if all signers are Xaman users.
If it doesn't, you might be accepting a TESTNET payment
!
Check Transaction ID: The response.txid value is the on-ledger transaction hash. You must verify this transaction on the ledger. Note that it may take around 4 seconds for a ledger to close and slightly longer for the ledger and transaction info to propagate. You may want to repeat async/delay fetching this info if you don't get a result at first or if your result contains a validated: false value.
⚠️ Check Delivered Amount: After fetching the transaction details, check the meta.delivered_amount value to see if the amount of XRP (in drops, one million drops = one XRP) equals the expected amount to be paid. This is a crucial step in the verification process.
The fact that you got a sandbox xApp is not to be presented anywhere as an endorsement (e.g. in communication like on social media, etc.))
To build an xApp, you need to have experience with Frontend Web Development as xApps are WebApps (loaded in Xumm)
xApps need to add value to a significant share of the Xumm user base
xApps need to be self explanatory to have clear instructions for end users
xApps need to be designed in a way where users can not make dangerous mistakes: users need to be protected
xApps developers can not be anonymous (accountability)
Promotion of speculation, pushing users towards buying tokens is not allowed (see: user protection)
Activating xApp features and building a sandbox xApp does NOT guarantee your xApp will be going live in the future. To take your xApp live, it will be audited by XRPL Labs. The rules above apply, security & usability will be tested. If you want to have more certainty in advance, please reach out.
All xApps
The xApp should be self explanatory, or do a good job explaining to the users what the xApp offers in the very first screen the xApp shows
xApps can not be designed in a way where it it completely unclear to end users if they are using a third party developed xApp or a XRPL Labs maintained component
xApps must not be a regular website/webapp fitted in an xApp: the user experience must be to seme degree tailored to users in Xumm, and must have relevance for Xumm users
xApps must not be in violation with Apple and Google App Store / Play Store requirements. For example, unlocking features based on NFTs owned is not allowed.
Technical
All links to external sites / window opens must be replaced by a openBrowser call on the Xumm SDK: Xumm UI interaction so that users won't reach another website through navigating in the xApp
No polling should be used: to retrieve the status of a payload, use the websocket we provide for status updates (or the createAndSubscribe / subscribe method provided by the SDK: / ). Backend applications can also use a webhook: .
Accessibility
Simple accessible navigation
Clear icons:
Reduce clutter: Keep minimum content on screen
Use accessible fonts
Use minimal of 16pt font for standard body text
Test on different devices:
Manage information on a logical level
Consistency in design
Use a 40x40px target area for touch controls
Good (horizontal) alignment:
Distinction between primary and secondary Buttons:
xApps should either have their own colour scheme (dark/light mode independent) or respect the Xumm colour schemes: Style guide. The end user styling will be passed to the xApp using the xAppStyle query parameter.
The xApp <html> and <body> tag must have a transparent background color right upon page load, so the xApp doesn't 'flicker' white while loading, until styling has been applied (rendered by the browser).
Sandboxed xApps
Full access, no restrictions, but only for the developer and max. 10 testers (whitelisted by Device UUID in the Xumm Developer Console)
Link (QR/Deeplink) only xApps
The xApp should look appealing
The xApp should respect different Xumm user screen sizes
The xApp should be well crafted: it should be clear what the xApp will do, and it should do what the xApp promised to do
The xApp should have a clear Support workflow & offer terms & conditions & a privacy statement
Public (listed) xApps
The xApp should not be a "launchpad" to something that could be perfectly located at a website: if there is no actual Xumm wallet/XRPL interaction where the integration with Xumm adds value, it should be a website, not an xApp
Offer value (features people will appreciate/need) for a large part of the XRPL / Xumm user base
The frontend source code must either be open source, shared (under NDA) with XRPL Labs for review or a third party security audit (code & dependencies + dependency update procedures) acceptable by XRPL Labs has to be provided.
Mobile
When a user visits on their smartphone with Xumm installed, your application can "deeplink" straight into Xumm, where a Sign Request will be opened.
If your application can persist state, you can use a return URL to get your user to return to your web app.
If you need the user to return to the launching webpage, do not provide a return URL to the payload, so the user is forced to go back to the launching browser.
To make sure the user is expecting Xumm to open, the best user experience would be to ask the user to open Xumm (with a button), alternatively allowing them to use a button to just show the QR code, so the Sign Request can be opened on another device.
Warning: most mobile browsers / operating systems will only allow deeplinks to trigger an application (so: the payload URL to trigger opening Xumm) if the button resulting in the trigger is user invoked.
Meaning there must always be a direct user onclick/ontap event resulting in the routine opening the payload URL being opened will deeplink.
Desktop
On the desktop, a user may or may not receive a push notification. The user can scan a QR code as fallback. The ideal implementation:
Checks if the pushed property of the created payload
If false the user is displayed the payload QR code to scan with their phone.
Using the method the application receives real time updates about end user interaction. The application can update to reflect the interaction the user has with the Sign Request on their phone ("opened": true).
If true the user is displayed a message that the Sign Request has been delivered to their phone. A button with a label like "I did not receive the Push Notification" is displayed, which takes users to the QR flow.
ready
xApp, Web3 (browser)
The SDK is ready (final state) so your application can render
retrieving
Web3 (browser)
The SDK is trying to retrieve & verify an existing session
logout
Web3 (browser)
The SDK is going to destroy a pending signed in session
loggedout
Web3 (browser)
The SDK destroyed a signed in session, a user can login again.
error
Web3 (browser)
An error occurred, see the browser console for more information
qr
The QR code scan dialog in Xumm has been closed (dismissed or a QR code has been scanned)
From:
payload
A Sign Request (payload) has been resolved (cancelled / signed / ...)
From:
destination
The "Destination Picker" dialog in Xumm has been closed (dismissed or a destination has been selected)
From:
networkswitch
The user switched the selected network in Xumm while present in the xApp, while your xApp settings (Xumm Developer Console) indicate the xApp shouldn't reload but receive an event.
network contains key.
Event order
The following order of events can be expected per environment.
Note about the ready vs the success event:
The ready event fires if the SDK state is ready for the rendering of your application. This does not have to mean the SDK is signed in: it just means the SDK is ready.
If you want to know a user
xApp (always auto-signed in)
retrieved - xApps always auto-resolve
success- all information is populated to SDK properties (Promises)
ready - ready to render your application with the correct Xumm SDK state
Web3 (browser) - Signed out & then signing in
retrieving - but the user is signed out
ready - ready to render your application with the correct Xumm SDK state, but the user must still log in
The user signs in
success - all information is populated to SDK properties (Promises)
Web3 (browser) - Already signed in
retrieving - existing session information is being fetched & verified
success - all information is populated to SDK properties (Promises)
retrieved - you are dealing with an already signed in user
ready - ready to render your application with the correct Xumm SDK state
retrieved
xApp, Web3 (browser)
A valid signed in Xumm SDK session has been retrieved.
success
xApp, Web3 (browser)
A user is succesfully identified and signed in
Identity (OAuth2, OpenID)
The Xumm platform can act as the OAuth2 provider. The Xumm platform supports the OAuth2 / OpenID Connect flow. Authenticate and identify end users using their self custodial XRPL accounts.
All credentials created in the Xumm Developer Console (https://apps.xumm.dev) will work with the OAuth2 / OpenID Connect flow.
OAuth2 flows
The Xumm OAuth2 / OpenID Connect provider supports the authorization code flow and the implicit flow.
The PKCE flow (which is the new & more secure industry standard and replaces the Implicit flow) is also available.
All supported OAuth2 flows have their own use cases, advantages and caveats. The right one depends on your project & audience.
Authorization code
PKCE
Implicit
Credentials & Redirect URLs
To use the Xumm Platform as OAuth2 / OpenID Connect provider, one or more valid OAuth2 redirect URI's must be whitelisted in the , on an application level.
The same API Key and API Secret the Xumm Developer Console offers to be used calling our API's and using our SDK's can be used as OAuth2 client id and secret.
Obtained credential (bearer)
The Xumm platform returns a Bearer token (JWT) with limited validity. The token can not be refreshed: after expiration a new user sign in is mandatory to obtain a new JWT token.
When using the (TypeScript & Javascript) all OAuth2/JWT interaction, authorisation & implementation will be abstracted away, which is by far the easiest way to interact with the Xumm platform.
Building your own integration, or using a standard OAuth2 consumer? All JWT tokens obtained through from a Xumm OAuth2 flow can be used with the (from a user locked context). The way to interact with the JWT endpoints is similar to the JWT flow for xApps, except the JWT is obtained through the OAuth2 flow instead of inside the xApp.
All JWTs the obtained by a successful user sign in are valid for one day (24h)
Auth URL
Special parameters
force_network allows you to specify a network the payload will have to be signed on. Sample values are MAINNETTESTNETXAHAUXAHAUTESTNET, etc.
signers allows you to specify one or more forced signers, by r-address, seperated by a comma (if multiple are to be provided where the user can choose from, providing they have signing capabilities for the account(s))
const {TxData} = require('xrpl-txdata')
const TxHash = '8F3CE0481EF31A1BE44AD7D744D286B0F440780CD0056951948F93A803D47F8B'
const VerifyTx = new TxData([
'wss://xrplcluster.com',
'wss://xrpl.link',
// Or:
// 'wss://testnet.xrpl-labs.com'
], {
OverallTimeoutMs: 6000,
EndpointTimeoutMs: 1500,
// If using testnet, see above:
// AllowNoFullHistory: true
})
// Specify the transaction hash to verify and the # of seconds
// to wait & monitor the XRPL if not found initially.
VerifyTx.getOne(TxHash, 20)
.then(tx => {
console.log(`Got the TX, details:`, tx)
})
const paload = await xumm.payload.create({
txjson: {
TransactionType: "Payment",
Destination: "r...",
Amount: "1000000"
},
options: {
return_url: {
app: "https://sample.test/?...",
web: "https://sample.test/?id={id}"
},
force_network: "MAINNET"
},
custom_meta: {
identifier: "123123",
instruction: "Please sign this to..."
}
})
// Now assigin the link to a button or redirect the user straight away to:
// payload.next.always
xumm.payload.createAndSubscribe({
TransactionType: 'Payment',
Destination: 'rfHn6cB5mmqZ6fHZ4fdemCDSxqLTijgMwo',
Amount: String(1000000) // one million drops, 1 XRP
}, eventMessage => {
if ('opened' in eventMessage.data) {
// Update the UI? The payload was opened.
}
if ('signed' in eventMessage.data) {
// The `signed` property is present, true (signed) / false (rejected)
return eventMessage
}
})
.then(({ created, resolved }) => {
console.log('Payload URL:', created.next.always)
console.log('Payload QR:', created.refs.qr_png)
return resolved // Return payload promise for the next `then`
})
.then(payload => console.log('Payload resolved', payload))
// This is where you can do `xumm.payload.get(...)` to fetch details
const { created, resolved } = await xumm.payload.createAndSubscribe({
TransactionType: 'Payment',
Destination: 'rfHn6cB5mmqZ6fHZ4fdemCDSxqLTijgMwo',
Amount: String(1000000) // one million drops, 1 XRP
}, eventMessage => {
if ('opened' in eventMessage.data) {
// Update the UI? The payload was opened.
}
if ('signed' in eventMessage.data) {
// The `signed` property is present, true (signed) / false (rejected)
return eventMessage
}
})
console.log('Payload URL:', created.next.always)
console.log('Payload QR:', created.refs.qr_png)
const payload = await resolved
console.log('Resolved', payload)
{
TransactionType:"Payment",
Destination:"r...",
Amount:"1000000"
},
options:{
return_url:{
app:"https://sample.test/?...",
web:"https://sample.test/?id={id}"
},
force_network:"MAINNET"
},
custom_meta:{
identifier:"123123",
instruction:"Please sign this to..."
}
}).then(payload=>{
// Redirect directly to payload.next.always, or (preferable)
You deal with the mobile return flow state persistence. You will have to make sure you restore your session to cover sessions where user return in another browser.
Only works on mobile when users leave and return from & to the same browser. E.g. when starting off in a Twitter embedded browser frame & returning to the native OS browser, the sign in will fail.
Works on mobile even when users start in one browser and get redirected to another browser (e.g. the OS native browser). Basically always works.
You deal with the desktop sign in flow (redirect / popup / ...)
Xumm SDK (TypeScript/Javascript) will trigger a pop up & handle sign state & events.
Xumm SDK (TypeScript/Javascript) will trigger a pop up & handle sign state & events.