feat(wallet) activate Wallet connect modal from deep-links

- Open wallet connect modal when the application is opened from a
  deep link
- Add test entry that opens wallet connect modal with mocked
  StatusDesktop app that can be used for testing
- Add tests

Closes #12641
This commit is contained in:
Stefan 2023-12-01 22:43:21 +03:00 committed by Stefan Dunca
parent d2b2aae000
commit a8fb355a8d
32 changed files with 20576 additions and 39 deletions

View File

@ -830,8 +830,10 @@ run-windows: nim_status_client $(NIM_WINDOWS_PREBUILT_DLLS)
PATH="$(DOTHERSIDE_LIBDIR)":"$(STATUSGO_LIBDIR)":"$(STATUSKEYCARDGO_LIBDIR)":"$(shell pwd)"/"$(shell dirname "$(NIM_WINDOWS_PREBUILT_DLLS)")":"$(PATH)" \ PATH="$(DOTHERSIDE_LIBDIR)":"$(STATUSGO_LIBDIR)":"$(STATUSKEYCARDGO_LIBDIR)":"$(shell pwd)"/"$(shell dirname "$(NIM_WINDOWS_PREBUILT_DLLS)")":"$(PATH)" \
./bin/nim_status_client.exe $(ARGS) ./bin/nim_status_client.exe $(ARGS)
NIM_TEST_FILES := $(wildcard test/nim/*.nim)
tests-nim-linux: | dotherside tests-nim-linux: | dotherside
LD_LIBRARY_PATH="$(QT5_LIBDIR):$(LD_LIBRARY_PATH)" \ LD_LIBRARY_PATH="$(QT5_LIBDIR):$(LD_LIBRARY_PATH)" \
$(ENV_SCRIPT) nim c $(NIM_PARAMS) $(NIM_EXTRA_PARAMS) -r test/nim/message_model_test.nim $(foreach nimfile,$(NIM_TEST_FILES),$(ENV_SCRIPT) nim c $(NIM_PARAMS) $(NIM_EXTRA_PARAMS) -r $(nimfile);)
endif # "variables.mk" was not included endif # "variables.mk" was not included

View File

@ -6,6 +6,7 @@ import backend/wallet_connect as backend_wallet_connect
import app/global/global_singleton import app/global/global_singleton
import app/core/eventemitter import app/core/eventemitter
import app/core/signals/types import app/core/signals/types
import app/global/app_signals
import app_service/common/utils as common_utils import app_service/common/utils as common_utils
from app_service/service/transaction/dto import PendingTransactionTypeDto from app_service/service/transaction/dto import PendingTransactionTypeDto
@ -14,7 +15,7 @@ import app_service/service/wallet_account/service as wallet_account_service
import app/modules/shared_modules/keycard_popup/io_interface as keycard_shared_module import app/modules/shared_modules/keycard_popup/io_interface as keycard_shared_module
import constants import constants
import tx_response_dto, helper import tx_response_dto, helpers
const UNIQUE_WC_SESSION_REQUEST_SIGNING_IDENTIFIER* = "WalletConnect-SessionRequestSigning" const UNIQUE_WC_SESSION_REQUEST_SIGNING_IDENTIFIER* = "WalletConnect-SessionRequestSigning"
const UNIQUE_WC_AUTH_REQUEST_SIGNING_IDENTIFIER* = "WalletConnect-AuthRequestSigning" const UNIQUE_WC_AUTH_REQUEST_SIGNING_IDENTIFIER* = "WalletConnect-AuthRequestSigning"
@ -37,6 +38,8 @@ QtObject:
proc finishSessionRequest(self: Controller, signature: string) proc finishSessionRequest(self: Controller, signature: string)
proc finishAuthRequest(self: Controller, signature: string) proc finishAuthRequest(self: Controller, signature: string)
proc requestOpenWalletConnectPopup*(self: Controller, uri: string) {.signal.}
proc setup(self: Controller) = proc setup(self: Controller) =
self.QObject.setup self.QObject.setup
@ -46,6 +49,12 @@ QtObject:
discard discard
) )
self.events.on(SIGNAL_STATUS_URL_ACTIVATED) do(e: Args):
var args = StatusUrlArgs(e)
let (found, wcUri) = extractAndCheckUriParameter(args.url)
if found:
self.requestOpenWalletConnectPopup(wcUri)
self.events.on(SIGNAL_SHARED_KEYCARD_MODULE_DATA_SIGNED) do(e: Args): self.events.on(SIGNAL_SHARED_KEYCARD_MODULE_DATA_SIGNED) do(e: Args):
let args = SharedKeycarModuleArgs(e) let args = SharedKeycarModuleArgs(e)
if args.uniqueIdentifier != UNIQUE_WC_SESSION_REQUEST_SIGNING_IDENTIFIER and if args.uniqueIdentifier != UNIQUE_WC_SESSION_REQUEST_SIGNING_IDENTIFIER and

View File

@ -1,4 +1,5 @@
import json, strutils import json, strutils
import uri
include app_service/common/json_utils include app_service/common/json_utils
@ -25,3 +26,16 @@ proc getRequestMethod*(jsonObj: JsonNode): RequestMethod =
discard discard
return RequestMethod.Unknown return RequestMethod.Unknown
# check and extract Wallet Connect URI parameter from a deep link updated URL
proc extractAndCheckUriParameter*(url: string): (bool, string) =
let parsedUrl = parseUri(url)
if parsedUrl.path != "/wc":
return (false, "")
for (key, value) in decodeQuery(parsedUrl.query):
if key.toLower == "uri":
if value.startsWith("wc:"):
return (true, value)
return (false, "")

View File

@ -33,21 +33,8 @@ Item {
url: `${pagesFolder}/../stubs/AppLayouts/Wallet/views/walletconnect/src/index.html` url: `${pagesFolder}/../stubs/AppLayouts/Wallet/views/walletconnect/src/index.html`
controller: WalletConnectController { controller: WalletConnectController {
pairSessionProposal: function(sessionProposalJson) { sessionProposal: function(sessionProposalJson) {
proposeUserPair(sessionProposalJson, `{"eip155":{"methods":[ respondSessionProposal(sessionProposalJson, `{"eip155":{"methods":["eth_sendTransaction","eth_sendRawTransaction","personal_sign","eth_sign","eth_signTransaction","eth_signTypedData","wallet_switchEthereumChain"],"chains":["eip155:5"],"events":["accountsChanged","chainChanged"],"accounts":["eip155:5:0xE2d622C817878dA5143bBE06866ca8E35273Ba8a"]}}`, "")
"personal_sign",
"eth_sendTransaction",
"eth_signTransaction",
"eth_sign",
"eth_signTypedData",
"eth_signTypedData_v4"
],
"chains":["eip155:5"],
"events":[
"chainChanged",
"accountsChanged"
],
"accounts":["eip155:5:0xBd54A96c0Ae19a220C8E1234f54c940DFAB34639"]}}`)
} }
recordSuccessfulPairing: function(sessionProposalJson) { recordSuccessfulPairing: function(sessionProposalJson) {
@ -57,6 +44,11 @@ Item {
topic: sessionProposal.params.pairingTopic, topic: sessionProposal.params.pairingTopic,
expiry: sessionProposal.params.expiry, expiry: sessionProposal.params.expiry,
active: true, active: true,
peerMetadata: {
name: sessionProposal.params.proposer.metadata.name,
url: sessionProposal.params.proposer.metadata.url,
icons: sessionProposal.params.proposer.metadata.icons,
}
}) })
root.saveListModel(pairingsModel) root.saveListModel(pairingsModel)
} }
@ -64,7 +56,7 @@ Item {
var found = false var found = false
for (var i = 0; i < pairingsModel.count; i++) { for (var i = 0; i < pairingsModel.count; i++) {
if (pairingsModel.get(i).topic === pairingTopic) { if (pairingsModel.get(i).topic === pairingTopic) {
pairingsModel.get.active = false pairingsModel.get(i).active = false
found = true found = true
break; break;
} }
@ -156,6 +148,23 @@ Item {
clip: true clip: true
} }
RowLayout {
StatusButton {
text: "Trigger Deep-Link"
onClicked: {
wc.controller.requestOpenWalletConnectPopup(deepLinkInput.text)
}
}
StatusInput {
id: deepLinkInput
Layout.preferredWidth: 300
placeholderText: "wc:a4f32854428af0f5b66...."
}
}
// spacer // spacer
ColumnLayout {} ColumnLayout {}
} }

View File

@ -6,21 +6,22 @@ import QtQuick.Layouts 1.15
Item { Item {
id: root id: root
signal proposeUserPair(string sessionProposalJson, string supportedNamespacesJson)
// function pairSessionProposal(/*string*/ sessionProposalJson) // function sessionProposal(/*string*/ sessionProposalJson)
required property var pairSessionProposal required property var sessionProposal
// function pairSessionRequest(/*string*/ sessionRequestJson) // function pairSessionRequest(/*string*/ sessionRequestJson)
required property var recordSuccessfulPairing required property var recordSuccessfulPairing
// function deletePairing(/*string*/ topic) // function deletePairing(/*string*/ topic)
required property var deletePairing required property var deletePairing
signal respondSessionProposal(string sessionProposalJson, string supportedNamespacesJson, string error)
signal respondSessionRequest(string sessionRequestJson, string signedJson, bool error) signal respondSessionRequest(string sessionRequestJson, string signedJson, bool error)
signal requestOpenWalletConnectPopup(string uri)
signal respondAuthRequest(string signature, string error)
// function sessionRequest(/*string*/ sessionRequestJson, /*string*/ password) // function sessionRequest(/*string*/ sessionRequestJson, /*string*/ password)
required property var sessionRequest required property var sessionRequest
required property bool hasActivePairings required property bool hasActivePairings
required property string projectId required property string projectId
} }

