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

# iOS (Swift) - Wallet

> Working with Particle Wallet within iOS applications.

## Particle Wallet for iOS

Particle Wallet for iOS is a standard interface and infrastructure for interacting with both Web2-based and Web3-based wallets, working directly with Particle Connect and Particle Auth. In essence, Particle Wallet provides a UI to send, swap, and purchase cryptocurrency, cross-compatible with multiple different account origins, primarily powered by either Particle Auth (for social logins) or Particle Connect (aggregating both social logins and external Web3 wallets).

A rundown on getting started and utilizing the Particle Wallet iOS SDK **is detailed below**.

***

## Getting Started

Configuration and implementation of Particle Wallet within iOS applications is relatively straightforward, although there are several prerequisites to ensure you avoid potential compatibility issues. These are as follows.

### Prerequisites

* Xcode **15.0** or later.
* CocoaPods **1.14.3** or higher.
* Your project must target these platform versions or later:
  * iOS **14**.

### Configuration

To begin the initialization process, you'll need to head over to the [Particle dashboard](https://dashboard.particle.network) to create a project alongside a corresponding application.

These will control specific customizations, statistics, etc. for your particular instance of Particle's Wallet-as-a-Service. After creating an application, you'll need to retrieve three key values to use later: `projectId`, `clientKey`, and `appId` later.

<Note>
  Find a full rundown of the process in the [dashboard guide](/social-logins/dashboard).
</Note>

### Installation

Now that you've created a project and an application within the [Particle dashboard](https://dashboard.particle.network), you'll need to go ahead and install the Particle Wallet SDK using CocoaPods (assuming you meet the minimum version requirements).

1. If you don't already have a Podfile, create one from the root of your project directory with:

   ```shell Terminal theme={null}
   pod init
   ```

2. Within the newly created Podfile, add the `ParticleWalletAPI` and `ParticleWalletGUI` pod.

   ```ruby Podfile theme={null}
   pod 'ParticleWalletAPI'
   pod 'ParticleWalletGUI'
   pod 'ParticleWalletConnect'
   ```

3. Install the pods, then open your corresponding .xcworkspace file to see the project in Xcode.

   ```shell Terminal  theme={null}
   pod install --repo-update
   open your-project.xcworkspace
   ```

4. From there, you'll need to configure the scheme URL itself; select your application target within the "Info" section, add a URL type, and include the scheme. **This scheme should be `pn` added to your `appId`.**

For example, if your `appId` is `63bfa427-cf5f-4742-9ff1-e8f5a1b9828f`, then the scheme URL would be `pn63bfa427-cf5f-4742-9ff1-e8f5a1b9828f` --simply adding `pn` to the beginning of the `appId`.

With the scheme URL configured, you'll also need to head into `info.plist` and add `LSApplicationQueriesSchemes` according to your specific utilization of Web3 wallets (not Particle Auth, but independent wallet adapters). An example of this can be seen below (each of these is optional and dependent upon your given implementation)

```xml Info.plist theme={null}
<key>LSApplicationQueriesSchemes</key>
<array>
<string>metamask</string>
<string>phantom</string>
<string>bitkeep</string>
<string>imtokenv2</string>
<string>rainbow</string>
<string>trust</string>
<string>zerion</string>
<string>mathwallet</string>
<string>oneinch</string>
<string>awallet</string>
<string>okex</string>
<string>bnc</string>
</array>
<key>NSPhotoLibraryUsageDescription</key>
<string>We need access in order to open photos of barcodes</string>
<key>NSCameraUsageDescription</key>
<string>We use the camera to scan barcodes</string>
<key>NSFaceIDUsageDescription</key>
<string>We use Face ID for secure access to the app.</string>
```

#### Podfile Configuration

Additionally, you'll need to ensure that your resulting Podfile is properly configured, as in the example below.

```ruby Podfile theme={null}
post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
    end
  end
end
```

And if you're using `ParticleWalletGUI` (which is optional if you're using a custom interface), then you'll also need to include the following:

```ruby Podfile theme={null}
pod 'SkeletonView', :git => 'https://github.com/SunZhiC/SkeletonView.git', :branch => 'main'
```

## Examples of Utilization, API

### Get Price

