or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

account-management.mdcryptographic-primitives.mderror-handling.mdindex.mdnetwork-sysvars.mdrpc-functionality.mdsystem-programs.mdtesting-infrastructure.mdtoken-operations.mdtransaction-construction.mdtransaction-status.md

account-management.mddocs/

0

# Account Management

1

2

Account data structures, encoding formats, and metadata handling for both raw and parsed account information. This includes account state management, commitment levels, data encoding options, and parsing utilities for program-specific account data.

3

4

## Capabilities

5

6

### Account Data Structures

7

8

Core account representations containing balance, data, ownership, and metadata information.

9

10

```python { .api }

11

class Account:

12

"""

13

Solana account containing balance, data, owner, and metadata.

14

"""

15

def __init__(self, lamports: int, data: bytes, owner: Pubkey, executable: bool, rent_epoch: int):

16

"""

17

Create account with balance, data, and metadata.

18

19

Parameters:

20

- lamports: int, account balance in lamports (1 SOL = 1e9 lamports)

21

- data: bytes, account data (program-specific)

22

- owner: Pubkey, program that owns this account

23

- executable: bool, whether account contains executable program code

24

- rent_epoch: int, epoch when rent was last collected

25

"""

26

27

@classmethod

28

def default() -> 'Account':

29

"""

30

Create default empty account.

31

32

Returns:

33

Account with zero balance, empty data, system program owner

34

"""

35

36

@property

37

def lamports(self) -> int:

38

"""Account balance in lamports."""

39

40

@property

41

def data(self) -> bytes:

42

"""Account data bytes."""

43

44

@property

45

def owner(self) -> Pubkey:

46

"""Program that owns this account."""

47

48

@property

49

def executable(self) -> bool:

50

"""Whether account contains executable code."""

51

52

@property

53

def rent_epoch(self) -> int:

54

"""Epoch when rent was last collected."""

55

56

def serialize(self) -> bytes:

57

"""

58

Serialize account to bytes.

59

60

Returns:

61

bytes, serialized account data

62

"""

63

64

@classmethod

65

def deserialize(cls, data: bytes) -> 'Account':

66

"""

67

Deserialize account from bytes.

68

69

Parameters:

70

- data: bytes, serialized account data

71

72

Returns:

73

Account object

74

"""

75

```

76

77

```python { .api }

78

class AccountJSON:

79

"""

80

JSON-serializable account representation for RPC responses.

81

"""

82

def __init__(

83

self,

84

lamports: int,

85

data: Union[str, List[str]],

86

owner: str,

87

executable: bool,

88

rent_epoch: int

89

):

90

"""

91

Create JSON account representation.

92

93

Parameters:

94

- lamports: int, account balance

95

- data: Union[str, List[str]], encoded account data

96

- owner: str, base58 owner pubkey

97

- executable: bool, executable flag

98

- rent_epoch: int, rent epoch

99

"""

100

101

def to_json(self) -> dict:

102

"""

103

Convert to JSON dictionary.

104

105

Returns:

106

dict, JSON-compatible account data

107

"""

108

109

@classmethod

110

def from_json(cls, data: dict) -> 'AccountJSON':

111

"""

112

Create from JSON dictionary.

113

114

Parameters:

115

- data: dict, JSON account data

116

117

Returns:

118

AccountJSON object

119

"""

120

```

121

122

### Account Encoding and Parsing

123

124

Data encoding formats and parsing utilities for account data representation.

125

126

```python { .api }

127

class UiAccountEncoding:

128

"""

129

Account data encoding format enumeration.

130

"""

131

Base64: 'UiAccountEncoding' # Base64 encoded data

132

JsonParsed: 'UiAccountEncoding' # Parsed JSON format (program-specific)

133

Base58: 'UiAccountEncoding' # Base58 encoded data

134

Base64Zstd: 'UiAccountEncoding' # Base64 + Zstandard compression

135

136

def __str__(self) -> str:

137

"""String representation of encoding type."""

138

```

139

140

