> For the complete documentation index, see [llms.txt](/llms.txt).

# Integrate Embedded Wallets with the Arbitrum Blockchain in Flutter

While using the Embedded Wallets Flutter SDK, you get the private key within the user scope after successful authorization. This private key can be used to retrieve the user's address, and interact with [Arbitrum](https://arbitrum.io/) to make any blockchain calls. We have highlighted a few here for getting you started quickly on that.

## Chain details for Arbitrum[​](#chain-details-for-arbitrum "Direct link to Chain details for Arbitrum")

- Mainnet
- Sepolia Testnet

- **Chain ID:** 0xa4b1
- **RPC URL:** You can use our bundled RPC service from Infura, or your own choice of RPC service for production.
- **Display Name:** Arbitrum One
- **Block Explorer Link:** `https://arbiscan.io`
- **Ticker:** ETH
- **Ticker Name:** Ethereum

- **Chain ID:** 0x66eee
- **Public RPC URL:** `https://sepolia-rollup.arbitrum.io/rpc`
- **Display Name:** Arbitrum Sepolia
- **Block Explorer Link:** `https://sepolia.arbiscan.io`
- **Ticker:** ETH
- **Ticker Name:** Ethereum

## Prerequisites[​](#prerequisites "Direct link to Prerequisites")

This doc assumes you have already setup your project in the Embedded Wallets dashboard (formerly Web3Auth), and have integrated Embedded Wallets in your Flutter app. If you haven't done that yet, you can learn how to [integrate Embedded Wallets in your Flutter app](/embedded-wallets/sdk/flutter/).

## Installation[​](#installation "Direct link to Installation")

