or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

accounts.mdclients.mdcore.mdindex.mdledger.mdmodels.mdtransactions.mdutils.mdwallets.md

wallets.mddocs/

0

# Wallet Operations

1

2

Create, manage, and operate XRPL wallets including key generation, address derivation, and testnet funding. The wallet module provides comprehensive cryptographic wallet functionality for XRPL applications.

3

4

## Capabilities

5

6

### Wallet Class

7

8

Complete wallet implementation with cryptographic key management and address operations.

9

10

```python { .api }

11

from xrpl.wallet import Wallet

12

from xrpl import CryptoAlgorithm

13

14

class Wallet:

15

"""XRPL wallet containing cryptographic keys and address information."""

16

17

def __init__(

18

self,

19

public_key: str,

20

private_key: str,

21

classic_address: str = None,

22

seed: str = None

23

):

24

"""

25

Initialize wallet with key material.

26

27

Args:

28

public_key: Hex-encoded public key

29

private_key: Hex-encoded private key

30

classic_address: XRPL classic address (derived if not provided)

31

seed: Original seed used to generate keys (optional)

32

"""

33

self.public_key = public_key

34

self.private_key = private_key

35

self.classic_address = classic_address

36

self.seed = seed

37

38

@property

39

def address(self) -> str:

40

"""Get the classic address (alias for classic_address)."""

41

return self.classic_address

42

43

@classmethod

44

def create(cls, algorithm: CryptoAlgorithm = CryptoAlgorithm.ED25519) -> "Wallet":

45

"""

46

Create a new wallet with randomly generated keys.

47

48

Args:

49

algorithm: Cryptographic algorithm to use (ED25519 or SECP256K1)

50

51

Returns:

52

New Wallet instance with generated keys

53

"""

54

55

@classmethod

56

def from_seed(

57

cls,

58

seed: str,

59

algorithm: CryptoAlgorithm = None

60

) -> "Wallet":

61

"""

62

Create wallet from existing seed.

63

64

Args:

65

seed: Base58-encoded seed string

66

algorithm: Algorithm to use (inferred from seed if not provided)

67

68

Returns:

69

Wallet instance derived from seed

70

"""

71

72

@classmethod

73

def from_secret(cls, seed: str) -> "Wallet":

74

"""

75

Create wallet from secret (alias for from_seed).

76

77

Args:

78

seed: Base58-encoded seed/secret string

79

80

Returns:

81

Wallet instance derived from secret

82

"""

83

84

def get_xaddress(self, tag: int = None, is_test: bool = False) -> str:

85

"""

86

Get X-address format of wallet address.

87

88

Args:

89

tag: Optional destination tag to encode

90

is_test: Whether this is for test network

91

92

Returns:

93

X-address string with optional tag encoded

94

"""

95

```

96

97

### Wallet Funding

98

99

Generate wallets funded by testnet faucets for development and testing.

100

101

```python { .api }

102

from xrpl.wallet import generate_faucet_wallet

103

104

def generate_faucet_wallet(

105

client,

106

wallet: Wallet = None,

107

usage_context: str = None

108

) -> Wallet:

109

"""

110

Generate a wallet funded by testnet faucet.

111

112

Args:

113

client: XRPL client connected to testnet

114

wallet: Existing wallet to fund (creates new if None)

115

usage_context: Usage context string for faucet request

116

117

Returns:

118

Funded wallet ready for testnet use

119

120

Raises:

121

XRPLFaucetException: If faucet funding fails

122

"""

123

```

124

125

## Usage Examples

126

127

### Creating New Wallets

128

129