View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>App and Integration</title>
<style>
iframe {
width: 50vh;
height: 100%;
border: none;
}
</style>
</head>
<body>
<h2>App Page</h2>
<iframe src="http://localhost:8080"></iframe>
<h2>Wallet Page</h2>
<iframe src="http://localhost:8081"></iframe>
</body>
</html>

View File

@ -0,0 +1,51 @@
/*
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
(self["webpackChunkwallet_connect_modal_test"] = self["webpackChunkwallet_connect_modal_test"] || []).push([["_8131-_4f7e-_ed1b-_d17e"],{
/***/ "?8131":
/*!************************!*\
!*** buffer (ignored) ***!
\************************/
/***/ (() => {
eval("/* (ignored) */\n\n//# sourceURL=webpack://wallet_connect_modal_test/buffer_(ignored)?");
/***/ }),
/***/ "?4f7e":
/*!********************************!*\
!*** ./util.inspect (ignored) ***!
\********************************/
/***/ (() => {
eval("/* (ignored) */\n\n//# sourceURL=webpack://wallet_connect_modal_test/./util.inspect_(ignored)?");
/***/ }),
/***/ "?ed1b":
/*!**********************!*\
!*** util (ignored) ***!
\**********************/
/***/ (() => {
eval("/* (ignored) */\n\n//# sourceURL=webpack://wallet_connect_modal_test/util_(ignored)?");
/***/ }),
/***/ "?d17e":
/*!**********************!*\
!*** util (ignored) ***!
\**********************/
/***/ (() => {
eval("/* (ignored) */\n\n//# sourceURL=webpack://wallet_connect_modal_test/util_(ignored)?");
/***/ })
}])

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,6 @@
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
github.com/webview/webview_go v0.0.0-20230901181450-5a14030a9070 h1:imZLWyo1ondeQjqfb/eHuYgFiOAYg6ugSMCnGfPTPmg=
github.com/webview/webview_go v0.0.0-20230901181450-5a14030a9070/go.mod h1:yE65LFCeWf4kyWD5re+h4XNvOHJEXOCOuJZ4v8l5sgk=
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71 h1:X/2sJAybVknnUnV7AD2HdT6rm2p5BP6eH2j+igduWgk=
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

