XUMM.NET.SDK 1.9.3

dotnet add package XUMM.NET.SDK --version 1.9.3
NuGet\Install-Package XUMM.NET.SDK -Version 1.9.3
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="XUMM.NET.SDK" Version="1.9.3" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add XUMM.NET.SDK --version 1.9.3
#r "nuget: XUMM.NET.SDK, 1.9.3"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install XUMM.NET.SDK as a Cake Addin
#addin nuget:?package=XUMM.NET.SDK&version=1.9.3

// Install XUMM.NET.SDK as a Cake Tool
#tool nuget:?package=XUMM.NET.SDK&version=1.9.3

XUMM.NET.SDK XUMM.NET.SDK

Interact with the XUMM SDK from .NET / C# environments.

Install XUMM.NET.SDK in server-side Blazor App

  1. Create a new ASP.NET Core Blazor Server-App project.
  2. Install NuGet-package: XUMM.NET.SDK.
  3. Add the following code block at the end of the services in Program.cs:
builder.Services.AddXummNet(builder.Configuration);
  1. Add the following configuration in appsettings.json:
  "Xumm": {
    "RestClientAddress": "https://xumm.app/api/v1",
    "ApiKey": "", // API Key which can be obtained from the xumm Developer Console.
    "ApiSecret": "" // API Secret which can be obtained from the xumm Developer Console.
  },
  1. Hit F5: you're now running a completely empty Blazor server-side App with XUMM.NET.
  2. Start building your app. For reference, browse the XUMM.NET.ServerApp to see all the options.

Credentials

The SDK will look in your appsettings for the ApiKey and ApiSecret values. Optionally the RestClientAddress can be provided. An example appsettings file is provided in this repository. Alternatively you can provide your XUMM API Key & Secret by passing them like:

builder.Services.AddXummNet(o =>
    {
        o.ApiKey = "00000000-0000-0000-000-000000000000";
        o.ApiSecret = "00000000-0000-0000-000-000000000000";
    });

Create your app and get your XUMM API credentials at the XUMM Developer Console:

More information about the XUMM API, payloads, the API workflow, sending Push notifications, etc. please check the XUMM API Docs:

Multiple Xumm Applications support

You can create an instance of XummSdk if your .NET application has to connect to multiple Xumm Applications. The XummSdk class contains client properties instead of using the clients by dependency injection.

  • IXummMiscAppStorageClient: XummSdk.AppStorage
  • IXummMiscClient: XummSdk.Miscellaneous
  • IXummPayloadClient: XummSdk.Payload
var xummSdk = new XummSdk("00000000-0000-0000-000-000000000000", "00000000-0000-0000-000-000000000000");
var pong = await xummSdk.Miscellaneous.GetPingAsync();
IXummMiscClient.GetPingAsync()

The GetPingAsync() method allows you to verify API access (valid credentials) and returns some info on your XUMM APP:

@inject IXummMiscClient MiscClient
var pong = await MiscClient.GetPingAsync();

Returns: XummPong

var pong = new XummPong
{
    Pong = true,
    Auth = new XummAuth
    {
        Quota = new Dictionary<string, object>
        {
            { "ratelimit", null}
        },
        Application = new XummApplication
        {
            Uuidv4 = "00000000-1111-2222-3333-aaaaaaaaaaaa",
            Name = "My XUMM APP",
            WebhookUrl = "",
            Disabled = 0
        },
        Call = new XummCall
        {
            Uuidv4 = "bbbbbbbb-cccc-dddd-eeee-111111111111"
        }
    }
}
IXummMiscClient.GetKycStatusAsync()

The GetKycStatusAsync() return the KYC status of a user based on a UserToken, 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 XummKycStatus.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.

@inject IXummMiscClient MiscClient
var kycStatus = await MiscClient.GetKycStatusAsync("rBLomsmaSJ1ttBmS3WPmPpWLAUDKFwiF9Q");

Returns: XummKycStatus

Notes on KYC information
  • 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.
IXummMiscClient.GetTransactionAsync()

The GetTransactionAsync() 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:
npm version

@inject IXummMiscClient MiscClient
var txInfo = await MiscClient.GetTransactionAsync("00000000-0000-0000-0000-000000000000");

Returns: XummTransaction

IXummXAppJwtClient.GetNFTokenDetailAsync()