```python

130

from xrpl.wallet import Wallet

131

from xrpl import CryptoAlgorithm

132

133

# Create wallet with default Ed25519 algorithm

134

wallet1 = Wallet.create()

135

print(f"Address: {wallet1.address}")

136

print(f"Public key: {wallet1.public_key}")

137

print(f"Seed: {wallet1.seed}")

138

139

# Create wallet with secp256k1 algorithm

140

wallet2 = Wallet.create(CryptoAlgorithm.SECP256K1)

141

print(f"Address: {wallet2.address}")

142

print(f"Algorithm: secp256k1")

143

144

# Create wallet from existing seed

145

existing_seed = "sEdTM1uX8pu2do5XvTnutH6HsouMaM2"

146

wallet3 = Wallet.from_seed(existing_seed)

147

print(f"Restored address: {wallet3.address}")

148

149

# Alternative method using from_secret

150

wallet4 = Wallet.from_secret(existing_seed)

151

print(f"Same address: {wallet4.address == wallet3.address}")

152

```

153

154

### Wallet Information and Address Formats

155

156

```python

157

from xrpl.wallet import Wallet

158

159

# Create a wallet

160

wallet = Wallet.create()

161

162

# Display wallet information

163

print("=== Wallet Information ===")

164

print(f"Classic Address: {wallet.address}")

165

print(f"Classic Address (property): {wallet.classic_address}")

166

print(f"Public Key: {wallet.public_key}")

167

print(f"Private Key: {wallet.private_key}")

168

print(f"Seed: {wallet.seed}")

169

170

# X-address formats

171

print("\n=== Address Formats ===")

172

print(f"Classic: {wallet.address}")

173

print(f"X-address (mainnet): {wallet.get_xaddress()}")

174

print(f"X-address (testnet): {wallet.get_xaddress(is_test=True)}")

175

print(f"X-address with tag: {wallet.get_xaddress(tag=12345, is_test=True)}")

176

177

# Address validation

178

from xrpl.core.addresscodec import is_valid_classic_address, is_valid_xaddress

179

classic_addr = wallet.address

180

x_addr = wallet.get_xaddress(is_test=True)

181

182

print(f"\nClassic address valid: {is_valid_classic_address(classic_addr)}")

183

print(f"X-address valid: {is_valid_xaddress(x_addr)}")

184

```

185

186

### Testnet Wallet Funding

187

188

```python

189

from xrpl.clients import JsonRpcClient

190

from xrpl.wallet import Wallet, generate_faucet_wallet

191

192

# Connect to testnet

193

client = JsonRpcClient("https://s.altnet.rippletest.net:51234")

194

195

# Method 1: Generate and fund new wallet

196

try:

197

funded_wallet = generate_faucet_wallet(client)

198

print(f"✅ Created funded wallet: {funded_wallet.address}")

199

200

# Check balance

201

from xrpl import account

202

balance = account.get_balance(funded_wallet.address, client)

203

print(f"Balance: {balance} drops ({balance / 1_000_000} XRP)")

204

205

except Exception as e:

206

print(f"❌ Faucet funding failed: {e}")

207

208

# Method 2: Fund existing wallet

209

existing_wallet = Wallet.create()

210

print(f"Created wallet: {existing_wallet.address}")

211

212

try:

213

funded_existing = generate_faucet_wallet(client, existing_wallet)

214

print(f"✅ Funded existing wallet: {funded_existing.address}")

215

216

except Exception as e:

217

print(f"❌ Failed to fund existing wallet: {e}")

218

```

219

220

### Wallet Persistence and Recovery

221

222

