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

# Algorand

> Derive Algorand addresses and sign transactions using Dynamic embedded wallets in React Native

## Overview

Algorand uses the Ed25519 elliptic curve — the same curve as Solana. An Algorand address is the base32-encoded 32-byte public key with a 4-byte checksum appended.

| Property       | Value                                    |
| -------------- | ---------------------------------------- |
| Curve          | Ed25519                                  |
| Root Wallet    | Solana                                   |
| Address Format | base32(pubkey ‖ checksum\[4]) — 58 chars |
| Hashing        | SHA-512/256 (checksum only)              |
| Serialization  | MessagePack                              |
| Smallest Unit  | microAlgo (1 ALGO = 10^6 microAlgo)      |

## Dependencies

<CodeGroup>
  ```bash npm theme={"system"}
  npm install @noble/hashes bs58
  ```

  ```bash yarn theme={"system"}
  yarn add @noble/hashes bs58
  ```

  ```bash pnpm theme={"system"}
  pnpm add @noble/hashes bs58
  ```

  ```bash bun theme={"system"}
  bun add @noble/hashes bs58
  ```
</CodeGroup>

## Derive Address

Algorand's address is a 32-byte Ed25519 public key encoded in base32, with a 4-byte checksum from SHA-512/256 of the public key:

```typescript theme={"system"}
import { sha512_256 } from "@noble/hashes/sha512.js";
import bs58 from "bs58";

const BASE32_ALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";

function base32Encode(bytes: Uint8Array): string {
  let result = "";
  let bits = 0;
  let value = 0;
  for (const byte of bytes) {
    value = (value << 8) | byte;
    bits += 8;
    while (bits >= 5) {
      result += BASE32_ALPHA[(value >>> (bits - 5)) & 0x1f];
      bits -= 5;
    }
  }
  if (bits > 0) result += BASE32_ALPHA[(value << (5 - bits)) & 0x1f];
  return result;
}

function deriveAlgorandAddress(solanaAddress: string): string {
  const pubkey = bs58.decode(solanaAddress);
  const checksum = sha512_256(pubkey).slice(28, 32);
  const payload = new Uint8Array(36);
  payload.set(pubkey, 0);
  payload.set(checksum, 32);
  return base32Encode(payload);
}
```

## Sign a Message

Sign raw message bytes using the Solana wallet:

```typescript theme={"system"}
async function signAlgorandMessage(message: string): Promise<string> {
  const wallet = dynamicClient.wallets.userWallets.find(w => w.chain === "SOL")!;
  const messageBytes = new TextEncoder().encode(message);
  const { signedMessage } = await dynamicClient.wallets.signMessage({
    wallet,
    message: bytesToHex(messageBytes),
  });
  return signedMessage;
}
```

## Sign a Transaction

Use the signing bytes from the Algorand SDK. The SDK prepends the `"TX"` prefix before signing:

```typescript theme={"system"}
import algosdk from "algosdk";

async function sendAlgorandTransfer(
  to: string,
  amountAlgo: number,
  fromAddress: string,
): Promise<string> {
  const wallet = dynamicClient.wallets.userWallets.find(w => w.chain === "SOL")!;
  const client = new algosdk.Algodv2("", "https://testnet-api.algonode.cloud", "");
  const suggestedParams = await client.getTransactionParams().do();

  const txn = algosdk.makePaymentTxnWithSuggestedParamsFromObject({
    from: fromAddress,
    to,
    amount: Math.round(amountAlgo * 1_000_000),
    suggestedParams,
  });

  const bytesToSign = txn.bytesToSign();
  const { signedMessage } = await dynamicClient.wallets.signMessage({
    wallet,
    message: bytesToHex(bytesToSign),
  });
  const sigBytes = decodeSig(signedMessage);

  const signedTxn = txn.attachSignature(bs58.decode(wallet.address), sigBytes);
  const result = await client.sendRawTransaction(signedTxn).do();
  return result.txId;
}
```

<Info>
  The Algorand SDK handles the `"TX"` prefix required before signing. If you implement transaction signing without algosdk, prepend the bytes `0x54 0x58` to the transaction bytes before passing to `signMessage`.
</Info>

## Verify a Signature

```typescript theme={"system"}
import { ed25519 } from "@noble/curves/ed25519.js";
import bs58 from "bs58";

function verifyAlgorandSignature(
  message: string,
  signature: string,
  solanaAddress: string,
): boolean {
  const pubkey = bs58.decode(solanaAddress);
  const messageBytes = new TextEncoder().encode(message);
  const sigBytes = decodeSig(signature);
  return ed25519.verify(sigBytes, messageBytes, pubkey);
}
```

## Check Balance

```typescript theme={"system"}
async function getAlgorandBalance(address: string): Promise<string> {
  const res = await fetch(`https://testnet-api.algonode.cloud/v2/accounts/${address}`);
  if (!res.ok) return "0";
  const data = await res.json();
  return (data.amount / 1_000_000).toString();
}
```

For full implementation details see the [JavaScript Algorand guide](/javascript/reference/tier-2-chains/algorand). The only difference in React Native is the signing call — address derivation, transaction building, and RPC calls are identical.