To interact with the Ethereum compatible blockchains in Flutter, you can use any [EIP1193](https://eips.ethereum.org/EIPS/eip-1193) compatible package. Here, we're using [web3dart](https://pub.dev/packages/web3dart) to demonstrate how to make blockchain calls using it with Embedded Wallets.

To install the `web3dart` package, you have two options. You can either manually add the package in the `pubspec.yaml` file, or you can use the `flutter pub add` command.

- Console
- Pubspec

Add `web3dart` using `flutter pub add` command.

```
flutter pub add web3dart

```

Add `web3dart` as a dependency to your `pubspec.yaml`.

```
dependencies:
  web3dart: ^2.7.3

```

## Initialize[​](#initialize "Direct link to Initialize")

We'll initialize the `Web3Client` with the RPC URL of the network you want to connect to. This client allows us to interact with the blockchain. To get the public RPC URL, see [Chainlist.org](https://chainlist.org/).

```
import 'package:web3dart/web3dart.dart';

// Please avoid using public RPC URL in production, use services
// like Infura.
final client = Web3Client("YOUR_RPC_URL", Client());

```

## Get account[​](#get-account "Direct link to Get account")

Once the user has successfully logged in, you can retrieve the user's private key using the `getPrivKey` method from the Embedded Wallets Flutter SDK. We'll use this private key to generate the Credentials for the user.

This Credentials object has the user's keypair of private key and public key, and can be used to sign the transactions. Please note, that this assumes that the user has already logged in and the private key is available.

```
import 'package:web3dart/web3dart.dart';

final privateKey = await Web3AuthFlutter.getPrivKey();

final credentials = EthPrivateKey.fromHex(privateKey);
final address = credentials.address;

```

## Get balance[​](#get-balance "Direct link to Get balance")

To retrieve the native balance of the user, you can use the `Web3Client` object we created earlier. It has `getBalance` method which helps to fetch the user's native token balance.

The result we get from Web3Client is in wei, the smallest unit of ether. To convert wei to ether, divide by 10^18, where 18 denotes the decimals for wei.

For the simplicity, we'll use a helper function from web3dart package which implements this conversion:

```

// Use the client and address variable from above
final balanceResponse = await client.getBalance(address);

// Convert the balance to ether format, and round off to 4 decimal places.
final balance = balanceResponse.getValueInUnit(EtherUnit.ether).toStringAsFixed(4);

```

## Sign a transaction[​](#sign-a-transaction "Direct link to Sign a transaction")

To sign a transaction, you can use the `Web3Client` object we created earlier. It has `signTransaction` method which signs the transaction for the given key pair, and chain.

The method internally handles the nonce, gas price, and gas limit. If you want to manually set the nonce, gas price, and gas limit, you can override the parameters in the Transaction object.

```
import 'package:web3dart/web3dart.dart';

// Use client, address, and credentials from previous code snippets
final signature = await client.signTransaction(
  credentials,
  Transaction(
    from: address,
    // Replace with the recipient address
    to: EthereumAddress.fromHex('0x809D4310d578649D8539e718030EE11e603Ee8f3'),
    // Replace with the amount of ETH to send
    value: EtherAmount.fromUnitAndValue(EtherUnit.gwei, 50000000), // 0.05 ETH
    chainId: null,
    fetchChainIdFromNetworkId: true,
  ),
);

```

## Send transaction[​](#send-transaction "Direct link to Send transaction")

If you wish to sign _and_ broadcast the transaction, you can use the `Web3Client.sendTransaction` method.

This method prepares the transaction, and signs similar to `signTransaction` method. The only difference is, it also broadcasts the transaction to the network, and returns the transaction receipt.

```
import 'package:web3dart/web3dart.dart';

// Use client, address, and credentials from previous code snippets
final receipt = await client.sendTransaction(
  credentials,
  Transaction(
    from: address,
    to: EthereumAddress.fromHex('0x809D4310d578649D8539e718030EE11e603Ee8f3'),
    value: EtherAmount.fromUnitAndValue(EtherUnit.gwei, 50000000), // 0.05 ETH
    chainId: null,
    fetchChainIdFromNetworkId: true,
  ),
);

```

## Smart contract interactions[​](#smart-contract-interactions "Direct link to Smart contract interactions")

In addition to the intetactions and transactions, the web3dart library allows you to deploy and interact with Smart Contracts.

Firstly, we'll create a new smart contract using Solidity that allows us to store a message and update it. The contract will have a constructor that takes an initial message as input, and a function to update the message.

```
pragma solidity ^0.8.20;

contract HelloWorld {

  string public message;

  constructor(string memory initMessage) public {
    message = initMessage;
  }

  function update(string memory newMessage) public {
    message = newMessage;
  }
}

```

The package don't have a way to compile Solidity smart contracts, so we'll need to compile the contract using an online compiler and get the bytecode and ABI from there. For this example we'll use [Remix IDE](https://remix.ethereum.org/) to compile the contract.

Please note that the bytecode and ABI are different for each network, so you'll need to compile the contract for the network you want to deploy it to.

Once compiled, please copy the bytecode and ABI for the future usecases.

```
final contractAbi = '[{"constant":false,"inputs":[{"name":"newMessage","type":"string"}],"name":"update","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"message","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"initMessage","type":"string"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"}]';
final  byteCode =
      "0x608060405234801561001057600080fd5b506040516104623803806104628339818101604052602081101561003357600080fd5b81019080805164010000000081111561004b57600080fd5b8281019050602081018481111561006157600080fd5b815185600182028301116401000000008211171561007e57600080fd5b5050929190505050806000908051906020019061009c9291906100a3565b5050610148565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100e457805160ff1916838001178555610112565b82800160010185558215610112579182015b828111156101115782518255916020019190600101906100f6565b5b50905061011f9190610123565b5090565b61014591905b80821115610141576000816000905550600101610129565b5090565b90565b61030b806101576000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80633d7403a31461003b578063e21f37ce146100f6575b600080fd5b6100f46004803603602081101561005157600080fd5b810190808035906020019064010000000081111561006e57600080fd5b82018360208201111561008057600080fd5b803590602001918460018302840111640100000000831117156100a257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610179565b005b6100fe610193565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561013e578082015181840152602081019050610123565b50505050905090810190601f16801561016b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b806000908051906020019061018f929190610231565b5050565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102295780601f106101fe57610100808354040283529160200191610229565b820191906000526020600020905b81548152906001019060200180831161020c57829003601f168201915b505050505081565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061027257805160ff19168380011785556102a0565b828001600101855582156102a0579182015b8281111561029f578251825591602001919060010190610284565b5b5090506102ad91906102b1565b5090565b6102d391905b808211156102cf5760008160009055506001016102b7565b5090565b9056fea265627a7a72305820a58716d2c2342b3cc5028e49842810b98f5c3f2c1591e8c7f3ec916096f6a03264736f6c634300050a0032";

```

### Deploy a contract[​](#deploy-a-contract "Direct link to Deploy a contract")

Since the web3dart package doesn't support deploying contracts directly, we'll use the precompiled smart contract byteCode to deploy the contract using the `sendTransaction` method.

```
// Use the client, address, and credentials from previous code snippets

// Use the bytecode from the previous step
final payload = Uint8List.fromList(utf8.encode(byteCode));

final transaction = Transaction(
  // Please make sure to keep the `to` field as `null`
  // for deploying the contract
  to: null,
  from: address,
  data: payload,
);

final receipt = await client.sendTransaction(credential, transaction);

```

### Read from contract[​](#read-from-contract "Direct link to Read from contract")

To interact with any smart contract, you need the contract address and the ABI of the contract. The ABI of the contract helps encode the function name and its parameters. Consideri ABI as an outline of the contract, which provides contract specifications.

We'll create a `DeployedContract` instance with the contract address and ABI. Once created, we can use it to call the contract function. To interact with the contract, we'll use the `call` method form the Web3Client.

In this sample, we'll read the message from the contract we deployed in the previous step.

```
import 'package:web3dart/web3dart.dart';

// Use the client, address, contractAbi and credentials from previous code snippets
final contract = DeployedContract(
    ContractAbi.fromJson(contractAbi, ''),
    "ADDRESS_OF_DEPLOYED_CONTRACT_IN_HEX",
);

final messageFunction = contract.function('message');

final message = await client.call(
    contract: contract,
    function: messageFunction,
    params: [],
);

```

### Write to Contract[​](#write-to-contract "Direct link to Write to Contract")

Similary, you can write to the contract using the `sendTransaction` method supported by Web3Client. In this sample, we'll update the message in the contract we deployed previously.

```
import 'package:web3dart/web3dart.dart';
// Use the client, address, contractAbi and credentials from previous code snippets
final contract = DeployedContract(
    ContractAbi.fromJson(contractAbi, ''),
    "ADDRESS_OF_DEPLOYED_CONTRACT_IN_HEX",
);

final updateFunction = contract.function('update');
final receipt = await client.sendTransaction(
  credentials,
  Transaction.callContract(
    contract: contract,
    function: updateFunction,
    parameters: ["YOUR_NEW_MESSAGE"]
  )
);

```
