Integrate Web3Auth with the XRPL Blockchain
The Embedded Wallets Web SDK includes an XRPL private key provider, XrplPrivateKeyProvider,
exported from the @web3auth/modal/providers/xrpl-provider subpath. It handles XRPL JSON-RPC
methods such as xrpl_getAccounts and xrpl_signTransaction. After sign-in, send these requests
through connection.ethereumProvider, which routes to the XRPL provider when you pass it as
privateKeyProvider.
Installation
- npm
- Yarn
- pnpm
- Bun
npm install --save @web3auth/modal xrpl
yarn add @web3auth/modal xrpl
pnpm add @web3auth/modal xrpl
bun add @web3auth/modal xrpl
Getting the chainConfig
- Mainnet
- Testnet
- Devnet
- Chain Namespace: XRPL
- Chain ID: 0x1
- Public RPC URL:
https://ripple-node.tor.us(Avoid using public rpcTarget in production, use services like Infura) - WebSocket URL (
wsTarget): wss://s2.ripple.com - Ticker: XRP
- Ticker Name: XRPL
- Display Name: xrpl mainnet
- Block Explorer Link:
https://livenet.xrpl.org
- Chain Namespace: XRPL
- Chain ID: 0x6
- Public RPC URL:
https://testnet-ripple-node.tor.us(Avoid using public rpcTarget in production, use services like Infura) - WebSocket URL (
wsTarget): wss://s.altnet.rippletest.net - Ticker: XRP
- Ticker Name: XRPL
- Display Name: xrpl testnet
- Block Explorer Link:
https://testnet.xrpl.org
- Chain Namespace: XRPL
- Chain ID: 0x3
- Public RPC URL:
https://devnet-ripple-node.tor.us(Avoid using public rpcTarget in production, use services like Infura) - WebSocket URL (
wsTarget): wss://s.devnet.rippletest.net/ - Ticker: XRP
- Ticker Name: XRPL
- Display Name: xrpl devnet
- Block Explorer Link:
https://devnet.xrpl.org
Initializing provider
XRPL requires an XrplPrivateKeyProvider passed as privateKeyProvider in
Web3AuthOptions. Without it, initialization
fails for XRPL chains. Pass the XRPL chain in chains and set it as defaultChainId. The chain
config must include wsTarget.
import { CHAIN_NAMESPACES, Web3Auth, WEB3AUTH_NETWORK } from '@web3auth/modal'
import type { IProvider } from '@web3auth/modal'
import { XrplPrivateKeyProvider } from '@web3auth/modal/providers/xrpl-provider'
const chain = {
chainNamespace: CHAIN_NAMESPACES.XRPL,
chainId: '0x6',
rpcTarget: 'https://testnet-ripple-node.tor.us',
wsTarget: 'wss://s.altnet.rippletest.net',
ticker: 'XRP',
tickerName: 'XRPL',
displayName: 'xrpl testnet',
blockExplorerUrl: 'https://testnet.xrpl.org',
logo: '',
}
const privateKeyProvider = new XrplPrivateKeyProvider({
config: { chain, chains: [chain] },
})
const web3auth = new Web3Auth({
clientId,
web3AuthNetwork: WEB3AUTH_NETWORK.SAPPHIRE_MAINNET,
privateKeyProvider,
chains: [chain],
defaultChainId: '0x6',
})
await web3auth.init()
await web3auth.connect()
const provider: IProvider | null = web3auth.connection?.ethereumProvider ?? null
In React, pass the same options in web3AuthOptions of Web3AuthContextConfig and read the
provider from useWeb3Auth().connection?.ethereumProvider. See the
XRPL example on GitHub.
Get account and Balance
try {
// provider is from above
const accounts = await provider.request<never, string[]>({
method: 'xrpl_getAccounts',
})
if (accounts) {
const accInfo = (await provider.request({
method: 'account_info',
params: [
{
account: accounts[0],
strict: true,
ledger_index: 'current',
queue: true,
},
],
})) as Record<string, Record<string, string>>
console.log('XRPL account info', accInfo)
// XRPL Account
const account = accInfo?.account_data?.Account
// Balance
const balance = accInfo?.account_data?.Balance
} else {
console.log('No accounts found, please report this issue.')
}
} catch (error) {
console.error('Error', error)
}
Sign a transaction
import { Payment, xrpToDrops } from 'xrpl'
try {
const accounts = await provider.request<never, string[]>({
method: 'xrpl_getAccounts',
})
if (accounts && accounts.length > 0) {
const tx: Payment = {
TransactionType: 'Payment',
Account: accounts[0] as string,
Amount: xrpToDrops(2),
Destination: 'rJAHHPYmy4g3h7kzfj2Mzm2nHwpKuVdEvX', // Destination address
}
const txSign = await provider.request({
method: 'xrpl_signTransaction',
params: {
transaction: tx,
},
})
console.log('txRes', txSign)
} else {
console.log('failed to fetch accounts')
}
} catch (error) {
console.log('error', error)
}
Send transaction
import { Payment, xrpToDrops } from 'xrpl'
try {
const accounts = await provider.request<never, string[]>({
method: 'xrpl_getAccounts',
})
if (accounts && accounts.length > 0) {
const tx: Payment = {
TransactionType: 'Payment',
Account: accounts[0] as string,
Amount: xrpToDrops(2),
Destination: 'rJAHHPYmy4g3h7kzfj2Mzm2nHwpKuVdEvX',
}
const txSign = await provider.request({
method: 'xrpl_submitTransaction',
params: {
transaction: tx,
},
})
console.log('txRes', txSign)
} else {
console.log('failed to fetch accounts')
}
} catch (error) {
console.log('error', error)
}
Sign a message
import { convertStringToHex } from 'xrpl'
try {
const msg = 'Hello world'
const hexMsg = convertStringToHex(msg)
const txSign = await provider.request<{ message: string }, { signature: string }>({
method: 'xrpl_signMessage',
params: {
message: hexMsg,
},
})
console.log('txRes', txSign)
} catch (error) {
console.log('error', error)
}