2023-10-30 16:58:57 +00:00
|
|
|
package walletconnect
|
|
|
|
|
|
|
|
import (
|
|
|
|
"reflect"
|
|
|
|
"testing"
|
|
|
|
|
2023-11-24 15:27:05 +00:00
|
|
|
"encoding/json"
|
|
|
|
|
2023-10-30 16:58:57 +00:00
|
|
|
"github.com/status-im/status-go/eth-node/types"
|
|
|
|
"github.com/status-im/status-go/multiaccounts/accounts"
|
2023-11-24 15:27:05 +00:00
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
2023-10-30 16:58:57 +00:00
|
|
|
)
|
|
|
|
|
2023-11-24 15:27:05 +00:00
|
|
|
func Test_sessionProposalValidity(t *testing.T) {
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
sessionProposalJSON string
|
|
|
|
expectedValidity bool
|
|
|
|
}{
|
|
|
|
// https://specs.walletconnect.com/2.0/specs/clients/sign/namespaces#11-proposal-namespaces-does-not-include-an-optional-namespace
|
|
|
|
{
|
|
|
|
name: "proposal-namespaces-does-not-include-an-optional-namespace",
|
|
|
|
sessionProposalJSON: `{
|
|
|
|
"params": {
|
|
|
|
"requiredNamespaces": {
|
|
|
|
"eip155:10": {
|
|
|
|
"methods": ["personal_sign"],
|
|
|
|
"events": ["accountsChanged", "chainChanged"]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}`,
|
|
|
|
expectedValidity: true,
|
|
|
|
},
|
|
|
|
// https://specs.walletconnect.com/2.0/specs/clients/sign/namespaces#12-proposal-namespaces-must-not-have-chains-empty
|
|
|
|
{
|
|
|
|
name: "proposal-namespaces-must-not-have-chains-empty",
|
|
|
|
sessionProposalJSON: `{
|
|
|
|
"params": {
|
|
|
|
"requiredNamespaces": {
|
|
|
|
"cosmos": {
|
|
|
|
"chains": [],
|
|
|
|
"methods": ["cosmos_signDirect"],
|
|
|
|
"events": ["someCosmosEvent"]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}`,
|
|
|
|
expectedValidity: false,
|
|
|
|
},
|
|
|
|
// https://specs.walletconnect.com/2.0/specs/clients/sign/namespaces#13-chains-might-be-omitted-if-the-caip-2-is-defined-in-the-index
|
|
|
|
{
|
|
|
|
name: "chains-might-be-omitted-if-the-caip-2-is-defined-in-the-index",
|
|
|
|
sessionProposalJSON: `{
|
|
|
|
"params": {
|
|
|
|
"requiredNamespaces": {
|
|
|
|
"eip155": {
|
|
|
|
"chains": ["eip155:1", "eip155:137"],
|
|
|
|
"methods": ["eth_sendTransaction", "eth_signTransaction", "eth_sign"],
|
|
|
|
"events": ["accountsChanged", "chainChanged"]
|
|
|
|
},
|
|
|
|
"eip155:10": {
|
|
|
|
"methods": ["personal_sign"],
|
|
|
|
"events": ["accountsChanged", "chainChanged"]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}`,
|
|
|
|
expectedValidity: true,
|
|
|
|
},
|
|
|
|
// https://specs.walletconnect.com/2.0/specs/clients/sign/namespaces#14-chains-must-be-caip-2-compliant
|
|
|
|
{
|
|
|
|
name: "chains-must-be-caip-2-compliant",
|
|
|
|
sessionProposalJSON: `{
|
|
|
|
"params": {
|
|
|
|
"requiredNamespaces": {
|
|
|
|
"eip155": {
|
|
|
|
"chains": ["42"],
|
|
|
|
"methods": ["eth_sign"],
|
|
|
|
"events": ["accountsChanged"]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}`,
|
|
|
|
expectedValidity: false,
|
|
|
|
},
|
|
|
|
// https://specs.walletconnect.com/2.0/specs/clients/sign/namespaces#15-proposal-namespace-methods-and-events-may-be-empty
|
|
|
|
{
|
|
|
|
name: "proposal-namespace-methods-and-events-may-be-empty",
|
|
|
|
sessionProposalJSON: `{
|
|
|
|
"params": {
|
|
|
|
"requiredNamespaces": {
|
|
|
|
"eip155": {
|
|
|
|
"chains": ["eip155:1"],
|
|
|
|
"methods": [],
|
|
|
|
"events": []
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}`,
|
|
|
|
expectedValidity: true,
|
|
|
|
},
|
|
|
|
// https://specs.walletconnect.com/2.0/specs/clients/sign/namespaces#16-all-chains-in-the-namespace-must-contain-the-namespace-prefix
|
|
|
|
{
|
|
|
|
name: "all-chains-in-the-namespace-must-contain-the-namespace-prefix",
|
|
|
|
sessionProposalJSON: `{
|
|
|
|
"params": {
|
|
|
|
"requiredNamespaces": {
|
|
|
|
"eip155": {
|
|
|
|
"chains": ["eip155:1", "eip155:137", "cosmos:cosmoshub-4"],
|
|
|
|
"methods": ["eth_sendTransaction"],
|
|
|
|
"events": ["accountsChanged", "chainChanged"]
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"optionalNamespaces": {
|
|
|
|
"eip155:42161": {
|
|
|
|
"methods": ["personal_sign"],
|
|
|
|
"events": ["accountsChanged", "chainChanged"]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}`,
|
|
|
|
expectedValidity: false,
|
|
|
|
},
|
|
|
|
// https://specs.walletconnect.com/2.0/specs/clients/sign/namespaces#17-namespace-key-must-comply-with-caip-2-specification
|
|
|
|
{
|
|
|
|
name: "namespace-key-must-comply-with-caip-2-specification",
|
|
|
|
sessionProposalJSON: `{
|
|
|
|
"params": {
|
|
|
|
"requiredNamespaces": {
|
|
|
|
"": {
|
|
|
|
"chains": [":1"],
|
|
|
|
"methods": ["personalSign"],
|
|
|
|
"events": []
|
|
|
|
},
|
|
|
|
"**": {
|
|
|
|
"chains": ["**:1"],
|
|
|
|
"methods": ["personalSign"],
|
|
|
|
"events": []
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}`,
|
|
|
|
expectedValidity: false,
|
|
|
|
},
|
|
|
|
// https://specs.walletconnect.com/2.0/specs/clients/sign/namespaces#18-all-namespaces-must-be-valid
|
|
|
|
{
|
|
|
|
name: "all-namespaces-must-be-valid",
|
|
|
|
sessionProposalJSON: `{
|
|
|
|
"params": {
|
|
|
|
"requiredNamespaces": {
|
|
|
|
"eip155": {
|
|
|
|
"chains": ["eip155:1"],
|
|
|
|
"methods": ["personalSign"],
|
|
|
|
"events": []
|
|
|
|
},
|
|
|
|
"cosmos": {
|
|
|
|
"chains": [],
|
|
|
|
"methods": [],
|
|
|
|
"events": []
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}`,
|
|
|
|
expectedValidity: false,
|
|
|
|
},
|
|
|
|
// https://specs.walletconnect.com/2.0/specs/clients/sign/namespaces#19-proposal-namespaces-may-be-empty
|
|
|
|
{
|
|
|
|
name: "proposal-namespaces-may-be-empty",
|
|
|
|
sessionProposalJSON: `{
|
|
|
|
"params": {
|
|
|
|
"requiredNamespaces": {}
|
|
|
|
}
|
|
|
|
}`,
|
|
|
|
expectedValidity: true,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
var sessionProposal SessionProposal
|
|
|
|
err := json.Unmarshal([]byte(tt.sessionProposalJSON), &sessionProposal)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
if tt.expectedValidity {
|
|
|
|
assert.True(t, sessionProposal.Valid())
|
|
|
|
} else {
|
|
|
|
assert.False(t, sessionProposal.Valid())
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-30 16:58:57 +00:00
|
|
|
func Test_sessionProposalToSupportedChain(t *testing.T) {
|
|
|
|
type args struct {
|
|
|
|
chains []string
|
|
|
|
supportsChain func(uint64) bool
|
|
|
|
}
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
args args
|
|
|
|
wantChains []uint64
|
|
|
|
wantEipChains []string
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "filter_out_unsupported_chains_and_invalid_chains",
|
|
|
|
args: args{
|
|
|
|
chains: []string{"eip155:1", "eip155:3", "eip155:invalid"},
|
|
|
|
supportsChain: func(chainID uint64) bool {
|
|
|
|
return chainID == 1
|
|
|
|
},
|
|
|
|
},
|
|
|
|
wantChains: []uint64{1},
|
|
|
|
wantEipChains: []string{"eip155:1"},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "no_supported_chains",
|
|
|
|
args: args{
|
|
|
|
chains: []string{"eip155:3", "eip155:5"},
|
|
|
|
supportsChain: func(chainID uint64) bool {
|
|
|
|
return false
|
|
|
|
},
|
|
|
|
},
|
|
|
|
wantChains: []uint64{},
|
|
|
|
wantEipChains: []string{},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "empty_proposal",
|
|
|
|
args: args{
|
|
|
|
chains: []string{},
|
|
|
|
supportsChain: func(chainID uint64) bool {
|
|
|
|
return true
|
|
|
|
},
|
|
|
|
},
|
|
|
|
wantChains: []uint64{},
|
|
|
|
wantEipChains: []string{},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
gotChains, gotEipChains := sessionProposalToSupportedChain(tt.args.chains, tt.args.supportsChain)
|
|
|
|
if !reflect.DeepEqual(gotChains, tt.wantChains) {
|
|
|
|
t.Errorf("sessionProposalToSupportedChain() gotChains = %v, want %v", gotChains, tt.wantChains)
|
|
|
|
}
|
|
|
|
if !reflect.DeepEqual(gotEipChains, tt.wantEipChains) {
|
|
|
|
t.Errorf("sessionProposalToSupportedChain() gotEipChains = %v, want %v", gotEipChains, tt.wantEipChains)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-24 15:27:05 +00:00
|
|
|
func Test_caip10Accounts(t *testing.T) {
|
2023-10-30 16:58:57 +00:00
|
|
|
type args struct {
|
2023-11-24 15:27:05 +00:00
|
|
|
accounts []*accounts.Account
|
|
|
|
chains []uint64
|
2023-10-30 16:58:57 +00:00
|
|
|
}
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
args args
|
2023-11-24 15:27:05 +00:00
|
|
|
want []string
|
2023-10-30 16:58:57 +00:00
|
|
|
}{
|
|
|
|
{
|
2023-11-24 15:27:05 +00:00
|
|
|
name: "generate_caip10_accounts",
|
2023-10-30 16:58:57 +00:00
|
|
|
args: args{
|
2023-11-24 15:27:05 +00:00
|
|
|
accounts: []*accounts.Account{
|
2023-10-30 16:58:57 +00:00
|
|
|
{
|
|
|
|
Address: types.HexToAddress("0x1"),
|
|
|
|
Type: accounts.AccountTypeWatch,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Address: types.HexToAddress("0x2"),
|
|
|
|
Type: accounts.AccountTypeSeed,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
chains: []uint64{1, 2},
|
|
|
|
},
|
|
|
|
want: []string{
|
|
|
|
"eip155:1:0x0000000000000000000000000000000000000001",
|
|
|
|
"eip155:2:0x0000000000000000000000000000000000000001",
|
|
|
|
"eip155:1:0x0000000000000000000000000000000000000002",
|
|
|
|
"eip155:2:0x0000000000000000000000000000000000000002",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "empty_addresses",
|
|
|
|
args: args{
|
2023-11-24 15:27:05 +00:00
|
|
|
accounts: []*accounts.Account{},
|
|
|
|
chains: []uint64{1, 2},
|
2023-10-30 16:58:57 +00:00
|
|
|
},
|
|
|
|
want: []string{},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "empty_chains",
|
|
|
|
args: args{
|
2023-11-24 15:27:05 +00:00
|
|
|
accounts: []*accounts.Account{
|
|
|
|
{
|
|
|
|
Address: types.HexToAddress("0x1"),
|
|
|
|
Type: accounts.AccountTypeWatch,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Address: types.HexToAddress("0x2"),
|
|
|
|
Type: accounts.AccountTypeSeed,
|
|
|
|
},
|
2023-10-30 16:58:57 +00:00
|
|
|
},
|
|
|
|
chains: []uint64{},
|
|
|
|
},
|
|
|
|
want: []string{},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
2023-11-24 15:27:05 +00:00
|
|
|
if got := caip10Accounts(tt.args.accounts, tt.args.chains); !reflect.DeepEqual(got, tt.want) {
|
2023-10-30 16:58:57 +00:00
|
|
|
t.Errorf("caip10Accounts() = %v, want %v", got, tt.want)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|