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

# Quickstart

> Get swapping in under 5 minutes.

## 1. Install

```bash theme={null}
npm install @oneswap/sdk
```

## 2. Get your API key

Create your SDK API key from the wallet-authenticated OneSwap developer portal.

* `os_live_...` keys identify your integration.
* Authenticate your Canton wallet, call `POST /api/sdk/wallet-login`, then create keys on `POST /api/sdk/keys`.
* For mainnet, create the key from `https://oneswap.cc/developer/keys`.
* For devnet, create the key from `https://devnet.oneswap.cc/developer/keys`.
* SDK developer auth and SDK swap flows do not use site-access tokens or access codes.
* Developer earnings, collections, and account analytics stay on the wallet-authenticated developer portal.
* Legacy `POST /api/sdk/register` and `POST /api/sdk/login` are retired and return `410 Gone`.

## 3. Initialize

```typescript theme={null}
import { OneSwap } from '@oneswap/sdk'

const apiKey = 'os_live_...'
const authClient = new OneSwap({ apiKey })
```

In SDK code, use `Amulet` when you mean `CC (Amulet)`.

To target devnet:

```typescript theme={null}
const authClient = new OneSwap({
  apiKey,
  environment: 'devnet',
})
```

## 4. Verify the user's wallet

Ask the user to sign the OneSwap challenge with the same wallet that will send the deposit.

```typescript theme={null}
const partyId = 'alice::12205a8c...'

const challenge = await authClient.walletAuth.requestChallenge(partyId)
const signature = await wallet.signMessage(challenge.message)

const verified = await authClient.walletAuth.verifyChallenge({
  partyId,
  nonce: challenge.nonce,
  signature,
  publicKey: wallet.publicKey,
})

const client = new OneSwap({
  apiKey,
  walletToken: verified.token,
})
```

If your app stores and refreshes the wallet token in browser state, you can pass `walletToken` as a function instead of a fixed string.

## 5. Get a quote

```typescript theme={null}
const quote = await client.quotes.get({
  from: 'Amulet',
  to: 'USDCx',
  amount: '100',
  receiverParty: partyId,
})

console.log(quote.outputAmount)
console.log(quote.rate)
console.log(quote.priceImpact)
console.log(quote.inputTokenAdmin)
console.log(quote.outputTokenAdmin)
console.log(quote.totalInputAmount)
console.log(quote.networkFeeAmount)
console.log(quote.poolFeeAmount)
console.log(quote.inputAmountAfterPoolFee)
console.log(quote.estimatedTrafficCost?.cc)
```

`amount` is the exact deposit amount the user plans to send. OneSwap estimates the payout-leg network fee in the input token, deducts that internally from the deposit, then deducts the 0.3% pool fee from the remainder before pricing the swap. `quote.outputAmount` is calculated from `quote.inputAmountAfterPoolFee`. `quote.totalInputAmount` currently echoes the exact deposit amount to send, and `quote.trafficFeeInInput` remains available as a compatibility alias for `quote.networkFeeAmount`.

If a token symbol exists under multiple admins, pass `poolId` or both token admin fields (`fromAdmin` and `toAdmin`) so OneSwap can resolve the exact pool pair.

## 6. Create a swap intent

```typescript theme={null}
const swap = await client.swaps.create({
  fromToken: 'Amulet',
  toToken: 'USDCx',
  amount: '100',
  walletAddress: partyId,
})

console.log(swap.depositAddress) // pool swap party
console.log(swap.depositReference) // pass through when the wallet supports Canton reason/reference metadata
console.log(swap.quotedSwapAmount) // the original deposit amount you asked OneSwap to process
console.log(swap.expectedAmount) // final deposit amount to send
console.log(swap.totalInputAmount) // same as expectedAmount in the current flow
console.log(swap.networkFeeAmount)
console.log(swap.poolFeeAmount)
console.log(swap.inputAmountAfterPoolFee)
console.log(swap.expectedOutput)
console.log(swap.expiresAt)
```

The `walletAddress` field is optional, but if you send it, it must match the authenticated wallet token.

Swap intents currently remain valid for 24 hours. Use `swap.expiresAt` from the response rather than hard-coding the timeout.

## 7. Send the deposit

The user sends `swap.expectedAmount` (same as `swap.totalInputAmount`) from `partyId` directly to `swap.depositAddress` and passes through `swap.depositReference` when the wallet supports Canton reason/reference metadata. Do not send from a different wallet or Canton party, or the swap will not complete.

## 8. Wait for completion

```typescript theme={null}
swap.on('processing', () => console.log('Deposit detected'))

const result = await swap.wait()
console.log(`Done! Got ${result.actualOutput} ${result.outputToken}`)
```

If slippage is exceeded, the swap is refunded automatically to the depositor party.

## What's next

<CardGroup cols={2}>
  <Card title="Swaps Guide" icon="arrow-right-arrow-left" href="/guides/swaps">
    Slippage, status polling, and failure states
  </Card>

  <Card title="Wallet Guide" icon="wallet" href="/guides/wallets">
    Connect a wallet and manage wallet tokens
  </Card>

  <Card title="SDK Methods" icon="code" href="/reference/sdk-methods">
    Review the swaps-focused SDK surface
  </Card>
</CardGroup>
