Implementation
- Web
- iOS
- Android
- Flutter
- React Native
- Unity
Start by importing
WalletConnectModal and initializing it.Copy
import { WalletConnectModal } from "@walletconnect/modal";
const modal = new WalletConnectModal({
projectId: "YOUR_PROJECT_ID",
chains: ["eip155:1"],
});
Trigger the modal
Once you have obtained your connection uri, you can open or close the modal.From here on, useprovider as you normally would, WalletConnectModal will be shown and hidden automatically i.e.Copy
await modal.openModal({
uri: "YOUR_CONNECTION_URI",
});
// Do some work...
modal.closeModal();
Configure Networking and Pair clients
Make sure that you properly configure Networking and Pair Clients first.Initialize WalletConnectModal Client
In order to initialize a client just call aconfigure method from the WalletKit instance wrapperCopy
let metadata = AppMetadata(
name: "Example Wallet",
description: "Wallet description",
url: "example.wallet",
icons: ["https://avatars.githubusercontent.com/u/37784886"],
// Used for the Verify: to opt-out verification ignore this parameter
verifyUrl: "verify.walletconnect.com"
)
WalletConnectModal.configure(
projectId: PROJECT_ID,
metadata: metadata
)
Copy
let methods: Set<String> = ["eth_sendTransaction", "personal_sign", "eth_signTypedData"]
let events: Set<String> = ["chainChanged", "accountsChanged"]
let blockchains: Set<Blockchain> = [Blockchain("eip155:1")!]
let namespaces: [String: ProposalNamespace] = [
"eip155": ProposalNamespace(
chains: blockchains,
methods: methods,
events: events
)
]
let defaultSessionParams = SessionParams(
requiredNamespaces: namespaces,
optionalNamespaces: nil,
sessionProperties: nil
)
Copy
let metadata = AppMetadata(...)
let sessionParams = SessionParams(...)
WalletConnectModal.configure(
projectId: PROJECT_ID,
metadata: metadata,
sessionParams: sessionParams
)
WalletConnectModal.set(sessionParams: SessionParams(...))WalletConnectModal is a singleton that interacts with the WalletConnectModal SDK.Initialize
Copy
val connectionType = ConnectionType.AUTOMATIC or ConnectionType.MANUAL
val projectId = "" // Get Project ID at https://dashboard.reown.com/
val appMetaData = Core.Model.AppMetaData(
name = "Kotlin.WalletConnectModal",
description = "Kotlin WalletConnectModal Implementation",
url = "kotlin.walletconnect.com",
icons = listOf("https://raw.githubusercontent.com/WalletConnect/walletconnect-assets/master/Icon/Gradient/Icon.png"),
redirect = "kotlin-modal://request"
)
CoreClient.initialize(projectId = projectId, connectionType = connectionType, application = this, metaData = appMetaData)
WalletConnectModal.initialize(
init = Modal.Params.Init(CoreClient),
onSuccess = {
// Callback will be called if initialization is successful
},
onError = { error ->
// Error will be thrown if there's an issue during initialization
}
)
SessionParams
This example will default to using following namespaces. You can define your own session parameters like this.Copy
val methods: List<String> = listOf("eth_sendTransaction", "personal_sign", "eth_sign", "eth_signTypedData")
val events: List<String> = listOf("chainChanged", "accountsChanged")
val chains: List<String> = listOf("eip155:1")
val namespaces = mapOf(
"eip155" to Modal.Model.Namespace.Proposal(
chains = chains,
methods = methods,
events = events
)
)
val sessionParams = Modal.Params.SessionParams(
requiredNamespaces = namespaces,
optionalNamespaces = null,
properties = null
)
WalletConnectModal.setSessionParams(sessionParams)
SessionParams must be set before opening the modal.Create your The service must be initialized before it can be used.With the To handle deep linking to your app, you will also need to add the following to the plist file:For other packages, see the example projectFor some reason, multiple wallets have the
WalletConnectModalService which is your primary class for opening, closing, disconnecting, etc.Be sure to update the project ID and metadata with your own.Copy
WalletConnectModalService service = WalletConnectModalService(
projectId: 'YOUR_PROJECT_ID',
metadata: const PairingMetadata(
name: 'Flutter WalletConnect',
description: 'Flutter WalletConnectModal Sign Example',
url: 'https://walletconnect.com/',
icons: ['https://walletconnect.com/walletconnect-logo.png'],
redirect: Redirect(
native: 'flutterdapp://',
universal: 'https://www.walletconnect.com',
),
),
);
await service.init();
WalletConnectModalService created and ready, you can call _service.open() to open the modal.To make things easy, you can use the WalletConnectModalConnect widget to open the modal.
This is a button that changes its state based on the modal and connection.
This widget requires the WalletConnectModalService to be passed in.Copy
WalletConnectModalConnect(
walletConnectModalService: _service,
),
iOS Setup
For each app you would like to be able to deep link to, you must add that app’s link into theios/Runner/Info.plist file like so:Copy
<key>LSApplicationQueriesSchemes</key>
<array>
<string>metamask</string>
<string>rainbow</string>
<string>trust</string>
</array>
Copy
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>flutterdapp</string> <!-- Change "flutterdapp" to be your deep link -->
</array>
<key>CFBundleURLName</key>
<string>com.walletconnect.flutterdapp</string> <!-- Change this package name to be your package -->
</dict>
</array>
Android Setup
On android 11+ you must specify that use can use the internet, along with the different packages you would like to be able to deep link to in theandroid/app/src/main/AndroidManifest.xml file like so:Copy
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Intent so you can deep link to wallets -->
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
</intent>
<package android:name="io.metamask"/>
<package android:name="com.wallet.crypto.trustapp"/>
<package android:name="io.gnosis.safe"/>
<package android:name="me.rainbow"/>
<package android:name="io.zerion.android"/>
<package android:name="com.imtoken.app"/>
<!-- Add other wallets you would like to launch from within the app -->
</queries>
<!-- Permission to access the internet -->
<uses-permission android:name="android.permission.INTERNET"/>
<!-- Update your activity to handle the deep linking from other apps -->
<activity
...>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- Accepts URIs that begin with "flutterdapp://”, change this to be your deep link -->
<data android:scheme="flutterdapp" />
</intent-filter>
</activity>
...
</manifest>
metamask intent, and will launch metamask as a result.
This is a bug in the wallets, not this package.Start by importing
@walletconnect/react-native-compat at the top of your app. Then import the WalletConnect Modal package, replace YOUR_PROJECT_ID with your Reown Dashboard Project ID and add your Project’s info in providerMetadataCopy
import "@walletconnect/react-native-compat";
import { WalletConnectModal } from "@walletconnect/modal-react-native";
const projectId = "YOUR_PROJECT_ID";
const providerMetadata = {
name: "YOUR_PROJECT_NAME",
description: "YOUR_PROJECT_DESCRIPTION",
url: "https://your-project-website.com/",
icons: ["https://your-project-logo.com/"],
redirect: {
native: "YOUR_APP_SCHEME://",
universal: "YOUR_APP_UNIVERSAL_LINK.com",
},
};
function App() {
return (
<>
<WalletConnectModal
projectId={projectId}
providerMetadata={providerMetadata}
/>
</>
);
}
- Fill in the Project ID and Metadata fields in the
Assets/WalletConnectUnity/Resources/WalletConnectProjectConfigasset.- If you don’t have a Project ID, you can create one at Reown Dashboard.).
- The
Redirectfields are optional. They are used to redirect the user back to your app after they approve or reject the session.
- Add
WalletConnectModalprefab fromWalletConnectUnity Modalpackage to the first scene in your game.
Usage
- Web
- iOS
- Android
- Flutter
- React Native
- Unity
openModal
Action to open the modal. Returns promise that resolves once modal is visible.Example
Copy
await modal.openModal({
uri: "YOUR_CONNECTION_URI",
});
Reference
Copy
openModal: (options?: OpenOptions) => Promise<void>;
Copy
interface OpenOptions {
// Uri that will be used to generate qrcode and mobile links, required
uri: string;
// CAIP-2 compliant chain ids to override initial chains defined when creating the modal
// Learn about CAIP-10: https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-10.md
chains?: string[];
}
closeModal
Action to close the modal.Example
Copy
modal.closeModal();
Reference
Copy
closeModal: () => void
subscribeModal
Action to subscribe to modal state changes.Example
Copy
modal.subscribeModal((state) => console.log(state));
Reference
Copy
subscribeModal: (callback: (state: ModalState) => void) => void
Copy
interface ModalState {
open: boolean;
}
To actually present the modal you can simply call.It will traverse the view hierarchy and try to present from top most controller. This is meant more towards SwiftUI.Otherwise you can specify the viewController to present from.
Copy
WalletConnectModal.present()
Copy
WalletConnectModal.present(from: viewController)
Subscribe for WalletConnectModal Publishers
The following publishers are available to subscribe:Copy
public var sessionPublisher: AnyPublisher<[Session], Never>
public var sessionSettlePublisher: AnyPublisher<Session, Never>
public var sessionRejectionPublisher: AnyPublisher<(Session.Proposal, Reason), Never>
public var sessionDeletePublisher: AnyPublisher<(String, Reason), Never>
public var sessionResponsePublisher: AnyPublisher<Response, Never>
public var socketConnectionStatusPublisher: AnyPublisher<SocketConnectionStatus, Never>
Sign methods
WalletConnectModal is internally using Sign SDK and most of its method are being exposed through WalletConnectModal interface.Where to go from here
Check the WalletConnectModal usage in our Example Showcase app that is part of WalletConnectSwiftV2 repository. Build API documentation in Xcode by going toProduct -> Build DocumentationAndroid Compose
Copy
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.ModalBottomSheetState
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.google.accompanist.navigation.material.BottomSheetNavigator
import com.google.accompanist.navigation.material.ExperimentalMaterialNavigationApi
import com.google.accompanist.navigation.material.ModalBottomSheetLayout
import com.google.accompanist.navigation.material.bottomSheet
import com.walletconnect.wcmodal.ui.walletConnectModalGraph
setContent {
val modalSheetState = rememberModalBottomSheetState(initialValue = ModalBottomSheetValue.Hidden, skipHalfExpanded = true)
val bottomSheetNavigator = BottomSheetNavigator(modalSheetState)
val navController = rememberNavController(bottomSheetNavigator)
ModalBottomSheetLayout(bottomSheetNavigator = bottomSheetNavigator) {
NavHost(
navController = navController,
startDestination = "home"
) {
composable("home") {
HomeScreen()
}
walletConnectModalGraph(navController)
}
}
}
ModalBottomSheetLayout should be imported from Accompanist Navigation MaterialCopy
import com.walletconnect.wcmodal.ui.openWalletConnectModal
navController.openWalletConnectModal()
Android View
Navigation Component
Copy
<navigation >
<fragment
android:id="@+id/HomeFragment"
android:name="com.walletconnect.sample.HomeFragment">
<action
android:id="@+id/action_to_bottomSheet"
app:destination="@id/bottomSheet" />
</fragment>
<dialog
android:id="@+id/bottomSheet"
android:name="com.walletconnect.wcmodal.ui.WalletConnectModalSheet" />
</navigation>
Copy
import androidx.navigation.fragment.findNavController
import com.walletconnect.wcmodal.ui.openWalletConnectModal
findNavController().openWalletConnectModal(id = R.id.action_to_bottomSheet)
Kotlin DSL
Copy
import androidx.navigation.createGraph
import androidx.navigation.fragment.fragment
import com.walletconnect.wcmodal.ui.walletConnectModal
navController.graph = navController.createGraph("Home") {
fragment<HomeFragment>("Home")
walletConnectModal()
}
Copy
import androidx.navigation.fragment.findNavController
import com.walletconnect.wcmodal.ui.openWalletConnectModal
findNavController().openWalletConnectModal()
WalletConnectModal.ModalDelegate
Copy
val walletConnectModalDelegate = object : WalletConnectModal.ModalDelegate {
override fun onSessionApproved(approvedSession: Modal.Model.ApprovedSession) {
// Triggered when receives the session approval from wallet
}
override fun onSessionRejected(rejectedSession: Modal.Model.RejectedSession) {
// Triggered when receives the session rejection from wallet
}
override fun onSessionUpdate(updatedSession: Modal.Model.UpdatedSession) {
// Triggered when receives the session update from wallet
}
override fun onSessionExtend(session: Modal.Model.Session) {
// Triggered when receives the session extend from wallet
}
override fun onSessionEvent(sessionEvent: Modal.Model.SessionEvent) {
// Triggered when the peer emits events that match the list of events agreed upon session settlement
}
override fun onSessionDelete(deletedSession: Modal.Model.DeletedSession) {
// Triggered when receives the session delete from wallet
}
override fun onSessionRequestResponse(response: Modal.Model.SessionRequestResponse) {
// Triggered when receives the session request response from wallet
}
override fun onProposalExpired(proposal: Modal.Model.ExpiredProposal) {
// Triggered when a proposal becomes expired
}
override fun onRequestExpired(request: Modal.Model.ExpiredRequest) {
// Triggered when a request becomes expired
}
override fun onConnectionStateChange(state: Modal.Model.ConnectionState) {
//Triggered whenever the connection state is changed
}
override fun onError(error: Modal.Model.Error) {
// Triggered whenever there is an issue inside the SDK
}
}
WalletConnectModal.ModalDelegate passed to it for it to be able to expose asynchronously updates sent from the Wallet. It can only be called after successful WalletConnectModal initializationConnect
Copy
val namespace: String = /*Namespace identifier, see for reference: https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-2.md#syntax*/
val chains: List<String> = /*List of chains that wallet will be requested for*/
val methods: List<String> = /*List of methods that wallet will be requested for*/
val events: List<String> = /*List of events that wallet will be requested for*/
val requiredNamespaces: Map<String, Modal.Model.Namespaces.Proposal> = mapOf(namespace, Modal.Model.Namespaces.Proposal(accounts, methods, events)) /*Required namespaces to setup a session*/
val optionalNamespaces: Map<String, Modal.Model.Namespaces.Proposal> = mapOf(namespace, Modal.Model.Namespaces.Proposal(accounts, methods, events)) /*Optional namespaces to setup a session*/
val pairing: Core.Model.Pairing = /*Either an active or inactive pairing*/
val connectParams = Modal.Params.Connect(requiredNamespaces, optionalNamespaces, pairing)
WalletConnectModal.connect(
connect = connectParams,
onSuccess = {
/* callback that letting you know that you have successfully initiated connecting */
},
onError = { error =>
/* callback for error while trying to initiate a connection with a peer */
}
)
Disconnect
Copy
val disconnectParams = WalletConnectModal.Params.Disconnect(topic)
WalletConnectModal.disconnect(
disconnect = disconnectParams,
onSuccess = {
/* callback that letting you know that you have successfully disconnected */
},
onError = { error ->
/* callback for error while trying to disconnection with a peer */
}
)
Request
Copy
val requestParams = Modal.Params.Request(
sessionTopic = sessionTopic,
method = /* Selected method */,
params = /* Method params */,
chainId = /* Chain id */
)
WalletConnectModal.request(
request = requestParams,
onSuccess = {
/* callback that letting you know that you have successful request */
},
onError = { error ->
/* callback for error */
}
)
Get List of Active Sessions
Copy
WalletConnectModal.getListOfActiveSessions()
WalletConnectModal.getListOfActiveSessions() which will return a list of type Modal.Model.Session.Get list of pending session requests for a topic
Copy
WalletConnectModal.getActiveSessionByTopic(topic)
WalletConnectModal.getActiveSessionByTopic() and pass a topic which will return
a Modal.Model.Session object containing requestId, method, chainIs and params for pending request.You can launch the currently connected wallet by calling
service.launchCurrentWallet().useWalletConnectModal
Hook to programmatically control the modal. Useful when you want to use your own UI elements and subscribe to modals state.*Note: A new session is created automatically when the modal is opened, so avoid callingprovider.connect by yourself.Copy
import { useWalletConnectModal } from "@walletconnect/modal-react-native";
const { isOpen, open, close, provider, isConnected, address } = useWalletConnectModal();
// Modal's open state
isOpen;
// Open modal
interface Options {
route?: 'ConnectWallet' | 'Qrcode' | 'WalletExplorer';
}
await open(options?: Options);
// Close modal
close();
// Initialized provider
provider;
// Wallet connection state
isConnected;
// Connected account's address
address;
Example
Copy
import { Pressable, Text } from "react-native";
import "@walletconnect/react-native-compat";
import {
WalletConnectModal,
useWalletConnectModal,
} from "@walletconnect/modal-react-native";
const projectId = "YOUR_PROJECT_ID";
const providerMetadata = {
name: "YOUR_PROJECT_NAME",
description: "YOUR_PROJECT_DESCRIPTION",
url: "https://your-project-website.com/",
icons: ["https://your-project-logo.com/"],
redirect: {
native: "YOUR_APP_SCHEME://",
universal: "YOUR_APP_UNIVERSAL_LINK.com",
},
};
function App() {
const { open, isConnected, provider } = useWalletConnectModal();
const onPress = () => {
if (isConnected) {
provider.disconnect();
} else {
open();
}
};
return (
<>
<Pressable onPress={onPress}>
<Text>{isConnected ? "Disconnect" : "Connect"}</Text>
</Pressable>
<WalletConnectModal
projectId={projectId}
providerMetadata={providerMetadata}
/>
</>
);
}
Connection and Events
- WalletConnect Modal is a singleton that can be accessed from any scene.
- By default Modal will initialize itself asynchronously on Awake. During initialization it will also try to connect to the last session.
- After initialization, Modal invokes
WalletConnectModal.Readystatic event. - If
Readyargument’sSessionResumedistrue, it means that Modal has successfully connected to the last session. In this case you don’t need to open the modal. Otherwise, open the modal withWalletConnectModal.Open()static method.
Copy
private void Start()
{
WalletConnectModal.Ready += (sender, args) =>
{
if (args.SessionResumed)
{
// Session has been resumed, proceed to the game
}
else
{
// Session hasn't been resumed
// Define required namespaces for new session
var requiredNamespaces = new RequiredNamespaces
{
{
"eip155", new ProposedNamespace
{
Methods = new[]
{
"eth_sendTransaction",
"personal_sign",
"eth_signTypedData"
},
Chains = new[]
{
"eip155:1"
},
Events = new[]
{
"chainChanged",
"accountsChanged"
}
}
}
};
var connectOptions = new ConnectOptions
{
RequiredNamespaces = requiredNamespaces
};
// Open the modal
WalletConnectModal.Open(new WalletConnectModalOptions
{
ConnectOptions = connectOptions
});
}
};
}
ActiveSessionChanged and SessionDeleted events. It’s recommended to do it in Ready event handler.Copy
WalletConnectModal.Ready += (sender, args) =>
{
// ....
// Invoked after wallet connected
WalletConnect.Instance.ActiveSessionChanged += (_, sessionStruct) =>
{
// Session connected/updated, proceed to the game if sessionStruct.topic is not null/empty
};
// Invoked after wallet disconnected
WalletConnect.Instance.SessionDisconnected += (_, _) =>
{
// Session deleted, show sign in screen
};
};
Disconnection
To disconnect from the current session, callWalletConnectModal.Disconnect() static method.Interaction with RPC
The WalletConnect Modal is responsible for facilitating communication between the game and the wallet. Some methods do not require the user to interact with the wallet. For example,eth_getBalance is used to get the address balance,
and eth_call is used to read data from a smart contract without modifying its state, hence no signature is required.To call these methods, you can use the Nethereum.Web3 package.Copy
private static async Task GetAccountBalance()
{
var session = WalletConnect.Instance.ActiveSession;
// Because one session can have multiple namespaces, we need to select one.
// In most cases, especially in games, dapp will use only one namespace.
var @namespace = session.Namespaces.First();
var address = session.CurrentAddress(@namespace.Key).Address;
var config = ProjectConfiguration.Load();
// Using WalletConnect Blockchain API: https://docs.walletconnect.com/cloud/blockchain-api
var url = $"https://rpc.walletconnect.com/v1?chainId={@namespace.Value.Chains[0]}&projectId={config.Id}";
var web3 = new Nethereum.Web3.Web3(url);
var balance = await web3.Eth.GetBalance.SendRequestAsync(address);
Debug.Log($"Balance of {address} in Wei: {balance.Value}");
var etherAmount = Nethereum.Web3.Web3.Convert.FromWei(balance.Value);
Debug.Log($"Balance of {address} in Ether: {etherAmount}");
}
Interaction with Smart Contracts
To query smart contracts, you can use Nethereum.Web3 package to makeeth_call requests directly to the RPC endpoint.
However, to call methods that modify the state of the smart contract, you need user to sign the transaction in the wallet.There are two ways to interact with smart contracts:- With Interceptor: using Nethereum’s
RequestInterceptor(recommended) - Manual: using Nethereum’s tools to encode data and make requests directly with WalletConnect
- Interceptor (recommended)
- Manual
WalletConnect provides a Nethereum interceptor utility that will route requests that require user signature to the wallet.
With this approach, you don’t need to manually encode data and make requests. Use convenient Nethereum’s methods to interact with smart contracts, and interceptor
will automatically route requests to the wallet.WalletConnectUnity Nethereum source codeNethereum allows to deploy and interact with custom smart contracts as well.
Refer to the Nethereum documentation for more information.
Install interceptor
Copy
openupm add com.walletconnect.nethereum
Use interceptor
This example shows how to calltransfer method of ERC20 smart contract using interceptor.Copy
// Nethereum's Web3 instance
var web3 = new Web3();
// Instance of WalletConnect singleton
var walletConnect = WalletConnect.Instance;
// Interceptor that will route requests requiring signing to the wallet connected with WalletConnect
var walletConnectUnityInterceptor = new WalletConnectUnityInterceptor(walletConnect);
// Assign the interceptor to the Web3 instance
web3.Client.OverridingRequestInterceptor = walletConnectUnityInterceptor;
const string contractAddress = "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984";
const string recipientAddress = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045";
const BigInteger amount = 1;
// Get ERC20 contract service
var contractService = Web3Modal.Web3.Eth.ERC20.GetContractService(contractAddress);
// Call transfer method of ERC20 contract
await contractService.TransferRequestAsync(recipientAddress, amount);
The example below shows how to call Please refer to Nethereum documentation for more details. Nethereum provides tools to simplify encoding and decoding.
These tools hadn’t been used in the example above to better illustrate the process.
approve method of WETH9 (Wrapped Ether) smart contract. It encodes data with Nethereum and makes request with WalletConnect.Copy
public async Task ContractTransaction()
{
var session = WalletConnect.Instance.ActiveSession;
// Because one session can have multiple namespaces, we need to select one.
// In most cases, especially in games, dapp will use only one namespace.
var @namespace = session.Namespaces.First();
var myAddress = session.CurrentAddress(@namespace.Key).Address;
// Define contract and function details
var contractAddress = "0x4200000000000000000000000000000000000006";
var toAddress = myAddress; // Use sender's address for the sake of example
var amount = new BigInteger(12345);
// Define the parameters for the approve function
var parameters = new Parameter[] {
new("address", "guy"),
new("uint256", "wad")
};
var functionCallEncoder = new FunctionCallEncoder();
var sha3Signature = new Sha3Keccack().CalculateHash("approve(address,uint256)");
// Encode the parameters
var encodedParameters = functionCallEncoder
.EncodeParameters(parameters, toAddress, amount)
.ToHex();
// Combine signature and parameters
var data = "0x" + sha3Signature[..8] + encodedParameters;
// Create transaction
var ethSendTransaction = new EthSendTransaction(new Transaction
{
From = myAddress,
To = contractAddress,
Value = "0",
Data = data
});
try
{
var result = await WalletConnect.Instance.RequestAsync<EthSendTransaction, string>(ethSendTransaction);
Debug.Log($"Transaction success! TxHash: {result}", this);
}
catch (Exception e)
{
Debug.LogError(e, this);
}
}
public class Transaction
{
[JsonProperty("from")] public string From { get; set; }
[JsonProperty("to")] public string To { get; set; }
[JsonProperty("gas", NullValueHandling = NullValueHandling.Ignore)]
public string Gas { get; set; }
[JsonProperty("gasPrice", NullValueHandling = NullValueHandling.Ignore)]
public string GasPrice { get; set; }
[JsonProperty("value")] public string Value { get; set; }
[JsonProperty("data", NullValueHandling = NullValueHandling.Ignore)]
public string Data { get; set; } = "0x";
}
[RpcMethod("eth_sendTransaction"), RpcRequestOptions(Clock.ONE_MINUTE, 99997)]
public class EthSendTransaction : List<Transaction>
{
public EthSendTransaction(params Transaction[] transactions) : base(transactions)
{
}
[Preserve]
public EthSendTransaction()
{
}
}
Subscribe to session events
Copy
var signClient = WalletConnect.Instance.SignClient;
signClient.SubscribeToSessionEvent("chainChanged", OnChainChanged);