Xaman Wallet Integration

Starting from version 1.1.0 Xaman Wallet is one of the authentication options available to all experiences. The authentication is handled automatically by this SDK. See below for signing and sending transactions.

Asset management

An integral part of any experience is being able to fetch assets that a user owns and allowing them to interact with them within an experience.

Users may fetch assets and token balances by utilising available hooks within the @futureverse/react library or manually through the FV graph. All react hooks have been built using an apollo query interface and allow for caching, custom configuration and more.

We recommend using useTrnApi hook and follow the types and JSDocs for signing and sending transactions. The SDK automatically recognises the authentication type and handles the wallet connection and blockchain interaction.

Fetching

  • Use hooks within @futureverse/react library

  • Alternatively, use the FV graph directly

Display balance

  • Use hooks with @futureverse/react to retrieve token balances and display them how you like

  • Alternatively, use the FV graph directly

Bridging

  • Wagmi/Web3 JS

  • TRN /polkadot client

  • Use useTrnApi hook and its methods

Sending - coming soon

  • Wagmi/Web3 JS

  • TRN /polkadot client

  • Use useTrnApi hook and its methods

useTrnApi hook

TRN API is a react hook exported from the @futureverse/react package that can be used to estimate transaction fees, sign and send transactions.

This hook provides a convenient way for experiences to interact with the root network without worrying about the connected wallet. It internally detects the connected wallet and communicates with it as per the request.

Import useTrnApi

import { useFutureverse, useTrnApi } from '@futureverse/react'

export function YourReactFunction(){
  const {
    trnApi, // A polkadot api that can be used to communicate with the root node.
    createTrnDispatcher, // a helper function to create TrnDispatcher that is used to estimate fees, sign and submit a transaction.
  } = useTrnApi()
  ...
}

Create a new extrinsic

trnApi from useTrnApi hook can be used to create extrinsics on root network. following are some of sample transfer extrinsics.

  const tokenTransfer = trnApi.tx.balances.transfer(
    '0xabcdef1234567890abcdef1234567890abcdef12', // toAddress
    100 // amount
  )

  const tokenTransferOfAssetId = trnApi.tx.assets.transfer(
    1, // assetID
    '0xabcdef1234567890abcdef1234567890abcdef12', // toAddress
    100 // amount
  )

  const nftTransfer = trnApi.tx.nft.transfer(
    10, // collectionId
    ['1'], // tokenIds
    '0xabcdef1234567890abcdef1234567890abcdef12' // toAddress
  )

createTrnDispatcher

Creates a TRN transaction dispatcher for Wagmi or Xaman based on the detected authentication method.

Parameters

  • options (Object): The options for creating the dispatcher.

    • wagmiOptions (Object): The options for the Wagmi signer.

      • signer (Object): The Wagmi signer instance.

      • signerOptions (Object, undefined): Additional options for the Wagmi signer.

    • xamanOptions (Object): The options for the Xaman signer.

      • signMessageCallbacks (Function, undefined): Callbacks for the sign message.

      • instruction (string, undefined): Custom instruction for the Xaman signer. The default is 'Sign extrinsic'.

    • onSignatureSuccess (Function, undefined): Callback to be called on successful signature.

    • feeAssetId (string, undefined): The asset ID to be used for fees. The default is XRP_ASSET_ID.

    • wrapWithFuturePass (boolean, undefined): Flag to wrap with Futurepass. The default is false. It always wraps with the FuturePass if a delegated login is detected.

Returns

  • trnDispatcher (Object|null): The dispatcher object with estimate and signAndSend methods, or null if the detected authentication method is custodial.

Throws

  • Error: Throws an error if the API or user session is not ready.

  • Error: Throws an error if the Wagmi signer is not provided.

  • Error: Throws an error if the authentication method is unsupported.

Example

import {
  useAuthenticationMethod,
  useFuturePassAccountAddress,
  useTrnApi,
} from '@futureverse/react'
import { useMemo, useState } from 'react'
import * as fvSdk from '@futureverse/experience-sdk'
import * as wagmi from 'wagmi'

