Skip to content

Commit

Permalink
feat(pip): implement PIP-23 (#1397)
Browse files Browse the repository at this point in the history
  • Loading branch information
ZigBalthazar authored Jul 12, 2024
1 parent 6318fad commit 50b5eb5
Show file tree
Hide file tree
Showing 48 changed files with 10,598 additions and 131 deletions.
9 changes: 9 additions & 0 deletions wallet/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,3 +191,12 @@ func (wm *Manager) AddressHistory(

return wlt.GetHistory(address), nil
}

func (wm *Manager) SignMessage(walletName, password, addr, msg string) (string, error) {
wlt, ok := wm.wallets[walletName]
if !ok {
return "", status.Errorf(codes.NotFound, "wallet is not loaded")
}

return wlt.SignMessage(password, addr, msg)
}
9 changes: 9 additions & 0 deletions wallet/wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -476,3 +476,12 @@ func (w *Wallet) AddTransaction(id tx.ID) error {
func (w *Wallet) GetHistory(addr string) []HistoryInfo {
return w.store.History.getAddrHistory(addr)
}

func (w *Wallet) SignMessage(password, addr, msg string) (string, error) {
prv, err := w.PrivateKey(password, addr)
if err != nil {
return "", err
}

return prv.Sign([]byte(msg)).String(), nil
}
20 changes: 20 additions & 0 deletions wallet/wallet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"testing"

"github.com/pactus-project/pactus/crypto"
"github.com/pactus-project/pactus/crypto/bls"
"github.com/pactus-project/pactus/genesis"
"github.com/pactus-project/pactus/state"
"github.com/pactus-project/pactus/types/account"
Expand All @@ -15,6 +16,7 @@ import (
"github.com/pactus-project/pactus/wallet"
"github.com/pactus-project/pactus/www/grpc"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

type testData struct {
Expand Down Expand Up @@ -178,6 +180,24 @@ func TestImportPrivateKey(t *testing.T) {
assert.Equal(t, pub.String(), valAddrInfo.PublicKey)
}

func TestSignMessage(t *testing.T) {
td := setup(t)
defer td.Close()

msg := "pactus"
expectedSig := "923d67a8624cbb7972b29328e15ec76cc846076ccf00a9e94d991c677846f334ae4ba4551396fbcd6d1cab7593baf3b7"
prv, err := bls.PrivateKeyFromString("SECRET1PDRWTLP5PX0FAHDX39GXZJP7FKZFALML0D5U9TT9KVQHDUC99CMGQQJVK67")

require.NoError(t, err)

err = td.wallet.ImportPrivateKey(td.password, prv)
assert.NoError(t, err)

sig, err := td.wallet.SignMessage(td.password, td.wallet.AllAccountAddresses()[0].Address, msg)
assert.NoError(t, err)
assert.Equal(t, sig, expectedSig)
}

func TestKeyInfo(t *testing.T) {
td := setup(t)
defer td.Close()
Expand Down
10 changes: 10 additions & 0 deletions www/grpc/buf/grpc-gateway.config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,13 @@ http:

- selector: pactus.Wallet.GetTotalBalance
get: "/pactus/wallet/get_total_balance"

- selector: pactus.Wallet.SignMessage
get: "/pactus/wallet/sign_message"

# Util APIs
- selector: pactus.Utils.SignMessageWithPrivateKey
get: "/pactus/Utils/sign_message_with_private_key"

- selector: pactus.Utils.VerifyMessage
get: "/pactus/Utils/verify_message"
4 changes: 4 additions & 0 deletions www/grpc/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ func (s *Server) startGateway(grpcAddr string) error {
if err != nil {
return err
}
err = pactus.RegisterUtilsHandler(s.ctx, gwMux, conn)
if err != nil {
return err
}

oa, err := s.getOpenAPIHandler()
if err != nil {
Expand Down
256 changes: 256 additions & 0 deletions www/grpc/gen/dart/utils.pb.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
///
// Generated code. Do not modify.
// source: utils.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name

import 'dart:async' as $async;
import 'dart:core' as $core;

import 'package:protobuf/protobuf.dart' as $pb;

class SignMessageWithPrivateKeyRequest extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SignMessageWithPrivateKeyRequest', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'pactus'), createEmptyInstance: create)
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'privateKey')
..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'message')
..hasRequiredFields = false
;

SignMessageWithPrivateKeyRequest._() : super();
factory SignMessageWithPrivateKeyRequest({
$core.String? privateKey,
$core.String? message,
}) {
final _result = create();
if (privateKey != null) {
_result.privateKey = privateKey;
}
if (message != null) {
_result.message = message;
}
return _result;
}
factory SignMessageWithPrivateKeyRequest.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory SignMessageWithPrivateKeyRequest.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
SignMessageWithPrivateKeyRequest clone() => SignMessageWithPrivateKeyRequest()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
SignMessageWithPrivateKeyRequest copyWith(void Function(SignMessageWithPrivateKeyRequest) updates) => super.copyWith((message) => updates(message as SignMessageWithPrivateKeyRequest)) as SignMessageWithPrivateKeyRequest; // ignore: deprecated_member_use
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static SignMessageWithPrivateKeyRequest create() => SignMessageWithPrivateKeyRequest._();
SignMessageWithPrivateKeyRequest createEmptyInstance() => create();
static $pb.PbList<SignMessageWithPrivateKeyRequest> createRepeated() => $pb.PbList<SignMessageWithPrivateKeyRequest>();
@$core.pragma('dart2js:noInline')
static SignMessageWithPrivateKeyRequest getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<SignMessageWithPrivateKeyRequest>(create);
static SignMessageWithPrivateKeyRequest? _defaultInstance;

@$pb.TagNumber(1)
$core.String get privateKey => $_getSZ(0);
@$pb.TagNumber(1)
set privateKey($core.String v) { $_setString(0, v); }
@$pb.TagNumber(1)
$core.bool hasPrivateKey() => $_has(0);
@$pb.TagNumber(1)
void clearPrivateKey() => clearField(1);

@$pb.TagNumber(2)
$core.String get message => $_getSZ(1);
@$pb.TagNumber(2)
set message($core.String v) { $_setString(1, v); }
@$pb.TagNumber(2)
$core.bool hasMessage() => $_has(1);
@$pb.TagNumber(2)
void clearMessage() => clearField(2);
}

class SignMessageWithPrivateKeyResponse extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SignMessageWithPrivateKeyResponse', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'pactus'), createEmptyInstance: create)
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'signature')
..hasRequiredFields = false
;

SignMessageWithPrivateKeyResponse._() : super();
factory SignMessageWithPrivateKeyResponse({
$core.String? signature,
}) {
final _result = create();
if (signature != null) {
_result.signature = signature;
}
return _result;
}
factory SignMessageWithPrivateKeyResponse.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory SignMessageWithPrivateKeyResponse.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
SignMessageWithPrivateKeyResponse clone() => SignMessageWithPrivateKeyResponse()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
SignMessageWithPrivateKeyResponse copyWith(void Function(SignMessageWithPrivateKeyResponse) updates) => super.copyWith((message) => updates(message as SignMessageWithPrivateKeyResponse)) as SignMessageWithPrivateKeyResponse; // ignore: deprecated_member_use
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static SignMessageWithPrivateKeyResponse create() => SignMessageWithPrivateKeyResponse._();
SignMessageWithPrivateKeyResponse createEmptyInstance() => create();
static $pb.PbList<SignMessageWithPrivateKeyResponse> createRepeated() => $pb.PbList<SignMessageWithPrivateKeyResponse>();
@$core.pragma('dart2js:noInline')
static SignMessageWithPrivateKeyResponse getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<SignMessageWithPrivateKeyResponse>(create);
static SignMessageWithPrivateKeyResponse? _defaultInstance;

@$pb.TagNumber(1)
$core.String get signature => $_getSZ(0);
@$pb.TagNumber(1)
set signature($core.String v) { $_setString(0, v); }
@$pb.TagNumber(1)
$core.bool hasSignature() => $_has(0);
@$pb.TagNumber(1)
void clearSignature() => clearField(1);
}

class VerifyMessageRequest extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'VerifyMessageRequest', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'pactus'), createEmptyInstance: create)
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'message')
..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'signature')
..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'publicKey')
..hasRequiredFields = false
;

