Skip to content

Commit

Permalink
Merge pull request #137 from MetaMask/convenience-methods
Browse files Browse the repository at this point in the history
Convenience methods
  • Loading branch information
elefantel authored Mar 15, 2024
2 parents a5af9e0 + 4364784 commit 4fe9251
Show file tree
Hide file tree
Showing 10 changed files with 294 additions and 71 deletions.
6 changes: 2 additions & 4 deletions Example/metamask-ios-sdk.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -588,8 +588,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MODULE_NAME = ExampleApp;
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)";
"PRODUCT_BUNDLE_IDENTIFIER[sdk=iphoneos*]" = "org.demo.metamask-ios-sdk-Example";
PRODUCT_BUNDLE_IDENTIFIER = io.metamask.ios.sdk;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
Expand Down Expand Up @@ -617,8 +616,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MODULE_NAME = ExampleApp;
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)";
"PRODUCT_BUNDLE_IDENTIFIER[sdk=iphoneos*]" = "org.demo.metamask-ios-sdk-Example";
PRODUCT_BUNDLE_IDENTIFIER = io.metamask.ios.sdk;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
Expand Down
9 changes: 2 additions & 7 deletions Example/metamask-ios-sdk/SignView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -100,15 +100,10 @@ struct SignView: View {
}