```python { .api }

141

class ParsedAccount:

142

"""

143

Account with parsed/decoded program-specific data.

144

"""

145

def __init__(self, account: Account, parsed_data: Optional[dict]):

146

"""

147

Create parsed account with structured data.

148

149

Parameters:

150

- account: Account, base account information

151

- parsed_data: Optional[dict], program-specific parsed data

152

"""

153

154

@property

155

def account(self) -> Account:

156

"""Base account information."""

157

158

@property

159

def parsed_data(self) -> Optional[dict]:

160

"""Program-specific parsed data."""

161

162

def is_token_account(self) -> bool:

163

"""

164

Check if account contains SPL token data.

165

166

Returns:

167

bool, True if account is token account

168

"""

169

170

def is_mint_account(self) -> bool:

171

"""

172

Check if account contains SPL mint data.

173

174

Returns:

175

bool, True if account is mint account

176

"""

177

```

178

179

```python { .api }

180

class UiDataSliceConfig:

181

"""

182

Configuration for slicing account data in RPC requests.

183

"""

184

def __init__(self, offset: int, length: int):

185

"""

186

Create data slice configuration.

187

188

Parameters:

189

- offset: int, byte offset to start slice

190

- length: int, number of bytes to return

191

"""

192

193

@property

194

def offset(self) -> int:

195

"""Slice offset in bytes."""

196

197

@property

198

def length(self) -> int:

199

"""Slice length in bytes."""

200

```

201

202

### Token Amount Handling

203

204

Specialized handling for token amounts with proper decimal representation.

205

206

```python { .api }

207

class UiTokenAmount:

208

"""

209

Token amount with decimal precision handling.

210

"""

211

def __init__(self, ui_amount: Optional[float], decimals: int, amount: str, ui_amount_string: str):

212

"""

213

Create token amount with decimal handling.

214

215

Parameters:

216

- ui_amount: Optional[float], human-readable amount (may be None for large numbers)

217

- decimals: int, number of decimal places for token

218

- amount: str, raw amount as string (no decimal adjustment)

219

- ui_amount_string: str, human-readable amount as string

220

"""

221

222

@property

223

def ui_amount(self) -> Optional[float]:

224

"""Human-readable amount (float, may be None for large values)."""

225

226

@property

227

def decimals(self) -> int:

228

"""Number of decimal places for this token."""

229

230

@property

231

def amount(self) -> str:

232

"""Raw token amount as string."""

233

234

@property

235

def ui_amount_string(self) -> str:

236

"""Human-readable amount as string."""

237

238

def to_float(self) -> float:

239

"""

240

Convert to float value.

241

242

Returns:

243

float, token amount as floating point

244

245

Raises:

246

- ValueError: if amount cannot be represented as float

247

"""

248

249

def to_decimal(self) -> 'Decimal':

250

"""

251

Convert to decimal for precise arithmetic.

252

253

Returns:

254

Decimal, exact token amount

255

"""

256

```

257

258

### Commitment and Configuration

259

260

Transaction commitment levels and account query configuration.

261

262

```python { .api }

263

class CommitmentLevel:

264

"""

265

Transaction confirmation levels.

266

"""

267

Processed: 'CommitmentLevel' # Transaction processed but not confirmed

268

Confirmed: 'CommitmentLevel' # Transaction confirmed by cluster

269

Finalized: 'CommitmentLevel' # Transaction finalized (cannot be rolled back)

270

271

def __str__(self) -> str:

272

"""String representation of commitment level."""

273

```

274

275

```python { .api }

276

class CommitmentConfig:

277

"""

278

Configuration for RPC request commitment level.

279

"""

280

def __init__(self, commitment: CommitmentLevel):

281

"""

282

Create commitment configuration.

283

284

Parameters:

285

- commitment: CommitmentLevel, desired confirmation level

286

"""

287

288

@classmethod

289

def processed() -> 'CommitmentConfig':

290

"""

291

Create processed commitment config.

292

293

Returns:

294

CommitmentConfig for processed transactions

295

"""

296

297

@classmethod

298

def confirmed() -> 'CommitmentConfig':

299

"""

300

Create confirmed commitment config.

301

302

Returns:

303

CommitmentConfig for confirmed transactions

304

"""

305

306

@classmethod

307

def finalized() -> 'CommitmentConfig':

308

"""

309

Create finalized commitment config.

310

311

Returns:

312

CommitmentConfig for finalized transactions

313

"""

314

315

@property

316

def commitment(self) -> CommitmentLevel:

317

"""Commitment level."""

318

```

