chore(wallet): add integration dev tests for pending tx status update
Remove the wallet connect backend dev test code Updates: #13124
This commit is contained in:
parent
7f6636dc94
commit
70767213ff
|
@ -1,20 +0,0 @@
|
||||||
<!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>
|
|
|
@ -11,6 +11,9 @@ import (
|
||||||
webview "github.com/webview/webview_go"
|
webview "github.com/webview/webview_go"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// main simulates a wallet connect client session with status registered as a wallet connect provider
|
||||||
|
// this is used as an alternative for testing the deep link integration until the status desktop app goes in production
|
||||||
|
// and we can register it as a wallet connect provider
|
||||||
func main() {
|
func main() {
|
||||||
// Serve files from the ./generated directory
|
// Serve files from the ./generated directory
|
||||||
fileServer := http.FileServer(http.Dir("./generated"))
|
fileServer := http.FileServer(http.Dir("./generated"))
|
||||||
|
|
|
@ -1,207 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"reflect"
|
|
||||||
|
|
||||||
statusgo "github.com/status-im/status-go/mobile"
|
|
||||||
"github.com/status-im/status-go/multiaccounts"
|
|
||||||
)
|
|
||||||
|
|
||||||
func loginToAccount(hashedPassword, userFolder, nodeConfigJson string) error {
|
|
||||||
absUserFolder, err := filepath.Abs(userFolder)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
accountsJson := statusgo.OpenAccounts(absUserFolder)
|
|
||||||
accounts := make([]multiaccounts.Account, 0)
|
|
||||||
err = getCAPIResponse(accountsJson, &accounts)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(accounts) == 0 {
|
|
||||||
return fmt.Errorf("no accounts found")
|
|
||||||
}
|
|
||||||
|
|
||||||
account := accounts[0]
|
|
||||||
keystorePath := filepath.Join(filepath.Join(absUserFolder, "keystore/"), account.KeyUID)
|
|
||||||
initKeystoreJson := statusgo.InitKeystore(keystorePath)
|
|
||||||
apiResponse := statusgo.APIResponse{}
|
|
||||||
err = getCAPIResponse(initKeystoreJson, &apiResponse)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
//serialize account of type multiaccounts.Account
|
|
||||||
accountJson, err := json.Marshal(account)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
loginJson := statusgo.LoginWithConfig(string(accountJson), hashedPassword, nodeConfigJson)
|
|
||||||
err = getCAPIResponse(loginJson, &apiResponse)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type jsonrpcMessage struct {
|
|
||||||
Version string `json:"jsonrpc"`
|
|
||||||
ID json.RawMessage `json:"id"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type jsonrpcRequest struct {
|
|
||||||
jsonrpcMessage
|
|
||||||
ChainID uint64 `json:"chainId"`
|
|
||||||
Method string `json:"method"`
|
|
||||||
Params json.RawMessage `json:"params,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func callPrivateMethod(method string, params []interface{}) string {
|
|
||||||
var paramsJson json.RawMessage
|
|
||||||
var err error
|
|
||||||
if params != nil {
|
|
||||||
paramsJson, err = json.Marshal(params)
|
|
||||||
if err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
msg := jsonrpcRequest{
|
|
||||||
jsonrpcMessage: jsonrpcMessage{
|
|
||||||
Version: "2.0",
|
|
||||||
},
|
|
||||||
Method: method,
|
|
||||||
Params: paramsJson,
|
|
||||||
}
|
|
||||||
|
|
||||||
msgJson, err := json.Marshal(msg)
|
|
||||||
if err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
return statusgo.CallPrivateRPC(string(msgJson))
|
|
||||||
}
|
|
||||||
|
|
||||||
type Config struct {
|
|
||||||
HashedPassword string `json:"hashedPassword"`
|
|
||||||
NodeConfigFile string `json:"nodeConfigFile"`
|
|
||||||
DataDir *string `json:"dataDir,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func processConfigArgs() (config *Config, nodeConfigJson string, userFolder string, err error) {
|
|
||||||
var configFilePath string
|
|
||||||
flag.StringVar(&configFilePath, "config", "", "path to json config file")
|
|
||||||
flag.StringVar(&userFolder, "dataDir", "../../../Status/data", "path to json config file")
|
|
||||||
flag.Parse()
|
|
||||||
|
|
||||||
if configFilePath == "" {
|
|
||||||
flag.Usage()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
config = &Config{}
|
|
||||||
// parse config file
|
|
||||||
configFile, err := os.Open(configFilePath)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
defer configFile.Close()
|
|
||||||
jsonParser := json.NewDecoder(configFile)
|
|
||||||
if err = jsonParser.Decode(&config); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read config.NodeConfigFile json file and store it as string
|
|
||||||
nodeConfigFile, err := os.Open(config.NodeConfigFile)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
defer nodeConfigFile.Close()
|
|
||||||
nodeConfigData, err := io.ReadAll(nodeConfigFile)
|
|
||||||
if err == nil {
|
|
||||||
nodeConfigJson = string(nodeConfigData)
|
|
||||||
}
|
|
||||||
|
|
||||||
if config.DataDir != nil {
|
|
||||||
userFolder = *config.DataDir
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func getCAPIResponse[T any](responseJson string, res T) error {
|
|
||||||
apiResponse := statusgo.APIResponse{}
|
|
||||||
err := json.Unmarshal([]byte(responseJson), &apiResponse)
|
|
||||||
if err == nil {
|
|
||||||
if apiResponse.Error != "" {
|
|
||||||
return fmt.Errorf("API error: %s", apiResponse.Error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
typeOfT := reflect.TypeOf(res)
|
|
||||||
kindOfT := typeOfT.Kind()
|
|
||||||
|
|
||||||
// Check for valid types: pointer, slice, map
|
|
||||||
if kindOfT != reflect.Ptr && kindOfT != reflect.Slice && kindOfT != reflect.Map {
|
|
||||||
return fmt.Errorf("type T must be a pointer, slice, or map")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := json.Unmarshal([]byte(responseJson), &res); err != nil {
|
|
||||||
return fmt.Errorf("failed to unmarshal data: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type jsonrpcSuccessfulResponse struct {
|
|
||||||
jsonrpcMessage
|
|
||||||
Result json.RawMessage `json:"result"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type jsonrpcErrorResponse struct {
|
|
||||||
jsonrpcMessage
|
|
||||||
Error jsonError `json:"error"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// jsonError represents Error message for JSON-RPC responses.
|
|
||||||
type jsonError struct {
|
|
||||||
Code int `json:"code"`
|
|
||||||
Message string `json:"message"`
|
|
||||||
Data interface{} `json:"data,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func getRPCAPIResponse[T any](responseJson string, res T) error {
|
|
||||||
errApiResponse := jsonrpcErrorResponse{}
|
|
||||||
err := json.Unmarshal([]byte(responseJson), &errApiResponse)
|
|
||||||
if err == nil && errApiResponse.Error.Code != 0 {
|
|
||||||
return fmt.Errorf("API error: %#v", errApiResponse.Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
apiResponse := jsonrpcSuccessfulResponse{}
|
|
||||||
err = json.Unmarshal([]byte(responseJson), &apiResponse)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to unmarshal jsonrpcSuccessfulResponse: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
typeOfT := reflect.TypeOf(res)
|
|
||||||
kindOfT := typeOfT.Kind()
|
|
||||||
|
|
||||||
// Check for valid types: pointer, slice, map
|
|
||||||
if kindOfT != reflect.Ptr && kindOfT != reflect.Slice && kindOfT != reflect.Map {
|
|
||||||
return fmt.Errorf("type T must be a pointer, slice, or map")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := json.Unmarshal(apiResponse.Result, &res); err != nil {
|
|
||||||
return fmt.Errorf("failed to unmarshal data: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,383 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<title>Wallet Connect status-go test</title>
|
|
||||||
<style></style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="log"></div>
|
|
||||||
<script src="bundle.js" type="module"></script>
|
|
||||||
<script>
|
|
||||||
// Helper functions
|
|
||||||
//
|
|
||||||
function goEcho(message) {
|
|
||||||
window.echo(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If not null add to it
|
|
||||||
var logEntries = null;
|
|
||||||
|
|
||||||
var newSessionButton;
|
|
||||||
var hashedPasswordInput;
|
|
||||||
|
|
||||||
function addHtmlEntry(htmlContent, color = null, entry = null) {
|
|
||||||
const logDiv = document.getElementById("log");
|
|
||||||
if (entry) {
|
|
||||||
entry.remove();
|
|
||||||
}
|
|
||||||
entry = document.createElement("div");
|
|
||||||
logDiv.appendChild(entry);
|
|
||||||
entry.innerHTML = htmlContent;
|
|
||||||
if (color) {
|
|
||||||
entry.style.color = color;
|
|
||||||
}
|
|
||||||
entry.scrollIntoView();
|
|
||||||
if (logEntries) {
|
|
||||||
logEntries.push(entry);
|
|
||||||
}
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
function addLogEntry(message, color = "black", entry = null) {
|
|
||||||
return addHtmlEntry(`${message}`, color, entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
function logComponentStatusChange(componentName, statusMessage, color = "black", entry = null) {
|
|
||||||
const componentHtml = `<span style="color: fuchsia;">${componentName}</span>: `;
|
|
||||||
const statusHtml = `<span style="color: ${color};">${statusMessage}</span>`;
|
|
||||||
return addHtmlEntry(`${componentHtml}${statusHtml}`, null, entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
// SDK initialization
|
|
||||||
//
|
|
||||||
const statusGoEntry = logComponentStatusChange("status-go", "Initializing...");
|
|
||||||
var initEventCount = 0;
|
|
||||||
var eventCount = 0;
|
|
||||||
const readyToPairEventName = "readyToPair";
|
|
||||||
async function initializeSDK() {
|
|
||||||
try {
|
|
||||||
const sdkEntry = logComponentStatusChange("SDK", "Initializing...");
|
|
||||||
const conf = await window.getConfiguration();
|
|
||||||
await window.wc.init(conf.projectId);
|
|
||||||
logComponentStatusChange("SDK", "Initialized", "green", sdkEntry);
|
|
||||||
initEventCount++;
|
|
||||||
} catch (error) {
|
|
||||||
goEcho(`SDK init error: ${error}`);
|
|
||||||
logComponentStatusChange("SDK", "FAIL initializing ${error}", "red", sdkEntry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Simulate statusObject
|
|
||||||
window.statusq = {
|
|
||||||
channel: {
|
|
||||||
objects: {
|
|
||||||
statusObject: {
|
|
||||||
sdkInitialized: function (error) {
|
|
||||||
window.statusObject_sdkInitialized(error);
|
|
||||||
},
|
|
||||||
onSessionProposal: function (sessionProposal) {
|
|
||||||
window.statusObject_onSessionProposal(JSON.stringify(sessionProposal)).then((success) => {
|
|
||||||
if (!success) {
|
|
||||||
goEcho(`statusObject: onSessionProposal call failed ${sessionProposal.id}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onSessionRequest: function (sessionRequest) {
|
|
||||||
eventCount++;
|
|
||||||
|
|
||||||
logComponentStatusChange("SDK", `received "session_request" event`, "green");
|
|
||||||
addLogEntry(`Data: ${JSON.stringify(sessionRequest)}`);
|
|
||||||
|
|
||||||
addHtmlEntry(
|
|
||||||
`<button id="acceptSessionButton${eventCount}">Accept</button> <button id="rejectSessionButton${eventCount}">Reject</button>`
|
|
||||||
);
|
|
||||||
|
|
||||||
const acceptSessionButton = document.getElementById(`acceptSessionButton${eventCount}`);
|
|
||||||
const rejectSessionButton = document.getElementById(`rejectSessionButton${eventCount}`);
|
|
||||||
acceptSessionButton.addEventListener("click", function () {
|
|
||||||
const sessionReqEntry = logComponentStatusChange("status-go", `sessionRequest called`, "orange");
|
|
||||||
window.sessionRequest(JSON.stringify(sessionRequest), hashedPasswordInput.value).then((success) => {
|
|
||||||
acceptSessionButton.disabled = true;
|
|
||||||
rejectSessionButton.disabled = true;
|
|
||||||
|
|
||||||
if (success) {
|
|
||||||
logComponentStatusChange("status-go", `sessionRequest OK`, "green", sessionReqEntry);
|
|
||||||
// waiting for "sessionRequestResult" event
|
|
||||||
} else {
|
|
||||||
logComponentStatusChange(
|
|
||||||
"status-go",
|
|
||||||
`sessionRequest call failed for topic ${sessionRequest.topic}`,
|
|
||||||
"red",
|
|
||||||
sessionReqEntry
|
|
||||||
);
|
|
||||||
window.wc.rejectSessionRequest(sessionRequest.topic, sessionRequest.id, true);
|
|
||||||
setStatus(`Session ${sessionRequest.id} rejected, internal error`, "purple");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
rejectSessionButton.addEventListener("click", function () {
|
|
||||||
acceptSessionButton.disabled = true;
|
|
||||||
rejectSessionButton.disabled = true;
|
|
||||||
window.wc.rejectSessionRequest(sessionRequest.topic, sessionRequest.id).then(
|
|
||||||
() => {
|
|
||||||
addLogEntry(`Session ${sessionRequest.id} rejected`);
|
|
||||||
},
|
|
||||||
(err) => {
|
|
||||||
addLogEntry(`Session ${sessionRequest.id} reject error: ${err.message}`, "red");
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onSessionDelete: function (deletePayload) {
|
|
||||||
goEcho(`statusObject: onSessionDelete ${JSON.stringify(deletePayload)}`);
|
|
||||||
},
|
|
||||||
onSessionExpire: function (expirePayload) {
|
|
||||||
goEcho(`statusObject: onSessionExpire ${JSON.stringify(expirePayload)}`);
|
|
||||||
},
|
|
||||||
onSessionUpdate: function (updatePayload) {
|
|
||||||
goEcho(`statusObject: onSessionUpdate ${JSON.stringify(updatePayload)}`);
|
|
||||||
},
|
|
||||||
onSessionExtend: function (extendPayload) {
|
|
||||||
goEcho(`statusObject: onSessionExtend ${JSON.stringify(extendPayload)}`);
|
|
||||||
},
|
|
||||||
onSessionPing: function (pingPayload) {
|
|
||||||
goEcho(`statusObject: onSessionPing ${JSON.stringify(pingPayload)}`);
|
|
||||||
},
|
|
||||||
onSessionEvent: function (eventPayload) {
|
|
||||||
goEcho(`statusObject: onSessionEvent ${JSON.stringify(eventPayload)}`);
|
|
||||||
},
|
|
||||||
onSessionRequest: function (sessionRequestPayload) {
|
|
||||||
goEcho(`statusObject: onSessionRequest ${JSON.stringify(sessionRequestPayload)}`);
|
|
||||||
},
|
|
||||||
onSessionRequestSent: function (sessionRequestSentPayload) {
|
|
||||||
goEcho(`statusObject: onSessionRequestSent ${JSON.stringify(sessionRequestSentPayload)}`);
|
|
||||||
},
|
|
||||||
onProposalExpire: function (proposalExpirePayload) {
|
|
||||||
goEcho(`statusObject: onProposalExpire ${JSON.stringify(proposalExpirePayload)}`);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
var pairLinkInput = null;
|
|
||||||
var pairButton = null;
|
|
||||||
function newPairWorkflow() {
|
|
||||||
// Remove all the previous entries
|
|
||||||
if (logEntries) {
|
|
||||||
for (let i = 0; i < logEntries.length; i++) {
|
|
||||||
logEntries[i].remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
logEntries = [];
|
|
||||||
eventCount++;
|
|
||||||
|
|
||||||
// Add session reset and password input
|
|
||||||
addHtmlEntry(`<button id="newSessionButton" style="display: none;">New Session</button>`);
|
|
||||||
newSessionButton = document.getElementById("newSessionButton");
|
|
||||||
newSessionButton.addEventListener("click", function () {
|
|
||||||
newPairWorkflow();
|
|
||||||
});
|
|
||||||
addHtmlEntry(
|
|
||||||
`<input type="text" id="hashedPasswordInput" placeholder="Insert hashed password" value="0x38301fb0b5fcf3aaa4b97c4771bb6c75546e313b4ce7057c51a8cc6a3ace9d7e"/>`
|
|
||||||
);
|
|
||||||
hashedPasswordInput = document.getElementById(`hashedPasswordInput`);
|
|
||||||
|
|
||||||
addHtmlEntry(
|
|
||||||
`<input type="text" id="pairLinkInput" placeholder="Insert pair link" /><button id="pairButton" disabled>Pair</button>`
|
|
||||||
);
|
|
||||||
|
|
||||||
// List existing pairing sessions
|
|
||||||
const pairingsRes = window.wc.getPairings();
|
|
||||||
let pairings = [];
|
|
||||||
if (pairingsRes) {
|
|
||||||
if (!!pairingsRes.error) {
|
|
||||||
goEcho(`getPairings() error: ${pairingsRes.error}`);
|
|
||||||
return;
|
|
||||||
} else if (pairingsRes.result) {
|
|
||||||
pairings = pairingsRes.result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (pairings.length > 0) {
|
|
||||||
addHtmlEntry(`Existing pairings:`, "fuchsia");
|
|
||||||
}
|
|
||||||
for (let i = 0; i < pairings.length; i++) {
|
|
||||||
const p = pairings[i];
|
|
||||||
const disconnectEntry = addHtmlEntry(
|
|
||||||
`[${i + 1}] <span style="color: ${p.active ? "green" : "orange"};">${
|
|
||||||
p.active ? "ACTIVE" : "INACTIVE"
|
|
||||||
}</span> <span class="elide-text">${p.topic}</span>; Expires: ${timestampToStr(
|
|
||||||
p.expiry
|
|
||||||
)} <button id="unpairButton${i}">Disconnect</button>`
|
|
||||||
);
|
|
||||||
const unpairButton = document.getElementById(`unpairButton${i}`);
|
|
||||||
unpairButton.addEventListener("click", function () {
|
|
||||||
const res = window.wc.disconnect(p.topic);
|
|
||||||
if (res && !!res.error) {
|
|
||||||
addLogEntry(`Pairing ${p.topic} disconnect error: ${err.message}`, "red", disconnectEntry);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
addLogEntry(`Pairing ${p.topic} disconnected`, "green", disconnectEntry);
|
|
||||||
unpairButton.remove();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add pairing options
|
|
||||||
pairLinkInput = document.getElementById(`pairLinkInput`);
|
|
||||||
pairButton = document.getElementById(`pairButton`);
|
|
||||||
pairLinkInput.addEventListener("input", function () {
|
|
||||||
pairButton.disabled = !(pairLinkInput.value.length > 0);
|
|
||||||
});
|
|
||||||
pairButton.addEventListener("click", function () {
|
|
||||||
newSessionButton.style.display = "inline";
|
|
||||||
pairButton.disabled = true;
|
|
||||||
pairLinkInput.disabled = true;
|
|
||||||
|
|
||||||
const sdkEntry = logComponentStatusChange("SDK", "Pairing...");
|
|
||||||
const result = window.wc.pair(pairLinkInput.value);
|
|
||||||
if (result && !!result.error) {
|
|
||||||
goEcho("pair() error: ", result.error);
|
|
||||||
logComponentStatusChange("SDK", `Pairing error ${error.message}`, "red", sdkEntry);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
logComponentStatusChange("SDK", "got Pair session proposal", "green", sdkEntry);
|
|
||||||
const goSessionEntry = logComponentStatusChange("GO.pairSessionProposal", "waiting status-go", "pink");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
document.addEventListener(`proposeUserPair`, function (event) {
|
|
||||||
logComponentStatusChange("GO.proposeUserPair", `received "proposeUserPair"`, "green");
|
|
||||||
addLogEntry(JSON.stringify(event.detail.supportedNamespaces));
|
|
||||||
if (!document.getElementById(`acceptPairButton`)) {
|
|
||||||
addHtmlEntry(`<button id="acceptPairButton">Accept</button><button id="rejectPairButton">Reject</button>`);
|
|
||||||
}
|
|
||||||
const acceptPairButton = document.getElementById(`acceptPairButton`);
|
|
||||||
const rejectPairButton = document.getElementById(`rejectPairButton`);
|
|
||||||
const sessionProposal = event.detail.sessionProposal;
|
|
||||||
acceptPairButton.addEventListener("click", function () {
|
|
||||||
const result = window.wc.approvePairSession(sessionProposal, event.detail.supportedNamespaces);
|
|
||||||
if (result && !!result.error) {
|
|
||||||
logComponentStatusChange(
|
|
||||||
"GO.pairSessionProposal",
|
|
||||||
`Pair session ${sessionProposal.id} approve error: ${result.error}`,
|
|
||||||
"red",
|
|
||||||
goSessionEntry
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
acceptPairButton.remove();
|
|
||||||
rejectPairButton.remove();
|
|
||||||
|
|
||||||
root.controller_recordSuccessfulPairing(JSON.stringify(sessionProposal));
|
|
||||||
|
|
||||||
logComponentStatusChange(
|
|
||||||
"GO.pairSessionProposal",
|
|
||||||
`Pair session ${sessionProposal.id} approved`,
|
|
||||||
"green",
|
|
||||||
goSessionEntry
|
|
||||||
);
|
|
||||||
});
|
|
||||||
rejectPairButton.addEventListener("click", function () {
|
|
||||||
const result = window.wc.rejectPairSession(sessionProposal.id);
|
|
||||||
if (result && !!result.error) {
|
|
||||||
logComponentStatusChange(
|
|
||||||
"GO.pairSessionProposal",
|
|
||||||
`Pair session ${sessionProposal.id} reject error: ${result.error}`,
|
|
||||||
"red",
|
|
||||||
goSessionEntry
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
acceptPairButton.remove();
|
|
||||||
rejectPairButton.remove();
|
|
||||||
|
|
||||||
logComponentStatusChange(
|
|
||||||
"GO.pairSessionProposal",
|
|
||||||
`Pair session ${sessionProposal.id} rejected`,
|
|
||||||
"green",
|
|
||||||
goSessionEntry
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
document.addEventListener("sessionRequestResult", function (event) {
|
|
||||||
let req = event.detail.sessionRequest;
|
|
||||||
const res = window.wc.respondSessionRequest(req.topic, req.id, event.detail.signed);
|
|
||||||
addLogEntry(`Session ${req.topic} approval accepted`);
|
|
||||||
addHtmlEntry(
|
|
||||||
`</br><a href="https://goerli.etherscan.io/tx/${event.detail.signed}" target="_blank">${event.detail.signed}</a>`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add start from scratch option
|
|
||||||
document.addEventListener(readyToPairEventName, function () {
|
|
||||||
newPairWorkflow();
|
|
||||||
});
|
|
||||||
|
|
||||||
async function processGoEvents() {
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
const event = await window.popNextEvent();
|
|
||||||
switch (event.name) {
|
|
||||||
case "nodeReady":
|
|
||||||
logComponentStatusChange("status-go", "Ready", "green", statusGoEntry);
|
|
||||||
initEventCount++;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// Handle status-go and SDK bootstrap events
|
|
||||||
if (initEventCount == 2) {
|
|
||||||
initEventCount++;
|
|
||||||
document.dispatchEvent(new CustomEvent(readyToPairEventName, {}));
|
|
||||||
} else if (event.name != "") {
|
|
||||||
goEcho(`GO event: ${event.name}`);
|
|
||||||
document.dispatchEvent(new CustomEvent(event.name, { detail: event.payload }));
|
|
||||||
} else {
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
goEcho(`GO event error: ${err.message}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
processGoEvents();
|
|
||||||
|
|
||||||
// Call the initializeSDK function on page load
|
|
||||||
window.addEventListener("DOMContentLoaded", (event) => {
|
|
||||||
initializeSDK();
|
|
||||||
});
|
|
||||||
|
|
||||||
function timestampToStr(timestamp) {
|
|
||||||
const date = new Date(timestamp * 1000);
|
|
||||||
const readableDate = date.toLocaleDateString();
|
|
||||||
const readableTime = date.toLocaleTimeString();
|
|
||||||
|
|
||||||
return `${readableDate} - ${readableTime}`;
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
<style>
|
|
||||||
.elide-text {
|
|
||||||
max-width: 100px;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
display: inline-block;
|
|
||||||
transition: max-width 0.3s ease;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
.elide-text:hover {
|
|
||||||
max-width: none;
|
|
||||||
background-color: #f0f0f0;
|
|
||||||
z-index: 1;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</html>
|
|
|
@ -1,229 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/log"
|
|
||||||
webview "github.com/webview/webview_go"
|
|
||||||
|
|
||||||
statusgo "github.com/status-im/status-go/mobile"
|
|
||||||
wc "github.com/status-im/status-go/services/wallet/walletconnect"
|
|
||||||
"github.com/status-im/status-go/services/wallet/walletevent"
|
|
||||||
"github.com/status-im/status-go/signal"
|
|
||||||
)
|
|
||||||
|
|
||||||
// l is used for local logging
|
|
||||||
var l log.Logger
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
l = log.New()
|
|
||||||
l.SetHandler(log.CallerFileHandler(log.StreamHandler(os.Stdout, log.TerminalFormat(false))))
|
|
||||||
}
|
|
||||||
|
|
||||||
type PairResult struct {
|
|
||||||
SessionProposal string `json:"sessionProposal"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Configuration struct {
|
|
||||||
ProjectId string `json:"projectId"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type GoEvent struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
Payload interface{} `json:"payload"`
|
|
||||||
}
|
|
||||||
|
|
||||||
var eventQueue chan GoEvent = make(chan GoEvent, 10000)
|
|
||||||
|
|
||||||
func signalHandler(jsonEvent string) {
|
|
||||||
// parse signal.Envelope from jsonEvent
|
|
||||||
envelope := signal.Envelope{}
|
|
||||||
err := json.Unmarshal([]byte(jsonEvent), &envelope)
|
|
||||||
if err != nil {
|
|
||||||
// check for error in json
|
|
||||||
apiResponse := statusgo.APIResponse{}
|
|
||||||
err = json.Unmarshal([]byte(jsonEvent), &apiResponse)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Error parsing the signal event: ", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if envelope.Type == signal.EventNodeReady {
|
|
||||||
eventQueue <- GoEvent{Name: "nodeReady", Payload: ""}
|
|
||||||
} else if envelope.Type == "wallet" {
|
|
||||||
// parse envelope.Event to json
|
|
||||||
walletEvent := walletevent.Event{}
|
|
||||||
err := json.Unmarshal([]byte(jsonEvent), &walletEvent)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Error parsing the wallet event: ", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// TODO: continue from here
|
|
||||||
// if walletEvent.Type == "WalletConnectProposeUserPair" {
|
|
||||||
// eventQueue <- GoEvent{Name: "proposeUserPair", Payload: walletEvent.Message}
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// Setup status-go logger
|
|
||||||
log.Root().SetHandler(log.CallerFileHandler(log.StdoutHandler))
|
|
||||||
|
|
||||||
signal.SetDefaultNodeNotificationHandler(signalHandler)
|
|
||||||
config, nodeConfigJson, userFolder, err := processConfigArgs()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Login to first account
|
|
||||||
err = loginToAccount(config.HashedPassword, userFolder, nodeConfigJson)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start WebView
|
|
||||||
w := webview.New(true)
|
|
||||||
defer w.Destroy()
|
|
||||||
w.SetTitle("WC status-go test")
|
|
||||||
w.SetSize(1280, 1024, webview.HintNone)
|
|
||||||
|
|
||||||
w.Bind("sessionRequest", func(sessionRequestJson, hashedPassword string) bool {
|
|
||||||
fmt.Println("sessionRequestJson:", sessionRequestJson)
|
|
||||||
sessionReqRes := callPrivateMethod("wallet_wCSessionRequest", []interface{}{sessionRequestJson})
|
|
||||||
fmt.Println("sessionReqRes:", sessionReqRes)
|
|
||||||
var apiResponse wc.SessionRequestResponse
|
|
||||||
err = getRPCAPIResponse(sessionReqRes, &apiResponse)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("Error parsing wallet_wCSessionRequest response", "error", err)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if apiResponse.SignOnKeycard {
|
|
||||||
l.Error("SignOnKeycard is not supported in this test")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
sessionReqRes = callPrivateMethod("wallet_wCSignMessage", []interface{}{apiResponse.MessageToSign, apiResponse.Address, hashedPassword})
|
|
||||||
fmt.Println("sessionReqRes:", sessionReqRes)
|
|
||||||
var signature string
|
|
||||||
err = getRPCAPIResponse(sessionReqRes, &signature)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("Error parsing wallet_wCSignMessage response", "error", err)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: process the request type ...
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
eventQueue <- GoEvent{Name: "sessionRequestResult", Payload: apiResponse}
|
|
||||||
}()
|
|
||||||
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
|
|
||||||
w.Bind("getConfiguration", func() Configuration {
|
|
||||||
projectID := os.Getenv("STATUS_BUILD_WALLET_CONNECT_PROJECT_ID")
|
|
||||||
if projectID == "" {
|
|
||||||
projectID = "87815d72a81d739d2a7ce15c2cfdefb3"
|
|
||||||
}
|
|
||||||
return Configuration{ProjectId: projectID}
|
|
||||||
})
|
|
||||||
|
|
||||||
w.Bind("echo", func(message string) bool {
|
|
||||||
fmt.Println("<D> WebView:", message)
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
|
|
||||||
// Setup go to webview event queue
|
|
||||||
w.Bind("popNextEvent", func() GoEvent {
|
|
||||||
select {
|
|
||||||
case event := <-eventQueue:
|
|
||||||
return event
|
|
||||||
default:
|
|
||||||
return GoEvent{Name: "", Payload: ""}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
mockStatusObject(w)
|
|
||||||
mockController(w)
|
|
||||||
|
|
||||||
// Start a local server to serve the files
|
|
||||||
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")
|
|
||||||
http.ServeFile(w, r, "../../../../ui/app/AppLayouts/Wallet/views/walletconnect/sdk/generated/bundle.js")
|
|
||||||
})
|
|
||||||
|
|
||||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.Header().Set("Cache-Control", "no-store, no-cache, must-revalidate, post-check=0, pre-check=0")
|
|
||||||
http.ServeFile(w, r, "./index.html")
|
|
||||||
})
|
|
||||||
|
|
||||||
go http.ListenAndServe(":8081", nil)
|
|
||||||
|
|
||||||
w.Navigate("http://localhost:8081")
|
|
||||||
w.Run()
|
|
||||||
}
|
|
||||||
|
|
||||||
func mockController(w webview.WebView) {
|
|
||||||
w.Bind("controller_recordSuccessfulPairing", func(sessionProposalJson string) {
|
|
||||||
fmt.Println("controller_recordSuccessfulPairing:", sessionProposalJson)
|
|
||||||
sessionProposalRes := callPrivateMethod("wallet_wCRecordSuccessfulPairing", []interface{}{sessionProposalJson})
|
|
||||||
var apiResponse wc.PairSessionResponse
|
|
||||||
err := getRPCAPIResponse(sessionProposalRes, &apiResponse)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("Error parsing the API response", "error", err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
w.Bind("controller_changePairingState", func(topic string, active bool) {
|
|
||||||
sessionProposalRes := callPrivateMethod("wallet_wCChangePairingState", []interface{}{topic, active})
|
|
||||||
var apiResponse wc.PairSessionResponse
|
|
||||||
err := getRPCAPIResponse(sessionProposalRes, &apiResponse)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("Error parsing the API response", "error", err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func mockStatusObject(w webview.WebView) {
|
|
||||||
w.Bind("statusObject_sdkInitialized", func(error string) {
|
|
||||||
// All OK here
|
|
||||||
})
|
|
||||||
w.Bind("statusObject_onSessionProposal", func(sessionProposalJson string) bool {
|
|
||||||
sessionProposalRes := callPrivateMethod("wallet_wCPairSessionProposal", []interface{}{sessionProposalJson})
|
|
||||||
var apiResponse wc.PairSessionResponse
|
|
||||||
err := getRPCAPIResponse(sessionProposalRes, &apiResponse)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("Error parsing the API response", "error", err)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
eventQueue <- GoEvent{Name: "proposeUserPair", Payload: apiResponse}
|
|
||||||
}()
|
|
||||||
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
w.Bind("statusObject_onSessionRequest", func(sessionRequestJson string) bool {
|
|
||||||
sessionReqRes := callPrivateMethod("wallet_wCSessionRequest", []interface{}{sessionRequestJson})
|
|
||||||
var apiResponse wc.SessionRequestResponse
|
|
||||||
err := getRPCAPIResponse(sessionReqRes, &apiResponse)
|
|
||||||
if err != nil {
|
|
||||||
l.Error("Error parsing the API response", "error", err)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
|
|
||||||
// function onSessionUpdate(details)
|
|
||||||
// function onSessionExtend(details)
|
|
||||||
// function onSessionPing(details)
|
|
||||||
// function onSessionDelete(details)
|
|
||||||
// function onSessionExpire(details)
|
|
||||||
// function onSessionRequestSent(details)
|
|
||||||
// function onSessionEvent(details)
|
|
||||||
// function onProposalExpire(details)
|
|
||||||
}
|
|
|
@ -0,0 +1 @@
|
||||||
|
.integration_tests_config.json
|
|
@ -0,0 +1,30 @@
|
||||||
|
# Development integration tests for status-go
|
||||||
|
|
||||||
|
These integration tests are an experiment. They rely on an existing developer environment (working user folder, blockchain access tokens) and internet connection.
|
||||||
|
|
||||||
|
If it proves its usefulness we might consider automating them and make it independent of internet services
|
||||||
|
|
||||||
|
## How to run tests
|
||||||
|
|
||||||
|
Setup steps
|
||||||
|
|
||||||
|
- Dump the node config passed to `Login` status-go call as `.node_config.json` and use its path later on in as `nodeConfigFile` in `.integration_tests_config.json`
|
||||||
|
- Ensure the blockchain access tokens are configured when dumping the configuration file
|
||||||
|
- Copy [integration_tests_config-template.json](./integration_tests_config-template.json) to tests sub-folders and rename it as `.integration_tests_config.json`, then update it with your own values.
|
||||||
|
- Update `nodeConfigFile` with the previously extracted node config path
|
||||||
|
- The `hashedPassword` should be the "0x" + `keccak256(clearPassword)`
|
||||||
|
- For `dataDir` it is expected an working status-go user folder (e.g. the usual `status-desktop/Second/data` used with `make run` command)
|
||||||
|
|
||||||
|
Run wallet tests
|
||||||
|
|
||||||
|
- once
|
||||||
|
|
||||||
|
```sh
|
||||||
|
(cd test/status-go/integration && go test -v ./wallet/... --tags=gowaku_no_rln,gowaku_skip_migrations)
|
||||||
|
```
|
||||||
|
|
||||||
|
- continuously on code changes
|
||||||
|
|
||||||
|
```sh
|
||||||
|
(cd test/status-go/integration && nodemon --watch ../../../vendor/status-go/ --watch . --ext "*.go,*.sql" --exec 'go test -v ./wallet/... --tags=gowaku_no_rln,gowaku_skip_migrations 2>&1 | tee ~/proj/tmp/status-go-tests.log || exit 1')
|
||||||
|
```
|
|
@ -1,8 +1,10 @@
|
||||||
module main
|
module github.com/status-im/status-desktop/test/status-go/integration
|
||||||
|
|
||||||
go 1.20
|
go 1.20
|
||||||
|
|
||||||
replace github.com/status-im/status-go => ../../../../vendor/status-go
|
replace github.com/status-im/status-desktop/test/status-go/integration => ./
|
||||||
|
|
||||||
|
replace github.com/status-im/status-go => ../../../vendor/status-go
|
||||||
|
|
||||||
// Keep these in sync with status-go/go.mod aliases
|
// 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/ethereum/go-ethereum v1.10.26 => github.com/status-im/go-ethereum v1.10.25-status.11
|
||||||
|
@ -18,14 +20,13 @@ replace github.com/mutecomm/go-sqlcipher/v4 v4.4.2 => github.com/status-im/go-sq
|
||||||
require (
|
require (
|
||||||
github.com/ethereum/go-ethereum v1.10.26
|
github.com/ethereum/go-ethereum v1.10.26
|
||||||
github.com/status-im/status-go v0.171.7
|
github.com/status-im/status-go v0.171.7
|
||||||
github.com/webview/webview_go v0.0.0-20230901181450-5a14030a9070
|
github.com/stretchr/testify v1.8.4
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/BurntSushi/toml v1.2.1 // indirect
|
github.com/BurntSushi/toml v1.2.1 // indirect
|
||||||
github.com/PuerkitoBio/goquery v1.6.1 // indirect
|
github.com/PuerkitoBio/goquery v1.6.1 // indirect
|
||||||
github.com/RoaringBitmap/roaring v0.9.4 // 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/VictoriaMetrics/fastcache v1.6.0 // indirect
|
||||||
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 // indirect
|
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 // indirect
|
||||||
github.com/anacrolix/chansync v0.3.0 // indirect
|
github.com/anacrolix/chansync v0.3.0 // indirect
|
||||||
|
@ -46,6 +47,7 @@ require (
|
||||||
github.com/anacrolix/utp v0.1.0 // indirect
|
github.com/anacrolix/utp v0.1.0 // indirect
|
||||||
github.com/andybalholm/brotli v1.0.5 // indirect
|
github.com/andybalholm/brotli v1.0.5 // indirect
|
||||||
github.com/andybalholm/cascadia v1.2.0 // indirect
|
github.com/andybalholm/cascadia v1.2.0 // indirect
|
||||||
|
github.com/avast/retry-go/v4 v4.5.1 // indirect
|
||||||
github.com/bahlo/generic-list-go v0.2.0 // indirect
|
github.com/bahlo/generic-list-go v0.2.0 // indirect
|
||||||
github.com/beevik/ntp v0.3.0 // indirect
|
github.com/beevik/ntp v0.3.0 // indirect
|
||||||
github.com/benbjohnson/clock v1.3.5 // indirect
|
github.com/benbjohnson/clock v1.3.5 // indirect
|
||||||
|
@ -70,7 +72,7 @@ require (
|
||||||
github.com/deckarep/golang-set v1.8.0 // indirect
|
github.com/deckarep/golang-set v1.8.0 // indirect
|
||||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
|
||||||
github.com/docker/go-units v0.5.0 // indirect
|
github.com/docker/go-units v0.5.0 // indirect
|
||||||
github.com/dustin/go-humanize v1.0.0 // indirect
|
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||||
github.com/edsrzf/mmap-go v1.0.0 // indirect
|
github.com/edsrzf/mmap-go v1.0.0 // indirect
|
||||||
github.com/elastic/gosigar v0.14.2 // indirect
|
github.com/elastic/gosigar v0.14.2 // indirect
|
||||||
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect
|
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect
|
||||||
|
@ -79,7 +81,7 @@ require (
|
||||||
github.com/forPelevin/gomoji v1.1.2 // indirect
|
github.com/forPelevin/gomoji v1.1.2 // indirect
|
||||||
github.com/francoispqt/gojay v1.2.13 // indirect
|
github.com/francoispqt/gojay v1.2.13 // indirect
|
||||||
github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // 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-ole/go-ole v1.2.6 // indirect
|
||||||
github.com/go-playground/locales v0.14.0 // indirect
|
github.com/go-playground/locales v0.14.0 // indirect
|
||||||
github.com/go-playground/universal-translator v0.18.0 // indirect
|
github.com/go-playground/universal-translator v0.18.0 // indirect
|
||||||
github.com/go-stack/stack v1.8.1 // indirect
|
github.com/go-stack/stack v1.8.1 // indirect
|
||||||
|
@ -211,7 +213,7 @@ require (
|
||||||
github.com/russolsen/transit v0.0.0-20180705123435-0794b4c4505a // indirect
|
github.com/russolsen/transit v0.0.0-20180705123435-0794b4c4505a // indirect
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||||
github.com/schollz/peerdiscovery v1.7.0 // indirect
|
github.com/schollz/peerdiscovery v1.7.0 // indirect
|
||||||
github.com/shirou/gopsutil v3.21.5+incompatible // indirect
|
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
|
||||||
github.com/shopspring/decimal v1.2.0 // indirect
|
github.com/shopspring/decimal v1.2.0 // indirect
|
||||||
github.com/siphiuel/lc-proxy-wrapper v0.0.0-20230516150924-246507cee8c7 // indirect
|
github.com/siphiuel/lc-proxy-wrapper v0.0.0-20230516150924-246507cee8c7 // indirect
|
||||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||||
|
@ -222,9 +224,9 @@ require (
|
||||||
github.com/status-im/migrate/v4 v4.6.2-status.3 // 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/rendezvous v1.3.7 // indirect
|
||||||
github.com/status-im/status-go/extkeys v1.1.2 // 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/tcp-shaker v1.1.1-status // indirect
|
||||||
github.com/status-im/zxcvbn-go v0.0.0-20220311183720-5e8676676857 // indirect
|
github.com/status-im/zxcvbn-go v0.0.0-20220311183720-5e8676676857 // indirect
|
||||||
github.com/stretchr/testify v1.8.4 // indirect
|
github.com/stretchr/objx v0.5.0 // indirect
|
||||||
github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a // indirect
|
github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a // indirect
|
||||||
github.com/tklauser/go-sysconf v0.3.6 // indirect
|
github.com/tklauser/go-sysconf v0.3.6 // indirect
|
||||||
github.com/tklauser/numcpus v0.2.2 // indirect
|
github.com/tklauser/numcpus v0.2.2 // indirect
|
||||||
|
@ -234,8 +236,8 @@ require (
|
||||||
github.com/vacp2p/mvds v0.0.24-0.20201124060106-26d8e94130d8 // 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-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-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-waku v0.8.1-0.20240104144340-585648c4eefe // indirect
|
||||||
github.com/waku-org/go-zerokit-rln v0.1.14-0.20230916173259-d284a3d8f2fd // indirect
|
github.com/waku-org/go-zerokit-rln v0.1.14-0.20240102145250-fa738c0bdf59 // indirect
|
||||||
github.com/waku-org/go-zerokit-rln-apple v0.0.0-20230916172309-ee0ee61dde2b // 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-arm v0.0.0-20230916171929-1dd9494ff065 // indirect
|
||||||
github.com/waku-org/go-zerokit-rln-x86_64 v0.0.0-20230916171518-2a77c3734dd1 // indirect
|
github.com/waku-org/go-zerokit-rln-x86_64 v0.0.0-20230916171518-2a77c3734dd1 // indirect
|
||||||
|
@ -250,6 +252,7 @@ require (
|
||||||
github.com/yeqown/go-qrcode/v2 v2.2.1 // 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/go-qrcode/writer/standard v1.2.1 // indirect
|
||||||
github.com/yeqown/reedsolomon v1.0.0 // indirect
|
github.com/yeqown/reedsolomon v1.0.0 // indirect
|
||||||
|
github.com/yusufpapurcu/wmi v1.2.3 // indirect
|
||||||
github.com/zenthangplus/goccm v0.0.0-20211005163543-2f2e522aca15 // indirect
|
github.com/zenthangplus/goccm v0.0.0-20211005163543-2f2e522aca15 // indirect
|
||||||
go.etcd.io/bbolt v1.3.6 // indirect
|
go.etcd.io/bbolt v1.3.6 // indirect
|
||||||
go.uber.org/atomic v1.11.0 // indirect
|
go.uber.org/atomic v1.11.0 // indirect
|
|
@ -158,7 +158,6 @@ github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:H
|
||||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||||
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
||||||
github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46 h1:5sXbqlSomvdjlRbWyNqkPsJ3Fg+tQZCbgeX1VGljbQY=
|
|
||||||
github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
||||||
github.com/VictoriaMetrics/fastcache v1.6.0 h1:C/3Oi3EiBCqufydp1neRZkqcwmEiuRT9c3fqvvgKm5o=
|
github.com/VictoriaMetrics/fastcache v1.6.0 h1:C/3Oi3EiBCqufydp1neRZkqcwmEiuRT9c3fqvvgKm5o=
|
||||||
github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw=
|
github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw=
|
||||||
|
@ -346,6 +345,8 @@ github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmV
|
||||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||||
github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
|
github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
|
||||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||||
|
github.com/avast/retry-go/v4 v4.5.1 h1:AxIx0HGi4VZ3I02jr78j5lZ3M6x1E0Ivxa6b0pUUh7o=
|
||||||
|
github.com/avast/retry-go/v4 v4.5.1/go.mod h1:/sipNsvNB3RRuT5iNcb6h73nw3IBmXJ/H3XrCQYSOpc=
|
||||||
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
|
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
|
||||||
github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0=
|
github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0=
|
||||||
github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||||
|
@ -711,8 +712,9 @@ github.com/dop251/goja v0.0.0-20211011172007-d99e4b8cbf48/go.mod h1:R9ET47fwRVRP
|
||||||
github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y=
|
github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y=
|
||||||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
github.com/dustin/go-humanize v0.0.0-20180421182945-02af3965c54e/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
github.com/dustin/go-humanize v0.0.0-20180421182945-02af3965c54e/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
|
||||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
|
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||||
|
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||||
github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw=
|
github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw=
|
||||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||||
|
@ -828,8 +830,9 @@ github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
|
||||||
github.com/go-logr/stdr v1.2.0/go.mod h1:YkVgnZu1ZjjL7xTxrfm/LLZBfkhTqSR1ydtm6jTKKwI=
|
github.com/go-logr/stdr v1.2.0/go.mod h1:YkVgnZu1ZjjL7xTxrfm/LLZBfkhTqSR1ydtm6jTKKwI=
|
||||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||||
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
|
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
|
||||||
github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY=
|
|
||||||
github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||||
|
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||||
|
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||||
github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
|
github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
|
||||||
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
||||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||||
|
@ -1900,8 +1903,9 @@ github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfP
|
||||||
github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo=
|
github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo=
|
||||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||||
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||||
github.com/shirou/gopsutil v3.21.5+incompatible h1:OloQyEerMi7JUrXiNzy8wQ5XN+baemxSl12QgIzt0jc=
|
|
||||||
github.com/shirou/gopsutil v3.21.5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
github.com/shirou/gopsutil v3.21.5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||||
|
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
|
||||||
|
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||||
github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||||
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
|
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
|
||||||
|
@ -1999,8 +2003,8 @@ github.com/status-im/resize v0.0.0-20201215164250-7c6d9f0d3088 h1:ClCAP2FPCvl8hG
|
||||||
github.com/status-im/resize v0.0.0-20201215164250-7c6d9f0d3088/go.mod h1:+92j1tN27DypDeBFxkg0uzkqfh1bNHTZe3Bv2PjvxpM=
|
github.com/status-im/resize v0.0.0-20201215164250-7c6d9f0d3088/go.mod h1:+92j1tN27DypDeBFxkg0uzkqfh1bNHTZe3Bv2PjvxpM=
|
||||||
github.com/status-im/status-go/extkeys v1.1.2 h1:FSjARgDathJ3rIapJt851LsIXP9Oyuu2M2jPJKuzloU=
|
github.com/status-im/status-go/extkeys v1.1.2 h1:FSjARgDathJ3rIapJt851LsIXP9Oyuu2M2jPJKuzloU=
|
||||||
github.com/status-im/status-go/extkeys v1.1.2/go.mod h1:hCmFzb2jiiVF2voZKYbzuhOQiHHCmyLJsZJXrFFg7BY=
|
github.com/status-im/status-go/extkeys v1.1.2/go.mod h1:hCmFzb2jiiVF2voZKYbzuhOQiHHCmyLJsZJXrFFg7BY=
|
||||||
github.com/status-im/tcp-shaker v0.0.0-20191114194237-215893130501 h1:oa0KU5jJRNtXaM/P465MhvSFo/HM2O8qi2DDuPcd7ro=
|
github.com/status-im/tcp-shaker v1.1.1-status h1:TnVeeWlq2SKCWotHc4Vi6qZQfY8TTe3VLmu1xpEFYhg=
|
||||||
github.com/status-im/tcp-shaker v0.0.0-20191114194237-215893130501/go.mod h1:RYo/itke1oU5k/6sj9DNM3QAwtE5rZSgg5JnkOv83hk=
|
github.com/status-im/tcp-shaker v1.1.1-status/go.mod h1:RYo/itke1oU5k/6sj9DNM3QAwtE5rZSgg5JnkOv83hk=
|
||||||
github.com/status-im/zxcvbn-go v0.0.0-20220311183720-5e8676676857 h1:sPkzT7Z7uLmejOsBRlZ0kwDWpqjpHJsp834o5nbhqho=
|
github.com/status-im/zxcvbn-go v0.0.0-20220311183720-5e8676676857 h1:sPkzT7Z7uLmejOsBRlZ0kwDWpqjpHJsp834o5nbhqho=
|
||||||
github.com/status-im/zxcvbn-go v0.0.0-20220311183720-5e8676676857/go.mod h1:lq9I5ROto5tcua65GmCE6SIW7VE0ucdEBs1fn4z7uWU=
|
github.com/status-im/zxcvbn-go v0.0.0-20220311183720-5e8676676857/go.mod h1:lq9I5ROto5tcua65GmCE6SIW7VE0ucdEBs1fn4z7uWU=
|
||||||
github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8=
|
github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8=
|
||||||
|
@ -2013,7 +2017,9 @@ github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||||
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
|
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
|
||||||
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
@ -2025,7 +2031,9 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
|
||||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||||
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||||
|
@ -2088,10 +2096,10 @@ github.com/waku-org/go-discover v0.0.0-20221209174356-61c833f34d98 h1:xwY0kW5XZF
|
||||||
github.com/waku-org/go-discover v0.0.0-20221209174356-61c833f34d98/go.mod h1:eBHgM6T4EG0RZzxpxKy+rGz/6Dw2Nd8DWxS0lm9ESDw=
|
github.com/waku-org/go-discover v0.0.0-20221209174356-61c833f34d98/go.mod h1:eBHgM6T4EG0RZzxpxKy+rGz/6Dw2Nd8DWxS0lm9ESDw=
|
||||||
github.com/waku-org/go-libp2p-rendezvous v0.0.0-20230628220917-7b4e5ae4c0e7 h1:0e1h+p84yBp0IN7AqgbZlV7lgFBjm214lgSOE7CeJmE=
|
github.com/waku-org/go-libp2p-rendezvous v0.0.0-20230628220917-7b4e5ae4c0e7 h1:0e1h+p84yBp0IN7AqgbZlV7lgFBjm214lgSOE7CeJmE=
|
||||||
github.com/waku-org/go-libp2p-rendezvous v0.0.0-20230628220917-7b4e5ae4c0e7/go.mod h1:pFvOZ9YTFsW0o5zJW7a0B5tr1owAijRWJctXJ2toL04=
|
github.com/waku-org/go-libp2p-rendezvous v0.0.0-20230628220917-7b4e5ae4c0e7/go.mod h1:pFvOZ9YTFsW0o5zJW7a0B5tr1owAijRWJctXJ2toL04=
|
||||||
github.com/waku-org/go-waku v0.8.1-0.20231103161423-351dd55a1498 h1:2Y06Ni3tBj2LQA0ys1o1PspZxZPM9GOKwNEGolbueQ4=
|
github.com/waku-org/go-waku v0.8.1-0.20240104144340-585648c4eefe h1:2D97fbaKlIQRjWMz/iTjnYcxi2z6ekKvspTGtcuPHgU=
|
||||||
github.com/waku-org/go-waku v0.8.1-0.20231103161423-351dd55a1498/go.mod h1:hem2hnXK5BdabxwJULszM0Rh1Yj+gD9IxjwLCGPPaxs=
|
github.com/waku-org/go-waku v0.8.1-0.20240104144340-585648c4eefe/go.mod h1:+b5fPPJ4YUIAPJtPOtwB7bTrOQ9lF15I2LnQjV6NMIA=
|
||||||
github.com/waku-org/go-zerokit-rln v0.1.14-0.20230916173259-d284a3d8f2fd h1:cu7CsUo7BK6ac/v193RIaqAzUcmpa6MNY4xYW9AenQI=
|
github.com/waku-org/go-zerokit-rln v0.1.14-0.20240102145250-fa738c0bdf59 h1:jisj+OCI6QydLtFq3Pyhu49wl9ytPN7oAHjMfepHDrA=
|
||||||
github.com/waku-org/go-zerokit-rln v0.1.14-0.20230916173259-d284a3d8f2fd/go.mod h1:1PdBdPzyTaKt3VnpAHk3zj+r9dXPFOr3IHZP9nFle6E=
|
github.com/waku-org/go-zerokit-rln v0.1.14-0.20240102145250-fa738c0bdf59/go.mod h1:1PdBdPzyTaKt3VnpAHk3zj+r9dXPFOr3IHZP9nFle6E=
|
||||||
github.com/waku-org/go-zerokit-rln-apple v0.0.0-20230916172309-ee0ee61dde2b h1:KgZVhsLkxsj5gb/FfndSCQu6VYwALrCOgYI3poR95yE=
|
github.com/waku-org/go-zerokit-rln-apple v0.0.0-20230916172309-ee0ee61dde2b h1:KgZVhsLkxsj5gb/FfndSCQu6VYwALrCOgYI3poR95yE=
|
||||||
github.com/waku-org/go-zerokit-rln-apple v0.0.0-20230916172309-ee0ee61dde2b/go.mod h1:KYykqtdApHVYZ3G0spwMnoxc5jH5eI3jyO9SwsSfi48=
|
github.com/waku-org/go-zerokit-rln-apple v0.0.0-20230916172309-ee0ee61dde2b/go.mod h1:KYykqtdApHVYZ3G0spwMnoxc5jH5eI3jyO9SwsSfi48=
|
||||||
github.com/waku-org/go-zerokit-rln-arm v0.0.0-20230916171929-1dd9494ff065 h1:Sd7QD/1Yo2o2M1MY49F8Zr4KNBPUEK5cz5HoXQVJbrs=
|
github.com/waku-org/go-zerokit-rln-arm v0.0.0-20230916171929-1dd9494ff065 h1:Sd7QD/1Yo2o2M1MY49F8Zr4KNBPUEK5cz5HoXQVJbrs=
|
||||||
|
@ -2104,8 +2112,6 @@ github.com/wealdtech/go-multicodec v1.4.0 h1:iq5PgxwssxnXGGPTIK1srvt6U5bJwIp7k6k
|
||||||
github.com/wealdtech/go-multicodec v1.4.0/go.mod h1:aedGMaTeYkIqi/KCPre1ho5rTb3hGpu/snBOS3GQLw4=
|
github.com/wealdtech/go-multicodec v1.4.0/go.mod h1:aedGMaTeYkIqi/KCPre1ho5rTb3hGpu/snBOS3GQLw4=
|
||||||
github.com/wealdtech/go-string2eth v1.1.0 h1:USJQmysUrBYYmZs7d45pMb90hRSyEwizP7lZaOZLDAw=
|
github.com/wealdtech/go-string2eth v1.1.0 h1:USJQmysUrBYYmZs7d45pMb90hRSyEwizP7lZaOZLDAw=
|
||||||
github.com/wealdtech/go-string2eth v1.1.0/go.mod h1:RUzsLjJtbZaJ/3UKn9kY19a/vCCUHtEWoUW3uiK6yGU=
|
github.com/wealdtech/go-string2eth v1.1.0/go.mod h1:RUzsLjJtbZaJ/3UKn9kY19a/vCCUHtEWoUW3uiK6yGU=
|
||||||
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=
|
|
||||||
github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||||
github.com/willf/bitset v1.1.9/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
github.com/willf/bitset v1.1.9/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||||
github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||||
|
@ -2148,6 +2154,8 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
|
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
|
||||||
|
github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||||
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
|
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
|
||||||
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
|
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
|
||||||
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
|
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
|
|
@ -0,0 +1,47 @@
|
||||||
|
package helpers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/status-im/status-go/multiaccounts/accounts"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetAllAccounts() (res []accounts.Account, err error) {
|
||||||
|
jsonRes, err := CallPrivateMethod("accounts_getAccounts", []interface{}{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var allAccounts []accounts.Account
|
||||||
|
err = GetRPCAPIResponse(jsonRes, &allAccounts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return allAccounts, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetWalletWatchOnlyAccounts() (res []accounts.Account, err error) {
|
||||||
|
accounts, err := GetAllAccounts()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, acc := range accounts {
|
||||||
|
if !acc.IsWalletNonWatchOnlyAccount() {
|
||||||
|
res = append(res, acc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetWalletOperableAccounts() (res []accounts.Account, err error) {
|
||||||
|
accounts, err := GetAllAccounts()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, acc := range accounts {
|
||||||
|
if acc.IsWalletAccountReadyForTransaction() {
|
||||||
|
res = append(res, acc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
|
@ -0,0 +1,314 @@
|
||||||
|
package helpers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
|
statusgo "github.com/status-im/status-go/mobile"
|
||||||
|
"github.com/status-im/status-go/multiaccounts"
|
||||||
|
"github.com/status-im/status-go/services/wallet/walletevent"
|
||||||
|
"github.com/status-im/status-go/signal"
|
||||||
|
)
|
||||||
|
|
||||||
|
type StatusGoEventName string
|
||||||
|
|
||||||
|
const NodeReadyEvent StatusGoEventName = "nodeReady"
|
||||||
|
const WalletEvent StatusGoEventName = "wallet"
|
||||||
|
|
||||||
|
type GoEvent struct {
|
||||||
|
Name StatusGoEventName `json:"name"`
|
||||||
|
Payload interface{} `json:"payload"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type envelope struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
Event json.RawMessage `json:"event"` // Use json.RawMessage to delay parsing
|
||||||
|
}
|
||||||
|
|
||||||
|
func signalHandler(eventQueue chan GoEvent, jsonEvent string) {
|
||||||
|
envelope := envelope{}
|
||||||
|
err := json.Unmarshal([]byte(jsonEvent), &envelope)
|
||||||
|
if err != nil {
|
||||||
|
apiResponse := statusgo.APIResponse{}
|
||||||
|
err = json.Unmarshal([]byte(jsonEvent), &apiResponse)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Error parsing the signal event: ", err)
|
||||||
|
} else if apiResponse.Error != "" {
|
||||||
|
log.Error("Error from status-go: ", apiResponse.Error)
|
||||||
|
} else {
|
||||||
|
log.Error("Unknown JSON content for event", jsonEvent)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if envelope.Type == signal.EventNodeReady {
|
||||||
|
eventQueue <- GoEvent{Name: NodeReadyEvent, Payload: string(envelope.Event)}
|
||||||
|
} else if envelope.Type == string(WalletEvent) {
|
||||||
|
walletEvent := walletevent.Event{}
|
||||||
|
err := json.Unmarshal(envelope.Event, &walletEvent)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Error parsing the wallet event: ", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
eventQueue <- GoEvent{Name: WalletEvent, Payload: walletEvent}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoginToTestAccount(t *testing.T) (eventQueue chan GoEvent, config *Config, l log.Logger) {
|
||||||
|
l = log.New()
|
||||||
|
l.SetHandler(log.CallerFileHandler(log.StreamHandler(os.Stdout, log.TerminalFormat(false))))
|
||||||
|
|
||||||
|
// Setup status-go logger
|
||||||
|
log.Root().SetHandler(log.CallerFileHandler(log.StdoutHandler))
|
||||||
|
|
||||||
|
eventQueue = make(chan GoEvent, 10000)
|
||||||
|
signal.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
|
||||||
|
signalHandler(eventQueue, jsonEvent)
|
||||||
|
})
|
||||||
|
|
||||||
|
conf, nodeConfigJson, userFolder, err := processConfigArgs("./.integration_tests_config.json")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
config = conf
|
||||||
|
|
||||||
|
// Login to first account
|
||||||
|
err = loginToAccount(config.HashedPassword, userFolder, nodeConfigJson)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func WaitForEvent(eventQueue chan GoEvent, eventName StatusGoEventName, timeout time.Duration) (event *GoEvent, err error) {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case event := <-eventQueue:
|
||||||
|
if event.Name == eventName {
|
||||||
|
return &event, nil
|
||||||
|
}
|
||||||
|
case <-time.After(timeout):
|
||||||
|
return nil, fmt.Errorf("timeout waiting for event %s", eventName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WaitForWalletEvent[T any](eventQueue chan GoEvent, eventName walletevent.EventType, timeout time.Duration) (payload *T, err error) {
|
||||||
|
var event *GoEvent
|
||||||
|
for {
|
||||||
|
event, err = WaitForEvent(eventQueue, WalletEvent, timeout)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
walletEvent, ok := event.Payload.(walletevent.Event)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("event payload is not a wallet event")
|
||||||
|
}
|
||||||
|
|
||||||
|
var newPayload T
|
||||||
|
if walletEvent.Type == eventName {
|
||||||
|
if walletEvent.Message != "" {
|
||||||
|
err = json.Unmarshal([]byte(walletEvent.Message), &newPayload)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &newPayload, nil
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func loginToAccount(hashedPassword, userFolder, nodeConfigJson string) error {
|
||||||
|
absUserFolder, err := filepath.Abs(userFolder)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
accountsJson := statusgo.OpenAccounts(absUserFolder)
|
||||||
|
accounts := make([]multiaccounts.Account, 0)
|
||||||
|
err = GetCAPIResponse(accountsJson, &accounts)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(accounts) == 0 {
|
||||||
|
return fmt.Errorf("no accounts found")
|
||||||
|
}
|
||||||
|
|
||||||
|
account := accounts[0]
|
||||||
|
keystorePath := filepath.Join(filepath.Join(absUserFolder, "keystore/"), account.KeyUID)
|
||||||
|
initKeystoreJson := statusgo.InitKeystore(keystorePath)
|
||||||
|
apiResponse := statusgo.APIResponse{}
|
||||||
|
err = GetCAPIResponse(initKeystoreJson, &apiResponse)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
//serialize account of type multiaccounts.Account
|
||||||
|
accountJson, err := json.Marshal(account)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
loginJson := statusgo.LoginWithConfig(string(accountJson), hashedPassword, nodeConfigJson)
|
||||||
|
err = GetCAPIResponse(loginJson, &apiResponse)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type jsonrpcMessage struct {
|
||||||
|
Version string `json:"jsonrpc"`
|
||||||
|
ID json.RawMessage `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type jsonrpcRequest struct {
|
||||||
|
jsonrpcMessage
|
||||||
|
ChainID uint64 `json:"chainId"`
|
||||||
|
Method string `json:"method"`
|
||||||
|
Params json.RawMessage `json:"params,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func CallPrivateMethod(method string, params []interface{}) (string, error) {
|
||||||
|
var paramsJson json.RawMessage
|
||||||
|
var err error
|
||||||
|
if params != nil {
|
||||||
|
paramsJson, err = json.Marshal(params)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := jsonrpcRequest{
|
||||||
|
jsonrpcMessage: jsonrpcMessage{
|
||||||
|
Version: "2.0",
|
||||||
|
},
|
||||||
|
Method: method,
|
||||||
|
Params: paramsJson,
|
||||||
|
}
|
||||||
|
|
||||||
|
msgJson, err := json.Marshal(msg)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return statusgo.CallPrivateRPC(string(msgJson)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
HashedPassword string `json:"hashedPassword"`
|
||||||
|
NodeConfigFile string `json:"nodeConfigFile"`
|
||||||
|
DataDir string `json:"dataDir"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// processConfigArgs expects that configFilePath points to a JSON file that contains a Config struct
|
||||||
|
// For now this are for developer to manually run them using an existing user folder.
|
||||||
|
// TODO: ideally we would generate a temporary user folder to be used in the entire suite.
|
||||||
|
func processConfigArgs(configFilePath string) (config *Config, nodeConfigJson string, userFolder string, err error) {
|
||||||
|
config = &Config{}
|
||||||
|
// parse config file
|
||||||
|
configFile, err := os.Open(configFilePath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", "", err
|
||||||
|
}
|
||||||
|
defer configFile.Close()
|
||||||
|
|
||||||
|
jsonParser := json.NewDecoder(configFile)
|
||||||
|
if err = jsonParser.Decode(&config); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeConfigFile, err := os.Open(config.NodeConfigFile)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer nodeConfigFile.Close()
|
||||||
|
|
||||||
|
nodeConfigData, err := io.ReadAll(nodeConfigFile)
|
||||||
|
if err == nil {
|
||||||
|
nodeConfigJson = string(nodeConfigData)
|
||||||
|
}
|
||||||
|
|
||||||
|
userFolder = config.DataDir
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetCAPIResponse[T any](responseJson string, res T) error {
|
||||||
|
apiResponse := statusgo.APIResponse{}
|
||||||
|
err := json.Unmarshal([]byte(responseJson), &apiResponse)
|
||||||
|
if err == nil {
|
||||||
|
if apiResponse.Error != "" {
|
||||||
|
return fmt.Errorf("API error: %s", apiResponse.Error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typeOfT := reflect.TypeOf(res)
|
||||||
|
kindOfT := typeOfT.Kind()
|
||||||
|
|
||||||
|
// Check for valid types: pointer, slice, map
|
||||||
|
if kindOfT != reflect.Ptr && kindOfT != reflect.Slice && kindOfT != reflect.Map {
|
||||||
|
return fmt.Errorf("type T must be a pointer, slice, or map")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := json.Unmarshal([]byte(responseJson), &res); err != nil {
|
||||||
|
return fmt.Errorf("failed to unmarshal data: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type jsonrpcSuccessfulResponse struct {
|
||||||
|
jsonrpcMessage
|
||||||
|
Result json.RawMessage `json:"result"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type jsonrpcErrorResponse struct {
|
||||||
|
jsonrpcMessage
|
||||||
|
Error jsonError `json:"error"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// jsonError represents Error message for JSON-RPC responses.
|
||||||
|
type jsonError struct {
|
||||||
|
Code int `json:"code"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
Data interface{} `json:"data,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetRPCAPIResponse[T any](responseJson string, res T) error {
|
||||||
|
errApiResponse := jsonrpcErrorResponse{}
|
||||||
|
err := json.Unmarshal([]byte(responseJson), &errApiResponse)
|
||||||
|
if err == nil && errApiResponse.Error.Code != 0 {
|
||||||
|
return fmt.Errorf("API error: %#v", errApiResponse.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
apiResponse := jsonrpcSuccessfulResponse{}
|
||||||
|
err = json.Unmarshal([]byte(responseJson), &apiResponse)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to unmarshal jsonrpcSuccessfulResponse: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
typeOfT := reflect.TypeOf(res)
|
||||||
|
kindOfT := typeOfT.Kind()
|
||||||
|
|
||||||
|
// Check for valid types: pointer, slice, map
|
||||||
|
if kindOfT != reflect.Ptr && kindOfT != reflect.Slice && kindOfT != reflect.Map {
|
||||||
|
return fmt.Errorf("type T must be a pointer, slice, or map")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := json.Unmarshal(apiResponse.Result, &res); err != nil {
|
||||||
|
return fmt.Errorf("failed to unmarshal data: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"hashedPassword": "0x<hashed password as expected by the login call>",
|
||||||
|
"nodeConfigFile": "<node config JSON as expected by the login call>",
|
||||||
|
"dataDir": "<optional user's status data dir (usually status-desktop/Status/data>"
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
// These tests are for development only to be run manually
|
||||||
|
// There is more work needed to automate them not to depend on an existing account and internet connection
|
||||||
|
|
||||||
|
package wallet
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
|
||||||
|
"github.com/status-im/status-desktop/test/status-go/integration/helpers"
|
||||||
|
|
||||||
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
|
"github.com/status-im/status-go/services/wallet/bridge"
|
||||||
|
"github.com/status-im/status-go/services/wallet/transfer"
|
||||||
|
"github.com/status-im/status-go/transactions"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestPendingTx_NotificationStatus tests that a pending transaction is created, then updated and finally deleted.
|
||||||
|
func TestPendingTx_NotificationStatus(t *testing.T) {
|
||||||
|
eventQueue, conf, _ := helpers.LoginToTestAccount(t)
|
||||||
|
|
||||||
|
_, err := helpers.WaitForEvent(eventQueue, helpers.NodeReadyEvent, 60*time.Second)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
opAccounts, err := helpers.GetWalletOperableAccounts()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Greater(t, len(opAccounts), 0)
|
||||||
|
sender := opAccounts[0]
|
||||||
|
|
||||||
|
watchAccounts, err := helpers.GetWalletWatchOnlyAccounts()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Greater(t, len(watchAccounts), 0)
|
||||||
|
recipient := watchAccounts[0]
|
||||||
|
|
||||||
|
mTCommand := transfer.MultiTransactionCommand{
|
||||||
|
FromAddress: common.Address(sender.Address),
|
||||||
|
ToAddress: common.Address(recipient.Address),
|
||||||
|
FromAsset: "ETH",
|
||||||
|
ToAsset: "ETH",
|
||||||
|
FromAmount: (*hexutil.Big)(new(big.Int).SetUint64(100000)),
|
||||||
|
Type: transfer.MultiTransactionSend,
|
||||||
|
}
|
||||||
|
data := []*bridge.TransactionBridge{
|
||||||
|
{
|
||||||
|
BridgeName: "Transfer",
|
||||||
|
ChainID: 5,
|
||||||
|
TransferTx: &transactions.SendTxArgs{
|
||||||
|
From: sender.Address,
|
||||||
|
To: &recipient.Address,
|
||||||
|
Value: (*hexutil.Big)(new(big.Int).Set(mTCommand.FromAmount.ToInt())),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
password := conf.HashedPassword
|
||||||
|
|
||||||
|
// Step 1: send a transaction that will generate a pending entry
|
||||||
|
sessionReqRes, err := helpers.CallPrivateMethod("wallet_createMultiTransaction", []interface{}{mTCommand, data, password})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
var apiResponse *transfer.MultiTransactionCommandResult
|
||||||
|
err = helpers.GetRPCAPIResponse(sessionReqRes, &apiResponse)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, 1, len(apiResponse.Hashes))
|
||||||
|
|
||||||
|
// Step 2: wait for the pending entry to be confirmed
|
||||||
|
statusPayload, err := helpers.WaitForWalletEvent[transactions.StatusChangedPayload](eventQueue, transactions.EventPendingTransactionStatusChanged, 60*time.Second)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, statusPayload.Status, transactions.Success)
|
||||||
|
|
||||||
|
// Step 3: Trigger downloading of the new transaction ...
|
||||||
|
_, err = helpers.CallPrivateMethod("wallet_checkRecentHistoryForChainIDs", []interface{}{[]uint64{5}, []types.Address{sender.Address, recipient.Address}})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// ... and wait for the new transaction download to trigger deletion from pending_transactions
|
||||||
|
updatePayload, err := helpers.WaitForWalletEvent[transactions.PendingTxUpdatePayload](eventQueue, transactions.EventPendingTransactionUpdate, 60*time.Second)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.True(t, updatePayload.Deleted)
|
||||||
|
}
|
Loading…
Reference in New Issue