VerifyMessageRequest._() : super();
factory VerifyMessageRequest({
$core.String? message,
$core.String? signature,
$core.String? publicKey,
}) {
final _result = create();
if (message != null) {
_result.message = message;
}
if (signature != null) {
_result.signature = signature;
}
if (publicKey != null) {
_result.publicKey = publicKey;
}
return _result;
}
factory VerifyMessageRequest.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory VerifyMessageRequest.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
VerifyMessageRequest clone() => VerifyMessageRequest()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
VerifyMessageRequest copyWith(void Function(VerifyMessageRequest) updates) => super.copyWith((message) => updates(message as VerifyMessageRequest)) as VerifyMessageRequest; // ignore: deprecated_member_use
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static VerifyMessageRequest create() => VerifyMessageRequest._();
VerifyMessageRequest createEmptyInstance() => create();
static $pb.PbList<VerifyMessageRequest> createRepeated() => $pb.PbList<VerifyMessageRequest>();
@$core.pragma('dart2js:noInline')
static VerifyMessageRequest getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<VerifyMessageRequest>(create);
static VerifyMessageRequest? _defaultInstance;

@$pb.TagNumber(1)
$core.String get message => $_getSZ(0);
@$pb.TagNumber(1)
set message($core.String v) { $_setString(0, v); }
@$pb.TagNumber(1)
$core.bool hasMessage() => $_has(0);
@$pb.TagNumber(1)
void clearMessage() => clearField(1);