319

320

## Usage Examples

321

322

### Basic Account Operations

323

324

```python

325

from solders.account import Account

326

from solders.pubkey import Pubkey

327

328

# Create account

329

owner = Pubkey.from_string("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA")

330

account_data = b"token_account_data_here"

331

332

account = Account(

333

lamports=2039280, # Rent-exempt minimum

334

data=account_data,

335

owner=owner,

336

executable=False,

337

rent_epoch=361

338

)

339

340

print(f"Account balance: {account.lamports / 1e9:.9f} SOL")

341

print(f"Data length: {len(account.data)} bytes")

342

print(f"Owner: {account.owner}")

343

print(f"Executable: {account.executable}")

344

```

345

346

### Working with Token Amounts

347

348

```python

349

from solders.account_decoder import UiTokenAmount

350

from decimal import Decimal

351

352

# Token amount with 6 decimals (USDC-style)

353

token_amount = UiTokenAmount(

354

ui_amount=1000.50,

355

decimals=6,

356

amount="1000500000", # Raw amount: 1000.5 * 10^6

357

ui_amount_string="1000.5"

358

)

359

360

print(f"UI amount: {token_amount.ui_amount}")

361

print(f"Raw amount: {token_amount.amount}")

362

print(f"Decimals: {token_amount.decimals}")

363

364

# Precise decimal arithmetic

365

precise_amount = token_amount.to_decimal()

366

print(f"Precise amount: {precise_amount}")

367

368

# Large number handling (ui_amount may be None)

369

large_amount = UiTokenAmount(

370

ui_amount=None, # Too large for float

371

decimals=9,

372

amount="999999999999999999999",

373

ui_amount_string="999999999999.999999999"

374

)

375

```

376

377

### Account Data Slicing

378

379

```python

380

from solders.account_decoder import UiDataSliceConfig

381

382

# Get first 64 bytes of account data

383

slice_config = UiDataSliceConfig(offset=0, length=64)

384

385

# Get specific portion (e.g., skip mint info, get owner)

386

token_account_slice = UiDataSliceConfig(offset=32, length=32)

387

388

print(f"Slice offset: {slice_config.offset}")

389

print(f"Slice length: {slice_config.length}")

390

```

391

392

### Commitment Level Usage

393

394

```python

395

from solders.commitment_config import CommitmentLevel, CommitmentConfig

396

397

# Different commitment levels

398

processed_config = CommitmentConfig.processed()

399

confirmed_config = CommitmentConfig.confirmed()

400

finalized_config = CommitmentConfig.finalized()

401

402

# Check commitment level

403

if confirmed_config.commitment == CommitmentLevel.Confirmed:

404

print("Using confirmed commitment level")

405

406

# Custom commitment

407

custom_config = CommitmentConfig(CommitmentLevel.Finalized)

408

```

409

410

### Account Serialization

411

412

```python

413

# Serialize account for storage or transmission

414

serialized = account.serialize()

415

print(f"Serialized size: {len(serialized)} bytes")

416

417

# Deserialize account

418

restored_account = Account.deserialize(serialized)

419

assert restored_account.lamports == account.lamports

420

assert restored_account.data == account.data

421

assert restored_account.owner == account.owner

422

```

423

424

### JSON Account Handling

425

426

```python

427

from solders.account import AccountJSON

428

429

# Create JSON representation

430

json_account = AccountJSON(

431

lamports=2039280,

432

data="dGVzdF9kYXRh", # Base64 encoded data

433

owner="TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",

434

executable=False,

435

rent_epoch=361

436

)

437

438

# Convert to dictionary for JSON serialization

439

json_dict = json_account.to_json()

440

441

# Restore from JSON

442

restored = AccountJSON.from_json(json_dict)

443

```

444

445

### Parsed Account Analysis

446

447

