> ## Documentation Index
> Fetch the complete documentation index at: https://docs.layerzero.network/llms.txt
> Use this file to discover all available pages before exploring further.

# Starknet FAQ

> Frequently asked questions about developing LayerZero applications on Starknet including account abstraction, OFT decimals, and crosschain transfers.

Frequently asked questions about developing LayerZero applications on Starknet.

## General

### Why does Starknet use account contracts instead of EOAs?

Starknet implements **native account abstraction**, meaning all accounts are smart contracts. This provides:

* **Flexible signature validation**: Support for different signature schemes
* **Custom transaction logic**: Batching, session keys, social recovery
* **Gas abstraction**: Pay fees in different tokens
* **Enhanced security**: Multi-sig, spending limits, etc.

Before you can deploy any contract, you must first deploy and fund an account contract (for example, Ready Wallet, formerly Argent; Braavos; or OpenZeppelin Account).

***

### What's the difference between class\_hash and contract\_address?

| Concept               | Description                                 | Analogy                 |
| --------------------- | ------------------------------------------- | ----------------------- |
| **class\_hash**       | Unique identifier for contract **code**     | Like a class/template   |
| **contract\_address** | Unique identifier for contract **instance** | Like an object/instance |

```
class_hash = 0x123...  (the "OFT" code template)
     │
     ├── contract_address = 0xaaa... (OFT instance for Token A)
     ├── contract_address = 0xbbb... (OFT instance for Token B)
     └── contract_address = 0xccc... (OFT instance for Token C)
```

Multiple contracts can share the same `class_hash` but have different addresses and state.

***

### Do I need to deploy my own Endpoint?

**No.** LayerZero deploys and maintains the Endpoint contract on each supported chain. You only need to:

1. Deploy your OApp/OFT contract
2. Reference the existing Endpoint address in your constructor
3. Configure your security settings (DVNs, peers, etc.)

Check [LayerZero Deployments](/v2/deployments/deployed-contracts) for the official Endpoint address.

***

### What's the difference between STRK and ETH on Starknet?

Starknet supports two fee tokens:

| Token    | Purpose               | Notes                          |
| -------- | --------------------- | ------------------------------ |
| **STRK** | Native Starknet token | Primary fee token on Starknet  |
| **ETH**  | Bridged Ethereum      | Still supported as a fee token |

LayerZero messaging fees are paid in the native token configured by your OApp (usually STRK on Starknet).

***

## Development

### How do I encode addresses for crosschain messages?

LayerZero uses `Bytes32` for addresses to support different address sizes across VMs:

```rust wrap theme={null}
// Starknet address (felt252) → Bytes32
let starknet_addr: ContractAddress = ...;
let as_bytes32: Bytes32 = starknet_addr.into();

// EVM address (20 bytes) → Bytes32 (left-padded with zeros)
// 0xABCDEF... becomes 0x000000000000000000000000ABCDEF...
let evm_peer = Bytes32 {
    value: 0x000000000000000000000000_<20_BYTE_EVM_ADDRESS>
};
```

***

### How do I batch multiple configuration calls?

Multicall is implemented at the account-contract level: a single INVOKE can execute multiple calls atomically when the account supports it. Most major account implementations (Ready Wallet, formerly Argent; Braavos; OpenZeppelin Account) expose multicall by default. If an account contract does not implement multicall, batching is not available for that account.

```typescript wrap theme={null}
// Using starknet.js
const calls = [
  { contractAddress: oft, entrypoint: 'set_enforced_options', calldata: [...] },
  { contractAddress: oft, entrypoint: 'set_dvn_config', calldata: [...] },
  { contractAddress: oft, entrypoint: 'set_peer', calldata: [...] },  // Last!
];

await account.execute(calls);  // All execute atomically
```

This is useful for configuring all settings in one transaction, ensuring the pathway isn't opened until everything is ready.

***

### What is the shared decimals limit?

OFTs use **shared decimals** (default: 6) to maintain consistency across chains with different token decimal precision:

| Local Decimals | Shared Decimals | Conversion Rate | Max Precision |
| -------------- | --------------- | --------------- | ------------- |
| 18             | 6               | 10^12           | 0.000001      |
| 8              | 6               | 10^2            | 0.000001      |
| 6              | 6               | 1               | 0.000001      |

**Implications:**

* Amounts smaller than the conversion rate become "dust" and are removed
* Always use `quote_oft` to see exact received amounts before sending

***

### Why is my constructor setting the wrong owner?

When deploying via the Universal Deployer Contract (UDC), `get_caller_address()` returns the UDC address, not your account.

**Wrong:**

```rust wrap theme={null}
#[constructor]
fn constructor(ref self: ContractState, endpoint: ContractAddress) {
    self.ownable.initializer(get_caller_address());  // Returns UDC!
}
```

**Correct:**

```rust wrap theme={null}
#[constructor]
fn constructor(
    ref self: ContractState,
    endpoint: ContractAddress,
    owner: ContractAddress,  // Pass explicitly
) {
    self.ownable.initializer(owner);
}
```

***

### How do I check my OApp configuration?

Query configuration via the Endpoint or your OApp:

```rust wrap theme={null}
// Check peer
let peer = oapp.get_peer(eid);

// Check delegate
let delegate = endpoint.get_delegate(oapp_address);

// Check library
let send_lib = endpoint.get_send_library(oapp_address, dst_eid);

// Check enforced options
let options = oapp.get_enforced_options(dst_eid, msg_type);
```