```python

223

import json

224

from xrpl.wallet import Wallet

225

from xrpl import CryptoAlgorithm

226

227

def save_wallet_safely(wallet: Wallet, filename: str, password: str = None):

228

"""Save wallet to encrypted file (simplified example)."""

229

230

# In production, use proper encryption!

231

wallet_data = {

232

"seed": wallet.seed,

233

"address": wallet.address,

234

"public_key": wallet.public_key,

235

# Never save private keys in plaintext!

236

"algorithm": "ed25519" if "ed25519" in wallet.seed else "secp256k1"

237

}

238

239

with open(filename, 'w') as f:

240

json.dump(wallet_data, f, indent=2)

241

242

print(f"⚠️ Wallet saved to {filename}")

243

print("⚠️ WARNING: This is a simplified example!")

244

print("⚠️ In production, encrypt private keys and use secure storage!")

245

246

def load_wallet_safely(filename: str, password: str = None) -> Wallet:

247

"""Load wallet from file (simplified example)."""

248

249

with open(filename, 'r') as f:

250

wallet_data = json.load(f)

251

252

# Restore wallet from seed

253

wallet = Wallet.from_seed(wallet_data["seed"])

254

255

# Verify address matches

256

if wallet.address != wallet_data["address"]:

257

raise ValueError("Address mismatch - corrupted wallet file!")

258

259

return wallet

260

261

# Example usage

262

original_wallet = Wallet.create()

263

print(f"Original wallet: {original_wallet.address}")

264

265

# Save wallet (INSECURE - for demo only!)

266

save_wallet_safely(original_wallet, "demo_wallet.json")

267

268

# Load wallet

269

restored_wallet = load_wallet_safely("demo_wallet.json")

270

print(f"Restored wallet: {restored_wallet.address}")

271

print(f"Addresses match: {original_wallet.address == restored_wallet.address}")

272

```

273

274

### Multi-Wallet Management

275

276

```python

277

from xrpl.wallet import Wallet, generate_faucet_wallet

278

from xrpl.clients import JsonRpcClient

279

from xrpl import account

280

281

class WalletManager:

282

"""Manage multiple XRPL wallets."""

283

284

def __init__(self, client):

285

self.client = client

286

self.wallets = {}

287

288

def create_wallet(self, name: str, algorithm=None) -> Wallet:

289

"""Create and store a new wallet."""

290

if algorithm:

291

wallet = Wallet.create(algorithm)

292

else:

293

wallet = Wallet.create()

294

295

self.wallets[name] = wallet

296

print(f"Created wallet '{name}': {wallet.address}")

297

return wallet

298

299

def fund_wallet(self, name: str) -> bool:

300

"""Fund a wallet using testnet faucet."""

301

if name not in self.wallets:

302

print(f"Wallet '{name}' not found")

303

return False

304

305

try:

306

funded_wallet = generate_faucet_wallet(self.client, self.wallets[name])

307

self.wallets[name] = funded_wallet

308

print(f"✅ Funded wallet '{name}'")

309

return True

310

except Exception as e:

311

print(f"❌ Failed to fund wallet '{name}': {e}")

312

return False

313

314

def get_balances(self) -> dict:

315

"""Get balances for all wallets."""

316

balances = {}

317

for name, wallet in self.wallets.items():

318

try:

319

if account.does_account_exist(wallet.address, self.client):

320

balance = account.get_balance(wallet.address, self.client)

321

balances[name] = {

322

"address": wallet.address,

323

"balance_drops": balance,

324

"balance_xrp": balance / 1_000_000

325

}

326

else:

327

balances[name] = {

328

"address": wallet.address,

329

"balance_drops": 0,

330

"balance_xrp": 0.0,

331

"exists": False

332

}

333

except Exception as e:

334

balances[name] = {

335

"address": wallet.address,

336

"error": str(e)

337

}

338

return balances

339

340

def get_wallet(self, name: str) -> Wallet:

341

"""Get wallet by name."""

342

return self.wallets.get(name)

343

344

# Usage example

345

client = JsonRpcClient("https://s.altnet.rippletest.net:51234")

346

manager = WalletManager(client)

347

348

# Create multiple wallets

349

manager.create_wallet("alice")

350

manager.create_wallet("bob", CryptoAlgorithm.SECP256K1)

351

manager.create_wallet("charlie")

352

353

# Fund wallets

354

manager.fund_wallet("alice")

355

manager.fund_wallet("bob")

356

357

# Check balances

358

balances = manager.get_balances()

359

for name, info in balances.items():

360

if "error" in info:

361

print(f"{name}: Error - {info['error']}")

362

elif info.get("exists", True):

363

print(f"{name} ({info['address']}): {info['balance_xrp']:.6f} XRP")

364

else:

365

print(f"{name} ({info['address']}): Account not funded")

366

```

