113
vendor/github.com/status-im/status-go/eth-node/bridge/geth/ens/ens.go
generated
vendored
Normal file
113
vendor/github.com/status-im/status-go/eth-node/bridge/geth/ens/ens.go
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
package ens
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/elliptic"
|
||||
"encoding/hex"
|
||||
"math/big"
|
||||
"time"
|
||||
|
||||
ens "github.com/wealdtech/go-ens/v3"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
|
||||
"github.com/status-im/status-go/eth-node/crypto"
|
||||
enstypes "github.com/status-im/status-go/eth-node/types/ens"
|
||||
)
|
||||
|
||||
const (
|
||||
contractQueryTimeout = 5000 * time.Millisecond
|
||||
)
|
||||
|
||||
type Verifier struct {
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
// NewVerifier returns a Verifier attached to the specified logger
|
||||
func NewVerifier(logger *zap.Logger) *Verifier {
|
||||
return &Verifier{logger: logger}
|
||||
}
|
||||
|
||||
func (m *Verifier) ReverseResolve(address common.Address, rpcEndpoint string) (string, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), contractQueryTimeout)
|
||||
defer cancel()
|
||||
|
||||
ethClient, err := ethclient.DialContext(ctx, rpcEndpoint)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return ens.ReverseResolve(ethClient, address)
|
||||
}
|
||||
|
||||
func (m *Verifier) verifyENSName(ensInfo enstypes.ENSDetails, ethclient *ethclient.Client) enstypes.ENSResponse {
|
||||
publicKeyStr := ensInfo.PublicKeyString
|
||||
ensName := ensInfo.Name
|
||||
m.logger.Info("Resolving ENS name", zap.String("name", ensName), zap.String("publicKey", publicKeyStr))
|
||||
response := enstypes.ENSResponse{
|
||||
Name: ensName,
|
||||
PublicKeyString: publicKeyStr,
|
||||
VerifiedAt: time.Now().Unix(),
|
||||
}
|
||||
|
||||
expectedPubKeyBytes, err := hex.DecodeString(publicKeyStr)
|
||||
if err != nil {
|
||||
response.Error = err
|
||||
return response
|
||||
}
|
||||
|
||||
publicKey, err := crypto.UnmarshalPubkey(expectedPubKeyBytes)
|
||||
if err != nil {
|
||||
response.Error = err
|
||||
return response
|
||||
}
|
||||
|
||||
// Resolve ensName
|
||||
resolver, err := ens.NewResolver(ethclient, ensName)
|
||||
if err != nil {
|
||||
m.logger.Error("error while creating ENS name resolver", zap.String("ensName", ensName), zap.Error(err))
|
||||
response.Error = err
|
||||
return response
|
||||
}
|
||||
x, y, err := resolver.PubKey()
|
||||
if err != nil {
|
||||
m.logger.Error("error while resolving public key from ENS name", zap.String("ensName", ensName), zap.Error(err))
|
||||
response.Error = err
|
||||
return response
|
||||
}
|
||||
|
||||
// Assemble the bytes returned for the pubkey
|
||||
pubKeyBytes := elliptic.Marshal(crypto.S256(), new(big.Int).SetBytes(x[:]), new(big.Int).SetBytes(y[:]))
|
||||
|
||||
response.PublicKey = publicKey
|
||||
response.Verified = bytes.Equal(pubKeyBytes, expectedPubKeyBytes)
|
||||
return response
|
||||
}
|
||||
|
||||
// CheckBatch verifies that a registered ENS name matches the expected public key
|
||||
func (m *Verifier) CheckBatch(ensDetails []enstypes.ENSDetails, rpcEndpoint, contractAddress string) (map[string]enstypes.ENSResponse, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), contractQueryTimeout)
|
||||
defer cancel()
|
||||
|
||||
ch := make(chan enstypes.ENSResponse)
|
||||
response := make(map[string]enstypes.ENSResponse)
|
||||
|
||||
ethclient, err := ethclient.DialContext(ctx, rpcEndpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, ensInfo := range ensDetails {
|
||||
go func(info enstypes.ENSDetails) { ch <- m.verifyENSName(info, ethclient) }(ensInfo)
|
||||
}
|
||||
|
||||
for range ensDetails {
|
||||
r := <-ch
|
||||
response[r.PublicKeyString] = r
|
||||
}
|
||||
close(ch)
|
||||
|
||||
return response, nil
|
||||
}
|
||||
58
vendor/github.com/status-im/status-go/eth-node/bridge/geth/envelope.go
generated
vendored
Normal file
58
vendor/github.com/status-im/status-go/eth-node/bridge/geth/envelope.go
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
package gethbridge
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
waku "github.com/status-im/status-go/waku/common"
|
||||
)
|
||||
|
||||
type wakuEnvelope struct {
|
||||
env *waku.Envelope
|
||||
}
|
||||
|
||||
// NewWakuEnvelope returns an object that wraps Geth's Waku Envelope in a types interface.
|
||||
func NewWakuEnvelope(e *waku.Envelope) types.Envelope {
|
||||
return &wakuEnvelope{env: e}
|
||||
}
|
||||
|
||||
func (w *wakuEnvelope) Unwrap() interface{} {
|
||||
return w.env
|
||||
}
|
||||
|
||||
func (w *wakuEnvelope) Hash() types.Hash {
|
||||
return types.Hash(w.env.Hash())
|
||||
}
|
||||
|
||||
func (w *wakuEnvelope) Bloom() []byte {
|
||||
return w.env.Bloom()
|
||||
}
|
||||
|
||||
func (w *wakuEnvelope) PoW() float64 {
|
||||
return w.env.PoW()
|
||||
}
|
||||
|
||||
func (w *wakuEnvelope) Expiry() uint32 {
|
||||
return w.env.Expiry
|
||||
}
|
||||
|
||||
func (w *wakuEnvelope) TTL() uint32 {
|
||||
return w.env.TTL
|
||||
}
|
||||
|
||||
func (w *wakuEnvelope) Topic() types.TopicType {
|
||||
return types.TopicType(w.env.Topic)
|
||||
}
|
||||
|
||||
func (w *wakuEnvelope) Size() int {
|
||||
return len(w.env.Data)
|
||||
}
|
||||
|
||||
func (w *wakuEnvelope) DecodeRLP(s *rlp.Stream) error {
|
||||
return w.env.DecodeRLP(s)
|
||||
}
|
||||
|
||||
func (w *wakuEnvelope) EncodeRLP(writer io.Writer) error {
|
||||
return rlp.Encode(writer, w.env)
|
||||
}
|
||||
43
vendor/github.com/status-im/status-go/eth-node/bridge/geth/envelope_error.go
generated
vendored
Normal file
43
vendor/github.com/status-im/status-go/eth-node/bridge/geth/envelope_error.go
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
package gethbridge
|
||||
|
||||
import (
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
waku "github.com/status-im/status-go/waku/common"
|
||||
wakuv2 "github.com/status-im/status-go/wakuv2/common"
|
||||
)
|
||||
|
||||
// NewWakuEnvelopeErrorWrapper returns a types.EnvelopeError object that mimics Geth's EnvelopeError
|
||||
func NewWakuEnvelopeErrorWrapper(envelopeError *waku.EnvelopeError) *types.EnvelopeError {
|
||||
if envelopeError == nil {
|
||||
panic("envelopeError should not be nil")
|
||||
}
|
||||
|
||||
return &types.EnvelopeError{
|
||||
Hash: types.Hash(envelopeError.Hash),
|
||||
Code: mapGethErrorCode(envelopeError.Code),
|
||||
Description: envelopeError.Description,
|
||||
}
|
||||
}
|
||||
|
||||
// NewWakuEnvelopeErrorWrapper returns a types.EnvelopeError object that mimics Geth's EnvelopeError
|
||||
func NewWakuV2EnvelopeErrorWrapper(envelopeError *wakuv2.EnvelopeError) *types.EnvelopeError {
|
||||
if envelopeError == nil {
|
||||
panic("envelopeError should not be nil")
|
||||
}
|
||||
|
||||
return &types.EnvelopeError{
|
||||
Hash: types.Hash(envelopeError.Hash),
|
||||
Code: mapGethErrorCode(envelopeError.Code),
|
||||
Description: envelopeError.Description,
|
||||
}
|
||||
}
|
||||
|
||||
func mapGethErrorCode(code uint) uint {
|
||||
switch code {
|
||||
case waku.EnvelopeTimeNotSynced:
|
||||
return types.EnvelopeTimeNotSynced
|
||||
case waku.EnvelopeOtherError:
|
||||
return types.EnvelopeOtherError
|
||||
}
|
||||
return types.EnvelopeOtherError
|
||||
}
|
||||
60
vendor/github.com/status-im/status-go/eth-node/bridge/geth/envelope_event.go
generated
vendored
Normal file
60
vendor/github.com/status-im/status-go/eth-node/bridge/geth/envelope_event.go
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
package gethbridge
|
||||
|
||||
import (
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
"github.com/status-im/status-go/waku"
|
||||
"github.com/status-im/status-go/wakuv2"
|
||||
|
||||
wakucommon "github.com/status-im/status-go/waku/common"
|
||||
wakuv2common "github.com/status-im/status-go/wakuv2/common"
|
||||
)
|
||||
|
||||
// NewWakuEnvelopeEventWrapper returns a types.EnvelopeEvent object that mimics Geth's EnvelopeEvent
|
||||
func NewWakuEnvelopeEventWrapper(envelopeEvent *wakucommon.EnvelopeEvent) *types.EnvelopeEvent {
|
||||
if envelopeEvent == nil {
|
||||
panic("envelopeEvent should not be nil")
|
||||
}
|
||||
|
||||
wrappedData := envelopeEvent.Data
|
||||
switch data := envelopeEvent.Data.(type) {
|
||||
case []wakucommon.EnvelopeError:
|
||||
wrappedData := make([]types.EnvelopeError, len(data))
|
||||
for index := range data {
|
||||
wrappedData[index] = *NewWakuEnvelopeErrorWrapper(&data[index])
|
||||
}
|
||||
case *waku.MailServerResponse:
|
||||
wrappedData = NewWakuMailServerResponseWrapper(data)
|
||||
}
|
||||
return &types.EnvelopeEvent{
|
||||
Event: types.EventType(envelopeEvent.Event),
|
||||
Hash: types.Hash(envelopeEvent.Hash),
|
||||
Batch: types.Hash(envelopeEvent.Batch),
|
||||
Peer: types.EnodeID(envelopeEvent.Peer),
|
||||
Data: wrappedData,
|
||||
}
|
||||
}
|
||||
|
||||
// NewWakuV2EnvelopeEventWrapper returns a types.EnvelopeEvent object that mimics Geth's EnvelopeEvent
|
||||
func NewWakuV2EnvelopeEventWrapper(envelopeEvent *wakuv2common.EnvelopeEvent) *types.EnvelopeEvent {
|
||||
if envelopeEvent == nil {
|
||||
panic("envelopeEvent should not be nil")
|
||||
}
|
||||
|
||||
wrappedData := envelopeEvent.Data
|
||||
switch data := envelopeEvent.Data.(type) {
|
||||
case []wakuv2common.EnvelopeError:
|
||||
wrappedData := make([]types.EnvelopeError, len(data))
|
||||
for index := range data {
|
||||
wrappedData[index] = *NewWakuV2EnvelopeErrorWrapper(&data[index])
|
||||
}
|
||||
case *wakuv2.MailServerResponse:
|
||||
wrappedData = NewWakuV2MailServerResponseWrapper(data)
|
||||
}
|
||||
return &types.EnvelopeEvent{
|
||||
Event: types.EventType(envelopeEvent.Event),
|
||||
Hash: types.Hash(envelopeEvent.Hash),
|
||||
Batch: types.Hash(envelopeEvent.Batch),
|
||||
Peer: types.EnodeID(envelopeEvent.Peer),
|
||||
Data: wrappedData,
|
||||
}
|
||||
}
|
||||
103
vendor/github.com/status-im/status-go/eth-node/bridge/geth/keystore.go
generated
vendored
Normal file
103
vendor/github.com/status-im/status-go/eth-node/bridge/geth/keystore.go
generated
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
package gethbridge
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts"
|
||||
"github.com/ethereum/go-ethereum/accounts/keystore"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
"github.com/status-im/status-go/extkeys"
|
||||
)
|
||||
|
||||
type gethKeyStoreAdapter struct {
|
||||
keystore *keystore.KeyStore
|
||||
}
|
||||
|
||||
// WrapKeyStore creates a types.KeyStore wrapper over a keystore.KeyStore object
|
||||
func WrapKeyStore(keystore *keystore.KeyStore) types.KeyStore {
|
||||
return &gethKeyStoreAdapter{keystore: keystore}
|
||||
}
|
||||
|
||||
func (k *gethKeyStoreAdapter) ImportECDSA(priv *ecdsa.PrivateKey, passphrase string) (types.Account, error) {
|
||||
gethAccount, err := k.keystore.ImportECDSA(priv, passphrase)
|
||||
return accountFrom(gethAccount), err
|
||||
}
|
||||
|
||||
func (k *gethKeyStoreAdapter) ImportSingleExtendedKey(extKey *extkeys.ExtendedKey, passphrase string) (types.Account, error) {
|
||||
gethAccount, err := k.keystore.ImportSingleExtendedKey(extKey, passphrase)
|
||||
return accountFrom(gethAccount), err
|
||||
}
|
||||
|
||||
func (k *gethKeyStoreAdapter) ImportExtendedKeyForPurpose(keyPurpose extkeys.KeyPurpose, extKey *extkeys.ExtendedKey, passphrase string) (types.Account, error) {
|
||||
gethAccount, err := k.keystore.ImportExtendedKeyForPurpose(keyPurpose, extKey, passphrase)
|
||||
return accountFrom(gethAccount), err
|
||||
}
|
||||
|
||||
func (k *gethKeyStoreAdapter) AccountDecryptedKey(a types.Account, auth string) (types.Account, *types.Key, error) {
|
||||
gethAccount, err := gethAccountFrom(a)
|
||||
if err != nil {
|
||||
return types.Account{}, nil, err
|
||||
}
|
||||
|
||||
var gethKey *keystore.Key
|
||||
gethAccount, gethKey, err = k.keystore.AccountDecryptedKey(gethAccount, auth)
|
||||
return accountFrom(gethAccount), keyFrom(gethKey), err
|
||||
}
|
||||
|
||||
func (k *gethKeyStoreAdapter) Delete(a types.Account) error {
|
||||
gethAccount, err := gethAccountFrom(a)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return k.keystore.Delete(gethAccount)
|
||||
}
|
||||
|
||||
// parseGethURL converts a user supplied URL into the accounts specific structure.
|
||||
func parseGethURL(url string) (accounts.URL, error) {
|
||||
parts := strings.Split(url, "://")
|
||||
if len(parts) != 2 || parts[0] == "" {
|
||||
return accounts.URL{}, errors.New("protocol scheme missing")
|
||||
}
|
||||
return accounts.URL{
|
||||
Scheme: parts[0],
|
||||
Path: parts[1],
|
||||
}, nil
|
||||
}
|
||||
|
||||
func gethAccountFrom(account types.Account) (accounts.Account, error) {
|
||||
var (
|
||||
gethAccount accounts.Account
|
||||
err error
|
||||
)
|
||||
gethAccount.Address = common.Address(account.Address)
|
||||
if account.URL != "" {
|
||||
gethAccount.URL, err = parseGethURL(account.URL)
|
||||
}
|
||||
return gethAccount, err
|
||||
}
|
||||
|
||||
func accountFrom(gethAccount accounts.Account) types.Account {
|
||||
return types.Account{
|
||||
Address: types.Address(gethAccount.Address),
|
||||
URL: gethAccount.URL.String(),
|
||||
}
|
||||
}
|
||||
|
||||
func keyFrom(k *keystore.Key) *types.Key {
|
||||
if k == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &types.Key{
|
||||
ID: k.Id,
|
||||
Address: types.Address(k.Address),
|
||||
PrivateKey: k.PrivateKey,
|
||||
ExtendedKey: k.ExtendedKey,
|
||||
SubAccountIndex: k.SubAccountIndex,
|
||||
}
|
||||
}
|
||||
33
vendor/github.com/status-im/status-go/eth-node/bridge/geth/mailserver_response.go
generated
vendored
Normal file
33
vendor/github.com/status-im/status-go/eth-node/bridge/geth/mailserver_response.go
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
package gethbridge
|
||||
|
||||
import (
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
"github.com/status-im/status-go/waku"
|
||||
"github.com/status-im/status-go/wakuv2"
|
||||
)
|
||||
|
||||
// NewWakuMailServerResponseWrapper returns a types.MailServerResponse object that mimics Geth's MailServerResponse
|
||||
func NewWakuMailServerResponseWrapper(mailServerResponse *waku.MailServerResponse) *types.MailServerResponse {
|
||||
if mailServerResponse == nil {
|
||||
panic("mailServerResponse should not be nil")
|
||||
}
|
||||
|
||||
return &types.MailServerResponse{
|
||||
LastEnvelopeHash: types.Hash(mailServerResponse.LastEnvelopeHash),
|
||||
Cursor: mailServerResponse.Cursor,
|
||||
Error: mailServerResponse.Error,
|
||||
}
|
||||
}
|
||||
|
||||
// NewWakuV2MailServerResponseWrapper returns a types.MailServerResponse object that mimics Geth's MailServerResponse
|
||||
func NewWakuV2MailServerResponseWrapper(mailServerResponse *wakuv2.MailServerResponse) *types.MailServerResponse {
|
||||
if mailServerResponse == nil {
|
||||
panic("mailServerResponse should not be nil")
|
||||
}
|
||||
|
||||
return &types.MailServerResponse{
|
||||
LastEnvelopeHash: types.Hash(mailServerResponse.LastEnvelopeHash),
|
||||
Cursor: mailServerResponse.Cursor,
|
||||
Error: mailServerResponse.Error,
|
||||
}
|
||||
}
|
||||
88
vendor/github.com/status-im/status-go/eth-node/bridge/geth/node.go
generated
vendored
Normal file
88
vendor/github.com/status-im/status-go/eth-node/bridge/geth/node.go
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
package gethbridge
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/status-im/status-go/waku"
|
||||
"github.com/status-im/status-go/wakuv2"
|
||||
|
||||
"github.com/ethereum/go-ethereum/node"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
|
||||
gethens "github.com/status-im/status-go/eth-node/bridge/geth/ens"
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
enstypes "github.com/status-im/status-go/eth-node/types/ens"
|
||||
)
|
||||
|
||||
type gethNodeWrapper struct {
|
||||
stack *node.Node
|
||||
waku1 *waku.Waku
|
||||
waku2 *wakuv2.Waku
|
||||
}
|
||||
|
||||
func NewNodeBridge(stack *node.Node, waku1 *waku.Waku, waku2 *wakuv2.Waku) types.Node {
|
||||
return &gethNodeWrapper{stack: stack, waku1: waku1, waku2: waku2}
|
||||
}
|
||||
|
||||
func (w *gethNodeWrapper) Poll() {
|
||||
// noop
|
||||
}
|
||||
|
||||
func (w *gethNodeWrapper) NewENSVerifier(logger *zap.Logger) enstypes.ENSVerifier {
|
||||
return gethens.NewVerifier(logger)
|
||||
}
|
||||
|
||||
func (w *gethNodeWrapper) SetWaku1(waku *waku.Waku) {
|
||||
w.waku1 = waku
|
||||
}
|
||||
|
||||
func (w *gethNodeWrapper) SetWaku2(waku *wakuv2.Waku) {
|
||||
w.waku2 = waku
|
||||
}
|
||||
|
||||
func (w *gethNodeWrapper) GetWaku(ctx interface{}) (types.Waku, error) {
|
||||
if w.waku1 == nil {
|
||||
return nil, errors.New("waku service is not available")
|
||||
}
|
||||
|
||||
return NewGethWakuWrapper(w.waku1), nil
|
||||
}
|
||||
|
||||
func (w *gethNodeWrapper) GetWakuV2(ctx interface{}) (types.Waku, error) {
|
||||
if w.waku2 == nil {
|
||||
return nil, errors.New("waku service is not available")
|
||||
}
|
||||
|
||||
return NewGethWakuV2Wrapper(w.waku2), nil
|
||||
}
|
||||
|
||||
func (w *gethNodeWrapper) AddPeer(url string) error {
|
||||
parsedNode, err := enode.ParseV4(url)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
w.stack.Server().AddPeer(parsedNode)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *gethNodeWrapper) RemovePeer(url string) error {
|
||||
parsedNode, err := enode.ParseV4(url)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
w.stack.Server().RemovePeer(parsedNode)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *gethNodeWrapper) PeersCount() int {
|
||||
if w.stack.Server() == nil {
|
||||
return 0
|
||||
}
|
||||
return len(w.stack.Server().Peers())
|
||||
}
|
||||
109
vendor/github.com/status-im/status-go/eth-node/bridge/geth/public_waku_api.go
generated
vendored
Normal file
109
vendor/github.com/status-im/status-go/eth-node/bridge/geth/public_waku_api.go
generated
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
package gethbridge
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
"github.com/status-im/status-go/waku"
|
||||
wakucommon "github.com/status-im/status-go/waku/common"
|
||||
)
|
||||
|
||||
type GethPublicWakuAPIWrapper struct {
|
||||
api *waku.PublicWakuAPI
|
||||
}
|
||||
|
||||
// NewGethPublicWakuAPIWrapper returns an object that wraps Geth's PublicWakuAPI in a types interface
|
||||
func NewGethPublicWakuAPIWrapper(api *waku.PublicWakuAPI) types.PublicWakuAPI {
|
||||
if api == nil {
|
||||
panic("PublicWakuAPI cannot be nil")
|
||||
}
|
||||
|
||||
return &GethPublicWakuAPIWrapper{
|
||||
api: api,
|
||||
}
|
||||
}
|
||||
|
||||
// AddPrivateKey imports the given private key.
|
||||
func (w *GethPublicWakuAPIWrapper) AddPrivateKey(ctx context.Context, privateKey types.HexBytes) (string, error) {
|
||||
return w.api.AddPrivateKey(ctx, hexutil.Bytes(privateKey))
|
||||
}
|
||||
|
||||
// GenerateSymKeyFromPassword derives a key from the given password, stores it, and returns its ID.
|
||||
func (w *GethPublicWakuAPIWrapper) GenerateSymKeyFromPassword(ctx context.Context, passwd string) (string, error) {
|
||||
return w.api.GenerateSymKeyFromPassword(ctx, passwd)
|
||||
}
|
||||
|
||||
// DeleteKeyPair removes the key with the given key if it exists.
|
||||
func (w *GethPublicWakuAPIWrapper) DeleteKeyPair(ctx context.Context, key string) (bool, error) {
|
||||
return w.api.DeleteKeyPair(ctx, key)
|
||||
}
|
||||
|
||||
// NewMessageFilter creates a new filter that can be used to poll for
|
||||
// (new) messages that satisfy the given criteria.
|
||||
func (w *GethPublicWakuAPIWrapper) NewMessageFilter(req types.Criteria) (string, error) {
|
||||
topics := make([]wakucommon.TopicType, len(req.Topics))
|
||||
for index, tt := range req.Topics {
|
||||
topics[index] = wakucommon.TopicType(tt)
|
||||
}
|
||||
|
||||
criteria := waku.Criteria{
|
||||
SymKeyID: req.SymKeyID,
|
||||
PrivateKeyID: req.PrivateKeyID,
|
||||
Sig: req.Sig,
|
||||
MinPow: req.MinPow,
|
||||
Topics: topics,
|
||||
AllowP2P: req.AllowP2P,
|
||||
}
|
||||
return w.api.NewMessageFilter(criteria)
|
||||
}
|
||||
|
||||
func (w *GethPublicWakuAPIWrapper) BloomFilter() []byte {
|
||||
return w.api.BloomFilter()
|
||||
}
|
||||
|
||||
// GetFilterMessages returns the messages that match the filter criteria and
|
||||
// are received between the last poll and now.
|
||||
func (w *GethPublicWakuAPIWrapper) GetFilterMessages(id string) ([]*types.Message, error) {
|
||||
msgs, err := w.api.GetFilterMessages(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
wrappedMsgs := make([]*types.Message, len(msgs))
|
||||
for index, msg := range msgs {
|
||||
wrappedMsgs[index] = &types.Message{
|
||||
Sig: msg.Sig,
|
||||
TTL: msg.TTL,
|
||||
Timestamp: msg.Timestamp,
|
||||
Topic: types.TopicType(msg.Topic),
|
||||
Payload: msg.Payload,
|
||||
Padding: msg.Padding,
|
||||
PoW: msg.PoW,
|
||||
Hash: msg.Hash,
|
||||
Dst: msg.Dst,
|
||||
P2P: msg.P2P,
|
||||
}
|
||||
}
|
||||
return wrappedMsgs, nil
|
||||
}
|
||||
|
||||
// Post posts a message on the network.
|
||||
// returns the hash of the message in case of success.
|
||||
func (w *GethPublicWakuAPIWrapper) Post(ctx context.Context, req types.NewMessage) ([]byte, error) {
|
||||
msg := waku.NewMessage{
|
||||
SymKeyID: req.SymKeyID,
|
||||
PublicKey: req.PublicKey,
|
||||
Sig: req.SigID, // Sig is really a SigID
|
||||
TTL: req.TTL,
|
||||
Topic: wakucommon.TopicType(req.Topic),
|
||||
Payload: req.Payload,
|
||||
Padding: req.Padding,
|
||||
PowTime: req.PowTime,
|
||||
PowTarget: req.PowTarget,
|
||||
TargetPeer: req.TargetPeer,
|
||||
Ephemeral: req.Ephemeral,
|
||||
}
|
||||
return w.api.Post(ctx, msg)
|
||||
}
|
||||
104
vendor/github.com/status-im/status-go/eth-node/bridge/geth/public_wakuv2_api.go
generated
vendored
Normal file
104
vendor/github.com/status-im/status-go/eth-node/bridge/geth/public_wakuv2_api.go
generated
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
package gethbridge
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
"github.com/status-im/status-go/wakuv2"
|
||||
wakucommon "github.com/status-im/status-go/wakuv2/common"
|
||||
)
|
||||
|
||||
type gethPublicWakuV2APIWrapper struct {
|
||||
api *wakuv2.PublicWakuAPI
|
||||
}
|
||||
|
||||
// NewGethPublicWakuAPIWrapper returns an object that wraps Geth's PublicWakuAPI in a types interface
|
||||
func NewGethPublicWakuV2APIWrapper(api *wakuv2.PublicWakuAPI) types.PublicWakuAPI {
|
||||
if api == nil {
|
||||
panic("PublicWakuV2API cannot be nil")
|
||||
}
|
||||
|
||||
return &gethPublicWakuV2APIWrapper{
|
||||
api: api,
|
||||
}
|
||||
}
|
||||
|
||||
// AddPrivateKey imports the given private key.
|
||||
func (w *gethPublicWakuV2APIWrapper) AddPrivateKey(ctx context.Context, privateKey types.HexBytes) (string, error) {
|
||||
return w.api.AddPrivateKey(ctx, hexutil.Bytes(privateKey))
|
||||
}
|
||||
|
||||
// GenerateSymKeyFromPassword derives a key from the given password, stores it, and returns its ID.
|
||||
func (w *gethPublicWakuV2APIWrapper) GenerateSymKeyFromPassword(ctx context.Context, passwd string) (string, error) {
|
||||
return w.api.GenerateSymKeyFromPassword(ctx, passwd)
|
||||
}
|
||||
|
||||
// DeleteKeyPair removes the key with the given key if it exists.
|
||||
func (w *gethPublicWakuV2APIWrapper) DeleteKeyPair(ctx context.Context, key string) (bool, error) {
|
||||
return w.api.DeleteKeyPair(ctx, key)
|
||||
}
|
||||
|
||||
func (w *gethPublicWakuV2APIWrapper) BloomFilter() []byte {
|
||||
return w.api.BloomFilter()
|
||||
}
|
||||
|
||||
// NewMessageFilter creates a new filter that can be used to poll for
|
||||
// (new) messages that satisfy the given criteria.
|
||||
func (w *gethPublicWakuV2APIWrapper) NewMessageFilter(req types.Criteria) (string, error) {
|
||||
topics := make([]wakucommon.TopicType, len(req.Topics))
|
||||
for index, tt := range req.Topics {
|
||||
topics[index] = wakucommon.TopicType(tt)
|
||||
}
|
||||
|
||||
criteria := wakuv2.Criteria{
|
||||
SymKeyID: req.SymKeyID,
|
||||
PrivateKeyID: req.PrivateKeyID,
|
||||
Sig: req.Sig,
|
||||
PubsubTopic: req.PubsubTopic,
|
||||
ContentTopics: topics,
|
||||
}
|
||||
return w.api.NewMessageFilter(criteria)
|
||||
}
|
||||
|
||||
// GetFilterMessages returns the messages that match the filter criteria and
|
||||
// are received between the last poll and now.
|
||||
func (w *gethPublicWakuV2APIWrapper) GetFilterMessages(id string) ([]*types.Message, error) {
|
||||
msgs, err := w.api.GetFilterMessages(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
wrappedMsgs := make([]*types.Message, len(msgs))
|
||||
for index, msg := range msgs {
|
||||
wrappedMsgs[index] = &types.Message{
|
||||
Sig: msg.Sig,
|
||||
Timestamp: msg.Timestamp,
|
||||
PubsubTopic: msg.PubsubTopic,
|
||||
Topic: types.TopicType(msg.ContentTopic),
|
||||
Payload: msg.Payload,
|
||||
Padding: msg.Padding,
|
||||
Hash: msg.Hash,
|
||||
Dst: msg.Dst,
|
||||
}
|
||||
}
|
||||
return wrappedMsgs, nil
|
||||
}
|
||||
|
||||
// Post posts a message on the network.
|
||||
// returns the hash of the message in case of success.
|
||||
func (w *gethPublicWakuV2APIWrapper) Post(ctx context.Context, req types.NewMessage) ([]byte, error) {
|
||||
msg := wakuv2.NewMessage{
|
||||
SymKeyID: req.SymKeyID,
|
||||
PublicKey: req.PublicKey,
|
||||
Sig: req.SigID, // Sig is really a SigID
|
||||
PubsubTopic: req.PubsubTopic,
|
||||
ContentTopic: wakucommon.TopicType(req.Topic),
|
||||
Payload: req.Payload,
|
||||
Padding: req.Padding,
|
||||
TargetPeer: req.TargetPeer,
|
||||
Ephemeral: req.Ephemeral,
|
||||
}
|
||||
return w.api.Post(ctx, msg)
|
||||
}
|
||||
30
vendor/github.com/status-im/status-go/eth-node/bridge/geth/subscription.go
generated
vendored
Normal file
30
vendor/github.com/status-im/status-go/eth-node/bridge/geth/subscription.go
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
package gethbridge
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
)
|
||||
|
||||
type gethSubscriptionWrapper struct {
|
||||
subscription event.Subscription
|
||||
}
|
||||
|
||||
// NewGethSubscriptionWrapper returns an object that wraps Geth's Subscription in a types interface
|
||||
func NewGethSubscriptionWrapper(subscription event.Subscription) types.Subscription {
|
||||
if subscription == nil {
|
||||
panic("subscription cannot be nil")
|
||||
}
|
||||
|
||||
return &gethSubscriptionWrapper{
|
||||
subscription: subscription,
|
||||
}
|
||||
}
|
||||
|
||||
func (w *gethSubscriptionWrapper) Err() <-chan error {
|
||||
return w.subscription.Err()
|
||||
}
|
||||
|
||||
func (w *gethSubscriptionWrapper) Unsubscribe() {
|
||||
w.subscription.Unsubscribe()
|
||||
}
|
||||
316
vendor/github.com/status-im/status-go/eth-node/bridge/geth/waku.go
generated
vendored
Normal file
316
vendor/github.com/status-im/status-go/eth-node/bridge/geth/waku.go
generated
vendored
Normal file
@@ -0,0 +1,316 @@
|
||||
package gethbridge
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/status-im/status-go/connection"
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
"github.com/status-im/status-go/waku"
|
||||
wakucommon "github.com/status-im/status-go/waku/common"
|
||||
)
|
||||
|
||||
type GethWakuWrapper struct {
|
||||
waku *waku.Waku
|
||||
}
|
||||
|
||||
// NewGethWakuWrapper returns an object that wraps Geth's Waku in a types interface
|
||||
func NewGethWakuWrapper(w *waku.Waku) types.Waku {
|
||||
if w == nil {
|
||||
panic("waku cannot be nil")
|
||||
}
|
||||
|
||||
return &GethWakuWrapper{
|
||||
waku: w,
|
||||
}
|
||||
}
|
||||
|
||||
// GetGethWhisperFrom retrieves the underlying whisper Whisper struct from a wrapped Whisper interface
|
||||
func GetGethWakuFrom(m types.Waku) *waku.Waku {
|
||||
return m.(*GethWakuWrapper).waku
|
||||
}
|
||||
|
||||
func (w *GethWakuWrapper) PublicWakuAPI() types.PublicWakuAPI {
|
||||
return NewGethPublicWakuAPIWrapper(waku.NewPublicWakuAPI(w.waku))
|
||||
}
|
||||
|
||||
func (w *GethWakuWrapper) Version() uint {
|
||||
return 1
|
||||
}
|
||||
|
||||
// Added for compatibility with waku V2
|
||||
func (w *GethWakuWrapper) PeerCount() int {
|
||||
return -1
|
||||
}
|
||||
|
||||
// Added for compatibility with waku V2
|
||||
func (w *GethWakuWrapper) StartDiscV5() error {
|
||||
return errors.New("not available in WakuV1")
|
||||
}
|
||||
|
||||
// Added for compatibility with waku V2
|
||||
func (w *GethWakuWrapper) StopDiscV5() error {
|
||||
return errors.New("not available in WakuV1")
|
||||
}
|
||||
|
||||
// PeerCount function only added for compatibility with waku V2
|
||||
func (w *GethWakuWrapper) AddStorePeer(address string) (peer.ID, error) {
|
||||
return "", errors.New("not available in WakuV1")
|
||||
}
|
||||
|
||||
// SubscribeToPubsubTopic function only added for compatibility with waku V2
|
||||
func (w *GethWakuWrapper) SubscribeToPubsubTopic(topic string, optPublicKey *ecdsa.PublicKey) error {
|
||||
// not available in WakuV1
|
||||
return errors.New("not available in WakuV1")
|
||||
}
|
||||
|
||||
func (w *GethWakuWrapper) UnsubscribeFromPubsubTopic(topic string) error {
|
||||
// not available in WakuV1
|
||||
return errors.New("not available in WakuV1")
|
||||
}
|
||||
|
||||
func (w *GethWakuWrapper) RetrievePubsubTopicKey(topic string) (*ecdsa.PrivateKey, error) {
|
||||
// not available in WakuV1
|
||||
return nil, errors.New("not available in WakuV1")
|
||||
}
|
||||
|
||||
func (w *GethWakuWrapper) StorePubsubTopicKey(topic string, privKey *ecdsa.PrivateKey) error {
|
||||
// not available in WakuV1
|
||||
return errors.New("not available in WakuV1")
|
||||
}
|
||||
|
||||
func (w *GethWakuWrapper) RemovePubsubTopicKey(topic string) error {
|
||||
// not available in WakuV1
|
||||
return errors.New("not available in WakuV1")
|
||||
}
|
||||
|
||||
// AddRelayPeer function only added for compatibility with waku V2
|
||||
func (w *GethWakuWrapper) AddRelayPeer(address string) (peer.ID, error) {
|
||||
return "", errors.New("not available in WakuV1")
|
||||
}
|
||||
|
||||
// DialPeer function only added for compatibility with waku V2
|
||||
func (w *GethWakuWrapper) DialPeer(address string) error {
|
||||
return errors.New("not available in WakuV1")
|
||||
}
|
||||
|
||||
// DialPeerByID function only added for compatibility with waku V2
|
||||
func (w *GethWakuWrapper) DialPeerByID(peerID string) error {
|
||||
return errors.New("not available in WakuV1")
|
||||
}
|
||||
|
||||
// ListenAddresses function only added for compatibility with waku V2
|
||||
func (w *GethWakuWrapper) ListenAddresses() ([]string, error) {
|
||||
return nil, errors.New("not available in WakuV1")
|
||||
}
|
||||
|
||||
// PeerCount function only added for compatibility with waku V2
|
||||
func (w *GethWakuWrapper) DropPeer(peerID string) error {
|
||||
return errors.New("not available in WakuV1")
|
||||
}
|
||||
|
||||
func (w *GethWakuWrapper) SubscribeToConnStatusChanges() (*types.ConnStatusSubscription, error) {
|
||||
return nil, errors.New("not available in WakuV1")
|
||||
}
|
||||
|
||||
// Peers function only added for compatibility with waku V2
|
||||
func (w *GethWakuWrapper) Peers() map[string]types.WakuV2Peer {
|
||||
p := make(map[string]types.WakuV2Peer)
|
||||
return p
|
||||
}
|
||||
|
||||
// MinPow returns the PoW value required by this node.
|
||||
func (w *GethWakuWrapper) MinPow() float64 {
|
||||
return w.waku.MinPow()
|
||||
}
|
||||
|
||||
// MaxMessageSize returns the MaxMessageSize set
|
||||
func (w *GethWakuWrapper) MaxMessageSize() uint32 {
|
||||
return w.waku.MaxMessageSize()
|
||||
}
|
||||
|
||||
// BloomFilter returns the aggregated bloom filter for all the topics of interest.
|
||||
// The nodes are required to send only messages that match the advertised bloom filter.
|
||||
// If a message does not match the bloom, it will tantamount to spam, and the peer will
|
||||
// be disconnected.
|
||||
func (w *GethWakuWrapper) BloomFilter() []byte {
|
||||
return w.waku.BloomFilter()
|
||||
}
|
||||
|
||||
// GetCurrentTime returns current time.
|
||||
func (w *GethWakuWrapper) GetCurrentTime() time.Time {
|
||||
return w.waku.CurrentTime()
|
||||
}
|
||||
|
||||
func (w *GethWakuWrapper) SubscribeEnvelopeEvents(eventsProxy chan<- types.EnvelopeEvent) types.Subscription {
|
||||
events := make(chan wakucommon.EnvelopeEvent, 100) // must be buffered to prevent blocking whisper
|
||||
go func() {
|
||||
for e := range events {
|
||||
eventsProxy <- *NewWakuEnvelopeEventWrapper(&e)
|
||||
}
|
||||
}()
|
||||
|
||||
return NewGethSubscriptionWrapper(w.waku.SubscribeEnvelopeEvents(events))
|
||||
}
|
||||
|
||||
func (w *GethWakuWrapper) GetPrivateKey(id string) (*ecdsa.PrivateKey, error) {
|
||||
return w.waku.GetPrivateKey(id)
|
||||
}
|
||||
|
||||
// AddKeyPair imports a asymmetric private key and returns a deterministic identifier.
|
||||
func (w *GethWakuWrapper) AddKeyPair(key *ecdsa.PrivateKey) (string, error) {
|
||||
return w.waku.AddKeyPair(key)
|
||||
}
|
||||
|
||||
// DeleteKeyPair deletes the key with the specified ID if it exists.
|
||||
func (w *GethWakuWrapper) DeleteKeyPair(keyID string) bool {
|
||||
return w.waku.DeleteKeyPair(keyID)
|
||||
}
|
||||
|
||||
func (w *GethWakuWrapper) AddSymKeyDirect(key []byte) (string, error) {
|
||||
return w.waku.AddSymKeyDirect(key)
|
||||
}
|
||||
|
||||
func (w *GethWakuWrapper) AddSymKeyFromPassword(password string) (string, error) {
|
||||
return w.waku.AddSymKeyFromPassword(password)
|
||||
}
|
||||
|
||||
func (w *GethWakuWrapper) DeleteSymKey(id string) bool {
|
||||
return w.waku.DeleteSymKey(id)
|
||||
}
|
||||
|
||||
func (w *GethWakuWrapper) GetSymKey(id string) ([]byte, error) {
|
||||
return w.waku.GetSymKey(id)
|
||||
}
|
||||
|
||||
func (w *GethWakuWrapper) Subscribe(opts *types.SubscriptionOptions) (string, error) {
|
||||
var (
|
||||
err error
|
||||
keyAsym *ecdsa.PrivateKey
|
||||
keySym []byte
|
||||
)
|
||||
|
||||
if opts.SymKeyID != "" {
|
||||
keySym, err = w.GetSymKey(opts.SymKeyID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
if opts.PrivateKeyID != "" {
|
||||
keyAsym, err = w.GetPrivateKey(opts.PrivateKeyID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
f, err := w.createFilterWrapper("", keyAsym, keySym, opts.PoW, opts.Topics)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
id, err := w.waku.Subscribe(GetWakuFilterFrom(f))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
f.(*wakuFilterWrapper).id = id
|
||||
return id, nil
|
||||
}
|
||||
|
||||
func (w *GethWakuWrapper) GetStats() types.StatsSummary {
|
||||
return w.waku.GetStats()
|
||||
}
|
||||
|
||||
func (w *GethWakuWrapper) GetFilter(id string) types.Filter {
|
||||
return NewWakuFilterWrapper(w.waku.GetFilter(id), id)
|
||||
}
|
||||
|
||||
func (w *GethWakuWrapper) Unsubscribe(ctx context.Context, id string) error {
|
||||
return w.waku.Unsubscribe(id)
|
||||
}
|
||||
|
||||
func (w *GethWakuWrapper) UnsubscribeMany(ids []string) error {
|
||||
return w.waku.UnsubscribeMany(ids)
|
||||
}
|
||||
|
||||
func (w *GethWakuWrapper) createFilterWrapper(id string, keyAsym *ecdsa.PrivateKey, keySym []byte, pow float64, topics [][]byte) (types.Filter, error) {
|
||||
return NewWakuFilterWrapper(&wakucommon.Filter{
|
||||
KeyAsym: keyAsym,
|
||||
KeySym: keySym,
|
||||
PoW: pow,
|
||||
AllowP2P: true,
|
||||
Topics: topics,
|
||||
Messages: wakucommon.NewMemoryMessageStore(),
|
||||
}, id), nil
|
||||
}
|
||||
|
||||
func (w *GethWakuWrapper) SendMessagesRequest(peerID []byte, r types.MessagesRequest) error {
|
||||
return w.waku.SendMessagesRequest(peerID, wakucommon.MessagesRequest{
|
||||
ID: r.ID,
|
||||
From: r.From,
|
||||
To: r.To,
|
||||
Limit: r.Limit,
|
||||
Cursor: r.Cursor,
|
||||
Bloom: r.Bloom,
|
||||
Topics: r.ContentTopics,
|
||||
})
|
||||
}
|
||||
|
||||
// RequestHistoricMessages sends a message with p2pRequestCode to a specific peer,
|
||||
// which is known to implement MailServer interface, and is supposed to process this
|
||||
// request and respond with a number of peer-to-peer messages (possibly expired),
|
||||
// which are not supposed to be forwarded any further.
|
||||
// The whisper protocol is agnostic of the format and contents of envelope.
|
||||
func (w *GethWakuWrapper) RequestHistoricMessagesWithTimeout(peerID []byte, envelope types.Envelope, timeout time.Duration) error {
|
||||
return w.waku.RequestHistoricMessagesWithTimeout(peerID, envelope.Unwrap().(*wakucommon.Envelope), timeout)
|
||||
}
|
||||
|
||||
func (w *GethWakuWrapper) ProcessingP2PMessages() bool {
|
||||
return w.waku.ProcessingP2PMessages()
|
||||
}
|
||||
|
||||
func (w *GethWakuWrapper) MarkP2PMessageAsProcessed(hash common.Hash) {
|
||||
w.waku.MarkP2PMessageAsProcessed(hash)
|
||||
}
|
||||
|
||||
func (w *GethWakuWrapper) RequestStoreMessages(ctx context.Context, peerID []byte, r types.MessagesRequest, processEnvelopes bool) (*types.StoreRequestCursor, int, error) {
|
||||
return nil, 0, errors.New("not implemented")
|
||||
}
|
||||
|
||||
func (w *GethWakuWrapper) ConnectionChanged(_ connection.State) {}
|
||||
|
||||
func (w *GethWakuWrapper) ClearEnvelopesCache() {
|
||||
w.waku.ClearEnvelopesCache()
|
||||
}
|
||||
|
||||
type wakuFilterWrapper struct {
|
||||
filter *wakucommon.Filter
|
||||
id string
|
||||
}
|
||||
|
||||
// NewWakuFilterWrapper returns an object that wraps Geth's Filter in a types interface
|
||||
func NewWakuFilterWrapper(f *wakucommon.Filter, id string) types.Filter {
|
||||
if f.Messages == nil {
|
||||
panic("Messages should not be nil")
|
||||
}
|
||||
|
||||
return &wakuFilterWrapper{
|
||||
filter: f,
|
||||
id: id,
|
||||
}
|
||||
}
|
||||
|
||||
// GetWakuFilterFrom retrieves the underlying whisper Filter struct from a wrapped Filter interface
|
||||
func GetWakuFilterFrom(f types.Filter) *wakucommon.Filter {
|
||||
return f.(*wakuFilterWrapper).filter
|
||||
}
|
||||
|
||||
// ID returns the filter ID
|
||||
func (w *wakuFilterWrapper) ID() string {
|
||||
return w.id
|
||||
}
|
||||
329
vendor/github.com/status-im/status-go/eth-node/bridge/geth/wakuv2.go
generated
vendored
Normal file
329
vendor/github.com/status-im/status-go/eth-node/bridge/geth/wakuv2.go
generated
vendored
Normal file
@@ -0,0 +1,329 @@
|
||||
package gethbridge
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
|
||||
"github.com/waku-org/go-waku/waku/v2/protocol/store"
|
||||
storepb "github.com/waku-org/go-waku/waku/v2/protocol/store/pb"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/status-im/status-go/connection"
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
"github.com/status-im/status-go/wakuv2"
|
||||
wakucommon "github.com/status-im/status-go/wakuv2/common"
|
||||
)
|
||||
|
||||
type gethWakuV2Wrapper struct {
|
||||
waku *wakuv2.Waku
|
||||
}
|
||||
|
||||
// NewGethWakuWrapper returns an object that wraps Geth's Waku in a types interface
|
||||
func NewGethWakuV2Wrapper(w *wakuv2.Waku) types.Waku {
|
||||
if w == nil {
|
||||
panic("waku cannot be nil")
|
||||
}
|
||||
|
||||
return &gethWakuV2Wrapper{
|
||||
waku: w,
|
||||
}
|
||||
}
|
||||
|
||||
// GetGethWhisperFrom retrieves the underlying whisper Whisper struct from a wrapped Whisper interface
|
||||
func GetGethWakuV2From(m types.Waku) *wakuv2.Waku {
|
||||
return m.(*gethWakuV2Wrapper).waku
|
||||
}
|
||||
|
||||
func (w *gethWakuV2Wrapper) PublicWakuAPI() types.PublicWakuAPI {
|
||||
return NewGethPublicWakuV2APIWrapper(wakuv2.NewPublicWakuAPI(w.waku))
|
||||
}
|
||||
|
||||
func (w *gethWakuV2Wrapper) Version() uint {
|
||||
return 2
|
||||
}
|
||||
|
||||
func (w *gethWakuV2Wrapper) PeerCount() int {
|
||||
return w.waku.PeerCount()
|
||||
}
|
||||
|
||||
// DEPRECATED: Not used in WakuV2
|
||||
func (w *gethWakuV2Wrapper) MinPow() float64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
// MaxMessageSize returns the MaxMessageSize set
|
||||
func (w *gethWakuV2Wrapper) MaxMessageSize() uint32 {
|
||||
return w.waku.MaxMessageSize()
|
||||
}
|
||||
|
||||
// DEPRECATED: not used in WakuV2
|
||||
func (w *gethWakuV2Wrapper) BloomFilter() []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetCurrentTime returns current time.
|
||||
func (w *gethWakuV2Wrapper) GetCurrentTime() time.Time {
|
||||
return w.waku.CurrentTime()
|
||||
}
|
||||
|
||||
func (w *gethWakuV2Wrapper) SubscribeEnvelopeEvents(eventsProxy chan<- types.EnvelopeEvent) types.Subscription {
|
||||
events := make(chan wakucommon.EnvelopeEvent, 100) // must be buffered to prevent blocking whisper
|
||||
go func() {
|
||||
for e := range events {
|
||||
eventsProxy <- *NewWakuV2EnvelopeEventWrapper(&e)
|
||||
}
|
||||
}()
|
||||
|
||||
return NewGethSubscriptionWrapper(w.waku.SubscribeEnvelopeEvents(events))
|
||||
}
|
||||
|
||||
func (w *gethWakuV2Wrapper) GetPrivateKey(id string) (*ecdsa.PrivateKey, error) {
|
||||
return w.waku.GetPrivateKey(id)
|
||||
}
|
||||
|
||||
// AddKeyPair imports a asymmetric private key and returns a deterministic identifier.
|
||||
func (w *gethWakuV2Wrapper) AddKeyPair(key *ecdsa.PrivateKey) (string, error) {
|
||||
return w.waku.AddKeyPair(key)
|
||||
}
|
||||
|
||||
// DeleteKeyPair deletes the key with the specified ID if it exists.
|
||||
func (w *gethWakuV2Wrapper) DeleteKeyPair(keyID string) bool {
|
||||
return w.waku.DeleteKeyPair(keyID)
|
||||
}
|
||||
|
||||
func (w *gethWakuV2Wrapper) AddSymKeyDirect(key []byte) (string, error) {
|
||||
return w.waku.AddSymKeyDirect(key)
|
||||
}
|
||||
|
||||
func (w *gethWakuV2Wrapper) AddSymKeyFromPassword(password string) (string, error) {
|
||||
return w.waku.AddSymKeyFromPassword(password)
|
||||
}
|
||||
|
||||
func (w *gethWakuV2Wrapper) DeleteSymKey(id string) bool {
|
||||
return w.waku.DeleteSymKey(id)
|
||||
}
|
||||
|
||||
func (w *gethWakuV2Wrapper) GetSymKey(id string) ([]byte, error) {
|
||||
return w.waku.GetSymKey(id)
|
||||
}
|
||||
|
||||
func (w *gethWakuV2Wrapper) Subscribe(opts *types.SubscriptionOptions) (string, error) {
|
||||
var (
|
||||
err error
|
||||
keyAsym *ecdsa.PrivateKey
|
||||
keySym []byte
|
||||
)
|
||||
|
||||
if opts.SymKeyID != "" {
|
||||
keySym, err = w.GetSymKey(opts.SymKeyID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
if opts.PrivateKeyID != "" {
|
||||
keyAsym, err = w.GetPrivateKey(opts.PrivateKeyID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
f, err := w.createFilterWrapper("", keyAsym, keySym, opts.PoW, opts.PubsubTopic, opts.Topics)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
id, err := w.waku.Subscribe(GetWakuV2FilterFrom(f))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
f.(*wakuV2FilterWrapper).id = id
|
||||
return id, nil
|
||||
}
|
||||
|
||||
func (w *gethWakuV2Wrapper) GetStats() types.StatsSummary {
|
||||
return w.waku.GetStats()
|
||||
}
|
||||
|
||||
func (w *gethWakuV2Wrapper) GetFilter(id string) types.Filter {
|
||||
return NewWakuV2FilterWrapper(w.waku.GetFilter(id), id)
|
||||
}
|
||||
|
||||
func (w *gethWakuV2Wrapper) Unsubscribe(ctx context.Context, id string) error {
|
||||
return w.waku.Unsubscribe(ctx, id)
|
||||
}
|
||||
|
||||
func (w *gethWakuV2Wrapper) UnsubscribeMany(ids []string) error {
|
||||
return w.waku.UnsubscribeMany(ids)
|
||||
}
|
||||
|
||||
func (w *gethWakuV2Wrapper) createFilterWrapper(id string, keyAsym *ecdsa.PrivateKey, keySym []byte, pow float64, pubsubTopic string, topics [][]byte) (types.Filter, error) {
|
||||
return NewWakuV2FilterWrapper(&wakucommon.Filter{
|
||||
KeyAsym: keyAsym,
|
||||
KeySym: keySym,
|
||||
ContentTopics: wakucommon.NewTopicSetFromBytes(topics),
|
||||
PubsubTopic: pubsubTopic,
|
||||
Messages: wakucommon.NewMemoryMessageStore(),
|
||||
}, id), nil
|
||||
}
|
||||
|
||||
// DEPRECATED: Not used in waku V2
|
||||
func (w *gethWakuV2Wrapper) SendMessagesRequest(peerID []byte, r types.MessagesRequest) error {
|
||||
return errors.New("DEPRECATED")
|
||||
}
|
||||
|
||||
func (w *gethWakuV2Wrapper) RequestStoreMessages(ctx context.Context, peerID []byte, r types.MessagesRequest, processEnvelopes bool) (*types.StoreRequestCursor, int, error) {
|
||||
var options []store.HistoryRequestOption
|
||||
|
||||
peer, err := peer.Decode(string(peerID))
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
options = []store.HistoryRequestOption{
|
||||
store.WithPaging(false, uint64(r.Limit)),
|
||||
}
|
||||
|
||||
if r.StoreCursor != nil {
|
||||
options = append(options, store.WithCursor(&storepb.Index{
|
||||
Digest: r.StoreCursor.Digest,
|
||||
ReceiverTime: r.StoreCursor.ReceiverTime,
|
||||
SenderTime: r.StoreCursor.SenderTime,
|
||||
PubsubTopic: r.StoreCursor.PubsubTopic,
|
||||
}))
|
||||
}
|
||||
|
||||
var contentTopics []wakucommon.TopicType
|
||||
for _, topic := range r.ContentTopics {
|
||||
contentTopics = append(contentTopics, wakucommon.BytesToTopic(topic))
|
||||
}
|
||||
|
||||
pbCursor, envelopesCount, err := w.waku.Query(ctx, peer, r.PubsubTopic, contentTopics, uint64(r.From), uint64(r.To), options, processEnvelopes)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
if pbCursor != nil {
|
||||
return &types.StoreRequestCursor{
|
||||
Digest: pbCursor.Digest,
|
||||
ReceiverTime: pbCursor.ReceiverTime,
|
||||
SenderTime: pbCursor.SenderTime,
|
||||
PubsubTopic: pbCursor.PubsubTopic,
|
||||
}, envelopesCount, nil
|
||||
}
|
||||
|
||||
return nil, envelopesCount, nil
|
||||
}
|
||||
|
||||
// DEPRECATED: Not used in waku V2
|
||||
func (w *gethWakuV2Wrapper) RequestHistoricMessagesWithTimeout(peerID []byte, envelope types.Envelope, timeout time.Duration) error {
|
||||
return errors.New("DEPRECATED")
|
||||
}
|
||||
|
||||
func (w *gethWakuV2Wrapper) StartDiscV5() error {
|
||||
return w.waku.StartDiscV5()
|
||||
}
|
||||
|
||||
func (w *gethWakuV2Wrapper) StopDiscV5() error {
|
||||
return w.waku.StopDiscV5()
|
||||
}
|
||||
|
||||
// Subscribe to a pubsub topic, passing an optional public key if the pubsub topic is protected
|
||||
func (w *gethWakuV2Wrapper) SubscribeToPubsubTopic(topic string, optPublicKey *ecdsa.PublicKey) error {
|
||||
return w.waku.SubscribeToPubsubTopic(topic, optPublicKey)
|
||||
}
|
||||
|
||||
func (w *gethWakuV2Wrapper) UnsubscribeFromPubsubTopic(topic string) error {
|
||||
return w.waku.UnsubscribeFromPubsubTopic(topic)
|
||||
}
|
||||
|
||||
func (w *gethWakuV2Wrapper) RetrievePubsubTopicKey(topic string) (*ecdsa.PrivateKey, error) {
|
||||
return w.waku.RetrievePubsubTopicKey(topic)
|
||||
}
|
||||
|
||||
func (w *gethWakuV2Wrapper) StorePubsubTopicKey(topic string, privKey *ecdsa.PrivateKey) error {
|
||||
return w.waku.StorePubsubTopicKey(topic, privKey)
|
||||
}
|
||||
|
||||
func (w *gethWakuV2Wrapper) RemovePubsubTopicKey(topic string) error {
|
||||
return w.waku.RemovePubsubTopicKey(topic)
|
||||
}
|
||||
|
||||
func (w *gethWakuV2Wrapper) AddStorePeer(address string) (peer.ID, error) {
|
||||
return w.waku.AddStorePeer(address)
|
||||
}
|
||||
|
||||
func (w *gethWakuV2Wrapper) AddRelayPeer(address string) (peer.ID, error) {
|
||||
return w.waku.AddRelayPeer(address)
|
||||
}
|
||||
|
||||
func (w *gethWakuV2Wrapper) Peers() map[string]types.WakuV2Peer {
|
||||
return w.waku.Peers()
|
||||
}
|
||||
|
||||
func (w *gethWakuV2Wrapper) DialPeer(address string) error {
|
||||
return w.waku.DialPeer(address)
|
||||
}
|
||||
|
||||
func (w *gethWakuV2Wrapper) DialPeerByID(peerID string) error {
|
||||
return w.waku.DialPeerByID(peerID)
|
||||
}
|
||||
|
||||
func (w *gethWakuV2Wrapper) ListenAddresses() ([]string, error) {
|
||||
return w.waku.ListenAddresses(), nil
|
||||
}
|
||||
|
||||
func (w *gethWakuV2Wrapper) DropPeer(peerID string) error {
|
||||
return w.waku.DropPeer(peerID)
|
||||
}
|
||||
|
||||
func (w *gethWakuV2Wrapper) ProcessingP2PMessages() bool {
|
||||
return w.waku.ProcessingP2PMessages()
|
||||
}
|
||||
|
||||
func (w *gethWakuV2Wrapper) MarkP2PMessageAsProcessed(hash common.Hash) {
|
||||
w.waku.MarkP2PMessageAsProcessed(hash)
|
||||
}
|
||||
|
||||
func (w *gethWakuV2Wrapper) SubscribeToConnStatusChanges() (*types.ConnStatusSubscription, error) {
|
||||
return w.waku.SubscribeToConnStatusChanges(), nil
|
||||
}
|
||||
|
||||
func (w *gethWakuV2Wrapper) ConnectionChanged(state connection.State) {
|
||||
w.waku.ConnectionChanged(state)
|
||||
}
|
||||
|
||||
func (w *gethWakuV2Wrapper) ClearEnvelopesCache() {
|
||||
w.waku.ClearEnvelopesCache()
|
||||
}
|
||||
|
||||
type wakuV2FilterWrapper struct {
|
||||
filter *wakucommon.Filter
|
||||
id string
|
||||
}
|
||||
|
||||
// NewWakuFilterWrapper returns an object that wraps Geth's Filter in a types interface
|
||||
func NewWakuV2FilterWrapper(f *wakucommon.Filter, id string) types.Filter {
|
||||
if f.Messages == nil {
|
||||
panic("Messages should not be nil")
|
||||
}
|
||||
|
||||
return &wakuV2FilterWrapper{
|
||||
filter: f,
|
||||
id: id,
|
||||
}
|
||||
}
|
||||
|
||||
// GetWakuFilterFrom retrieves the underlying whisper Filter struct from a wrapped Filter interface
|
||||
func GetWakuV2FilterFrom(f types.Filter) *wakucommon.Filter {
|
||||
return f.(*wakuV2FilterWrapper).filter
|
||||
}
|
||||
|
||||
// ID returns the filter ID
|
||||
func (w *wakuV2FilterWrapper) ID() string {
|
||||
return w.id
|
||||
}
|
||||
48
vendor/github.com/status-im/status-go/eth-node/core/types/transaction.go
generated
vendored
Normal file
48
vendor/github.com/status-im/status-go/eth-node/core/types/transaction.go
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
)
|
||||
|
||||
type TransactionStatus uint64
|
||||
|
||||
const (
|
||||
TransactionStatusFailed = 0
|
||||
TransactionStatusSuccess = 1
|
||||
TransactionStatusPending = 2
|
||||
)
|
||||
|
||||
type Message struct {
|
||||
to *types.Address
|
||||
from types.Address
|
||||
nonce uint64
|
||||
amount *big.Int
|
||||
gasLimit uint64
|
||||
gasPrice *big.Int
|
||||
data []byte
|
||||
checkNonce bool
|
||||
}
|
||||
|
||||
func NewMessage(from types.Address, to *types.Address, nonce uint64, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte, checkNonce bool) Message {
|
||||
return Message{
|
||||
from: from,
|
||||
to: to,
|
||||
nonce: nonce,
|
||||
amount: amount,
|
||||
gasLimit: gasLimit,
|
||||
gasPrice: gasPrice,
|
||||
data: data,
|
||||
checkNonce: checkNonce,
|
||||
}
|
||||
}
|
||||
|
||||
func (m Message) From() types.Address { return m.from }
|
||||
func (m Message) To() *types.Address { return m.to }
|
||||
func (m Message) GasPrice() *big.Int { return m.gasPrice }
|
||||
func (m Message) Value() *big.Int { return m.amount }
|
||||
func (m Message) Gas() uint64 { return m.gasLimit }
|
||||
func (m Message) Nonce() uint64 { return m.nonce }
|
||||
func (m Message) Data() []byte { return m.data }
|
||||
func (m Message) CheckNonce() bool { return m.checkNonce }
|
||||
254
vendor/github.com/status-im/status-go/eth-node/crypto/crypto.go
generated
vendored
Normal file
254
vendor/github.com/status-im/status-go/eth-node/crypto/crypto.go
generated
vendored
Normal file
@@ -0,0 +1,254 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/ecdsa"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/crypto/sha3"
|
||||
|
||||
types "github.com/status-im/status-go/eth-node/types"
|
||||
|
||||
gethcrypto "github.com/ethereum/go-ethereum/crypto"
|
||||
)
|
||||
|
||||
const (
|
||||
aesNonceLength = 12
|
||||
)
|
||||
|
||||
// Sign calculates an ECDSA signature.
|
||||
//
|
||||
// This function is susceptible to chosen plaintext attacks that can leak
|
||||
// information about the private key that is used for signing. Callers must
|
||||
// be aware that the given digest cannot be chosen by an adversery. Common
|
||||
// solution is to hash any input before calculating the signature.
|
||||
//
|
||||
// The produced signature is in the [R || S || V] format where V is 0 or 1.
|
||||
func Sign(digestHash []byte, prv *ecdsa.PrivateKey) (sig []byte, err error) {
|
||||
return gethcrypto.Sign(digestHash, prv)
|
||||
}
|
||||
|
||||
// SignBytes signs the hash of arbitrary data.
|
||||
func SignBytes(data []byte, prv *ecdsa.PrivateKey) (sig []byte, err error) {
|
||||
return Sign(Keccak256(data), prv)
|
||||
}
|
||||
|
||||
// SignBytesAsHex signs the Keccak256 hash of arbitrary data and returns its hex representation.
|
||||
func SignBytesAsHex(data []byte, identity *ecdsa.PrivateKey) (string, error) {
|
||||
signature, err := SignBytes(data, identity)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return hex.EncodeToString(signature), nil
|
||||
}
|
||||
|
||||
// SignStringAsHex signs the Keccak256 hash of arbitrary string and returns its hex representation.
|
||||
func SignStringAsHex(data string, identity *ecdsa.PrivateKey) (string, error) {
|
||||
return SignBytesAsHex([]byte(data), identity)
|
||||
}
|
||||
|
||||
// VerifySignatures verifies tuples of signatures content/hash/public key
|
||||
func VerifySignatures(signaturePairs [][3]string) error {
|
||||
for _, signaturePair := range signaturePairs {
|
||||
content := Keccak256([]byte(signaturePair[0]))
|
||||
|
||||
signature, err := hex.DecodeString(signaturePair[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
publicKeyBytes, err := hex.DecodeString(signaturePair[2])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
publicKey, err := UnmarshalPubkey(publicKeyBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
recoveredKey, err := SigToPub(
|
||||
content,
|
||||
signature,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if PubkeyToAddress(*recoveredKey) != PubkeyToAddress(*publicKey) {
|
||||
return errors.New("identity key and signature mismatch")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ExtractSignatures extract from tuples of signatures content a public key
|
||||
// DEPRECATED: use ExtractSignature
|
||||
func ExtractSignatures(signaturePairs [][2]string) ([]string, error) {
|
||||
response := make([]string, len(signaturePairs))
|
||||
for i, signaturePair := range signaturePairs {
|
||||
content := Keccak256([]byte(signaturePair[0]))
|
||||
|
||||
signature, err := hex.DecodeString(signaturePair[1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
recoveredKey, err := SigToPub(
|
||||
content,
|
||||
signature,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response[i] = fmt.Sprintf("%x", FromECDSAPub(recoveredKey))
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
// ExtractSignature returns a public key for a given data and signature.
|
||||
func ExtractSignature(data, signature []byte) (*ecdsa.PublicKey, error) {
|
||||
dataHash := Keccak256(data)
|
||||
return SigToPub(dataHash, signature)
|
||||
}
|
||||
|
||||
func EncryptSymmetric(key, plaintext []byte) ([]byte, error) {
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Never use more than 2^32 random nonces with a given key because of the risk of a repeat.
|
||||
salt, err := generateSecureRandomData(aesNonceLength)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
aesgcm, err := cipher.NewGCM(block)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
encrypted := aesgcm.Seal(nil, salt, plaintext, nil)
|
||||
return append(encrypted, salt...), nil
|
||||
}
|
||||
|
||||
func DecryptSymmetric(key []byte, cyphertext []byte) ([]byte, error) {
|
||||
// symmetric messages are expected to contain the 12-byte nonce at the end of the payload
|
||||
if len(cyphertext) < aesNonceLength {
|
||||
return nil, errors.New("missing salt or invalid payload in symmetric message")
|
||||
}
|
||||
salt := cyphertext[len(cyphertext)-aesNonceLength:]
|
||||
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
aesgcm, err := cipher.NewGCM(block)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
decrypted, err := aesgcm.Open(nil, salt, cyphertext[:len(cyphertext)-aesNonceLength], nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return decrypted, nil
|
||||
}
|
||||
|
||||
func containsOnlyZeros(data []byte) bool {
|
||||
for _, b := range data {
|
||||
if b != 0 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func validateDataIntegrity(k []byte, expectedSize int) bool {
|
||||
if len(k) != expectedSize {
|
||||
return false
|
||||
}
|
||||
if containsOnlyZeros(k) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func generateSecureRandomData(length int) ([]byte, error) {
|
||||
res := make([]byte, length)
|
||||
|
||||
_, err := rand.Read(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !validateDataIntegrity(res, length) {
|
||||
return nil, errors.New("crypto/rand failed to generate secure random data")
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// TextHash is a helper function that calculates a hash for the given message that can be
|
||||
// safely used to calculate a signature from.
|
||||
//
|
||||
// The hash is calulcated as
|
||||
//
|
||||
// keccak256("\x19Ethereum Signed Message:\n"${message length}${message}).
|
||||
//
|
||||
// This gives context to the signed message and prevents signing of transactions.
|
||||
func TextHash(data []byte) []byte {
|
||||
hash, _ := TextAndHash(data)
|
||||
return hash
|
||||
}
|
||||
|
||||
// TextAndHash is a helper function that calculates a hash for the given message that can be
|
||||
// safely used to calculate a signature from.
|
||||
//
|
||||
// The hash is calulcated as
|
||||
//
|
||||
// keccak256("\x19Ethereum Signed Message:\n"${message length}${message}).
|
||||
//
|
||||
// This gives context to the signed message and prevents signing of transactions.
|
||||
func TextAndHash(data []byte) ([]byte, string) {
|
||||
msg := fmt.Sprintf("\x19Ethereum Signed Message:\n%d%s", len(data), string(data))
|
||||
hasher := sha3.NewLegacyKeccak256()
|
||||
_, _ = hasher.Write([]byte(msg))
|
||||
return hasher.Sum(nil), msg
|
||||
}
|
||||
|
||||
func EcRecover(ctx context.Context, data types.HexBytes, sig types.HexBytes) (types.Address, error) {
|
||||
// Returns the address for the Account that was used to create the signature.
|
||||
//
|
||||
// Note, this function is compatible with eth_sign and personal_sign. As such it recovers
|
||||
// the address of:
|
||||
// hash = keccak256("\x19${byteVersion}Ethereum Signed Message:\n${message length}${message}")
|
||||
// addr = ecrecover(hash, signature)
|
||||
//
|
||||
// Note, the signature must conform to the secp256k1 curve R, S and V values, where
|
||||
// the V value must be be 27 or 28 for legacy reasons.
|
||||
//
|
||||
// https://github.com/ethereum/go-ethereum/wiki/Management-APIs#personal_ecRecover
|
||||
if len(sig) != 65 {
|
||||
return types.Address{}, fmt.Errorf("signature must be 65 bytes long")
|
||||
}
|
||||
if sig[64] != 27 && sig[64] != 28 {
|
||||
return types.Address{}, fmt.Errorf("invalid Ethereum signature (V is not 27 or 28)")
|
||||
}
|
||||
sig[64] -= 27 // Transform yellow paper V from 27/28 to 0/1
|
||||
hash := TextHash(data)
|
||||
rpk, err := SigToPub(hash, sig)
|
||||
if err != nil {
|
||||
return types.Address{}, err
|
||||
}
|
||||
return PubkeyToAddress(*rpk), nil
|
||||
}
|
||||
366
vendor/github.com/status-im/status-go/eth-node/crypto/ecies/ecies.go
generated
vendored
Normal file
366
vendor/github.com/status-im/status-go/eth-node/crypto/ecies/ecies.go
generated
vendored
Normal file
@@ -0,0 +1,366 @@
|
||||
// Copyright (c) 2013 Kyle Isom <kyle@tyrfingr.is>
|
||||
// Copyright (c) 2012 The Go Authors. All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package ecies
|
||||
|
||||
import (
|
||||
"crypto/cipher"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/hmac"
|
||||
"crypto/subtle"
|
||||
"fmt"
|
||||
"hash"
|
||||
"io"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrImport = fmt.Errorf("ecies: failed to import key")
|
||||
ErrInvalidCurve = fmt.Errorf("ecies: invalid elliptic curve")
|
||||
ErrInvalidParams = fmt.Errorf("ecies: invalid ECIES parameters")
|
||||
ErrInvalidPublicKey = fmt.Errorf("ecies: invalid public key")
|
||||
ErrSharedKeyIsPointAtInfinity = fmt.Errorf("ecies: shared key is point at infinity")
|
||||
ErrSharedKeyTooBig = fmt.Errorf("ecies: shared key params are too big")
|
||||
)
|
||||
|
||||
// PublicKey is a representation of an elliptic curve public key.
|
||||
type PublicKey struct {
|
||||
X *big.Int
|
||||
Y *big.Int
|
||||
elliptic.Curve
|
||||
Params *ECIESParams
|
||||
}
|
||||
|
||||
// Export an ECIES public key as an ECDSA public key.
|
||||
func (pub *PublicKey) ExportECDSA() *ecdsa.PublicKey {
|
||||
return &ecdsa.PublicKey{Curve: pub.Curve, X: pub.X, Y: pub.Y}
|
||||
}
|
||||
|
||||
// Import an ECDSA public key as an ECIES public key.
|
||||
func ImportECDSAPublic(pub *ecdsa.PublicKey) *PublicKey {
|
||||
return &PublicKey{
|
||||
X: pub.X,
|
||||
Y: pub.Y,
|
||||
Curve: pub.Curve,
|
||||
Params: ParamsFromCurve(pub.Curve),
|
||||
}
|
||||
}
|
||||
|
||||
// PrivateKey is a representation of an elliptic curve private key.
|
||||
type PrivateKey struct {
|
||||
PublicKey
|
||||
D *big.Int
|
||||
}
|
||||
|
||||
// Export an ECIES private key as an ECDSA private key.
|
||||
func (prv *PrivateKey) ExportECDSA() *ecdsa.PrivateKey {
|
||||
pub := &prv.PublicKey
|
||||
pubECDSA := pub.ExportECDSA()
|
||||
return &ecdsa.PrivateKey{PublicKey: *pubECDSA, D: prv.D}
|
||||
}
|
||||
|
||||
// Import an ECDSA private key as an ECIES private key.
|
||||
func ImportECDSA(prv *ecdsa.PrivateKey) *PrivateKey {
|
||||
pub := ImportECDSAPublic(&prv.PublicKey)
|
||||
return &PrivateKey{*pub, prv.D}
|
||||
}
|
||||
|
||||
// Generate an elliptic curve public / private keypair. If params is nil,
|
||||
// the recommended default parameters for the key will be chosen.
|
||||
func GenerateKey(rand io.Reader, curve elliptic.Curve, params *ECIESParams) (prv *PrivateKey, err error) {
|
||||
pb, x, y, err := elliptic.GenerateKey(curve, rand)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
prv = new(PrivateKey)
|
||||
prv.PublicKey.X = x
|
||||
prv.PublicKey.Y = y
|
||||
prv.PublicKey.Curve = curve
|
||||
prv.D = new(big.Int).SetBytes(pb)
|
||||
if params == nil {
|
||||
params = ParamsFromCurve(curve)
|
||||
}
|
||||
prv.PublicKey.Params = params
|
||||
return
|
||||
}
|
||||
|
||||
// MaxSharedKeyLength returns the maximum length of the shared key the
|
||||
// public key can produce.
|
||||
func MaxSharedKeyLength(pub *PublicKey) int {
|
||||
return (pub.Curve.Params().BitSize + 7) / 8
|
||||
}
|
||||
|
||||
// ECDH key agreement method used to establish secret keys for encryption.
|
||||
func (prv *PrivateKey) GenerateShared(pub *PublicKey, skLen, macLen int) (sk []byte, err error) {
|
||||
if prv.PublicKey.Curve != pub.Curve {
|
||||
return nil, ErrInvalidCurve
|
||||
}
|
||||
if skLen+macLen > MaxSharedKeyLength(pub) {
|
||||
return nil, ErrSharedKeyTooBig
|
||||
}
|
||||
|
||||
x, _ := pub.Curve.ScalarMult(pub.X, pub.Y, prv.D.Bytes())
|
||||
if x == nil {
|
||||
return nil, ErrSharedKeyIsPointAtInfinity
|
||||
}
|
||||
|
||||
sk = make([]byte, skLen+macLen)
|
||||
skBytes := x.Bytes()
|
||||
copy(sk[len(sk)-len(skBytes):], skBytes)
|
||||
return sk, nil
|
||||
}
|
||||
|
||||
var (
|
||||
ErrKeyDataTooLong = fmt.Errorf("ecies: can't supply requested key data")
|
||||
ErrSharedTooLong = fmt.Errorf("ecies: shared secret is too long")
|
||||
ErrInvalidMessage = fmt.Errorf("ecies: invalid message")
|
||||
)
|
||||
|
||||
var (
|
||||
big2To32 = new(big.Int).Exp(big.NewInt(2), big.NewInt(32), nil)
|
||||
big2To32M1 = new(big.Int).Sub(big2To32, big.NewInt(1))
|
||||
)
|
||||
|
||||
func incCounter(ctr []byte) {
|
||||
if ctr[3]++; ctr[3] != 0 {
|
||||
return
|
||||
}
|
||||
if ctr[2]++; ctr[2] != 0 {
|
||||
return
|
||||
}
|
||||
if ctr[1]++; ctr[1] != 0 {
|
||||
return
|
||||
}
|
||||
if ctr[0]++; ctr[0] != 0 {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// NIST SP 800-56 Concatenation Key Derivation Function (see section 5.8.1).
|
||||
func concatKDF(hash hash.Hash, z, s1 []byte, kdLen int) (k []byte, err error) {
|
||||
if s1 == nil {
|
||||
s1 = make([]byte, 0)
|
||||
}
|
||||
|
||||
reps := ((kdLen + 7) * 8) / (hash.BlockSize() * 8)
|
||||
if big.NewInt(int64(reps)).Cmp(big2To32M1) > 0 {
|
||||
fmt.Println(big2To32M1)
|
||||
return nil, ErrKeyDataTooLong
|
||||
}
|
||||
|
||||
counter := []byte{0, 0, 0, 1}
|
||||
k = make([]byte, 0)
|
||||
|
||||
for i := 0; i <= reps; i++ {
|
||||
hash.Write(counter)
|
||||
hash.Write(z)
|
||||
hash.Write(s1)
|
||||
k = append(k, hash.Sum(nil)...)
|
||||
hash.Reset()
|
||||
incCounter(counter)
|
||||
}
|
||||
|
||||
k = k[:kdLen]
|
||||
return
|
||||
}
|
||||
|
||||
// messageTag computes the MAC of a message (called the tag) as per
|
||||
// SEC 1, 3.5.
|
||||
func messageTag(hash func() hash.Hash, km, msg, shared []byte) []byte {
|
||||
mac := hmac.New(hash, km)
|
||||
mac.Write(msg)
|
||||
mac.Write(shared)
|
||||
tag := mac.Sum(nil)
|
||||
return tag
|
||||
}
|
||||
|
||||
// Generate an initialisation vector for CTR mode.
|
||||
func generateIV(params *ECIESParams, rand io.Reader) (iv []byte, err error) {
|
||||
iv = make([]byte, params.BlockSize)
|
||||
_, err = io.ReadFull(rand, iv)
|
||||
return
|
||||
}
|
||||
|
||||
// symEncrypt carries out CTR encryption using the block cipher specified in the
|
||||
// parameters.
|
||||
func symEncrypt(rand io.Reader, params *ECIESParams, key, m []byte) (ct []byte, err error) {
|
||||
c, err := params.Cipher(key)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
iv, err := generateIV(params, rand)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
ctr := cipher.NewCTR(c, iv)
|
||||
|
||||
ct = make([]byte, len(m)+params.BlockSize)
|
||||
copy(ct, iv)
|
||||
ctr.XORKeyStream(ct[params.BlockSize:], m)
|
||||
return
|
||||
}
|
||||
|
||||
// symDecrypt carries out CTR decryption using the block cipher specified in
|
||||
// the parameters
|
||||
func symDecrypt(params *ECIESParams, key, ct []byte) (m []byte, err error) {
|
||||
c, err := params.Cipher(key)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
ctr := cipher.NewCTR(c, ct[:params.BlockSize])
|
||||
|
||||
m = make([]byte, len(ct)-params.BlockSize)
|
||||
ctr.XORKeyStream(m, ct[params.BlockSize:])
|
||||
return
|
||||
}
|
||||
|
||||
// Encrypt encrypts a message using ECIES as specified in SEC 1, 5.1.
|
||||
//
|
||||
// s1 and s2 contain shared information that is not part of the resulting
|
||||
// ciphertext. s1 is fed into key derivation, s2 is fed into the MAC. If the
|
||||
// shared information parameters aren't being used, they should be nil.
|
||||
func Encrypt(rand io.Reader, pub *PublicKey, m, s1, s2 []byte) (ct []byte, err error) {
|
||||
params := pub.Params
|
||||
if params == nil {
|
||||
if params = ParamsFromCurve(pub.Curve); params == nil {
|
||||
err = ErrUnsupportedECIESParameters
|
||||
return
|
||||
}
|
||||
}
|
||||
R, err := GenerateKey(rand, pub.Curve, params)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
hash := params.Hash()
|
||||
z, err := R.GenerateShared(pub, params.KeyLen, params.KeyLen)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
K, err := concatKDF(hash, z, s1, params.KeyLen+params.KeyLen)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
Ke := K[:params.KeyLen]
|
||||
Km := K[params.KeyLen:]
|
||||
hash.Write(Km)
|
||||
Km = hash.Sum(nil)
|
||||
hash.Reset()
|
||||
|
||||
em, err := symEncrypt(rand, params, Ke, m)
|
||||
if err != nil || len(em) <= params.BlockSize {
|
||||
return
|
||||
}
|
||||
|
||||
d := messageTag(params.Hash, Km, em, s2)
|
||||
|
||||
Rb := elliptic.Marshal(pub.Curve, R.PublicKey.X, R.PublicKey.Y)
|
||||
ct = make([]byte, len(Rb)+len(em)+len(d))
|
||||
copy(ct, Rb)
|
||||
copy(ct[len(Rb):], em)
|
||||
copy(ct[len(Rb)+len(em):], d)
|
||||
return
|
||||
}
|
||||
|
||||
// Decrypt decrypts an ECIES ciphertext.
|
||||
func (prv *PrivateKey) Decrypt(c, s1, s2 []byte) (m []byte, err error) {
|
||||
if len(c) == 0 {
|
||||
return nil, ErrInvalidMessage
|
||||
}
|
||||
params := prv.PublicKey.Params
|
||||
if params == nil {
|
||||
if params = ParamsFromCurve(prv.PublicKey.Curve); params == nil {
|
||||
err = ErrUnsupportedECIESParameters
|
||||
return
|
||||
}
|
||||
}
|
||||
hash := params.Hash()
|
||||
|
||||
var (
|
||||
rLen int
|
||||
hLen int = hash.Size()
|
||||
mStart int
|
||||
mEnd int
|
||||
)
|
||||
|
||||
switch c[0] {
|
||||
case 2, 3, 4:
|
||||
rLen = (prv.PublicKey.Curve.Params().BitSize + 7) / 4
|
||||
if len(c) < (rLen + hLen + 1) {
|
||||
err = ErrInvalidMessage
|
||||
return
|
||||
}
|
||||
default:
|
||||
err = ErrInvalidPublicKey
|
||||
return
|
||||
}
|
||||
|
||||
mStart = rLen
|
||||
mEnd = len(c) - hLen
|
||||
|
||||
R := new(PublicKey)
|
||||
R.Curve = prv.PublicKey.Curve
|
||||
R.X, R.Y = elliptic.Unmarshal(R.Curve, c[:rLen])
|
||||
if R.X == nil {
|
||||
err = ErrInvalidPublicKey
|
||||
return
|
||||
}
|
||||
if !R.Curve.IsOnCurve(R.X, R.Y) {
|
||||
err = ErrInvalidCurve
|
||||
return
|
||||
}
|
||||
|
||||
z, err := prv.GenerateShared(R, params.KeyLen, params.KeyLen)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
K, err := concatKDF(hash, z, s1, params.KeyLen+params.KeyLen)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
Ke := K[:params.KeyLen]
|
||||
Km := K[params.KeyLen:]
|
||||
hash.Write(Km)
|
||||
Km = hash.Sum(nil)
|
||||
hash.Reset()
|
||||
|
||||
d := messageTag(params.Hash, Km, c[mStart:mEnd], s2)
|
||||
if subtle.ConstantTimeCompare(c[mEnd:], d) != 1 {
|
||||
err = ErrInvalidMessage
|
||||
return
|
||||
}
|
||||
|
||||
m, err = symDecrypt(params, Ke, c[mStart:mEnd])
|
||||
return
|
||||
}
|
||||
117
vendor/github.com/status-im/status-go/eth-node/crypto/ecies/params.go
generated
vendored
Normal file
117
vendor/github.com/status-im/status-go/eth-node/crypto/ecies/params.go
generated
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
// Copyright (c) 2013 Kyle Isom <kyle@tyrfingr.is>
|
||||
// Copyright (c) 2012 The Go Authors. All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package ecies
|
||||
|
||||
// This file contains parameters for ECIES encryption, specifying the
|
||||
// symmetric encryption and HMAC parameters.
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/elliptic"
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"fmt"
|
||||
"hash"
|
||||
|
||||
gethcrypto "github.com/ethereum/go-ethereum/crypto"
|
||||
)
|
||||
|
||||
var (
|
||||
DefaultCurve = gethcrypto.S256()
|
||||
ErrUnsupportedECDHAlgorithm = fmt.Errorf("ecies: unsupported ECDH algorithm")
|
||||
ErrUnsupportedECIESParameters = fmt.Errorf("ecies: unsupported ECIES parameters")
|
||||
)
|
||||
|
||||
type ECIESParams struct {
|
||||
Hash func() hash.Hash // hash function
|
||||
hashAlgo crypto.Hash
|
||||
Cipher func([]byte) (cipher.Block, error) // symmetric cipher
|
||||
BlockSize int // block size of symmetric cipher
|
||||
KeyLen int // length of symmetric key
|
||||
}
|
||||
|
||||
// Standard ECIES parameters:
|
||||
// * ECIES using AES128 and HMAC-SHA-256-16
|
||||
// * ECIES using AES256 and HMAC-SHA-256-32
|
||||
// * ECIES using AES256 and HMAC-SHA-384-48
|
||||
// * ECIES using AES256 and HMAC-SHA-512-64
|
||||
|
||||
var (
|
||||
ECIES_AES128_SHA256 = &ECIESParams{
|
||||
Hash: sha256.New,
|
||||
hashAlgo: crypto.SHA256,
|
||||
Cipher: aes.NewCipher,
|
||||
BlockSize: aes.BlockSize,
|
||||
KeyLen: 16,
|
||||
}
|
||||
|
||||
ECIES_AES256_SHA256 = &ECIESParams{
|
||||
Hash: sha256.New,
|
||||
hashAlgo: crypto.SHA256,
|
||||
Cipher: aes.NewCipher,
|
||||
BlockSize: aes.BlockSize,
|
||||
KeyLen: 32,
|
||||
}
|
||||
|
||||
ECIES_AES256_SHA384 = &ECIESParams{
|
||||
Hash: sha512.New384,
|
||||
hashAlgo: crypto.SHA384,
|
||||
Cipher: aes.NewCipher,
|
||||
BlockSize: aes.BlockSize,
|
||||
KeyLen: 32,
|
||||
}
|
||||
|
||||
ECIES_AES256_SHA512 = &ECIESParams{
|
||||
Hash: sha512.New,
|
||||
hashAlgo: crypto.SHA512,
|
||||
Cipher: aes.NewCipher,
|
||||
BlockSize: aes.BlockSize,
|
||||
KeyLen: 32,
|
||||
}
|
||||
)
|
||||
|
||||
var paramsFromCurve = map[elliptic.Curve]*ECIESParams{
|
||||
gethcrypto.S256(): ECIES_AES128_SHA256,
|
||||
elliptic.P256(): ECIES_AES128_SHA256,
|
||||
elliptic.P384(): ECIES_AES256_SHA384,
|
||||
elliptic.P521(): ECIES_AES256_SHA512,
|
||||
}
|
||||
|
||||
func AddParamsForCurve(curve elliptic.Curve, params *ECIESParams) {
|
||||
paramsFromCurve[curve] = params
|
||||
}
|
||||
|
||||
// ParamsFromCurve selects parameters optimal for the selected elliptic curve.
|
||||
// Only the curves P256, P384, and P512 are supported.
|
||||
func ParamsFromCurve(curve elliptic.Curve) (params *ECIESParams) {
|
||||
return paramsFromCurve[curve]
|
||||
}
|
||||
197
vendor/github.com/status-im/status-go/eth-node/crypto/ethereum_crypto.go
generated
vendored
Normal file
197
vendor/github.com/status-im/status-go/eth-node/crypto/ethereum_crypto.go
generated
vendored
Normal file
@@ -0,0 +1,197 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
dr "github.com/status-im/doubleratchet"
|
||||
"golang.org/x/crypto/hkdf"
|
||||
|
||||
"github.com/status-im/status-go/eth-node/crypto/ecies"
|
||||
)
|
||||
|
||||
// EthereumCrypto is an implementation of Crypto with cryptographic primitives recommended
|
||||
// by the Double Ratchet Algorithm specification. However, some details are different,
|
||||
// see function comments for details.
|
||||
type EthereumCrypto struct{}
|
||||
|
||||
// See the Crypto interface.
|
||||
func (c EthereumCrypto) GenerateDH() (dr.DHPair, error) {
|
||||
keys, err := GenerateKey()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return DHPair{
|
||||
PubKey: CompressPubkey(&keys.PublicKey),
|
||||
PrvKey: FromECDSA(keys),
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
||||
// See the Crypto interface.
|
||||
func (c EthereumCrypto) DH(dhPair dr.DHPair, dhPub dr.Key) (dr.Key, error) {
|
||||
tmpKey := dhPair.PrivateKey()
|
||||
privateKey, err := ToECDSA(tmpKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
eciesPrivate := ecies.ImportECDSA(privateKey)
|
||||
|
||||
publicKey, err := DecompressPubkey(dhPub)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
eciesPublic := ecies.ImportECDSAPublic(publicKey)
|
||||
|
||||
key, err := eciesPrivate.GenerateShared(
|
||||
eciesPublic,
|
||||
16,
|
||||
16,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return key, nil
|
||||
}
|
||||
|
||||
// See the Crypto interface.
|
||||
func (c EthereumCrypto) KdfRK(rk, dhOut dr.Key) (dr.Key, dr.Key, dr.Key) {
|
||||
var (
|
||||
// We can use a non-secret constant as the last argument
|
||||
r = hkdf.New(sha256.New, dhOut, rk, []byte("rsZUpEuXUqqwXBvSy3EcievAh4cMj6QL"))
|
||||
buf = make([]byte, 96)
|
||||
)
|
||||
|
||||
rootKey := make(dr.Key, 32)
|
||||
chainKey := make(dr.Key, 32)
|
||||
headerKey := make(dr.Key, 32)
|
||||
|
||||
// The only error here is an entropy limit which won't be reached for such a short buffer.
|
||||
_, _ = io.ReadFull(r, buf)
|
||||
|
||||
copy(rootKey, buf[:32])
|
||||
copy(chainKey, buf[32:64])
|
||||
copy(headerKey, buf[64:96])
|
||||
return rootKey, chainKey, headerKey
|
||||
}
|
||||
|
||||
// See the Crypto interface.
|
||||
func (c EthereumCrypto) KdfCK(ck dr.Key) (dr.Key, dr.Key) {
|
||||
const (
|
||||
ckInput = 15
|
||||
mkInput = 16
|
||||
)
|
||||
|
||||
chainKey := make(dr.Key, 32)
|
||||
msgKey := make(dr.Key, 32)
|
||||
|
||||
h := hmac.New(sha256.New, ck)
|
||||
|
||||
_, _ = h.Write([]byte{ckInput})
|
||||
copy(chainKey, h.Sum(nil))
|
||||
h.Reset()
|
||||
|
||||
_, _ = h.Write([]byte{mkInput})
|
||||
copy(msgKey, h.Sum(nil))
|
||||
|
||||
return chainKey, msgKey
|
||||
}
|
||||
|
||||
// Encrypt uses a slightly different approach than in the algorithm specification:
|
||||
// it uses AES-256-CTR instead of AES-256-CBC for security, ciphertext length and implementation
|
||||
// complexity considerations.
|
||||
func (c EthereumCrypto) Encrypt(mk dr.Key, plaintext, ad []byte) ([]byte, error) {
|
||||
encKey, authKey, iv := c.deriveEncKeys(mk)
|
||||
|
||||
ciphertext := make([]byte, aes.BlockSize+len(plaintext))
|
||||
copy(ciphertext, iv[:])
|
||||
|
||||
block, err := aes.NewCipher(encKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
stream := cipher.NewCTR(block, iv[:])
|
||||
stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext)
|
||||
|
||||
return append(ciphertext, c.computeSignature(authKey, ciphertext, ad)...), nil
|
||||
}
|
||||
|
||||
// See the Crypto interface.
|
||||
func (c EthereumCrypto) Decrypt(mk dr.Key, authCiphertext, ad []byte) ([]byte, error) {
|
||||
var (
|
||||
l = len(authCiphertext)
|
||||
ciphertext = authCiphertext[:l-sha256.Size]
|
||||
signature = authCiphertext[l-sha256.Size:]
|
||||
)
|
||||
|
||||
// Check the signature.
|
||||
encKey, authKey, _ := c.deriveEncKeys(mk)
|
||||
|
||||
if s := c.computeSignature(authKey, ciphertext, ad); !bytes.Equal(s, signature) {
|
||||
return nil, fmt.Errorf("invalid signature")
|
||||
}
|
||||
|
||||
// Decrypt.
|
||||
block, err := aes.NewCipher(encKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
stream := cipher.NewCTR(block, ciphertext[:aes.BlockSize])
|
||||
plaintext := make([]byte, len(ciphertext[aes.BlockSize:]))
|
||||
|
||||
stream.XORKeyStream(plaintext, ciphertext[aes.BlockSize:])
|
||||
|
||||
return plaintext, nil
|
||||
}
|
||||
|
||||
// deriveEncKeys derive keys for message encryption and decryption. Returns (encKey, authKey, iv, err).
|
||||
func (c EthereumCrypto) deriveEncKeys(mk dr.Key) (dr.Key, dr.Key, [16]byte) {
|
||||
// First, derive encryption and authentication key out of mk.
|
||||
salt := make([]byte, 32)
|
||||
var (
|
||||
r = hkdf.New(sha256.New, mk, salt, []byte("pcwSByyx2CRdryCffXJwy7xgVZWtW5Sh"))
|
||||
buf = make([]byte, 80)
|
||||
)
|
||||
|
||||
encKey := make(dr.Key, 32)
|
||||
authKey := make(dr.Key, 32)
|
||||
var iv [16]byte
|
||||
|
||||
// The only error here is an entropy limit which won't be reached for such a short buffer.
|
||||
_, _ = io.ReadFull(r, buf)
|
||||
|
||||
copy(encKey, buf[0:32])
|
||||
copy(authKey, buf[32:64])
|
||||
copy(iv[:], buf[64:80])
|
||||
return encKey, authKey, iv
|
||||
}
|
||||
|
||||
func (c EthereumCrypto) computeSignature(authKey, ciphertext, associatedData []byte) []byte {
|
||||
h := hmac.New(sha256.New, authKey)
|
||||
_, _ = h.Write(associatedData)
|
||||
_, _ = h.Write(ciphertext)
|
||||
return h.Sum(nil)
|
||||
}
|
||||
|
||||
type DHPair struct {
|
||||
PrvKey dr.Key
|
||||
PubKey dr.Key
|
||||
}
|
||||
|
||||
func (p DHPair) PrivateKey() dr.Key {
|
||||
return p.PrvKey
|
||||
}
|
||||
|
||||
func (p DHPair) PublicKey() dr.Key {
|
||||
return p.PubKey
|
||||
}
|
||||
237
vendor/github.com/status-im/status-go/eth-node/crypto/gethcrypto.go
generated
vendored
Normal file
237
vendor/github.com/status-im/status-go/eth-node/crypto/gethcrypto.go
generated
vendored
Normal file
@@ -0,0 +1,237 @@
|
||||
// Copyright 2014 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
"os"
|
||||
|
||||
"golang.org/x/crypto/sha3"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/math"
|
||||
"github.com/ethereum/go-ethereum/crypto/secp256k1"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
)
|
||||
|
||||
// SignatureLength indicates the byte length required to carry a signature with recovery id.
|
||||
const SignatureLength = 64 + 1 // 64 bytes ECDSA signature + 1 byte recovery id
|
||||
|
||||
// RecoveryIDOffset points to the byte offset within the signature that contains the recovery id.
|
||||
const RecoveryIDOffset = 64
|
||||
|
||||
// DigestLength sets the signature digest exact length
|
||||
const DigestLength = 32
|
||||
|
||||
var (
|
||||
secp256k1N, _ = new(big.Int).SetString("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", 16)
|
||||
)
|
||||
|
||||
var errInvalidPubkey = errors.New("invalid secp256k1 public key")
|
||||
|
||||
// Keccak256 calculates and returns the Keccak256 hash of the input data.
|
||||
func Keccak256(data ...[]byte) []byte {
|
||||
d := sha3.NewLegacyKeccak256()
|
||||
for _, b := range data {
|
||||
_, _ = d.Write(b)
|
||||
}
|
||||
return d.Sum(nil)
|
||||
}
|
||||
|
||||
// Keccak256Hash calculates and returns the Keccak256 hash of the input data,
|
||||
// converting it to an internal Hash data structure.
|
||||
func Keccak256Hash(data ...[]byte) (h types.Hash) {
|
||||
d := sha3.NewLegacyKeccak256()
|
||||
for _, b := range data {
|
||||
_, _ = d.Write(b)
|
||||
}
|
||||
d.Sum(h[:0])
|
||||
return h
|
||||
}
|
||||
|
||||
// Keccak512 calculates and returns the Keccak512 hash of the input data.
|
||||
func Keccak512(data ...[]byte) []byte {
|
||||
d := sha3.NewLegacyKeccak512()
|
||||
for _, b := range data {
|
||||
_, _ = d.Write(b)
|
||||
}
|
||||
return d.Sum(nil)
|
||||
}
|
||||
|
||||
// CreateAddress creates an ethereum address given the bytes and the nonce
|
||||
func CreateAddress(b types.Address, nonce uint64) types.Address {
|
||||
data, _ := rlp.EncodeToBytes([]interface{}{b, nonce})
|
||||
return types.BytesToAddress(Keccak256(data)[12:])
|
||||
}
|
||||
|
||||
// CreateAddress2 creates an ethereum address given the address bytes, initial
|
||||
// contract code hash and a salt.
|
||||
func CreateAddress2(b types.Address, salt [32]byte, inithash []byte) types.Address {
|
||||
return types.BytesToAddress(Keccak256([]byte{0xff}, b.Bytes(), salt[:], inithash)[12:])
|
||||
}
|
||||
|
||||
// ToECDSA creates a private key with the given D value.
|
||||
func ToECDSA(d []byte) (*ecdsa.PrivateKey, error) {
|
||||
return toECDSA(d, true)
|
||||
}
|
||||
|
||||
// ToECDSAUnsafe blindly converts a binary blob to a private key. It should almost
|
||||
// never be used unless you are sure the input is valid and want to avoid hitting
|
||||
// errors due to bad origin encoding (0 prefixes cut off).
|
||||
func ToECDSAUnsafe(d []byte) *ecdsa.PrivateKey {
|
||||
priv, _ := toECDSA(d, false)
|
||||
return priv
|
||||
}
|
||||
|
||||
// toECDSA creates a private key with the given D value. The strict parameter
|
||||
// controls whether the key's length should be enforced at the curve size or
|
||||
// it can also accept legacy encodings (0 prefixes).
|
||||
func toECDSA(d []byte, strict bool) (*ecdsa.PrivateKey, error) {
|
||||
priv := new(ecdsa.PrivateKey)
|
||||
priv.PublicKey.Curve = S256()
|
||||
if strict && 8*len(d) != priv.Params().BitSize {
|
||||
return nil, fmt.Errorf("invalid length, need %d bits", priv.Params().BitSize)
|
||||
}
|
||||
priv.D = new(big.Int).SetBytes(d)
|
||||
|
||||
// The priv.D must < N
|
||||
if priv.D.Cmp(secp256k1N) >= 0 {
|
||||
return nil, fmt.Errorf("invalid private key, >=N")
|
||||
}
|
||||
// The priv.D must not be zero or negative.
|
||||
if priv.D.Sign() <= 0 {
|
||||
return nil, fmt.Errorf("invalid private key, zero or negative")
|
||||
}
|
||||
|
||||
priv.PublicKey.X, priv.PublicKey.Y = priv.PublicKey.Curve.ScalarBaseMult(d)
|
||||
if priv.PublicKey.X == nil {
|
||||
return nil, errors.New("invalid private key")
|
||||
}
|
||||
return priv, nil
|
||||
}
|
||||
|
||||
// FromECDSA exports a private key into a binary dump.
|
||||
func FromECDSA(priv *ecdsa.PrivateKey) []byte {
|
||||
if priv == nil {
|
||||
return nil
|
||||
}
|
||||
return math.PaddedBigBytes(priv.D, priv.Params().BitSize/8)
|
||||
}
|
||||
|
||||
// UnmarshalPubkey converts bytes to a secp256k1 public key.
|
||||
func UnmarshalPubkey(pub []byte) (*ecdsa.PublicKey, error) {
|
||||
x, y := elliptic.Unmarshal(S256(), pub)
|
||||
if x == nil {
|
||||
return nil, errInvalidPubkey
|
||||
}
|
||||
return &ecdsa.PublicKey{Curve: S256(), X: x, Y: y}, nil
|
||||
}
|
||||
|
||||
func FromECDSAPub(pub *ecdsa.PublicKey) []byte {
|
||||
if pub == nil || pub.X == nil || pub.Y == nil {
|
||||
return nil
|
||||
}
|
||||
return elliptic.Marshal(S256(), pub.X, pub.Y)
|
||||
}
|
||||
|
||||
// HexToECDSA parses a secp256k1 private key.
|
||||
func HexToECDSA(hexkey string) (*ecdsa.PrivateKey, error) {
|
||||
b, err := hex.DecodeString(hexkey)
|
||||
if err != nil {
|
||||
return nil, errors.New("invalid hex string")
|
||||
}
|
||||
return ToECDSA(b)
|
||||
}
|
||||
|
||||
// LoadECDSA loads a secp256k1 private key from the given file.
|
||||
func LoadECDSA(file string) (*ecdsa.PrivateKey, error) {
|
||||
buf := make([]byte, 64)
|
||||
fd, err := os.Open(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer fd.Close()
|
||||
if _, err := io.ReadFull(fd, buf); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
key, err := hex.DecodeString(string(buf))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ToECDSA(key)
|
||||
}
|
||||
|
||||
// SaveECDSA saves a secp256k1 private key to the given file with
|
||||
// restrictive permissions. The key data is saved hex-encoded.
|
||||
func SaveECDSA(file string, key *ecdsa.PrivateKey) error {
|
||||
k := hex.EncodeToString(FromECDSA(key))
|
||||
return ioutil.WriteFile(file, []byte(k), 0600)
|
||||
}
|
||||
|
||||
func GenerateKey() (*ecdsa.PrivateKey, error) {
|
||||
return ecdsa.GenerateKey(S256(), rand.Reader)
|
||||
}
|
||||
|
||||
func PubkeyToAddress(p ecdsa.PublicKey) types.Address {
|
||||
pubBytes := FromECDSAPub(&p)
|
||||
return types.BytesToAddress(Keccak256(pubBytes[1:])[12:])
|
||||
}
|
||||
|
||||
// Ecrecover returns the uncompressed public key that created the given signature.
|
||||
func Ecrecover(hash, sig []byte) ([]byte, error) {
|
||||
return secp256k1.RecoverPubkey(hash, sig)
|
||||
}
|
||||
|
||||
// SigToPub returns the public key that created the given signature.
|
||||
func SigToPub(hash, sig []byte) (*ecdsa.PublicKey, error) {
|
||||
s, err := Ecrecover(hash, sig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
x, y := elliptic.Unmarshal(S256(), s)
|
||||
return &ecdsa.PublicKey{Curve: S256(), X: x, Y: y}, nil
|
||||
}
|
||||
|
||||
// DecompressPubkey parses a public key in the 33-byte compressed format.
|
||||
func DecompressPubkey(pubkey []byte) (*ecdsa.PublicKey, error) {
|
||||
x, y := secp256k1.DecompressPubkey(pubkey)
|
||||
if x == nil {
|
||||
return nil, fmt.Errorf("invalid public key")
|
||||
}
|
||||
return &ecdsa.PublicKey{X: x, Y: y, Curve: S256()}, nil
|
||||
}
|
||||
|
||||
// CompressPubkey encodes a public key to the 33-byte compressed format.
|
||||
func CompressPubkey(pubkey *ecdsa.PublicKey) []byte {
|
||||
return secp256k1.CompressPubkey(pubkey.X, pubkey.Y)
|
||||
}
|
||||
|
||||
// S256 returns an instance of the secp256k1 curve.
|
||||
func S256() elliptic.Curve {
|
||||
return secp256k1.S256()
|
||||
}
|
||||
15
vendor/github.com/status-im/status-go/eth-node/keystore/keystore.go
generated
vendored
Normal file
15
vendor/github.com/status-im/status-go/eth-node/keystore/keystore.go
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
// Imported from github.com/ethereum/go-ethereum/accounts/keystore/keystore.go
|
||||
|
||||
package keystore
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
const (
|
||||
version = 3
|
||||
)
|
||||
|
||||
var (
|
||||
ErrDecrypt = errors.New("could not decrypt key with given password")
|
||||
)
|
||||
353
vendor/github.com/status-im/status-go/eth-node/keystore/passphrase.go
generated
vendored
Normal file
353
vendor/github.com/status-im/status-go/eth-node/keystore/passphrase.go
generated
vendored
Normal file
@@ -0,0 +1,353 @@
|
||||
// Imported from github.com/ethereum/go-ethereum/accounts/keystore/passphrase.go
|
||||
// and github.com/ethereum/go-ethereum/accounts/keystore/presale.go
|
||||
|
||||
package keystore
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"golang.org/x/crypto/pbkdf2"
|
||||
"golang.org/x/crypto/scrypt"
|
||||
|
||||
"github.com/status-im/status-go/eth-node/crypto"
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
"github.com/status-im/status-go/extkeys"
|
||||
)
|
||||
|
||||
const (
|
||||
keyHeaderKDF = "scrypt"
|
||||
)
|
||||
|
||||
type EncryptedKeyJSONV3 struct {
|
||||
Address string `json:"address"`
|
||||
Crypto CryptoJSON `json:"crypto"`
|
||||
Id string `json:"id"`
|
||||
Version int `json:"version"`
|
||||
ExtendedKey CryptoJSON `json:"extendedkey"`
|
||||
SubAccountIndex uint32 `json:"subaccountindex"`
|
||||
}
|
||||
|
||||
type encryptedKeyJSONV1 struct {
|
||||
Address string `json:"address"`
|
||||
Crypto CryptoJSON `json:"crypto"`
|
||||
Id string `json:"id"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
type CryptoJSON struct {
|
||||
Cipher string `json:"cipher"`
|
||||
CipherText string `json:"ciphertext"`
|
||||
CipherParams cipherparamsJSON `json:"cipherparams"`
|
||||
KDF string `json:"kdf"`
|
||||
KDFParams map[string]interface{} `json:"kdfparams"`
|
||||
MAC string `json:"mac"`
|
||||
}
|
||||
|
||||
type cipherparamsJSON struct {
|
||||
IV string `json:"iv"`
|
||||
}
|
||||
|
||||
// DecryptKey decrypts a key from a json blob, returning the private key itself.
|
||||
func DecryptKey(keyjson []byte, auth string) (*types.Key, error) {
|
||||
// Parse the json into a simple map to fetch the key version
|
||||
m := make(map[string]interface{})
|
||||
if err := json.Unmarshal(keyjson, &m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Depending on the version try to parse one way or another
|
||||
var (
|
||||
keyBytes, keyId []byte
|
||||
err error
|
||||
extKeyBytes []byte
|
||||
extKey *extkeys.ExtendedKey
|
||||
)
|
||||
|
||||
subAccountIndex, ok := m["subaccountindex"].(float64)
|
||||
if !ok {
|
||||
subAccountIndex = 0
|
||||
}
|
||||
|
||||
if version, ok := m["version"].(string); ok && version == "1" {
|
||||
k := new(encryptedKeyJSONV1)
|
||||
if err := json.Unmarshal(keyjson, k); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
keyBytes, keyId, err = decryptKeyV1(k, auth)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
extKey, err = extkeys.NewKeyFromString(extkeys.EmptyExtendedKeyString)
|
||||
} else {
|
||||
k := new(EncryptedKeyJSONV3)
|
||||
if err := json.Unmarshal(keyjson, k); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
keyBytes, keyId, err = decryptKeyV3(k, auth)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
extKeyBytes, err = decryptExtendedKey(k, auth)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
extKey, err = extkeys.NewKeyFromString(string(extKeyBytes))
|
||||
}
|
||||
// Handle any decryption errors and return the key
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
key := crypto.ToECDSAUnsafe(keyBytes)
|
||||
|
||||
id, err := uuid.FromBytes(keyId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &types.Key{
|
||||
ID: id,
|
||||
Address: crypto.PubkeyToAddress(key.PublicKey),
|
||||
PrivateKey: key,
|
||||
ExtendedKey: extKey,
|
||||
SubAccountIndex: uint32(subAccountIndex),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func DecryptDataV3(cryptoJson CryptoJSON, auth string) ([]byte, error) {
|
||||
if cryptoJson.Cipher != "aes-128-ctr" {
|
||||
return nil, fmt.Errorf("Cipher not supported: %v", cryptoJson.Cipher)
|
||||
}
|
||||
mac, err := hex.DecodeString(cryptoJson.MAC)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
iv, err := hex.DecodeString(cryptoJson.CipherParams.IV)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cipherText, err := hex.DecodeString(cryptoJson.CipherText)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
derivedKey, err := getKDFKey(cryptoJson, auth)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
calculatedMAC := crypto.Keccak256(derivedKey[16:32], cipherText)
|
||||
if !bytes.Equal(calculatedMAC, mac) {
|
||||
return nil, ErrDecrypt
|
||||
}
|
||||
|
||||
plainText, err := aesCTRXOR(derivedKey[:16], cipherText, iv)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return plainText, err
|
||||
}
|
||||
|
||||
func decryptKeyV3(keyProtected *EncryptedKeyJSONV3, auth string) (keyBytes []byte, keyId []byte, err error) {
|
||||
if keyProtected.Version != version {
|
||||
return nil, nil, fmt.Errorf("Version not supported: %v", keyProtected.Version)
|
||||
}
|
||||
id, err := uuid.Parse(keyProtected.Id)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
keyId = id[:]
|
||||
plainText, err := DecryptDataV3(keyProtected.Crypto, auth)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return plainText, keyId, err
|
||||
}
|
||||
|
||||
func decryptKeyV1(keyProtected *encryptedKeyJSONV1, auth string) (keyBytes []byte, keyId []byte, err error) {
|
||||
id, err := uuid.Parse(keyProtected.Id)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
keyId = id[:]
|
||||
|
||||
mac, err := hex.DecodeString(keyProtected.Crypto.MAC)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
iv, err := hex.DecodeString(keyProtected.Crypto.CipherParams.IV)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
cipherText, err := hex.DecodeString(keyProtected.Crypto.CipherText)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
derivedKey, err := getKDFKey(keyProtected.Crypto, auth)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
calculatedMAC := crypto.Keccak256(derivedKey[16:32], cipherText)
|
||||
if !bytes.Equal(calculatedMAC, mac) {
|
||||
return nil, nil, ErrDecrypt
|
||||
}
|
||||
|
||||
plainText, err := aesCBCDecrypt(crypto.Keccak256(derivedKey[:16])[:16], cipherText, iv)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return plainText, keyId, err
|
||||
}
|
||||
|
||||
func decryptExtendedKey(keyProtected *EncryptedKeyJSONV3, auth string) (plainText []byte, err error) {
|
||||
if len(keyProtected.ExtendedKey.CipherText) == 0 {
|
||||
return []byte(extkeys.EmptyExtendedKeyString), nil
|
||||
}
|
||||
|
||||
if keyProtected.Version != version {
|
||||
return nil, fmt.Errorf("Version not supported: %v", keyProtected.Version)
|
||||
}
|
||||
|
||||
if keyProtected.ExtendedKey.Cipher != "aes-128-ctr" {
|
||||
return nil, fmt.Errorf("Cipher not supported: %v", keyProtected.ExtendedKey.Cipher)
|
||||
}
|
||||
|
||||
mac, err := hex.DecodeString(keyProtected.ExtendedKey.MAC)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
iv, err := hex.DecodeString(keyProtected.ExtendedKey.CipherParams.IV)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cipherText, err := hex.DecodeString(keyProtected.ExtendedKey.CipherText)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
derivedKey, err := getKDFKey(keyProtected.ExtendedKey, auth)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
calculatedMAC := crypto.Keccak256(derivedKey[16:32], cipherText)
|
||||
if !bytes.Equal(calculatedMAC, mac) {
|
||||
return nil, ErrDecrypt
|
||||
}
|
||||
|
||||
plainText, err = aesCTRXOR(derivedKey[:16], cipherText, iv)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return plainText, err
|
||||
}
|
||||
|
||||
func getKDFKey(cryptoJSON CryptoJSON, auth string) ([]byte, error) {
|
||||
authArray := []byte(auth)
|
||||
salt, err := hex.DecodeString(cryptoJSON.KDFParams["salt"].(string))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dkLen := ensureInt(cryptoJSON.KDFParams["dklen"])
|
||||
|
||||
if cryptoJSON.KDF == keyHeaderKDF {
|
||||
n := ensureInt(cryptoJSON.KDFParams["n"])
|
||||
r := ensureInt(cryptoJSON.KDFParams["r"])
|
||||
p := ensureInt(cryptoJSON.KDFParams["p"])
|
||||
return scrypt.Key(authArray, salt, n, r, p, dkLen)
|
||||
|
||||
} else if cryptoJSON.KDF == "pbkdf2" {
|
||||
c := ensureInt(cryptoJSON.KDFParams["c"])
|
||||
prf := cryptoJSON.KDFParams["prf"].(string)
|
||||
if prf != "hmac-sha256" {
|
||||
return nil, fmt.Errorf("Unsupported PBKDF2 PRF: %s", prf)
|
||||
}
|
||||
key := pbkdf2.Key(authArray, salt, c, dkLen, sha256.New)
|
||||
return key, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("Unsupported KDF: %s", cryptoJSON.KDF)
|
||||
}
|
||||
|
||||
// TODO: can we do without this when unmarshalling dynamic JSON?
|
||||
// why do integers in KDF params end up as float64 and not int after
|
||||
// unmarshal?
|
||||
func ensureInt(x interface{}) int {
|
||||
res, ok := x.(int)
|
||||
if !ok {
|
||||
res = int(x.(float64))
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func aesCTRXOR(key, inText, iv []byte) ([]byte, error) {
|
||||
// AES-128 is selected due to size of encryptKey.
|
||||
aesBlock, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
stream := cipher.NewCTR(aesBlock, iv)
|
||||
outText := make([]byte, len(inText))
|
||||
stream.XORKeyStream(outText, inText)
|
||||
return outText, err
|
||||
}
|
||||
|
||||
func aesCBCDecrypt(key, cipherText, iv []byte) ([]byte, error) {
|
||||
aesBlock, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
decrypter := cipher.NewCBCDecrypter(aesBlock, iv)
|
||||
paddedPlaintext := make([]byte, len(cipherText))
|
||||
decrypter.CryptBlocks(paddedPlaintext, cipherText)
|
||||
plaintext := pkcs7Unpad(paddedPlaintext)
|
||||
if plaintext == nil {
|
||||
return nil, ErrDecrypt
|
||||
}
|
||||
return plaintext, err
|
||||
}
|
||||
|
||||
// From https://leanpub.com/gocrypto/read#leanpub-auto-block-cipher-modes
|
||||
func pkcs7Unpad(in []byte) []byte {
|
||||
if len(in) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
padding := in[len(in)-1]
|
||||
if int(padding) > len(in) || padding > aes.BlockSize {
|
||||
return nil
|
||||
} else if padding == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := len(in) - 1; i > len(in)-int(padding)-1; i-- {
|
||||
if in[i] != padding {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return in[:len(in)-int(padding)]
|
||||
}
|
||||
|
||||
func RawKeyToCryptoJSON(rawKeyFile []byte) (cj CryptoJSON, e error) {
|
||||
var keyJSON EncryptedKeyJSONV3
|
||||
if e := json.Unmarshal(rawKeyFile, &keyJSON); e != nil {
|
||||
return cj, fmt.Errorf("failed to read key file: %s", e)
|
||||
}
|
||||
|
||||
return keyJSON.Crypto, e
|
||||
}
|
||||
8
vendor/github.com/status-im/status-go/eth-node/types/account.go
generated
vendored
Normal file
8
vendor/github.com/status-im/status-go/eth-node/types/account.go
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
package types
|
||||
|
||||
// Account represents an Ethereum account located at a specific location defined
|
||||
// by the optional URL field.
|
||||
type Account struct {
|
||||
Address Address `json:"address"` // Ethereum account address derived from the key
|
||||
URL string `json:"url"` // Optional resource locator within a backend
|
||||
}
|
||||
219
vendor/github.com/status-im/status-go/eth-node/types/address.go
generated
vendored
Normal file
219
vendor/github.com/status-im/status-go/eth-node/types/address.go
generated
vendored
Normal file
@@ -0,0 +1,219 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/crypto/sha3"
|
||||
)
|
||||
|
||||
/////////// Address
|
||||
|
||||
// AddressLength is the expected length of the address
|
||||
const AddressLength = 20
|
||||
|
||||
var (
|
||||
addressT = reflect.TypeOf(Address{})
|
||||
)
|
||||
|
||||
// Address represents the 20 byte address of an Ethereum account.
|
||||
type Address [AddressLength]byte
|
||||
|
||||
// BytesToAddress returns Address with value b.
|
||||
// If b is larger than len(h), b will be cropped from the left.
|
||||
func BytesToAddress(b []byte) Address {
|
||||
var a Address
|
||||
a.SetBytes(b)
|
||||
return a
|
||||
}
|
||||
|
||||
// BigToAddress returns Address with byte values of b.
|
||||
// If b is larger than len(h), b will be cropped from the left.
|
||||
func BigToAddress(b *big.Int) Address { return BytesToAddress(b.Bytes()) }
|
||||
|
||||
// HexToAddress returns Address with byte values of s.
|
||||
// If s is larger than len(h), s will be cropped from the left.
|
||||
func HexToAddress(s string) Address { return BytesToAddress(FromHex(s)) }
|
||||
|
||||
// IsHexAddress verifies whether a string can represent a valid hex-encoded
|
||||
// Ethereum address or not.
|
||||
func IsHexAddress(s string) bool {
|
||||
if has0xPrefix(s) {
|
||||
s = s[2:]
|
||||
}
|
||||
return len(s) == 2*AddressLength && isHex(s)
|
||||
}
|
||||
|
||||
// Bytes gets the string representation of the underlying address.
|
||||
func (a Address) Bytes() []byte { return a[:] }
|
||||
|
||||
// Hash converts an address to a hash by left-padding it with zeros.
|
||||
func (a Address) Hash() Hash { return BytesToHash(a[:]) }
|
||||
|
||||
// Hex returns an EIP55-compliant hex string representation of the address.
|
||||
func (a Address) Hex() string {
|
||||
unchecksummed := hex.EncodeToString(a[:])
|
||||
sha := sha3.NewLegacyKeccak256()
|
||||
_, _ = sha.Write([]byte(unchecksummed))
|
||||
hash := sha.Sum(nil)
|
||||
|
||||
result := []byte(unchecksummed)
|
||||
for i := 0; i < len(result); i++ {
|
||||
hashByte := hash[i/2]
|
||||
if i%2 == 0 {
|
||||
hashByte = hashByte >> 4
|
||||
} else {
|
||||
hashByte &= 0xf
|
||||
}
|
||||
if result[i] > '9' && hashByte > 7 {
|
||||
result[i] -= 32
|
||||
}
|
||||
}
|
||||
return "0x" + string(result)
|
||||
}
|
||||
|
||||
// String implements fmt.Stringer.
|
||||
func (a Address) String() string {
|
||||
return a.Hex()
|
||||
}
|
||||
|
||||
// Format implements fmt.Formatter, forcing the byte slice to be formatted as is,
|
||||
// without going through the stringer interface used for logging.
|
||||
func (a Address) Format(s fmt.State, c rune) {
|
||||
fmt.Fprintf(s, "%"+string(c), a[:])
|
||||
}
|
||||
|
||||
// SetBytes sets the address to the value of b.
|
||||
// If b is larger than len(a) it will panic.
|
||||
func (a *Address) SetBytes(b []byte) {
|
||||
if len(b) > len(a) {
|
||||
b = b[len(b)-AddressLength:]
|
||||
}
|
||||
copy(a[AddressLength-len(b):], b)
|
||||
}
|
||||
|
||||
// MarshalText returns the hex representation of a.
|
||||
func (a Address) MarshalText() ([]byte, error) {
|
||||
return HexBytes(a[:]).MarshalText()
|
||||
}
|
||||
|
||||
// UnmarshalText parses a hash in hex syntax.
|
||||
func (a *Address) UnmarshalText(input []byte) error {
|
||||
return UnmarshalFixedText("Address", input, a[:])
|
||||
}
|
||||
|
||||
// UnmarshalJSON parses a hash in hex syntax.
|
||||
func (a *Address) UnmarshalJSON(input []byte) error {
|
||||
return UnmarshalFixedJSON(addressT, input, a[:])
|
||||
}
|
||||
|
||||
// Scan implements Scanner for database/sql.
|
||||
func (a *Address) Scan(src interface{}) error {
|
||||
srcB, ok := src.([]byte)
|
||||
if !ok {
|
||||
return fmt.Errorf("can't scan %T into Address", src)
|
||||
}
|
||||
if len(srcB) != AddressLength {
|
||||
return fmt.Errorf("can't scan []byte of len %d into Address, want %d", len(srcB), AddressLength)
|
||||
}
|
||||
copy(a[:], srcB)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Value implements valuer for database/sql.
|
||||
func (a Address) Value() (driver.Value, error) {
|
||||
return a[:], nil
|
||||
}
|
||||
|
||||
// ImplementsGraphQLType returns true if Hash implements the specified GraphQL type.
|
||||
func (a Address) ImplementsGraphQLType(name string) bool { return name == "Address" }
|
||||
|
||||
// UnmarshalGraphQL unmarshals the provided GraphQL query data.
|
||||
func (a *Address) UnmarshalGraphQL(input interface{}) error {
|
||||
var err error
|
||||
switch input := input.(type) {
|
||||
case string:
|
||||
err = a.UnmarshalText([]byte(input))
|
||||
default:
|
||||
err = fmt.Errorf("Unexpected type for Address: %v", input)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// UnprefixedAddress allows marshaling an Address without 0x prefix.
|
||||
type UnprefixedAddress Address
|
||||
|
||||
// UnmarshalText decodes the address from hex. The 0x prefix is optional.
|
||||
func (a *UnprefixedAddress) UnmarshalText(input []byte) error {
|
||||
return UnmarshalFixedUnprefixedText("UnprefixedAddress", input, a[:])
|
||||
}
|
||||
|
||||
// MarshalText encodes the address as hex.
|
||||
func (a UnprefixedAddress) MarshalText() ([]byte, error) {
|
||||
return []byte(hex.EncodeToString(a[:])), nil
|
||||
}
|
||||
|
||||
// MixedcaseAddress retains the original string, which may or may not be
|
||||
// correctly checksummed
|
||||
type MixedcaseAddress struct {
|
||||
addr Address
|
||||
original string
|
||||
}
|
||||
|
||||
// NewMixedcaseAddress constructor (mainly for testing)
|
||||
func NewMixedcaseAddress(addr Address) MixedcaseAddress {
|
||||
return MixedcaseAddress{addr: addr, original: addr.Hex()}
|
||||
}
|
||||
|
||||
// NewMixedcaseAddressFromString is mainly meant for unit-testing
|
||||
func NewMixedcaseAddressFromString(hexaddr string) (*MixedcaseAddress, error) {
|
||||
if !IsHexAddress(hexaddr) {
|
||||
return nil, fmt.Errorf("Invalid address")
|
||||
}
|
||||
a := FromHex(hexaddr)
|
||||
return &MixedcaseAddress{addr: BytesToAddress(a), original: hexaddr}, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON parses MixedcaseAddress
|
||||
func (ma *MixedcaseAddress) UnmarshalJSON(input []byte) error {
|
||||
if err := UnmarshalFixedJSON(addressT, input, ma.addr[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
return json.Unmarshal(input, &ma.original)
|
||||
}
|
||||
|
||||
// MarshalJSON marshals the original value
|
||||
func (ma *MixedcaseAddress) MarshalJSON() ([]byte, error) {
|
||||
if strings.HasPrefix(ma.original, "0x") || strings.HasPrefix(ma.original, "0X") {
|
||||
return json.Marshal(fmt.Sprintf("0x%s", ma.original[2:]))
|
||||
}
|
||||
return json.Marshal(fmt.Sprintf("0x%s", ma.original))
|
||||
}
|
||||
|
||||
// Address returns the address
|
||||
func (ma *MixedcaseAddress) Address() Address {
|
||||
return ma.addr
|
||||
}
|
||||
|
||||
// String implements fmt.Stringer
|
||||
func (ma *MixedcaseAddress) String() string {
|
||||
if ma.ValidChecksum() {
|
||||
return fmt.Sprintf("%s [chksum ok]", ma.original)
|
||||
}
|
||||
return fmt.Sprintf("%s [chksum INVALID]", ma.original)
|
||||
}
|
||||
|
||||
// ValidChecksum returns true if the address has valid checksum
|
||||
func (ma *MixedcaseAddress) ValidChecksum() bool {
|
||||
return ma.original == ma.addr.Hex()
|
||||
}
|
||||
|
||||
// Original returns the mixed-case input string
|
||||
func (ma *MixedcaseAddress) Original() string {
|
||||
return ma.original
|
||||
}
|
||||
46
vendor/github.com/status-im/status-go/eth-node/types/bytes.go
generated
vendored
Normal file
46
vendor/github.com/status-im/status-go/eth-node/types/bytes.go
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
package types
|
||||
|
||||
import "encoding/hex"
|
||||
|
||||
// has0xPrefix validates str begins with '0x' or '0X'.
|
||||
func has0xPrefix(str string) bool {
|
||||
return len(str) >= 2 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X')
|
||||
}
|
||||
|
||||
// isHexCharacter returns bool of c being a valid hexadecimal.
|
||||
func isHexCharacter(c byte) bool {
|
||||
return ('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F')
|
||||
}
|
||||
|
||||
// isHex validates whether each byte is valid hexadecimal string.
|
||||
func isHex(str string) bool {
|
||||
if len(str)%2 != 0 {
|
||||
return false
|
||||
}
|
||||
for _, c := range []byte(str) {
|
||||
if !isHexCharacter(c) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Bytes2Hex returns the hexadecimal encoding of d.
|
||||
func Bytes2Hex(d []byte) string {
|
||||
return hex.EncodeToString(d)
|
||||
}
|
||||
|
||||
// Hex2Bytes returns the bytes represented by the hexadecimal string str.
|
||||
func Hex2Bytes(str string) []byte {
|
||||
if has0xPrefix(str) {
|
||||
str = str[2:]
|
||||
}
|
||||
|
||||
h, _ := hex.DecodeString(str)
|
||||
return h
|
||||
}
|
||||
|
||||
// ToHex returns the hex string representation of bytes with 0x prefix.
|
||||
func ToHex(bytes []byte) string {
|
||||
return "0x" + Bytes2Hex(bytes)
|
||||
}
|
||||
8
vendor/github.com/status-im/status-go/eth-node/types/const.go
generated
vendored
Normal file
8
vendor/github.com/status-im/status-go/eth-node/types/const.go
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
package types
|
||||
|
||||
const (
|
||||
// PubKeyLength represents the length (in bytes) of an uncompressed public key
|
||||
PubKeyLength = 512 / 8
|
||||
// AesKeyLength represents the length (in bytes) of an private key
|
||||
AesKeyLength = 256 / 8
|
||||
)
|
||||
27
vendor/github.com/status-im/status-go/eth-node/types/ens/ens.go
generated
vendored
Normal file
27
vendor/github.com/status-im/status-go/eth-node/types/ens/ens.go
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
package enstypes
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
)
|
||||
|
||||
type ENSVerifier interface {
|
||||
// CheckBatch verifies that a registered ENS name matches the expected public key
|
||||
CheckBatch(ensDetails []ENSDetails, rpcEndpoint, contractAddress string) (map[string]ENSResponse, error)
|
||||
ReverseResolve(address common.Address, rpcEndpoint string) (string, error)
|
||||
}
|
||||
|
||||
type ENSDetails struct {
|
||||
Name string `json:"name"`
|
||||
PublicKeyString string `json:"publicKey"`
|
||||
}
|
||||
|
||||
type ENSResponse struct {
|
||||
Name string `json:"name"`
|
||||
Verified bool `json:"verified"`
|
||||
VerifiedAt int64 `json:"verifiedAt"`
|
||||
Error error `json:"error"`
|
||||
PublicKey *ecdsa.PublicKey `json:"-"`
|
||||
PublicKeyString string `json:"publicKey"`
|
||||
}
|
||||
88
vendor/github.com/status-im/status-go/eth-node/types/envelopes.go
generated
vendored
Normal file
88
vendor/github.com/status-im/status-go/eth-node/types/envelopes.go
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
package types
|
||||
|
||||
// Envelope represents a clear-text data packet to transmit through the Whisper
|
||||
// network. Its contents may or may not be encrypted and signed.
|
||||
type Envelope interface {
|
||||
Wrapped
|
||||
|
||||
Hash() Hash // cached hash of the envelope to avoid rehashing every time
|
||||
Bloom() []byte
|
||||
PoW() float64
|
||||
Expiry() uint32
|
||||
TTL() uint32
|
||||
Topic() TopicType
|
||||
Size() int
|
||||
}
|
||||
|
||||
// EventType used to define known envelope events.
|
||||
type EventType string
|
||||
|
||||
// NOTE: This list of event names is extracted from Geth. It must be kept in sync, or otherwise a mapping layer needs to be created
|
||||
const (
|
||||
// EventEnvelopeSent fires when envelope was sent to a peer.
|
||||
EventEnvelopeSent EventType = "envelope.sent"
|
||||
// EventEnvelopeExpired fires when envelop expired
|
||||
EventEnvelopeExpired EventType = "envelope.expired"
|
||||
// EventEnvelopeReceived is sent once envelope was received from a peer.
|
||||
// EventEnvelopeReceived must be sent to the feed even if envelope was previously in the cache.
|
||||
// And event, ideally, should contain information about peer that sent envelope to us.
|
||||
EventEnvelopeReceived EventType = "envelope.received"
|
||||
// EventBatchAcknowledged is sent when batch of envelopes was acknowledged by a peer.
|
||||
EventBatchAcknowledged EventType = "batch.acknowledged"
|
||||
// EventEnvelopeAvailable fires when envelop is available for filters
|
||||
EventEnvelopeAvailable EventType = "envelope.available"
|
||||
// EventMailServerRequestSent fires when such request is sent.
|
||||
EventMailServerRequestSent EventType = "mailserver.request.sent"
|
||||
// EventMailServerRequestCompleted fires after mailserver sends all the requested messages
|
||||
EventMailServerRequestCompleted EventType = "mailserver.request.completed"
|
||||
// EventMailServerRequestExpired fires after mailserver the request TTL ends.
|
||||
// This event is independent and concurrent to EventMailServerRequestCompleted.
|
||||
// Request should be considered as expired only if expiry event was received first.
|
||||
EventMailServerRequestExpired EventType = "mailserver.request.expired"
|
||||
// EventMailServerEnvelopeArchived fires after an envelope has been archived
|
||||
EventMailServerEnvelopeArchived EventType = "mailserver.envelope.archived"
|
||||
// EventMailServerSyncFinished fires when the sync of messages is finished.
|
||||
EventMailServerSyncFinished EventType = "mailserver.sync.finished"
|
||||
)
|
||||
|
||||
const (
|
||||
// EnvelopeTimeNotSynced represents the code passed to notify of a clock skew situation
|
||||
EnvelopeTimeNotSynced uint = 1000
|
||||
// EnvelopeOtherError represents the code passed to notify of a generic error situation
|
||||
EnvelopeOtherError
|
||||
)
|
||||
|
||||
// EnvelopeEvent used for envelopes events.
|
||||
type EnvelopeEvent struct {
|
||||
Event EventType
|
||||
Hash Hash
|
||||
Batch Hash
|
||||
Peer EnodeID
|
||||
Data interface{}
|
||||
}
|
||||
|
||||
// EnvelopeError code and optional description of the error.
|
||||
type EnvelopeError struct {
|
||||
Hash Hash
|
||||
Code uint
|
||||
Description string
|
||||
}
|
||||
|
||||
// Subscription represents a stream of events. The carrier of the events is typically a
|
||||
// channel, but isn't part of the interface.
|
||||
//
|
||||
// Subscriptions can fail while established. Failures are reported through an error
|
||||
// channel. It receives a value if there is an issue with the subscription (e.g. the
|
||||
// network connection delivering the events has been closed). Only one value will ever be
|
||||
// sent.
|
||||
//
|
||||
// The error channel is closed when the subscription ends successfully (i.e. when the
|
||||
// source of events is closed). It is also closed when Unsubscribe is called.
|
||||
//
|
||||
// The Unsubscribe method cancels the sending of events. You must call Unsubscribe in all
|
||||
// cases to ensure that resources related to the subscription are released. It can be
|
||||
// called any number of times.
|
||||
type Subscription interface {
|
||||
Err() <-chan error // returns the error channel
|
||||
Unsubscribe() // cancels sending of events, closing the error channel
|
||||
}
|
||||
6
vendor/github.com/status-im/status-go/eth-node/types/filter.go
generated
vendored
Normal file
6
vendor/github.com/status-im/status-go/eth-node/types/filter.go
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
package types
|
||||
|
||||
// Filter represents a Whisper message filter
|
||||
type Filter interface {
|
||||
ID() string
|
||||
}
|
||||
119
vendor/github.com/status-im/status-go/eth-node/types/hash.go
generated
vendored
Normal file
119
vendor/github.com/status-im/status-go/eth-node/types/hash.go
generated
vendored
Normal file
@@ -0,0 +1,119 @@
|
||||
// Code extracted from vendor/github.com/ethereum/go-ethereum/common/types.go
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
const (
|
||||
// HashLength is the expected length of the hash
|
||||
HashLength = 32
|
||||
)
|
||||
|
||||
// Hash represents the 32 byte Keccak256 hash of arbitrary data.
|
||||
type Hash [HashLength]byte
|
||||
|
||||
var hashT = reflect.TypeOf(Hash{})
|
||||
|
||||
// Encode encodes b as a hex string with 0x prefix.
|
||||
func encode(b []byte) string {
|
||||
enc := make([]byte, len(b)*2+2)
|
||||
copy(enc, "0x")
|
||||
hex.Encode(enc[2:], b)
|
||||
return string(enc)
|
||||
}
|
||||
|
||||
// FromHex returns the bytes represented by the hexadecimal string s.
|
||||
// s may be prefixed with "0x".
|
||||
func FromHex(s string) []byte {
|
||||
if has0xPrefix(s) {
|
||||
s = s[2:]
|
||||
}
|
||||
if len(s)%2 == 1 {
|
||||
s = "0" + s
|
||||
}
|
||||
return Hex2Bytes(s)
|
||||
}
|
||||
|
||||
// HexToHash sets byte representation of s to hash.
|
||||
// If b is larger than len(h), b will be cropped from the left.
|
||||
func HexToHash(s string) Hash { return BytesToHash(FromHex(s)) }
|
||||
|
||||
// Hex converts a hash to a hex string.
|
||||
func (h *Hash) Hex() string { return encode(h[:]) }
|
||||
|
||||
// Bytes gets the byte representation of the underlying hash.
|
||||
func (h Hash) Bytes() []byte { return h[:] }
|
||||
|
||||
// String implements the stringer interface and is used also by the logger when
|
||||
// doing full logging into a file.
|
||||
func (h Hash) String() string {
|
||||
return h.Hex()
|
||||
}
|
||||
|
||||
// SetBytes sets the hash to the value of b.
|
||||
// If b is larger than len(h), b will be cropped from the left.
|
||||
func (h *Hash) SetBytes(b []byte) {
|
||||
if len(b) > len(h) {
|
||||
b = b[len(b)-HashLength:]
|
||||
}
|
||||
|
||||
copy(h[HashLength-len(b):], b)
|
||||
}
|
||||
|
||||
// UnmarshalText parses a hash in hex syntax.
|
||||
func (h *Hash) UnmarshalText(input []byte) error {
|
||||
return UnmarshalFixedText("Hash", input, h[:])
|
||||
}
|
||||
|
||||
// UnmarshalJSON parses a hash in hex syntax.
|
||||
func (h *Hash) UnmarshalJSON(input []byte) error {
|
||||
return UnmarshalFixedJSON(hashT, input, h[:])
|
||||
}
|
||||
|
||||
// MarshalText returns the hex representation of h.
|
||||
func (h Hash) MarshalText() ([]byte, error) {
|
||||
return HexBytes(h[:]).MarshalText()
|
||||
}
|
||||
|
||||
// BytesToHash sets b to hash.
|
||||
// If b is larger than len(h), b will be cropped from the left.
|
||||
func BytesToHash(b []byte) Hash {
|
||||
var h Hash
|
||||
h.SetBytes(b)
|
||||
return h
|
||||
}
|
||||
|
||||
// UnmarshalFixedJSON decodes the input as a string with 0x prefix. The length of out
|
||||
// determines the required input length. This function is commonly used to implement the
|
||||
// UnmarshalJSON method for fixed-size types.
|
||||
func UnmarshalFixedJSON(typ reflect.Type, input, out []byte) error {
|
||||
if !isString(input) {
|
||||
return errNonString(typ)
|
||||
}
|
||||
return wrapTypeError(UnmarshalFixedText(typ.String(), input[1:len(input)-1], out), typ)
|
||||
}
|
||||
|
||||
// UnmarshalFixedText decodes the input as a string with 0x prefix. The length of out
|
||||
// determines the required input length. This function is commonly used to implement the
|
||||
// UnmarshalText method for fixed-size types.
|
||||
func UnmarshalFixedText(typname string, input, out []byte) error {
|
||||
raw, err := checkText(input, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(raw)/2 != len(out) {
|
||||
return fmt.Errorf("hex string has length %d, want %d for %s", len(raw), len(out)*2, typname)
|
||||
}
|
||||
// Pre-verify syntax before modifying out.
|
||||
for _, b := range raw {
|
||||
if decodeNibble(b) == badNibble {
|
||||
return ErrSyntax
|
||||
}
|
||||
}
|
||||
_, err = hex.Decode(out, raw)
|
||||
return err
|
||||
}
|
||||
58
vendor/github.com/status-im/status-go/eth-node/types/hex.go
generated
vendored
Normal file
58
vendor/github.com/status-im/status-go/eth-node/types/hex.go
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
// Code extracted from vendor/github.com/ethereum/go-ethereum/common/hexutil/hexutil.go
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
var (
|
||||
bytesT = reflect.TypeOf(HexBytes(nil))
|
||||
)
|
||||
|
||||
// HexBytes marshals/unmarshals as a JSON string with 0x prefix.
|
||||
// The empty slice marshals as "0x".
|
||||
type HexBytes []byte
|
||||
|
||||
func (b HexBytes) Bytes() []byte {
|
||||
result := make([]byte, len(b)*2+2)
|
||||
copy(result, `0x`)
|
||||
hex.Encode(result[2:], b)
|
||||
return result
|
||||
}
|
||||
|
||||
// MarshalText implements encoding.TextMarshaler
|
||||
func (b HexBytes) MarshalText() ([]byte, error) {
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler.
|
||||
func (b *HexBytes) UnmarshalJSON(input []byte) error {
|
||||
if !isString(input) {
|
||||
return errNonString(bytesT)
|
||||
}
|
||||
return wrapTypeError(b.UnmarshalText(input[1:len(input)-1]), bytesT)
|
||||
}
|
||||
|
||||
// UnmarshalFixedUnprefixedText decodes the input as a string with optional 0x prefix. The
|
||||
// length of out determines the required input length. This function is commonly used to
|
||||
// implement the UnmarshalText method for fixed-size types.
|
||||
func UnmarshalFixedUnprefixedText(typname string, input, out []byte) error {
|
||||
raw, err := checkText(input, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(raw)/2 != len(out) {
|
||||
return fmt.Errorf("hex string has length %d, want %d for %s", len(raw), len(out)*2, typname)
|
||||
}
|
||||
// Pre-verify syntax before modifying out.
|
||||
for _, b := range raw {
|
||||
if decodeNibble(b) == badNibble {
|
||||
return ErrSyntax
|
||||
}
|
||||
}
|
||||
_, err = hex.Decode(out, raw)
|
||||
return err
|
||||
}
|
||||
180
vendor/github.com/status-im/status-go/eth-node/types/json.go
generated
vendored
Normal file
180
vendor/github.com/status-im/status-go/eth-node/types/json.go
generated
vendored
Normal file
@@ -0,0 +1,180 @@
|
||||
// Code extracted from vendor/github.com/ethereum/go-ethereum/common/hexutil/json.go
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const (
|
||||
badNibble = ^uint64(0)
|
||||
uintBits = 32 << (uint64(^uint(0)) >> 63)
|
||||
)
|
||||
|
||||
// Errors
|
||||
var (
|
||||
ErrEmptyString = &decError{"empty hex string"}
|
||||
ErrSyntax = &decError{"invalid hex string"}
|
||||
ErrMissingPrefix = &decError{"hex string without 0x prefix"}
|
||||
ErrOddLength = &decError{"hex string of odd length"}
|
||||
ErrEmptyNumber = &decError{"hex string \"0x\""}
|
||||
ErrLeadingZero = &decError{"hex number with leading zero digits"}
|
||||
ErrUint64Range = &decError{"hex number > 64 bits"}
|
||||
ErrUintRange = &decError{fmt.Sprintf("hex number > %d bits", uintBits)}
|
||||
ErrBig256Range = &decError{"hex number > 256 bits"}
|
||||
)
|
||||
|
||||
type decError struct{ msg string }
|
||||
|
||||
func (err decError) Error() string { return err.msg }
|
||||
|
||||
func decodeNibble(in byte) uint64 {
|
||||
switch {
|
||||
case in >= '0' && in <= '9':
|
||||
return uint64(in - '0')
|
||||
case in >= 'A' && in <= 'F':
|
||||
return uint64(in - 'A' + 10)
|
||||
case in >= 'a' && in <= 'f':
|
||||
return uint64(in - 'a' + 10)
|
||||
default:
|
||||
return badNibble
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalText implements encoding.TextUnmarshaler.
|
||||
func (b *HexBytes) UnmarshalText(input []byte) error {
|
||||
raw, err := checkText(input, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dec := make([]byte, len(raw)/2)
|
||||
if _, err = hex.Decode(dec, raw); err != nil {
|
||||
err = mapError(err)
|
||||
} else {
|
||||
*b = dec
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// UnmarshalFixedHexText decodes the input as a string with 0x prefix. The length of out
|
||||
// determines the required input length. This function is commonly used to implement the
|
||||
// UnmarshalText method for fixed-size types.
|
||||
func UnmarshalFixedHexText(typname string, input, out []byte) error {
|
||||
raw, err := checkText(input, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(raw)/2 != len(out) {
|
||||
return fmt.Errorf("hex string has length %d, want %d for %s", len(raw), len(out)*2, typname)
|
||||
}
|
||||
// Pre-verify syntax before modifying out.
|
||||
for _, b := range raw {
|
||||
if decodeNibble(b) == badNibble {
|
||||
return ErrSyntax
|
||||
}
|
||||
}
|
||||
_, err = hex.Decode(out, raw)
|
||||
return err
|
||||
}
|
||||
|
||||
// String returns the hex encoding of b.
|
||||
func (b HexBytes) String() string {
|
||||
return EncodeHex(b)
|
||||
}
|
||||
|
||||
// EncodeHex encodes b as a hex string with 0x prefix.
|
||||
func EncodeHex(b []byte) string {
|
||||
enc := make([]byte, len(b)*2+2)
|
||||
copy(enc, "0x")
|
||||
hex.Encode(enc[2:], b)
|
||||
return string(enc)
|
||||
}
|
||||
|
||||
// EncodeHex encodes bs as a hex strings with 0x prefix.
|
||||
func EncodeHexes(bs [][]byte) []string {
|
||||
result := make([]string, len(bs))
|
||||
for i, b := range bs {
|
||||
result[i] = EncodeHex(b)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// DecodeHex decodes a hex string with 0x prefix.
|
||||
func DecodeHex(input string) ([]byte, error) {
|
||||
if len(input) == 0 {
|
||||
return nil, ErrEmptyString
|
||||
}
|
||||
if !has0xPrefix(input) {
|
||||
return nil, ErrMissingPrefix
|
||||
}
|
||||
b, err := hex.DecodeString(input[2:])
|
||||
if err != nil {
|
||||
err = mapError(err)
|
||||
}
|
||||
return b, err
|
||||
}
|
||||
|
||||
// MustDecodeHex decodes a hex string with 0x prefix. It panics for invalid input.
|
||||
func MustDecodeHex(input string) []byte {
|
||||
dec, err := DecodeHex(input)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return dec
|
||||
}
|
||||
|
||||
func isString(input []byte) bool {
|
||||
return len(input) >= 2 && input[0] == '"' && input[len(input)-1] == '"'
|
||||
}
|
||||
|
||||
func bytesHave0xPrefix(input []byte) bool {
|
||||
return len(input) >= 2 && input[0] == '0' && (input[1] == 'x' || input[1] == 'X')
|
||||
}
|
||||
|
||||
func checkText(input []byte, wantPrefix bool) ([]byte, error) {
|
||||
if len(input) == 0 {
|
||||
return nil, nil // empty strings are allowed
|
||||
}
|
||||
if bytesHave0xPrefix(input) {
|
||||
input = input[2:]
|
||||
} else if wantPrefix {
|
||||
return nil, ErrMissingPrefix
|
||||
}
|
||||
if len(input)%2 != 0 {
|
||||
return nil, ErrOddLength
|
||||
}
|
||||
return input, nil
|
||||
}
|
||||
|
||||
func mapError(err error) error {
|
||||
if err, ok := err.(*strconv.NumError); ok {
|
||||
switch err.Err {
|
||||
case strconv.ErrRange:
|
||||
return ErrUint64Range
|
||||
case strconv.ErrSyntax:
|
||||
return ErrSyntax
|
||||
}
|
||||
}
|
||||
if _, ok := err.(hex.InvalidByteError); ok {
|
||||
return ErrSyntax
|
||||
}
|
||||
if err == hex.ErrLength {
|
||||
return ErrOddLength
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func wrapTypeError(err error, typ reflect.Type) error {
|
||||
if _, ok := err.(*decError); ok {
|
||||
return &json.UnmarshalTypeError{Value: err.Error(), Type: typ}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func errNonString(typ reflect.Type) error {
|
||||
return &json.UnmarshalTypeError{Value: "non-string", Type: typ}
|
||||
}
|
||||
25
vendor/github.com/status-im/status-go/eth-node/types/key.go
generated
vendored
Normal file
25
vendor/github.com/status-im/status-go/eth-node/types/key.go
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/status-im/status-go/extkeys"
|
||||
)
|
||||
|
||||
type Key struct {
|
||||
ID uuid.UUID // Version 4 "random" for unique id not derived from key data
|
||||
// to simplify lookups we also store the address
|
||||
Address Address
|
||||
// we only store privkey as pubkey/address can be derived from it
|
||||
// privkey in this struct is always in plaintext
|
||||
PrivateKey *ecdsa.PrivateKey
|
||||
// ExtendedKey is the extended key of the PrivateKey itself, and it's used
|
||||
// to derive child keys.
|
||||
ExtendedKey *extkeys.ExtendedKey
|
||||
// SubAccountIndex is DEPRECATED
|
||||
// It was use in Status to keep track of the number of sub-account created
|
||||
// before having multi-account support.
|
||||
SubAccountIndex uint32
|
||||
}
|
||||
26
vendor/github.com/status-im/status-go/eth-node/types/keystore.go
generated
vendored
Normal file
26
vendor/github.com/status-im/status-go/eth-node/types/keystore.go
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
|
||||
"github.com/status-im/status-go/extkeys"
|
||||
)
|
||||
|
||||
type KeyStore interface {
|
||||
// ImportAccount imports the account specified with privateKey.
|
||||
ImportECDSA(priv *ecdsa.PrivateKey, passphrase string) (Account, error)
|
||||
// ImportSingleExtendedKey imports an extended key setting it in both the PrivateKey and ExtendedKey fields
|
||||
// of the Key struct.
|
||||
// ImportExtendedKey is used in older version of Status where PrivateKey is set to be the BIP44 key at index 0,
|
||||
// and ExtendedKey is the extended key of the BIP44 key at index 1.
|
||||
ImportSingleExtendedKey(extKey *extkeys.ExtendedKey, passphrase string) (Account, error)
|
||||
// ImportExtendedKeyForPurpose stores ECDSA key (obtained from extended key) along with CKD#2 (root for sub-accounts)
|
||||
// If key file is not found, it is created. Key is encrypted with the given passphrase.
|
||||
// Deprecated: status-go is now using ImportSingleExtendedKey
|
||||
ImportExtendedKeyForPurpose(keyPurpose extkeys.KeyPurpose, extKey *extkeys.ExtendedKey, passphrase string) (Account, error)
|
||||
// AccountDecryptedKey returns decrypted key for account (provided that password is correct).
|
||||
AccountDecryptedKey(a Account, auth string) (Account, *Key, error)
|
||||
// Delete deletes the key matched by account if the passphrase is correct.
|
||||
// If the account contains no filename, the address must match a unique key.
|
||||
Delete(a Account) error
|
||||
}
|
||||
89
vendor/github.com/status-im/status-go/eth-node/types/mailserver.go
generated
vendored
Normal file
89
vendor/github.com/status-im/status-go/eth-node/types/mailserver.go
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
// MaxLimitInMessagesRequest represents the maximum number of messages
|
||||
// that can be requested from the mailserver
|
||||
MaxLimitInMessagesRequest = 1000
|
||||
)
|
||||
|
||||
// MessagesRequest contains details of a request of historic messages.
|
||||
type MessagesRequest struct {
|
||||
// ID of the request. The current implementation requires ID to be 32-byte array,
|
||||
// however, it's not enforced for future implementation.
|
||||
ID []byte `json:"id"`
|
||||
// From is a lower bound of time range.
|
||||
From uint32 `json:"from"`
|
||||
// To is a upper bound of time range.
|
||||
To uint32 `json:"to"`
|
||||
// Limit determines the number of messages sent by the mail server
|
||||
// for the current paginated request.
|
||||
Limit uint32 `json:"limit"`
|
||||
// Cursor is used as starting point for paginated requests.
|
||||
Cursor []byte `json:"cursor"`
|
||||
// StoreCursor is used as starting point for WAKUV2 paginatedRequests
|
||||
StoreCursor *StoreRequestCursor `json:"storeCursor"`
|
||||
// Bloom is a filter to match requested messages.
|
||||
Bloom []byte `json:"bloom"`
|
||||
// PubsubTopic is the gossipsub topic on which the message was broadcasted
|
||||
PubsubTopic string `json:"pubsubTopic"`
|
||||
// ContentTopics is a list of topics. A returned message should
|
||||
// belong to one of the topics from the list.
|
||||
ContentTopics [][]byte `json:"contentTopics"`
|
||||
}
|
||||
|
||||
type StoreRequestCursor struct {
|
||||
Digest []byte `json:"digest"`
|
||||
ReceiverTime int64 `json:"receiverTime"`
|
||||
SenderTime int64 `json:"senderTime"`
|
||||
PubsubTopic string `json:"pubsubTopic"`
|
||||
}
|
||||
|
||||
// SetDefaults sets the From and To defaults
|
||||
func (r *MessagesRequest) SetDefaults(now time.Time) {
|
||||
// set From and To defaults
|
||||
if r.To == 0 {
|
||||
r.To = uint32(now.UTC().Unix())
|
||||
}
|
||||
|
||||
if r.From == 0 {
|
||||
oneDay := uint32(86400) // -24 hours
|
||||
if r.To < oneDay {
|
||||
r.From = 0
|
||||
} else {
|
||||
r.From = r.To - oneDay
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MailServerResponse is the response payload sent by the mailserver.
|
||||
type MailServerResponse struct {
|
||||
LastEnvelopeHash Hash
|
||||
Cursor []byte
|
||||
Error error
|
||||
}
|
||||
|
||||
// SyncMailRequest contains details which envelopes should be synced
|
||||
// between Mail Servers.
|
||||
type SyncMailRequest struct {
|
||||
// Lower is a lower bound of time range for which messages are requested.
|
||||
Lower uint32
|
||||
// Upper is a lower bound of time range for which messages are requested.
|
||||
Upper uint32
|
||||
// Bloom is a bloom filter to filter envelopes.
|
||||
Bloom []byte
|
||||
// Limit is the max number of envelopes to return.
|
||||
Limit uint32
|
||||
// Cursor is used for pagination of the results.
|
||||
Cursor []byte
|
||||
}
|
||||
|
||||
// SyncEventResponse is a response from the Mail Server
|
||||
// form which the peer received envelopes.
|
||||
type SyncEventResponse struct {
|
||||
Cursor []byte
|
||||
Error string
|
||||
}
|
||||
11
vendor/github.com/status-im/status-go/eth-node/types/negotiated_secret.go
generated
vendored
Normal file
11
vendor/github.com/status-im/status-go/eth-node/types/negotiated_secret.go
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
)
|
||||
|
||||
// NegotiatedSecret represents a negotiated secret (both public and private keys)
|
||||
type NegotiatedSecret struct {
|
||||
PublicKey *ecdsa.PublicKey
|
||||
Key []byte
|
||||
}
|
||||
26
vendor/github.com/status-im/status-go/eth-node/types/node.go
generated
vendored
Normal file
26
vendor/github.com/status-im/status-go/eth-node/types/node.go
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
enstypes "github.com/status-im/status-go/eth-node/types/ens"
|
||||
)
|
||||
|
||||
// EnodeID is a unique identifier for each node.
|
||||
type EnodeID [32]byte
|
||||
|
||||
// ID prints as a long hexadecimal number.
|
||||
func (n EnodeID) String() string {
|
||||
return fmt.Sprintf("%x", n[:])
|
||||
}
|
||||
|
||||
type Node interface {
|
||||
NewENSVerifier(logger *zap.Logger) enstypes.ENSVerifier
|
||||
GetWaku(ctx interface{}) (Waku, error)
|
||||
GetWakuV2(ctx interface{}) (Waku, error)
|
||||
AddPeer(url string) error
|
||||
RemovePeer(url string) error
|
||||
PeersCount() int
|
||||
}
|
||||
96
vendor/github.com/status-im/status-go/eth-node/types/rpc.go
generated
vendored
Normal file
96
vendor/github.com/status-im/status-go/eth-node/types/rpc.go
generated
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
// NewMessage represents a new whisper message that is posted through the RPC.
|
||||
type NewMessage struct {
|
||||
SymKeyID string `json:"symKeyID"`
|
||||
PublicKey []byte `json:"pubKey"`
|
||||
SigID string `json:"sig"`
|
||||
TTL uint32 `json:"ttl"`
|
||||
PubsubTopic string `json:"pubsubTopic"`
|
||||
Topic TopicType `json:"topic"`
|
||||
Payload []byte `json:"payload"`
|
||||
Padding []byte `json:"padding"`
|
||||
PowTime uint32 `json:"powTime"`
|
||||
PowTarget float64 `json:"powTarget"`
|
||||
TargetPeer string `json:"targetPeer"`
|
||||
Ephemeral bool `json:"ephemeral"`
|
||||
}
|
||||
|
||||
// Message is the RPC representation of a whisper message.
|
||||
type Message struct {
|
||||
Sig []byte `json:"sig,omitempty"`
|
||||
TTL uint32 `json:"ttl"`
|
||||
Timestamp uint32 `json:"timestamp"`
|
||||
PubsubTopic string `json:"pubsubTopic"`
|
||||
Topic TopicType `json:"topic"`
|
||||
Payload []byte `json:"payload"`
|
||||
Padding []byte `json:"padding"`
|
||||
PoW float64 `json:"pow"`
|
||||
Hash []byte `json:"hash"`
|
||||
Dst []byte `json:"recipientPublicKey,omitempty"`
|
||||
P2P bool `json:"bool,omitempty"`
|
||||
ThirdPartyID string `json:"thirdPartyId,omitempty"`
|
||||
}
|
||||
|
||||
// Criteria holds various filter options for inbound messages.
|
||||
type Criteria struct {
|
||||
SymKeyID string `json:"symKeyID"`
|
||||
PrivateKeyID string `json:"privateKeyID"`
|
||||
Sig []byte `json:"sig"`
|
||||
MinPow float64 `json:"minPow"`
|
||||
PubsubTopic string `json:"pubsubTopic"`
|
||||
Topics []TopicType `json:"topics"`
|
||||
AllowP2P bool `json:"allowP2P"`
|
||||
}
|
||||
|
||||
// PublicWhisperAPI provides the whisper RPC service that can be
|
||||
// use publicly without security implications.
|
||||
type PublicWhisperAPI interface {
|
||||
// AddPrivateKey imports the given private key.
|
||||
AddPrivateKey(ctx context.Context, privateKey HexBytes) (string, error)
|
||||
// GenerateSymKeyFromPassword derives a key from the given password, stores it, and returns its ID.
|
||||
GenerateSymKeyFromPassword(ctx context.Context, passwd string) (string, error)
|
||||
// DeleteKeyPair removes the key with the given key if it exists.
|
||||
DeleteKeyPair(ctx context.Context, key string) (bool, error)
|
||||
|
||||
// Post posts a message on the Whisper network.
|
||||
// returns the hash of the message in case of success.
|
||||
Post(ctx context.Context, req NewMessage) ([]byte, error)
|
||||
|
||||
// NewMessageFilter creates a new filter that can be used to poll for
|
||||
// (new) messages that satisfy the given criteria.
|
||||
NewMessageFilter(req Criteria) (string, error)
|
||||
// GetFilterMessages returns the messages that match the filter criteria and
|
||||
// are received between the last poll and now.
|
||||
GetFilterMessages(id string) ([]*Message, error)
|
||||
// BloomFilter returns the current bloomfilter of the node
|
||||
BloomFilter() []byte
|
||||
}
|
||||
|
||||
// PublicWakuAPI provides the waku RPC service that can be
|
||||
// use publicly without security implications.
|
||||
type PublicWakuAPI interface {
|
||||
// AddPrivateKey imports the given private key.
|
||||
AddPrivateKey(ctx context.Context, privateKey HexBytes) (string, error)
|
||||
// GenerateSymKeyFromPassword derives a key from the given password, stores it, and returns its ID.
|
||||
GenerateSymKeyFromPassword(ctx context.Context, passwd string) (string, error)
|
||||
// DeleteKeyPair removes the key with the given key if it exists.
|
||||
DeleteKeyPair(ctx context.Context, key string) (bool, error)
|
||||
|
||||
// Post posts a message on the Whisper network.
|
||||
// returns the hash of the message in case of success.
|
||||
Post(ctx context.Context, req NewMessage) ([]byte, error)
|
||||
|
||||
// NewMessageFilter creates a new filter that can be used to poll for
|
||||
// (new) messages that satisfy the given criteria.
|
||||
NewMessageFilter(req Criteria) (string, error)
|
||||
// GetFilterMessages returns the messages that match the filter criteria and
|
||||
// are received between the last poll and now.
|
||||
GetFilterMessages(id string) ([]*Message, error)
|
||||
|
||||
BloomFilter() []byte
|
||||
}
|
||||
6
vendor/github.com/status-im/status-go/eth-node/types/stats.go
generated
vendored
Normal file
6
vendor/github.com/status-im/status-go/eth-node/types/stats.go
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
package types
|
||||
|
||||
type StatsSummary struct {
|
||||
UploadRate uint64 `json:"uploadRate"`
|
||||
DownloadRate uint64 `json:"downloadRate"`
|
||||
}
|
||||
11
vendor/github.com/status-im/status-go/eth-node/types/subscribe.go
generated
vendored
Normal file
11
vendor/github.com/status-im/status-go/eth-node/types/subscribe.go
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
package types
|
||||
|
||||
// SubscriptionOptions represents the parameters passed to Subscribe()
|
||||
// to customize the subscription behavior.
|
||||
type SubscriptionOptions struct {
|
||||
PrivateKeyID string
|
||||
SymKeyID string
|
||||
PoW float64
|
||||
PubsubTopic string
|
||||
Topics [][]byte
|
||||
}
|
||||
99
vendor/github.com/status-im/status-go/eth-node/types/topic.go
generated
vendored
Normal file
99
vendor/github.com/status-im/status-go/eth-node/types/topic.go
generated
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
)
|
||||
|
||||
const (
|
||||
// TopicLength is the expected length of the topic, in bytes
|
||||
TopicLength = 4
|
||||
// BloomFilterSize is the expected length of a bloom filter byte array, in bytes
|
||||
BloomFilterSize = 64
|
||||
)
|
||||
|
||||
// TopicType represents a cryptographically secure, probabilistic partial
|
||||
// classifications of a message, determined as the first (left) 4 bytes of the
|
||||
// SHA3 hash of some arbitrary data given by the original author of the message.
|
||||
type TopicType [TopicLength]byte
|
||||
|
||||
// BytesToTopic converts from the byte array representation of a topic
|
||||
// into the TopicType type.
|
||||
func BytesToTopic(b []byte) (t TopicType) {
|
||||
sz := TopicLength
|
||||
if x := len(b); x < TopicLength {
|
||||
sz = x
|
||||
}
|
||||
for i := 0; i < sz; i++ {
|
||||
t[i] = b[i]
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
// String converts a topic byte array to a string representation.
|
||||
func (t *TopicType) String() string {
|
||||
return EncodeHex(t[:])
|
||||
}
|
||||
|
||||
// MarshalText returns the hex representation of t.
|
||||
func (t TopicType) MarshalText() ([]byte, error) {
|
||||
return HexBytes(t[:]).MarshalText()
|
||||
}
|
||||
|
||||
// UnmarshalText parses a hex representation to a topic.
|
||||
func (t *TopicType) UnmarshalText(input []byte) error {
|
||||
return UnmarshalFixedText("Topic", input, t[:])
|
||||
}
|
||||
|
||||
// TopicToBloom converts the topic (4 bytes) to the bloom filter (64 bytes)
|
||||
func TopicToBloom(topic TopicType) []byte {
|
||||
b := make([]byte, BloomFilterSize)
|
||||
var index [3]int
|
||||
for j := 0; j < 3; j++ {
|
||||
index[j] = int(topic[j])
|
||||
if (topic[3] & (1 << uint(j))) != 0 {
|
||||
index[j] += 256
|
||||
}
|
||||
}
|
||||
|
||||
for j := 0; j < 3; j++ {
|
||||
byteIndex := index[j] / 8
|
||||
bitIndex := index[j] % 8
|
||||
b[byteIndex] = (1 << uint(bitIndex))
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// BloomFilterMatch returns true if a sample matches a bloom filter
|
||||
func BloomFilterMatch(filter, sample []byte) bool {
|
||||
if filter == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
for i := 0; i < BloomFilterSize; i++ {
|
||||
f := filter[i]
|
||||
s := sample[i]
|
||||
if (f | s) != f {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// MakeFullNodeBloom returns a bloom filter which matches all topics
|
||||
func MakeFullNodeBloom() []byte {
|
||||
bloom := make([]byte, BloomFilterSize)
|
||||
for i := 0; i < BloomFilterSize; i++ {
|
||||
bloom[i] = 0xFF
|
||||
}
|
||||
return bloom
|
||||
}
|
||||
|
||||
func StringToTopic(s string) (t TopicType) {
|
||||
str, _ := hexutil.Decode(s)
|
||||
return BytesToTopic(str)
|
||||
}
|
||||
|
||||
func TopicTypeToByteArray(t TopicType) []byte {
|
||||
return t[:4]
|
||||
}
|
||||
171
vendor/github.com/status-im/status-go/eth-node/types/waku.go
generated
vendored
Normal file
171
vendor/github.com/status-im/status-go/eth-node/types/waku.go
generated
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
"github.com/libp2p/go-libp2p/core/protocol"
|
||||
"github.com/pborman/uuid"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/status-im/status-go/connection"
|
||||
)
|
||||
|
||||
type ConnStatus struct {
|
||||
IsOnline bool `json:"isOnline"`
|
||||
HasHistory bool `json:"hasHistory"`
|
||||
Peers map[string]WakuV2Peer `json:"peers"`
|
||||
}
|
||||
|
||||
type WakuV2Peer struct {
|
||||
Protocols []protocol.ID `json:"protocols"`
|
||||
Addresses []string `json:"addresses"`
|
||||
}
|
||||
|
||||
type ConnStatusSubscription struct {
|
||||
sync.RWMutex
|
||||
|
||||
ID string
|
||||
C chan ConnStatus
|
||||
active bool
|
||||
}
|
||||
|
||||
func NewConnStatusSubscription() *ConnStatusSubscription {
|
||||
return &ConnStatusSubscription{
|
||||
ID: uuid.NewRandom().String(),
|
||||
C: make(chan ConnStatus, 100),
|
||||
active: true,
|
||||
}
|
||||
}
|
||||
|
||||
func (u *ConnStatusSubscription) Active() bool {
|
||||
u.RLock()
|
||||
defer u.RUnlock()
|
||||
return u.active
|
||||
}
|
||||
|
||||
func (u *ConnStatusSubscription) Unsubscribe() {
|
||||
u.Lock()
|
||||
defer u.Unlock()
|
||||
close(u.C)
|
||||
u.active = false
|
||||
}
|
||||
|
||||
type WakuKeyManager interface {
|
||||
// GetPrivateKey retrieves the private key of the specified identity.
|
||||
GetPrivateKey(id string) (*ecdsa.PrivateKey, error)
|
||||
// AddKeyPair imports a asymmetric private key and returns a deterministic identifier.
|
||||
AddKeyPair(key *ecdsa.PrivateKey) (string, error)
|
||||
// DeleteKeyPair deletes the key with the specified ID if it exists.
|
||||
DeleteKeyPair(keyID string) bool
|
||||
// DeleteKeyPairs deletes all the keys
|
||||
DeleteKeyPairs() error
|
||||
AddSymKeyDirect(key []byte) (string, error)
|
||||
AddSymKeyFromPassword(password string) (string, error)
|
||||
DeleteSymKey(id string) bool
|
||||
GetSymKey(id string) ([]byte, error)
|
||||
}
|
||||
|
||||
// Whisper represents a dark communication interface through the Ethereum
|
||||
// network, using its very own P2P communication layer.
|
||||
type Waku interface {
|
||||
PublicWakuAPI() PublicWakuAPI
|
||||
|
||||
// Waku protocol version
|
||||
Version() uint
|
||||
|
||||
// PeerCount
|
||||
PeerCount() int
|
||||
|
||||
ListenAddresses() ([]string, error)
|
||||
|
||||
Peers() map[string]WakuV2Peer
|
||||
|
||||
StartDiscV5() error
|
||||
|
||||
StopDiscV5() error
|
||||
|
||||
SubscribeToPubsubTopic(topic string, optPublicKey *ecdsa.PublicKey) error
|
||||
|
||||
UnsubscribeFromPubsubTopic(topic string) error
|
||||
|
||||
StorePubsubTopicKey(topic string, privKey *ecdsa.PrivateKey) error
|
||||
|
||||
RetrievePubsubTopicKey(topic string) (*ecdsa.PrivateKey, error)
|
||||
|
||||
RemovePubsubTopicKey(topic string) error
|
||||
|
||||
AddStorePeer(address string) (peer.ID, error)
|
||||
|
||||
AddRelayPeer(address string) (peer.ID, error)
|
||||
|
||||
DialPeer(address string) error
|
||||
|
||||
DialPeerByID(peerID string) error
|
||||
|
||||
DropPeer(peerID string) error
|
||||
|
||||
SubscribeToConnStatusChanges() (*ConnStatusSubscription, error)
|
||||
|
||||
// MinPow returns the PoW value required by this node.
|
||||
MinPow() float64
|
||||
// BloomFilter returns the aggregated bloom filter for all the topics of interest.
|
||||
// The nodes are required to send only messages that match the advertised bloom filter.
|
||||
// If a message does not match the bloom, it will tantamount to spam, and the peer will
|
||||
// be disconnected.
|
||||
BloomFilter() []byte
|
||||
|
||||
// GetCurrentTime returns current time.
|
||||
GetCurrentTime() time.Time
|
||||
|
||||
// GetPrivateKey retrieves the private key of the specified identity.
|
||||
GetPrivateKey(id string) (*ecdsa.PrivateKey, error)
|
||||
|
||||
SubscribeEnvelopeEvents(events chan<- EnvelopeEvent) Subscription
|
||||
|
||||
// AddKeyPair imports a asymmetric private key and returns a deterministic identifier.
|
||||
AddKeyPair(key *ecdsa.PrivateKey) (string, error)
|
||||
// DeleteKeyPair deletes the key with the specified ID if it exists.
|
||||
DeleteKeyPair(keyID string) bool
|
||||
AddSymKeyDirect(key []byte) (string, error)
|
||||
AddSymKeyFromPassword(password string) (string, error)
|
||||
DeleteSymKey(id string) bool
|
||||
GetSymKey(id string) ([]byte, error)
|
||||
MaxMessageSize() uint32
|
||||
|
||||
GetStats() StatsSummary
|
||||
|
||||
Subscribe(opts *SubscriptionOptions) (string, error)
|
||||
GetFilter(id string) Filter
|
||||
Unsubscribe(ctx context.Context, id string) error
|
||||
UnsubscribeMany(ids []string) error
|
||||
|
||||
// RequestHistoricMessages sends a message with p2pRequestCode to a specific peer,
|
||||
// which is known to implement MailServer interface, and is supposed to process this
|
||||
// request and respond with a number of peer-to-peer messages (possibly expired),
|
||||
// which are not supposed to be forwarded any further.
|
||||
// The whisper protocol is agnostic of the format and contents of envelope.
|
||||
// A timeout of 0 never expires.
|
||||
RequestHistoricMessagesWithTimeout(peerID []byte, envelope Envelope, timeout time.Duration) error
|
||||
// SendMessagesRequest sends a MessagesRequest. This is an equivalent to RequestHistoricMessages
|
||||
// in terms of the functionality.
|
||||
SendMessagesRequest(peerID []byte, request MessagesRequest) error
|
||||
|
||||
// RequestStoreMessages uses the WAKU2-STORE protocol to request historic messages
|
||||
RequestStoreMessages(ctx context.Context, peerID []byte, request MessagesRequest, processEnvelopes bool) (*StoreRequestCursor, int, error)
|
||||
|
||||
// ProcessingP2PMessages indicates whether there are in-flight p2p messages
|
||||
ProcessingP2PMessages() bool
|
||||
|
||||
// MarkP2PMessageAsProcessed tells the waku layer that a P2P message has been processed
|
||||
MarkP2PMessageAsProcessed(common.Hash)
|
||||
|
||||
// ConnectionChanged is called whenever the client knows its connection status has changed
|
||||
ConnectionChanged(connection.State)
|
||||
|
||||
// ClearEnvelopesCache clears waku envelopes cache
|
||||
ClearEnvelopesCache()
|
||||
}
|
||||
59
vendor/github.com/status-im/status-go/eth-node/types/whisper.go
generated
vendored
Normal file
59
vendor/github.com/status-im/status-go/eth-node/types/whisper.go
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Whisper represents a dark communication interface through the Ethereum
|
||||
// network, using its very own P2P communication layer.
|
||||
type Whisper interface {
|
||||
PublicWhisperAPI() PublicWhisperAPI
|
||||
|
||||
// MinPow returns the PoW value required by this node.
|
||||
MinPow() float64
|
||||
// BloomFilter returns the aggregated bloom filter for all the topics of interest.
|
||||
// The nodes are required to send only messages that match the advertised bloom filter.
|
||||
// If a message does not match the bloom, it will tantamount to spam, and the peer will
|
||||
// be disconnected.
|
||||
BloomFilter() []byte
|
||||
// SetTimeSource assigns a particular source of time to a whisper object.
|
||||
SetTimeSource(timesource func() time.Time)
|
||||
// GetCurrentTime returns current time.
|
||||
GetCurrentTime() time.Time
|
||||
MaxMessageSize() uint32
|
||||
|
||||
// GetPrivateKey retrieves the private key of the specified identity.
|
||||
GetPrivateKey(id string) (*ecdsa.PrivateKey, error)
|
||||
|
||||
SubscribeEnvelopeEvents(events chan<- EnvelopeEvent) Subscription
|
||||
|
||||
// AddKeyPair imports a asymmetric private key and returns a deterministic identifier.
|
||||
AddKeyPair(key *ecdsa.PrivateKey) (string, error)
|
||||
// DeleteKeyPair deletes the key with the specified ID if it exists.
|
||||
DeleteKeyPair(keyID string) bool
|
||||
// DeleteKeyPairs removes all cryptographic identities known to the node
|
||||
DeleteKeyPairs() error
|
||||
AddSymKeyDirect(key []byte) (string, error)
|
||||
AddSymKeyFromPassword(password string) (string, error)
|
||||
DeleteSymKey(id string) bool
|
||||
GetSymKey(id string) ([]byte, error)
|
||||
|
||||
Subscribe(opts *SubscriptionOptions) (string, error)
|
||||
GetFilter(id string) Filter
|
||||
Unsubscribe(id string) error
|
||||
UnsubscribeMany(ids []string) error
|
||||
|
||||
// RequestHistoricMessages sends a message with p2pRequestCode to a specific peer,
|
||||
// which is known to implement MailServer interface, and is supposed to process this
|
||||
// request and respond with a number of peer-to-peer messages (possibly expired),
|
||||
// which are not supposed to be forwarded any further.
|
||||
// The whisper protocol is agnostic of the format and contents of envelope.
|
||||
// A timeout of 0 never expires.
|
||||
RequestHistoricMessagesWithTimeout(peerID []byte, envelope Envelope, timeout time.Duration) error
|
||||
// SendMessagesRequest sends a MessagesRequest. This is an equivalent to RequestHistoricMessages
|
||||
// in terms of the functionality.
|
||||
SendMessagesRequest(peerID []byte, request MessagesRequest) error
|
||||
// SyncMessages can be sent between two Mail Servers and syncs envelopes between them.
|
||||
SyncMessages(peerID []byte, req SyncMailRequest) error
|
||||
}
|
||||
7
vendor/github.com/status-im/status-go/eth-node/types/wrapped.go
generated
vendored
Normal file
7
vendor/github.com/status-im/status-go/eth-node/types/wrapped.go
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
package types
|
||||
|
||||
// Wrapped tells that a given object has an underlying representation
|
||||
// and this representation can be accessed using `Unwrap` method.
|
||||
type Wrapped interface {
|
||||
Unwrap() interface{}
|
||||
}
|
||||
Reference in New Issue
Block a user