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

# Stablecoin Yield via Paxos Amplify

> Enable stablecoin deposits, withdrawals, and yield strategies using Paxos Amplify's protocol and Para embedded wallets.

Combine Para's wallet infrastructure with [Amplify](https://www.paxoslabs.com) to enable stablecoin yield deposits and withdrawals, all from a Para-powered wallet.

This walkthrough covers two integration paths: the **Amplify SDK** for a higher-level API, and **direct smart contract** calls for environments where the SDK isn't available.

## Why Combine Para and Paxos Amplify

| Para Wallets                                             | Paxos Amplify                               |
| -------------------------------------------------------- | ------------------------------------------- |
| Instant onboarding, MPC-secure, white-label              | Stablecoin yield across multiple strategies |
| Embedded + external wallet support                       | Multi-chain support, unified deposit API    |
| Email/social login — no seed phrase or browser extension | Audited smart contracts                     |

## Example Use Cases

1. **Fintech App Integration** — Embed stablecoin deposit and yield flows directly in your fintech application with Para's white-label wallet onboarding.

2. **Stablecoin Yield Product** — Build a consumer-facing earn product where users deposit stablecoins into Amplify vaults through a Para-powered wallet — no browser extension required.

3. **Treasury Management** — Automate treasury yield strategies from Para wallets with programmable deposit and withdrawal rules.

4. **Multi-Language Backend** — Call Amplify contracts directly from Python, Go, Swift, or any language with an Ethereum JSON-RPC library — no JavaScript SDK required.

## What You Need

* **Para SDK** for creating and managing wallets
* **EVM-compatible chain** such as Ethereum Mainnet
* **Amplify API Credentials** (`pxl_your_api_key`) from [support@paxoslabs.com](mailto:support@paxoslabs.com)
* **Amplify SDK** (SDK path only) — `@paxoslabs/amplify-sdk`

## Step-by-Step Integration