367

368

### Wallet Security Best Practices

369

370

```python

371

from xrpl.wallet import Wallet

372

import secrets

373

import hashlib

374

375

def create_secure_wallet():

376

"""Create wallet with additional entropy."""

377

378

# Add extra entropy (optional - Wallet.create() is already secure)

379

extra_entropy = secrets.token_bytes(32)

380

wallet = Wallet.create()

381

382

print("🔐 Wallet Security Checklist:")

383

print("✅ Generated with cryptographically secure random number generator")

384

print("✅ Private key never transmitted over network")

385

print("✅ Seed can regenerate the entire wallet")

386

387

return wallet

388

389

def verify_wallet_integrity(wallet: Wallet) -> bool:

390

"""Verify wallet keys are consistent."""

391

392

try:

393

# Create new wallet from same seed

394

verification_wallet = Wallet.from_seed(wallet.seed)

395

396

# Check all components match

397

checks = [

398

wallet.address == verification_wallet.address,

399

wallet.public_key == verification_wallet.public_key,

400

wallet.private_key == verification_wallet.private_key

401

]

402

403

if all(checks):

404

print("✅ Wallet integrity verified")

405

return True

406

else:

407

print("❌ Wallet integrity check failed!")

408

return False

409

410

except Exception as e:

411

print(f"❌ Wallet verification error: {e}")

412

return False

413

414

def wallet_security_audit(wallet: Wallet):

415

"""Perform basic security audit of wallet."""

416

417

print("🔍 Wallet Security Audit")

418

print(f"Address: {wallet.address}")

419

420

# Check key lengths

421

public_key_len = len(wallet.public_key)

422

private_key_len = len(wallet.private_key)

423

424

print(f"Public key length: {public_key_len} chars")

425

print(f"Private key length: {private_key_len} chars")

426

427

# Verify integrity

428

integrity_ok = verify_wallet_integrity(wallet)

429

430

# Check address format

431

from xrpl.core.addresscodec import is_valid_classic_address

432

address_valid = is_valid_classic_address(wallet.address)

433

print(f"Address format valid: {address_valid}")

434

435

# Security recommendations

436

print("\n🛡️ Security Recommendations:")

437

print("- Store seed/private key in encrypted storage")

438

print("- Never share private key or seed")

439

print("- Use hardware wallets for large amounts")

440

print("- Test with small amounts first")

441

print("- Keep backups of seed in secure locations")

442

print("- Use testnet for development")

443

444

# Example usage

445

wallet = create_secure_wallet()

446

wallet_security_audit(wallet)

447

```

448

449

## Exceptions

450

451

```python { .api }

452

class XRPLFaucetException(XRPLException):

453

"""Exception raised when faucet operations fail during wallet funding."""

454

```

455

456

## Wallet Properties Summary

457

458

```python { .api }

459

# Wallet instance properties

460

wallet = Wallet.create()

461

462

wallet.address # str: Classic XRPL address (rXXX...)

463

wallet.classic_address # str: Same as address

464

wallet.public_key # str: Hex-encoded public key

465

wallet.private_key # str: Hex-encoded private key

466

wallet.seed # str: Base58-encoded seed for key derivation

467

468

# Methods

469

wallet.get_xaddress(tag=None, is_test=False) # X-address format

470

471

# Class methods

472

Wallet.create(algorithm=CryptoAlgorithm.ED25519) # Create new wallet

473

Wallet.from_seed(seed, algorithm=None) # From existing seed

474

Wallet.from_secret(seed) # Alias for from_seed

475

```