Skip to main content

Installation

Swift implementation of WalletConnect v.2 protocol for native iOS applications.

Getting started with wallet integration

Set up a project

In order to connect to WalletConnect Cloud, you need to create a new project first:

  1. Go to https://cloud.walletconnect.com/app
  2. Tap New Project
  3. Give it a name and tap Create button
  4. Your new project should appear on the projects list
  5. You should see a project ID string if you tap on your project. for more info on Project ID look at Project ID.

Add SDK for your project.

You can add a WalletConnect SDK to your project with Swift Package Manager. In order to do that:

  1. Open XCode
  2. Go to File -> Add Packages
  3. Paste the repo GitHub url: https://github.com/authentication/WalletConnectSwiftV2
  4. Tap Add Package

Instantiate a client

Create an AppMetadata object first. It will describe your application and define its appearance in a web browser. Then create an instance of WalletConnectClient, inject a metadata object you have instantiated, set a project ID generated when starting a project on WalletConnect Cloud. Set your client as a controller and provide a relayHost URL.

Note that you want to have only one instance of a client in your app, and you don’t want to deinitialize that instance.

    let client: WalletConnectClient = {
let metadata = AppMetadata(
name: "My Wallet",
description: "description",
url: "",
icons: ["icon_url"])
return WalletConnectClient(
metadata: metadata,
projectId: "project_id",
isController: true,
relayHost: "relay.walletconnect.com"
)
}()
Set client's delegate

Your View Controller or whatever place you have decided to initialize your client should conform to WalletConnectDelegate.

final class MyViewController: UIViewController, WalletConnectClientDelegate {
...
override func viewDidLoad() {
super.viewDidLoad()
client.delegate = self
}
}

Connect Clients

Your Wallet should allow users to scan a QR code generated by dapps. You are responsible for implementing it on your own. For testing, you can use our test dapp at: https://react-app.walletconnect.com/, which is v2 protocol compliant. Once you derive a URI from the QR code call pair method:

try? client.pair(uri: uri)

if everything goes well, the following delegate method should be called

func didReceive(sessionProposal: Session.Proposal) {

}

Session.Proposal object conveys Permissions structure that contains allowed blockchains and methods that later the dapp will be authorized to request. The user will either approve the session proposal (with allowed accounts) or reject it. Accounts must be provided according to CAIP10 specification and be prefixed with a chain identifier. chain_id + : + account_address. You can find more on blockchain identifiers in CAIP2.

let account = Account("eip155:1:0xab16a96d359ec26a11e2c2b3d8f8b8942d5bfcdb")!
client.approve(proposal: proposal, accounts: [account])

When session is sucessfully approved another delegate method is called:

func didSettle(session: Session) {
}

Session object represents an active session connection with a dapp. It contains dapp’s metadata (that you may want to use for displaying an active session to the user), permissions, and accounts. There is also a topic property that you will use for linking requests with related sequences.

You can always query settled sessions from the client later with:

client.getSettledSessions()

Handle requests from dapp

After the session is established, a dapp will request your wallet users to sign a transaction or a message. Requests will be delivered by the following delegate method.

func didReceive(sessionRequest: Request) {

}

When a wallet receives a session request, you probably want to show it to the user. It’s method will be one of those allowed by the session permissions. And it’s params are represented by AnyCodable type. An expected object can be derived as follows:

        if sessionRequest.method == "personal_sign" {
let params = try! sessionRequest.params.get([String].self)
} else if method == "eth_signTypedData" {
let params = try! sessionRequest.params.get([String].self)
} else if method == "eth_sendTransaction" {
let params = try! sessionRequest.params.get([EthereumTransaction].self)
}

Now, your wallet (as it owns your user’s privete keys) is responsible for signing the transaction. After doing it, you can send a response to a dapp.

let result = sign(request: sessionRequest) // implement your signing method
let response = JSONRPCResponse<AnyCodable>(id: sessionRequest.id, result: result)
client.respond(topic: sessionRequest.topic, response: .response(response))

Web Socket Connection

By default web socket connection is handled internally by the SDK. That means that Web socket will be safely disconnected when apps go to background and it will connect back when app reaches foreground. But if it is not expeted for your app and you want to handle socket connection manually you can do it as follows:

  1. instantiate Relayer object.
let relayer = Relayer(
relayHost: "relay.walletconnect.com",
projectId: "52af113ee0c1e1a20xxx95730196c13e,
socketConnectionType: .manual")
  1. inject relayer into WalletConnectClient instance:
    let client = WalletConnectClient(metadata: metadata, relayer: relayer)
  2. control connection:
    relayer.connect()

Where to go from here

Try our example wallet implementation that is part of WalletConnectSwiftV2 repository.

You may also be interested in reading our Beginner guide to WalletConnect v2.0 for iOS Developers