export function YourReactFunction() {
  const { createTrnDispatcher } = useTrnApi()
  const { data: futurePassAccount } = useFuturePassAccountAddress()
  const authenticationMethod = useAuthenticationMethod()

  // modify these two variables to match your use case
  const senderAddress = '0x1234567890abcdef1234567890abcdef12345678'
  const feeOptions = {
    assetId: 2,
    slippage: 0.05,
  }

  const { data: signer } = wagmi.useSigner()

  const [signAndSubmitStep, setSignAndSubmitStep] = useState<string>()
  // Optionally use this to display a QR code for XRPL user to scan
  const [_xamanData, setXamanData] = useState<{
    qrCodeImg: string
    deeplink: string
  }>()

  const trnDispatcher = useMemo(() => {
    try {
      if (!futurePassAccount || !signer || !senderAddress)
        throw new Error(
          `${
            !futurePassAccount
              ? 'futurePassAccount'
              : !signer
                ? 'signer'
                : 'senderAddress'
          } was undefined`
        )

      return createTrnDispatcher({
        wrapWithFuturePass: fvSdk.addressEquals(
          senderAddress,
          futurePassAccount
        ),
        feeOptions: {
          assetId: feeOptions?.assetId ?? fvSdk.XRP_ASSET_ID,
          slippage: feeOptions?.slippage ?? 0.05,
        },
        wagmiOptions: {
          signer,
        },
        xamanOptions: {
          signMessageCallbacks: {
            onRejected: () => setSignAndSubmitStep(undefined),
            onCreated: createdPayload => {
              setXamanData({
                qrCodeImg: createdPayload.refs.qr_png,
                deeplink: createdPayload.next.always,
              })
              setSignAndSubmitStep('waitingForSignature')
            },
          },
        },
        onSignatureSuccess:
          authenticationMethod === 'xaman'
            ? () => {
                setSignAndSubmitStep('submittingToChain')
              }
            : undefined,
      })
    } catch (err: any) {
      console.warn('Unable to create dispatcher:', err.message)
    }
  }, [
    authenticationMethod,
    createTrnDispatcher,
    futurePassAccount,
    senderAddress,
    signer,
    feeOptions,
  ])
}

Estimate Transaction fees

The trnDispatcher.estimate function can be used to estimate the transaction fees for a given transaction.

Parameters

  • extrinsic (Extrinsic): The extrinsic to be estimated.

  • assetId (number|undefined): The asset ID to be used for fees.

Returns

  • Promise<bigint>: A promise that resolves to the estimated fee.

Throws

  • Error: If an error occurs during the estimation process.

Example

  ...
  const estimateFee = useCallback(
    async (extrinsic: fvSdk.Extrinsic) => {
      if (!trnDispatcher || !extrinsic)
        throw new Error(
          `Unable to submit extrinsic: ${
            !trnDispatcher ? 'dispatcher' : 'extrinsic'
          } was undefined`
        )

      const result = await trnDispatcher.estimate(
        extrinsic, // root extrinsic
        feeOptions?.assetId // assetId in which fees should be estimated.
      )
      if (!result.ok)
        throw new Error(`Error estimating fee: ${result.value.cause}`)

      return BigNumber.from(result.value)
    },
    [trnDispatcher, feeOptions]
  )
  ...

Sign and submit a transaction

trnDispatcher.signAndSend can be used to sign and send an extrinsic.

Parameters

  • extrinsic (SubmittableExtrinsic<'promise'>): The extrinsic to be signed and sent.

Returns

  • Promise<Object>: The result of the transaction.

    • return.ok (boolean): Indicates if the transaction was successful.

    • return.value (Object, undefined): Contains details of the transaction if successful.

      • return.value.extrinsicId (string): The ID of the extrinsic.

      • return.value.transactionHash (string): The hash of the transaction.

    • Error (Object, undefined): An error object if the transaction failed.

Throws

  • Error: If an error occurs during the signing or sending process.

Example

...
  const submitExtrinsic = useCallback(
    async (extrinsic: fvSdk.Extrinsic) => {
      if (!trnDispatcher || !extrinsic)
        throw new Error(
          `Unable to submit extrinsic: ${
            !trnDispatcher ? 'dispatcher' : 'extrinsic'
          } was undefined`
        )

      const result = await trnDispatcher.signAndSend(extrinsic)

      if (!result.ok)
        throw new Error(`Error submitting extrinsic: ${result.value.cause}`)

      return result.value
    },
    [trnDispatcher]
  )
  ...

Example

A complete example can be found in the Futureverse Experience Next Demo.

Last updated

© 2023 -> ♾️