@$pb.TagNumber(2)
$core.String get signature => $_getSZ(1);
@$pb.TagNumber(2)
set signature($core.String v) { $_setString(1, v); }
@$pb.TagNumber(2)
$core.bool hasSignature() => $_has(1);
@$pb.TagNumber(2)
void clearSignature() => clearField(2);

@$pb.TagNumber(3)
$core.String get publicKey => $_getSZ(2);
@$pb.TagNumber(3)
set publicKey($core.String v) { $_setString(2, v); }
@$pb.TagNumber(3)
$core.bool hasPublicKey() => $_has(2);
@$pb.TagNumber(3)
void clearPublicKey() => clearField(3);
}

class VerifyMessageResponse extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'VerifyMessageResponse', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'pactus'), createEmptyInstance: create)
..aOB(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'isValid')
..hasRequiredFields = false
;

VerifyMessageResponse._() : super();
factory VerifyMessageResponse({
$core.bool? isValid,
}) {
final _result = create();
if (isValid != null) {
_result.isValid = isValid;
}
return _result;
}
factory VerifyMessageResponse.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory VerifyMessageResponse.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
VerifyMessageResponse clone() => VerifyMessageResponse()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
VerifyMessageResponse copyWith(void Function(VerifyMessageResponse) updates) => super.copyWith((message) => updates(message as VerifyMessageResponse)) as VerifyMessageResponse; // ignore: deprecated_member_use
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static VerifyMessageResponse create() => VerifyMessageResponse._();
VerifyMessageResponse createEmptyInstance() => create();
static $pb.PbList<VerifyMessageResponse> createRepeated() => $pb.PbList<VerifyMessageResponse>();
@$core.pragma('dart2js:noInline')
static VerifyMessageResponse getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<VerifyMessageResponse>(create);
static VerifyMessageResponse? _defaultInstance;

@$pb.TagNumber(1)
$core.bool get isValid => $_getBF(0);
@$pb.TagNumber(1)
set isValid($core.bool v) { $_setBool(0, v); }
@$pb.TagNumber(1)
$core.bool hasIsValid() => $_has(0);
@$pb.TagNumber(1)
void clearIsValid() => clearField(1);
}

class UtilsApi {
$pb.RpcClient _client;
UtilsApi(this._client);

$async.Future<SignMessageWithPrivateKeyResponse> signMessageWithPrivateKey($pb.ClientContext? ctx, SignMessageWithPrivateKeyRequest request) {
var emptyResponse = SignMessageWithPrivateKeyResponse();
return _client.invoke<SignMessageWithPrivateKeyResponse>(ctx, 'Utils', 'SignMessageWithPrivateKey', request, emptyResponse);
}
$async.Future<VerifyMessageResponse> verifyMessage($pb.ClientContext? ctx, VerifyMessageRequest request) {
var emptyResponse = VerifyMessageResponse();
return _client.invoke<VerifyMessageResponse>(ctx, 'Utils', 'VerifyMessage', request, emptyResponse);
}
}

7 changes: 7 additions & 0 deletions www/grpc/gen/dart/utils.pbenum.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
///
// Generated code. Do not modify.
// source: utils.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name

Loading

0 comments on commit 50b5eb5

Please sign in to comment.