View File

@ -0,0 +1,57 @@
package main
import (
"log"
"math/rand"
"net/http"
"strconv"
"time"
"github.com/pkg/browser"
webview "github.com/webview/webview_go"
)
func main() {
// Serve files from the ./generated directory
fileServer := http.FileServer(http.Dir("./generated"))
// Serve the index.html file on the root path "/"
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
// Set cache-control headers before serving the file
w.Header().Set("Cache-Control", "no-store, no-cache, must-revalidate, post-check=0, pre-check=0")
if r.URL.Path != "/" {
// Let the file server handle non-root requests
fileServer.ServeHTTP(w, r)
return
}
// Serve the root path
http.ServeFile(w, r, "./src/index.html")
})
openExternally := true
r := rand.New(rand.NewSource(time.Now().UnixNano()))
port := strconv.Itoa(10000 + r.Intn(9999))
pageURL := "http://localhost:" + port
if openExternally {
err := browser.OpenURL(pageURL)
if err != nil {
log.Fatal(err)
}
http.ListenAndServe(":"+port, nil)
} else {
// Start WebView
w := webview.New(true)
defer w.Destroy()
w.SetTitle("WC modal")
w.SetSize(1280, 1024, webview.HintNone)
go http.ListenAndServe(":"+port, nil)
w.Navigate(pageURL)
w.Run()
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,23 @@
{
"name": "wallet_connect_modal_test",
"version": "0.1.0",
"description": "Wallet Connect Modal Test",
"private": true,
"devDependencies": {
"webpack": "^5.89.0",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^4.15.1"
},
"license": "MPL-2.0",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --mode production",
"build:dev": "webpack --mode development",
"start": "webpack serve --mode development --open"
},
"dependencies": {
"@wagmi/core": "^1.4.7",
"@web3modal/wagmi": "^3.4.0",
"viem": "^1.19.11"
}
}

View File

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>WC Modal test</title>
<script type="module" src="./bundle.js" defer></script>
</head>
<body>
<p>Test</p>
<w3m-button />
</body>
</html>

