Privy is a developer wallet SDK that creates and signs XRPL transactions server-side — no seed phrase stored in your code. Human buyers get a wallet via email or social login; AI agents create one programmatically and sign EscrowCreate transactions without ever holding a private key in plaintext.
Users sign in with email, Google, or Apple. Privy creates and manages their XRPL wallet — no extension, no seed phrase, no friction. Wallet address is ready in seconds.
Your agent calls Privy's API to create an XRPL wallet server-side, then signs any transaction type — EscrowCreate, Payment, DelegateSet — without storing a seed anywhere in code.
1 XRP base reserve required. Every XRPL account must hold at least 1 XRP on-ledger before it can submit transactions. Fund the address after creation via an exchange, Coinbase, or the fund_xrpl_wallet_via_coinbase MCP tool.
npm install @eamwhite1/agenttrust-sdk xrpl
const { PrivyWallet } = require('@eamwhite1/agenttrust-sdk');
const privy = new PrivyWallet({
appId: process.env.PRIVY_APP_ID,
appSecret: process.env.PRIVY_APP_SECRET,
});
const wallet = await privy.createWallet();
// { id: 'wal_...', address: 'rXXXX...', publicKey: '02...' }
// Fund with 1 XRP before submitting any transactions
console.log('Fund this address:', wallet.address);
const { Client, xrpToDrops } = require('xrpl');
const xrpl = new Client('wss://xrplcluster.com');
await xrpl.connect();
const tx = await xrpl.autofill({
TransactionType: 'Payment',
Account: wallet.address,
Destination: 'rDest...',
Amount: xrpToDrops('10'),
});
// Sign via Privy — no seed stored
const signedBlob = await privy.signTransaction(
wallet.id, wallet.address, wallet.publicKey, tx
);
const result = await xrpl.submit(signedBlob);
console.log(result.result.engine_result); // tesSUCCESS
await xrpl.disconnect();
const { AgentTrust } = require('@eamwhite1/agenttrust-sdk');
const at = new AgentTrust();
// Pre-flight check
const check = await at.assessCounterparty({
workerAddress: workerWallet.address,
amountXrp: 10,
});
if (!check.proceed) throw new Error(check.reason);
// Create escrow — returns ready-to-sign tx
const escrow = await at.hireAndPay({
task: 'Write a 500-word blog post about XRPL',
buyerAddress: buyerWallet.address,
amountXrp: 10,
workerAddress: workerWallet.address,
escrowId: `job-${Date.now()}`,
feeHash: feeHash,
});
// Sign EscrowCreate with Privy
const signed = await privy.signTransaction(
buyerWallet.id, buyerWallet.address, buyerWallet.publicKey,
escrow.tx_dict
);
const txResult = await xrpl.submit(signed);
// Confirm on-chain
await at.confirmEscrow({
escrowId: escrow.escrow_id,
txHash: txResult.result.tx_json.hash,
});
Every XRPL account needs at least 1 XRP on-ledger before it can submit any transaction. Here are the three paths — pick the one that fits your setup.
Call fund_xrpl_wallet_via_coinbase (an AgentTrust MCP tool). It buys XRP on Coinbase using the agent's own API key and withdraws it directly to the XRPL address — no human in the loop once set up.
One-time human step: a human must create the Coinbase account and complete KYC (passport/ID) once. After that, the agent can fund itself autonomously using the API key. Store COINBASE_API_KEY and COINBASE_API_SECRET as env vars with wallet:buys:create + wallet:transactions:send permissions.
// After creating the wallet:
await agentTrust.fundWalletViaCoinbase({
xrplAddress: wallet.address,
usdAmount: 5.0, // buys ~5 USD worth of XRP — covers base reserve + fees
});
Send at least 1 XRP from any funded XRPL wallet — your own, an exchange withdrawal, or Xaman. The receiving address activates the moment the Payment lands.
const { Client, Wallet, xrpToDrops } = require('xrpl');
const client = new Client('wss://xrplcluster.com');
await client.connect();
const funderWallet = Wallet.fromSeed(process.env.FUNDER_SEED);
const prepared = await client.autofill({
TransactionType: 'Payment',
Account: funderWallet.address,
Destination: newWallet.address, // the Privy-created address
Amount: xrpToDrops('2'), // 2 XRP: 1 reserve + buffer for fees
});
const signed = funderWallet.sign(prepared);
const result = await client.submitAndWait(signed.tx_blob);
console.log(result.result.meta.TransactionResult); // tesSUCCESS
await client.disconnect();
If your agent has received RLUSD from completed work, it can swap to XRP on the XRPL DEX to cover its own reserve. Use get_rlusd_quote first to check the rate, then submit an OfferCreate.
// Check live DEX rate
const quote = await agentTrust.getRlusdQuote({
walletAddress: wallet.address,
amountRlusd: 2.0,
});
// { xrp_equivalent: 1.84, rate: 0.92, trustline_active: true }
// If rate looks good, submit the swap via your signed OfferCreate tx
The DEX swap requires an active RLUSD trustline on the wallet first (TrustSet transaction). A fresh wallet can't do this until it has the 1 XRP reserve — so Option C only works for top-up funding after the initial activation.
Privy's policy engine lets you restrict a wallet's signing power at creation time — useful for agent wallets that should only sign specific transaction types or pay specific addresses.
| Policy field | What it controls | Example |
|---|---|---|
| TransactionType | Restrict which tx types the wallet can sign | Only EscrowCreate, Payment |
| Payment.Destination | Allowlist or denylist recipient addresses | Only pay AgentTrust escrow address |
| Payment.Amount.drops | Cap XRP payment size | Max 100 XRP per transaction |
| OfferCreate.TakerPays | Constrain DEX buy orders | Only buy RLUSD |
| TrustSet.LimitAmount | Restrict trust line creation | Only trust Gatehub USDC |
Wallets can sign any valid XRPL transaction type, but policies only evaluate the types above. Transactions of unsupported types (e.g. DelegateSet) are denied unless a system-level rule allows them — test carefully.
No seed phrase, no browser extension, no crypto knowledge required. Privy creates a real XRPL wallet using your existing email or social login.