> ## 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.

# Flutter (Dart) - Auth

> Interacting with Particle Auth within applications made using Flutter.

## Particle Auth for Flutter

The **Particle Auth Flutter SDK** enables full-stack integration of Particle Auth into applications built on Flutter. This includes everything from the initial configuration of Particle's Wallet-as-a-Service to specific interactions.

In this case, Flutter can be leveraged in either Android or iOS environments, both to the same degree. This is done primarily through Dart.

<Note>Platform-specific configuration instructions, alongside examples of utilization, can be found below.</Note>

## Getting Started

Interaction with the Particle Auth Flutter SDK follows a standard approach consistent with other Particle Auth SDKs, though notable differences exist within the configuration process.

<Tip>
  The configuration process for this SDK varies significantly depending on whether you're using Flutter for Android or iOS.
</Tip>

To begin, you'll need to head over to the [Particle dashboard](https://dashboard.particle.network) and retrieve your `projectId`, `clientKey`, and `appId`.

<Note>
  Find a full rundown in the [Dashboard Guide](/social-logins/dashboard)
</Note>

### Adding the Particle Auth Flutter SDK to your application

Additionally, regardless of platform, you'll need to begin by adding `particle_auth_core` to your **Flutter** application; this is a requirement before moving onto platform-specific configuration.

```shell Terminal theme={null}
flutter pub add particle_auth_core
```

### Android configuration

#### Prerequisites