View File

@ -0,0 +1,56 @@
import { createWeb3Modal, walletConnectProvider, EIP6963Connector } from '@web3modal/wagmi'
import { configureChains, createConfig } from '@wagmi/core'
import { goerli } from 'viem/chains'
import { publicProvider } from '@wagmi/core/providers/public'
import { InjectedConnector } from '@wagmi/core'
import { CoinbaseWalletConnector } from '@wagmi/core/connectors/coinbaseWallet'
import { WalletConnectConnector } from '@wagmi/core/connectors/walletConnect'
const projectId = '0ff537ebcebc5ce0947866d3a90e0ebf'
const { chains, publicClient } = configureChains([goerli], [
walletConnectProvider({ projectId }),
publicProvider()
])
const metadata = {
name: 'Test Web3Modal',
description: 'Web3Modal Test',
url: 'https://web3modal.com',
icons: ['https://avatars.githubusercontent.com/u/37784886']
}
const wagmiConfig = createConfig({
autoConnect: true,
connectors: [
new WalletConnectConnector({ chains, options: { projectId, showQrModal: false, metadata } }),
new EIP6963Connector({ chains }),
new InjectedConnector({ chains, options: { shimDisconnect: true } }),
new CoinbaseWalletConnector({ chains, options: { appName: metadata.name } })
],
publicClient
})
const testWalletIds = [
'statusDesktopTest',
'af9a6dfff9e63977bbde28fb23518834f08b696fe8bff6dd6827acad1814c6be' // Status Mobile
]
const modal = createWeb3Modal({ wagmiConfig, projectId, chains,
customWallets: [
{
id: 'statusDesktopTest',
name: 'Status Desktop Test',
homepage: 'https://status.app/', // Optional
image_url: 'https://res.cloudinary.com/dhgck7ebz/image/upload/f_auto,c_limit,w_1080,q_auto/Brand/Logo%20Section/Mark/Mark_01', // Optional
//mobile_link: 'mobile_link', // Optional - Deeplink or universal
desktop_link: 'status-app://', // Optional - Deeplink
//webapp_link: 'webapp_link', // Optional
//app_store: 'app_store', // Optional
//play_store: 'play_store' // Optional
}
],
featuredWalletIds: testWalletIds,
includeWalletIds: testWalletIds
})
modal.open({ view: 'All wallets' })

View File

@ -0,0 +1,22 @@
const path = require('path');
module.exports = {
entry: './src/main.ts',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'generated'),
module: true,
//clean: true,
},
devServer: {
static: path.join(__dirname, "."),
compress: true,
port: 9000,
client: {
overlay: false,
}
},
experiments: {
outputModule: true,
},
};

View File

