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

# Aptos

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

> [card] Recommended: JavaScript SDK for React Native
>
> While this SDK is still supported, we recommend using newer [JavaScript SDK](https://docs.dynamic.xyz/docs/javascript/reference/react-native-quickstart.md), which is optimized for React Native, but also comes with a host of other benefits.

## Overview

Aptos uses the Ed25519 elliptic curve — the same curve as Solana. You derive an Aptos address by hashing the Solana wallet's public key with SHA3-256 and appending a scheme byte. Transactions use BCS (Binary Canonical Serialization).

| Property | Value |
| - | - |
| Curve | Ed25519 |
| Root Wallet | Solana |
| Address Format | `0x` + SHA3-256 hex (64 chars) |
| Hashing | SHA3-256 |
| Serialization | BCS |
| Smallest Unit | Octas (1 APT = 10^8 octas) |

## Dependencies

```bash npm theme={"system"}
npm install @aptos-labs/ts-sdk @noble/hashes bs58
```

```bash yarn theme={"system"}
yarn add @aptos-labs/ts-sdk @noble/hashes bs58
```

```bash pnpm theme={"system"}
pnpm add @aptos-labs/ts-sdk @noble/hashes bs58
```

```bash bun theme={"system"}
bun add @aptos-labs/ts-sdk @noble/hashes bs58
```

## Derive Address

Extract the Ed25519 public key from the Solana wallet address, append the single-key scheme byte (`0x00`), and hash with SHA3-256:

```typescript theme={"system"}
import { sha3_256 } from "@noble/hashes/sha3";
import bs58 from "bs58";

function deriveAptosAddress(solanaAddress: string): string {
  const pubkey = bs58.decode(solanaAddress);
  const payload = new Uint8Array(33);
  payload.set(pubkey, 0);
  payload[32] = 0x00; // single-key Ed25519 scheme byte
  return "0x" + bytesToHex(sha3_256(payload));
}
```

## Sign a Message

Sign the raw UTF-8 bytes of the message using the Solana wallet:

```typescript theme={"system"}
async function signAptosMessage(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 `@aptos-labs/ts-sdk` to build the transaction, generate the signing message, and submit with an Ed25519 authenticator:

```typescript theme={"system"}
import {
  Aptos, AptosConfig, Network, generateSigningMessageForTransaction,
  AccountAuthenticatorEd25519, Ed25519PublicKey, Ed25519Signature,
} from "@aptos-labs/ts-sdk";
import bs58 from "bs58";

const aptos = new Aptos(new AptosConfig({ network: Network.TESTNET }));

async function sendAptosTransfer(
  recipient: string,
  amountOctas: number,
  aptosAddress: string,
): Promise<string> {
  const wallet = dynamicClient.wallets.userWallets.find(w => w.chain === "SOL")!;
  const pubkeyBytes = bs58.decode(wallet.address);

  const transaction = await aptos.transaction.build.simple({
    sender: aptosAddress,
    data: {
      function: "0x1::aptos_account::transfer",
      functionArguments: [recipient, amountOctas],
    },
  });

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

  const authenticator = new AccountAuthenticatorEd25519(
    new Ed25519PublicKey(pubkeyBytes),
    new Ed25519Signature(bytesToHex(sigBytes)),
  );

  const { hash } = await aptos.transaction.submit.simple({
    transaction,
    senderAuthenticator: authenticator,
  });

  return hash;
}
```

## Verify a Signature

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

function verifyAptosSignature(
  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 getAptosBalance(address: string): Promise<string> {
  const BASE = "https://fullnode.testnet.aptoslabs.com/v1";

  // Try legacy CoinStore model
  try {
    const res = await fetch(
      `${BASE}/accounts/${address}/resource/0x1::coin::CoinStore%3C0x1::aptos_coin::AptosCoin%3E`,
    );
    if (res.ok) {
      const data = await res.json();
      const octas = BigInt(data.data?.coin?.value ?? "0");
      if (octas > BigInt(0)) {
        return (Number(octas) / 1e8).toFixed(8).replace(/\.?0+$/, "");
      }
    }
  } catch {
    // fall through to FA model
  }

  // Fall back to Fungible Asset model
  try {
    const res = await fetch(`${BASE}/view`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        function: "0x1::primary_fungible_store::balance",
        type_arguments: ["0x1::fungible_asset::Metadata"],
        arguments: [address, "0x000000000000000000000000000000000000000000000000000000000000000a"],
      }),
    });
    if (res.ok) {
      const data = await res.json();
      const octas = BigInt(data[0] ?? "0");
      return (Number(octas) / 1e8).toFixed(8).replace(/\.?0+$/, "");
    }
  } catch {
    // ignore
  }

  return "0";
}
```

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


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.