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

# Reference

> Read the reference documentation for the Portal Web SDK.

## Portal Class

The `Portal` class is the main entry point for the Portal Web SDK. It provides methods for wallet management, transaction signing, and blockchain interactions.

### Constructor

Creates a new Portal instance with the specified configuration.

```typescript theme={null}
constructor(options: PortalOptions)
```

**Parameters**

| Name                   | Type            | Required | Default                      | Description                                                                                                                                                                                                                                                                                     |
| ---------------------- | --------------- | -------- | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `options.rpcConfig`    | `RpcConfig`     | No       | Auto-generated for 13 chains | RPC endpoint map (CAIP-2 chain ID → URL). When omitted or `{}`, the SDK auto-generates gateway URLs for 13 built-in chains pointing at the Portal RPC gateway. An explicit non-empty map is used verbatim — no merging with defaults.                                                           |
| `options.gatewayHost`  | `string`        | No       | Derived from `host`          | Portal RPC gateway hostname, used when auto-generating `rpcConfig`. Resolution order: `gatewayHost` → `host` → `'web.portalhq.io'`. Only needed when the gateway lives on a different hostname than `host` (e.g. a custom CDN). For standard Portal environments, setting `host` is sufficient. |
| `options.apiKey`       | `string`        | No       | -                            | Portal API key for authentication                                                                                                                                                                                                                                                               |
| `options.authToken`    | `string`        | No       | -                            | Authentication token for Portal services                                                                                                                                                                                                                                                        |
| `options.authUrl`      | `string`        | No       | -                            | Custom authentication URL                                                                                                                                                                                                                                                                       |
| `options.autoApprove`  | `boolean`       | No       | `false`                      | Automatically approve transactions without user confirmation                                                                                                                                                                                                                                    |
| `options.gdrive`       | `GDriveConfig`  | No       | -                            | Google Drive backup configuration with `clientId`                                                                                                                                                                                                                                               |
| `options.passkey`      | `PasskeyConfig` | No       | -                            | Passkey configuration for WebAuthn backup                                                                                                                                                                                                                                                       |
| `options.host`         | `string`        | No       | `'web.portalhq.io'`          | Portal host URL                                                                                                                                                                                                                                                                                 |
| `options.mpcVersion`   | `string`        | No       | `'v6'`                       | MPC protocol version                                                                                                                                                                                                                                                                            |
| `options.mpcHost`      | `string`        | No       | `'mpc-client.portalhq.io'`   | MPC service host                                                                                                                                                                                                                                                                                |
| `options.featureFlags` | `FeatureFlags`  | No       | `{}`                         | Feature flags configuration                                                                                                                                                                                                                                                                     |
| `options.chainId`      | `string`        | No       | -                            | Default chain ID for the provider                                                                                                                                                                                                                                                               |
| `options.logLevel`     | `LogLevel`      | No       | `'none'`                     | Logging level: `'none'`, `'error'`, `'warn'`, `'info'`, or `'debug'`. See [Logging Configuration](/sdks/web/guide/logging)                                                                                                                                                                      |
| `options.logger`       | `ILogger`       | No       | `console`                    | Custom logger implementing `error`, `warn`, `info`, and `debug` methods                                                                                                                                                                                                                         |

**Example Usage**

```typescript theme={null}
import Portal, { buildDefaultRpcConfig } from '@portal-hq/web';

// Zero-config: SDK auto-generates RPC URLs for 13 built-in chains
// via the Portal-managed gateway (web.portalhq.io).
const portal = new Portal({
  apiKey: 'your-api-key',
});

// Custom subdomain: set `host` once — RPC gateway derives automatically.
const portalCustom = new Portal({
  apiKey: 'your-api-key',
  host: 'YOUR-CUSTOM-SUBDOMAIN',
});

// Extended config: start from the default 13 chains and add extras.
// Use this when your app needs chains not in the built-in set (e.g. Tron, AVAX Fuji).
const portalExtended = new Portal({
  apiKey: 'your-api-key',
  rpcConfig: {
    ...buildDefaultRpcConfig('web.portalhq.io'),
    'tron:mainnet': 'https://web.portalhq.io/rpc/v1/tron/mainnet',
  },
  gdrive: {
    clientId: 'your-client-id',
  },
});
```

### Public Properties

| Property        | Type                         | Description                                                                                                                                                  |
| --------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `address`       | `string \| undefined`        | The current wallet address                                                                                                                                   |
| `apiKey`        | `string \| undefined`        | Portal API key                                                                                                                                               |
| `authToken`     | `string \| undefined`        | Authentication token                                                                                                                                         |
| `authUrl`       | `string \| undefined`        | Authentication URL                                                                                                                                           |
| `autoApprove`   | `boolean`                    | Auto-approve transactions setting                                                                                                                            |
| `gDriveConfig`  | `GDriveConfig \| undefined`  | Google Drive configuration                                                                                                                                   |
| `passkeyConfig` | `PasskeyConfig \| undefined` | Passkey configuration                                                                                                                                        |
| `host`          | `string`                     | Portal host URL                                                                                                                                              |
| `mpc`           | `Mpc`                        | MPC instance for wallet operations                                                                                                                           |
| `yield`         | `Yield`                      | [Yield.xyz integration](/integrations/Yield/yield-xyz) instance                                                                                              |
| `trading`       | `Trading`                    | [LiFi trading integration](/integrations/Trading/lifi) instance                                                                                              |
| `ramps`         | `Ramps`                      | Fiat on/off-ramp integrations: [Noah](/integrations/On-Off-Ramp/noah) (`portal.ramps.noah`) and [Meld](/integrations/On-Off-Ramp/meld) (`portal.ramps.meld`) |
| `delegations`   | `Delegations`                | [Token delegations](/sdks/web/guide/delegations) (`portal.delegations`)                                                                                      |
| `mpcHost`       | `string`                     | MPC service host                                                                                                                                             |
| `mpcVersion`    | `string`                     | MPC protocol version                                                                                                                                         |
| `provider`      | `Provider`                   | Provider instance for RPC requests                                                                                                                           |
| `featureFlags`  | `FeatureFlags`               | Feature flags configuration                                                                                                                                  |
| `ready`         | `boolean`                    | Whether the Portal instance is ready (read-only getter)                                                                                                      |

### Feature flags

The `featureFlags` option controls optional SDK behavior. Pass it when creating a `Portal` instance.