@ -0,0 +1,283 @@
module main
go 1.20
replace github.com/status-im/status-go => ../../../../vendor/status-go
// Keep these in sync with status-go/go.mod aliases
replace github.com/ethereum/go-ethereum v1.10.26 => github.com/status-im/go-ethereum v1.10.25-status.11
replace github.com/docker/docker => github.com/docker/engine v1.4.2-0.20190717161051-705d9623b7c1
replace github.com/nfnt/resize => github.com/status-im/resize v0.0.0-20201215164250-7c6d9f0d3088
replace github.com/forPelevin/gomoji => github.com/status-im/gomoji v1.1.3-0.20220213022530-e5ac4a8732d4
replace github.com/mutecomm/go-sqlcipher/v4 v4.4.2 => github.com/status-im/go-sqlcipher/v4 v4.5.4-status.2
require (
github.com/ethereum/go-ethereum v1.10.26
github.com/status-im/status-go v0.171.7
github.com/webview/webview_go v0.0.0-20230901181450-5a14030a9070
)
require (
github.com/BurntSushi/toml v1.2.1 // indirect
github.com/PuerkitoBio/goquery v1.6.1 // indirect
github.com/RoaringBitmap/roaring v0.9.4 // indirect
github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46 // indirect
github.com/VictoriaMetrics/fastcache v1.6.0 // indirect
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 // indirect
github.com/anacrolix/chansync v0.3.0 // indirect
github.com/anacrolix/confluence v1.9.0 // indirect
github.com/anacrolix/dht/v2 v2.15.2-0.20220123034220-0538803801cb // indirect
github.com/anacrolix/envpprof v1.1.1 // indirect
github.com/anacrolix/go-libutp v1.2.0 // indirect
github.com/anacrolix/log v0.10.1-0.20220123034749-3920702c17f8 // indirect
github.com/anacrolix/missinggo v1.3.0 // indirect
github.com/anacrolix/missinggo/perf v1.0.0 // indirect
github.com/anacrolix/missinggo/v2 v2.5.2 // indirect
github.com/anacrolix/mmsg v1.0.0 // indirect
github.com/anacrolix/multiless v0.2.0 // indirect
github.com/anacrolix/stm v0.3.0 // indirect
github.com/anacrolix/sync v0.4.0 // indirect
github.com/anacrolix/torrent v1.41.0 // indirect
github.com/anacrolix/upnp v0.1.3-0.20220123035249-922794e51c96 // indirect
github.com/anacrolix/utp v0.1.0 // indirect
github.com/andybalholm/brotli v1.0.5 // indirect
github.com/andybalholm/cascadia v1.2.0 // indirect
github.com/bahlo/generic-list-go v0.2.0 // indirect
github.com/beevik/ntp v0.3.0 // indirect
github.com/benbjohnson/clock v1.3.5 // indirect
github.com/benbjohnson/immutable v0.3.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bits-and-blooms/bitset v1.2.0 // indirect
github.com/bradfitz/iter v0.0.0-20191230175014-e8f45d346db8 // indirect
github.com/btcsuite/btcd v0.22.1 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 // indirect
github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce // indirect
github.com/buger/jsonparser v1.1.1 // indirect
github.com/cenkalti/backoff/v3 v3.2.2 // indirect
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/containerd/cgroups v1.1.0 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/cruxic/go-hmac-drbg v0.0.0-20170206035330-84c46983886d // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect
github.com/deckarep/golang-set v1.8.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/dustin/go-humanize v1.0.0 // indirect
github.com/edsrzf/mmap-go v1.0.0 // indirect
github.com/elastic/gosigar v0.14.2 // indirect
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect
github.com/flynn/noise v1.0.0 // indirect
github.com/fogleman/gg v1.3.0 // indirect
github.com/forPelevin/gomoji v1.1.2 // indirect
github.com/francoispqt/gojay v1.2.13 // indirect
github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect
github.com/go-ole/go-ole v1.2.5 // indirect
github.com/go-playground/locales v0.14.0 // indirect
github.com/go-playground/universal-translator v0.18.0 // indirect
github.com/go-stack/stack v1.8.1 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v4 v4.3.0 // indirect
github.com/golang-migrate/migrate/v4 v4.15.2 // indirect
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/btree v1.0.1 // indirect
github.com/google/gopacket v1.1.19 // indirect
github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/gorilla/securecookie v1.1.1 // indirect
github.com/gorilla/sessions v1.2.1 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-bexpr v0.1.10 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-version v1.2.0 // indirect
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect
github.com/hashicorp/golang-lru/v2 v2.0.2 // indirect
github.com/holiman/bloomfilter/v2 v2.0.3 // indirect
github.com/holiman/uint256 v1.2.0 // indirect
github.com/huandu/xstrings v1.3.2 // indirect
github.com/huin/goupnp v1.2.0 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/ipfs/go-cid v0.4.1 // indirect
github.com/ipfs/go-log/v2 v2.5.1 // indirect
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect
github.com/jellydator/ttlcache/v3 v3.1.0 // indirect
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a // indirect
github.com/jmoiron/sqlx v1.3.5 // indirect
github.com/keighl/metabolize v0.0.0-20150915210303-97ab655d4034 // indirect
github.com/kilic/bls12-381 v0.0.0-20200607163746-32e1441c8a9f // indirect
github.com/klauspost/compress v1.16.7 // indirect
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
github.com/koron/go-ssdp v0.0.4 // indirect
github.com/ladydascalie/currency v1.6.0 // indirect
github.com/leodido/go-urn v1.2.1 // indirect
github.com/lib/pq v1.10.4 // indirect
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
github.com/libp2p/go-cidranger v1.1.0 // indirect
github.com/libp2p/go-flow-metrics v0.1.0 // indirect
github.com/libp2p/go-libp2p v0.29.2 // indirect
github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect
github.com/libp2p/go-libp2p-pubsub v0.9.3 // indirect
github.com/libp2p/go-mplex v0.7.0 // indirect
github.com/libp2p/go-msgio v0.3.0 // indirect
github.com/libp2p/go-nat v0.2.0 // indirect
github.com/libp2p/go-netroute v0.2.1 // indirect
github.com/libp2p/go-reuseport v0.3.0 // indirect
github.com/libp2p/go-yamux/v4 v4.0.1 // indirect
github.com/lucasb-eyer/go-colorful v1.0.3 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect
github.com/mat/besticon v0.0.0-20210314201728-1579f269edb7 // indirect
github.com/mattn/go-colorable v0.1.8 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/meirf/gopart v0.0.0-20180520194036-37e9492a85a8 // indirect
github.com/miekg/dns v1.1.55 // indirect
github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect
github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect
github.com/minio/sha256-simd v1.0.1 // indirect
github.com/mitchellh/mapstructure v1.4.1 // indirect
github.com/mitchellh/pointerstructure v1.2.0 // indirect
github.com/mr-tron/base58 v1.2.0 // indirect
github.com/mschoch/smat v0.2.0 // indirect
github.com/multiformats/go-base32 v0.1.0 // indirect
github.com/multiformats/go-base36 v0.2.0 // indirect
github.com/multiformats/go-multiaddr v0.10.1 // indirect
github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect
github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect
github.com/multiformats/go-multibase v0.2.0 // indirect
github.com/multiformats/go-multicodec v0.9.0 // indirect
github.com/multiformats/go-multihash v0.2.3 // indirect
github.com/multiformats/go-multistream v0.4.1 // indirect
github.com/multiformats/go-varint v0.0.7 // indirect
github.com/mutecomm/go-sqlcipher/v4 v4.4.2 // indirect
github.com/nfnt/resize v0.0.0-00010101000000-000000000000 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/oliamb/cutter v0.2.2 // indirect
github.com/onsi/ginkgo/v2 v2.11.0 // indirect
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 // indirect
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect
github.com/pborman/uuid v1.2.0 // indirect
github.com/pion/datachannel v1.5.2 // indirect
github.com/pion/dtls/v2 v2.1.2 // indirect
github.com/pion/ice/v2 v2.1.20 // indirect
github.com/pion/interceptor v0.1.7 // indirect
github.com/pion/logging v0.2.2 // indirect
github.com/pion/mdns v0.0.5 // indirect
github.com/pion/randutil v0.1.0 // indirect
github.com/pion/rtcp v1.2.9 // indirect
github.com/pion/rtp v1.7.4 // indirect
github.com/pion/sctp v1.8.2 // indirect
github.com/pion/sdp/v3 v3.0.4 // indirect
github.com/pion/srtp/v2 v2.0.5 // indirect
github.com/pion/stun v0.3.5 // indirect
github.com/pion/transport v0.13.0 // indirect
github.com/pion/turn/v2 v2.0.6 // indirect
github.com/pion/udp v0.1.1 // indirect
github.com/pion/webrtc/v3 v3.1.24-0.20220208053747-94262c1b2b38 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_golang v1.16.0 // indirect
github.com/prometheus/client_model v0.4.0 // indirect
github.com/prometheus/common v0.42.0 // indirect
github.com/prometheus/procfs v0.10.1 // indirect
github.com/prometheus/tsdb v0.10.0 // indirect
github.com/quic-go/qpack v0.4.0 // indirect
github.com/quic-go/qtls-go1-19 v0.3.3 // indirect
github.com/quic-go/qtls-go1-20 v0.2.3 // indirect
github.com/quic-go/quic-go v0.36.4 // indirect
github.com/quic-go/webtransport-go v0.5.3 // indirect
github.com/raulk/go-watchdog v1.3.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/rjeczalik/notify v0.9.3 // indirect
github.com/rs/cors v1.7.0 // indirect
github.com/rs/dnscache v0.0.0-20210201191234-295bba877686 // indirect
github.com/russolsen/transit v0.0.0-20180705123435-0794b4c4505a // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/schollz/peerdiscovery v1.7.0 // indirect
github.com/shirou/gopsutil v3.21.5+incompatible // indirect
github.com/shopspring/decimal v1.2.0 // indirect
github.com/siphiuel/lc-proxy-wrapper v0.0.0-20230516150924-246507cee8c7 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/status-im/doubleratchet v3.0.0+incompatible // indirect
github.com/status-im/go-multiaddr-ethv4 v1.2.5 // indirect
github.com/status-im/keycard-go v0.0.0-20200402102358-957c09536969 // indirect
github.com/status-im/markdown v0.0.0-20231114210825-6c2d15b5dc57 // indirect
github.com/status-im/migrate/v4 v4.6.2-status.3 // indirect
github.com/status-im/rendezvous v1.3.7 // indirect
github.com/status-im/status-go/extkeys v1.1.2 // indirect
github.com/status-im/tcp-shaker v0.0.0-20191114194237-215893130501 // indirect
github.com/status-im/zxcvbn-go v0.0.0-20220311183720-5e8676676857 // indirect
github.com/stretchr/testify v1.8.4 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a // indirect
github.com/tklauser/go-sysconf v0.3.6 // indirect
github.com/tklauser/numcpus v0.2.2 // indirect
github.com/tsenart/tb v0.0.0-20181025101425-0d2499c8b6e9 // indirect
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
github.com/urfave/cli/v2 v2.24.4 // indirect
github.com/vacp2p/mvds v0.0.24-0.20201124060106-26d8e94130d8 // indirect
github.com/waku-org/go-discover v0.0.0-20221209174356-61c833f34d98 // indirect
github.com/waku-org/go-libp2p-rendezvous v0.0.0-20230628220917-7b4e5ae4c0e7 // indirect
github.com/waku-org/go-waku v0.8.1-0.20231103161423-351dd55a1498 // indirect
github.com/waku-org/go-zerokit-rln v0.1.14-0.20230916173259-d284a3d8f2fd // indirect
github.com/waku-org/go-zerokit-rln-apple v0.0.0-20230916172309-ee0ee61dde2b // indirect
github.com/waku-org/go-zerokit-rln-arm v0.0.0-20230916171929-1dd9494ff065 // indirect
github.com/waku-org/go-zerokit-rln-x86_64 v0.0.0-20230916171518-2a77c3734dd1 // indirect
github.com/wealdtech/go-ens/v3 v3.5.0 // indirect
github.com/wealdtech/go-multicodec v1.4.0 // indirect
github.com/wk8/go-ordered-map v1.0.0 // indirect
github.com/wk8/go-ordered-map/v2 v2.1.7 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
github.com/yeqown/go-qrcode/v2 v2.2.1 // indirect
github.com/yeqown/go-qrcode/writer/standard v1.2.1 // indirect
github.com/yeqown/reedsolomon v1.0.0 // indirect
github.com/zenthangplus/goccm v0.0.0-20211005163543-2f2e522aca15 // indirect
go.etcd.io/bbolt v1.3.6 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/dig v1.17.0 // indirect
go.uber.org/fx v1.20.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.24.0 // indirect
golang.org/x/crypto v0.12.0 // indirect
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 // indirect
golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb // indirect
golang.org/x/mod v0.12.0 // indirect
golang.org/x/net v0.14.0 // indirect
golang.org/x/sync v0.3.0 // indirect
golang.org/x/sys v0.11.0 // indirect
golang.org/x/text v0.13.0 // indirect
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af // indirect
golang.org/x/tools v0.12.1-0.20230818130535-1517d1a3ba60 // indirect
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/go-playground/validator.v9 v9.31.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
lukechampine.com/blake3 v1.2.1 // indirect
modernc.org/libc v1.11.82 // indirect
modernc.org/mathutil v1.4.1 // indirect
modernc.org/memory v1.0.5 // indirect
modernc.org/sqlite v1.14.2-0.20211125151325-d4ed92c0a70f // indirect
olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3 // indirect
zombiezen.com/go/sqlite v0.8.0 // indirect
)

