Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions docs/content/docs/addresses/address-types/base.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
---
title: Base Addresses
description: Standard Cardano addresses with payment and staking credentials
---

# Base Addresses

Base addresses contain both a payment credential and a staking credential. This is the standard address format on Cardano.

## Structure

```
Base Address = Payment Credential + Staking Credential
```

**Payment Credential**: Controls who can spend UTXOs at this address
**Staking Credential**: Controls delegation and receives staking rewards

Both credentials are typically derived from the same wallet, but can come from different sources (see [Franken Addresses](/docs/addresses/franken)).

## Construction

Create base addresses by instantiating the `BaseAddress` class:

```typescript twoslash
import { Core } from "@evolution-sdk/evolution";

const address = new Core.BaseAddress.BaseAddress({
networkId: 1, // mainnet
paymentCredential: new Core.KeyHash.KeyHash({
hash: new Uint8Array(28)
}),
stakeCredential: new Core.KeyHash.KeyHash({
hash: new Uint8Array(28)
})
});

// Convert to Bech32 string
const bech32 = Core.Address.toBech32(address);
console.log(bech32); // "addr1..."
```

## Parsing Addresses

Parse a Bech32 address string into a `BaseAddress` instance:

```typescript twoslash
import { Core } from "@evolution-sdk/evolution";

const bech32 = "addr1qx2kd28nq8ac5prwg32hhvudlwggpgfp8utlyqxu6wqgz62f79qsdmm5dsknt9ecr5w468r9ey0fxwkdrwh08ly3tu9sy0f4qd";

const address = Core.Address.fromBech32(bech32) as Core.BaseAddress.BaseAddress;

console.log("Network ID:", address.networkId);
console.log("Payment:", address.paymentCredential);
console.log("Stake:", address.stakeCredential);
```

## Script-Based Addresses

Base addresses can use script hashes for payment and/or staking credentials:

```typescript twoslash
import { Core } from "@evolution-sdk/evolution";

// Address with script credentials
const scriptAddress = new Core.BaseAddress.BaseAddress({
networkId: 1, // mainnet
paymentCredential: new Core.ScriptHash.ScriptHash({
hash: new Uint8Array(28) // 28-byte payment script hash
}),
stakeCredential: new Core.ScriptHash.ScriptHash({
hash: new Uint8Array(28) // 28-byte stake script hash
})
});

const bech32 = Core.Address.toBech32(scriptAddress);
console.log("Script-based address:", bech32);
```

## Address Components

### Payment Credential
- **Purpose**: Spending authorization
- **Type**: Key hash (28 bytes) or script hash (28 bytes)
- **Usage**: Required to sign spending transactions

### Staking Credential
- **Purpose**: Delegation and rewards
- **Type**: Key hash (28 bytes) or script hash (28 bytes)
- **Usage**: Required to delegate stake or withdraw rewards

## Format Details

**Bech32 Prefix**: `addr` (mainnet) or `addr_test` (testnet)
**Size**: 57 bytes on-chain

## Related

- **[Enterprise Addresses](./enterprise)** - Payment credential only
- **[Reward Addresses](./reward)** - Staking credential only
- **[Franken Addresses](/docs/addresses/franken)** - Addresses with credentials from different sources
103 changes: 103 additions & 0 deletions docs/content/docs/addresses/address-types/enterprise.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
---
title: Enterprise Addresses
description: Payment-only addresses without staking capability
---

# Enterprise Addresses

Enterprise addresses contain only a payment credential, with no staking component.

## Structure

```
Enterprise Address = Payment Credential Only
```

**Payment Credential**: Controls who can spend UTXOs at this address
**No Staking**: Cannot delegate stake or earn staking rewards

## Construction

Create enterprise addresses by instantiating the `EnterpriseAddress` class:

```typescript twoslash
import { Core } from "@evolution-sdk/evolution";

const address = new Core.EnterpriseAddress.EnterpriseAddress({
networkId: 1, // mainnet
paymentCredential: new Core.KeyHash.KeyHash({
hash: new Uint8Array(28)
})
});

// Convert to Bech32 string
const bech32 = Core.Address.toBech32(address);
console.log(bech32); // "addr1..."
```

## Parsing Addresses

Parse a Bech32 address string into an `EnterpriseAddress` instance:

```typescript twoslash
import { Core } from "@evolution-sdk/evolution";

const bech32 = "addr1vx2kd28nq8ac5prwg32hhvudlwggpgfp8utlyqxu6wqgz6cevnrgl";

const address = Core.Address.fromBech32(bech32) as Core.EnterpriseAddress.EnterpriseAddress;

console.log("Network ID:", address.networkId);
console.log("Payment:", address.paymentCredential);
```

## Script-Based Example

Enterprise addresses can use script hashes as payment credentials:

```typescript twoslash
import { Core } from "@evolution-sdk/evolution";

// Script address example
const scriptAddr = new Core.EnterpriseAddress.EnterpriseAddress({
networkId: 1, // mainnet
paymentCredential: new Core.ScriptHash.ScriptHash({
hash: new Uint8Array(28) // 28-byte script hash
})
});

// Convert to Bech32 string
const bech32 = Core.Address.toBech32(scriptAddr);
console.log("Script enterprise address:", bech32);
```

## Format Details

**Bech32 Prefix**: `addr` (mainnet) or `addr_test` (testnet)
**Length**: 29 bytes raw / ~59 characters Bech32
**Header Bits**: `0110xxxx` (enterprise address type)
**Size Advantage**: Half the size of base addresses (29 vs 57 bytes)

## Comparison with Base Addresses

| Feature | Enterprise | Base |
|---------|-----------|------|
| Payment credential | • Yes | • Yes |
| Staking credential | ✗ No | • Yes |
| Can receive funds | • Yes | • Yes |
| Can delegate stake | ✗ No | • Yes |
| Earns staking rewards | ✗ No | • Yes |
| Size | 29 bytes | 57 bytes |
| Use case | Exchanges, scripts | User wallets |

## Characteristics

**Smaller Size**: 29 bytes compared to 57 bytes for base addresses.

**Single Credential**: Only payment credential required - no stake key management.

**No Staking**: Cannot delegate stake or earn staking rewards.

## Related

- **[Base Addresses](./base)** - Addresses with both payment and staking credentials
- **[Reward Addresses](./reward)** - Staking credential only
52 changes: 52 additions & 0 deletions docs/content/docs/addresses/address-types/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
title: Address Types
description: Comprehensive guide to all Cardano address types and formats
---

# Address Types

The Evolution SDK implements all Cardano address formats as defined in the ledger specification. This section documents the serialization and deserialization of each address type.

## SDK Architecture

Evolution SDK provides two interfaces for working with addresses:

**Core Address Module (`Core.Address`)**: A unified API for common address operations.
- Handles `Payment Credential + Optional Staking Credential`
- Automatically serializes as Base Address (with staking) or Enterprise Address (without staking)
- Simplifies most serialization tasks

**Type-Specific Modules**: Complete implementations for protocol compliance.
- `Core.BaseAddress`, `Core.EnterpriseAddress`, `Core.RewardAddress`, `Core.PointerAddress`, `Core.ByronAddress`
- Required for exact CBOR encoding/decoding
- Used for protocol-level operations and blockchain tooling

## Address Format Specifications

Each address type encodes different credential combinations:

- **Payment Credential**: Hash of payment verification key or script
- **Staking Credential**: Hash of stake verification key or script

### Format Comparison

| Address Type | Payment | Staking | On-Chain Size | Bech32 Prefix | Header Bits |
|--------------|---------|---------|---------------|---------------|-------------|
| **[Base](./base)** | ✓ | ✓ | 57 bytes | `addr`/`addr_test` | `0000xxxx` |
| **[Enterprise](./enterprise)** | ✓ | ✗ | 29 bytes | `addr`/`addr_test` | `0110xxxx` |
| **[Reward](./reward)** | ✗ | ✓ | 29 bytes | `stake`/`stake_test` | `1110xxxx` |
| **[Pointer](./pointer)** | ✓ | Pointer | Variable | `addr`/`addr_test` | `0100xxxx` |

## Address Type Documentation

Detailed serialization specifications for each format:

- **[Base Addresses](./base)** - Payment and staking credential encoding
- **[Enterprise Addresses](./enterprise)** - Payment credential only encoding
- **[Reward Addresses](./reward)** - Staking credential only encoding
- **[Pointer Addresses](./pointer)** - On-chain stake registration reference encoding

## Related

