zhuguoqing ff550d5d6a init
2022-05-22 10:32:02 +08:00

214 lines
6.3 KiB
Swift

//
// WalletUtils.swift
// MyDapp
//
// Created by on 2022/4/22.
//
import Foundation
import WalletConnectSwift
import UIKit
import StoreKit
// Wallet list -> https://registry.walletconnect.org/data/wallets.json
enum Wallet: String {
case metaMask = "https://metamask.app.link" //ok io.metamask
case imtoken = "imtokenv2:/" //ok im.token.app
case alphawallet = "https://aw.app" //ok com.stormbird.alphawallet
//https://apps.apple.com/us/app/metamask/id1438144202
//https://apps.apple.com/us/app/imtoken-btc-eth-wallet/id1384798940
//https://apps.apple.com/us/app/alphawallet-eth-wallet/id1358230430
}
@objcMembers
class WalletUtils:NSObject {
@Published var accountId: String?
//Keep strong reference to client!!
private (set) var client: Client?
private (set) var wcURL: WCURL?
private (set) var wallet: Wallet?
var signData = """
{
"types": {
"EIP712Domain": [
{
"name": "name",
"type": "string"
},
{
"name": "version",
"type": "string"
}
],
"set": [
{
"name": "tips",
"type": "string"
},
{
"name": "nonce",
"type": "string"
}
]
},
"primaryType": "set",
"domain": {
"name": "Auth",
"version": "1"
},
"message": {
"tips":"sign request",
"nonce":"tobechange"
}
}
"""
func walletSign(param:String){
var finalSign = signData.replacingOccurrences(of:"tobechange",with: param)
openDeepLink()
try? client!.eth_signTypedData(url: wcURL!, account: accountId!, message:finalSign) {
[weak self] res in
var sign = try? res.result(as: String.self)
AppController.signOK(sign)
}
}
func connectMetaMask() {
self.wallet = .metaMask
if(detectInstalled(URLString: "metamask://")){
commonConnect()
}else{
let str = "https://apps.apple.com/us/app/metamask/id1438144202"
AppController.openSocialUrl(str)
}
}
func connectimToken() {
self.wallet = .imtoken
if(detectInstalled(URLString: "imtokenv2://")){
commonConnect()
}else{
let str = "https://apps.apple.com/us/app/imtoken-btc-eth-wallet/id1384798940"
AppController.openSocialUrl(str)
}
}
func connectAlphaWallet() {
self.wallet = .alphawallet
if(detectInstalled(URLString: "awallet://")){
commonConnect()
}else{
let str = "https://apps.apple.com/us/app/alphawallet-eth-wallet/id1358230430"
AppController.openSocialUrl(str)
}
}
func detectInstalled(URLString: String?)->Bool{
if let URLString = URLString, let exsistURL = URL(string: URLString), UIApplication.shared.canOpenURL(exsistURL) {
return true
} else {
return false
}
}
func commonConnect(){
let bridge = "https://safe-walletconnect.gnosis.io"
guard let key = randomKey(),
let bridgeURL = URL(string: bridge) else {
return
}
let meta = Session.ClientMeta(name: "CEBG",
description: "CEBG",
icons: [],
url: URL(string: "http://cebg.games/")!)
let info = Session.DAppInfo(peerId: UUID().uuidString,
peerMeta: meta)
wcURL = WCURL(topic: UUID().uuidString,
bridgeURL: bridgeURL,
key: key)
client = Client(delegate: self, dAppInfo: info)
do {
try client?.connect(to: wcURL!)
print("Connect to", wcURL?.absoluteString ?? "")
} catch {
print("Can't connect", error)
}
}
private func openDeepLink() {
guard let wallet = wallet,
let wcURL = wcURL,
let uri = wcURL.absoluteString.addingPercentEncoding(withAllowedCharacters: .alphanumerics),
let url = URL(string: "\(wallet.rawValue)/wc?uri=\(uri)"),
UIApplication.shared.canOpenURL(url) else {
print("Can't create deeplink")
return
}
print("okokokoko",url)
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
private func randomKey() -> String? {
var bytes = [Int8](repeating: 0, count: 32)
let status = SecRandomCopyBytes(kSecRandomDefault, bytes.count, &bytes)
if status == errSecSuccess {
return Data(bytes: bytes, count: 32).toHexString()
} else {
return nil
}
}
}
//MARK: - ClientDelegate
extension WalletUtils: ClientDelegate {
func client(_ client: Client, didFailToConnect url: WCURL) {
print("Did fail to connect to URL", url)
}
func client(_ client: Client, didConnect url: WCURL) {
print("Did connect to URL", url)
// Connection to brigde established
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
self.openDeepLink()
}
}
func client(_ client: Client, didConnect session: Session) {
print("Did connect to session", session)
// Successfully connected to session
print("链id", session.walletInfo?.chainId)
if(session.walletInfo?.chainId==321){
accountId = session.walletInfo?.accounts.first
AppController.connectOK(accountId)
}else{
AppController.showToast("Your wallet should support KCC chain!")
}
}
func client(_ client: Client, didDisconnect session: Session) {
print("Did disconnect from session", session)
}
func client(_ client: Client, didUpdate session: Session) {
print("Session did update", session)
}
}