Beginning with `ParticleWalletAPI`, you can use Particle Wallet to directly call data API methods and retrieve information that may be relevant to the underlying account and wallet. One of these methods includes `getPrice` on either `ParticleWalletAPI.getSolanaService` or `ParticleWalletAPI.getEvmService`. `getPrice` is used for the retrieval of the real-time price of tokens defined within the methods first parameter, `addresses` (in which the native token is `"native"`), denominated in currencies listed within `currencies`. E.g.:

| Field        | Type       | Description                                                       |
| ------------ | ---------- | ----------------------------------------------------------------- |
| `addresses`  | `[String]` | The tokens's addresses, for native token, you can pass `"native"` |
| `currencies` | `[String]` | The price unity, such as `"usd"`                                  |

```swift theme={null}
let addresses: [String] = ["native"]
let currencies: [String] = ["usd"]
let tokenPrices = try await ParticleWalletAPI.getSolanaService().getPrice(by: addresses, currencies: currencies).value

let addresses: [String] = ["native"]
let currencies: [String] = ["usd"]
let tokenPrices = try await ParticleWalletAPI.getEvmService().getPrice(by: addresses, currencies: currencies).value
```

### Tokens by Address

`getTokensAndNFTs` alongside `getTokensAndNFTsFromDB` (returns from database without RPC calls) return a list of ERC20/721/SPL tokens associated with a given address. This can be called on either `ParticleWalletAPI.getSolanaService` or `ParticleWalletAPI.getEvmService`, both taking a singular parameter (`address`), dictating the specific account to be queried. E.g.:

```swift theme={null}
let address: String = ""
let tokenResult = try await ParticleWalletAPI.getSolanaService().getTokensAndNFTs(by: address).value

let tokenResult = try await ParticleWalletAPI.getSolanaService().getTokensAndNFTsFromDB(by: address).value

let address: String = ""
let tokenResult = try await ParticleWalletAPI.getEvmService().getTokensAndNFTs(by: address).value

let tokenResult = try await ParticleWalletAPI.getEvmService().getTokensAndNFTsFromDB(by: address).value
```

### Transaction History by Address

Another solid example of utilizing `ParticleWalletAPI` is the retrieval of transaction history by address. Either `getTransactions` or `getTransactionsFromDB` (returns from database without RPC calls) will return a list of transactions associated with a given address. This can be called on either `ParticleWalletAPI.getSolanaService` or `ParticleWalletAPI.getEvmService`. For `getEvmService`, you'll only need to pass in a given targeted `address`, otherwise for `getSolanaService`, you have the option of passing additional parameters such as `beforeSignature`, `untilSignature`, and `limit`. E.g.:

```swift theme={null}
let address: String = ""
let result = try await ParticleWalletAPI.getSolanaService().getTransactions(by: address, beforeSignature: nil, untilSignature: nil, limit: 1000).value

let result = try await ParticleWalletAPI.getSolanaService().getTransactionsFromDB(by: address, beforeSignature: nil, untilSignature: nil, limit: 1000).value

let address: String = ""
let result = try await ParticleWalletAPI.getEvmService().getTransactions(by: address).value

let result = try await ParticleWalletAPI.getEvmService().getTransactionsFromDB(by: address).value
```

### Create Transaction

`ParticleWalletAPI.createTransaction`facilitates the construction of a transaction object derived from the standard from, to, amount (value), and data fields. This transaction, once constructed with `ParticleWalletAPI.createTransaction`, can be passed for in-UI proposal with `auth.sendTransaction` or `adapter.signAndSendTransaction`. Specifically, eight key parameters are available within `ParticleWalletAPI.getEvmService().createTransaction`:

| Field            | Type              | Description                                                                                                                                                                                             |
| ---------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `from`           | `String`          | The user's public address, which to sign the transaction.                                                                                                                                               |
| `to`             | `String?`         | If you send a erc20, erc721, erc1155 or interact with a contract, this is the contract address, if you send native, this is receiver address, if you want to deploy a contract, this to should be `nil` |
| `value`          | `String?`         | Native value, default is nil, expressed as a hex string.                                                                                                                                                |
| `data`           | `String`          | If you send a erc20, erc721, erc1155 or interact with a contract, this is the data field, if you send native, this should be `0x`, default value is `0x`                                                |
| `contractParams` | `ContractParams?` | You can use this object to describe a write contract function                                                                                                                                           |
| `type`           | `String`          | Default is 0x2. Support EIP1559, you can ignore this parameter                                                                                                                                          |
| `gasFeeLevel`    | `gasFeeLevel`     | The specific gas fee level to be used. This can be either `.low`, `.medium`, `.high`, default is `.medium`                                                                                              |
| `action`         | `Action`          | Transaction execution mechanism. This can be either `.normal`, `.cancel`, `.speedUp`, default is `.normal`, which means send a new transaction                                                          |