The GetNFTokenDetailAsync 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!

@inject IXummXAppJwtClient XAppJwtClient
var detall = await XAppJwtClient.GetNFTokenDetailAsync("", "");

Returns: XummXAppJwtNFTokenDetail

App Storage

App Storage allows you to store a JSON object at the XUMM API platform, containing max 60KB of data. Your XUMM APP storage is stored at the XUMM API backend, meaning it persists until you overwrite or delete it.

This data is private, and accessible only with your own API credentials. This private JSON data can be used to store credentials / config / bootstrap info / ... for your headless application (eg. POS device).

@inject IXummMiscAppStorageClient MiscAppStorageClient

var storageSet = await MiscAppStorageClient.StoreAsync({name: 'Dominique', age: 32, male: true});
Console.WriteLine(storageSet.Stored)
// true

var storageGet = await MiscAppStorageClient.GetAsync()
Console.WriteLine(storageGet.Data)
// { name: 'Dominique', age: 32, male: true }

var storageDelete = await MiscAppStorageClient.ClearAsync()
Console.WriteLine(storageSet.Stored)
// true

var storageGetAfterDelete = await MiscAppStorageClient.GetAsync()
Console.WriteLine(storageGetAfterDelete.Data)
// null
Payloads
Intro

Payloads are the primary reason for the XUMM API (thus this SDK) to exist. The XUMM API Docs explain 'Payloads' like this:

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:

var payload = new XummPostJsonPayload(
        "{ \"TransactionType\": \"Payment\", " + 
        "\"Destination\": \"rBLomsmaSJ1ttBmS3WPmPpWLAUDKFwiF9Q\", " + 
        "\"Amount\": \"1337\" }");

As you can see the payload looks like a regular XRPL transaction, wrapped in an TxJson object, omitting the mandatory Account, Fee and Sequence properties. They will be added containing the correct values when the payload is signed by an app user.

Optionally (besides TxJson) a payload can contain these properties (XummPayloadBodyBase definition):

  • XummPayloadOptions to define payload options like a return URL, expiration, etc.
  • XummPayloadCustomMeta to add metadata, user instruction, your own unique ID, ...
  • UserToken to push the payload to a user (after obtaining a user specific token)

A reference for payload options & custom meta can be found in the API Docs.

Instead of providing a TxJson transaction via XummPostJsonPayload, a transaction formatted as HEX blob (string) can be provided in a TxBlob property via XummPostBlobPayload.

IXummPayloadClient.GetAsync

To get payload details, status and if resolved & signed: results (transaction, transaction hash, etc.) you can GetAsync() a payload.

Note! Please don't use polling! The XUMM API offers Webhooks (configure your Webhook endpoint in the Developer Console) or use a subscription to receive live payload updates (for non-SDK users: Webhooks).

You can GetAsync() a payload by:

  • Payload UUID

    @inject IXummPayloadClient PayloadClient
    var payload = await PayloadClient.GetAsync("00000000-0000-0000-0000-000000000000");
    
  • Passing a created Payload object (see: IXummPayloadClient.CreateAsync)

    @inject IXummPayloadClient PayloadClient
    var newPayload = new XummPostJsonPayload("{...}");
    var created = await PayloadClient.CreateAsync(newPayload);
    var payload = await PayloadClient.GetAsync(created);
    

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 exception in case a payload can't be retrieved:

@inject IXummPayloadClient PayloadClient
var payload = await PayloadClient.GetAsync("00000000-0000-0000-0000-000000000000", true);
IXummPayloadClient.CreateAsync

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. See the Intro for more information about payloads. Take a look at the Developer Docs for more information about payloads.

The response (see: Developer Docs) of a IXummPayloadClient.CreateAsync() operation, a <XummPayloadResponse> object, looks like this:

