github.com/status-im/status-go@v1.1.0/services/web3provider/api_test.go (about)

     1  package web3provider
     2  
     3  import (
     4  	"database/sql"
     5  	"encoding/json"
     6  	"testing"
     7  
     8  	"github.com/golang/mock/gomock"
     9  	"github.com/stretchr/testify/require"
    10  
    11  	"github.com/status-im/status-go/account"
    12  	"github.com/status-im/status-go/appdatabase"
    13  	"github.com/status-im/status-go/eth-node/types"
    14  	"github.com/status-im/status-go/multiaccounts/accounts"
    15  	"github.com/status-im/status-go/multiaccounts/settings"
    16  	"github.com/status-im/status-go/params"
    17  	"github.com/status-im/status-go/services/permissions"
    18  	"github.com/status-im/status-go/t/helpers"
    19  	"github.com/status-im/status-go/t/utils"
    20  	"github.com/status-im/status-go/transactions/fake"
    21  
    22  	gethrpc "github.com/ethereum/go-ethereum/rpc"
    23  	statusRPC "github.com/status-im/status-go/rpc"
    24  )
    25  
    26  func createDB(t *testing.T) (*sql.DB, func()) {
    27  	db, cleanup, err := helpers.SetupTestSQLDB(appdatabase.DbInitializer{}, "provider-tests-")
    28  	require.NoError(t, err)
    29  	return db, func() { require.NoError(t, cleanup()) }
    30  }
    31  
    32  func setupTestAPI(t *testing.T) (*API, func()) {
    33  	t.Skip("skip test using infura")
    34  	db, cancel := createDB(t)
    35  
    36  	keyStoreDir := t.TempDir()
    37  
    38  	// Creating a dummy status node to simulate what it's done in get_status_node.go
    39  	upstreamConfig := params.UpstreamRPCConfig{
    40  		URL:     "https://mainnet.infura.io/v3/800c641949d64d768a5070a1b0511938",
    41  		Enabled: true,
    42  	}
    43  
    44  	txServiceMockCtrl := gomock.NewController(t)
    45  	server, _ := fake.NewTestServer(txServiceMockCtrl)
    46  	client := gethrpc.DialInProc(server)
    47  
    48  	rpcClient, err := statusRPC.NewClient(client, 1, upstreamConfig, nil, db, nil)
    49  	require.NoError(t, err)
    50  
    51  	// import account keys
    52  	utils.Init()
    53  	require.NoError(t, utils.ImportTestAccount(keyStoreDir, utils.GetAccount1PKFile()))
    54  
    55  	accManager := account.NewGethManager()
    56  
    57  	nodeConfig := &params.NodeConfig{
    58  		KeyStoreDir: keyStoreDir,
    59  		NetworkID:   1,
    60  	}
    61  
    62  	accDB, err := accounts.NewDB(db)
    63  	require.NoError(t, err)
    64  
    65  	service := NewService(db, accDB, rpcClient, nodeConfig, accManager, nil, nil)
    66  
    67  	networks := json.RawMessage("{}")
    68  	settings := settings.Settings{
    69  		DappsAddress: types.HexToAddress(utils.TestConfig.Account1.WalletAddress),
    70  		Networks:     &networks,
    71  	}
    72  
    73  	accounts := []*accounts.Account{
    74  		{Address: types.HexToAddress(utils.TestConfig.Account1.WalletAddress), Chat: true, Wallet: true},
    75  	}
    76  	require.NoError(t, service.accountsDB.SaveOrUpdateAccounts(accounts, false))
    77  
    78  	require.NoError(t, service.accountsDB.CreateSettings(settings, *nodeConfig))
    79  
    80  	return &API{
    81  		s: service,
    82  	}, cancel
    83  }
    84  
    85  func TestRequestPermission(t *testing.T) {
    86  	api, cancel := setupTestAPI(t)
    87  	defer cancel()
    88  
    89  	request := APIRequest{
    90  		Hostname: "www.status.im",
    91  	}
    92  
    93  	_, err := api.ProcessAPIRequest(request)
    94  	require.Error(t, err)
    95  
    96  	request.Permission = PermissionWeb3
    97  
    98  	response, err := api.ProcessAPIRequest(request)
    99  	require.NoError(t, err)
   100  	require.False(t, response.IsAllowed)
   101  	require.Equal(t, ResponseAPI, response.ProviderResponse.ResponseType)
   102  
   103  	_ = api.s.permissionsDB.AddPermissions(permissions.DappPermissions{Name: "www.status.im", Permissions: []string{PermissionWeb3, PermissionContactCode, "RandomPermission"}})
   104  
   105  	response, err = api.ProcessAPIRequest(request)
   106  	require.NoError(t, err)
   107  	require.True(t, response.IsAllowed)
   108  
   109  	d := make([]interface{}, 1)
   110  	d[0] = types.HexToAddress(utils.TestConfig.Account1.WalletAddress)
   111  	var data interface{} = d
   112  	require.Equal(t, data, response.Data)
   113  
   114  	request.Permission = PermissionContactCode
   115  	response, err = api.ProcessAPIRequest(request)
   116  	require.NoError(t, err)
   117  	require.True(t, response.IsAllowed)
   118  
   119  	pubKey, _ := api.s.accountsDB.GetPublicKey()
   120  	data = pubKey
   121  	require.Equal(t, data, response.Data)
   122  
   123  	request.Permission = "RandomPermission"
   124  	_, err = api.ProcessAPIRequest(request)
   125  	require.Error(t, err)
   126  }
   127  
   128  func TestWeb3Call(t *testing.T) {
   129  	api, cancel := setupTestAPI(t)
   130  	defer cancel()
   131  
   132  	request := Web3SendAsyncReadOnlyRequest{
   133  		Hostname:  "www.status.im",
   134  		MessageID: 1,
   135  		Payload: ETHPayload{
   136  			ID:      1,
   137  			JSONRPC: "2.0",
   138  			From:    types.HexToAddress(utils.TestConfig.Account1.WalletAddress).String(),
   139  			Method:  "net_version",
   140  			Params:  []interface{}{},
   141  		},
   142  	}
   143  
   144  	response, err := api.ProcessWeb3ReadOnlyRequest(request)
   145  	require.NoError(t, err)
   146  	require.Equal(t, `{"jsonrpc":"2.0","id":1,"result":"1"}`, string(response.Result.(json.RawMessage)))
   147  
   148  	request.Payload.Method = "eth_accounts"
   149  	response, err = api.ProcessWeb3ReadOnlyRequest(request)
   150  	require.NoError(t, err)
   151  	require.Equal(t, uint(4100), response.Error.(Web3SendAsyncReadOnlyError).Code)
   152  
   153  	_ = api.s.permissionsDB.AddPermissions(permissions.DappPermissions{Name: "www.status.im", Permissions: []string{PermissionWeb3}})
   154  
   155  	response, err = api.ProcessWeb3ReadOnlyRequest(request)
   156  	require.NoError(t, err)
   157  
   158  	d := make([]types.Address, 1)
   159  	d[0] = types.HexToAddress(utils.TestConfig.Account1.WalletAddress)
   160  	var data interface{} = d // eth_account is an array of addresses
   161  	require.Equal(t, data, response.Result.(JSONRPCResponse).Result)
   162  
   163  	request.Payload.Method = "eth_coinbase"
   164  	data = d[0] // eth_coinbase is an address
   165  	response, err = api.ProcessWeb3ReadOnlyRequest(request)
   166  	require.NoError(t, err)
   167  	require.Equal(t, data, response.Result.(JSONRPCResponse).Result)
   168  }
   169  
   170  func TestWeb3Signature(t *testing.T) {
   171  	api, cancel := setupTestAPI(t)
   172  	defer cancel()
   173  
   174  	_ = api.s.permissionsDB.AddPermissions(permissions.DappPermissions{Name: "www.status.im", Permissions: []string{PermissionWeb3}})
   175  
   176  	request := Web3SendAsyncReadOnlyRequest{
   177  		Hostname:  "www.status.im",
   178  		MessageID: 1,
   179  		Payload: ETHPayload{
   180  			ID:       1,
   181  			JSONRPC:  "2.0",
   182  			From:     types.HexToAddress(utils.TestConfig.Account1.WalletAddress).String(),
   183  			Method:   "personal_sign",
   184  			Params:   []interface{}{types.HexBytes{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}},
   185  			Password: "wrong-password",
   186  		},
   187  	}
   188  
   189  	response, err := api.ProcessWeb3ReadOnlyRequest(request)
   190  	require.NoError(t, err)
   191  	require.Equal(t, uint(4100), response.Error.(Web3SendAsyncReadOnlyError).Code)
   192  	require.Equal(t, "could not decrypt key with given password", response.Error.(Web3SendAsyncReadOnlyError).Message)
   193  
   194  	request.Payload.Password = utils.TestConfig.Account1.Password
   195  	response, err = api.ProcessWeb3ReadOnlyRequest(request)
   196  	require.NoError(t, err)
   197  	require.Equal(t, types.HexBytes(types.Hex2Bytes("0xc113a94f201334da86b8237c676951932d2b0ee2b539d941736da5b736f0f224448be6435846a9df9ea0085d92b107b6e49b1786e90d6604d3ef7d6f6ec19d531c")), response.Result.(JSONRPCResponse).Result.(types.HexBytes))
   198  }