<CodeGroup>
  ```swift Send native theme={null}
  let sender = auth.evm.getAddress() ?? ""
  let receiver = "0xAC6d81182998EA5c196a4424EA6AB250C7eb175b"
  // Send 0.0001 native tokens, need convert to the minimal unit.
  let amount = BDouble(0.0001 * pow(10, 18)).rounded()

  let transaction = try await ParticleWalletAPI.getEvmService().createTransaction(from: sender, to: receiver, value: amount.toHexString()).value
  let signature = try await auth.evm.sendTransaction(transaction, chainInfo: nil)
  ```

  ```swift Send erc20 token theme={null}
  let from = auth.evm.getAddress() ?? ""
  // Send 0.0001 ERC20 token, need convert to the minimal unit, suppose the token decimals is 18.
  let amount = BDouble(0.0001 * pow(10, 18)).rounded()
  // The ERC20 token contract address.
  let contractAddress = "0xa36085F69e2889c224210F603D836748e7dC0088"
  // This is receiver address.
  let receiver = "0xAC6d81182998EA5c196a4424EA6AB250C7eb175b"

  let contractParams = ContractParams.erc20Transfer(contractAddress: contractAddress, to: receiver, amount: amount)
  // Note the to address is the token contract address, not receiver address.
  let transaction = try await ParticleWalletAPI.getEvmService().createTransaction(from: from, to: contractAddress, value: nil, contractParams: contractParams).value
  let signature = auth.evm.sendTransaction(transaction, chainInfo: nil)
  ```

  ```swift Send ERC721 NFT theme={null}
  let from = auth.evm.getAddress() ?? ""
  // This is your NFT contract address
  let contractAddress = "0xD18e451c11A6852Fb92291Dc59bE35a59d143836"
  // This is the receiver address
  let receiver = "0xAC6d81182998EA5c196a4424EA6AB250C7eb175b"
  // Your ERC721 NFT token ID
  let tokenId = "2302"

  let contractParams = ContractParams.erc721SafeTransferFrom(contractAddress: contractAddress, from: from, to: receiver, tokenId: tokenId)
  // Note the to address is the NFT contract address, not receiver address.
  let transaction = ParticleWalletAPI.getEvmService().createTransaction(from: from, to: contractAddress, value: nil, contractParams: contractParams).value
  let signature = try await auth.evm.sendTransaction(transaction, chainInfo: nil)
  ```

  ```swift Text send erc1155 NFT theme={null}
  let from = auth.evm.getAddress() ?? ""
  // This is your NFT contract address
  let contractAddress = "0xD18e451c11A6852Fb92291Dc59bE35a59d143836"
  // This is the receiver address
  let receiver = "0xAC6d81182998EA5c196a4424EA6AB250C7eb175b"
  // Your ERC721 NFT token ID
  let tokenId = "2302"
  // Number of ERC1155 tokens to send
  let tokenAmount: BInt = 10

  let contractParams = ContractParams.erc1155SafeTransferFrom(contractAddress: contractAddress, from: from, to: receiver, id: tokenId, amount: tokenAmount, data: "0x")
  // Note the to address is the NFT contract address, not receiver address.
  let transaction = ParticleWalletAPI.getEvmService().createTransaction(from: from, to: contractAddress, value: nil, contractParams: contractParams).value
  let signature = try await auth.evm.sendTransaction(transaction, chainInfo: nil)
  ```

  ```swift Text deploy contract theme={null}
  let data = getContractData()
  let from = auth.evm.getAddress() ?? ""

  let transacion = try await ParticleWalletAPI.getEvmService().createTransaction(from: from, to: nil, data: data).value
  let signature = try await auth.evm.sendTransaction(transaction, chainInfo: nil)
  ```
</CodeGroup>

### Contract Interaction

#### Read Contract

Specifically, four key parameters are available within `ParticleWalletAPI.getEvmService().readContract`:

| Field             | Type          | Description                                                                 |
| ----------------- | ------------- | --------------------------------------------------------------------------- |
| `contractAddress` | `String`      | The contract address.                                                       |
| `methodName`      | `String`      | The method's name in the contract.                                          |
| `params`          | `[Encodable]` | The parameters of the method, each parameter requires a hexadecimal string. |
| `abiJsonString`   | `String?`     | (Optional) The ABI JSON string for the method.                              |

Here is a abiJsonString example.

```swift theme={null}
let abiJsonString = "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"quantity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"

```

```swift theme={null}
let params = ContractParams.customAbiEncodeFunctionCall(
  contractAddress: "0xd000f000aa1f8accbd5815056ea32a54777b2fc4",
  methodName: "balanceOf",
  params: ["0xBbc1CA8776EfDeC12C75e218C64e96ce52aC6671"],
  abiJsonString: nil)
let result = try await ParticleWalletAPI.getEvmService().readContract(contractParams: params).value
```

#### Write Contract

Specifically, four five parameters are available within `ParticleWalletAPI.getEvmService().writeContract`:

The first four parameters are the same as readContract.

| Field  | Type     | Description                                               |
| ------ | -------- | --------------------------------------------------------- |
| `from` | `String` | The user's public address, which to sign the transaction. |

```swift theme={null}
let params = ContractParams.customAbiEncodeFunctionCall(
  contractAddress: "0xd000f000aa1f8accbd5815056ea32a54777b2fc4",
  methodName: "mint",
  params: ["0x1"],
  abiJsonString: nil)
let from = auth.evm.getAddress()
let result = try await ParticleWalletAPI.getEvmService().writeContract(contractParams: params, from: from).value

```

## Examples of Utilization, Wallet

In addition to `ParticleWalletAPI`, you can also use `ParticleWalletGUI` as the primary means of programmatically configuring and interacting with Particle Wallet. To begin, `ParticleWalletGUI` relies on WalletConnect through Particle Connect to enable usage of external Web3 wallet (such as Metamask or Phantom) within Particle Wallet.

```swift theme={null}
ParticleWalletConnect.initialize(
            WalletMetaData(name: "Particle Wallet",
                           icon: URL(string: "https://connect.particle.network/icons/512.png")!,
                           url: URL(string: "https://connect.particle.network/")!,
                           description: "Particle Connect is a decentralized wallet connection protocol that makes it easy for users to connect their wallets to your DApp.", redirectUniversalLink: nil)
        )
```

### Custom Wallet UI

`ParticleWalletGUI` is drived by wallet adapters; after initializing the SDK, you'll be able to retrieve all relevant adapters through `ParticleConnect.getAdapters`, which can be plugged into `ParticleWalletGUI.setAdapters` to initiate the custom wallet interface, as is shown below.

```swift theme={null}
let adapters = ParticleConnect.getAdapters()
ParticleWalletGUI.setAdapters(adapters)
```

With `ParticleWalletGUI`, one of the primary functions is configuring the wallet interface for your specific application. This is managed through numerous methods, all of which toggle different interface components, enabling deep customization. These methods include:

* `setSwapDisabled`, whether or not the "Swap" functionality is displayed within the interface. This takes one parameter, either `true` or `false`, with the default being `false`.
* `setPayDisabled`, whether or not the "Buy" functionality is displayed within the interface. This takes one parameter, either `true` or `false`, with the default being `false`.
* `setBridgeDisabled`, whether or not the "Bridge" functionality is displayed within the interface. This takes one parameter, either `true` or `false`, with the default being `false`.
* `setSupportWalletConnect`, controls the visibility of the WalletConnect feature within the interface. It accepts a Boolean parameter, `true` or `false`, and is set to `true` by default.
* `setSupportDappBrowser`, determines whether the DApp browser is available on the wallet page. It takes a Boolean parameter, `true` or `false`, with `true` as the default value
* `setShowTestNetwork`, decides if the test network should be shown or hidden. This accepts a Boolean value, `true` or `false`, defaulting to `false`
* `setSupportChain`, specifies the blockchain networks supported by Particle Connect. Accepts an array of chains.
* `setShowManageWallet`, toggles the visibility of the manage wallet page. It takes a Boolean value, `true` or `false`, with `true` as the default.
* `setShowLanguageSetting`, controls the display of language settings in the settings page. It accepts a Boolean value, `true` or `false`, with the default being `false`.
* `setShowAppearanceSetting`, decides whether the appearance settings are shown in the settings page. It takes a Boolean value, `true` or `false`, defaulting to `false`.
* `setSupportAddToken`, toggles the option to add tokens, with `true` showing the add token button and `false` hiding it. The default value is `true`.
* `setDisplayTokenAddresses`, sets specific token addresses to be displayed in the wallet; other tokens won't be displayed. It accepts an array of token addresses or `nil` to reset.
* `setDisplayNFTContractAddresses`, configures the wallet to display NFTs exclusively from specified NFT contract addresses. It accepts an array of addresses or `nil` to reset.
* `setPriorityTokenAddresses`, sets priority token addresses that will appear at the top of the list. It accepts an array of token addresses or `nil` to reset (reflected on the wallet page's token list and token send page).
* `setPriorityNFTContractAddresses`, specifies NFT contract addresses for priority display at the top of the list. It takes an array of NFT contract addresses.
* `setCustomTokenAddresses`, allows for the specification of custom token addresses to be displayed in the token list, unless hidden by the user. This method is overridden if `setDisplayTokenAddresses` is used (reflected on the wallet page token list and token send select page).
* `loadCustomUIJsonString`, sets a custom UI by passing a JSON string.
* `setCustomWalletName`, configures a custom name and icon for the wallet, supported for the `WalletType` of `particle` and `authcore`. It requires specifying the wallet type, name, and icon URL.
* `setCustomLocalizable`, allows for setting custom localizable strings

E.g.:

```swift theme={null}
ParticleWalletGUI.setPayDisabled(false)

ParticleWalletGUI.setSwapDisabled(false)

ParticleWalletGUI.setSupportWalletConnect(false)

ParticleWalletGUI.setSupportDappBrowser(false)

ParticleWalletGUI.setShowTestNetwork(false)

ParticleWalletGUI.setSupportChain([.bsc, .arbitrum, .harmony])

ParticleWalletGUI.setShowManageWallet(true)

ParticleWalletGUI.setShowLanguageSetting(true)

ParticleWalletGUI.setShowAppearanceSetting(true)

ParticleWalletGUI.setSupportAddToken(false)

ParticleWalletGUI.setDisplayTokenAddresses([tokenAddress])

ParticleWalletGUI.([nftContractAddress])

ParticleWalletGUI.setPriorityTokenAddresses([tokenAddress])

ParticleWalletGUI.setPriorityNFTContractAddresses([nftContractAddress])

ParticleWalletGUI.setCustomTokenAddresses([tokenAddress])


let jsonString = ""
try! ParticleWalletGUI.loadCustomUIJsonString(jsonString)

ConnectManager.setCustomWalletName(walletType: .particle, name: .init(name: "Wallet Name", icon: "Icon URL"))

let customLocalizable = [Language.en: ["network fee": "Service Fee",
        "particle auth wallet": "Your Wallet Name"]]
ParticleWalletGUI.setCustomLocalizable(customLocalizable)
```

Additionally, if you'd like to support the WalletConnect feature within the wallet itself, you'll need to open `AppDelegate.swift` and paste in the below snippet:

```swift theme={null}
// In AppDelegate.swift, under application(_:open:options:)
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
  if ParticleWalletGUI.handleWalletConnectUrl(url, withScheme: "particlewallet") {
    return true
  } else {
    return ParticleConnect.handleUrl(url)
  }
}
```

### Switch Wallet

Before opening the UI, if you'd like to switch the `WalletType` (`walletType` in this case) reflected and used within the wallet itself, you can use `ParticleWalletGUI.switchWallet`, passing in the specific `walletType` (see for more information) and targeted user address, `publicAddress`:

| Field           | Type         | Description                                            |
| --------------- | ------------ | ------------------------------------------------------ |
| `walletType`    | `WalletType` | The `walletType` is used to identify a unique user.    |
| `publicAddress` | `String`     | The `publicAddress` is used to identify a unique user. |

```swift theme={null}
ParticleWalletGUI.switchWallet(walletType: .metaMask, publicAddress: "YOUR_PUBLIC_ADDRESS")
```

### Open Wallet

To programmatically open the wallet interface, you'll need to use `PNRouter`. This will act as the primary mechanism for opening and managing specific pages of Particle Wallet. In this case, you can call `PNRouter.navigatorWallet` to throw the main page within Particle Wallet. E.g.:

```swift theme={null}
PNRouter.navigatorWallet()
```

### TabViewController Embed

If you'd like to embed the wallet interface within your `tabViewController`, you'll need to call `PNRouter.extractWallet`, passing in optional parameters such as `hiddenBackButton` for configuration before extraction. This will return a navigation controller, which can then be used within `tabViewController.viewControllers`. E.g.:

```swift theme={null}
let walletVc = PNRouter.extractWallet(hiddenBackButton: true)

tabViewController.viewControllers = [otherVc1, walletVc, otherVc2]
```

### Open Send Token

To open the page coordinating sending a token (token referring to ERC20/SPL tokens), you can call `PNRouter.navigatorTokenSend`; if you're sending a specific ERC20/SPL token, you can also pass in `tokenSendConfig`, a `TokenSendConfig` object containing the following:

| Field          | Type      | Description                                                           |
| -------------- | --------- | --------------------------------------------------------------------- |
| `tokenAddress` | `String?` | The address of the token to be sent, default is the native token      |
| `toAddress`    | `String?` | (Optional) The recipient's address                                    |
| `amount`       | `BInt?`   | (Optional) The amount to be sent, should pass the minimal unit amount |

```swift theme={null}
let tokenSendConfig = TokenSendConfig(tokenAddress: nil, toAddress: nil, amount: nil)
PNRouter.navigatorTokenSend(tokenSendConfig: tokenSendConfig)
```

### Open Receive Token

A page displaying both the user's address and an associated QR code can be opened through `PNRouter.navigatorTokenReceive`. If you'd like to generate a specific QR code for a token, placing the token logo at the center of the QR code, you can pass in `tokenReceiveConfig`, a `TokenReceiveConfig` object containing the `tokenAddress` of the token in question. E.g.:

| Field          | Type      | Description                                           |
| -------------- | --------- | ----------------------------------------------------- |
| `tokenAddress` | `String?` | The address of the token, default is the native token |

```swift theme={null}
PNRouter.navigatorTokenReceive()

let config = TokenReceiveConfig(tokenAddress: "")
PNRouter.navigatorTokenReceive(tokenReceiveConfig: config)
```

### Open Transaction Records

Transaction records (history) for both ERC20/721 tokens can be programmatically opened through `PNRouter.navigatorTokenTransactionRecords`, passing in `tokenTransactionRecordsConfig`, a `TokenTransactionRecordsConfig` object taking the `tokenAddress` of a specific token to search for.

| Field          | Type     | Description                                           |
| -------------- | -------- | ----------------------------------------------------- |
| `tokenAddress` | `String` | The address of the token, default is the native token |

```swift theme={null}
let tokenTransactionRecordsConfig = TokenTransactionRecordsConfig(tokenAddress: tokenAddress)
PNRouter.navigatorTokenTransactionRecords(tokenTransactionRecordsConfig: tokenTransactionRecordsConfig)

PNRouter.navigatorTokenTransactionRecords()
```

### Open Send NFT

If you'd like to force the NFT sending menu to open, you can use `PNRouter.navigatorNFTSend`, passing in `nftSendConfig`, a `NFTSendConfig` object that takes the following parameters:

| Field       | Type      | Description                                                                                        |
| ----------- | --------- | -------------------------------------------------------------------------------------------------- |
| `address`   | `String`  | The contract address of the NFT being sent.                                                        |
| `toAddress` | `String?` | The recipient's address.                                                                           |
| `tokenId`   | `String?` | The specific token ID of the NFT you'd like to send (belonging to the collection under `address`). |
| `amount`    | `BInt`?   | The volume of NFTs that you'd like to send, for NFT 721, the amount should always be 1.            |

```swift theme={null}
let nftContractAddress = ""
let receiverAddress = ""
let tokenId = ""
let amount = BInt(1)
let config = NFTSendConfig(address: nftContractAddress, toAddress: receiverAddress, tokenId: tokenId, amount: amount)
PNRouter.navigatorNFTSend(nftSendConfig: config)
```

### Open NFT Details

Particle Wallet also natively supports viewing specific NFTs (traits, description, image, etc.). Forcing this menu programmatically can happen through `PNRouter.navigatorNFTDetails`, passing in `nftDetailsConfig`, a `NFTDetailsConfig` object that takes the `address` of the NFT and the specific `tokenId`; for Solana. `tokenId` can be left blank. E.g.:

| Field     | Type      | Description                                                                                        |
| --------- | --------- | -------------------------------------------------------------------------------------------------- |
| `address` | `String`  | The contract address of the NFT being sent.                                                        |
| `tokenId` | `String?` | The specific token ID of the NFT you'd like to send (belonging to the collection under `address`). |

```swift theme={null}
let address = ""
let tokenId = ""
let config = NFTDetailsConfig(address: address, tokenId: tokenId)
PNRouter.navigatorNFTDetails(nftDetailsConfig: config)
```

### Open Buy Crypto

Particle Wallet also has a native onramp aggregator, allowing users to bring fiat on-chain through various onramp providers. Opening this programmatically can happen through `PNRouter.navigatorBuy`, passing in several optional parameters to customize the values used within the onramp. Upon calling, this will throw a popup or total redirect to a corresponding configuration of [https://ramp.particle.network](https://ramp.particle.network).

The specific parameters that can be used within `PNRouter.navigatorBuy` are listed below:

| Field           | Type                    | Description                                                                                   |
| --------------- | ----------------------- | --------------------------------------------------------------------------------------------- |
| `walletAddress` | `String?`               | (Optional) the wallet address to receive the cryptocurrency, default is current user address. |
| `network`       | `ChainInfo?`            | (Optional) The chainInfo, default is current chainInfo.                                       |
| `cryptoCoin`    | `String?`               | (Optional) Cryptocurrency denomination. default is current chain native token symbol.         |
| `fiatAmt`       | `int?`                  | (Optional) The amount of fiat to be automatically filled in as the purchase volume.           |
| `fiatCoin`      | `String?`               | (Optional) Fiat currency denomination. Default is current fiat coin.                          |
| `fixFiatCoin`   | `Bool`                  | (Optional) Lock selection of fiat coin in the buy menu, default is false.                     |
| `fixFiatAmt`    | `bool`                  | (Optional) Lock selection of fiat amount in the buy menu, default is false.                   |
| `fixCryptoCoin` | `bool`                  | (Optional) Lock selection of crypto coin in the buy menu, default is false.                   |
| `theme`         | `String`                | (Optional) The buy page theme, `dark` or `light`, default is current appearance.              |
| `language`      | `Language?`             | (Optional) The buy page lanuage, default is current language.                                 |
| `modalStyle`    | `IOSModalPresentStyle?` | (Optional) Control iOS presentation style, default is `pageSheet`.                            |

```swift theme={null}
let buyCryptoConfig = BuyCryptoConfig(walletAddress: "YOUR WALLET ADDRESS",
                                              network: .ethereum,
                                              cryptoCoin: "ETH",
                                              fiatAmt: 1000,
                                              fiatCoin: "USD",
                                              fixFiatCoin: false,
                                              fixFiatAmt: false,
                                              fixCryptoCoin: false,
                                              theme: "light",
                                              language: "en-US")

PNRouter.navigatorBuy(buyCryptoConfig: buyCryptoConfig)
```

### Open Swap

Additionally, Particle Wallet has a built-in swap functionality (retrieves multiple quotes from different providers such as 1inch, iZUMi, etc., routing the swap through the best one) for Mainnets (Solana and EVM). The Swap menu can be opened via `PNRouter.navigatorSwap`, which alone will open the default swap menu without values filled in, although you can pass in a `SwapConfig` object, containing:

* `fromTokenAddress`, the token to swap from.
* `toTokenAddress`, the token to swap to.
* `fromTokenAmount`, the amount of `fromTokenAddress` to be automatically reflected within the UI.

```swift theme={null}
PNRouter.navigatorSwap()

let config = SwapConfig(fromTokenAddress: nil,
                toTokenAddress: nil,
                fromTokenAmount: nil)
PNRouter.navigatorSwap(swapConfig: config)
```

### Open DApp Browser Page

Finally, Particle Wallet also includes a dApp Browser, allowing users to open different dApps (web apps), automatically connecting with the account loaded into the instance of Particle Wallet. This enables account usage across any dApp. This can be programmatically opened through `PNRouter.navigatorDappBrowser`, taking one parameter, `url`, which will dictate the site opened. E.g.:

```swift theme={null}
if let url = URL(string: "app.uniswap.org") {
  PNRouter.navigatorDappBrowser(url: url)
}
```

### (Optional) Custom WalletConnect Projcet ID

```swift theme={null}
ParticleWalletConnect.setWalletConnectV2ProjectId("WalletConnect project ID")
```