- **[Conversion](/docs/addresses/conversion)** - Format transformations (Bech32, hex, bytes)
- **[Validation](/docs/addresses/validation)** - Parsing and validation
10 changes: 10 additions & 0 deletions docs/content/docs/addresses/address-types/meta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"title": "Address Types",
"pages": [
"index",
"base",
"enterprise",
"reward",
"pointer"
]
}
123 changes: 123 additions & 0 deletions docs/content/docs/addresses/address-types/pointer.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
---
title: Pointer Addresses
description: Payment addresses with on-chain stake pointer reference
---

# Pointer Addresses

> **! Legacy Format**: Pointer addresses are rarely used in practice. This documentation exists for parsing historical transactions and understanding the complete address specification.

Pointer addresses contain a payment credential plus a pointer to an on-chain stake registration certificate. They reference stake information indirectly via blockchain coordinates instead of embedding a stake credential.

## Historical Context

Pointer addresses were part of the original Shelley address design, intended to optimize for size by referencing stake information rather than embedding it.

**Original Goal**: Save 28 bytes per address by using a pointer instead of a full stake credential.

**Reality**: Minimal savings, added complexity. On-chain stake registrations must be permanent and indexed. Wallet software needs additional logic to resolve pointers.

**Outcome**: The ecosystem converged on base addresses as the standard format.

## Structure

```
Pointer Address = Payment Credential + Pointer (slot, txIndex, certIndex)
```

**Payment Credential**: Controls who can spend UTXOs
**Pointer**: References stake registration cert location on-chain

## Comparison with Base Addresses

| Feature | Pointer | Base |
|---------|---------|------|
| Payment credential | • Yes | • Yes |
| Stake credential | Via pointer | Direct embed |
| Size | Variable | Fixed 57 bytes |
| Complexity | High | Low |
| Adoption | Rare | Universal |
| Recommended | ✗ No | • Yes |

## Parsing Pointer Addresses

If you encounter a pointer address, you can parse it using the `AddressDetails` utility:

```typescript twoslash
import { AddressDetails } from "@evolution-sdk/evolution";

// Parse a pointer address from Bech32
const details = AddressDetails.fromBech32("addr_test1gz...");

if (details.type === "PointerAddress" && details.address._tag === "PointerAddress") {
// Type narrowed to PointerAddress - now we can access pointer-specific properties
console.log("Payment credential:", details.address.paymentCredential);
console.log("Pointer:", details.address.pointer);
}
```

## Migration to Base Address

If you have funds at a pointer address, you can send them to a base address using your wallet. Create a transaction that spends from the pointer address UTXOs and sends to your base address. This requires the appropriate signing keys for the payment credential referenced in the pointer address.

## Advanced: Understanding Pointer Structure

The pointer identifies where the stake registration certificate lives on-chain:

- **slot**: Block slot number containing the registration
- **txIndex**: Transaction position within that block
- **certIndex**: Certificate position within that transaction

This triplet uniquely identifies the stake registration certificate.

### Stake Registration Requirement

For a pointer address to work:

1. A stake registration certificate must exist on-chain at the pointer location
2. That certificate must register a stake credential
3. The pointer (slot, txIndex, certIndex) must be valid and resolvable

If any of these fail, the address is invalid.

## Advanced: Manual Construction

This example shows the structure for completeness. **Do not use in production**:

```typescript twoslash
import { Core } from "@evolution-sdk/evolution";

// Create payment credential (key hash)
const paymentCred = new Core.KeyHash.KeyHash({
hash: new Uint8Array(28).fill(0)
});

// Create pointer to stake registration certificate
// Note: Pointer uses numbers, not bigint
const pointer = new Core.Pointer.Pointer({
slot: 12345,
txIndex: 2,
certIndex: 0
});

// Construct pointer address (rarely used in practice)
// PointerAddress is a separate class from regular Address
const pointerAddr = new Core.PointerAddress.PointerAddress({
networkId: 0,
paymentCredential: paymentCred,
pointer: pointer
});

console.log("Pointer address (deprecated):", pointerAddr);
```

## Format Details

**Bech32 Prefix**: `addr` (mainnet) or `addr_test` (testnet)
**Length**: Variable (34-48 bytes depending on pointer values)
**Header Bits**: `0100xxxx` (pointer address type)

## Related

- **[Base Addresses](./base)** - Standard address format with embedded stake credential
- **[Enterprise Addresses](./enterprise)** - Payment credential only
Loading
Loading