diff --git a/pkg/rpcclient/unwrap/unwrap.go b/pkg/rpcclient/unwrap/unwrap.go index c31c74558..fad8bcffa 100644 --- a/pkg/rpcclient/unwrap/unwrap.go +++ b/pkg/rpcclient/unwrap/unwrap.go @@ -146,6 +146,16 @@ func Uint256(r *result.Invoke, err error) (util.Uint256, error) { return util.Uint256DecodeBytesBE(b) } +// PublicKey expects correct execution (HALT state) with a single stack item +// returned. A public key is extracted from this item and returned. +func PublicKey(r *result.Invoke, err error) (*keys.PublicKey, error) { + b, err := Bytes(r, err) + if err != nil { + return nil, err + } + return keys.NewPublicKeyFromBytes(b, elliptic.P256()) +} + // SessionIterator expects correct execution (HALT state) with a single stack // item returned. If this item is an iterator it's returned to the caller along // with the session ID. Notice that this function also returns successfully diff --git a/pkg/rpcclient/unwrap/unwrap_test.go b/pkg/rpcclient/unwrap/unwrap_test.go index 29606da5c..5544216cc 100644 --- a/pkg/rpcclient/unwrap/unwrap_test.go +++ b/pkg/rpcclient/unwrap/unwrap_test.go @@ -43,6 +43,9 @@ func TestStdErrors(t *testing.T) { func(r *result.Invoke, err error) (interface{}, error) { return Uint256(r, err) }, + func(r *result.Invoke, err error) (interface{}, error) { + return PublicKey(r, err) + }, func(r *result.Invoke, err error) (interface{}, error) { _, _, err = SessionIterator(r, err) return nil, err @@ -189,6 +192,18 @@ func TestUint256(t *testing.T) { require.Equal(t, util.Uint256{1, 2, 3}, u) } +func TestPublicKey(t *testing.T) { + k, err := keys.NewPrivateKey() + require.NoError(t, err) + + _, err = PublicKey(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make(util.Uint160{1, 2, 3}.BytesBE())}}, nil) + require.Error(t, err) + + pk, err := PublicKey(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make(k.PublicKey().Bytes())}}, nil) + require.NoError(t, err) + require.Equal(t, k.PublicKey(), pk) +} + func TestSessionIterator(t *testing.T) { _, _, err := SessionIterator(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make(42)}}, nil) require.Error(t, err)