<Tabs>
  <Tab title="SDK Integration">
    ### Step 1: Install Dependencies

    ```bash theme={null}
    npm install @getpara/viem-v2-integration @getpara/react-sdk @paxoslabs/amplify-sdk viem
    ```

    ### Step 2: Initialize Para and Amplify

    Complete authentication before signing any transactions.

    ```typescript theme={null}
    import { createParaViemClient, createParaAccount } from "@getpara/viem-v2-integration";
    import { ParaWeb } from "@getpara/react-sdk";
    import { http, createPublicClient } from "viem";
    import { mainnet } from "viem/chains";
    import { initAmplifySDK } from "@paxoslabs/amplify-sdk";

    // Initialize Para
    const para = new ParaWeb("YOUR_PARA_API_KEY");

    // Initialize Amplify SDK
    await initAmplifySDK("pxl_your_api_key", {
      rpcUrls: { [mainnet.id]: "https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY" },
    });
    ```

    ### Step 3: Create Para Account and Clients

    ```typescript theme={null}
    const account = await createParaAccount(para);

    const walletClient = createParaViemClient(para, {
      account,
      chain: mainnet,
      transport: http("https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY"),
    });

    const publicClient = createPublicClient({
      chain: mainnet,
      transport: http("https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY"),
    });
    ```

    ### Step 4: Discover a Vault and Deposit

    The SDK auto-detects the optimal authorization method (gasless permit, standard approval, or existing allowance) and handles each path for you.

    ```typescript theme={null}
    import {
      getVaultsByConfig,
      prepareDepositAuthorization,
      prepareDeposit,
      isPermitAuth,
      isApprovalAuth,
      isAlreadyApprovedAuth,
      YieldType,
    } from "@paxoslabs/amplify-sdk";

    // Find a vault by yield strategy, chain, and asset
    const [vault] = await getVaultsByConfig({
      yieldType: YieldType.CORE, // "CORE", "TREASURY", or "FRONTIER"
      chainId: mainnet.id,
      depositAssetAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
    });

    const params = {
      vaultName: vault.name,
      depositAsset: vault.vault.baseTokenAddress,
      depositAmount: "1000", // 1000 USDC
      to: account.address,
      chainId: mainnet.id,
    };

    // Auto-detect optimal authorization method
    const auth = await prepareDepositAuthorization(params);

    if (isPermitAuth(auth)) {
      // Para signs the EIP-712 permit off-chain (gasless)
      const signature = await walletClient.signTypedData({
        account,
        ...auth.permitData,
      });

      const prepared = await prepareDeposit({
        ...params,
        signature,
        deadline: auth.permitData.message.deadline,
      });

      const hash = await walletClient.writeContract({ ...prepared.txData, account });
      await publicClient.waitForTransactionReceipt({ hash });
    } else if (isApprovalAuth(auth)) {
      // Standard ERC-20 approve followed by deposit
      const approvalHash = await walletClient.writeContract({ ...auth.txData, account });
      await publicClient.waitForTransactionReceipt({ hash: approvalHash });

      const prepared = await prepareDeposit(params);
      const depositHash = await walletClient.writeContract({ ...prepared.txData, account });
      await publicClient.waitForTransactionReceipt({ hash: depositHash });
    } else if (isAlreadyApprovedAuth(auth)) {
      // Sufficient allowance — deposit directly
      const prepared = await prepareDeposit(params);
      const hash = await walletClient.writeContract({ ...prepared.txData, account });
      await publicClient.waitForTransactionReceipt({ hash });
    }
    ```

    ### Step 5: Withdraw from a Vault

    ```typescript theme={null}
    import {
      prepareWithdrawalAuthorization,
      prepareWithdrawal,
      isWithdrawApprovalAuth,
    } from "@paxoslabs/amplify-sdk";

    const withdrawParams = {
      vaultName: vault.name,
      wantAsset: vault.vault.baseTokenAddress,
      withdrawAmount: "500", // 500 Shares
      userAddress: account.address,
      chainId: mainnet.id,
    };

    const withdrawAuth = await prepareWithdrawalAuthorization(withdrawParams);

    if (isWithdrawApprovalAuth(withdrawAuth)) {
      const approvalHash = await walletClient.writeContract({ ...withdrawAuth.txData, account });
      await publicClient.waitForTransactionReceipt({ hash: approvalHash });
    }

    const withdrawTxData = await prepareWithdrawal(withdrawParams);
    const withdrawHash = await walletClient.writeContract({ ...withdrawTxData, account });
    await publicClient.waitForTransactionReceipt({ hash: withdrawHash });
    ```
  </Tab>

  <Tab title="Direct Contracts">
    ### Step 1: Install Dependencies

    ```bash theme={null}
    npm install @getpara/viem-v2-integration @getpara/react-sdk viem
    ```

    ### Step 2: Initialize Para

    Complete authentication before signing any transactions.

    ```typescript theme={null}
    import { createParaViemClient, createParaAccount } from "@getpara/viem-v2-integration";
    import { ParaWeb } from "@getpara/react-sdk";
    import { http, createPublicClient } from "viem";
    import { mainnet } from "viem/chains";

    const para = new ParaWeb("YOUR_PARA_API_KEY");
    ```

    ### Step 3: Create Para Account and Clients

    ```typescript theme={null}
    const account = await createParaAccount(para);

    const walletClient = createParaViemClient(para, {
      account,
      chain: mainnet,
      transport: http("https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY"),
    });

    const publicClient = createPublicClient({
      chain: mainnet,
      transport: http("https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY"),
    });
    ```

    ### Step 4: Discover Contract Addresses

    Query the Amplify GraphQL API to get vault and module addresses for your target chain and yield type.

    ```typescript theme={null}
    const response = await fetch("https://api.paxoslabs.com/graphql", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "x-api-key": "YOUR_AMPLIFY_API_KEY",
      },
      body: JSON.stringify({
        query: `query {
          amplifySdkConfigs(chainId: 1, yieldType: CORE) {
            vault {
              boringVaultAddress
              communityCodeDepositorModuleId
              withdrawQueueModuleId
              accountantModuleId
              supportedAssets { address symbol decimals depositable withdrawable }
            }
          }
        }`,
      }),
    });

    const { data } = await response.json();
    const vault = data.amplifySdkConfigs[0].vault;

    const depositorAddress = vault.communityCodeDepositorModuleId;
    const withdrawQueueAddress = vault.withdrawQueueModuleId;
    const accountantAddress = vault.accountantModuleId;
    const boringVaultAddress = vault.boringVaultAddress;
    const usdcAddress = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
    ```

    ### Step 5: Approve and Deposit

    ```typescript theme={null}
    const erc20Abi = [
      {
        inputs: [
          { name: "spender", type: "address" },
          { name: "amount", type: "uint256" },
        ],
        name: "approve",
        outputs: [{ name: "", type: "bool" }],
        stateMutability: "nonpayable",
        type: "function",
      },
    ];

    const depositorAbi = [
      {
        inputs: [
          { name: "depositAsset", type: "address" },
          { name: "depositAmount", type: "uint256" },
          { name: "minimumMint", type: "uint256" },
          { name: "to", type: "address" },
          { name: "distributorCode", type: "bytes" },
          {
            components: [
              { name: "uuid", type: "string" },
              { name: "expiration", type: "uint256" },
              { name: "attester", type: "address" },
              { name: "signature", type: "bytes" },
            ],
            name: "_attestation",
            type: "tuple",
          },
        ],
        name: "deposit",
        outputs: [{ name: "shares", type: "uint256" }],
        stateMutability: "nonpayable",
        type: "function",
      },
    ];

    const depositAmount = 1000000000n; // 1,000 USDC (6 decimals)

    // Approve the depositor to spend your USDC
    const approvalHash = await walletClient.writeContract({
      address: usdcAddress,
      abi: erc20Abi,
      functionName: "approve",
      args: [depositorAddress, depositAmount],
      account,
    });
    await publicClient.waitForTransactionReceipt({ hash: approvalHash });

    // Deposit into the vault
    const depositHash = await walletClient.writeContract({
      address: depositorAddress,
      abi: depositorAbi,
      functionName: "deposit",
      args: [
        usdcAddress,
        depositAmount,
        0n, // minimumMint — see production note below
        account.address,
        "0x", // distributorCode
        {
          uuid: "",
          expiration: 0n,
          attester: "0x0000000000000000000000000000000000000000",
          signature: "0x",
        },
      ],
      account,
    });
    await publicClient.waitForTransactionReceipt({ hash: depositHash });
    ```

    <Warning>
      In production, query `Accountant.getRateInQuoteSafe(usdcAddress)` to calculate a safe `minimumMint` with slippage protection instead of passing `0n`. See the slippage calculation below.
    </Warning>

    **Production slippage calculation:**

    The intermediate arithmetic uses WAD (1e18) precision, then scales to the vault share token's on-chain decimals.

    ```typescript theme={null}
    const WAD = 10n ** 18n;
    const SLIPPAGE_BPS = 50n; // 0.5%

    const accountantAbi = [
      {
        inputs: [{ name: "quote", type: "address" }],
        name: "getRateInQuoteSafe",
        outputs: [{ name: "rateInQuote", type: "uint256" }],
        stateMutability: "view",
        type: "function",
      },
    ] as const;

    const rateInQuote = await publicClient.readContract({
      address: accountantAddress,
      abi: accountantAbi,
      functionName: "getRateInQuoteSafe",
      args: [usdcAddress],
    });

    const vaultTokenDecimals = await publicClient.readContract({
      address: boringVaultAddress,
      abi: [{ inputs: [], name: "decimals", outputs: [{ type: "uint8" }], stateMutability: "view", type: "function" }],
      functionName: "decimals",
    });

    const idealMint = (depositAmount * WAD) / rateInQuote;
    const slippageWad = (SLIPPAGE_BPS * WAD) / 10_000n;
    const slippageAmount = (idealMint * slippageWad) / WAD;

    const minimumMint = vaultTokenDecimals > 18
      ? (idealMint - slippageAmount) * 10n ** (BigInt(vaultTokenDecimals) - 18n)
      : (idealMint - slippageAmount) / 10n ** (18n - BigInt(vaultTokenDecimals));
    ```

    ### Step 6: Submit a Withdrawal Order

    Withdrawal orders are fulfilled by the Amplify account operator, typically within 24 hours.

    ```typescript theme={null}
    const withdrawQueueAbi = [
      {
        inputs: [
          {
            components: [
              { name: "amountOffer", type: "uint256" },
              { name: "wantAsset", type: "address" },
              { name: "intendedDepositor", type: "address" },
              { name: "receiver", type: "address" },
              { name: "refundReceiver", type: "address" },
              {
                components: [
                  { name: "approvalMethod", type: "uint8" },
                  { name: "approvalV", type: "uint8" },
                  { name: "approvalR", type: "bytes32" },
                  { name: "approvalS", type: "bytes32" },
                  { name: "submitWithSignature", type: "bool" },
                  { name: "deadline", type: "uint256" },
                  { name: "eip2612Signature", type: "bytes" },
                ],
                name: "signatureParams",
                type: "tuple",
              },
            ],
            name: "params",
            type: "tuple",
          },
        ],
        name: "submitOrder",
        outputs: [{ name: "orderIndex", type: "uint256" }],
        stateMutability: "nonpayable",
        type: "function",
      },
    ];

    const sharesToWithdraw = 500000000000000000000n; // example share amount

    // Approve vault shares to the WithdrawQueue
    const shareApprovalHash = await walletClient.writeContract({
      address: boringVaultAddress,
      abi: erc20Abi,
      functionName: "approve",
      args: [withdrawQueueAddress, sharesToWithdraw],
      account,
    });
    await publicClient.waitForTransactionReceipt({ hash: shareApprovalHash });

    // Submit the withdrawal order
    const withdrawHash = await walletClient.writeContract({
      address: withdrawQueueAddress,
      abi: withdrawQueueAbi,
      functionName: "submitOrder",
      args: [
        {
          amountOffer: sharesToWithdraw,
          wantAsset: usdcAddress,
          intendedDepositor: account.address,
          receiver: account.address,
          refundReceiver: account.address,
          signatureParams: {
            approvalMethod: 0,
            approvalV: 0,
            approvalR: "0x0000000000000000000000000000000000000000000000000000000000000000",
            approvalS: "0x0000000000000000000000000000000000000000000000000000000000000000",
            submitWithSignature: false,
            deadline: 0n,
            eip2612Signature: "0x",
          },
        },
      ],
      account,
    });
    await publicClient.waitForTransactionReceipt({ hash: withdrawHash });
    ```

    <Tip>
      Use `WithdrawQueue.getOrderStatus(orderIndex)` to poll for withdrawal completion.
    </Tip>
  </Tab>
</Tabs>

## Related Resources

<CardGroup cols={3}>
  <Card title="Paxos Amplify" icon="chart-line" href="https://www.paxoslabs.com">
    Stablecoin yield protocol documentation and API reference
  </Card>

  <Card title="Para Viem Integration" icon="plug" href="/v3/react/guides/web3-operations/evm/setup-libraries">
    Set up Para wallets with Viem for EVM transaction signing
  </Card>

  <Card title="EIP-712 Typed Data Signing" icon="file-signature" href="/v3/walkthroughs/eip712-typed-data-signing">
    Sign structured data using the EIP-712 standard with Para wallets
  </Card>
</CardGroup>
