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

# Developer Quickstart

> Bridge USDC using the Gas API and Cashmere smart contracts.

import { Tabs, Tab, Callout } from 'mintlify';

## What You Need

<Callout type="info">
  The Cashmere Developer SDK is currently in **alpha**.\
  A more comprehensive and production-ready version will be released in the coming weeks.
</Callout>

* Access to a JSON-RPC endpoint for the origin chain (e.g., Ethereum).
* A signer with USDC balance and the ability to send transactions.
* Cashmere contract addresses from the Smart Contracts guide.
* Node.js (for the TypeScript example) or your preferred language runtime.

<Callout type="info">
  All tooling in this quickstart is open—no API keys or proprietary SDKs required.
</Callout>

## Step-by-Step (EVM)

<Tabs>
  <Tab title="1. Fetch Fee" icon="bolt">
    ```ts theme={null}
    const response = await fetch(
      'https://gas.cashmere.exchange/getEcdsaSig_native?' +
        new URLSearchParams({
          localDomain: '0',          // Ethereum
          destinationDomain: '3',    // Arbitrum
          isV2: 'true',              // transferV2
          isNative: 'false',
        })
    );

    if (!response.ok) throw new Error('Gas API error');
    const quote = await response.json();
    ```
  </Tab>

  <Tab title="2. Build Params" icon="list-check">
    ```ts theme={null}
    import { zeroPadValue, parseUnits } from 'ethers';

    const isNative = Boolean(useNativeFees);
    const amount = parseUnits(transferAmount, 6);                  // always 6-decimal USDC
    const gasDropAmount = isNative
      ? parseUnits(nativeGasDrop, nativeDecimals)                  // e.g. 18 for EVM, 9 for Solana
      : parseUnits(usdcGasDrop, 6);

    const minimumFeeBps = fetchMinimumFeeBps(localDomain, destinationDomain); // e.g. 100 (1%)
    const maxFee = ceilDiv(amount * BigInt(minimumFeeBps), 10_000n);

    const params = {
      amount,
      maxFee,
      fee: BigInt(quote.fee),
      deadline: BigInt(quote.deadline),
      gasDropAmount,
      destinationDomain,
      minFinalityThreshold: 1_000,                                  // Fast preset
      recipient: zeroPadValue(destinationAddress, 32),
      solanaOwner: ZERO_BYTES_32,                                   // non-Solana routes
      isNative,
      hookData: '0x00',
      signature: quote.signature,
    };

    <Callout type="info">
      Bridging into Solana (`destinationDomain = 5`)? Set `recipient` to the hex-encoded USDC Associated Token Account (ATA) for the destination wallet, and populate `solanaOwner` with that wallet’s 32-byte address. Cashmere relayers will bootstrap the ATA if it does not already exist.
    </Callout>
    ```
  </Tab>

  <Tab title="3. Execute" icon="rocket-launch">
    ```ts theme={null}
    const provider = new ethers.JsonRpcProvider(process.env.RPC_URL);
    const signer = new ethers.Wallet(process.env.PRIVATE_KEY!, provider);
    const cashmere = createCashmereContract(signer);               // load ABI + address from config
    const usdc = createUsdcContract(signer);

    const allowance = params.isNative ? params.amount : params.amount + params.gasDropAmount;
    await usdc.approve(cashmere.target, allowance);

    const overrides = params.isNative
      ? { value: params.fee + params.gasDropAmount }
      : {};

    const tx = await cashmere.transferV2(params, overrides);
    await tx.wait();
    ```
  </Tab>
</Tabs>

<Callout type="info">
  <strong>Decimals cheat sheet</strong><br />
  Gas API quotes `fee` in 6-decimal USDC unless `isNative=true`. For native-fee routes use the chain’s native decimals when encoding `gasDropAmount` and forwarding value:
  EVM → 18 decimals, Solana (lamports) → 9, Sui → 9, Aptos → 8.
</Callout>

<Callout type="info">
  Need tighter `maxFee` bounds? Query Circle IRIS at `https://iris-api.circle.com/v2/burn/USDC/fees/{sourceDomainId}/{destDomainId}`. The response lists recommended `minimumFee` values for each `finalityThreshold` (e.g., 1,000 for Fast, 2,000 for Normal).
</Callout>

***

## Step-by-Step (Solana)

1. Request an Ed25519 signature from the Gas API. Pass `version=2` when calling the v2 instruction.
2. Derive the Solana Associated Token Account (ATA) for the destination wallet and convert both the ATA and owner to 32-byte hex (see the Recipient Encoding section in the Smart Contracts guide).
3. Insert an `Ed25519Program` instruction ahead of the Cashmere program call inside the same `VersionedTransaction` and reuse the quote’s `fee`, `deadline`, and signature bytes when invoking `transfer_v2`.
4. Include the Cashmere lookup table (`865YCTTsymGpBjLMTvjd3T3RCGT8yvxnAHhyKZqRFfLi`) so the transaction stays within the account limits, and fetch the config account to populate fee collectors.