View File

@ -153,7 +153,7 @@ func main() {
// Start a local server to serve the files // Start a local server to serve the files
http.HandleFunc("/bundle.js", func(w http.ResponseWriter, r *http.Request) { http.HandleFunc("/bundle.js", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Cache-Control", "no-store, no-cache, must-revalidate, post-check=0, pre-check=0") w.Header().Set("Cache-Control", "no-store, no-cache, must-revalidate, post-check=0, pre-check=0")
http.ServeFile(w, r, "../../../ui/app/AppLayouts/Wallet/views/walletconnect/sdk/generated/bundle.js") http.ServeFile(w, r, "../../../../ui/app/AppLayouts/Wallet/views/walletconnect/sdk/generated/bundle.js")
}) })
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
@ -161,9 +161,9 @@ func main() {
http.ServeFile(w, r, "./index.html") http.ServeFile(w, r, "./index.html")
}) })
go http.ListenAndServe(":8080", nil) go http.ListenAndServe(":8081", nil)
w.Navigate("http://localhost:8080") w.Navigate("http://localhost:8081")
w.Run() w.Run()
} }

View File

@ -1,12 +1,12 @@
import unittest import unittest
import ../../../src/app_service/common/types import app_service/common/types
import ../../../src/app_service/service/contacts/dto/contact_details import app_service/service/contacts/dto/contact_details
import ../../../src/app_service/service/message/dto/message import app_service/service/message/dto/message
import ../../../src/app/modules/shared_models/message_model import app/modules/shared_models/message_model
import ../../../src/app/modules/shared_models/message_item import app/modules/shared_models/message_item
import ../../../src/app/modules/shared_models/message_transaction_parameters_item import app/modules/shared_models/message_transaction_parameters_item
proc createTestMessageItem(id: string, clock: int64): Item = proc createTestMessageItem(id: string, clock: int64): Item =
return initItem( return initItem(

View File

@ -0,0 +1,29 @@
import unittest
import app/modules/main/wallet_section/wallet_connect/helpers
suite "wallet connect":
test "parse deep link url":
const testUrl = "https://status.app/wc?uri=wc%3Aa4f32854428af0f5b6635fb7a3cb2cfe174eaad63b9d10d52ef1c686f8eab862%402%3Frelay-protocol%3Dirn%26symKey%3D4ccbae2b4c81c26fbf4a6acee9de2771705d467de9a1d24c80240e8be59de6be"
let (resOk, wcUri) = extractAndCheckUriParameter(testUrl)
check(resOk)
check(wcUri == "wc:a4f32854428af0f5b6635fb7a3cb2cfe174eaad63b9d10d52ef1c686f8eab862@2?relay-protocol=irn&symKey=4ccbae2b4c81c26fbf4a6acee9de2771705d467de9a1d24c80240e8be59de6be")
test "parse another valid deep link url":
const testUrl = "https://status.app/notwc?uri=lt%3Asomevalue"
let (resOk, wcUri) = extractAndCheckUriParameter(testUrl)
check(not resOk)
check(wcUri == "")
test "parse a WC no-prefix deeplink":
const testUrl = "https://status.app/wc?uri=w4%3Atest"
let (resOk, wcUri) = extractAndCheckUriParameter(testUrl)
check(not resOk)
check(wcUri == "")

View File

@ -22,7 +22,7 @@ ListView {
width: root.width width: root.width
StatusIcon { StatusIcon {
icon: model.peerMetadata.icons.length > 0? model.peerMetadata.icons[0] : "" icon: model.peerMetadata.icons.length > 0 ? model.peerMetadata.icons[0] : ""
visible: !!icon visible: !!icon
} }

View File

@ -32,4 +32,11 @@ Item {
root.controller.deletePairing(deletePayload.topic) root.controller.deletePairing(deletePayload.topic)
} }
} }
Connections {
target: root.controller
function onRequestOpenWalletConnectPopup(uri) {
modal.openWithUri(uri)
}
}
} }

