Skip to content

Commit

Permalink
Document iOS SDK (MetaMask#110)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexandratran authored Apr 12, 2023
1 parent 4492a7e commit df0d72c
Show file tree
Hide file tree
Showing 5 changed files with 242 additions and 7 deletions.
2 changes: 1 addition & 1 deletion docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ const config = {
},
prism: {
theme: codeTheme,
additionalLanguages: ["csharp"],
additionalLanguages: ["csharp","swift"],
},
algolia: {
// The application ID provided by Algolia
Expand Down
1 change: 1 addition & 0 deletions wallet-sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const sidebar = {
items: [
"how-to/use-sdk/react-native",
"how-to/use-sdk/pure-js",
"how-to/use-sdk/ios",
"how-to/use-sdk/unity",
],
},
Expand Down
6 changes: 3 additions & 3 deletions wallet/how-to/use-sdk/index.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
# Use MetaMask SDK

MetaMask SDK currently supports all JavaScript-based dapps and Unity gaming dapps.
MetaMask SDK currently supports all JavaScript-based, native iOS, and Unity gaming dapps.
It provides a reliable, secure, and seamless [connection](../../concepts/sdk-connections.md) from
your dapp to a MetaMask wallet client.

The following instructions work for dapps based on standard JavaScript, React, Node.js, Electron,
and other web frameworks.
You can also see instructions for [React Native](react-native.md), [pure JavaScript](pure-js.md),
and [Unity gaming](unity.md) dapps.
[native iOS](ios.md), and [Unity gaming](unity.md) dapps.

:::tip Coming soon
SDK support for Android native, iOS native, and Unreal Engine dapps is coming soon.
SDK support for Android and Unreal Engine dapps is coming soon.
:::

:::note
Expand Down
234 changes: 234 additions & 0 deletions wallet/how-to/use-sdk/ios.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
---
title: Native iOS
---

# Use MetaMask SDK with iOS

You can import MetaMask SDK into your native iOS dapp to enable your users to easily connect
with their MetaMask Mobile wallet.

## Prerequisites

An iOS project set up with iOS version 14+.

## Steps

### 1. Install the SDK

To add the SDK as a Swift Package Manager (SPM) package to your project, in Xcode, select
**File > Swift Packages > Add Package Dependency**.
Enter the URL of the MetaMask iOS SDK repository: `https://github.com/MetaMask/metamask-ios-sdk`.

Alternatively, you can add the URL directly in your project's package file:

```swift
dependencies: [
.package(
url: "https://github.com/MetaMask/metamask-ios-sdk",
from: "0.1.0"
)
]
```

:::note
The SDK supports `ios-arm64` (iOS devices) and `ios-arm64-simulator` (M1 chip simulators).
It currently doesn't support `ios-ax86_64-simulator` (Intel chip simulators).
:::

### 2. Import the SDK

Import the SDK by adding the following line to the top of your project file:

```
import metamask_ios_sdk
```

### 3. Connect your dapp

Connect your dapp by adding the following code to your project file:

```swift
@ObservedObject var ethereum = MetaMaskSDK.shared.ethereum

let dapp = Dapp(name: "Dub Dapp", url: "https://dubdapp.com")

// This is the same as calling eth_requestAccounts
ethereum.connect(dapp)
```

By default, MetaMask logs three SDK events: `connectionRequest`, `connected`, and `disconnected`.
This allows MetaMask to monitor any SDK connection issues.
To disable this, set `MetaMaskSDK.shared.enableDebug = false` or `ethereum.enableDebug = false`.

### 4. Call provider methods

You can now call any [provider API method](../../reference/provider-api.md).

The SDK uses [Combine](https://developer.apple.com/documentation/combine) to publish Ethereum
events, so you need to define an `AnyCancellable` storage by adding the following line to your
project file:

```swift
@State private var cancellables: Set<AnyCancellable> = []
```

The following examples use the
[`window.ethereum.request(args)`](../../reference/provider-api.md#windowethereumrequest--args-)
provider API method to call various [RPC API](../../reference/rpc-api.md) methods.

#### Example: Get chain ID

The following example gets the user's chain ID by calling
[`eth_chainId`](https://metamask.github.io/api-playground/api-documentation/#eth_chainId).

```swift
@State var chainId: String?

let chainIdRequest = EthereumRequest(method: .ethChainId)

ethereum.request(chainIdRequest)?.sink(receiveCompletion: { completion in
switch completion {
case .failure(let error):
print("\(error.localizedDescription)")
default: break
}
}, receiveValue: { result in
self.chainId = result
})
.store(in: &cancellables)
```

#### Example: Get account balance

The following example gets the user's account balance by calling
[`eth_getBalance`](https://metamask.github.io/api-playground/api-documentation/#eth_getBalance).

```swift
@State var balance: String?

// Create parameters
let parameters: [String] = [
ethereum.selectedAddress, // address to check for balance
"latest" // "latest", "earliest" or "pending" (optional)
]

// Create request
let getBalanceRequest = EthereumRequest(
method: .ethGetBalance,
params: parameters)

// Make request
ethereum.request(getBalanceRequest)?.sink(receiveCompletion: { completion in
switch completion {
case .failure(let error):
print("\(error.localizedDescription)")
default: break
}
}, receiveValue: { result in
self.balance = result
})
.store(in: &cancellables)
```

#### Example: Send transaction

The following examples send a transaction by calling
[`eth_sendTransaction`](https://metamask.github.io/api-playground/api-documentation/#eth_sendTransaction).

<!--tabs-->

# Use a dictionary

If your request parameters make up a simple dictionary of string key-value pairs, you can use the
dictionary directly.
Note that `Any` or even `AnyHashable` types aren't supported, since the type must be explicitly known.

```swift
// Create parameters
let parameters: [String: String] = [
"to": "0x...", // receiver address
"from": ethereum.selectedAddress, // sender address
"value": "0x..." // amount
]

// Create request
let transactionRequest = EthereumRequest(
method: .ethSendTransaction,
params: [parameters] // eth_sendTransaction expects an array parameters object
)

// Make a transaction request
ethereum.request(transactionRequest)?.sink(receiveCompletion: { completion in
switch completion {
case .failure(let error):
print("\(error.localizedDescription)")
default: break
}
}, receiveValue: { result in
print(result)
})
.store(in: &cancellables)
```

# Use a struct

For more complex parameter representations, define and use a struct that conforms to `CodableData`,
that is, implements the following requirement:

```
func socketRepresentation() -> NetworkData
```

The type can then be represented as a socket packet.

```swift
struct Transaction: CodableData {
let to: String
let from: String
let value: String
let data: String?

init(to: String, from: String, value: String, data: String? = nil) {
self.to = to
self.from = from
self.value = value
self.data = data
}

func socketRepresentation() -> NetworkData {
[
"to": to,
"from": from,
"value": value,
"data": data
]
}
}

// Create parameters
let transaction = Transaction(
to: "0x...", // receiver address
from: ethereum.selectedAddress, // sender address
value: "0x..." // amount
)

// Create request
let transactionRequest = EthereumRequest(
method: .ethSendTransaction,
params: [transaction] // eth_sendTransaction expects an array parameters object
)

// Make a transaction request
ethereum.request(transactionRequest)?.sink(receiveCompletion: { completion in
switch completion {
case .failure(let error):
print("\(error.localizedDescription)")
default: break
}
}, receiveValue: { result in
print(result)
})
.store(in: &cancellables)
```

<!--/tabs-->
6 changes: 3 additions & 3 deletions wallet/how-to/use-sdk/react-native.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,9 @@ const accounts = await ethereum.request({ method: 'eth_requestAccounts' });

You can configure the SDK using any [options](../../reference/sdk-js-options.md) and call any
[provider API methods](../../reference/provider-api.md).
Always call [`eth_requestAccounts`](../../reference/rpc-api.md#eth_requestaccounts) using
[`ethereum.request()`](../../reference/provider-api.md#ethereumrequestargs) first, since it prompts
the installation or connection popup to appear.
Always call [`eth_requestAccounts`](../../reference/rpc-api.md#ethrequestaccounts) using
[`ethereum.request()`](../../reference/provider-api.md#windowethereumrequest--args-) first, since it
prompts the installation or connection popup to appear.

You can use [EthersJS](https://docs.ethers.io/v5/getting-started/) with your React Native app:

Expand Down

0 comments on commit df0d72c

Please sign in to comment.