```ts theme={null}
import { Ed25519Program, PublicKey } from '@solana/web3.js';
import { getAssociatedTokenAddressSync } from '@solana/spl-token';

const quote = await fetchEd25519Quote({ localDomain: 5, destinationDomain, isNative, version: 2 });

const ed25519Ix = Ed25519Program.createInstructionWithPublicKey({
  publicKey: Buffer.from(quote.publicKey.slice(2), 'hex'),
  message: Buffer.from(quote.message.slice(2), 'hex'),
  signature: Buffer.from(quote.signature.slice(2), 'hex'),
});

const usdcMint = new PublicKey(process.env.SOLANA_USDC_MINT!);
const destinationWallet = new PublicKey(targetSolanaOwner);
const ata = getAssociatedTokenAddressSync(usdcMint, destinationWallet, true);
const recipientHex = toBytes32(ata);
const solanaOwnerHex = toBytes32(destinationWallet);
```

🔗 A full Anchor transaction (including PDA derivations and lookup-table usage) lives under **Integration Examples → Solana Transfer (Anchor)**.

## Step-by-Step (Sui)

1. Request the Ed25519 quote with `localDomain=8` (Sui) and your target `destinationDomain`.
2. Mint or split USDC/SUI coins so `prepare_deposit_for_burn_ticket` receives `usdc_coin` containing the burn amount plus any USDC gas drop. When `fee_is_native=true`, split SUI gas to cover `fee + gas_drop_amount`.
3. Call `prepare_deposit_for_burn_ticket`, forward the ticket to Circle’s `deposit_for_burn_with_package_auth`, then finish with `post_deposit_for_burn`.

```ts theme={null}
const quote = await fetchEd25519Quote({ localDomain: 8, destinationDomain, isNative });
const signatureBytes = hexToByteArray(quote.signature);

tx.moveCall({
  target: `${modules.cashmereTransfer}::prepare_deposit_for_burn_ticket`,
  typeArguments: [modules.usdcType],
  arguments: [
    usdcCoin,
    nativeFeeCoin,
    tx.pure.u32(destinationDomain),
    tx.pure.address(recipientHex),
    tx.pure.address(solanaOwnerHex),
    tx.pure.u64(quote.fee),
    tx.pure.u64(quote.deadline),
    tx.pure.u64(gasDropAmount.toString()),
    tx.pure.bool(isNative),
    tx.pure.vector('u8', signatureBytes),
    tx.object(configId),
    tx.object(clockId),
  ],
});
```

🔗 Refer to **Integration Examples → Sui Transfer (Transactions API)** for the full script with mainnet object IDs.

## Step-by-Step (Aptos)

1. Fetch the Ed25519 quote with `localDomain=9` and convert the signature hex into a byte array.
2. Populate `transfer_outer` parameters: amounts in 6-decimal USDC, optional native fee in 8-decimal APT, and the 32-byte `recipient`/`solana_owner` fields.
3. Build the entry-function payload, simulate if your wallet supports it, then sign and submit.

```ts theme={null}
const quote = await fetchEd25519Quote({ localDomain: 9, destinationDomain, isNative });
const signatureBytes = hexToByteArray(quote.signature);

const payload = {
  function: `${process.env.APTOS_CASHMERE_MODULE}::transfer_outer`,
  typeArguments: [],
  functionArguments: [
    amount.toString(),
    nativeAmount.toString(),            // fee + gas drop when fee_is_native
    destinationDomain,
    recipientHex,
    solanaOwnerHex,
    quote.fee,
    quote.deadline,
    gasDropMicro.toString(),
    isNative,
    signatureBytes,
  ],
};
```

🔗 See **Integration Examples → Aptos Transfer (ts-sdk)** for a complete example that handles deadline refreshes and Pontem wallet quirks.

***

## Monitor the Outcome

* Use `https://kapi.cashmere.exchange/transactionsmainnet` to confirm settlement.
* Subscribe to `wss://gas.cashmere.exchange/subscribe` for live fee updates.

```ts theme={null}
const ws = new WebSocket('wss://gas.cashmere.exchange/subscribe');
ws.onmessage = (event) => console.log('Fee update:', JSON.parse(event.data));
```

```bash theme={null}
curl "https://kapi.cashmere.exchange/transactionsmainnet?senders=0xYourAddress&limit=20"
```

***

## Next Steps

* Review the [Backend APIs](/developers/backend-apis) for detailed payload structures.
* Explore the [Smart Contracts](/developers/smart-contracts) guide for per-chain nuances.
* Build notifications by polling `/transactionsmainnet` or streaming from your preferred indexer.