| Property           | Type      | Default | Description                                                                                                                                                                                                                                                                                          |
| ------------------ | --------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `usePresignatures` | `boolean` | `false` | When `true`, the SDK uses presignatures to improve signing latency. The SDK generates and consumes presignatures in the background; you do not call presign APIs directly. Applies to SECP256K1 (EVM) signing only. See [Feature flags](/sdks/web/guide/feature-flags#usepresignatures) for details. |

**Example**

```typescript theme={null}
const portal = new Portal({
  apiKey: 'your-api-key',
  featureFlags: {
    usePresignatures: true,
  },
})
```

***

## Logging Methods

### setLogLevel

Sets the SDK log level at runtime. All SDK messages (e.g. deprecation warnings, provider messages) respect this level.

```typescript theme={null}
public setLogLevel(level: LogLevel): void
```

**Parameters**

| Name    | Type       | Description                                                  |
| ------- | ---------- | ------------------------------------------------------------ |
| `level` | `LogLevel` | One of `'none'`, `'error'`, `'warn'`, `'info'`, or `'debug'` |

**Example Usage**

```typescript theme={null}
portal.setLogLevel('debug')  // Enable verbose logging
portal.setLogLevel('none')   // Disable all SDK logs
```

See [Logging Configuration](/sdks/web/guide/logging) for full details.

### getLogLevel

Returns the current SDK log level.

```typescript theme={null}
public getLogLevel(): LogLevel
```

**Returns**

`LogLevel` — The current level: `'none' | 'error' | 'warn' | 'info' | 'debug'`

**Example Usage**

```typescript theme={null}
const level = portal.getLogLevel()
console.log('Current log level:', level)
```

***

## Initialization Methods

### onReady

Registers a callback to be executed when the Portal instance is ready.

```typescript theme={null}
public onReady(callback: () => any | Promise<any>): () => void
```

**Parameters**

| Name       | Type                        | Description                    |
| ---------- | --------------------------- | ------------------------------ |
| `callback` | `() => any \| Promise<any>` | Function to execute when ready |

**Returns**

A cleanup function that removes the callback when called.

**Example Usage**

```typescript theme={null}
const unsubscribe = portal.onReady(() => {
  console.log('Portal is ready!');
});

// Later, to remove the callback:
unsubscribe();
```

### onInitializationError

Registers a callback to be executed if initialization fails.

```typescript theme={null}
public onInitializationError(callback: (reason: string) => any | Promise<any>): () => void
```

**Parameters**

| Name       | Type                                      | Description                                         |
| ---------- | ----------------------------------------- | --------------------------------------------------- |
| `callback` | `(reason: string) => any \| Promise<any>` | Function to execute on error, receives error reason |

**Returns**

A cleanup function that removes the callback when called.

**Example Usage**

```typescript theme={null}
const unsubscribe = portal.onInitializationError(reason => {
  console.error('Initialization failed:', reason);
});
```

### onWalletNotOnDevice

Registers a callback to be executed when the user's wallet signing share is no longer in device storage (for example, after Safari ITP clears `localStorage`).

The callback is replayed immediately if the event already fired before this method was called, so it is safe to register at any point during initialization.

```typescript theme={null}
public onWalletNotOnDevice(
  callback: (payload: WalletNotOnDevicePayload) => any | Promise<any>,
): () => void
```

**Parameters**

| Name       | Type                                                         | Description                                          |
| ---------- | ------------------------------------------------------------ | ---------------------------------------------------- |
| `callback` | `(payload: WalletNotOnDevicePayload) => any \| Promise<any>` | Function to execute when the wallet is not on device |

**Returns**

A cleanup function that removes the callback when called.

**Payload — `WalletNotOnDevicePayload`**

| Field        | Type                | Description                                         |
| ------------ | ------------------- | --------------------------------------------------- |
| `clientId`   | `string`            | The client ID of the affected wallet                |
| `isBackedUp` | `boolean`           | Whether a backup exists that can be used to recover |
| `reason`     | `'storage_cleared'` | Why the wallet is not on device                     |

**Example Usage**

```typescript theme={null}
const unsubscribe = portal.onWalletNotOnDevice(async (payload) => {
  if (payload.isBackedUp) {
    // prompt user to recover their wallet
  } else {
    // no backup — clear state and restart onboarding
    await portal.clearLocalWallet()
  }
});
```

***

## Wallet Lifecycle Methods

### createWallet

Creates a new wallet and generates addresses for supported chains.

```typescript theme={null}
public async createWallet(progress?: ProgressCallback): Promise<string>
```

**Parameters**

| Name       | Type               | Description                                                      |
| ---------- | ------------------ | ---------------------------------------------------------------- |
| `progress` | `ProgressCallback` | Optional callback for tracking progress with `MpcStatus` updates |

**Returns**

`Promise<string>` - The wallet address

**Example Usage**

```typescript theme={null}
const address = await portal.createWallet(status => {
  console.log('Status:', status);
});

console.log('Wallet created with address:', address);
```

### configureFirebaseStorage

Registers Firebase Authentication for wallet backup and recovery. The Web SDK runs MPC inside an iframe; your parent page implements `getToken`, and the iframe requests Firebase ID tokens over a `postMessage` bridge when storing or reading encryption keys on Portal’s token backup service (TBS).

Call this method before `backupWallet` or `recoverWallet` with `BackupMethods.firebase`.

```typescript theme={null}
public configureFirebaseStorage(options: FirebaseStorageConfigOptions): void
```

**Parameters**

| Name               | Type                                                                | Required | Description                                                                                                                                                                                          |
| ------------------ | ------------------------------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `options.getToken` | `(options?: { forceRefresh?: boolean }) => Promise<string \| null>` | Yes      | Returns a Firebase **ID token** for the signed-in user, or `null` if there is no user. When `options.forceRefresh` is `true`, request a refreshed token (used internally after HTTP `401` from TBS). |
| `options.tbsHost`  | `string`                                                            | No       | TBS hostname or full origin (for example `backup.web.portalhq.io`). Defaults to `backup.web.portalhq.io`.                                                                                            |

**`FirebaseStorageConfigOptions`**

```typescript theme={null}
import type { FirebaseStorageConfigOptions } from '@portal-hq/web/types'
```

**Example usage**

```typescript theme={null}
import Portal, { BackupMethods } from '@portal-hq/web'
import { getAuth } from 'firebase/auth'

const portal = new Portal({
  apiKey: 'YOUR_PORTAL_CLIENT_API_KEY',
})

portal.configureFirebaseStorage({
  getToken: async (options?: { forceRefresh?: boolean }) => {
    const user = getAuth().currentUser
    if (!user) {
      return null
    }
    return user.getIdToken(Boolean(options?.forceRefresh))
  },
})

await portal.backupWallet(BackupMethods.firebase)
```

**Errors and behavior**

* If `getToken` is not configured and the iframe requests a token, the bridge rejects with **`Firebase storage is not configured (getToken missing)`**.
* If `getToken` returns `null`, backup/recovery fails with messages such as **`[FirebaseStorage] Firebase ID token is required`** or **`[FirebaseStorage] Firebase ID token is null`**.
* After HTTP `401`, the iframe retries once with `getToken({ forceRefresh: true })`. If that still returns `null`, you may see **`[FirebaseStorage] Firebase ID token is null after 401 retry`**.
* TBS HTTP failures surface as **`[FirebaseStorage] Failed to store encryption key: …`** or **`[FirebaseStorage] Failed to read encryption key: …`**.

Firebase ID tokens are sent as the `X-Firebase-Token` header together with your Portal Client API key (`Authorization: Bearer …` from the iframe’s configured `apiKey`).

<Note>
  `validateOperations` on the iframe side only checks that a Firebase ID token is available; it does not verify TBS connectivity.
</Note>

***

### backupWallet

Creates a backup of the wallet using the specified backup method.

```typescript theme={null}
public async backupWallet(
  backupMethod: BackupMethods,
  progress?: ProgressCallback,
  backupConfigs?: BackupConfigs
): Promise<BackupResponse>
```

**Parameters**

| Name            | Type               | Description                                                   |
| --------------- | ------------------ | ------------------------------------------------------------- |
| `backupMethod`  | `BackupMethods`    | Backup method: `GDRIVE`, `PASSWORD`, `PASSKEY`, or `FIREBASE` |
| `progress`      | `ProgressCallback` | Optional progress callback                                    |
| `backupConfigs` | `BackupConfigs`    | Optional backup configuration (e.g., password)                |

**Returns**

`Promise<BackupResponse>` containing:

* `cipherText`: Encrypted backup data
* `storageCallback`: Function to finalize storage

**Example Usage**

```typescript theme={null}
import { getAuth } from 'firebase/auth'

// Password backup
const passwordBackup = await portal.backupWallet(BackupMethods.password, status => console.log(status), {
  passwordStorage: { password: 'your-password' },
});
await passwordBackup.storageCallback();
console.log('Password backup cipher text:', passwordBackup.cipherText);

// Firebase backup (call configureFirebaseStorage first)
portal.configureFirebaseStorage({
  getToken: async (options?: { forceRefresh?: boolean }) => {
    const user = getAuth().currentUser
    if (!user) {
      return null
    }
    return user.getIdToken(Boolean(options?.forceRefresh))
  },
})
const firebaseBackup = await portal.backupWallet(BackupMethods.firebase, status =>
  console.log(status),
)
await firebaseBackup.storageCallback();
console.log('Firebase backup cipher text:', firebaseBackup.cipherText);
```

### recoverWallet

Recovers a wallet from a backup.

```typescript theme={null}
public async recoverWallet(
  cipherText: string,
  backupMethod: BackupMethods,
  backupConfigs?: BackupConfigs,
  progress?: ProgressCallback
): Promise<string>
```

**Parameters**

| Name            | Type               | Description                   |
| --------------- | ------------------ | ----------------------------- |
| `cipherText`    | `string`           | Encrypted backup data         |
| `backupMethod`  | `BackupMethods`    | Backup method used            |
| `backupConfigs` | `BackupConfigs`    | Optional backup configuration |
| `progress`      | `ProgressCallback` | Optional progress callback    |

**Returns**

`Promise<string>` - The recovered wallet address

**Example Usage**

```typescript theme={null}
const address = await portal.recoverWallet('your-cipher-text', BackupMethods.password, {
  passwordStorage: { password: 'your-password' },
});

console.log('Wallet recovered:', address);
```

### provisionWallet

Alias for `recoverWallet`. Provisions a wallet from a backup.

```typescript theme={null}
public async provisionWallet(
  cipherText: string,
  backupMethod: BackupMethods,
  backupConfigs: BackupConfigs,
  progress?: ProgressCallback
): Promise<string>
```

### clearLocalWallet

Clears the local wallet data from device storage.

```typescript theme={null}
public async clearLocalWallet(): Promise<boolean>
```

**Returns**

`Promise<boolean>` - `true` if successful

**Example Usage**

```typescript theme={null}
const cleared = await portal.clearLocalWallet();
console.log('Wallet cleared:', cleared);
```

***

## Wallet Status Methods

### doesWalletExist

Checks if a wallet exists for the client.

```typescript theme={null}
public async doesWalletExist(chainId?: string): Promise<boolean>
```

**Parameters**

| Name      | Type     | Description                                                        |
| --------- | -------- | ------------------------------------------------------------------ |
| `chainId` | `string` | Optional chain ID to check specific namespace (e.g., `'eip155:1'`) |

**Returns**

`Promise<boolean>` - `true` if wallet exists

**Example Usage**

```typescript theme={null}
// Check if any wallet exists
const exists = await portal.doesWalletExist();

// Check for specific chain
const hasEthWallet = await portal.doesWalletExist('eip155:1');
```

### isWalletOnDevice

Checks if wallet shares are stored on the current device.

```typescript theme={null}
public async isWalletOnDevice(chainId?: string): Promise<boolean>
```

**Parameters**

| Name      | Type     | Description                               |
| --------- | -------- | ----------------------------------------- |
| `chainId` | `string` | Optional chain ID to check specific curve |

**Returns**

`Promise<boolean>` - `true` if wallet is on device

### isWalletBackedUp

Checks if the wallet has been backed up.

```typescript theme={null}
public async isWalletBackedUp(chainId?: string): Promise<boolean>
```

**Parameters**

| Name      | Type     | Description                                |
| --------- | -------- | ------------------------------------------ |
| `chainId` | `string` | Optional chain ID to check specific wallet |

**Returns**

`Promise<boolean>` - `true` if wallet is backed up

### isWalletRecoverable

Checks if the wallet can be recovered.

```typescript theme={null}
public async isWalletRecoverable(chainId?: string): Promise<boolean>
```

**Returns**

`Promise<boolean>` - `true` if wallet is recoverable

### availableRecoveryMethods

Gets the available recovery methods for the wallet.

```typescript theme={null}
public async availableRecoveryMethods(chainId?: string): Promise<BackupMethods[]>
```

**Returns**

`Promise<BackupMethods[]>` - Array of available backup methods

**Example Usage**

```typescript theme={null}
const methods = await portal.availableRecoveryMethods();
console.log('Available recovery methods:', methods);
// e.g., ['GDRIVE', 'PASSWORD']
```

***

## Address Methods

### getEip155Address

Gets the EIP-155 (Ethereum-compatible) address.

```typescript theme={null}
public async getEip155Address(): Promise<string>
```

**Returns**

`Promise<string>` - The Ethereum address

**Example Usage**

```typescript theme={null}
const ethAddress = await portal.getEip155Address();
console.log('Ethereum address:', ethAddress);
```

### getSolanaAddress

Gets the Solana address.

```typescript theme={null}
public async getSolanaAddress(): Promise<string>
```

**Returns**

`Promise<string>` - The Solana address

**Example Usage**

```typescript theme={null}
const solAddress = await portal.getSolanaAddress();
console.log('Solana address:', solAddress);
```

### getTronAddress

Gets the TRON address.

```typescript theme={null}
public async getTronAddress(): Promise<string>
```

**Returns**

`Promise<string>` - The TRON address, or an empty string if no TRON wallet exists yet

**Example Usage**

```typescript theme={null}
const tronAddress = await portal.getTronAddress();
console.log('TRON address:', tronAddress);
```

***

## Eject Methods

<Warning>
  Providing the custodian backup share to the client device puts both MPC shares on a single device, removing
  the multi-party security benefits of MPC. This operation should only be done for users who want to move off
  of MPC and into a single private key. Use portal.eject() or portal.ejectPrivateKeys() at your own risk!
</Warning>

### eject

Ejects the SECP256K1 private key from MPC custody. For eject examples see [here](./guide/eject-a-wallet)

```typescript theme={null}
public async eject(
  backupMethod: BackupMethods,
  backupConfigs: BackupConfigs,
  orgBackupShare?: string,
  clientBackupCipherText?: string
): Promise<EjectResult>
```

**Parameters**

| Name                     | Type            | Description                                                     |
| ------------------------ | --------------- | --------------------------------------------------------------- |
| `backupMethod`           | `BackupMethods` | Backup method to use                                            |
| `backupConfigs`          | `BackupConfigs` | Backup configuration                                            |
| `orgBackupShare`         | `string`        | Organization backup share (required if not using Portal backup) |
| `clientBackupCipherText` | `string`        | Client backup cipher text (required if not using Portal backup) |

**Returns**

`Promise<EjectResult>` containing:

* `SECP256K1`: The private key as a string

### ejectPrivateKeys

Ejects all private keys (both SECP256K1 and ED25519) from MPC custody.

```typescript theme={null}
public async ejectPrivateKeys(
  backupMethod: BackupMethods,
  backupConfigs: BackupConfigs,
  orgBackupShares: OrgBackupShares,
  clientBackupCipherText?: string
): Promise<EjectPrivateKeysResult>
```

**Parameters**

| Name                     | Type              | Description                                                     |
| ------------------------ | ----------------- | --------------------------------------------------------------- |
| `backupMethod`           | `BackupMethods`   | Backup method to use                                            |
| `backupConfigs`          | `BackupConfigs`   | Backup configuration                                            |
| `orgBackupShares`        | `OrgBackupShares` | Organization backup shares for both curves                      |
| `clientBackupCipherText` | `string`          | Client backup cipher text (required if not using Portal backup) |

**Returns**

`Promise<EjectPrivateKeysResult>` containing:

* `SECP256K1`: The SECP256K1 private key
* `ED25519`: The ED25519 private key

***

## Transaction Methods

### request

Makes an RPC request to a blockchain network. This is the primary method for interacting with blockchains.

```typescript theme={null}
public async request(request: RequestArguments): Promise<any>
```

**Parameters**

| Name                            | Type      | Description                                                          |
| ------------------------------- | --------- | -------------------------------------------------------------------- |
| `request.chainId`               | `string`  | Chain ID in CAIP-2 format (e.g., `'eip155:1'`)                       |
| `request.method`                | `string`  | RPC method name (e.g., `'eth_sendTransaction'`)                      |
| `request.params`                | `any`     | Method parameters                                                    |
| `request.sponsorGas`            | `boolean` | Optional. Whether to sponsor gas (Account Abstraction).              |
| `request.signatureApprovalMemo` | `string`  | Optional. Memo shown to the user during the signature approval flow. |

**Returns**

`Promise<any>` - Response from the RPC call

**Example Usage**

```typescript theme={null}
// Send Ethereum transaction
const txHash = await portal.request({
  chainId: 'eip155:1',
  method: 'eth_sendTransaction',
  params: [
    {
      from: portal.address,
      to: '0x...',
      value: '0xDE0B6B3A7640000', // 1 ETH in wei
    },
  ],
  signatureApprovalMemo: 'Send 1 ETH', // optional
});

// Sign Solana transaction
const signature = await portal.request({
  chainId: 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp',
  method: 'sol_signAndSendTransaction',
  params: [transaction],
});
```

### sendAsset

Helper method to send assets to another address. Supports EVM (`eip155:*`), Solana (`solana:*`), and TRON (`tron:*`) chains.

```typescript theme={null}
public async sendAsset(chain: string, params: SendAssetParams): Promise<string>
```

**Parameters**

| Name                           | Type      | Description                                                          |
| ------------------------------ | --------- | -------------------------------------------------------------------- |
| `chain`                        | `string`  | Chain ID in CAIP-2 format (e.g., `'eip155:1'`, `'tron:mainnet'`)     |
| `params.to`                    | `string`  | Recipient address                                                    |
| `params.token`                 | `string`  | Token contract address, or `'NATIVE'` for the chain's native token   |
| `params.amount`                | `string`  | Amount to send                                                       |
| `params.sponsorGas`            | `boolean` | Optional. Whether to sponsor gas (Account Abstraction, EVM only).    |
| `params.signatureApprovalMemo` | `string`  | Optional. Memo shown to the user during the signature approval flow. |

**Returns**

`Promise<string>` — transaction hash (EVM / Solana) or transaction ID (TRON)

**Example Usage**

```typescript theme={null}
// EVM
const txHash = await portal.sendAsset('eip155:1', {
  to: '0x...',
  token: 'NATIVE', // Native ETH
  amount: '1000000000000000000', // 1 ETH in wei
});
console.log('Transaction hash:', txHash);

// TRON
const txId = await portal.sendAsset('tron:mainnet', {
  to: 'TRecipientAddress',
  token: 'NATIVE', // TRX
  amount: '1',
  signatureApprovalMemo: 'Send TRX', // optional
});
console.log('Transaction ID:', txId);
```

<Note>
  TRON transaction confirmation polling is not supported. `portal.waitForConfirmation` always returns
  `false` for `tron:*` chains. Verify the transaction status directly via TRON RPC using the transaction
  ID returned by `sendAsset`.
</Note>

### sendSol

Helper method to send SOL tokens.

```typescript theme={null}
public async sendSol({
  chainId,
  to,
  lamports
}: {
  chainId: string
  to: string
  lamports: number
}): Promise<string>
```

**Parameters**

| Name       | Type     | Description                                         |
| ---------- | -------- | --------------------------------------------------- |
| `chainId`  | `string` | Solana chain ID (must start with `'solana:'`)       |
| `to`       | `string` | Recipient Solana address (44 characters)            |
| `lamports` | `number` | Amount in lamports (1 SOL = 1,000,000,000 lamports) |

**Returns**

`Promise<string>` - Transaction signature

**Example Usage**

```typescript theme={null}
const signature = await portal.sendSol({
  chainId: 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp',
  to: 'DYw8...',
  lamports: 1000000000, // 1 SOL
});
```

### sendEth

Helper method to send ETH.

```typescript theme={null}
public sendEth = async ({
  chainId,
  to,
  value
}: {
  chainId: string
  to: string
  value: string
}): Promise<any>
```

**Parameters**

| Name      | Type     | Description                |
| --------- | -------- | -------------------------- |
| `chainId` | `string` | EIP-155 chain ID           |
| `to`      | `string` | Recipient address          |
| `value`   | `string` | Amount in wei (hex string) |

**Returns**

`Promise<any>` - Transaction hash

**Example Usage**

```typescript theme={null}
const txHash = await portal.sendEth({
  chainId: 'eip155:1',
  to: '0x...',
  value: '0xDE0B6B3A7640000', // 1 ETH in wei
});

console.log('Transaction hash:', txHash);
```

### rawSign

Signs data directly using the specified cryptographic curve. An optional third argument accepts **`signatureApprovalMemo`** which is shown to the user during the approval flow.

```typescript theme={null}
public async rawSign(
  curve: PortalCurve,
  param: string,
  options?: RawSignOptions
): Promise<string>
```

**Parameters**

| Name      | Type             | Description                                    |
| --------- | ---------------- | ---------------------------------------------- |
| `curve`   | `PortalCurve`    | Cryptographic curve (`ED25519` or `SECP256K1`) |
| `param`   | `string`         | Data to sign                                   |
| `options` | `RawSignOptions` | Optional. `{ signatureApprovalMemo?: string }` |

**Returns**

`Promise<string>` - Signature

**Example Usage**

```typescript theme={null}
import { PortalCurve } from '@portal-hq/web';

// Sign with SECP256K1 (Ethereum)
const signature = await portal.rawSign(PortalCurve.SECP256K1, 'your-data-to-sign');

// With optional approval memo (shown to user during approval)
const signatureWithMemo = await portal.rawSign(
  PortalCurve.SECP256K1,
  'your-data-to-sign',
  { signatureApprovalMemo: 'Sign login challenge' }
);

console.log('Signature:', signature);
```

***

### sendBatchUserOp

Builds, signs, and broadcasts a batch of token transfers as a single ERC-4337 UserOperation. Only available on Account Abstraction clients. Chain must be `eip155:`-prefixed.

```typescript theme={null}
public async sendBatchUserOp(
  data: SendBatchUserOpRequest
): Promise<BroadcastBatchedUserOpResponse>
```

**`SendBatchUserOpRequest` fields:**

| Field                   | Type                           | Required | Description                                  |
| ----------------------- | ------------------------------ | -------- | -------------------------------------------- |
| `chain`                 | `string`                       | Yes      | CAIP-2 chain ID (must start with `eip155:`)  |
| `transactions`          | `SendBatchUserOpTransaction[]` | Yes      | Ordered list of transfers to batch           |
| `signatureApprovalMemo` | `string`                       | No       | Optional memo shown during the approval flow |

**`SendBatchUserOpTransaction` fields:**

| Field   | Type     | Description                                 |
| ------- | -------- | ------------------------------------------- |
| `token` | `string` | Token symbol (e.g. `'USDC'`, `'NATIVE'`)    |
| `value` | `string` | Human-readable amount                       |
| `to`    | `string` | Recipient EVM address (`0x` + 40 hex chars) |

**Returns**

`Promise<BroadcastBatchedUserOpResponse>` — `{ data: { userOpHash: string }, metadata: { chainId: string } }`

**Example Usage**

```typescript theme={null}
import type { SendBatchUserOpRequest } from '@portal-hq/web'

const result = await portal.sendBatchUserOp({
  chain: 'eip155:10143',
  transactions: [
    { token: 'USDC', value: '5.00', to: '0xAlice...' },
    { token: 'USDC', value: '5.00', to: '0xBob...' },
  ],
  signatureApprovalMemo: 'Batch transfer',
})
console.log('UserOp hash:', result.data.userOpHash)
```

See [Batch User Operations](/resources/account-abstraction#batch-user-operations-web-sdk) for the full guide.

***

### sendBatchedAssets

Builds, signs, and broadcasts a gas-subsidized batch that includes a reimbursement transfer — in a fee token you supply — to recover the paymaster gas cost. Requires an AA client. Chain must be `eip155:`-prefixed.

```typescript theme={null}
public async sendBatchedAssets(
  data: SendBatchedAssetsRequest
): Promise<BroadcastBatchedUserOpResponse>
```

**`SendBatchedAssetsRequest` fields:**

| Field                   | Type                           | Required | Description                                                          |
| ----------------------- | ------------------------------ | -------- | -------------------------------------------------------------------- |
| `chain`                 | `string`                       | Yes      | CAIP-2 chain ID (must start with `eip155:`)                          |
| `transactions`          | `SendBatchUserOpTransaction[]` | Yes      | The user's actual transfers                                          |
| `gasReimbursement`      | `GasReimbursement`             | Yes      | Reimbursement config — fee token, recipient, and conversion callback |
| `signatureApprovalMemo` | `string`                       | No       | Optional memo shown during the approval flow                         |

**`GasReimbursement` fields:**

| Field                   | Type                                                | Required | Description                                                                                                                                                              |
| ----------------------- | --------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `feeToken`              | `string`                                            | Yes      | Token symbol charged for reimbursement (e.g. `'USDC'`)                                                                                                                   |
| `feeRecipient`          | `string`                                            | Yes      | EVM address that receives the reimbursement                                                                                                                              |
| `convertGasToFeeAmount` | `(gasCostWei: bigint) => string \| Promise<string>` | Yes      | Platform-supplied conversion — Portal provides the native gas cost in wei; you return the fee-token amount as a decimal string. Portal does not perform this conversion. |
| `bufferBps`             | `number`                                            | No       | Safety margin in basis points applied to the gas cost before conversion (e.g. `1000` = +10%). Defaults to `0`.                                                           |
| `placeholderAmount`     | `string`                                            | No       | Amount used for the fee call during the estimation pass. Defaults to `'0.01'`. Must be ≤ the wallet's balance.                                                           |

**Returns**

`Promise<BroadcastBatchedUserOpResponse>`

See [Batch User Operations](/resources/account-abstraction#batch-user-operations-web-sdk) for the full guide including the two-pass build flow.

***

### buildBatchedUserOp

Low-level: builds an ERC-4337 UserOperation from an ordered list of raw calls without signing or broadcasting it. Use this when you need direct control over the sign/broadcast steps.

```typescript theme={null}
public async buildBatchedUserOp(
  data: BuildBatchedUserOpRequest
): Promise<BuildBatchedUserOpResponse>
```

**`BuildBatchedUserOpRequest` fields:**

| Field   | Type                  | Required | Description                                 |
| ------- | --------------------- | -------- | ------------------------------------------- |
| `chain` | `string`              | Yes      | CAIP-2 chain ID (must start with `eip155:`) |
| `calls` | `UserOperationCall[]` | Yes      | Ordered list of raw calls                   |

**`UserOperationCall` fields:**

| Field   | Type     | Description                                                                    |
| ------- | -------- | ------------------------------------------------------------------------------ |
| `to`    | `string` | Target address                                                                 |
| `value` | `string` | (optional) Native token amount in wei (decimal string). Omit for ERC-20 calls. |
| `data`  | `string` | (optional) Calldata hex string. Defaults to `'0x'` for native transfers.       |

**`BuildBatchedUserOpResponse.metadata` fields** (all optional — backends that predate this change omit them):

| Field                 | Description                                                                                                                |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `totalGas`            | Sum of all ERC-4337 gas limit fields (decimal string). The prefund multiplier is not applied.                              |
| `maxFeePerGas`        | Price per gas unit in wei (decimal string). `'0'` on chains with no on-chain fee.                                          |
| `estimatedGasCostWei` | Build-time upper bound gas cost in wei (`totalGas × maxFeePerGas`). Use this as the authoritative value to charge against. |

***

### broadcastBatchedUserOp

Low-level: broadcasts a signed UserOperation to the bundler.

```typescript theme={null}
public async broadcastBatchedUserOp(
  data: BroadcastBatchedUserOpRequest
): Promise<BroadcastBatchedUserOpResponse>
```

**`BroadcastBatchedUserOpRequest` fields:**

| Field           | Type     | Required | Description                                                    |
| --------------- | -------- | -------- | -------------------------------------------------------------- |
| `chain`         | `string` | Yes      | CAIP-2 chain ID                                                |
| `userOperation` | `string` | Yes      | Serialized UserOperation JSON string from `buildBatchedUserOp` |
| `signature`     | `string` | Yes      | Signature over `userOpHash` (without `0x` prefix)              |

<Note>
  When signing `userOpHash` manually with `rawSign`, strip the `0x` prefix before passing it: `userOpHash.replace(/^0x/, '')`.
</Note>

***

## Delegations <a href="#delegations" id="delegations" />

`portal.delegations` exposes approve, revoke, status, transfer, and high-level sign-and-submit helpers for token delegations on supported EVM and Solana chains. See [Manage Token Delegations](/sdks/web/guide/delegations) for walkthroughs.

The interfaces below match the types exported from `@portal-hq/web` (for example `import type { ApproveDelegationRequest } from '@portal-hq/web'`).

### `portal.delegations` methods

| Method              | Signature                                                                                                              |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `approve`           | `approve(params: ApproveDelegationRequest): Promise<ApproveDelegationResponse>`                                        |
| `revoke`            | `revoke(params: RevokeDelegationRequest): Promise<RevokeDelegationResponse>`                                           |
| `getStatus`         | `getStatus(params: GetDelegationStatusRequest): Promise<DelegationStatusResponse>`                                     |
| `transferFrom`      | `transferFrom(params: TransferFromRequest): Promise<TransferFromResponse>`                                             |
| `approveAndSubmit`  | `approveAndSubmit(params: ApproveDelegationRequest, options?: DelegationSubmitOptions): Promise<{ hashes: string[] }>` |
| `revokeAndSubmit`   | `revokeAndSubmit(params: RevokeDelegationRequest, options?: DelegationSubmitOptions): Promise<{ hashes: string[] }>`   |
| `transferAndSubmit` | `transferAndSubmit(params: TransferFromRequest, options?: DelegationSubmitOptions): Promise<{ hashes: string[] }>`     |

### Request and options types

#### ApproveDelegationRequest <a href="#approve-delegation-request" id="approve-delegation-request" />

```typescript theme={null}
interface ApproveDelegationRequest {
  chain: string
  token: string
  delegateAddress: string
  amount: string
}
```

#### RevokeDelegationRequest <a href="#revoke-delegation-request" id="revoke-delegation-request" />

```typescript theme={null}
interface RevokeDelegationRequest {
  chain: string
  token: string
  delegateAddress: string
}
```

#### GetDelegationStatusRequest <a href="#get-delegation-status-request" id="get-delegation-status-request" />

```typescript theme={null}
interface GetDelegationStatusRequest {
  chain: string
  token: string
  delegateAddress: string
}
```

#### TransferFromRequest <a href="#transfer-from-request" id="transfer-from-request" />

```typescript theme={null}
interface TransferFromRequest {
  chain: string
  token: string
  fromAddress: string
  toAddress: string
  amount: string
}
```

#### DelegationSubmitOptions <a href="#delegation-submit-options" id="delegation-submit-options" />

Optional second argument for `approveAndSubmit`, `revokeAndSubmit`, and `transferAndSubmit`.

```typescript theme={null}
interface DelegationSubmitOptions {
  signAndSendTransaction?: (
    transaction: unknown,
    chainId: string
  ) => Promise<string>
  onProgress?: (event: DelegationSubmitProgress) => void
}
```

#### DelegationSubmitProgress <a href="#delegation-submit-progress" id="delegation-submit-progress" />

```typescript theme={null}
interface DelegationSubmitProgress {
  step: 'signing' | 'submitted'
  index: number
  total: number
  hash?: string
}
```

***

## Yield Types <a href="#yield-types" id="yield-types" />

Types used by the high-level `deposit` and `withdraw` methods on `portal.yield.yieldXyz`. All types are exported from `@portal-hq/web`.

#### YieldDepositParams <a href="#yield-deposit-params" id="yield-deposit-params" />

Union type — provide either `yieldId` or `chain` + `token`. A non-empty `yieldId` takes precedence.

```typescript theme={null}
type YieldDepositParams =
  | { yieldId: string; amount: string; address?: string; arguments?: YieldXyzEnterArguments }
  | { chain: string; token: string; amount: string; address?: string; arguments?: YieldXyzEnterArguments }
```

#### YieldWithdrawParams <a href="#yield-withdraw-params" id="yield-withdraw-params" />

Same union as `YieldDepositParams`.

```typescript theme={null}
type YieldWithdrawParams = YieldDepositParams
```

#### YieldSubmitOptions <a href="#yield-submit-options" id="yield-submit-options" />

```typescript theme={null}
interface YieldSubmitOptions {
  onProgress?: (event: YieldSubmitProgress) => void
  signAndSendTransaction?: (transaction: unknown, network: string) => Promise<string>
  waitForConfirmation?: (txHash: string, network: string) => Promise<void | boolean>
  evmRequestFn?: (method: string, params: unknown[], network: string) => Promise<unknown>
  evmPollerOptions?: { pollIntervalMs?: number; timeoutMs?: number }
}
```

#### YieldSubmitProgress <a href="#yield-submit-progress" id="yield-submit-progress" />

```typescript theme={null}
interface YieldSubmitProgress {
  step: 'signing' | 'submitted' | 'confirming' | 'confirmed'
  index: number
  total: number
  hash?: string
}
```

#### YieldDepositResult <a href="#yield-deposit-result" id="yield-deposit-result" />

```typescript theme={null}
interface YieldDepositResult {
  hashes: string[]
  yieldId: string
  chain?: string
  token?: string
  yieldOpportunityDetails: {
    yieldId: string
    intent?: string
    type?: string
    executionPattern?: string
    status?: string
    amount?: string | null
    amountUsd?: string | null
  }
}
```

#### YieldWithdrawResult <a href="#yield-withdraw-result" id="yield-withdraw-result" />

Same shape as `YieldDepositResult`.

```typescript theme={null}
interface YieldWithdrawResult {
  hashes: string[]
  yieldId: string
  chain?: string
  token?: string
  yieldOpportunityDetails: {
    yieldId: string
    intent?: string
    type?: string
    executionPattern?: string
    status?: string
    amount?: string | null
    amountUsd?: string | null
  }
}
```

#### YieldXyzValidator <a href="#yield-xyz-validator" id="yield-xyz-validator" />

```typescript theme={null}
interface YieldXyzValidator {
  address: string
  name?: string
  commission?: string
  apy?: string
  [key: string]: unknown
}
```

***

## API Methods

### getClient

Gets information about the client and their wallets.

```typescript theme={null}
public async getClient(): Promise<ClientResponse>
```

**Returns**

`Promise<ClientResponse>` with client information including:

* `id`: Client ID
* `address`: Primary address
* `wallets`: Array of wallet information
* `metadata`: Namespace metadata with addresses

**Example Usage**

```typescript theme={null}
const client = await portal.getClient();
console.log('Client ID:', client.id);
console.log('Wallets:', client.wallets);
```

### getAssets

Gets the assets (tokens) held by the wallet.

```typescript theme={null}
public async getAssets(chainId: string, includeNfts?: boolean): Promise<GetAssetsResponse>
```

**Parameters**

| Name          | Type      | Description                                |
| ------------- | --------- | ------------------------------------------ |
| `chainId`     | `string`  | Chain ID to query                          |
| `includeNfts` | `boolean` | Whether to include NFTs (default: `false`) |

**Returns**

`Promise<GetAssetsResponse>` with asset information

**Example Usage**

```typescript theme={null}
const assets = await portal.getAssets('eip155:1', false);
console.log('Assets:', assets);
```

### getNFTAssets

Gets NFT assets held by the wallet.

```typescript theme={null}
public async getNFTAssets(chainId: string): Promise<NFTAsset[]>
```

**Parameters**

| Name      | Type     | Description       |
| --------- | -------- | ----------------- |
| `chainId` | `string` | Chain ID to query |

**Returns**

`Promise<NFTAsset[]>` - Array of NFT assets

**Example Usage**

```typescript theme={null}
const nfts = await portal.getNFTAssets('eip155:1');
console.log('NFT assets:', nfts);
```

### getTransactionHistory

Returns the transaction history for a wallet across supported chains.
Replaces the legacy `getTransactions` method with pagination and extended support for modern transaction types (including ERC-4337 UserOperations on EVM chains). EVM responses use the normalized format documented below, while Solana currently returns its legacy response shape and will be unified in a future update.

```typescript theme={null}
public async getTransactionHistory(
  params: GetTransactionHistoryParams
): Promise<GetTransactionHistoryResponse>
```

**Parameters**

| Name                    | Type                               | Description                                                                                                                      |
| ----------------------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `params.chainId`        | `string`                           | Chain ID in CAIP-2 format (e.g., `'eip155:1'`, `'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp'`)                                      |
| `params.limit`          | `number`                           | Maximum number of transactions to return (default: 50; max: 1000 for EVM, 15 for Solana)                                         |
| `params.offset`         | `number`                           | Number of transactions to skip for pagination (default: 0)                                                                       |
| `params.order`          | `'asc' \| 'desc'`                  | Sort order by block number (default: `'desc'`, EVM only)                                                                         |
| `params.address`        | `string`                           | Optional address override (EVM only)                                                                                             |
| `params.userOperations` | `'include' \| 'only' \| 'exclude'` | Optional. Filter ERC-4337 UserOperations on **EVM chains (`eip155:*`)** only. If set, the SDK always sends that value unchanged. |

**Default behavior (`userOperations`)**

* **EVM (`eip155:*`)** — If the authenticated client has Account Abstraction enabled (`isAccountAbstracted`), the SDK automatically sends `userOperations=only`. If the client is an EOA, the SDK does not send the parameter.
* **Non-EVM chains** (e.g. `solana:*`, Bitcoin, Tron, Stellar) — The SDK never injects `userOperations`; the filter does not apply to those namespaces.

If `userOperations` is provided, it always overrides this behavior.

**Returns**

`Promise<GetTransactionHistoryResponse>`

**For Solana chains (`solana:*`)**:

```typescript theme={null}
{
  data: {
    transactions: SolanaTransactionDetails[]
  },
  metadata: {
    address: string
    chainId: string
    clientId: string
    limit: number
    offset: number
    count: number
  }
}
```

**For EVM, Bitcoin, Tron, Stellar chains**:

```typescript theme={null}
{
  data: {
    transactions: TransactionHistoryItem[]
  },
  metadata: {
    address: string
    chainId: string
    clientId: string
    limit: number
    offset: number
    count: number
  }
}
```

**TransactionHistoryItem** is a discriminated union:

* **RegularTransaction**: `type: 'transaction'` with optional token metadata (`asset`, `tokenAddress`, `tokenDecimals`)
* **UserOperationTransaction**: `type: 'userOperation'` with UserOp fields (`userOpHash`, `entryPoint`, `actualGasCost`, `actualGasUsed`)

**Example Usage**

```typescript theme={null}
// Get EVM transactions including UserOperations
const evmTxs = await portal.getTransactionHistory({
  chainId: 'eip155:1',
  limit: 20,
  order: 'desc',
  userOperations: 'include',  // Include both regular txs and UserOps
});

// Type narrowing based on transaction type
evmTxs.data.transactions.forEach(tx => {
  if (tx.type === 'userOperation') {
    console.log('UserOp hash:', tx.userOpHash);
    console.log('Entry point:', tx.entryPoint);
    // tx.asset not available (compile error)
  } else {
    console.log('Token:', tx.asset);
    console.log('Token address:', tx.tokenAddress);
    // tx.userOpHash not available (compile error)
  }
});

// EVM + Account Abstraction: omit `userOperations`
// If wallet is AA-enabled, SDK injects `userOperations='only'`
// Otherwise (EOA), the parameter is not sent
const aaEvmHistory = await portal.getTransactionHistory({
  chainId: 'eip155:42161',
  limit: 20,
});

// Get Solana transactions
const solanaTxs = await portal.getTransactionHistory({
  chainId: 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp',
  limit: 15,
});

// Solana transactions have a different structure
solanaTxs.data.transactions.forEach(tx => {
  console.log('Signature:', tx.signature);
  console.log('Block time:', tx.blockTime);
  console.log('Status:', tx.status);
});

// Get only UserOperations (EVM only)
const userOps = await portal.getTransactionHistory({
  chainId: 'eip155:137',
  userOperations: 'only',
  limit: 10,
});
```

### getTransactions

<Warning>
  **Deprecated**: Use `getTransactionHistory()` instead, which provides improved type safety with discriminated unions for regular transactions and UserOperations, and proper polymorphic response types for Solana vs unified formats.
</Warning>

Gets transaction history for the wallet.

```typescript theme={null}
public async getTransactions(
  chainId: string,
  limit?: number,
  offset?: number,
  order?: GetTransactionsOrder
): Promise<Transaction[]>
```

**Parameters**

| Name      | Type                   | Description                              |
| --------- | ---------------------- | ---------------------------------------- |
| `chainId` | `string`               | Chain ID to query                        |
| `limit`   | `number`               | Maximum number of transactions to return |
| `offset`  | `number`               | Number of transactions to skip           |
| `order`   | `GetTransactionsOrder` | Sort order: `'asc'` or `'desc'`          |

**Returns**

`Promise<Transaction[]>` - Array of transactions

**Example Usage**

```typescript theme={null}
import { GetTransactionsOrder } from '@portal-hq/web';

// ⚠️ DEPRECATED: Use getTransactionHistory() instead
const txs = await portal.getTransactions('eip155:1', 10, 0, GetTransactionsOrder.DESC);

// ✅ RECOMMENDED: Use the new method with improved type safety
const walletTxs = await portal.getTransactionHistory({
  chainId: 'eip155:1',
  limit: 10,
  offset: 0,
  order: 'desc',
});
```

### evaluateTransaction

Evaluates a transaction before execution to check if the transaction can be executed, and perform security validations.

```typescript theme={null}
public async evaluateTransaction(
  chainId: string,
  transaction: EvaluateTransactionParam,
  operationType?: EvaluateTransactionOperationType
): Promise<EvaluatedTransaction>
```

**Parameters**

| Name            | Type                               | Description                           |
| --------------- | ---------------------------------- | ------------------------------------- |
| `chainId`       | `string`                           | Chain ID                              |
| `transaction`   | `EvaluateTransactionParam`         | Transaction to evaluate               |
| `operationType` | `EvaluateTransactionOperationType` | Type of evaluation (default: `'all'`) |

**Returns**

`Promise<EvaluatedTransaction>` with security analysis

**Example Usage**

```typescript theme={null}
const evaluation = await portal.evaluateTransaction('eip155:1', {
  from: portal.address,
  to: '0x...',
  value: '0x1',
});

console.log('Security warnings:', evaluation.warnings);
```

### buildTransaction

Builds a transaction for sending tokens.

```typescript theme={null}
public async buildTransaction(
  chainId: string,
  to: string,
  token: string,
  amount: string
): Promise<BuiltTransaction>
```

**Parameters**

| Name      | Type     | Description            |
| --------- | -------- | ---------------------- |
| `chainId` | `string` | Chain ID               |
| `to`      | `string` | Recipient address      |
| `token`   | `string` | Token contract address |
| `amount`  | `string` | Amount to send         |

**Returns**

`Promise<BuiltTransaction>` with the built transaction object

**Example Usage**

```typescript theme={null}
const builtTx = await portal.buildTransaction(
  'eip155:1',
  '0x...',
  '0x0000000000000000000000000000000000000000', // Native ETH
  '1000000000000000000' // 1 ETH in wei
);

// Use the built transaction
const txHash = await portal.request({
  chainId: 'eip155:1',
  method: 'eth_sendTransaction',
  params: [builtTx.transaction],
});
```

### receiveTestnetAsset

Requests testnet assets from a faucet.

```typescript theme={null}
public async receiveTestnetAsset(chainId: string, params: FundParams): Promise<FundResponse>
```

**Parameters**

| Name            | Type     | Description       |
| --------------- | -------- | ----------------- |
| `chainId`       | `string` | Testnet chain ID  |
| `params.amount` | `string` | Amount to request |
| `params.token`  | `string` | Token identifier  |

**Returns**

`Promise<FundResponse>` with funding details

**Example Usage**

```typescript theme={null}
const fundResponse = await portal.receiveTestnetAsset('eip155:11155111', {
  amount: '1',
  token: 'ETH',
});

console.log('Transaction hash:', fundResponse.data?.txHash);
console.log('Explorer URL:', fundResponse.data?.explorerUrl);
```

***

## Swap Methods

### getQuote

Gets a quote for an in-chain token swap.

<Warning>Deprecated: Use the `portal.trading.zerox.getQuote` method instead.</Warning>

```typescript theme={null}
public async getQuote(
  apiKey: string,
  args: QuoteArgs,
  chainId: string
): Promise<QuoteResponse>
```

### getSources

Gets available swap sources for in-chain swaps.

<Warning>Deprecated: Use the `portal.trading.zerox.getSources` method instead.</Warning>

```typescript theme={null}
public async getSources(apiKey: string, chainId: string): Promise<Record<string, string>>
```

***

## Utility Methods

### updateChain

Updates the current chain ID for the provider.

```typescript theme={null}
public updateChain(newChainId: string): void
```

**Parameters**

| Name         | Type     | Description         |
| ------------ | -------- | ------------------- |
| `newChainId` | `string` | New chain ID to set |

**Example Usage**

```typescript theme={null}
portal.updateChain('eip155:137'); // Switch to Polygon
```

### getRpcUrl

Gets the configured RPC URL for a chain.

```typescript theme={null}
public getRpcUrl(chainId?: string): string
```

**Parameters**

| Name      | Type     | Description         |
| --------- | -------- | ------------------- |
| `chainId` | `string` | Chain ID to look up |

**Returns**

`string` - The RPC URL

**Throws**

Error if chain ID is not configured

### storedClientBackupShare

Notifies Portal that a backup share has been stored.

```typescript theme={null}
public async storedClientBackupShare(success: boolean, backupMethod: BackupMethods): Promise<void>
```

**Parameters**

| Name           | Type            | Description                       |
| -------------- | --------------- | --------------------------------- |
| `success`      | `boolean`       | Whether the backup was successful |
| `backupMethod` | `BackupMethods` | The backup method that was used   |

**Returns**

`Promise<void>`

**Example Usage**

```typescript theme={null}
import { BackupMethods } from '@portal-hq/web';

// After successfully storing a backup
await portal.storedClientBackupShare(true, BackupMethods.gdrive);
```

***

## Integration Classes

### portal.yield (Yield)

The `Yield` class provides access to [Yield.xyz](/integrations/Yield/yield-xyz) integration for yield farming opportunities.

**Properties**

| Property   | Type       | Description                    |
| ---------- | ---------- | ------------------------------ |
| `yieldXyz` | `YieldXyz` | Yield.xyz integration instance |

#### getValidators

Fetches validator addresses for a specific `yieldId`. Delegates to `portal.yield.yieldXyz.getValidators`. Throws if the response does not contain a valid validators array.

```typescript theme={null}
public getValidators(yieldId: string): Promise<YieldXyzValidator[]>
```

**Parameters**

| Name      | Type     | Description                                                            |
| --------- | -------- | ---------------------------------------------------------------------- |
| `yieldId` | `string` | Yield opportunity identifier (e.g. `monad-testnet-mon-native-staking`) |

**Returns**

`Promise<YieldXyzValidator[]>` — Array of validator objects. Each entry includes at minimum `address: string` plus optional `name`, `commission`, `apy`, and any additional provider-specific fields.

**Example Usage**

```typescript theme={null}
const validators = await portal.yield.getValidators('monad-testnet-mon-native-staking')
console.log('Validators:', validators)
```

### portal.yield.yieldXyz (YieldXyz)

Access yield farming features through the Yield.xyz integration. Includes low-level methods (`discover`, `enter`, `exit`, `manage`, `track`, `getTransaction`, `getBalances`, `getHistoricalActions`) and high-level helpers (`deposit`, `withdraw`). See the [Yield.xyz guide](/sdks/web/guide/yield-xyz) for walkthroughs.

#### deposit

High-level deposit: resolves the yield, builds the enter action, signs and sends each transaction in order, waits for confirmation between steps when configured, and reports hashes to Yield.xyz — all in one call. See the [Yield.xyz guide](/sdks/web/guide/yield-xyz#high-level-methods) for parameter tables and examples.

```typescript theme={null}
public async deposit(
  params: YieldDepositParams,
  options?: YieldSubmitOptions,
): Promise<YieldDepositResult>
```

**Parameters**

| Name      | Type                 | Required | Description                                                                                                                                                                                      |
| --------- | -------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `params`  | `YieldDepositParams` | Yes      | Either `{ yieldId, amount }` or `{ chain, token, amount }`. Non-empty `yieldId` takes precedence. `chain` must be a full CAIP-2 id (e.g. `eip155:11155111`). Optional `address` and `arguments`. |
| `options` | `YieldSubmitOptions` | No       | `onProgress`, per-call `signAndSendTransaction`, `waitForConfirmation`, `evmRequestFn`, `evmPollerOptions`.                                                                                      |

**Returns**

`Promise<YieldDepositResult>` with fields:

| Field                     | Type       | Description                                                                                                        |
| ------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------ |
| `hashes`                  | `string[]` | Submitted tx hashes, in order.                                                                                     |
| `yieldId`                 | `string`   | Resolved yield id.                                                                                                 |
| `chain`                   | `string?`  | Echoed when you passed `chain` + `token`.                                                                          |
| `token`                   | `string?`  | Echoed when you passed `chain` + `token`.                                                                          |
| `yieldOpportunityDetails` | `object`   | Action metadata from Yield.xyz (`yieldId`, `intent`, `type`, `executionPattern`, `status`, `amount`, `amountUsd`). |

#### withdraw

High-level withdraw: same dual-input modes, `yieldId` resolution, signer fallback, and confirmation behavior as `deposit`, but calls the Yield.xyz exit action. See the [Yield.xyz guide](/sdks/web/guide/yield-xyz#high-level-methods) for parameter tables and examples.

```typescript theme={null}
public async withdraw(
  params: YieldWithdrawParams,
  options?: YieldSubmitOptions,
): Promise<YieldWithdrawResult>
```

**Parameters**

| Name      | Type                  | Required | Description                         |
| --------- | --------------------- | -------- | ----------------------------------- |
| `params`  | `YieldWithdrawParams` | Yes      | Same union as `YieldDepositParams`. |
| `options` | `YieldSubmitOptions`  | No       | Same options as `deposit`.          |

**Returns**

`Promise<YieldWithdrawResult>` — Same shape as `YieldDepositResult`.

#### discover

Discovers available yield opportunities.

```typescript theme={null}
public async discover(data: YieldXyzGetYieldsRequest): Promise<YieldXyzGetYieldsResponse>
```

**Parameters**

| Name   | Type                       | Description                    |
| ------ | -------------------------- | ------------------------------ |
| `data` | `YieldXyzGetYieldsRequest` | Parameters for yield discovery |

**Returns**

`Promise<YieldXyzGetYieldsResponse>` - Available yield opportunities

**Example Usage**

```typescript theme={null}
const yields = await portal.yield.yieldXyz.discover({
  // Discovery parameters
});
console.log('Available yields:', yields);
```

#### getBalances

Retrieves yield balances for specified addresses and networks.

```typescript theme={null}
public async getBalances(data: YieldXyzGetBalancesRequest): Promise<YieldXyzGetBalancesResponse>
```

**Parameters**

| Name   | Type                         | Description                                         |
| ------ | ---------------------------- | --------------------------------------------------- |
| `data` | `YieldXyzGetBalancesRequest` | Request parameters including addresses and networks |

**Returns**

`Promise<YieldXyzGetBalancesResponse>` - Balance information

#### getHistoricalActions

Retrieves historical yield actions with optional filtering.

```typescript theme={null}
public async getHistoricalActions(
  data: YieldXyzGetHistoricalActionsRequest
): Promise<YieldXyzGetHistoricalActionsResponse>
```

**Returns**

`Promise<YieldXyzGetHistoricalActionsResponse>` - Historical actions

#### enter

Enters a yield opportunity.

```typescript theme={null}
public async enter(data: YieldXyzEnterRequest): Promise<YieldXyzEnterYieldResponse>
```

**Parameters**

| Name   | Type                   | Description                                 |
| ------ | ---------------------- | ------------------------------------------- |
| `data` | `YieldXyzEnterRequest` | Parameters for entering a yield opportunity |

**Returns**

`Promise<YieldXyzEnterYieldResponse>` - Action details

**Example Usage**

```typescript theme={null}
const result = await portal.yield.yieldXyz.enter({
  // Enter parameters
});
```

#### exit

Exits a yield opportunity.

```typescript theme={null}
public async exit(data: YieldXyzExitRequest): Promise<YieldXyzExitResponse>
```

**Parameters**

| Name   | Type                  | Description                                |
| ------ | --------------------- | ------------------------------------------ |
| `data` | `YieldXyzExitRequest` | Parameters for exiting a yield opportunity |

**Returns**

`Promise<YieldXyzExitResponse>` - Action details

#### manage

Manages a yield opportunity with specified parameters.

```typescript theme={null}
public async manage(data: YieldXyzManageYieldRequest): Promise<YieldXyzManageYieldResponse>
```

**Parameters**

| Name   | Type                         | Description                                 |
| ------ | ---------------------------- | ------------------------------------------- |
| `data` | `YieldXyzManageYieldRequest` | Parameters for managing a yield opportunity |

**Returns**

`Promise<YieldXyzManageYieldResponse>` - Action details

#### track

Tracks a transaction by submitting its hash.

```typescript theme={null}
public async track(data: YieldXyzTrackTransactionRequest): Promise<YieldXyzTrackTransactionResponse>
```

**Parameters**

| Name                 | Type     | Description                           |
| -------------------- | -------- | ------------------------------------- |
| `data.transactionId` | `string` | The ID of the transaction to track    |
| `data.txHash`        | `string` | The hash of the transaction to submit |

**Returns**

`Promise<YieldXyzTrackTransactionResponse>` - Tracking confirmation

#### getTransaction

Retrieves a single yield action transaction by its ID.

```typescript theme={null}
public async getTransaction(transactionId: string): Promise<YieldXyzGetTransactionResponse>
```

**Parameters**

| Name            | Type     | Description                    |
| --------------- | -------- | ------------------------------ |
| `transactionId` | `string` | The transaction ID to retrieve |

**Returns**

`Promise<YieldXyzGetTransactionResponse>` - Transaction details

***

### portal.trading (Trading)

The `Trading` class provides access to:

* [Li.Fi](/integrations/Trading/lifi) integration for cross-chain swaps and bridges
* [0x](./guide/perform-swaps) integration for in-chain swaps

**Properties**

| Property | Type    | Description                |
| -------- | ------- | -------------------------- |
| `lifi`   | `LiFi`  | Li.Fi integration instance |
| `zeroX`  | `ZeroX` | 0x integration instance    |

### portal.trading.lifi (LiFi)

Access cross-chain swap and bridge features through the Li.Fi integration. Includes `tradeAsset` for end-to-end trades and lower-level methods for manual flows. See the [Li.Fi guide](/sdks/web/guide/lifi) for walkthroughs.

#### tradeAsset

Runs the end-to-end Li.Fi flow in one call: discover routes, select a route, build each step, sign and broadcast, wait for confirmation, poll Li.Fi status for cross-chain steps, and return hashes. See the [Li.Fi guide](/sdks/web/guide/lifi#tradeasset) for parameter tables, progress lifecycle, and examples.

```typescript theme={null}
public async tradeAsset(
  params: LifiTradeAssetParams,
  options?: LifiTradeAssetOptions,
): Promise<LifiTradeAssetResult>
```

**Parameters**

| Name      | Type                    | Required | Description                                                                                                                                                           |
| --------- | ----------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `params`  | `LifiTradeAssetParams`  | Yes      | `fromChain`, `toChain`, `fromToken`, `toToken`, `amount`, `fromAddress` (required); `toAddress`, `routeOptions`, `routeIndex`, `onProgress`, `statusPoll` (optional). |
| `options` | `LifiTradeAssetOptions` | No       | Per-call `signAndSendTransaction`, `waitForConfirmation`, `evmRequestFn`, `evmPollerOptions`.                                                                         |

**Returns**

`Promise<LifiTradeAssetResult>` with fields:

| Field    | Type         | Description                           |
| -------- | ------------ | ------------------------------------- |
| `hashes` | `string[]`   | Transaction hashes per executed step. |
| `steps`  | `LifiStep[]` | Step objects from the API.            |
| `route`  | `LifiRoute`  | The executed route.                   |

#### pollStatus

Built-in Li.Fi status polling with retries and exponential backoff. Use when you already have a tx hash and want the same polling behavior as inside `tradeAsset`. See the [Li.Fi guide](/sdks/web/guide/lifi#pollstatus) for option defaults and examples.

```typescript theme={null}
public async pollStatus(
  request: Pick<LifiStatusRequest, 'txHash' | 'fromChain' | 'toChain' | 'bridge'>,
  options?: LifiPollStatusOptions & {
    onUpdate?: (raw: LifiStatusRawResponse) => boolean | void
  },
): Promise<LifiStatusRawResponse>
```

**Parameters**

| Name                           | Type                                              | Required | Description                                                     |
| ------------------------------ | ------------------------------------------------- | -------- | --------------------------------------------------------------- |
| `request.txHash`               | `string`                                          | Yes      | Transaction hash to poll.                                       |
| `request.fromChain`            | `string`                                          | Yes      | Source chain.                                                   |
| `request.toChain`              | `string`                                          | No       | Destination chain.                                              |
| `request.bridge`               | `string`                                          | No       | Bridge tool identifier.                                         |
| `options.everyMs`              | `number`                                          | No       | Interval between requests (default `10000`).                    |
| `options.initialDelayMs`       | `number`                                          | No       | Delay before the first request (default `10000`).               |
| `options.timeoutMs`            | `number`                                          | No       | Max total poll time (default `600000`).                         |
| `options.maxConsecutiveErrors` | `number`                                          | No       | Abort after this many consecutive errors (default `10`).        |
| `options.backoff`              | `{ factor: number; maxIntervalMs: number }`       | No       | Backoff config (default `factor: 1.5`, `maxIntervalMs: 15000`). |
| `options.onUpdate`             | `(raw: LifiStatusRawResponse) => boolean \| void` | No       | Return `false` to stop early.                                   |

**Returns**

`Promise<LifiStatusRawResponse>` — Terminal status response.

#### getRoutes

Retrieves available routes for cross-chain swaps and bridges.

```typescript theme={null}
public async getRoutes(data: LifiRoutesRequest): Promise<LifiRoutesResponse>
```

**Parameters**

| Name   | Type                | Description                    |
| ------ | ------------------- | ------------------------------ |
| `data` | `LifiRoutesRequest` | Parameters for route discovery |

**Returns**

`Promise<LifiRoutesResponse>` - Available routes

**Example Usage**

```typescript theme={null}
const routes = await portal.trading.lifi.getRoutes({
  fromChainId: 1,
  toChainId: 137,
  fromTokenAddress: '0x...',
  toTokenAddress: '0x...',
  fromAmount: '1000000000000000000',
});
console.log('Available routes:', routes);
```

#### getQuote

Retrieves a quote for a swap or bridge operation.

```typescript theme={null}
public async getQuote(data: LifiQuoteRequest): Promise<LifiQuoteResponse>
```

**Parameters**

| Name   | Type               | Description                      |
| ------ | ------------------ | -------------------------------- |
| `data` | `LifiQuoteRequest` | Parameters for the quote request |

**Returns**

`Promise<LifiQuoteResponse>` - Quote details including fees and estimated time

**Example Usage**

```typescript theme={null}
const quote = await portal.trading.lifi.getQuote({
  fromChain: '1',
  toChain: '137',
  fromToken: '0x...',
  toToken: '0x...',
  fromAmount: '1000000000000000000',
  fromAddress: portal.address,
});
```

#### getStatus

Retrieves the status of a cross-chain transaction.

```typescript theme={null}
public async getStatus(data: LifiStatusRequest): Promise<LifiStatusResponse>
```

**Parameters**

| Name   | Type                | Description                                          |
| ------ | ------------------- | ---------------------------------------------------- |
| `data` | `LifiStatusRequest` | Status request parameters including transaction hash |

**Returns**

`Promise<LifiStatusResponse>` - Transaction status

**Example Usage**

```typescript theme={null}
const status = await portal.trading.lifi.getStatus({
  txHash: '0x...',
  bridge: 'hop',
});
console.log('Transaction status:', status.status);
```

#### getRouteStep

Retrieves an unsigned transaction for a specific route step.

```typescript theme={null}
public async getRouteStep(data: LifiStepTransactionRequest): Promise<LifiStepTransactionResponse>
```

**Parameters**

| Name   | Type                         | Description                                |
| ------ | ---------------------------- | ------------------------------------------ |
| `data` | `LifiStepTransactionRequest` | Step transaction request with step details |

**Returns**

`Promise<LifiStepTransactionResponse>` - Unsigned transaction ready to be signed

**Example Usage**

```typescript theme={null}
const step = await portal.trading.lifi.getRouteStep({
  route: selectedRoute,
  stepIndex: 0,
});

// Sign and send the transaction
const txHash = await portal.request({
  chainId: 'eip155:1',
  method: 'eth_sendTransaction',
  params: [step.transactionRequest],
});
```

### portal.trading.zeroX (0x)

Access in-chain swap features through the 0x integration. See the [0x guide](./guide/zero-x) for full walkthroughs.

#### tradeAsset

Fetches a 0x quote, signs and broadcasts the transaction, waits for on-chain confirmation, and returns hashes. See the [0x guide](./guide/zero-x#tradeasset) for parameter tables and examples.

```typescript theme={null}
public async tradeAsset(
  params: ZeroXTradeAssetParams,
  options?: ZeroXTradeAssetOptions,
): Promise<ZeroXTradeAssetResult>
```

#### getPrice

Retrieves an indicative price for a token swap without generating executable transaction data.

```typescript theme={null}
public async getPrice(
  request: ZeroExPriceRequest,
  options?: { zeroXApiKey?: string },
): Promise<ZeroExPriceResponse>
```

#### getQuote

Gets a swap quote with executable transaction data.

```typescript theme={null}
public async getQuote(
  request: ZeroExQuoteRequest,
  options?: { zeroXApiKey?: string },
): Promise<ZeroExQuoteResponse>
```

#### getSources

Gets available liquidity sources for a chain.

```typescript theme={null}
public async getSources(
  chainId: string,
  options?: { zeroXApiKey?: string },
): Promise<ZeroExSourcesResponse>
```

***

### portal.ramps (Ramps)

The `Ramps` class groups fiat on/off-ramp integrations.

**Properties**

| Property | Type   | Description                                                        |
| -------- | ------ | ------------------------------------------------------------------ |
| `noah`   | `Noah` | [Noah](/integrations/On-Off-Ramp/noah) ramp API                    |
| `meld`   | `Meld` | [Meld](/integrations/On-Off-Ramp/meld) buy, sell, and transfer API |

See the [Noah Web SDK guide](./guide/noah) and the [Meld Web SDK guide](./guide/meld) for end-to-end flows and prerequisites.

### portal.ramps.noah (Noah)

Noah methods forward to the embedded Portal iframe, which calls `https://api.portalhq.io/api/v3/clients/me/integrations/noah/...` with the authenticated client session. Responses follow the `{ data, metadata? }` envelope used across Client API integrations.

#### initiateKyc

```typescript theme={null}
public async initiateKyc(data: NoahInitiateKycRequest): Promise<NoahInitiateKycResponse>
```

| Parameter | Type                     | Description                                                                     |
| --------- | ------------------------ | ------------------------------------------------------------------------------- |
| `data`    | `NoahInitiateKycRequest` | `returnUrl` (HTTPS), optional `fiatOptions`, `customerType`, `metadata`, `form` |

**Returns** — `Promise<NoahInitiateKycResponse>` with `data.hostedUrl` for hosted onboarding.

#### initiatePayin

```typescript theme={null}
public async initiatePayin(data: NoahInitiatePayinRequest): Promise<NoahInitiatePayinResponse>
```

| Parameter | Type                       | Description                                                              |
| --------- | -------------------------- | ------------------------------------------------------------------------ |
| `data`    | `NoahInitiatePayinRequest` | `fiatCurrency`, `cryptoCurrency`, CAIP-2 `network`, `destinationAddress` |

**Returns** — `Promise<NoahInitiatePayinResponse>` with `data.payinId` and `data.bankDetails`.

#### simulatePayin

```typescript theme={null}
public async simulatePayin(data: NoahSimulatePayinRequest): Promise<NoahSimulatePayinResponse>
```

| Parameter | Type                       | Description                                     |
| --------- | -------------------------- | ----------------------------------------------- |
| `data`    | `NoahSimulatePayinRequest` | `paymentMethodId`, `fiatAmount`, `fiatCurrency` |

**Returns** — `Promise<NoahSimulatePayinResponse>` (sandbox simulation payload).

#### getPayoutCountries

```typescript theme={null}
public async getPayoutCountries(): Promise<NoahGetPayoutCountriesResponse>
```

**Returns** — `Promise<NoahGetPayoutCountriesResponse>` with `data.countries`.

#### getPayoutChannels

```typescript theme={null}
public async getPayoutChannels(data: NoahGetPayoutChannelsRequest): Promise<NoahGetPayoutChannelsResponse>
```

| Parameter | Type                           | Description                                                                                                               |
| --------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------- |
| `data`    | `NoahGetPayoutChannelsRequest` | `cryptoCurrency` (required); optional `country`, `fiatCurrency`, `fiatAmount`, `paymentMethodId`, `pageSize`, `pageToken` |

**Returns** — `Promise<NoahGetPayoutChannelsResponse>` (`data` shape is provider-specific).

#### getPayoutChannelForm

```typescript theme={null}
public async getPayoutChannelForm(channelId: string): Promise<NoahGetPayoutChannelFormResponse>
```

| Parameter   | Type     | Description                                |
| ----------- | -------- | ------------------------------------------ |
| `channelId` | `string` | Payout channel id from `getPayoutChannels` |

**Returns** — `Promise<NoahGetPayoutChannelFormResponse>` (dynamic form schema).

#### getPayoutQuote

```typescript theme={null}
public async getPayoutQuote(data: NoahGetPayoutQuoteRequest): Promise<NoahGetPayoutQuoteResponse>
```

| Parameter | Type                        | Description                                                                                     |
| --------- | --------------------------- | ----------------------------------------------------------------------------------------------- |
| `data`    | `NoahGetPayoutQuoteRequest` | `channelId`, `cryptoCurrency`, `fiatAmount`, optional `form`, `fiatCurrency`, `paymentMethodId` |

**Returns** — `Promise<NoahGetPayoutQuoteResponse>` including `payoutId`, `formSessionId`, `cryptoAmountEstimate`, `totalFee`.

#### initiatePayout

```typescript theme={null}
public async initiatePayout(data: NoahInitiatePayoutRequest): Promise<NoahInitiatePayoutResponse>
```

| Parameter | Type                        | Description                                                                              |
| --------- | --------------------------- | ---------------------------------------------------------------------------------------- |
| `data`    | `NoahInitiatePayoutRequest` | `payoutId`, `sourceAddress`, ISO `expiry`, `nonce`, CAIP-2 `network`, optional `trigger` |

**Returns** — `Promise<NoahInitiatePayoutResponse>` with `destinationAddress` and `conditions` for deposit legs when applicable.

#### getPaymentMethods

```typescript theme={null}
public async getPaymentMethods(data?: NoahGetPaymentMethodsRequest): Promise<NoahGetPaymentMethodsResponse>
```

**Returns** — `Promise<NoahGetPaymentMethodsResponse>` with `data.paymentMethods` and optional `pageToken`.

***

### portal.ramps.meld (Meld)

Meld methods forward to the embedded Portal iframe, which calls `https://api.portalhq.io/api/v3/clients/me/integrations/meld/...` with the authenticated client session. Responses follow the `{ data, metadata? }` envelope used across Client API integrations.

See the [Meld Web SDK guide](./guide/meld) for end-to-end flows with full examples.

#### createCustomer

```typescript theme={null}
public async createCustomer(
  data: MeldCreateCustomerRequest
): Promise<MeldCreateCustomerResponse>
```

| Parameter | Type                        | Description                                                                               |
| --------- | --------------------------- | ----------------------------------------------------------------------------------------- |
| `data`    | `MeldCreateCustomerRequest` | Optional `name`, `email`, `phone`, `dateOfBirth`, `type` (`"INDIVIDUAL"` \| `"BUSINESS"`) |

**Returns** — `Promise<MeldCreateCustomerResponse>` with `data: MeldCustomer` (`id`, `externalId`, `accountId`, `name`, `email`, `type`, `status`).

#### searchCustomer

```typescript theme={null}
public async searchCustomer(): Promise<MeldSearchCustomerResponse>
```

**Returns** — `Promise<MeldSearchCustomerResponse>` with `data: { customers: MeldCustomer[]; count: number; remaining: number }`.

#### getRetailQuote

```typescript theme={null}
public async getRetailQuote(
  data: MeldGetRetailQuoteRequest
): Promise<MeldGetRetailQuoteResponse>
```

| Parameter | Type                        | Description                                                                                                                                                                                        |
| --------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `data`    | `MeldGetRetailQuoteRequest` | Required: `countryCode`, `sourceCurrencyCode`, `destinationCurrencyCode`, `sourceAmount` (number). Optional: `walletAddress`, `customerId`, `paymentMethodType`, `serviceProviders`, `subdivision` |

**Returns** — `Promise<MeldGetRetailQuoteResponse>` with `data: { quotes: MeldQuote[]; message?: string; error?: string; timestamp?: string }`.

Each `MeldQuote` includes required fields: `serviceProvider`, `transactionType`, `sourceAmount`, `sourceCurrencyCode`, `destinationAmount`, `destinationCurrencyCode`, `exchangeRate`, `transactionFee`, `totalFee`, `paymentMethodType`; and optional nullable fields: `sourceAmountWithoutFees`, `destinationAmountWithoutFees`, `networkFee`, `partnerFee`, `fiatAmountWithoutFees`, `countryCode`, `customerScore`, `institutionName`, `isNativeAvailable`, `rampIntelligence`.

#### createRetailWidget

```typescript theme={null}
public async createRetailWidget(
  data: MeldCreateRetailWidgetRequest
): Promise<MeldCreateRetailWidgetResponse>
```

| Parameter | Type                            | Description                                                                                                                                                |
| --------- | ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `data`    | `MeldCreateRetailWidgetRequest` | Required: `sessionType` (`"BUY"` \| `"SELL"` \| `"TRANSFER"`), `sessionData` (`MeldSessionData`). Optional: `externalSessionId`, `customerId`, `bypassKyc` |

**Returns** — `Promise<MeldCreateRetailWidgetResponse>` with `data: { id, token, customerId, externalCustomerId, externalSessionId, widgetUrl }`.

#### searchRetailTransactions

```typescript theme={null}
public async searchRetailTransactions(
  data?: MeldSearchRetailTransactionsParams
): Promise<MeldSearchRetailTransactionsResponse>
```

| Parameter | Type                                 | Description                                        |
| --------- | ------------------------------------ | -------------------------------------------------- |
| `data`    | `MeldSearchRetailTransactionsParams` | Optional `status`, `limit`, `offset` (all strings) |

**Returns** — `Promise<MeldSearchRetailTransactionsResponse>` with `data: { transactions: MeldTransaction[]; count: number; remaining: number; totalCount: number }`.

#### getRetailTransaction

```typescript theme={null}
public async getRetailTransaction(id: string): Promise<MeldGetRetailTransactionResponse>
```

| Parameter | Type     | Description         |
| --------- | -------- | ------------------- |
| `id`      | `string` | Meld transaction ID |

**Returns** — `Promise<MeldGetRetailTransactionResponse>` with `data: { transaction: MeldTransaction }`.

#### getRetailTransactionBySession

```typescript theme={null}
public async getRetailTransactionBySession(
  sessionId: string
): Promise<MeldGetRetailTransactionResponse>
```

| Parameter   | Type     | Description                                                    |
| ----------- | -------- | -------------------------------------------------------------- |
| `sessionId` | `string` | Meld session ID from `createRetailWidget` response (`data.id`) |

**Returns** — `Promise<MeldGetRetailTransactionResponse>` with `data: { transaction: MeldTransaction }`.

#### getServiceProviders

```typescript theme={null}
public async getServiceProviders(
  params?: MeldDiscoveryParams
): Promise<MeldGetServiceProvidersResponse>
```

**Returns** — `Promise<MeldGetServiceProvidersResponse>` with `data: MeldServiceProvider[]`.

#### getCountries

```typescript theme={null}
public async getCountries(
  params?: MeldDiscoveryParams
): Promise<MeldGetCountriesResponse>
```

**Returns** — `Promise<MeldGetCountriesResponse>` with `data: MeldCountry[]`.

#### getFiatCurrencies

```typescript theme={null}
public async getFiatCurrencies(
  params?: MeldDiscoveryParams
): Promise<MeldGetFiatCurrenciesResponse>
```

**Returns** — `Promise<MeldGetFiatCurrenciesResponse>` with `data: MeldFiatCurrency[]`.

#### getCryptoCurrencies

```typescript theme={null}
public async getCryptoCurrencies(
  params?: MeldDiscoveryParams
): Promise<MeldGetCryptoCurrenciesResponse>
```

**Returns** — `Promise<MeldGetCryptoCurrenciesResponse>` with `data: MeldCryptoCurrency[]`.

#### getPaymentMethods

```typescript theme={null}
public async getPaymentMethods(
  params?: MeldDiscoveryParams
): Promise<MeldGetPaymentMethodsResponse>
```

**Returns** — `Promise<MeldGetPaymentMethodsResponse>` with `data: MeldPaymentMethod[]`.

#### getDefaults

```typescript theme={null}
public async getDefaults(
  params?: MeldDiscoveryParams
): Promise<MeldGetDefaultsResponse>
```

**Returns** — `Promise<MeldGetDefaultsResponse>` with `data: MeldCountryDefault[]` (`countryCode`, `defaultCurrencyCode`, `defaultPaymentMethods`).

#### getBuyLimits

```typescript theme={null}
public async getBuyLimits(
  params?: MeldDiscoveryParams
): Promise<MeldGetBuyLimitsResponse>
```

**Returns** — `Promise<MeldGetBuyLimitsResponse>` with `data: MeldFiatCurrencyPurchaseLimit[]` (`currencyCode`, `minimumAmount`, `maximumAmount`, `defaultAmount`).

#### getSellLimits

```typescript theme={null}
public async getSellLimits(
  params?: MeldDiscoveryParams
): Promise<MeldGetSellLimitsResponse>
```

**Returns** — `Promise<MeldGetSellLimitsResponse>` with `data: MeldCryptoCurrencySellLimit[]` (`currencyCode`, `chainCode`, `minimumAmount`, `maximumAmount`, `defaultAmount`).

#### getKycLimits

```typescript theme={null}
public async getKycLimits(
  params?: MeldDiscoveryParams
): Promise<MeldGetKycLimitsResponse>
```

**Returns** — `Promise<MeldGetKycLimitsResponse>` with `data: MeldKycFiatLevel[]`. Each entry includes `currencyCode` and optional `level1`, `level2`, `level3` of type `MeldKycLimitTier` with `dailyLimit`, `weeklyLimit`, `monthlyLimit`, `yearlyLimit`, `transactionLimit`.

***

## Deprecated Methods

The following methods are deprecated. Use `portal.request()` instead.

### ethEstimateGas

<Warning>
  Deprecated: Use `portal.request({ method: 'eth_estimateGas', ... })` instead.
</Warning>

```typescript theme={null}
public async ethEstimateGas(chainId: string, transaction: EthereumTransaction): Promise<any>
```

### ethGasPrice

<Warning>
  Deprecated: Use `portal.request({ method: 'eth_gasPrice', ... })` instead.
</Warning>

```typescript theme={null}
public async ethGasPrice(chainId: string): Promise<string>
```

### ethGetBalance

<Warning>
  Deprecated: Use `portal.request({ method: 'eth_getBalance', ... })` instead.
</Warning>

```typescript theme={null}
public async ethGetBalance(chainId: string): Promise<string>
```

### ethSendTransaction

<Warning>
  Deprecated: Use `portal.request({ method: 'eth_sendTransaction', ... })` instead.
</Warning>

```typescript theme={null}
public async ethSendTransaction(chainId: string, transaction: EthereumTransaction): Promise<string>
```

### ethSignTransaction

<Warning>
  Deprecated: Use `portal.request({ method: 'eth_signTransaction', ... })` instead.
</Warning>

```typescript theme={null}
public async ethSignTransaction(chainId: string, transaction: EthereumTransaction): Promise<string>
```

### ethSignTypedData

<Warning>
  Deprecated: Use `portal.request({ method: 'eth_signTypedData', ... })` instead.
</Warning>

```typescript theme={null}
public async ethSignTypedData(chainId: string, data: TypedData): Promise<string>
```

### ethSignTypedDataV3

<Warning>
  Deprecated: Use `portal.request({ method: 'eth_signTypedData_v3', ... })` instead.
</Warning>

```typescript theme={null}
public async ethSignTypedDataV3(chainId: string, data: TypedData): Promise<string>
```

### ethSignTypedDataV4

<Warning>
  Deprecated: Use `portal.request({ method: 'eth_signTypedData_v4', ... })` instead.
</Warning>

```typescript theme={null}
public async ethSignTypedDataV4(chainId: string, data: TypedData): Promise<string>
```

### personalSign

<Warning>
  Deprecated: Use `portal.request({ method: 'personal_sign', ... })` instead.
</Warning>

```typescript theme={null}
public async personalSign(chainId: string, message: string): Promise<string>
```

### getBalances

<Warning>Deprecated: Use `portal.getAssets()` instead.</Warning>

```typescript theme={null}
public async getBalances(chainId: string): Promise<Balance[]>
```

### getNFTs

<Warning>Deprecated: Use `portal.getNFTAssets()` instead.</Warning>

```typescript theme={null}
public async getNFTs(chainId: string): Promise<NFT[]>
```

### simulateTransaction

<Warning>Deprecated: Use `portal.evaluateTransaction()` instead.</Warning>

```typescript theme={null}
public async simulateTransaction(
  chainId: string,
  transaction: SimulateTransactionParam
): Promise<SimulatedTransaction>
```

***
