Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rainbow opens, but connection is not made #147

Open
itsallmememe opened this issue May 30, 2023 · 1 comment
Open

Rainbow opens, but connection is not made #147

itsallmememe opened this issue May 30, 2023 · 1 comment

Comments

@itsallmememe
Copy link

I'm trying to integrate the WalletConnect v2 Swift SDK into out iOS App.

The code below does not create any runtime errors that I can see. A uri is created and Rainbow does open, but there's no connection attempt.

Can you help me debug please?

I set up WalletConnect as follows

        Networking.configure(projectId: Self.ProjectId, socketFactory: WebSocketWrapper(url: url))

        let metadata = AppMetadata(name: "Source",
                                   description: "A mobile application acting as a Dapp to connect to a crypto wallet using the WalletConnect SDK",
                                   url: Self.ClientUrl.absoluteString,
                                   icons: ["https://i.ebayimg.com/images/g/5qgAAOSwoBtW3zvq/s-l400.jpg"])

        Pair.configure(metadata: metadata)
        Auth.configure(crypto: Web3Signer())

And I then initiate the contact with this. The RequestParams code is taken from your demo project and needs amended slightly.

private func connect(wallet: WalletConnectType) {
        Task {
            let uri = try await Pair.instance.create()
            try await Auth.instance.request(.stub(), topic: uri.topic)

            var urlComponents = URLComponents()
            urlComponents.scheme = "https"
            urlComponents.host = "rnbwapp.com"
            urlComponents.path = "/wc"
            urlComponents.queryItems = [URLQueryItem(name: "uri", value: uri.deeplinkUri)]

            let url = urlComponents.url

            await UIApplication.shared.open(url!)
        }
    }

private extension RequestParams {
    static func stub(
        domain: String = "service.invalid",
        chainId: String = "eip155:1",
        nonce: String = "32891756",
        aud: String = "https://service.invalid/login",
        nbf: String? = nil,
        exp: String? = nil,
        statement: String? = "I accept the ServiceOrg Terms of Service: https://service.invalid/tos",
        requestId: String? = nil,
        resources: [String]? = ["ipfs://bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq/", "https://example.com/my-web2-claim.json"]
    ) -> RequestParams {
        return RequestParams(
            domain: domain,
            chainId: chainId,
            nonce: nonce,
            aud: aud,
            nbf: nbf,
            exp: exp,
            statement: statement,
            requestId: requestId,
            resources: resources
        )
    }
}

Here's the Web3Signer

public struct Web3Signer: EthereumSigner, CryptoProvider {
    public func sign(message: Data, with key: Data) throws -> EthereumSignature {
        let privateKey = try EthereumPrivateKey(privateKey: [UInt8](key))
        let signature = try privateKey.sign(message: message.bytes)
        return EthereumSignature(v: UInt8(signature.v), r: signature.r, s: signature.s)
    }

    public func recoverPubKey(signature: EthereumSignature, message: Data) throws -> Data {
        let publicKey = try EthereumPublicKey(
            message: message.bytes,
            v: EthereumQuantity(quantity: BigUInt(signature.v)),
            r: EthereumQuantity(signature.r),
            s: EthereumQuantity(signature.s)
        )
        return Data(publicKey.rawPublicKey)
    }

    public func keccak256(_ data: Data) -> Data {
        let digest = SHA3(variant: .keccak256)
        let hash = digest.calculate(for: [UInt8](data))
        return Data(hash)
    }
}

And the SocketFactory

struct SocketFactory: WebSocketFactory {
    func create(with url: URL) -> WebSocketConnecting {
        return WebSocketWrapper(url: url)
    }
}

enum WebSocketWrapperError: Error {
    case disconnected(String, UInt16)
}

class WebSocketWrapper {
    private let websocket: WebSocket

    var request: URLRequest {
        didSet {
            websocket.request = request
        }
    }

    var isConnected: Bool = false
    var onConnect: (() -> Void)?
    var onDisconnect: ((Error?) -> Void)?

    var onText: ((String) -> Void)?

    init(url: URL) {
        request = URLRequest(url: url)
        request.addValue("relay.walletconnect.com", forHTTPHeaderField: "Origin")

        websocket = WebSocket(request: request)
        websocket.delegate = self
    }

}

extension WebSocketWrapper: WebSocketDelegate {
    func didReceive(event: Starscream.WebSocketEvent, client: Starscream.WebSocket) {
        switch event {
        case .connected(_):
            isConnected = true
            onConnect?()

        case let .disconnected(string, code):
            isConnected = false
            onDisconnect?(WebSocketWrapperError.disconnected(string, code))

        case .text(let text):
            onText?(text)

        case .binary(_): break
        case .cancelled: break
        case .error(_): break
        case .ping(_): break
        case .pong(_): break
        case .reconnectSuggested(_): break
        case .viabilityChanged(_): break
        }
    }
}

extension WebSocketWrapper: WebSocketConnecting {
    func connect() {
        websocket.connect()
    }

    func disconnect() {
        websocket.disconnect()
    }

    func write(string: String, completion: (() -> Void)?) {
        websocket.write(data: string.data(using: .utf8) ?? Data(), completion: completion)
    }
}
@itsallmememe
Copy link
Author

To give more information we need to use WalletConnect for two reasons

  • verify that a user has access to a wallet - I assume I use Auth here?
  • sign a transaction - I assume I use Sign here

So, in total can you

  • confirm that these assumptions are correct?
  • help us diagnose the issue with the code above?
  • help us understand what data is required for RequestParams
  • advise on how we use Sign to sign a transaction

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant