diff --git a/core/chains/starknet/chain.go b/core/chains/starknet/chain.go index 2c4ebf211f9..705c3e79770 100644 --- a/core/chains/starknet/chain.go +++ b/core/chains/starknet/chain.go @@ -15,6 +15,7 @@ import ( "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/txm" "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/starknet" "github.com/smartcontractkit/chainlink/v2/core/chains" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/starkkey" "github.com/smartcontractkit/chainlink/v2/core/chains/starknet/types" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -33,9 +34,9 @@ type chain struct { txm txm.StarkTXM } -func newChain(id string, cfg config.Config, ks keystore.StarkNet, cfgs types.Configs, lggr logger.Logger) (ch *chain, err error) { +func newChain(id string, cfg config.Config, ks keystore.StarkNet, cfgs types.Configs, lggr logger.Logger) (*chain, error) { lggr = lggr.With("starknetChainID", id) - ch = &chain{ + ch := &chain{ id: id, cfg: cfg, cfgs: cfgs, @@ -46,7 +47,16 @@ func newChain(id string, cfg config.Config, ks keystore.StarkNet, cfgs types.Con return ch.getClient() } - ch.txm, err = txm.New(lggr, ks, cfg, getClient) + looppKs := starkkey.NewLooppKeystore(func(id string) (*big.Int, error) { + k, err := ks.Get(id) + if err != nil { + return nil, err + } + return k.ToPrivKey(), nil + }) + ksAdapter := starkkey.NewKeystoreAdapter(looppKs) + var err error + ch.txm, err = txm.New(lggr, ksAdapter.Loopp(), cfg, getClient) if err != nil { return nil, err } diff --git a/core/cmd/starknet_keys_commands.go b/core/cmd/starknet_keys_commands.go index fc3e3366efa..f32ad268224 100644 --- a/core/cmd/starknet_keys_commands.go +++ b/core/cmd/starknet_keys_commands.go @@ -1,8 +1,7 @@ package cmd import ( - starkkey "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/keys" - + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/starkkey" "github.com/smartcontractkit/chainlink/v2/core/utils" "github.com/smartcontractkit/chainlink/v2/core/web/presenters" ) diff --git a/core/cmd/starknet_keys_commands_test.go b/core/cmd/starknet_keys_commands_test.go index 23090426d54..1512cc0d30f 100644 --- a/core/cmd/starknet_keys_commands_test.go +++ b/core/cmd/starknet_keys_commands_test.go @@ -11,11 +11,10 @@ import ( "github.com/stretchr/testify/require" "github.com/urfave/cli" - starkkey "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/keys" - "github.com/smartcontractkit/chainlink/v2/core/cmd" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/starkkey" "github.com/smartcontractkit/chainlink/v2/core/utils" "github.com/smartcontractkit/chainlink/v2/core/web/presenters" ) diff --git a/core/internal/cltest/cltest.go b/core/internal/cltest/cltest.go index 6da6fb7ccf7..1626ee28263 100644 --- a/core/internal/cltest/cltest.go +++ b/core/internal/cltest/cltest.go @@ -42,8 +42,6 @@ import ( pkgsolana "github.com/smartcontractkit/chainlink-solana/pkg/solana" - starkkey "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/keys" - clienttypes "github.com/smartcontractkit/chainlink/v2/common/chains/client" "github.com/smartcontractkit/chainlink/v2/core/assets" "github.com/smartcontractkit/chainlink/v2/core/auth" @@ -80,6 +78,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocrkey" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/solkey" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/starkkey" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/vrfkey" "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 8cd363afd41..6dd219f81c6 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -283,11 +283,11 @@ require ( github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.22.12 // indirect github.com/sirupsen/logrus v1.9.0 // indirect - github.com/smartcontractkit/caigo v0.0.0-20230508053235-41120ca1f9f3 // indirect + github.com/smartcontractkit/caigo v0.0.0-20230526231506-786d4587099a // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.0 // indirect - github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230526232037-00743d25b7ec // indirect + github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230530222821-30d787a10087 // indirect github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230518143827-0b7a6e43719c // indirect - github.com/smartcontractkit/chainlink-starknet/relayer v0.0.0-20230522061116-665c91c3d1fa // indirect + github.com/smartcontractkit/chainlink-starknet/relayer v0.0.0-20230530233948-90c8af98011e // indirect github.com/smartcontractkit/wsrpc v0.7.2 // indirect github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 74502607725..9b40fecf725 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1370,16 +1370,16 @@ github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/smartcontractkit/caigo v0.0.0-20230508053235-41120ca1f9f3 h1:6RsuA0LBbC/6DgTYzg659Pw7GKktubj1GzTcB/VNC44= -github.com/smartcontractkit/caigo v0.0.0-20230508053235-41120ca1f9f3/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= +github.com/smartcontractkit/caigo v0.0.0-20230526231506-786d4587099a h1:B0WjTVtPW+GNY90rpmiwD/8tf3xr4jFC60sjuznNtRs= +github.com/smartcontractkit/caigo v0.0.0-20230526231506-786d4587099a/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= github.com/smartcontractkit/chainlink-cosmos v0.4.0 h1:xYLAcJJIm0cyMtYtMaosO45bykEwcwQOmZz3mz46Y2A= github.com/smartcontractkit/chainlink-cosmos v0.4.0/go.mod h1:938jBqOrhdCq4A8enUiBliiDLBndAXebHIitKsDVqY0= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230526232037-00743d25b7ec h1:ZG/N6BvjAKh6SkAHSYZ7el9WU6prCf0WsvcFjWJd0uU= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230526232037-00743d25b7ec/go.mod h1:f7/HKcJWWFzINrkDDlpKsFaU6D+8D4B4OrQxkkCX4oc= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230530222821-30d787a10087 h1:Xq3iwi8Vn+5uZb6RtKOn43GbSWLW7ij6S8Nn8JZ8vsg= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230530222821-30d787a10087/go.mod h1:f7/HKcJWWFzINrkDDlpKsFaU6D+8D4B4OrQxkkCX4oc= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230518143827-0b7a6e43719c h1:pM7FH+S92F7Xa/VSfbIs941FDKqSmo9pYeUBWHl1Pq0= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230518143827-0b7a6e43719c/go.mod h1:CUmP50gxZsjwEYA7balCV3mhvX0CrR/a01X6jGBZR8I= -github.com/smartcontractkit/chainlink-starknet/relayer v0.0.0-20230522061116-665c91c3d1fa h1:WWCXWDUAiKiEuDpOTvSukEDzOpOF73x/9nFrnFyf8rA= -github.com/smartcontractkit/chainlink-starknet/relayer v0.0.0-20230522061116-665c91c3d1fa/go.mod h1:bwWxlWboUoG99segq2uS80r+q4VPBPE0I/CztPBCMuY= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.0-20230530233948-90c8af98011e h1:0g2/8OSVFxbGQ2L7FTDo29t90ItOf+1CI2zOn3DBwHM= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.0-20230530233948-90c8af98011e/go.mod h1:m43fLfOPrJK+cLDyhoCn9wY7hPWZzW1Ywu1rqZQ2Xhk= github.com/smartcontractkit/libocr v0.0.0-20230503222226-29f534b2de1a h1:NFTlIAjSwx9vBYZeUerd0DDsvg+zZ5TSESw4dPNdwJk= github.com/smartcontractkit/libocr v0.0.0-20230503222226-29f534b2de1a/go.mod h1:5JnCHuYgmIP9ZyXzgAfI5Iwu0WxBtBKp+ApeT5o1Cjw= github.com/smartcontractkit/ocr2keepers v0.6.15 h1:dFhg+qT+tc6b3G8N4qnAHuHe8N0m8CSA8g4YGSeTGPo= diff --git a/core/services/keystore/keys/ocr2key/export.go b/core/services/keystore/keys/ocr2key/export.go index 2b4860aefa4..54e73ecf98f 100644 --- a/core/services/keystore/keys/ocr2key/export.go +++ b/core/services/keystore/keys/ocr2key/export.go @@ -5,9 +5,9 @@ import ( "github.com/ethereum/go-ethereum/accounts/keystore" - starknet "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/keys" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/starkkey" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -45,7 +45,7 @@ func FromEncryptedJSON(keyJSON []byte, password string) (KeyBundle, error) { case chaintype.Solana: kb = newKeyBundle(new(solanaKeyring)) case chaintype.StarkNet: - kb = newKeyBundle(new(starknet.OCR2Key)) + kb = newKeyBundle(new(starkkey.OCR2Key)) default: return nil, chaintype.NewErrInvalidChainType(export.ChainType) } diff --git a/core/services/keystore/keys/ocr2key/key_bundle.go b/core/services/keystore/keys/ocr2key/key_bundle.go index 78b3d84dac2..13be6fc3cae 100644 --- a/core/services/keystore/keys/ocr2key/key_bundle.go +++ b/core/services/keystore/keys/ocr2key/key_bundle.go @@ -9,9 +9,8 @@ import ( "github.com/ethereum/go-ethereum/crypto/secp256k1" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" - starknet "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/keys" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/starkkey" "github.com/smartcontractkit/chainlink/v2/core/store/models" ) @@ -33,7 +32,7 @@ type KeyBundle interface { var _ KeyBundle = &keyBundle[*evmKeyring]{} var _ KeyBundle = &keyBundle[*cosmosKeyring]{} var _ KeyBundle = &keyBundle[*solanaKeyring]{} -var _ KeyBundle = &keyBundle[*starknet.OCR2Key]{} +var _ KeyBundle = &keyBundle[*starkkey.OCR2Key]{} var curve = secp256k1.S256() @@ -47,7 +46,7 @@ func New(chainType chaintype.ChainType) (KeyBundle, error) { case chaintype.Solana: return newKeyBundleRand(chaintype.Solana, newSolanaKeyring) case chaintype.StarkNet: - return newKeyBundleRand(chaintype.StarkNet, starknet.NewOCR2Key) + return newKeyBundleRand(chaintype.StarkNet, starkkey.NewOCR2Key) } return nil, chaintype.NewErrInvalidChainType(chainType) } @@ -62,7 +61,7 @@ func MustNewInsecure(reader io.Reader, chainType chaintype.ChainType) KeyBundle case chaintype.Solana: return mustNewKeyBundleInsecure(chaintype.Solana, newSolanaKeyring, reader) case chaintype.StarkNet: - return mustNewKeyBundleInsecure(chaintype.StarkNet, starknet.NewOCR2Key, reader) + return mustNewKeyBundleInsecure(chaintype.StarkNet, starkkey.NewOCR2Key, reader) } panic(chaintype.NewErrInvalidChainType(chainType)) } @@ -111,7 +110,7 @@ func (raw Raw) Key() (kb KeyBundle) { case chaintype.Solana: kb = newKeyBundle(new(solanaKeyring)) case chaintype.StarkNet: - kb = newKeyBundle(new(starknet.OCR2Key)) + kb = newKeyBundle(new(starkkey.OCR2Key)) default: return nil } diff --git a/core/services/keystore/keys/starkkey/export.go b/core/services/keystore/keys/starkkey/export.go index 9d5818b0b11..366243a8da2 100644 --- a/core/services/keystore/keys/starkkey/export.go +++ b/core/services/keystore/keys/starkkey/export.go @@ -3,7 +3,6 @@ package starkkey import ( "github.com/ethereum/go-ethereum/accounts/keystore" - stark "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/keys" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -11,20 +10,20 @@ import ( const keyTypeIdentifier = "StarkNet" // FromEncryptedJSON gets key from json and password -func FromEncryptedJSON(keyJSON []byte, password string) (stark.Key, error) { +func FromEncryptedJSON(keyJSON []byte, password string) (Key, error) { return keys.FromEncryptedJSON( keyTypeIdentifier, keyJSON, password, adulteratedPassword, - func(_ keys.EncryptedKeyExport, rawPrivKey []byte) (stark.Key, error) { - return stark.Raw(rawPrivKey).Key(), nil + func(_ keys.EncryptedKeyExport, rawPrivKey []byte) (Key, error) { + return Raw(rawPrivKey).Key(), nil }, ) } // ToEncryptedJSON returns encrypted JSON representing key -func ToEncryptedJSON(key stark.Key, password string, scryptParams utils.ScryptParams) (export []byte, err error) { +func ToEncryptedJSON(key Key, password string, scryptParams utils.ScryptParams) (export []byte, err error) { return keys.ToEncryptedJSON( keyTypeIdentifier, key.Raw(), @@ -32,7 +31,7 @@ func ToEncryptedJSON(key stark.Key, password string, scryptParams utils.ScryptPa password, scryptParams, adulteratedPassword, - func(id string, key stark.Key, cryptoJSON keystore.CryptoJSON) (keys.EncryptedKeyExport, error) { + func(id string, key Key, cryptoJSON keystore.CryptoJSON) (keys.EncryptedKeyExport, error) { return keys.EncryptedKeyExport{ KeyType: id, PublicKey: key.StarkKeyStr(), diff --git a/core/services/keystore/keys/starkkey/export_test.go b/core/services/keystore/keys/starkkey/export_test.go index f348e1c8b23..27caa1744b4 100644 --- a/core/services/keystore/keys/starkkey/export_test.go +++ b/core/services/keystore/keys/starkkey/export_test.go @@ -3,7 +3,6 @@ package starkkey import ( "testing" - starknet "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/keys" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -13,7 +12,7 @@ func TestStarkNetKeys_ExportImport(t *testing.T) { } func createKey() (keys.KeyType, error) { - key, err := starknet.New() + key, err := New() return TestWrapped{key}, err } @@ -24,7 +23,7 @@ func decryptKey(keyJSON []byte, password string) (keys.KeyType, error) { // wrap key to conform to desired test interface type TestWrapped struct { - starknet.Key + Key } func (w TestWrapped) ToEncryptedJSON(password string, scryptParams utils.ScryptParams) ([]byte, error) { diff --git a/core/services/keystore/keys/starkkey/key.go b/core/services/keystore/keys/starkkey/key.go new file mode 100644 index 00000000000..f42e98c93ba --- /dev/null +++ b/core/services/keystore/keys/starkkey/key.go @@ -0,0 +1,104 @@ +package starkkey + +import ( + crypto_rand "crypto/rand" + "encoding/hex" + "fmt" + "io" + "math/big" + + "github.com/smartcontractkit/caigo" +) + +// Raw represents the Stark private key +type Raw []byte + +// Key gets the Key +func (raw Raw) Key() Key { + k := Key{} + var err error + + k.priv = new(big.Int).SetBytes(raw) + k.pub.X, k.pub.Y, err = caigo.Curve.PrivateToPoint(k.priv) + if err != nil { + panic(err) // key not generated + } + return k +} + +// String returns description +func (raw Raw) String() string { + return "" +} + +// GoString wraps String() +func (raw Raw) GoString() string { + return raw.String() +} + +var _ fmt.GoStringer = &Key{} + +type PublicKey struct { + X, Y *big.Int +} + +// Key represents Starknet key +type Key struct { + priv *big.Int + pub PublicKey +} + +// New creates new Key +func New() (Key, error) { + return newFrom(crypto_rand.Reader) +} + +// MustNewInsecure return Key if no error +func MustNewInsecure(reader io.Reader) Key { + key, err := newFrom(reader) + if err != nil { + panic(err) + } + return key +} + +func newFrom(reader io.Reader) (Key, error) { + return GenerateKey(reader) +} + +// ID gets Key ID +func (key Key) ID() string { + return key.StarkKeyStr() +} + +// StarkKeyStr is the starknet public key associated to the private key +// it is the X component of the ECDSA pubkey and used in the deployment of the account contract +// this func is used in exporting it via CLI and API +func (key Key) StarkKeyStr() string { + return "0x" + hex.EncodeToString(PubKeyToStarkKey(key.pub)) +} + +// Raw from private key +func (key Key) Raw() Raw { + return key.priv.Bytes() +} + +// String is the print-friendly format of the Key +func (key Key) String() string { + return fmt.Sprintf("StarknetKey{PrivateKey: , StarkKey: %s}", key.StarkKeyStr()) +} + +// GoString wraps String() +func (key Key) GoString() string { + return key.String() +} + +// ToPrivKey returns the key usable for signing. +func (key Key) ToPrivKey() *big.Int { + return key.priv +} + +// PublicKey copies public key object +func (key Key) PublicKey() PublicKey { + return key.pub +} diff --git a/core/services/keystore/keys/starkkey/keystore.go b/core/services/keystore/keys/starkkey/keystore.go new file mode 100644 index 00000000000..ad1df7bbe2a --- /dev/null +++ b/core/services/keystore/keys/starkkey/keystore.go @@ -0,0 +1,115 @@ +package starkkey + +import ( + "context" + "fmt" + "math/big" + + "github.com/smartcontractkit/caigo" + + "github.com/smartcontractkit/chainlink-relay/pkg/loop" + adapters "github.com/smartcontractkit/chainlink-relay/pkg/loop/adapters/starknet" +) + +// KeystoreAdapter is a starknet-specific adaption layer to translate between the generic Loop Keystore (bytes) and +// the type specific caigo Keystore (big.Int) +// The loop.Keystore must be produce a byte representation that can be parsed by the Decode func implementation +// Users of the interface are responsible to ensure this compatibility. +// +//go:generate mockery --name KeystoreAdapter --output ./mocks/ --case=underscore --filename keystore.go +type KeystoreAdapter interface { + caigo.Keystore + // Loopp must return a LOOPp Keystore implementation whose Sign func + // is compatible with the [Decode] func implementation + Loopp() loop.Keystore + // Decode translates from the raw signature of the LOOPp Keystore to that of the Caigo Keystore + Decode(ctx context.Context, rawSignature []byte) (*big.Int, *big.Int, error) +} + +// keystoreAdapter implements [KeystoreAdapter] +type keystoreAdapter struct { + looppKs loop.Keystore +} + +// NewKeystoreAdapter instantiates the KeystoreAdapter interface +// Callers are responsible for ensuring that the given LOOPp Keystore encodes +// signatures that can be parsed by the Decode function +func NewKeystoreAdapter(lk loop.Keystore) KeystoreAdapter { + return &keystoreAdapter{looppKs: lk} +} + +// Sign implements the caigo Keystore Sign func. +func (ca *keystoreAdapter) Sign(ctx context.Context, senderAddress string, hash *big.Int) (*big.Int, *big.Int, error) { + raw, err := ca.looppKs.Sign(ctx, senderAddress, hash.Bytes()) + if err != nil { + return nil, nil, fmt.Errorf("error computing loopp keystore signature: %w", err) + } + return ca.Decode(ctx, raw) +} + +func (ca *keystoreAdapter) Decode(ctx context.Context, rawSignature []byte) (x *big.Int, y *big.Int, err error) { + starknetSig, serr := adapters.SignatureFromBytes(rawSignature) + if serr != nil { + return nil, nil, fmt.Errorf("error creating starknet signature from raw signature: %w", serr) + } + return starknetSig.Ints() +} + +func (ca *keystoreAdapter) Loopp() loop.Keystore { + return ca.looppKs +} + +// LooppKeystore implements [loop.Keystore] interface and the requirements +// of signature d/encoding of the [KeystoreAdapter] +type LooppKeystore struct { + Get func(id string) (*big.Int, error) +} + +func NewLooppKeystore(get func(id string) (*big.Int, error)) *LooppKeystore { + return &LooppKeystore{Get: get} +} + +var _ loop.Keystore = &LooppKeystore{} + +// Sign implements [loop.Keystore] +// hash is expected to be the byte representation of big.Int +// the return []byte is encodes a starknet signature per [signature.bytes] +func (lk *LooppKeystore) Sign(ctx context.Context, id string, hash []byte) ([]byte, error) { + + k, err := lk.Get(id) + if err != nil { + return nil, err + } + // loopp spec requires passing nil hash to check existence of id + if hash == nil { + return nil, nil + } + + starkHash := new(big.Int).SetBytes(hash) + x, y, err := caigo.Curve.Sign(starkHash, k) + if err != nil { + return nil, fmt.Errorf("error signing data with curve: %w", err) + } + + sig, err := adapters.SignatureFromBigInts(x, y) + if err != nil { + return nil, err + } + return sig.Bytes() +} + +// TODO what is this supposed to return for starknet? +func (lk *LooppKeystore) Accounts(ctx context.Context) ([]string, error) { + return nil, fmt.Errorf("unimplemented") +} + +// pad bytes to specific length +func padBytes(a []byte, length int) []byte { + if len(a) < length { + pad := make([]byte, length-len(a)) + return append(pad, a...) + } + + // return original if length is >= to specified length + return a +} diff --git a/core/services/keystore/keys/starkkey/keystore_test.go b/core/services/keystore/keys/starkkey/keystore_test.go new file mode 100644 index 00000000000..4fea3983f5b --- /dev/null +++ b/core/services/keystore/keys/starkkey/keystore_test.go @@ -0,0 +1,89 @@ +package starkkey_test + +import ( + "context" + "errors" + "fmt" + "math/big" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/caigo" + + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/starkkey" +) + +func TestKeyStoreAdapter(t *testing.T) { + var ( + starknetPK = generateTestKey(t) + starknetSenderAddr = "legit" + ) + + lk := starkkey.NewLooppKeystore(func(id string) (*big.Int, error) { + if id != starknetSenderAddr { + return nil, fmt.Errorf("error getting key for sender %s: %w", id, ErrSenderNoExist) + } + return starknetPK, nil + }) + adapter := starkkey.NewKeystoreAdapter(lk) + // test that adapter implements the loopp spec. signing nil data should not error + // on existing sender id + signed, err := adapter.Loopp().Sign(context.Background(), starknetSenderAddr, nil) + require.Nil(t, signed) + require.NoError(t, err) + + signed, err = adapter.Loopp().Sign(context.Background(), "not an address", nil) + require.Nil(t, signed) + require.Error(t, err) + + hash, err := caigo.Curve.PedersenHash([]*big.Int{big.NewInt(42)}) + require.NoError(t, err) + r, s, err := adapter.Sign(context.Background(), starknetSenderAddr, hash) + require.NoError(t, err) + require.NotNil(t, r) + require.NotNil(t, s) + + pubx, puby, err := caigo.Curve.PrivateToPoint(starknetPK) + require.NoError(t, err) + require.True(t, caigo.Curve.Verify(hash, r, s, pubx, puby)) +} + +func generateTestKey(t *testing.T) *big.Int { + // sadly generating a key can fail, but it should happen infrequently + // best effort here to avoid flaky tests + var generatorDuration = 1 * time.Second + d, exists := t.Deadline() + if exists { + generatorDuration = time.Until(d) / 2 + } + timer := time.NewTicker(generatorDuration) + defer timer.Stop() + var key *big.Int + var generationErr error + + generated := func() bool { + select { + case <-timer.C: + key = nil + generationErr = fmt.Errorf("failed to generate test key in allotted time") + return true + default: + key, generationErr = caigo.Curve.GetRandomPrivateKey() + if generationErr == nil { + return true + } + } + return false + } + + //nolint:all + for !generated() { + } + + require.NoError(t, generationErr) + return key +} + +var ErrSenderNoExist = errors.New("sender does not exist") diff --git a/core/services/keystore/keys/starkkey/ocr2key.go b/core/services/keystore/keys/starkkey/ocr2key.go new file mode 100644 index 00000000000..22952ddd388 --- /dev/null +++ b/core/services/keystore/keys/starkkey/ocr2key.go @@ -0,0 +1,173 @@ +package starkkey + +import ( + "bytes" + "io" + "math/big" + + "github.com/NethermindEth/juno/pkg/crypto/pedersen" + junotypes "github.com/NethermindEth/juno/pkg/types" + "github.com/pkg/errors" + + "github.com/smartcontractkit/caigo" + "github.com/smartcontractkit/libocr/offchainreporting2/chains/evmutil" + "github.com/smartcontractkit/libocr/offchainreporting2/types" +) + +var _ types.OnchainKeyring = &OCR2Key{} + +type OCR2Key struct { + Key +} + +func NewOCR2Key(material io.Reader) (*OCR2Key, error) { + k, err := GenerateKey(material) + + return &OCR2Key{k}, err +} + +func (sk *OCR2Key) PublicKey() types.OnchainPublicKey { + return PubKeyToStarkKey(sk.pub) +} + +func ReportToSigData(reportCtx types.ReportContext, report types.Report) (*big.Int, error) { + var dataArray []*big.Int + + rawReportContext := rawReportContext(reportCtx) + dataArray = append(dataArray, new(big.Int).SetBytes(rawReportContext[0][:])) + dataArray = append(dataArray, new(big.Int).SetBytes(rawReportContext[1][:])) + dataArray = append(dataArray, new(big.Int).SetBytes(rawReportContext[2][:])) + + // split report into separate felts for hashing + splitReport, err := splitReport(report) + if err != nil { + return &big.Int{}, err + } + for i := 0; i < len(splitReport); i++ { + dataArray = append(dataArray, new(big.Int).SetBytes(splitReport[i])) + } + + hash := pedersen.ArrayDigest(dataArray...) + return hash, nil +} + +func (sk *OCR2Key) Sign(reportCtx types.ReportContext, report types.Report) ([]byte, error) { + hash, err := ReportToSigData(reportCtx, report) + if err != nil { + return []byte{}, err + } + + r, s, err := caigo.Curve.Sign(hash, sk.priv) + if err != nil { + return []byte{}, err + } + + // enforce s <= N/2 to prevent signature malleability + if s.Cmp(new(big.Int).Rsh(caigo.Curve.N, 1)) > 0 { + s.Sub(caigo.Curve.N, s) + } + + // encoding: public key (32 bytes) + r (32 bytes) + s (32 bytes) + buff := bytes.NewBuffer([]byte(sk.PublicKey())) + if _, err := buff.Write(padBytes(r.Bytes(), byteLen)); err != nil { + return []byte{}, err + } + if _, err := buff.Write(padBytes(s.Bytes(), byteLen)); err != nil { + return []byte{}, err + } + + out := buff.Bytes() + if len(out) != sk.MaxSignatureLength() { + return []byte{}, errors.Errorf("unexpected signature size, got %d want %d", len(out), sk.MaxSignatureLength()) + } + return out, nil +} + +func (sk *OCR2Key) Verify(publicKey types.OnchainPublicKey, reportCtx types.ReportContext, report types.Report, signature []byte) bool { + // check valid signature length + if len(signature) != sk.MaxSignatureLength() { + return false + } + + // convert OnchainPublicKey (starkkey) into ecdsa public keys (prepend 2 or 3 to indicate +/- Y coord) + var keys [2]PublicKey + keys[0].X = new(big.Int).SetBytes(publicKey) + keys[0].Y = caigo.Curve.GetYCoordinate(keys[0].X) + + // When there is no point with the provided x-coordinate, the GetYCoordinate function returns the nil value. + if keys[0].Y == nil { + return false + } + + keys[1].X = keys[0].X + keys[1].Y = new(big.Int).Mul(keys[0].Y, big.NewInt(-1)) + + hash, err := ReportToSigData(reportCtx, report) + if err != nil { + return false + } + + r := new(big.Int).SetBytes(signature[32:64]) + s := new(big.Int).SetBytes(signature[64:]) + + // Only allow canonical signatures to avoid signature malleability. Verify s <= N/2 + if s.Cmp(new(big.Int).Rsh(caigo.Curve.N, 1)) == 1 { + return false + } + + return caigo.Curve.Verify(hash, r, s, keys[0].X, keys[0].Y) || caigo.Curve.Verify(hash, r, s, keys[1].X, keys[1].Y) +} + +func (sk *OCR2Key) MaxSignatureLength() int { + return 32 + 32 + 32 // publickey + r + s +} + +func (sk *OCR2Key) Marshal() ([]byte, error) { + return padBytes(sk.priv.Bytes(), sk.privateKeyLen()), nil +} + +func (sk *OCR2Key) privateKeyLen() int { + // https://github.com/NethermindEth/juno/blob/3e71279632d82689e5af03e26693ca5c58a2376e/pkg/crypto/weierstrass/weierstrass.go#L377 + return 32 +} + +func (sk *OCR2Key) Unmarshal(in []byte) error { + // enforce byte length + if len(in) != sk.privateKeyLen() { + return errors.Errorf("unexpected seed size, got %d want %d", len(in), sk.privateKeyLen()) + } + + sk.Key = Raw(in).Key() + return nil +} + +func splitReport(report types.Report) ([][]byte, error) { + chunkSize := junotypes.FeltLength + if len(report)%chunkSize != 0 { + return [][]byte{}, errors.New("invalid report length") + } + + // order is guaranteed by buildReport: + // observation_timestamp + // observers + // observations_len + // observations + // juels_per_fee_coin + // gas_price + slices := [][]byte{} + for i := 0; i < len(report)/chunkSize; i++ { + idx := i * chunkSize + slices = append(slices, report[idx:(idx+chunkSize)]) + } + + return slices, nil +} + +// NOTE: this should sit in the ocr2 package but that causes import cycles +func rawReportContext(repctx types.ReportContext) [3][32]byte { + rawReportContext := evmutil.RawReportContext(repctx) + // NOTE: Ensure extra_hash is 31 bytes with first byte blanked out + // libocr generates a 32 byte extraHash but we need to fit it into a felt + rawReportContext[2][0] = 0 + return rawReportContext +} diff --git a/core/services/keystore/keys/starkkey/ocr2key_test.go b/core/services/keystore/keys/starkkey/ocr2key_test.go new file mode 100644 index 00000000000..fdc953a6584 --- /dev/null +++ b/core/services/keystore/keys/starkkey/ocr2key_test.go @@ -0,0 +1,178 @@ +package starkkey + +import ( + cryptorand "crypto/rand" + "encoding/hex" + "math/big" + "testing" + + junotypes "github.com/NethermindEth/juno/pkg/types" + caigotypes "github.com/smartcontractkit/caigo/types" + + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +// msg to hash +// [ +// '0x4acf99cb25a4803916f086440c661295b105a485efdc649ac4de9536da25b', // digest +// 1, // epoch_and_round +// 1, // extra_hash +// 1, // timestamp +// '0x00010203000000000000000000000000000000000000000000000000000000', // observers +// 4, // len +// 99, // reports +// 99, +// 99, +// 99, +// 1 juels_per_fee_coin +// ] +// hash 0x1332a8dabaabef63b03438ca50760cb9f5c0292cbf015b2395e50e6157df4e3 +// --> privKey 2137244795266879235401249500471353867704187908407744160927664772020405449078 r 2898571078985034687500959842265381508927681132188252715370774777831313601543 s 1930849708769648077928186998643944706551011476358007177069185543644456022504 pubKey 1118148281956858477519852250235501663092798578871088714409528077622994994907 +// privKey 3571531812827697194985986636869245829152430835021673171507607525908246940354 r 3242770073040892094735101607173275538752888766491356946211654602282309624331 s 2150742645846855766116236144967953798077492822890095121354692808525999221887 pubKey 2445157821578193538289426656074203099996547227497157254541771705133209838679 + +func TestStarknetKeyring_TestVector(t *testing.T) { + var kr1 OCR2Key + bigKey, _ := new(big.Int).SetString("2137244795266879235401249500471353867704187908407744160927664772020405449078", 10) + feltKey := junotypes.BigToFelt(bigKey) + err := kr1.Unmarshal(feltKey.Bytes()) + require.NoError(t, err) + // kr2, err := NewOCR2Key(cryptorand.Reader) + // require.NoError(t, err) + + bytes, err := caigotypes.HexToBytes("0x004acf99cb25a4803916f086440c661295b105a485efdc649ac4de9536da25b") + require.NoError(t, err) + configDigest, err := ocrtypes.BytesToConfigDigest(bytes) + require.NoError(t, err) + + ctx := ocrtypes.ReportContext{ + ReportTimestamp: ocrtypes.ReportTimestamp{ + ConfigDigest: configDigest, + Epoch: 0, + Round: 1, + }, + ExtraHash: [32]byte{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + }, + } + + var report []byte + report = append(report, junotypes.BigToFelt(big.NewInt(1)).Bytes()...) + report = append(report, junotypes.HexToFelt("0x00010203000000000000000000000000000000000000000000000000000000").Bytes()...) + report = append(report, junotypes.BigToFelt(big.NewInt(4)).Bytes()...) + report = append(report, junotypes.BigToFelt(big.NewInt(99)).Bytes()...) + report = append(report, junotypes.BigToFelt(big.NewInt(99)).Bytes()...) + report = append(report, junotypes.BigToFelt(big.NewInt(99)).Bytes()...) + report = append(report, junotypes.BigToFelt(big.NewInt(99)).Bytes()...) + report = append(report, junotypes.BigToFelt(big.NewInt(1)).Bytes()...) + + // check that report hash matches expected + msg, err := ReportToSigData(ctx, report) + require.NoError(t, err) + + expected, err := caigotypes.HexToBytes("0x1332a8dabaabef63b03438ca50760cb9f5c0292cbf015b2395e50e6157df4e3") + require.NoError(t, err) + assert.Equal(t, expected, msg.Bytes()) + + // check that signature matches expected + sig, err := kr1.Sign(ctx, report) + require.NoError(t, err) + + pub := junotypes.BytesToFelt(sig[0:32]) + r := junotypes.BytesToFelt(sig[32:64]) + s := junotypes.BytesToFelt(sig[64:]) + + bigPubExpected, _ := new(big.Int).SetString("1118148281956858477519852250235501663092798578871088714409528077622994994907", 10) + feltPubExpected := junotypes.BigToFelt(bigPubExpected) + assert.Equal(t, feltPubExpected, pub) + + bigRExpected, _ := new(big.Int).SetString("2898571078985034687500959842265381508927681132188252715370774777831313601543", 10) + feltRExpected := junotypes.BigToFelt(bigRExpected) + assert.Equal(t, feltRExpected, r) + + // test for malleability + otherS, _ := new(big.Int).SetString("1930849708769648077928186998643944706551011476358007177069185543644456022504", 10) + bigSExpected, _ := new(big.Int).SetString("1687653079896483135769135784451125398975732275358080312084893914240056843079", 10) + + feltSExpected := junotypes.BigToFelt(bigSExpected) + assert.NotEqual(t, otherS, s, "signature not in canonical form") + assert.Equal(t, feltSExpected, s) +} + +func TestStarknetKeyring_Sign_Verify(t *testing.T) { + kr1, err := NewOCR2Key(cryptorand.Reader) + require.NoError(t, err) + kr2, err := NewOCR2Key(cryptorand.Reader) + require.NoError(t, err) + + digest := "00044e5d4f35325e464c87374b13c512f60e09d1236dd902f4bef4c9aedd7300" + bytes, err := hex.DecodeString(digest) + require.NoError(t, err) + configDigest, err := ocrtypes.BytesToConfigDigest(bytes) + require.NoError(t, err) + + ctx := ocrtypes.ReportContext{ + ReportTimestamp: ocrtypes.ReportTimestamp{ + ConfigDigest: configDigest, + Epoch: 1, + Round: 1, + }, + ExtraHash: [32]byte{ + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + }, + } + report := ocrtypes.Report{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 91, 43, 83, // observations_timestamp + 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // observers + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, // len + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 150, 2, 210, // observation 1 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 150, 2, 211, // observation 2 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 224, 182, 179, 167, 100, 0, 0, // juels per fee coin (1 with 18 decimal places) + } + + t.Run("can verify", func(t *testing.T) { + sig, err := kr1.Sign(ctx, report) + require.NoError(t, err) + result := kr2.Verify(kr1.PublicKey(), ctx, report, sig) + require.True(t, result) + }) + + t.Run("invalid sig", func(t *testing.T) { + result := kr2.Verify(kr1.PublicKey(), ctx, report, []byte{0x01}) + require.False(t, result) + + longSig := [100]byte{} + result = kr2.Verify(kr1.PublicKey(), ctx, report, longSig[:]) + require.False(t, result) + }) + + t.Run("invalid pubkey", func(t *testing.T) { + sig, err := kr1.Sign(ctx, report) + require.NoError(t, err) + + pk := []byte{0x01} + result := kr2.Verify(pk, ctx, report, sig) + require.False(t, result) + + pk = big.NewInt(int64(31337)).Bytes() + result = kr2.Verify(pk, ctx, report, sig) + require.False(t, result) + }) +} + +func TestStarknetKeyring_Marshal(t *testing.T) { + kr1, err := NewOCR2Key(cryptorand.Reader) + require.NoError(t, err) + m, err := kr1.Marshal() + require.NoError(t, err) + kr2 := OCR2Key{} + err = kr2.Unmarshal(m) + require.NoError(t, err) + assert.True(t, kr1.priv.Cmp(kr2.priv) == 0) + + // Invalid seed size should error + require.Error(t, kr2.Unmarshal([]byte{0x01})) +} diff --git a/core/services/keystore/keys/starkkey/utils.go b/core/services/keystore/keys/starkkey/utils.go new file mode 100644 index 00000000000..9f6d1f4dc32 --- /dev/null +++ b/core/services/keystore/keys/starkkey/utils.go @@ -0,0 +1,58 @@ +package starkkey + +import ( + "crypto/rand" + "fmt" + "io" + "math/big" + + "github.com/NethermindEth/juno/pkg/crypto/pedersen" + "github.com/smartcontractkit/caigo" +) + +// constants +var ( + byteLen = 32 +) + +// PubKeyToContract implements the pubkey to deployed account given contract hash + salt +func PubKeyToAccount(pubkey PublicKey, classHash, salt *big.Int) []byte { + hash := pedersen.ArrayDigest( + new(big.Int).SetBytes([]byte("STARKNET_CONTRACT_ADDRESS")), + big.NewInt(0), + salt, // salt + classHash, // classHash + pedersen.ArrayDigest(pubkey.X), + ) + + // pad big.Int to 32 bytes if needed + return padBytes(hash.Bytes(), byteLen) +} + +// PubToStarkKey implements the pubkey to starkkey functionality: https://github.com/0xs34n/starknet.js/blob/cd61356974d355aa42f07a3d63f7ccefecbd913c/src/utils/ellipticCurve.ts#L49 +func PubKeyToStarkKey(pubkey PublicKey) []byte { + return padBytes(pubkey.X.Bytes(), byteLen) +} + +// reimplements parts of https://github.com/smartcontractkit/caigo/blob/main/utils.go#L85 +// generate the PK as a pseudo-random number in the interval [1, CurveOrder - 1] +// using io.Reader, and Key struct +func GenerateKey(material io.Reader) (k Key, err error) { + max := new(big.Int).Sub(caigo.Curve.N, big.NewInt(1)) + + k.priv, err = rand.Int(material, max) + if err != nil { + return k, err + } + + k.pub.X, k.pub.Y, err = caigo.Curve.PrivateToPoint(k.priv) + if err != nil { + return k, err + } + + if !caigo.Curve.IsOnCurve(k.pub.X, k.pub.Y) { + return k, fmt.Errorf("key gen is not on stark curve") + } + + return k, nil +} diff --git a/core/services/keystore/master.go b/core/services/keystore/master.go index e9952e8fa4c..ab25715af5b 100644 --- a/core/services/keystore/master.go +++ b/core/services/keystore/master.go @@ -6,22 +6,21 @@ import ( "reflect" "sync" - starkkey "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/keys" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/cosmoskey" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/dkgencryptkey" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/dkgsignkey" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/solkey" - "github.com/pkg/errors" "github.com/smartcontractkit/sqlx" "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/cosmoskey" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/csakey" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/dkgencryptkey" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/dkgsignkey" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocrkey" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/solkey" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/starkkey" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/vrfkey" "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/utils" diff --git a/core/services/keystore/mocks/starknet.go b/core/services/keystore/mocks/starknet.go deleted file mode 100644 index 20f847c6007..00000000000 --- a/core/services/keystore/mocks/starknet.go +++ /dev/null @@ -1,205 +0,0 @@ -// Code generated by mockery v2.28.1. DO NOT EDIT. - -package mocks - -import ( - keys "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/keys" - - mock "github.com/stretchr/testify/mock" -) - -// StarkNet is an autogenerated mock type for the StarkNet type -type StarkNet struct { - mock.Mock -} - -// Add provides a mock function with given fields: key -func (_m *StarkNet) Add(key keys.Key) error { - ret := _m.Called(key) - - var r0 error - if rf, ok := ret.Get(0).(func(keys.Key) error); ok { - r0 = rf(key) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// Create provides a mock function with given fields: -func (_m *StarkNet) Create() (keys.Key, error) { - ret := _m.Called() - - var r0 keys.Key - var r1 error - if rf, ok := ret.Get(0).(func() (keys.Key, error)); ok { - return rf() - } - if rf, ok := ret.Get(0).(func() keys.Key); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(keys.Key) - } - - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Delete provides a mock function with given fields: id -func (_m *StarkNet) Delete(id string) (keys.Key, error) { - ret := _m.Called(id) - - var r0 keys.Key - var r1 error - if rf, ok := ret.Get(0).(func(string) (keys.Key, error)); ok { - return rf(id) - } - if rf, ok := ret.Get(0).(func(string) keys.Key); ok { - r0 = rf(id) - } else { - r0 = ret.Get(0).(keys.Key) - } - - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(id) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// EnsureKey provides a mock function with given fields: -func (_m *StarkNet) EnsureKey() error { - ret := _m.Called() - - var r0 error - if rf, ok := ret.Get(0).(func() error); ok { - r0 = rf() - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// Export provides a mock function with given fields: id, password -func (_m *StarkNet) Export(id string, password string) ([]byte, error) { - ret := _m.Called(id, password) - - var r0 []byte - var r1 error - if rf, ok := ret.Get(0).(func(string, string) ([]byte, error)); ok { - return rf(id, password) - } - if rf, ok := ret.Get(0).(func(string, string) []byte); ok { - r0 = rf(id, password) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]byte) - } - } - - if rf, ok := ret.Get(1).(func(string, string) error); ok { - r1 = rf(id, password) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Get provides a mock function with given fields: id -func (_m *StarkNet) Get(id string) (keys.Key, error) { - ret := _m.Called(id) - - var r0 keys.Key - var r1 error - if rf, ok := ret.Get(0).(func(string) (keys.Key, error)); ok { - return rf(id) - } - if rf, ok := ret.Get(0).(func(string) keys.Key); ok { - r0 = rf(id) - } else { - r0 = ret.Get(0).(keys.Key) - } - - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(id) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// GetAll provides a mock function with given fields: -func (_m *StarkNet) GetAll() ([]keys.Key, error) { - ret := _m.Called() - - var r0 []keys.Key - var r1 error - if rf, ok := ret.Get(0).(func() ([]keys.Key, error)); ok { - return rf() - } - if rf, ok := ret.Get(0).(func() []keys.Key); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]keys.Key) - } - } - - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Import provides a mock function with given fields: keyJSON, password -func (_m *StarkNet) Import(keyJSON []byte, password string) (keys.Key, error) { - ret := _m.Called(keyJSON, password) - - var r0 keys.Key - var r1 error - if rf, ok := ret.Get(0).(func([]byte, string) (keys.Key, error)); ok { - return rf(keyJSON, password) - } - if rf, ok := ret.Get(0).(func([]byte, string) keys.Key); ok { - r0 = rf(keyJSON, password) - } else { - r0 = ret.Get(0).(keys.Key) - } - - if rf, ok := ret.Get(1).(func([]byte, string) error); ok { - r1 = rf(keyJSON, password) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -type mockConstructorTestingTNewStarkNet interface { - mock.TestingT - Cleanup(func()) -} - -// NewStarkNet creates a new instance of StarkNet. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewStarkNet(t mockConstructorTestingTNewStarkNet) *StarkNet { - mock := &StarkNet{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/core/services/keystore/models.go b/core/services/keystore/models.go index 1e113ecd595..ad3a6cd0c42 100644 --- a/core/services/keystore/models.go +++ b/core/services/keystore/models.go @@ -6,23 +6,21 @@ import ( "math/big" "time" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/cosmoskey" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/dkgencryptkey" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/dkgsignkey" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/solkey" - gethkeystore "github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" - starkkey "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/keys" - "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/cosmoskey" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/csakey" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/dkgencryptkey" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/dkgsignkey" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocrkey" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/solkey" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/starkkey" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/vrfkey" "github.com/smartcontractkit/chainlink/v2/core/utils" ) diff --git a/core/services/keystore/starknet.go b/core/services/keystore/starknet.go index 11b11fb11db..3fa87afc9c5 100644 --- a/core/services/keystore/starknet.go +++ b/core/services/keystore/starknet.go @@ -5,20 +5,16 @@ import ( "github.com/pkg/errors" - stark "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/keys" - "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/starkkey" ) -//go:generate mockery --quiet --name StarkNet --output ./mocks/ --case=underscore --filename starknet.go - type StarkNet interface { - Get(id string) (stark.Key, error) - GetAll() ([]stark.Key, error) - Create() (stark.Key, error) - Add(key stark.Key) error - Delete(id string) (stark.Key, error) - Import(keyJSON []byte, password string) (stark.Key, error) + Get(id string) (starkkey.Key, error) + GetAll() ([]starkkey.Key, error) + Create() (starkkey.Key, error) + Add(key starkkey.Key) error + Delete(id string) (starkkey.Key, error) + Import(keyJSON []byte, password string) (starkkey.Key, error) Export(id string, password string) ([]byte, error) EnsureKey() error } @@ -35,16 +31,16 @@ func newStarkNetKeyStore(km *keyManager) *starknet { } } -func (ks *starknet) Get(id string) (stark.Key, error) { +func (ks *starknet) Get(id string) (starkkey.Key, error) { ks.lock.RLock() defer ks.lock.RUnlock() if ks.isLocked() { - return stark.Key{}, ErrLocked + return starkkey.Key{}, ErrLocked } return ks.getByID(id) } -func (ks *starknet) GetAll() (keys []stark.Key, _ error) { +func (ks *starknet) GetAll() (keys []starkkey.Key, _ error) { ks.lock.RLock() defer ks.lock.RUnlock() if ks.isLocked() { @@ -56,20 +52,20 @@ func (ks *starknet) GetAll() (keys []stark.Key, _ error) { return keys, nil } -func (ks *starknet) Create() (stark.Key, error) { +func (ks *starknet) Create() (starkkey.Key, error) { ks.lock.Lock() defer ks.lock.Unlock() if ks.isLocked() { - return stark.Key{}, ErrLocked + return starkkey.Key{}, ErrLocked } - key, err := stark.New() + key, err := starkkey.New() if err != nil { - return stark.Key{}, err + return starkkey.Key{}, err } return key, ks.safeAddKey(key) } -func (ks *starknet) Add(key stark.Key) error { +func (ks *starknet) Add(key starkkey.Key) error { ks.lock.Lock() defer ks.lock.Unlock() if ks.isLocked() { @@ -81,32 +77,32 @@ func (ks *starknet) Add(key stark.Key) error { return ks.safeAddKey(key) } -func (ks *starknet) Delete(id string) (stark.Key, error) { +func (ks *starknet) Delete(id string) (starkkey.Key, error) { ks.lock.Lock() defer ks.lock.Unlock() if ks.isLocked() { - return stark.Key{}, ErrLocked + return starkkey.Key{}, ErrLocked } key, err := ks.getByID(id) if err != nil { - return stark.Key{}, err + return starkkey.Key{}, err } err = ks.safeRemoveKey(key) return key, err } -func (ks *starknet) Import(keyJSON []byte, password string) (stark.Key, error) { +func (ks *starknet) Import(keyJSON []byte, password string) (starkkey.Key, error) { ks.lock.Lock() defer ks.lock.Unlock() if ks.isLocked() { - return stark.Key{}, ErrLocked + return starkkey.Key{}, ErrLocked } key, err := starkkey.FromEncryptedJSON(keyJSON, password) if err != nil { - return stark.Key{}, errors.Wrap(err, "StarkNetKeyStore#ImportKey failed to decrypt key") + return starkkey.Key{}, errors.Wrap(err, "StarkNetKeyStore#ImportKey failed to decrypt key") } if _, found := ks.keyRing.StarkNet[key.ID()]; found { - return stark.Key{}, fmt.Errorf("key with ID %s already exists", key.ID()) + return starkkey.Key{}, fmt.Errorf("key with ID %s already exists", key.ID()) } return key, ks.keyManager.safeAddKey(key) } @@ -134,7 +130,7 @@ func (ks *starknet) EnsureKey() error { return nil } - key, err := stark.New() + key, err := starkkey.New() if err != nil { return err } @@ -144,10 +140,10 @@ func (ks *starknet) EnsureKey() error { return ks.safeAddKey(key) } -func (ks *starknet) getByID(id string) (stark.Key, error) { +func (ks *starknet) getByID(id string) (starkkey.Key, error) { key, found := ks.keyRing.StarkNet[id] if !found { - return stark.Key{}, KeyNotFoundError{ID: id, KeyType: "StarkNet"} + return starkkey.Key{}, KeyNotFoundError{ID: id, KeyType: "StarkNet"} } return key, nil } diff --git a/core/services/keystore/starknet_test.go b/core/services/keystore/starknet_test.go index a8cde30d25d..63f599d21a4 100644 --- a/core/services/keystore/starknet_test.go +++ b/core/services/keystore/starknet_test.go @@ -6,11 +6,11 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - starkkey "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/keys" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" configtest "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest/v2" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/starkkey" "github.com/smartcontractkit/chainlink/v2/core/utils" ) diff --git a/core/web/presenters/starknet_key.go b/core/web/presenters/starknet_key.go index 788e56cf701..1ac98de87e2 100644 --- a/core/web/presenters/starknet_key.go +++ b/core/web/presenters/starknet_key.go @@ -1,7 +1,7 @@ package presenters import ( - starknet "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/keys" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/starkkey" ) // StarkNetKeyResource represents a StarkNet key JSONAPI resource. @@ -15,7 +15,7 @@ func (StarkNetKeyResource) GetName() string { return "encryptedStarkNetKeys" } -func NewStarkNetKeyResource(key starknet.Key) *StarkNetKeyResource { +func NewStarkNetKeyResource(key starkkey.Key) *StarkNetKeyResource { r := &StarkNetKeyResource{ JAID: JAID{ID: key.ID()}, StarkKey: key.StarkKeyStr(), @@ -24,7 +24,7 @@ func NewStarkNetKeyResource(key starknet.Key) *StarkNetKeyResource { return r } -func NewStarkNetKeyResources(keys []starknet.Key) []StarkNetKeyResource { +func NewStarkNetKeyResources(keys []starkkey.Key) []StarkNetKeyResource { rs := []StarkNetKeyResource{} for _, key := range keys { rs = append(rs, *NewStarkNetKeyResource(key)) diff --git a/core/web/starknet_keys_controller.go b/core/web/starknet_keys_controller.go index bbdc60d73c0..a7968e165b7 100644 --- a/core/web/starknet_keys_controller.go +++ b/core/web/starknet_keys_controller.go @@ -1,9 +1,8 @@ package web import ( - starkkey "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/keys" - "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/starkkey" "github.com/smartcontractkit/chainlink/v2/core/web/presenters" ) diff --git a/go.mod b/go.mod index 8200b49d8f7..39906d06ab4 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/Depado/ginprom v1.7.11 github.com/Masterminds/semver/v3 v3.2.1 github.com/Masterminds/sprig/v3 v3.2.3 + github.com/NethermindEth/juno v0.0.0-20220630151419-cbd368b222ac github.com/avast/retry-go/v4 v4.3.4 github.com/btcsuite/btcd v0.23.4 github.com/cosmos/cosmos-sdk v0.45.11 @@ -63,10 +64,11 @@ require ( github.com/scylladb/go-reflectx v1.0.1 github.com/shirou/gopsutil/v3 v3.22.12 github.com/shopspring/decimal v1.3.1 + github.com/smartcontractkit/caigo v0.0.0-20230526231506-786d4587099a github.com/smartcontractkit/chainlink-cosmos v0.4.0 - github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230526232037-00743d25b7ec + github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230530222821-30d787a10087 github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230518143827-0b7a6e43719c - github.com/smartcontractkit/chainlink-starknet/relayer v0.0.0-20230522061116-665c91c3d1fa + github.com/smartcontractkit/chainlink-starknet/relayer v0.0.0-20230530233948-90c8af98011e github.com/smartcontractkit/libocr v0.0.0-20230503222226-29f534b2de1a github.com/smartcontractkit/ocr2keepers v0.6.15 github.com/smartcontractkit/ocr2vrf v0.0.0-20230510102715-c58be582bf19 @@ -111,7 +113,6 @@ require ( github.com/DataDog/zstd v1.5.2 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect - github.com/NethermindEth/juno v0.0.0-20220630151419-cbd368b222ac // indirect github.com/VictoriaMetrics/fastcache v1.10.0 // indirect github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 // indirect github.com/armon/go-metrics v0.4.1 // indirect @@ -306,7 +307,6 @@ require ( github.com/sasha-s/go-deadlock v0.3.1 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/sirupsen/logrus v1.9.0 // indirect - github.com/smartcontractkit/caigo v0.0.0-20230508053235-41120ca1f9f3 // indirect github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/spf13/afero v1.9.2 // indirect diff --git a/go.sum b/go.sum index a506f140559..71a8fc90042 100644 --- a/go.sum +++ b/go.sum @@ -1379,16 +1379,16 @@ github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/smartcontractkit/caigo v0.0.0-20230508053235-41120ca1f9f3 h1:6RsuA0LBbC/6DgTYzg659Pw7GKktubj1GzTcB/VNC44= -github.com/smartcontractkit/caigo v0.0.0-20230508053235-41120ca1f9f3/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= +github.com/smartcontractkit/caigo v0.0.0-20230526231506-786d4587099a h1:B0WjTVtPW+GNY90rpmiwD/8tf3xr4jFC60sjuznNtRs= +github.com/smartcontractkit/caigo v0.0.0-20230526231506-786d4587099a/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= github.com/smartcontractkit/chainlink-cosmos v0.4.0 h1:xYLAcJJIm0cyMtYtMaosO45bykEwcwQOmZz3mz46Y2A= github.com/smartcontractkit/chainlink-cosmos v0.4.0/go.mod h1:938jBqOrhdCq4A8enUiBliiDLBndAXebHIitKsDVqY0= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230526232037-00743d25b7ec h1:ZG/N6BvjAKh6SkAHSYZ7el9WU6prCf0WsvcFjWJd0uU= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230526232037-00743d25b7ec/go.mod h1:f7/HKcJWWFzINrkDDlpKsFaU6D+8D4B4OrQxkkCX4oc= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230530222821-30d787a10087 h1:Xq3iwi8Vn+5uZb6RtKOn43GbSWLW7ij6S8Nn8JZ8vsg= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230530222821-30d787a10087/go.mod h1:f7/HKcJWWFzINrkDDlpKsFaU6D+8D4B4OrQxkkCX4oc= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230518143827-0b7a6e43719c h1:pM7FH+S92F7Xa/VSfbIs941FDKqSmo9pYeUBWHl1Pq0= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230518143827-0b7a6e43719c/go.mod h1:CUmP50gxZsjwEYA7balCV3mhvX0CrR/a01X6jGBZR8I= -github.com/smartcontractkit/chainlink-starknet/relayer v0.0.0-20230522061116-665c91c3d1fa h1:WWCXWDUAiKiEuDpOTvSukEDzOpOF73x/9nFrnFyf8rA= -github.com/smartcontractkit/chainlink-starknet/relayer v0.0.0-20230522061116-665c91c3d1fa/go.mod h1:bwWxlWboUoG99segq2uS80r+q4VPBPE0I/CztPBCMuY= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.0-20230530233948-90c8af98011e h1:0g2/8OSVFxbGQ2L7FTDo29t90ItOf+1CI2zOn3DBwHM= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.0-20230530233948-90c8af98011e/go.mod h1:m43fLfOPrJK+cLDyhoCn9wY7hPWZzW1Ywu1rqZQ2Xhk= github.com/smartcontractkit/libocr v0.0.0-20230503222226-29f534b2de1a h1:NFTlIAjSwx9vBYZeUerd0DDsvg+zZ5TSESw4dPNdwJk= github.com/smartcontractkit/libocr v0.0.0-20230503222226-29f534b2de1a/go.mod h1:5JnCHuYgmIP9ZyXzgAfI5Iwu0WxBtBKp+ApeT5o1Cjw= github.com/smartcontractkit/ocr2keepers v0.6.15 h1:dFhg+qT+tc6b3G8N4qnAHuHe8N0m8CSA8g4YGSeTGPo= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index d7a5e58973d..1de9cc042f7 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -281,9 +281,8 @@ require ( github.com/shirou/gopsutil/v3 v3.22.12 // indirect github.com/shopspring/decimal v1.3.1 // indirect github.com/sirupsen/logrus v1.9.0 // indirect - github.com/smartcontractkit/caigo v0.0.0-20230508053235-41120ca1f9f3 // indirect - github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230526232037-00743d25b7ec // indirect - github.com/smartcontractkit/chainlink-starknet/relayer v0.0.0-20230522061116-665c91c3d1fa // indirect + github.com/smartcontractkit/caigo v0.0.0-20230526231506-786d4587099a // indirect + github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230530222821-30d787a10087 // indirect github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb // indirect github.com/smartcontractkit/wsrpc v0.7.2 // indirect github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index fe9375b95be..4aa025b8a4a 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1338,16 +1338,15 @@ github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0 github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/slack-go/slack v0.12.2 h1:x3OppyMyGIbbiyFhsBmpf9pwkUzMhthJMRNmNlA4LaQ= github.com/slack-go/slack v0.12.2/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= -github.com/smartcontractkit/caigo v0.0.0-20230508053235-41120ca1f9f3 h1:6RsuA0LBbC/6DgTYzg659Pw7GKktubj1GzTcB/VNC44= -github.com/smartcontractkit/caigo v0.0.0-20230508053235-41120ca1f9f3/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= +github.com/smartcontractkit/caigo v0.0.0-20230526231506-786d4587099a h1:B0WjTVtPW+GNY90rpmiwD/8tf3xr4jFC60sjuznNtRs= +github.com/smartcontractkit/caigo v0.0.0-20230526231506-786d4587099a/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= github.com/smartcontractkit/chainlink-cosmos v0.4.0 h1:xYLAcJJIm0cyMtYtMaosO45bykEwcwQOmZz3mz46Y2A= github.com/smartcontractkit/chainlink-env v0.32.5 h1:xwlaie96Q+BO//Wl4DHyzwktgLg/62j/JiX12hUSV0A= github.com/smartcontractkit/chainlink-env v0.32.5/go.mod h1:9c0Czq4a6wZKY20BcoAlK29DnejQIiLo/MwKYtSFnHk= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230526232037-00743d25b7ec h1:ZG/N6BvjAKh6SkAHSYZ7el9WU6prCf0WsvcFjWJd0uU= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230526232037-00743d25b7ec/go.mod h1:f7/HKcJWWFzINrkDDlpKsFaU6D+8D4B4OrQxkkCX4oc= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230530222821-30d787a10087 h1:Xq3iwi8Vn+5uZb6RtKOn43GbSWLW7ij6S8Nn8JZ8vsg= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230530222821-30d787a10087/go.mod h1:f7/HKcJWWFzINrkDDlpKsFaU6D+8D4B4OrQxkkCX4oc= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230518143827-0b7a6e43719c h1:pM7FH+S92F7Xa/VSfbIs941FDKqSmo9pYeUBWHl1Pq0= -github.com/smartcontractkit/chainlink-starknet/relayer v0.0.0-20230522061116-665c91c3d1fa h1:WWCXWDUAiKiEuDpOTvSukEDzOpOF73x/9nFrnFyf8rA= -github.com/smartcontractkit/chainlink-starknet/relayer v0.0.0-20230522061116-665c91c3d1fa/go.mod h1:bwWxlWboUoG99segq2uS80r+q4VPBPE0I/CztPBCMuY= +github.com/smartcontractkit/chainlink-starknet/relayer v0.0.0-20230530233948-90c8af98011e h1:0g2/8OSVFxbGQ2L7FTDo29t90ItOf+1CI2zOn3DBwHM= github.com/smartcontractkit/chainlink-testing-framework v1.11.6 h1:W5BfxVDRWZ/PepyMUyJqR8w8XcnFbP4aZqL+ha+DiaA= github.com/smartcontractkit/chainlink-testing-framework v1.11.6/go.mod h1:76JD6PEhH9QActeOUKfPjm/4Cfyn+cpp3u0ASoq0RpU= github.com/smartcontractkit/libocr v0.0.0-20230503222226-29f534b2de1a h1:NFTlIAjSwx9vBYZeUerd0DDsvg+zZ5TSESw4dPNdwJk=