Or use block explorers like [Voyager](https://voyager.online/) or [Starkscan](https://starkscan.co/).

***

## Deployment

### What tooling do I use to deploy Starknet contracts?

Use **Starknet Foundry** (`sncast`):

```bash theme={null}
# Declare (publish code)
sncast declare --contract-name MyOFT

# Deploy (create instance)
sncast deploy --class-hash 0x... --arguments '...'
```

***

### Can I use Hardhat or Foundry (EVM) for Starknet?

No. Starknet uses Cairo, not Solidity. You need Starknet-specific tools:

| EVM Tool | Starknet Equivalent                 |
| -------- | ----------------------------------- |
| Hardhat  | Scarb + sncast                      |
| Foundry  | Starknet Foundry (sncast + snforge) |
| Remix    | N/A (use Scarb locally)             |

***

### How do I verify my contract?

Use `sncast verify` or block explorers:

**Using sncast (recommended):**

```bash theme={null}
sncast verify \
  --class-hash <CLASS_HASH> \
  --contract-name MyOFT \
  --verifier voyager \
  --network sepolia
```

**Using block explorers:**

1. **Voyager**: Go to contract → "Verify & Publish"
2. **Starkscan**: Go to contract → "Verify Contract"

Upload your source files or provide a GitHub link.

***

## Crosschain

### How long do crosschain transfers take?

Transfer time depends on:

1. **Source chain finality**: Time for DVNs to verify
2. **DVN verification**: Usually 1-5 minutes after finality
3. **Executor delivery**: Near-instant after verification

Typical Starknet → EVM: 10-30 minutes
Typical EVM → Starknet: 5-15 minutes

Track your transfer on [LayerZero Scan](https://layerzeroscan.com/).

***

### Why did my crosschain message fail?

Common reasons:

1. **Insufficient gas**: Increase enforced options
2. **Peer not set**: Configure bidirectional peers
3. **Contract paused**: Unpause the destination contract
4. **Rate limit exceeded**: Check OFTMintBurnAdapter limits
5. **Application error**: Bug in `_lz_receive` logic

Check [LayerZero Scan](https://layerzeroscan.com/) for the `LzReceiveAlert` event details.

***

### Can I retry a failed message?

If a message failed execution (not verification), you can:

1. **Fix the issue** on the destination contract
2. **Use recovery operations** if needed:
   * `clear`: Clear a blocking message
   * `nilify`: Reset verification
   * `skip`: Skip unverified message

See [Protocol Overview - Recovery Operations](/v2/developers/starknet/protocol-overview#recovery-operations).

***

## Security

### What are the default security settings?

If you don't configure custom settings:

| Setting         | Default                 |
| --------------- | ----------------------- |
| DVN             | LayerZero Labs DVN      |
| Executor        | LayerZero Labs Executor |
| Send Library    | ULN302                  |
| Receive Library | ULN302                  |

***

### Should I use multiple DVNs?

**Recommended for production.** Multiple DVNs provide:

* Increased security (multiple independent verifiers)
* Resilience (no single point of failure)
* Trust minimization

Example dual DVN setup using the TypeScript SDK:

```typescript wrap theme={null}
import {encodeUlnConfig} from '@layerzerolabs/lz-v2-protocol-starknet';

const config = encodeUlnConfig({
  confirmations: 15,
  has_confirmations: true,
  required_dvns: [LAYERZERO_DVN, PARTNER_DVN], // Sorted ascending
  has_required_dvns: true,
  optional_dvns: [],
  optional_dvn_threshold: 0,
  has_optional_dvns: false,
});
```

***

### What's the difference between owner and delegate?

| Role         | Permissions                        | Use Case               |
| ------------ | ---------------------------------- | ---------------------- |
| **Owner**    | Full control (peers, ownership)    | Long-term custody      |
| **Delegate** | Configuration only (DVNs, options) | Operational management |

Delegates can manage day-to-day configuration without having power to set peers or transfer ownership.

***

## Costs

### What fees are involved in crosschain transfers?

1. **Source chain gas**: Pay for the `send` transaction
2. **LayerZero fees**: DVN and Executor fees (quoted via `quote_send`)
3. **Destination gas**: Paid by Executor, funded by step 2

Use `quote_send` to get the total LayerZero fee before sending.

***

### Why are my fees higher than expected?

Fee factors:

* **Options**: Higher gas limits = higher fees
* **Message size**: Larger payloads cost more
* **Destination chain**: Different chains have different costs
* **DVN count**: More DVNs = higher verification costs

Optimize by:

* Using appropriate gas limits (not excessive)
* Minimizing message payload size
* Using efficient encoding

***

## Troubleshooting

### Where can I get help?

1. **Documentation**: You're here! Check other sections.
2. **LayerZero Scan**: Track and debug transactions
3. **Discord**: [LayerZero Discord](https://discord.com/invite/ktbvm8Nkcr)
4. **GitHub**: Report issues on the relevant repository

***

### How do I debug a transaction?

1. **Get transaction hash** from sncast output
2. **Check status**:
   ```bash theme={null}
   sncast tx-status <HASH>
   ```
3. **View on explorer**: Voyager or Starkscan
4. **Check events**: Look for error events
5. **Simulate locally**: Use `snforge test`

***

## Additional Resources

* [Getting Started](/v2/developers/starknet/getting-started)
* [OApp Overview](/v2/developers/starknet/oapp/overview)
* [OFT Overview](/v2/developers/starknet/oft/overview)
* [Common Errors](/v2/developers/starknet/troubleshooting/common-errors)
* [Starknet Documentation](https://docs.starknet.io/)
* [The Cairo Book](https://book.cairo-lang.org/)