var payload = new XummPayloadResponse
{
    Uuid = "1289e9ae-7d5d-4d5f-b89c-18633112ce09",
    Next = new XummPayloadNextResponse
    {
        Always = "https://xumm.app/sign/1289e9ae-7d5d-4d5f-b89c-18633112ce09",
        NoPushMessageReceived = "https://xumm.app/sign/1289e9ae-7d5d-4d5f-b89c-18633112ce09/qr"
    },
    Refs = new XummPayloadRefsResponse
    {
        QrPng = "https://xumm.app/sign/1289e9ae-7d5d-4d5f-b89c-18633112ce09_q.png",
        QrMatrix = "https://xumm.app/sign/1289e9ae-7d5d-4d5f-b89c-18633112ce09_q.json",
        QrUriQualityOpts = new List<string> { "m", "q", "h" },
        WebsocketStatus = "wss://xumm.app/sign/1289e9ae-7d5d-4d5f-b89c-18633112ce09"
    },
    Pushed = true
};

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 UserToken has been provided as part of the payload data provided to IXummPayloadClient.CreateAsync(), 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.NoPushMessageReceived URL. The alternatively user routing / instruction flows can be custom built using the QR information provided in the XummPayloadRefsResponse object, and a subscription for live status updates (opened, signed, etc.) using a WebSocket client can be setup by conneting to the Refs.WebsocketStatus URL. Please note: this SDK already offers subscriptions. There's no need to setup your own WebSocket client, see Payload subscriptions: live updates. There's more information about the payload workflow and a payload lifecycle in the Developer Docs.

IXummPayloadClient.CancelAsync

To cancel a payload, provide a payload UUID (string), a <XummPayloadResponse> (by performing a IXummPayloadClient.GetAsync() first) or a <XummPayloadDetails> (by using the response of a IXummPayloadClient.CreateAsync() 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 XummDeletePayload response looks like:

var deletedPayload = new XummDeletePayload
{
    Result = new XummDeletePayloadResult
    {
        Cancelled = true,
        Reason = "OK"
    },
    Meta = new XummPayloadDetailsMeta
    {
        Uuid = "1289e9ae-7d5d-4d5f-b89c-18633112ce09"
    }
};
Payload subscriptions: live updates

To subscribe to live payload status updates, the XUMM .NET SDK can setup a WebSocket connection and monitor live status events. Emitted events include:

  • 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)

More information about the status update events & sample event data can be found in the Developer Docs.

Status updates can be processed by providing a callback function to the IXummPayloadClient.SubscribeAsync() method.

The subscription will be closed by either:

  • Requesting a cancellation via the CancellationToken passed to the IXummPayloadClient.SubscribeAsync() method.
  • Manually calling <XummSubscriptionEventArgs>.CloseConnectionAsync() on the event returned by the IXummPayloadClient.SubscribeAsync() event handler.
IXummPayloadClient.SubscribeAsync

For every payload specific event the callback function will be called with <XummSubscriptionEventArgs>. The <XummSubscriptionEventArgs>.Data property contains parsed JSON containing event information.

Resolving (by requesting a cancellation or calling CloseConnectionAsync() manually) closes the WebSocket client the XUMM SDK sets up 'under the hood'.

Examples:

IXummPayloadClient.CreateAndSubscribeAsync

All information that applies on IXummPayloadClient.CreateAsync() and IXummPayloadClient.SubscribeAsync() applies. Only differences is that the input for a IXummPayloadClient.CreateAndSubscribeAsync() call isn't a payload UUID / existing payload, but a payload to create.

Debugging (logging)

The XUMM .NET SDK will emit logs with the use of https://docs.microsoft.com/en-us/dotnet/core/extensions/logging

Product Compatible and additional computed target framework versions.
.NET net5.0 is compatible.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp3.1 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.9.3 151 12/12/2023
1.9.2 276 9/14/2023
1.9.1 146 9/5/2023
1.9.0 151 6/23/2023
1.8.2 185 4/3/2023
1.8.1 208 3/20/2023
1.8.0 290 1/2/2023
1.7.1 365 11/4/2022
1.7.0 367 10/5/2022
1.6.7 374 9/5/2022
1.6.6 379 8/28/2022
1.6.5 379 8/24/2022
1.6.4 407 6/22/2022
1.6.3 399 6/13/2022
1.6.2 406 6/10/2022
1.6.1 393 6/10/2022
1.6.0 380 5/30/2022
1.5.1 385 5/25/2022
1.5.0 388 5/24/2022
1.4.1 386 5/9/2022
1.4.0 402 4/19/2022
1.3.1 391 3/30/2022
1.3.0 388 3/29/2022
1.2.0 382 3/23/2022
1.1.1 389 3/12/2022
1.1.0 397 3/10/2022
1.0.0 397 3/9/2022