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.
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
npm install @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:
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
const hash = sha3_256(payload);
return "0x" + bytesToHex(hash);
}
Sign a Message
Sign the raw UTF-8 bytes of the message using the Solana wallet:
import { signMessage } from "@dynamic-labs-sdk/client";
import type { WalletAccount } from "@dynamic-labs-sdk/client";
async function signAptosMessage(
message: string,
solWallet: WalletAccount,
): Promise<string> {
const messageBytes = new TextEncoder().encode(message);
const result = await signMessage({
walletAccount: solWallet,
message: bytesToHex(messageBytes),
});
return result.signature;
}
Verify a Signature
Verify the Ed25519 signature against the raw message bytes:
import { ed25519 } from "@noble/curves/ed25519";
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
Query the APT balance using the Aptos REST API. Tries the legacy CoinStore resource first, then falls back to the Fungible Asset model used by newer accounts:
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";
}
Send a Transfer
Use the @aptos-labs/ts-sdk to build the transaction, generate the signing message, and submit with an Ed25519 authenticator:
import {
Aptos, AptosConfig, Network, generateSigningMessageForTransaction,
AccountAuthenticatorEd25519, Ed25519PublicKey, Ed25519Signature,
} from "@aptos-labs/ts-sdk";
import { signMessage } from "@dynamic-labs-sdk/client";
import bs58 from "bs58";
const aptos = new Aptos(new AptosConfig({ network: Network.TESTNET }));
async function sendAptosTransfer(
recipient: string,
amountOctas: number,
aptosAddress: string,
solWallet: WalletAccount,
): Promise<string> {
const pubkeyBytes = bs58.decode(solWallet.address);
const transaction = await aptos.transaction.build.simple({
sender: aptosAddress,
data: {
function: "0x1::aptos_account::transfer",
functionArguments: [recipient, amountOctas],
},
});
const signingBytes = generateSigningMessageForTransaction(transaction);
const signResult = await signMessage({
walletAccount: solWallet,
message: bytesToHex(signingBytes),
});
const sigBytes = decodeSig(signResult.signature);
const authenticator = new AccountAuthenticatorEd25519(
new Ed25519PublicKey(pubkeyBytes),
new Ed25519Signature(bytesToHex(sigBytes)),
);
const { hash } = await aptos.transaction.submit.simple({
transaction,
senderAuthenticator: authenticator,
});
return hash;
}