View File

@ -19,8 +19,6 @@ Popup {
clip: true clip: true
property bool sdkReady: d.state === d.sdkReadyState
// wallet_connect.Controller \see wallet_section/wallet_connect/controller.nim // wallet_connect.Controller \see wallet_section/wallet_connect/controller.nim
required property var controller required property var controller
@ -32,6 +30,19 @@ Popup {
root.open() root.open()
} }
function openWithUri(uri) {
pairLinkInput.text = uri
root.open()
if (root.sdk.sdkReady) {
d.setStatusText("Pairing from deeplink ...")
sdk.pair(uri)
} else {
d.pairModalUriWhenReady = uri
}
}
Flickable { Flickable {
id: flickable id: flickable
@ -257,15 +268,22 @@ Popup {
Connections { Connections {
target: root.sdk target: root.sdk
function onSdkReadyChanged() {
if (root.sdk.sdkReady && d.pairModalUriWhenReady) {
d.setStatusText("Lazy pairing from deeplink ...")
sdk.pair(d.pairModalUriWhenReady)
d.pairModalUriWhenReady = ""
}
}
function onSdkInit(success, info) { function onSdkInit(success, info) {
d.setDetailsText(info) d.setDetailsText(info)
if (success) { if (success) {
d.setStatusText("Ready to pair or auth") d.setStatusText("Ready to pair or auth")
d.state = d.sdkReadyState
} else { } else {
d.setStatusText("SDK Error", "red") d.setStatusText("SDK Error", "red")
d.state = ""
} }
d.state = ""
} }
function onSessionProposal(sessionProposal) { function onSessionProposal(sessionProposal) {
@ -282,13 +300,13 @@ Popup {
root.controller.recordSuccessfulPairing(JSON.stringify(sessionProposal)) root.controller.recordSuccessfulPairing(JSON.stringify(sessionProposal))
} else { } else {
d.setStatusText("Pairing error", "red") d.setStatusText("Pairing error", "red")
d.state = d.sdkReadyState d.state = ""
} }
} }
function onRejectSessionResult(error) { function onRejectSessionResult(error) {
d.setDetailsText("") d.setDetailsText("")
d.state = d.sdkReadyState d.state = ""
if (!error) { if (!error) {
d.setStatusText("Pairing rejected") d.setStatusText("Pairing rejected")
} else { } else {
@ -390,8 +408,9 @@ Popup {
property var sessionRequest: null property var sessionRequest: null
property var signedData: null property var signedData: null
property string pairModalUriWhenReady: ""
property string state: "" property string state: ""
readonly property string sdkReadyState: "sdk_ready"
readonly property string waitingPairState: "waiting_pairing" readonly property string waitingPairState: "waiting_pairing"
readonly property string waitingUserResponseToSessionRequest: "waiting_user_response_to_session_request" readonly property string waitingUserResponseToSessionRequest: "waiting_user_response_to_session_request"
readonly property string waitingUserResponseToAuthRequest: "waiting_user_response_to_auth_request" readonly property string waitingUserResponseToAuthRequest: "waiting_user_response_to_auth_request"