```python

448

from solders.account_decoder import ParsedAccount

449

450

# Parsed token account data

451

parsed_data = {

452

"type": "account",

453

"info": {

454

"mint": "So11111111111111111111111111111111111111112",

455

"owner": "7dHbWXmci3dT8UFYWYZweBLXgycu7Y3iL6trKn1Y7ARj",

456

"tokenAmount": {

457

"amount": "1000000000",

458

"decimals": 9,

459

"uiAmount": 1.0,

460

"uiAmountString": "1"

461

}

462

}

463

}

464

465

parsed_account = ParsedAccount(account, parsed_data)

466

467

# Check account type

468

if parsed_account.is_token_account():

469

print("This is a token account")

470

token_info = parsed_account.parsed_data["info"]

471

print(f"Token mint: {token_info['mint']}")

472

print(f"Owner: {token_info['owner']}")

473

474

if parsed_account.is_mint_account():

475

print("This is a mint account")

476

```

477

478

## Account State Management

479

480

### Account Lifecycle

481

482

```python

483

# New account (empty, system-owned)

484

new_account = Account.default()

485

assert new_account.lamports == 0

486

assert new_account.owner == SYSTEM_PROGRAM_ID

487

assert not new_account.executable

488

489

# Funded account

490

funded_account = Account(

491

lamports=5000000, # 0.005 SOL

492

data=b"",

493

owner=SYSTEM_PROGRAM_ID,

494

executable=False,

495

rent_epoch=361

496

)

497

498

# Program account (executable)

499

program_account = Account(

500

lamports=10000000,

501

data=b"program_bytecode_here",

502

owner=SYSTEM_PROGRAM_ID,

503

executable=True,

504

rent_epoch=361

505

)

506

```

507

508

### Rent Exemption Checking

509

510

```python

511

from solders.rent import Rent

512

513

# Calculate rent exemption

514

rent = Rent.default()

515

data_size = 165 # Size of token account

516

minimum_balance = rent.minimum_balance(data_size)

517

518

# Check if account is rent exempt

519

def is_rent_exempt(account: Account) -> bool:

520

return account.lamports >= minimum_balance

521

522

if is_rent_exempt(account):

523

print("Account is rent exempt")

524

else:

525

print(f"Need {minimum_balance - account.lamports} more lamports for rent exemption")

526

```

527

528

## Encoding Utilities

529

530

### Data Encoding Helpers

531

532

```python

533

import base64

534

import base58

535

536

def encode_account_data(data: bytes, encoding: UiAccountEncoding) -> Union[str, List[str]]:

537

"""Encode account data in specified format."""

538

if encoding == UiAccountEncoding.Base64:

539

return base64.b64encode(data).decode()

540

elif encoding == UiAccountEncoding.Base58:

541

return base58.b58encode(data).decode()

542

elif encoding == UiAccountEncoding.JsonParsed:

543

# Would require program-specific parsing

544

return "parsed"

545

else:

546

return data.hex()

547

548

def decode_account_data(encoded_data: str, encoding: UiAccountEncoding) -> bytes:

549

"""Decode account data from specified format."""

550

if encoding == UiAccountEncoding.Base64:

551

return base64.b64decode(encoded_data)

552

elif encoding == UiAccountEncoding.Base58:

553

return base58.b58decode(encoded_data)

554

else:

555

return bytes.fromhex(encoded_data)

556

```

557

558

## Constants and Defaults

559

560

### Well-Known Accounts

561

562

```python { .api }

563

# System Program ID (default owner for user accounts)

564

SYSTEM_PROGRAM_ID: Final[Pubkey] = Pubkey.from_string("11111111111111111111111111111112")

565

566

# Native SOL Token Mint

567

NATIVE_MINT: Final[Pubkey] = Pubkey.from_string("So11111111111111111111111111111111111111112")

568

```

569

570

### Default Values

571

572

```python { .api }

573

# Default commitment level for most operations

574

DEFAULT_COMMITMENT: Final[CommitmentLevel] = CommitmentLevel.Finalized

575

576

# Minimum account sizes

577

MINIMUM_ACCOUNT_SIZE: Final[int] = 0

578

TOKEN_ACCOUNT_SIZE: Final[int] = 165

579

MINT_ACCOUNT_SIZE: Final[int] = 82

580

```