* minSdkVersion **23** or higher.
* compileSdkVersion, targetSdkVersion **34** or higher.
* JavaVersion **17**.
* [Jetpack (AndroidX)](https://developer.android.com/jetpack/androidx/migrate?authuser=0).
* Android Gradle Plugin Version : 8.5.1 or higher.
* Gradle Version : 8.9 or higher.

If you're building an Android application with Flutter, follow the steps below to configure Particle Auth. To begin, you'll need to go ahead and open your `build.gradle` file, often found at the following file path: `${project name}/android/app/build.gradle`

Within your `build.gradle` file, you'll need to add four new lines to ensure Particle Auth runs appropriately:

1. `minSdkVersion`, which in most cases will be set to `23`.
2. `manifestPlaceholders["PN_PROJECT_ID"]`, the `projectId` previously retrieved from the Particle dashboard.
3. `manifestPlaceholders["PN_PROJECT_CLIENT_KEY"]`, the `clientKey` previously retrieved from the Particle dashboard.
4. `manifestPlaceholders["PN_APP_ID"]`, the `appId` previously retrieved from the Particle dashboard.

```groovy build.gradle theme={null}
// Example
defaultConfig {
  applicationId "com.example.particle_auth_test"

  minSdkVersion 23 // Required by Particle Auth
  targetSdkVersion flutter.targetSdkVersion
  versionCode flutterVersionCode.toInteger()
  versionName flutterVersionName

  manifestPlaceholders["PN_PROJECT_ID"] = "EXAMPLE"
  manifestPlaceholders["PN_PROJECT_CLIENT_KEY"] = "EXAMPLE"
  manifestPlaceholders["PN_APP_ID"] = "EXAMPLE"
}
```

Staying within your `build.gradle` file, you'll need to ensure that you're using version 17 of Java in both `compileOptions` and `kotlinOptions`, alongside enabling `dataBinding`.

```groovy build.gradle theme={null}
// Example
compileOptions {
  sourceCompatibility JavaVersion.VERSION_17
  targetCompatibility JavaVersion.VERSION_17
}

kotlinOptions {
  jvmTarget = JavaVersion.VERSION_17.toString()
}

dataBinding {
  enabled = true
}
```

Finally, for dependency management, within `build.gradle` you'll need to ensure that the `repositories` object in both `buildscript` and `allprojects` has `maven { setUrl("https://jitpack.io") }` present, such as is shown below.

```groovy build.gradle theme={null}
// Example
buildscript {
  ...
  repositories {
      google()
      mavenCentral()
      maven { setUrl("https://jitpack.io") }  // Add this
  }

  dependencies {
      ...
  }
}


allprojects {
  repositories {
      google()
      mavenCentral()
      maven { setUrl("https://jitpack.io") }  // Add this
  }
}

...

```

***

### iOS configuration

If you're building an iOS application with Flutter, this also entails a unique and iOS-specific configuration process. Before beginning, ensure your project meets the following prerequisites:

* Xcode 15.0 or later.

* iOS 14 or later.

With these requirements set, you'll need to open an exported iOS project and find `apps/{project name}.xcworkspace`.

At the root of your Xcode project, create a new file, `ParticleNetwork-Info.plist`. Ensure this is marked under `Target Membership`.

Now, with a fresh `ParticleNetwork-Info.plist` file, go ahead and fill it in with the following:

```xml ParticleNetwork-Info.plist theme={null}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>PROJECT_UUID</key>
	<string>YOUR_PROJECT_UUID</string>
	<key>PROJECT_CLIENT_KEY</key>
	<string>YOUR_PROJECT_CLIENT_KEY</string>
	<key>PROJECT_APP_UUID</key>
	<string>YOUR_PROJECT_APP_UUID</string>
</dict>
</plist>
```

Similar to the Android configuration, you'll need to fill in `PROJECT_UUID` (`projectId`), `PROJECT_CLIENT_KEY`, and `PROJECT_APP_UUID` (`appId`) with the corresponding values retrieved from the [Particle dashboard](https://dashboard.particle.network).

To enable Face ID for your app, add a usage description to your `Info.plist` file by including the following code:

```xml Info.plist theme={null}
<key>NSFaceIDUsageDescription</key>
  <string>We use Face ID for secure access to the app.</string>
```

Finally, you'll need to edit your Podfile to ensure `particle_auth_core` is properly imported. Head over to the [linked guide](https://github.com/Particle-Network/particle-flutter/blob/master/particle-auth-core/example/ios/Podfile) to complete this, if you haven't already.

<Note>
  <p>Another important note before continuing.</p>
  <p>Our SDK is a static library (XCFramework). When using the Particle Auth Flutter SDK, you'll need to specify that you're using a static framework through the following:</p>

  <p>
    ```ruby 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
    ```
  </p>
</Note>

***

## Examples of utilization

### Initialization

Before using the full extent of the SDK, you'll need to initialize it with `init`, passing in the specific chain to which you intend to primarily onboard within Particle's Wallet-as-a-Service. This is represented as an object containing chain info (often derived from `ChainInfo.{Chain}`).

```dart theme={null}
// Set relevant project info, retrieved from https://dashboard.particle.network
ParticleInfo.set(projectId, clientKey);
// Initialize ParticleAuth and ParticleAuthCore.
ParticleBase.init(ChainInfo.Ethereum, env);
ParticleAuthCore.init()
```

### Connect

After installing, configuring, and initializing Particle Auth, initiate the login process by using `ParticleAuthCore.connect`. This triggers a social login prompt, and upon successful authentication, a user account is created, unlocking the full SDK functionality.

`ParticleAuthCore.connect` takes the following parameters:

| Field              | Type                     | Description                                                                                                                                                                                                                                                                         |
| ------------------ | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `loginType`        | `LoginType`              | The specific social login to be used. This can be either `.email`, `.phone`, `.google`, `.apple`, `.jwt`, `.facebook`, `.twitter`, `.discord`, `.github`, `.twitch`, `.microsoft` or `linkedin`.                                                                                    |
| `account`          | `String?`                | (Optional) When `type` is set to either `.email`, `.phone`, or `.jwt`, you can use the `account` parameter to pass in an expected email, phone number, or JWT. This is optional for the former two, but required for `.jwt`. If passing a phone number, it must be in E.164 format. |
| `prompt`           | `SocialLoginPrompt?`     | (Optional) Changes what the OAuth provider prompts a user to do; either `.none`, `.consent`, or `.select_account`. Only Google, Discord and Microsoft support it.                                                                                                                   |
| `loginPageConfig`  | `LoginPageConfig?`       | (Optional) Controls login UI customization: contains project name, icon and description.                                                                                                                                                                                            |
| `supportAuthTypes` | `List<SupportAuthType>?` | The methods of authentication visible on the authentication popup UI. By default, this will be exclusive to the chosen social login method, although by passing in additional types, you can expand the UI to include the ability to login with those as an alternative to type.    |

<Tip>You can use your existing user base (account system) or a custom authentication method with Particle Connect through JWT. Click [here](/social-logins/configuration/auth/jwt) to learn how to configure JWT.</Tip>

```dart theme={null}
// Google or other social login
final userInfo = await ParticleAuthCore.connect(LoginType.google, prompt: SocialLoginPrompt.select_account);

// Email or phone login, facilitated through Particle's UI
final userInfo = await ParticleAuthCore.connect(LoginType.email, supportAuthTypes: SupportAuthType.values, prompt: SocialLoginPrompt.select_account);

// Custom authentication via JWT
final userInfo = await ParticleAuthCore.connect(LoginType.jwt, account: jwt);

// Configuration of a custom email or phone login page, programmatically driving verification codes
final result = await ParticleAuthCore.sendEmailCode("user@example.com");
final result = await ParticleAuthCore.sendPhoneCode("+11234567890"); // Must be in E.164 format

// After a code is sent, the user should enter it within your UI, upon which you can use it for connection
final userInfo = await ParticleAuthCore.connectWithCode(email: "user@example.com", code: code);
final userInfo = await ParticleAuthCore.connectWithCode(phone: "+11234567890", code: code);
```

### Is Connected

There may be scenarios where it is important to know whether a current session (a user) is logged in with Particle Auth. This is achieved through `ParticleAuthCore.isConnected` (server-side check).

```dart theme={null}
final isConnected = await ParticleAuthCore.isConnected();
```

### Disconnect

To exit an existing session (logging a user out), call `ParticleAuthCore.disconnect`.

```dart theme={null}
final result = await ParticleAuthCore.disconnect();
```

### Get User Info

To retrieve an object containing detailed user information, call `ParticleAuthCore.getUserInfo`.

```dart theme={null}
final userInfo = await ParticleAuthCore.getUserInfo();
```

### Get Address

To retrieve the address, call `Evm.getAddress` or `Solana.getAddress`.

```dart theme={null}
final address = await Evm.getAddress();
final address = await Solana.getAddress();
```

### Sign Message (EIP191)

To request an EIP191 signature from a user's embedded wallet, you can use either the `Evm.personalSign` or `Evm.personalSignUnique` method.

If you need the same message to return a unique signature each time, use the `Evm.personalSignUnique` method. Otherwise, the `Evm.personalSign` method is generally recommended. On Solana, you can call `Solana.signMessage`, you can pass in a UTF-8/readable string.

| Field     | Type     | Description                                                                       |
| --------- | -------- | --------------------------------------------------------------------------------- |
| `message` | `String` | On Evm requires a hexadecimal string, on Solana, requires a UTF-8/readable string |

```dart theme={null}
final messageHex = "0x${StringUtils.toHexString("Hello Particle")}";
String signature = await Evm.personalSign(messageHex);
String signature = await Evm.personalSignUnique(messageHex);

const message = "Hello Particle";
final signature = await Solana.signMessage(message);
```

### Sign Transaction

This is a **Solana-specific** method for signing a transaction without sending it. Similar to message signing, this will prompt a signature in-UI with details about the transaction.

Programmatically, the proposed transaction should be formatted as a (converted to a) base58 string. Passing in an object directly will not work in this case.

| Field         | Type     | Description              |
| ------------- | -------- | ------------------------ |
| `transaction` | `String` | Requires a base58 string |

```dart theme={null}
final signature = await Solana.signTransaction(transaction);
```

### Sign All Transactions

Following the method above, you can use `Solana.signAllTransactions` to propose a collection of **Solana** transactions for signature, rather than just a single transaction.

| Field          | Type           | Description                           |
| -------------- | -------------- | ------------------------------------- |
| `transactions` | `List<String>` | Each element requires a base58 string |

```dart theme={null}
List<String> signatures = await Solana.signAllTransactions(transactions);
```

### Sign and Send Transaction

For more generalized transaction execution, `Evm.sendTransaction` and sendTransaction`and`Solana.signAndSendTransaction\` will be the primary methods used in virtually every scenario.

This will propose a signature (on both EVM and Solana) and then immediately push it to the network once confirmed.

| Field         | Type     | Description                                                               |
| ------------- | -------- | ------------------------------------------------------------------------- |
| `transaction` | `String` | On Evm requires a hexadecimal string, on Solana, requires a base58 string |

```dart theme={null}
final signature = await Evm.sendTransaction(transaction);
final signature = await Solana.signAndSendTransaction(transaction);
```

### Sign Typed Data V4 (EIP712)

To request an EIP712 signature from a user's embedded wallet, you can use the `Evm.signTypedData` or `Evm.signTypedDataUnique` method.

If you need the same message to return a unique signature each time, use the `Evm.signTypedDataUnique` method. Otherwise, the `Evm.signTypedData` method is generally recommended.

| Field     | Type     | Description                   |
| --------- | -------- | ----------------------------- |
| `message` | `String` | Requires a hexadecimal string |

```dart theme={null}
// your typed data is a json string
String typedDataHex = "0x${StringUtils.toHexString(typedData)}";

String signature = await Evm.signTypedData(typedDataHex);
String signature = await Evm.signTypedDataUnique(typedDataHex);
```

### Set Chain Info

To change the chain after it’s initially defined in `init`, you can use `ParticleBase.setChainInfo` for a synchronous update or `ParticleAuthCore.switchChain` for an asynchronous update, both typically using `ChainInfo.{Chain}`.

```dart theme={null}
await ParticleBase.setChainInfo(ChainInfo.Ethereum);

await ParticleAuthCore.switchChain(ChainInfo.Ethereum);
```

### Get Chain Info

To retrieve the currently selected (primary) chain in an active session, use `ParticleBase.getChainInfo`. This returns a `ChainInfo` object containing:

* `name`: The chain's name (e.g., Ethereum).
* `id`: The ID of the chain (e.g., 11155111).
* `network`: The specific network associated with the chain ID (e.g., Sepolia).

```dart theme={null}
final chainInfo = await ParticleBase.getChainInfo();
int id = chainInfo.id;
String name = chainInfo.name;
String network = chainInfo.network;
```

### Set Security Account Config

Another important component of integrating the Particle Auth SDK (Wallet-as-a-Service) is the (optional) security account requirements enforced upon application users.

For all Particle accounts, various security options are available, including:

* **Master Password**: A non-recoverable password required upon login.
* **Payment Password**: A PIN required for transaction signatures.

With the SDK, you can determine how often a user is prompted to configure their security settings. This control is facilitated by `ParticleBase.setSecurityAccountConfig`, where you pass in a `SecurityAccountConfig` object with two parameters:

| Field                                  | Type  | Description                                         |
| -------------------------------------- | ----- | --------------------------------------------------- |
| `promptSettingWhenSign`                | `int` | The security account config prompts (default is 1). |
| `promptMasterPasswordSettingWhenLogin` | `int` | The master password prompts (default is 0).         |

* `0` means a prompt is never shown requesting this setting.
* `1` means a prompt is shown only upon the first startup.
* `2` means a prompt is shown every time.
* `3` means force set payment password before sign.

```dart theme={null}
final config = SecurityAccountConfig(1, 2);
ParticleBase.setSecurityAccountConfig(config);
```

### Open Account and Security Page

Following the above, if you'd like to force the opening of account/security settings (in-UI), you can do so with `ParticleAuthCore.openAccountAndSecurity`.

```dart theme={null}
await ParticleAuthCore.openAccountAndSecurity();
```

### Has Master Password, Payment Password, Security Account

Similarly to the `isConnected` function covered prior, there are various scenarios in which knowing whether or not a user has specific security settings enabled may be useful.

In the case of the Particle Auth Flutter SDK, this can happen in one of two ways:

With the built-in `ParticleAuthCore.hasMasterPassword`, `ParticleAuthCore.hasPaymentPassword`, and `ParticleAuthCore.changeMasterPassword` methods.

```dart theme={null}
await ParticleAuthCore.hasMasterPassword();
await ParticleAuthCore.hasPaymentPassword();
await ParticleAuthCore.changeMasterPassword();
```

### Set Appearance

You can forcibly set a specific appearance within the UI using `ParticleBase.setAppearance`. By default, it will follow the current system setting.

| Field        | Type         | Description                                                                          |
| ------------ | ------------ | ------------------------------------------------------------------------------------ |
| `appearance` | `Appearance` | The specific appearance to be used. This can be either `.system`, `.dark`, `.light`. |

```dart theme={null}
// This is the default setting
ParticleBase.setAppearance(Appearance.system);
// Dark mode
ParticleBase.setAppearance(Appearance.dark);
// Light mode
ParticleBase.setAppearance(Appearance.light);
```

### Set and Get Language

You can forcibly set a specific language to be used within the UI using `ParticleBase.setLanguage`, with the retrieval of the currently active language facilitated by `ParticleBase.getLanguage`. By default, this is set to English.

| Field      | Type       | Description                                                                                       |
| ---------- | ---------- | ------------------------------------------------------------------------------------------------- |
| `language` | `Language` | The specific language to be used. This can be either `.en`, `.ja`, `.zh_hans`, `.zh_hant`, `.ko`. |

```dart theme={null}
ParticleBase.setLanguage(Language.en)

ParticleBase.getLanguage()
```

***

### Blind Sign Enable

Silently sign messages/transactions, this switch will work if the following conditions are met:

1. your account is connected with JWT
2. your account does not set payment password
3. SecurityAccountConfig.promptSettingWhenSign is 0, you can call `ParticleBase.setSecurityAccountConfig` to update its value.

```dart theme={null}
// Enable blind signing
ParticleAuthCore.setBlindEnable(enable);
// Retrieve a Boolean representing whether or not blind signing is enabled
final result = ParticleAuthCore.getBlindEnable();
```

***

### Filter Unsupported Countries (Phone Authentication)

If necessary, you can restrict specific countries from authenticating via phone number; upon entering a phone number originating from a country specified here, the login modal will block the user.

| Field         | Type           | Description                                                                                                    |
| ------------- | -------------- | -------------------------------------------------------------------------------------------------------------- |
| `isoCodeList` | `List<String>` | [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) code list, such as the US, the UK, etc. |

```dart theme={null}
List<String> isoCodeList = ['US', 'CA', 'GB'];
ParticleBase.setUnsupportCountries(isoCodeList);
```

***

## `EvmService` utilization examples

In addition to `ParticleAuthCore` for authentication and interaction with Particle's Wallet-as-a-Service, the Flutter SDK also includes a class, `EvmService`, for general interaction with EVM chains.

### Write Contract

`EvmService.writeContract` allows you to execute a write contract call defined by a specific method and set of parameters. This requires a corresponding ABI, contract address, and requester public address.

| Field             | Type           | Description                                                                 |
| ----------------- | -------------- | --------------------------------------------------------------------------- |
| `address`         | `String`       | The user's public address.                                                  |
| `contractAddress` | `String`       | The contract address.                                                       |
| `methodName`      | `String`       | The method name that defined in the contract, such as `mint`, `balanceOf`.  |
| `parameters`      | `List<Object>` | The parameters of this method.                                              |
| `abiJsonString`   | `String`       | The abi json string of this method.                                         |
| `gasFeeLevel`     | `GasFeeLevel`  | (Optional) The gas fee level, `high`, `medium` or `low`, default is `high`. |

```dart theme={null}
String contractAddress = "Your contract address";
String methodName = "Your method name"; // This is your contract method name, like balanceOf, mint.
List<Object> params = <Object>["0x1"]; // This is the method params, each parameter requires a hexadecimal string.

// ABI json string for the contract in question.
// For example,
// [{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"quantity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]
const abiJsonString = null;
final result = EvmService.writeContract(publicAddress, contractAddress, methodName, params, abiJsonString, gasFeeLevel: GasFeeLevel.high);
```

### Read Contract

`EvmService.readContract` allows you to execute a read-only contract call defined by a specific method and set of parameters. This requires a corresponding ABI, contract address, and requester public address.

| Field             | Type           | Description                                                                |
| ----------------- | -------------- | -------------------------------------------------------------------------- |
| `address`         | `String`       | The user's public address.                                                 |
| `contractAddress` | `String`       | The contract address.                                                      |
| `methodName`      | `String`       | The method name that defined in the contract, such as `mint`, `balanceOf`. |
| `parameters`      | `List<Object>` | The parameters of this method.                                             |
| `abiJsonString`   | `String`       | The abi json string of this method.                                        |

```dart theme={null}
String publicAddress = "your public address";
String contractAddress = "your contract address";
String methodName ="your method name"; // ex: balanceOf, mint
List<Object> parameters = <Object>["0x1"];  // This is the method params, each parameter requires a hexadecimal string.

// ex: [{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"}]
const abiJsonString = null;

final result = await EvmService.readContract(publicAddress, contractAddress, methodName, parameters, abiJsonString);
```

### Create Transaction

`EvmService.createTransaction` facilitates the construction of a transaction object derived from the standard `from`, `to` (`receiver` in this example), `amount` (`value`), and `data` fields. This transaction, once constructed with `EvmService.createTransaction`, can be passed for in-UI proposal with `ParticleAuthCore.sendTransaction`.

| Field         | Type          | Description                                                                                                                                   |
| ------------- | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `from`        | `String`      | The user's public address.                                                                                                                    |
| `data`        | `String`      | The transaction's data.                                                                                                                       |
| `value`       | `BigInt`      | The native amount.                                                                                                                            |
| `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. |
| `gasFeeLevel` | `GasFeeLevel` | (Optional) the gas fee level, `high`, `medium` or `low`, default is `high`.                                                                   |

```dart theme={null}
String from = "Your public address";
String receiver = "Receiver address"
String contractAddress = "Contract address"
BigInt amount = BigInt.from(1000000000000000);
String to = contractAddress;
final data =  await EvmService.erc20Transfer(contractAddress, receiver, amount);

final transaction = await EvmService.createTransaction(from, data, amount, to, gasFeeLevel: GasFeeLevel.high);
```

### Estimate Gas

Given a standard transaction structure (a detached set of values as shown below), you can estimate the gas consumption for a specified transaction using the `EvmService.ethEstimateGas` method.

This acts as a wrapper for `eth_estimateGas` to simulate and retrieve the estimated gas required.

```dart theme={null}
final gasLimit = await EvmService.ethEstimateGas(from, to, value, data);
```

### Get Suggested Gas Fees

To retrieve categorized gas price suggestions (3 categories scaling from low to high) based upon current network conditions, you can call `EvmService.suggestedGasFees`.

```dart theme={null}
final gasFees = await EvmService.suggestedGasFees();
```

### Get Tokens and NFTs

`EvmService` also extends to Data API methods such as `getTokensAndNFTs`, which returns a highly detailed JSON list of ERC20 tokens and ERC721 NFTs belonging to a specified address.

This is accessible through `EvmService.getTokensAndNFTs`, passing in the public address to retrieve the tokens and NFTs. Also, you can retrieve tokens from `getTokens` or NFTs from `getNFTs`

| Field            | Type           | Description                    |
| ---------------- | -------------- | ------------------------------ |
| `address`        | `String`       | The user's public address.     |
| `tokenAddresses` | `List<String>` | The specific tokens' addresses |

```dart theme={null}
final result = await EvmService.getTokensAndNFTs(publicAddress, []);
final result = await EvmService.getTokens(publicAddress, []);
final result = await EvmService.getNFTs(publicAddress, []);
```

### Get Transactions by Address

Similar to the former method, `EvmService.getTransactionsByAddress` enables the retrieval of a detailed JSON response containing a complete list of transactions involving a specified address.

```dart theme={null}
final result = await EvmService.getTransactionsByAddress(publicAddress);
```

### Get Price

To retrieve the price of specific tokens, call `EvmService.getPrice`.

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

```dart theme={null}
final result = await EvmService.getPrice(tokenAddresses, currencies);
```

### Basic RPC Method

You can call any basic EVM RPC method through `EvmService.rpc`

```dart theme={null}
final result = await EvmService.rpc(method, params);
```

## `SolanaService` utilization examples

In addition to `ParticleAuth` for authentication and interaction with Particle's Wallet-as-a-Service, the Flutter SDK also includes a class, `SolanaService`, for general interaction with Solana chains.

### Get Tokens and NFTs

`SolanaService` also extends to Data API methods such as `getTokensAndNFTs`, which returns a highly detailed JSON list of SPL tokens and NFTs belonging to a specified address. This is accessible through `SolanaService.getTokensAndNFTs`, passing in the public address to retrieve the tokens and NFTs of.

| Field              | Type     | Description                 |
| ------------------ | -------- | --------------------------- |
| `address`          | `String` | The user's public address.  |
| `parseMetadataUri` | `bool`   | if parse the nft meta data. |

```dart theme={null}
final result = await SolanaService.getTokensAndNFTs(publicAddress, true);
```

### Serialize Transactions

`SolanaService.serializeSolTransaction` facilitates the construction of a SOL transaction object,

`SolanaService.serializeSplTokenTransaction` facilitates the construction of a Spl-token transaction object,

`SolanaService.serializeWSolTokenTransaction` facilitates the construction of a unwrap WSOL transaction object.

These transactions, once constructed, can be passed for in-UI proposal with `Solana.signAndSendTransaction`.

<CodeGroup>
  ```dart Send sol theme={null}
  final transaction = SerializeSOLTransaction();
  transaction.lamports = TestAccount.solana.amount.toInt();
  transaction.receiver = TestAccount.solana.publicAddress;
  transaction.sender = publicAddress;

  final result = await SolanaService.serializeSolTransaction(transaction);
  final serializedTransaction = result["transaction"]["serialized"];
  ```

  ```dart Send spl token theme={null}
  final transaction = SerializeSplTokenTransaction();
  transaction.amount = TestAccount.solana.amount.toInt();
  transaction.receiver = TestAccount.solana.publicAddress;
  transaction.mint = TestAccount.solana.tokenContractAddress;
  transaction.sender = publicAddress;

  final result = await SolanaService.serializeSplTokenTransaction(transaction);
  final serializedTransaction = result["transaction"]["serialized"];
  ```

  ```dart Unwrap WSOL theme={null}
  final transaction = SerializeWSOLTransaction();
  transaction.address = publicAddress;

  final result = await SolanaService.serializeWSolTokenTransaction(transaction);
  final serializedTransaction = result["transaction"]["serialized"];
  ```
</CodeGroup>

### Get Price

To retrieve the price of specific tokens, call `SolanaService.getPrice`.

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

```dart theme={null}
final result = await SolanaService.getPrice(tokenAddresses, currencies);
```

### Get Transactions by address

To retrieve transactions executed by a specific a address, call `SolanaService.getTransactionsByAddress`.

```dart theme={null}
final result = await SolanaService.getTransactionsByAddress(address);
```

### Get Token by Token Address

To obtain the balance of a specific token at a given address, call `SolanaService.getTokenByTokenAddresses`

| Field            | Type           | Description                |
| ---------------- | -------------- | -------------------------- |
| `address`        | `String`       | The user's public address. |
| `tokenAddresses` | `List<String>` | The tokens' addresses      |

```dart theme={null}
await SolanaService.getTokenByTokenAddresses(address, tokenAddresses);
```

### Basic RPC Method

Any basic Solana RPC method can be called through `SolanaService.rpc`.

```dart theme={null}
await SolanaService.rpc(method, params);
```