func signMessage() async {
let from = metamaskSDK.account
let params: [String] = [from, signMessage]
let signRequest = EthereumRequest(
method: .ethSignTypedDataV4,
params: params
)
let account = metamaskSDK.account

showProgressView = true
let requestResult = await metamaskSDK.request(signRequest)
let requestResult = await metamaskSDK.signTypedDataV4(typedData: signMessage, address: account)
showProgressView = false

switch requestResult {
Expand Down
64 changes: 24 additions & 40 deletions Example/metamask-ios-sdk/SwitchChainView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ struct SwitchChainView: View {
@EnvironmentObject var metamaskSDK: MetaMaskSDK

@State private var alert: AlertInfo?
@State var networkSelection: Network = .goerli
@State var networkSelection: Network = .polygon

struct AlertInfo: Identifiable {
enum Status {
Expand All @@ -32,8 +32,7 @@ struct SwitchChainView: View {
}

enum Network: String, CaseIterable, Identifiable {
case goerli = "0x5"
case kovan = "0x2a"
case avalanche = "0xa86a"
case ethereum = "0x1"
case polygon = "0x89"

Expand All @@ -47,14 +46,22 @@ struct SwitchChainView: View {
switch self {
case .polygon: return "Polygon"
case .ethereum: return "Ethereum"
case .kovan: return "Kovan Testnet"
case .goerli: return "Goerli Testnet"
case .avalanche: return "Avalanche"
}
}

var symbol: String {
switch self {
case .polygon: return "MATIC"
case .ethereum: return "ETH"
case .avalanche: return "AVAX"
}
}

var rpcUrls: [String] {
switch self {
case .polygon: return ["https://polygon-rpc.com"]
case .avalanche: return ["https://api.avax.network/ext/bc/C/rpc"]
default: return []
}
}
Expand Down Expand Up @@ -112,23 +119,15 @@ struct SwitchChainView: View {
}
.onAppear {
networkSelection = metamaskSDK.chainId == networkSelection.rawValue
? .ethereum
: .goerli
? .ethereum
: .polygon
}
.background(Color.blue.grayscale(0.5))
}

func switchEthereumChain() async {
let switchChainParams: [String: String] = [
"chainId": networkSelection.chainId
]

let switchChainRequest = EthereumRequest(
method: .switchEthereumChain,
params: [switchChainParams] // wallet_switchEthereumChain rpc call expects an array parameters object
)

let switchChainResult = await metamaskSDK.request(switchChainRequest)
let switchChainResult = await metamaskSDK.switchEthereumChain(chainId: networkSelection
.chainId)

switch switchChainResult {
case .success(_):
Expand Down Expand Up @@ -165,19 +164,18 @@ struct SwitchChainView: View {
}

func addEthereumChain() async {
let addChainParams = AddChainRequest(
let addChainResult = await metamaskSDK.addEthereumChain(
chainId: networkSelection.chainId,
chainName: networkSelection.name,
rpcUrls: networkSelection.rpcUrls
)

let addChainRequest = EthereumRequest(
method: .addEthereumChain,
params: [addChainParams] // wallet_addEthereumChain rpc call expects an array parameters object
rpcUrls: networkSelection.rpcUrls,
iconUrls: [],
blockExplorerUrls: nil,
nativeCurrency: NativeCurrency(
name: networkSelection.name,
symbol: networkSelection.symbol,
decimals: 18)
)

let addChainResult = await metamaskSDK.request(addChainRequest)

switch addChainResult {
case .success:
alert = AlertInfo(
Expand All @@ -200,20 +198,6 @@ struct SwitchChainView: View {
}
}

struct AddChainRequest: CodableData {
let chainId: String
let chainName: String
let rpcUrls: [String]

public func socketRepresentation() -> NetworkData {
[
"chainId": chainId,
"chainName": chainName,
"rpcUrls": rpcUrls
]
}
}

struct SwitchChainView_Previews: PreviewProvider {
static var previews: some View {
SwitchChainView()
Expand Down
2 changes: 1 addition & 1 deletion Example/metamask-ios-sdk/TransactionView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ struct TransactionView: View {

let transactionResult = isConnectWith
? await metamaskSDK.connectWith(transactionRequest)
: await metamaskSDK.request(transactionRequest)
: await metamaskSDK.sendTransaction(from: metamaskSDK.account, to: to, amount: amount)

showProgressView = false

Expand Down
34 changes: 18 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Alternatively, you can add the URL directly in your project's package file:
dependencies: [
.package(
url: "https://github.com/MetaMask/metamask-ios-sdk",
from: "0.5.1"
from: "0.5.2"
)
]
```
Expand All @@ -76,7 +76,7 @@ let appMetadata = AppMetadata(name: "Dub Dapp", url: "https://dubdapp.com")

@ObservedObject var metamaskSDK = MetaMaskSDK.shared(appMetadata)

metamaskSDK.connect()
let connectResult = await metamaskSDK.connect()
```

By default, MetaMask logs three SDK events: `connectionRequest`, `connected`, and `disconnected`.
Expand All @@ -88,14 +88,15 @@ To disable this, set `metamaskSDK.enableDebug = false`.
You can now call any [JSON-RPC API method](https://docs.metamask.io/wallet/reference/eth_subscribe/)
using `metamaskSDK.request()`.

We have provided convenience methods for most common rpc calls so that you do not have to manually construct rpc requests. However, if you wish to provide a more fine-grained request not catered for by the convenience methods you can construct a request and then call `metamaskSDK.request(EthereumRequest)`

#### Example: Get chain ID

The following example gets the user's chain ID by calling
[`eth_chainId`](https://docs.metamask.io/wallet/reference/eth_chainid/).

```swift
let chainIdRequest = EthereumRequest(method: .ethChainId)
let chainId = await metamaskSDK.request(chainIdRequest)
let result = await metamaskSDK.getChainId()
```

#### Example: Get account balance
Expand All @@ -106,27 +107,28 @@ The following example gets the user's account balance by calling
```swift

// Create parameters
let account = metamaskSDK.account

let parameters: [String] = [
account, // account to check for balance
"latest" // "latest", "earliest" or "pending" (optional)
]

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

// Make request
let accountBalance = await metamaskSDK.request(getBalanceRequest)
let accountBalance = await metamaskSDK.getEthBalance(address: selectedAddress, block: "latest")
```

#### Example: Send transaction

The following example sends a transaction by calling
[`eth_sendTransaction`](https://docs.metamask.io/wallet/reference/eth_sendtransaction/).

**Use convenience method**
```swift
let selectedAddress = metamaskSDK.account

let result = await metamaskSDK.sendTransaction(
from: selectedAddress,
to: "0x...", // recipient address
value: "0x....." // amount
)
```

**Use a dictionary**

If your request parameters make up a simple dictionary of string key-value pairs, you can use the
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//
// AddChainParameters.swift
// metamask-ios-sdk
//


import Foundation

public struct AddChainParameters: CodableData {
public let chainId: String
public let chainName: String
public let rpcUrls: [String]
public let iconUrls: [String]?
public let blockExplorerUrls: [String]?
public let nativeCurrency: NativeCurrency

public func socketRepresentation() -> NetworkData {
[
"chainId": chainId,
"chainName": chainName,
"rpcUrls": rpcUrls,
"iconUrls": iconUrls ?? [],
"blockExplorerUrls": blockExplorerUrls ?? [],
"nativeCurrency": nativeCurrency.socketRepresentation()
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//
// NativeCurrency.swift
// metamask-ios-sdk

import Foundation

public struct NativeCurrency: CodableData {
public let name: String?
public let symbol: String
public let decimals: Int

public init(name: String?, symbol: String, decimals: Int) {
self.name = name
self.symbol = symbol
self.decimals = decimals
}

public func socketRepresentation() -> NetworkData {
[
"name": name ?? "",
"symbol": symbol,
"decimals": decimals
]
}
}
Loading

0 comments on commit 4fe9251

Please sign in to comment.