diff --git a/content/docs/sdk/all-modules.mdx b/content/docs/sdk/all-modules.mdx index 45d896e2..930b35fa 100644 --- a/content/docs/sdk/all-modules.mdx +++ b/content/docs/sdk/all-modules.mdx @@ -83,6 +83,7 @@ On-ramp and off-ramp functionality for fiat currency integration. | Module | Provider | Description | Documentation | |--------|----------|-------------|---------------| | [`@tetherto/wdk-protocol-fiat-moonpay`](https://github.com/tetherto/wdk-protocol-fiat-moonpay) | MoonPay | MoonPay integration for fiat on-ramp | [Docs](/sdk/fiat-modules/fiat-moonpay/) | +| [`@tetherto/wdk-protocol-fiat-transak`](https://github.com/tetherto/wdk-protocol-fiat-transak) | Transak | Transak integration for fiat on-ramp and off-ramp | [Docs](/sdk/fiat-modules/fiat-transak/) | ## Community Modules diff --git a/content/docs/sdk/fiat-modules/fiat-transak/api-reference.mdx b/content/docs/sdk/fiat-modules/fiat-transak/api-reference.mdx new file mode 100644 index 00000000..93f14ecd --- /dev/null +++ b/content/docs/sdk/fiat-modules/fiat-transak/api-reference.mdx @@ -0,0 +1,377 @@ +--- +title: Fiat Transak API Reference +description: API Reference for the @tetherto/wdk-protocol-fiat-transak module +docType: reference +schemaType: APIReference +icon: Code +--- + +# API Reference + +Complete API documentation for the `@tetherto/wdk-protocol-fiat-transak` module. + +## Constructor + +### `new TransakProtocol(account, config)` + +Creates a new TransakProtocol instance. + +**Parameters:** + +| Name | Type | Description | +|------|------|-------------| +| `account` | `IWalletAccount` \| `IWalletAccountReadOnly` \| `undefined` | Wallet account for transactions | +| `config` | `TransakProtocolConfig` | Configuration object | + +**Config Options:** + +| Name | Type | Required | Default | Description | +|------|------|----------|---------|-------------| +| `apiKey` | string | Yes | - | Your Transak partner API key | +| `widgetUrl` | function | For `buy`/`sell` | - | Callback `(widgetParams) => Promise` that returns a session-based widget URL. `buy`/`sell` throw without it. | +| `getOrder` | function | For `getTransactionDetail` | - | Callback `(txId) => Promise` that fetches a Transak order. `getTransactionDetail` throws without it. | +| `cacheTime` | number | No | `600000` | Cache duration for supported currencies (ms) | +| `environment` | `'PRODUCTION' \| 'STAGING'` | No | `PRODUCTION` | Selects the Transak API host | + +**Example:** + +```typescript +import TransakProtocol from '@tetherto/wdk-protocol-fiat-transak'; + +const transak = new TransakProtocol(walletAccount, { + apiKey: 'YOUR_TRANSAK_PARTNER_KEY', + widgetUrl: async (widgetParams) => { /* call your backend */ }, + getOrder: async (txId) => { /* call your backend */ }, + environment: 'PRODUCTION', +}); +``` + +--- + +## Methods + +### `buy(options)` + +Generates a Transak widget URL for purchasing cryptocurrency via the configured `widgetUrl` callback. + +**Parameters:** + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `options.cryptoAsset` | string | Yes | Crypto asset code, upper-case (e.g. `'ETH'`) | +| `options.fiatCurrency` | string | Yes | Fiat currency code, upper-case (e.g. `'EUR'`) | +| `options.cryptoAmount` | number \| bigint | No* | Amount in crypto base units (e.g. wei) | +| `options.fiatAmount` | number \| bigint | No* | Amount in fiat base units (e.g. cents) | +| `options.recipient` | string | No | Destination wallet address (falls back to the account address) | +| `options.config` | `TransakBuyParams` | No | Widget parameters, including `network` and the required `referrerDomain` | + +*Either `cryptoAmount` or `fiatAmount` must be provided, but not both. + +**Returns:** `Promise<{ buyUrl: string }>` + +--- + +### `sell(options)` + +Generates a Transak widget URL for selling cryptocurrency via the configured `widgetUrl` callback. + +**Parameters:** + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `options.cryptoAsset` | string | Yes | Crypto asset code, upper-case | +| `options.fiatCurrency` | string | Yes | Fiat currency code, upper-case | +| `options.cryptoAmount` | number \| bigint | No* | Amount in crypto base units | +| `options.fiatAmount` | number \| bigint | No* | Amount in fiat base units | +| `options.config` | `TransakSellParams` | No | Widget parameters, including `network` and the required `referrerDomain` | + +*Either `cryptoAmount` or `fiatAmount` must be provided, but not both. + +**Returns:** `Promise<{ sellUrl: string }>` + +--- + +### `quoteBuy(options)` + +Gets a price quote for a cryptocurrency purchase. + +**Parameters:** + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `options.cryptoAsset` | string | Yes | Crypto asset code, upper-case | +| `options.fiatCurrency` | string | Yes | Fiat currency code, upper-case | +| `options.cryptoAmount` | number \| bigint | No* | Amount in crypto base units | +| `options.fiatAmount` | number \| bigint | No* | Amount in fiat base units | +| `options.config` | `TransakQuoteBuyParams` | No | `paymentMethod` and `network` (resolved from the supported list when omitted) | + +*Either `cryptoAmount` or `fiatAmount` must be provided, but not both. + +**Returns:** `Promise` + +```typescript +{ + cryptoAmount: bigint, // Crypto amount you'll receive, in base units + fiatAmount: bigint, // Fiat amount to pay, in base units + fee: bigint, // Total fee, in fiat base units + rate: string, // Exchange rate, as a decimal string + metadata: TransakQuote // The full raw Transak quote +} +``` + +--- + +### `quoteSell(options)` + +Gets a price quote for selling cryptocurrency. + +**Parameters:** + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `options.cryptoAsset` | string | Yes | Crypto asset code, upper-case | +| `options.fiatCurrency` | string | Yes | Fiat currency code, upper-case | +| `options.cryptoAmount` | number \| bigint | Yes | Amount in crypto base units | +| `options.config` | `TransakQuoteSellParams` | No | `paymentMethod` and `network` (resolved from the supported list when omitted) | + +**Returns:** `Promise` + +```typescript +{ + cryptoAmount: bigint, // Crypto amount to sell, in base units + fiatAmount: bigint, // Fiat amount you'll receive, in base units + fee: bigint, // Total fee, in fiat base units + rate: string, // Exchange rate, as a decimal string + metadata: TransakQuote // The full raw Transak quote +} +``` + +--- + +### `getSupportedCryptoAssets()` + +Fetches the list of supported cryptocurrencies. Results are cached per `cacheTime`. + +**Returns:** `Promise` + +```typescript +{ + code: string, // Crypto asset code (e.g. 'ETH') + decimals: number, // On-chain base-unit decimal places + networkCode: string, // Network identifier (e.g. 'ethereum') + name: string, // Display name + metadata: TransakCryptoCurrencyDetails +} +``` + +--- + +### `getSupportedFiatCurrencies()` + +Fetches the list of supported fiat currencies. Results are cached per `cacheTime`. + +**Returns:** `Promise` + +```typescript +{ + code: string, // Fiat currency code (e.g. 'EUR') + decimals: number, // ISO 4217 decimal places for the smallest unit + name: string, // Display name + metadata: TransakFiatCurrencyDetails +} +``` + +--- + +### `getSupportedCountries()` + +Fetches the list of supported countries. + +**Returns:** `Promise` + +```typescript +{ + code: string, // ISO 3166-1 alpha-2 (or alpha-3 fallback) country code + isBuyAllowed: boolean, // Buy operations allowed + isSellAllowed: boolean, // Sell operations allowed + name: string, // Country name + metadata: TransakCountryDetail +} +``` + +--- + +### `getTransactionDetail(txId)` + +Retrieves the details of a specific order via the configured `getOrder` callback. + +**Parameters:** + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `txId` | string | Yes | The Transak order id | + +**Returns:** `Promise` + +```typescript +{ + status: 'completed' | 'failed' | 'in_progress', + cryptoAsset: string, + fiatCurrency: string, + metadata: TransakOrder // The full raw Transak order +} +``` + +--- + +## Types + +### `TransakProtocolConfig` + +```typescript +interface TransakProtocolConfig { + apiKey: string; + widgetUrl?: (widgetParams: TransakWidgetParams) => Promise; + getOrder?: (txId: string) => Promise; + cacheTime?: number; + environment?: 'PRODUCTION' | 'STAGING'; +} +``` + +### `TransakWidgetParams` + +The parameters your `widgetUrl` callback receives. Send this object as `widgetParams` to Transak's Create Widget URL API. + +```typescript +interface TransakWidgetParams { + apiKey: string; + productsAvailed: 'BUY' | 'SELL'; + cryptoCurrencyCode: string; + network: string; + fiatCurrency: string; + fiatAmount?: number; + cryptoAmount?: number; + walletAddress?: string; +} +``` + +### `TransakBuyParams` + +Widget configuration options for `buy()` operations. Refer [here](https://docs.transak.com/customization/query-parameters) for all supported Transak's query parameters. + +```typescript +interface TransakBuyParams { + // Shared UI options + themeColor?: string; + colorMode?: 'DARK' | 'LIGHT'; + redirectURL?: string; + referrerDomain?: string; // required by buy()/sell() + hideMenu?: string; + + // Buy-specific options + defaultCryptoCurrency?: string; + walletAddress?: string; + walletAddressesData?: string; + disableWalletAddressForm?: boolean; + hideExchangeScreen?: boolean; + isFeeCalculationHidden?: boolean; + defaultPaymentMethod?: string; + paymentMethod?: string; + email?: string; + partnerOrderId?: string; + partnerCustomerId?: string; + network?: string; +} +``` + +### `TransakSellParams` + +Widget configuration options for `sell()` operations. Refer [here](https://docs.transak.com/customization/query-parameters) for all supported Transak's query parameters. + +```typescript +interface TransakSellParams { + // Shared UI options + themeColor?: string; + colorMode?: 'DARK' | 'LIGHT'; + redirectURL?: string; + referrerDomain?: string; // required by buy()/sell() + hideMenu?: string; + + // Sell-specific options + defaultCryptoCurrency?: string; + walletAddress?: string; + walletAddressesData?: string; + disableWalletAddressForm?: boolean; + hideExchangeScreen?: boolean; + isFeeCalculationHidden?: boolean; + defaultPaymentMethod?: string; + paymentMethod?: string; + email?: string; + partnerOrderId?: string; + partnerCustomerId?: string; + network?: string; +} +``` + +### `TransakQuoteBuyParams` + +```typescript +interface TransakQuoteBuyParams { + paymentMethod?: string; + network?: string; // resolved from the supported assets list when omitted +} +``` + +### `TransakQuoteSellParams` + +```typescript +interface TransakQuoteSellParams { + paymentMethod?: string; + network?: string; // resolved from the supported assets list when omitted +} +``` + +### `TransakOrder` + +The raw order object returned by your `getOrder` callback, and exposed as `metadata` on `TransakTransactionDetail`: + +```typescript +interface TransakOrder { + id: string; + status: TransakOrderStatus; + cryptoCurrency: string; + fiatCurrency: string; + fiatAmount: number; + cryptoAmount?: number; + isBuyOrSell: 'BUY' | 'SELL'; + network: string; + walletAddress?: string; + transactionHash?: string; + amountPaid?: number; + createdAt?: string; // ISO 8601 + completedAt?: string; // ISO 8601 +} +``` + +### `TransakOrderStatus` + +```typescript +type TransakOrderStatus = + | 'AWAITING_PAYMENT_FROM_USER' + | 'PAYMENT_DONE_MARKED_BY_USER' + | 'PROCESSING' + | 'PENDING_DELIVERY_FROM_TRANSAK' + | 'ON_HOLD_PENDING_DELIVERY_FROM_TRANSAK' + | 'COMPLETED' + | 'CANCELLED' + | 'FAILED' + | 'REFUNDED' + | 'EXPIRED'; +``` + +`getTransactionDetail` normalises these into `'completed'`, `'failed'`, or `'in_progress'` + +## Next Steps + +- [Configuration](/sdk/fiat-modules/fiat-transak/configuration) - Setup and configuration options +- [Usage Guide](/sdk/fiat-modules/fiat-transak/usage) - Common usage patterns diff --git a/content/docs/sdk/fiat-modules/fiat-transak/configuration.mdx b/content/docs/sdk/fiat-modules/fiat-transak/configuration.mdx new file mode 100644 index 00000000..5ec564d0 --- /dev/null +++ b/content/docs/sdk/fiat-modules/fiat-transak/configuration.mdx @@ -0,0 +1,250 @@ +--- +title: Fiat Transak Configuration +description: Configuration options for the @tetherto/wdk-protocol-fiat-transak module +docType: reference +schemaType: TechArticle +icon: Settings +--- + +# Configuration + +This page covers all configuration options for the Transak fiat module, including the required backend callbacks and environment selection. + +## Prerequisites + +Before using this module, you need: + +1. A Transak partner account - [Create an account on the Transak Partner Dashboard](https://dashboard.transak.com/) +2. A partner API key and API secret from your dashboard +3. A backend endpoint that implements the `widgetUrl` callback (required for `buy`/`sell`) +4. A backend endpoint that implements the `getOrder` callback (required for `getTransactionDetail`) + + +Never ship your Transak API secret to the client. `widgetUrl` and `getOrder` must run on your backend, where the secret is safe. + + +## Installation + +```bash +npm install @tetherto/wdk-protocol-fiat-transak +``` + +## Basic Configuration + +```typescript +import TransakProtocol from '@tetherto/wdk-protocol-fiat-transak'; + +const widgetUrl = async (widgetParams) => { + const response = await fetch('https://your-backend.example.com/transak/widget-url', { + method: 'POST', + headers: { + 'x-api-key': transakApiKey, + 'x-user-ip': userIp + }, + body: JSON.stringify({ widgetParams }), + }); + + if (!response.ok) { + throw new Error(`Failed to create Transak widget URL: ${response.status}`); + } + + const { widgetUrl } = await response.json(); + return widgetUrl; +}; + +const getOrder = async (txId) => { + const response = await fetch(`https://your-backend.example.com/transak/order/${txId}`, { + headers: { + 'x-api-key': transakApiKey + } + }); + + if (!response.ok) { + throw new Error(`Failed to fetch Transak order: ${response.status}`); + } + + const { order } = await response.json(); + return order; +}; + +const transak = new TransakProtocol(walletAccount, { + apiKey: 'YOUR_TRANSAK_PARTNER_KEY', // Your Transak partner API key + widgetUrl, // Required for buy()/sell() + getOrder, // Required for getTransactionDetail() + environment: 'STAGING', // 'PRODUCTION' (default) | 'STAGING' +}); +``` + +## Configuration Options + +| Option | Type | Required | Default | Description | +|--------|------|----------|---------|-------------| +| `apiKey` | string | Yes | - | Your Transak partner API key | +| `widgetUrl` | function | For `buy`/`sell` | - | Callback that receives the assembled `widgetParams` object and returns a widget URL. `buy`/`sell` throw without it. | +| `getOrder` | function | For `getTransactionDetail` | - | Callback `(txId) => Promise` that fetches a Transak order on your backend. `getTransactionDetail` throws without it. | +| `cacheTime` | number | No | `600000` (10 min) | Duration in milliseconds to cache supported currencies | +| `environment` | `'PRODUCTION' \| 'STAGING'` | No | `PRODUCTION` | Selects the Transak API host. Use `STAGING` for testing with non-real funds. | + +## Constructor Overloads + +The `TransakProtocol` class supports three constructor patterns: + +```typescript +// Without account (for public read operations like fetching supported currencies) +const transak = new TransakProtocol(undefined, config); + +// With read-only account +const transak = new TransakProtocol(readOnlyAccount, config); + +// With full wallet account (for buy/sell operations) +const transak = new TransakProtocol(walletAccount, config); +``` + +## Implementing the backend callbacks + +Transak's authenticated APIs require a partner `access-token` minted from your API secret, plus a mandatory `x-user-ip` header. Neither can be exposed client-side, so `widgetUrl` and `getOrder` delegate that authenticated work to your backend. + +### `widgetUrl` (backend) + +Turns the assembled `widgetParams` into a session-based widget URL, using [Transak's APIs](https://docs.transak.com/guides/migration-to-api-based-transak-widget-url): + +```typescript +// Runs on your backend. Never ship the API secret to the client. +// `userIp` is the end user's IP from the incoming request (e.g. req.ip, or your +// CDN's cf-connecting-ip). Transak requires it as the `x-user-ip` header. +async function createWidgetUrl(widgetParams, userIp) { + // 1. Get a partner access token (cache it until it expires). + const tokenRes = await fetch('https://api.transak.com/partners/api/v2/refresh-token', { + method: 'POST', + headers: { 'api-secret': partnerApiSecret, 'content-type': 'application/json', 'x-user-ip': userIp }, + body: JSON.stringify({ apiKey: partnerApiKey }), + }); + const { data: { accessToken } } = await tokenRes.json(); + + // 2. Create the widget session and return its URL. + const sessionRes = await fetch('https://api-gateway.transak.com/api/v2/auth/session', { + method: 'POST', + headers: { 'x-api-key': partnerApiKey, 'access-token': accessToken, 'content-type': 'application/json', 'x-user-ip': userIp }, + body: JSON.stringify({ widgetParams }), + }); + const { data: { widgetUrl } } = await sessionRes.json(); + return widgetUrl; // valid for 5 minutes, single use +} +``` + +For staging, use `https://api-stg.transak.com` and `https://api-gateway-stg.transak.com`. + +### `getOrder` (backend) + +Fetches an order via Transak's [Get Order API](https://docs.transak.com/api/public/get-order-by-order-id), reusing the same access token: + +```typescript +async function getOrder(txId, userIp) { + const token = await accessToken(); // reuse the same one as the widget URL flow + const res = await fetch(`https://api.transak.com/partners/api/v2/order/${txId}`, { + headers: { 'x-api-key': partnerApiKey, 'access-token': token, 'x-user-ip': userIp }, + }); + const { data } = await res.json(); // Get Order responses are wrapped in { data } + return data; +} +``` + +Expose each of these behind an endpoint your frontend `widgetUrl`/`getOrder` callbacks call, following the same pattern shown in [Basic Configuration](#basic-configuration). + +## Environment Configuration + +### STAGING (Testing) + +Use `STAGING` for development and testing against non-real funds: + +```typescript +const transak = new TransakProtocol(walletAccount, { + apiKey: partnerApiKey, + widgetUrl, + getOrder, + environment: 'STAGING', +}); +``` + +In staging mode, requests are routed to `api-stg.transak.com` / `api-gateway-stg.transak.com` instead of the production hosts. + +### PRODUCTION + +`PRODUCTION` is the default. Omit `environment`, or set it explicitly, for live transactions: + +```typescript +const transak = new TransakProtocol(walletAccount, { + apiKey: partnerApiKey, + widgetUrl, + getOrder, + environment: 'PRODUCTION', +}); +``` + +## Widget Customization + +When calling `buy()` or `sell()`, pass provider-specific extras, including the widget's UI options, under `config`. Refer [here](https://docs.transak.com/customization/query-parameters) for all supported Transak's query parameters + +```typescript +const result = await transak.buy({ + cryptoAsset: 'ETH', + fiatCurrency: 'EUR', + fiatAmount: 10_000n, // €100.00 in cents + config: { + network: 'ethereum', + paymentMethod: 'credit_debit_card', + referrerDomain: 'yourdomain.com', // required, see below + colorMode: 'DARK', + themeColor: '3B82F6', + }, +}); +``` + +### Available Widget UI Options (shared) + +| Option | Type | Description | +|--------|------|-------------| +| `themeColor` | string | Primary color of the widget, as a hex code without the leading `#` | +| `colorMode` | `'DARK' \| 'LIGHT'` | Default appearance for the widget | +| `redirectURL` | string | URL to redirect to after the flow completes (must use `https://`) | +| `referrerDomain` | string | Your domain URL (web) or app package name (mobile), required for `buy`/`sell` | +| `hideMenu` | string | If `'true'`, hides the widget navigation menu | + +### Available Buy Widget Options + +| Option | Type | Description | +|--------|------|-------------| +| `defaultCryptoCurrency` | string | Crypto currency you'd prefer the customer to purchase | +| `walletAddress` | string | Destination wallet address. If valid, the customer isn't prompted for one | +| `walletAddressesData` | string | JSON string of wallet addresses for multiple networks/coins | +| `disableWalletAddressForm` | boolean | If `true`, the customer can't edit the destination address | +| `hideExchangeScreen` | boolean | If `true`, skips straight to the payment screen | +| `isFeeCalculationHidden` | boolean | If `true`, hides the fee breakdown | +| `defaultPaymentMethod` | string | Pre-selected payment method | +| `paymentMethod` | string | Restricts the customer to a single payment method | +| `email` | string | Pre-filled customer email | +| `partnerOrderId` | string | Your identifier for the order, returned in webhooks and order data | +| `partnerCustomerId` | string | Your identifier for the customer, returned in webhooks and order data | +| `network` | string | Restricts the customer to a single network for the selected crypto currency | + +### Available Sell Widget Options + +| Option | Type | Description | +|--------|------|-------------| +| `defaultCryptoCurrency` | string | Crypto currency you'd prefer the customer to sell | +| `walletAddress` | string | Wallet address the customer sends crypto from | +| `walletAddressesData` | string | JSON string of wallet addresses for multiple networks/coins | +| `disableWalletAddressForm` | boolean | If `true`, the customer can't edit the source address | +| `hideExchangeScreen` | boolean | If `true`, skips straight to the payout screen | +| `isFeeCalculationHidden` | boolean | If `true`, hides the fee breakdown | +| `defaultPaymentMethod` | string | Pre-selected payout method | +| `paymentMethod` | string | Restricts the customer to a single payout method | +| `email` | string | Pre-filled customer email | +| `partnerOrderId` | string | Your identifier for the order, returned in webhooks and order data | +| `partnerCustomerId` | string | Your identifier for the customer, returned in webhooks and order data | +| `network` | string | Restricts the customer to a single network for the selected crypto currency | + +## Next Steps + +- [Usage Guide](/sdk/fiat-modules/fiat-transak/usage) - Learn how to integrate Transak +- [API Reference](/sdk/fiat-modules/fiat-transak/api-reference) - Complete API documentation diff --git a/content/docs/sdk/fiat-modules/fiat-transak/guides/buy-and-sell.mdx b/content/docs/sdk/fiat-modules/fiat-transak/guides/buy-and-sell.mdx new file mode 100644 index 00000000..c184789d --- /dev/null +++ b/content/docs/sdk/fiat-modules/fiat-transak/guides/buy-and-sell.mdx @@ -0,0 +1,172 @@ +--- +title: Buy and Sell +description: On-ramp, off-ramp, quotes, supported assets, widget options, and custom recipients. +--- + +This guide explains [buying crypto (on-ramp)](#buy-crypto-on-ramp), [selling crypto (off-ramp)](#sell-crypto-off-ramp), [quotes](#get-price-quotes), [supported currencies](#supported-currencies-and-countries), [widget customization](#widget-customization), [multi-network assets](#multi-network-assets), and [custom recipients](#custom-recipient-addresses). It assumes a [`TransakProtocol`](/sdk/fiat-modules/fiat-transak/api-reference) instance named `transak`. + + +Amounts use base units: fiat in minor units (cents), crypto in on-chain base units (for example wei for ETH). `cryptoAsset`/`fiatCurrency` are upper-case (`ETH`, `EUR`), while `network`/`paymentMethod` are lower-case (`ethereum`, `credit_debit_card`). Codes are matched exactly, with no normalisation, so fetch the exact values with [supported currencies](#supported-currencies-and-countries). + + +## Buy crypto (on-ramp) + +You can build a buy widget URL with [`buy()`](/sdk/fiat-modules/fiat-transak/api-reference) when you know the fiat spend: + +```typescript title="Buy with fiat amount" +const result = await transak.buy({ + cryptoAsset: 'ETH', + fiatCurrency: 'EUR', + fiatAmount: 10_000n, // €100.00 in cents + config: { referrerDomain: 'yourdomain.com' } +}) + +window.open(result.buyUrl, '_blank') +``` + +You can request a fixed crypto amount instead by passing `cryptoAmount` to [`buy()`](/sdk/fiat-modules/fiat-transak/api-reference): + +```typescript title="Buy with crypto amount" +const result = await transak.buy({ + cryptoAsset: 'ETH', + fiatCurrency: 'EUR', + cryptoAmount: 500000000000000000n, // 0.5 ETH in wei + config: { referrerDomain: 'yourdomain.com' } +}) + +window.open(result.buyUrl, '_blank') +``` + + +**`referrerDomain` is required for `buy`/`sell`.** Transak's Create Widget URL API rejects requests without `config.referrerDomain` (your web domain or app package name). It may need allow-listing in the Partner dashboard first. `quoteBuy`/`quoteSell` don't need it. + + +## Sell crypto (off-ramp) + +You can generate a sell widget URL with [`sell()`](/sdk/fiat-modules/fiat-transak/api-reference): + +```typescript title="Sell ETH for EUR" +const result = await transak.sell({ + cryptoAsset: 'ETH', + fiatCurrency: 'EUR', + cryptoAmount: 500000000000000000n, // 0.5 ETH in wei + config: { referrerDomain: 'yourdomain.com' } +}) + +window.open(result.sellUrl, '_blank') +``` + +## Get price quotes + +You can preview economics before opening the widget using [`quoteBuy()`](/sdk/fiat-modules/fiat-transak/api-reference): + +```typescript title="Buy quote" +const buyQuote = await transak.quoteBuy({ + cryptoAsset: 'ETH', + fiatCurrency: 'EUR', + fiatAmount: 10_000n // €100.00 in cents +}) + +console.log('Crypto amount:', buyQuote.cryptoAmount) +console.log('Fee:', buyQuote.fee) +console.log('Exchange rate:', buyQuote.rate) +``` + +You can estimate proceeds for a sell with [`quoteSell()`](/sdk/fiat-modules/fiat-transak/api-reference). Note that `cryptoAmount` is required, since unlike `quoteBuy`, `quoteSell` doesn't accept a `fiatAmount`: + +```typescript title="Sell quote" +const sellQuote = await transak.quoteSell({ + cryptoAsset: 'ETH', + fiatCurrency: 'EUR', + cryptoAmount: 500000000000000000n // 0.5 ETH in wei +}) + +console.log('Fiat amount:', sellQuote.fiatAmount) +``` + +## Supported currencies and countries + +You can list tradable assets with [`getSupportedCryptoAssets()`](/sdk/fiat-modules/fiat-transak/api-reference) + +```typescript title="Supported crypto" +const cryptoAssets = await transak.getSupportedCryptoAssets() +console.log(cryptoAssets) +``` + +You can list fiat currencies with [`getSupportedFiatCurrencies()`](/sdk/fiat-modules/fiat-transak/api-reference) + +```typescript title="Supported fiat" +const fiatCurrencies = await transak.getSupportedFiatCurrencies() +console.log(fiatCurrencies) +``` + +You can check regional availability with [`getSupportedCountries()`](/sdk/fiat-modules/fiat-transak/api-reference): + +```typescript title="Supported countries" +const countries = await transak.getSupportedCountries() +console.log(countries) +``` + +## Widget customization + +You can pass UI options under `config` to [`buy()`](/sdk/fiat-modules/fiat-transak/api-reference) (see [`TransakBuyParams`](/sdk/fiat-modules/fiat-transak/api-reference)): + +```typescript title="Themed buy widget" +const result = await transak.buy({ + cryptoAsset: 'USDT', + fiatCurrency: 'EUR', + fiatAmount: 5_000n, + config: { + network: 'ethereum', + paymentMethod: 'credit_debit_card', + referrerDomain: 'yourdomain.com', + colorMode: 'DARK', + redirectURL: 'https://yourapp.com/payment-complete', + email: 'user@example.com', + partnerCustomerId: 'user_123' + } +}) + +window.open(result.buyUrl, '_blank') +``` + +## Multi-network assets + +A symbol like `USDT` can exist on several networks (Ethereum, Tron, and more). Pass `config.network` to disambiguate. Otherwise, the module resolves the first match: + +```typescript title="Sell USDT on Tron specifically" +const result = await transak.sell({ + cryptoAsset: 'USDT', + fiatCurrency: 'EUR', + cryptoAmount: 100_000_000n, // 100 USDT, 6 decimals + config: { network: 'tron', referrerDomain: 'yourdomain.com' } +}) + +window.open(result.sellUrl, '_blank') +``` + +If the requested `cryptoAsset`/`fiatCurrency`/`network` combination can't be found in the supported lists, `buy`, `sell`, `quoteBuy`, and `quoteSell` all throw `Cannot find info for cryptoAsset and fiatCurrency`. + +## Custom recipient addresses + +By default [`buy()`](/sdk/fiat-modules/fiat-transak/api-reference) credits the connected wallet. You can override the destination with `recipient`: + +```typescript title="Custom buy recipient" +const result = await transak.buy({ + cryptoAsset: 'ETH', + fiatCurrency: 'EUR', + fiatAmount: 10_000n, + recipient: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', + config: { referrerDomain: 'yourdomain.com' } +}) + +window.open(result.buyUrl, '_blank') +``` + +If `recipient` isn't provided, the wallet address falls back to the bound account's address. If there's no bound account either, the Transak widget prompts the user for one. + +## Next Steps + +- [Manage transactions](/sdk/fiat-modules/fiat-transak/guides/manage-transactions/) +- [Get started](/sdk/fiat-modules/fiat-transak/guides/get-started/) +- [API reference](/sdk/fiat-modules/fiat-transak/api-reference) diff --git a/content/docs/sdk/fiat-modules/fiat-transak/guides/get-started.mdx b/content/docs/sdk/fiat-modules/fiat-transak/guides/get-started.mdx new file mode 100644 index 00000000..99ecb009 --- /dev/null +++ b/content/docs/sdk/fiat-modules/fiat-transak/guides/get-started.mdx @@ -0,0 +1,69 @@ +--- +title: Get Started +description: Install the package and initialize TransakProtocol with your wallet, API key, and backend callbacks. +--- + +This guide covers [installation](#installation) and [initializing the protocol](#initialize-transakprotocol). You need [Node.js](https://nodejs.org/), [npm](https://www.npmjs.com/), and Transak partner credentials from your [Transak Partner Dashboard](https://dashboard.transak.com/). + +## Installation + +Run the following to install [@tetherto/wdk-protocol-fiat-transak](https://www.npmjs.com/package/@tetherto/wdk-protocol-fiat-transak): + +```bash title="Install with npm" +npm install @tetherto/wdk-protocol-fiat-transak +``` + +## Initialize TransakProtocol + +You can create a fiat ramp client with [`new TransakProtocol(account, config)`](/sdk/fiat-modules/fiat-transak/api-reference): + +```typescript title="Construct TransakProtocol" +import TransakProtocol from '@tetherto/wdk-protocol-fiat-transak' + +const transak = new TransakProtocol(walletAccount, { + apiKey: partnerApiKey, + widgetUrl, // required for buy()/sell(), see below + getOrder, // required for getTransactionDetail(), see below + environment: 'STAGING' // 'PRODUCTION' (default) | 'STAGING' +}) +``` + +`widgetUrl` and `getOrder` are callbacks that run on **your backend**, where your Transak API secret is safe: + +```typescript title="Backend callbacks (frontend side)" +const widgetUrl = async (widgetParams) => { + const res = await fetch('https://your-backend.example.com/transak/widget-url', { + method: 'POST', + headers: { + 'x-api-key': transakApiKey, + 'x-user-ip': userIp + }, + body: JSON.stringify({ widgetParams }) + }) + if (!res.ok) throw new Error(`Failed to create Transak widget URL: ${res.status}`) + const { widgetUrl } = await res.json() + return widgetUrl +} + +const getOrder = async (txId) => { + const res = await fetch(`https://your-backend.example.com/transak/order/${txId}`, { + headers: { + 'x-api-key': transakApiKey + } + }) + if (!res.ok) throw new Error(`Failed to fetch Transak order: ${res.status}`) + const { order } = await res.json() + return order +} +``` + + +Never ship your Transak API secret to browsers. `widgetUrl` and `getOrder` must call your backend, which mints a partner access-token from the secret. See [Configuration](/sdk/fiat-modules/fiat-transak/configuration#implementing-the-backend-callbacks) for the full backend implementation. + + +See [Configuration](/sdk/fiat-modules/fiat-transak/configuration) for `cacheTime` and other options. + +## Next Steps + +- [Buy and sell](/sdk/fiat-modules/fiat-transak/guides/buy-and-sell/) +- [Manage transactions](/sdk/fiat-modules/fiat-transak/guides/manage-transactions/) diff --git a/content/docs/sdk/fiat-modules/fiat-transak/guides/manage-transactions.mdx b/content/docs/sdk/fiat-modules/fiat-transak/guides/manage-transactions.mdx new file mode 100644 index 00000000..aa618aef --- /dev/null +++ b/content/docs/sdk/fiat-modules/fiat-transak/guides/manage-transactions.mdx @@ -0,0 +1,48 @@ +--- +title: Manage Transactions +description: Fetch Transak order status and inspect returned details. +--- + +This guide shows how to [check transaction status](#check-transaction-status) and [read transaction details](#read-transaction-details) with [`getTransactionDetail()`](/sdk/fiat-modules/fiat-transak/api-reference). Pass the order id Transak returns after checkout (for example from your redirect URL or webhook payload). The same order id works for both buy and sell orders, since there's no separate direction argument. + + +`getTransactionDetail` delegates the authenticated lookup to your `getOrder` callback. It throws `A 'getOrder' callback is required to fetch a Transak order` if one wasn't configured. See [Configuration](/sdk/fiat-modules/fiat-transak/configuration#getorder-backend) for the backend implementation. + + +## Check transaction status + +You can read the high-level state of an order with [`getTransactionDetail()`](/sdk/fiat-modules/fiat-transak/api-reference): + +```typescript title="Transaction status" +const tx = await transak.getTransactionDetail(transakOrderId) + +console.log('Status:', tx.status) +``` + +`status` is one of `completed`, `failed`, or `in_progress`, normalised from Transak's raw order status: + +| WDK status | Transak status | +|------------|-----------------| +| `completed` | `COMPLETED` | +| `failed` | `CANCELLED`, `FAILED`, `REFUNDED`, `EXPIRED` | +| `in_progress` | `AWAITING_PAYMENT_FROM_USER`, `PAYMENT_DONE_MARKED_BY_USER`, `PROCESSING`, `PENDING_DELIVERY_FROM_TRANSAK`, `ON_HOLD_PENDING_DELIVERY_FROM_TRANSAK`, and any unrecognised status | + +## Read transaction details + +You can load the same record to inspect assets and currencies using [`getTransactionDetail()`](/sdk/fiat-modules/fiat-transak/api-reference): + +```typescript title="Transaction fields" +const tx = await transak.getTransactionDetail(transakOrderId) + +console.log('Crypto asset:', tx.cryptoAsset) // e.g. 'ETH' +console.log('Fiat currency:', tx.fiatCurrency) // e.g. 'EUR' +console.log('Metadata:', tx.metadata) // the full raw Transak order +``` + +The raw order under `metadata` includes fields like `id`, `isBuyOrSell`, `walletAddress`, `transactionHash`, `amountPaid`, `createdAt`, and `completedAt`. See [`TransakOrder`](/sdk/fiat-modules/fiat-transak/api-reference#transakorder) in the API reference. + +## Next Steps + +- [Buy and sell](/sdk/fiat-modules/fiat-transak/guides/buy-and-sell/) +- [Get started](/sdk/fiat-modules/fiat-transak/guides/get-started/) +- [Configuration](/sdk/fiat-modules/fiat-transak/configuration) diff --git a/content/docs/sdk/fiat-modules/fiat-transak/index.mdx b/content/docs/sdk/fiat-modules/fiat-transak/index.mdx new file mode 100644 index 00000000..b4ee419b --- /dev/null +++ b/content/docs/sdk/fiat-modules/fiat-transak/index.mdx @@ -0,0 +1,67 @@ +--- +title: On-ramp and off-ramp with Transak +description: Build Transak widget URLs and quotes for buying and selling crypto with fiat inside a WDK app. +docType: explanation +schemaType: TechArticle +--- + +Use the Transak fiat module to build widget URLs and quotes that let users buy and sell cryptocurrency with fiat inside your application. The `widgetUrl` and `getOrder` callbacks run on your backend, where your Transak API secret stays safe. The module never touches it directly. + +Get started by reading the [Usage](/sdk/fiat-modules/fiat-transak/usage) guide. + + +This module requires a Transak partner account. [Create your account here](https://dashboard.transak.com/). + + + +This package is in beta. Please test in a dev setup first. + + +## Features + +- **Fiat On-Ramp**: Build widget URLs for users to buy cryptocurrency with fiat +- **Fiat Off-Ramp**: Build widget URLs for users to sell cryptocurrency for fiat +- **Price Quotes**: Get real-time quotes for buy and sell operations, no widget required +- **Transaction Tracking**: Retrieve order status and details by order id +- **Currency Support**: Query supported cryptocurrencies, fiat currencies, and countries +- **Customizable Widget**: Configure colors, themes, and payment methods + +## Supported Payment Methods + +- Credit and debit cards +- Bank transfers (ACH, SEPA, and more) +- Apple Pay and Google Pay +- Local payment methods (varies by region) + + +## Supported Cryptocurrencies + +This module supports purchasing and selling cryptocurrencies on networks compatible with WDK wallet modules. A crypto symbol (e.g. `USDT`) may exist on several networks, so use [`getSupportedCryptoAssets()`](/sdk/fiat-modules/fiat-transak/api-reference) to see the supported networks. + +## Next Steps + + + +Set up your Transak API key, backend callbacks, and environment + + +Learn how to integrate Transak in your application + + +Complete API documentation for the module + + + +--- + +### Transak Resources + +- [Transak Partner Dashboard](https://dashboard.transak.com/) - Create your developer account and manage API keys +- [Transak Documentation](https://docs.transak.com/) - Official Transak API and widget documentation +- [Query Parameters](https://docs.transak.com/customization/query-parameters) - Full list of widget customization options + +--- + +### Need Help? + + diff --git a/content/docs/sdk/fiat-modules/fiat-transak/usage.mdx b/content/docs/sdk/fiat-modules/fiat-transak/usage.mdx new file mode 100644 index 00000000..eb28d938 --- /dev/null +++ b/content/docs/sdk/fiat-modules/fiat-transak/usage.mdx @@ -0,0 +1,37 @@ +--- +title: Fiat Transak Usage +description: How to use the @tetherto/wdk-protocol-fiat-transak module +docType: how-to +schemaType: TechArticle +icon: BookOpen +--- + +# Usage + +The [@tetherto/wdk-protocol-fiat-transak](https://www.npmjs.com/package/@tetherto/wdk-protocol-fiat-transak) module builds Transak widget URLs and quotes for on-ramp and off-ramp flows. Use the guides below for setup, trading, and transaction follow-up. + + + +Install the package and initialize TransakProtocol. + + +On-ramp, off-ramp, quotes, supported assets, widget options, recipients. + + +Check status and load transaction details from Transak. + + + + + +Get started with WDK in a Node.js environment + + +API keys, backend callbacks, caching, and Transak configuration options + + +Constructor, methods, and types for TransakProtocol + + + + diff --git a/content/docs/sdk/fiat-modules/index.mdx b/content/docs/sdk/fiat-modules/index.mdx index 36cbd0ff..24d32187 100644 --- a/content/docs/sdk/fiat-modules/index.mdx +++ b/content/docs/sdk/fiat-modules/index.mdx @@ -14,6 +14,7 @@ On-ramp and off-ramp functionality for fiat currency integration: | Module | Provider | Status | Documentation | |--------|----------|--------|---------------| | [`@tetherto/wdk-protocol-fiat-moonpay`](https://github.com/tetherto/wdk-protocol-fiat-moonpay) | MoonPay | ✅ Ready | [Documentation](/sdk/fiat-modules/fiat-moonpay/) | +| [`@tetherto/wdk-protocol-fiat-transak`](https://github.com/tetherto/wdk-protocol-fiat-transak) | Transak | ✅ Ready | [Documentation](/sdk/fiat-modules/fiat-transak/) | ## Features diff --git a/src/lib/custom-tree.ts b/src/lib/custom-tree.ts index aa7f6529..66dbc736 100644 --- a/src/lib/custom-tree.ts +++ b/src/lib/custom-tree.ts @@ -325,6 +325,16 @@ export const customTree: Node[] = [ configuration('/sdk/fiat-modules/fiat-moonpay/configuration'), apiReference('/sdk/fiat-modules/fiat-moonpay/api-reference'), ]), + folder('Transak', '/sdk/fiat-modules/fiat-transak', 'CreditCard', [ + usage('/sdk/fiat-modules/fiat-transak/usage'), + guides([ + page('Get Started', '/sdk/fiat-modules/fiat-transak/guides/get-started'), + page('Buy and Sell', '/sdk/fiat-modules/fiat-transak/guides/buy-and-sell'), + page('Manage Transactions', '/sdk/fiat-modules/fiat-transak/guides/manage-transactions'), + ]), + configuration('/sdk/fiat-modules/fiat-transak/configuration'), + apiReference('/sdk/fiat-modules/fiat-transak/api-reference'), + ]), separator('AI'), page('Build with AI', '/start-building/build-with-ai', 'Bot'),