Skip to content

Commit

Permalink
chore(gRPC): defining transaction APIs properly (#935)
Browse files Browse the repository at this point in the history
Co-authored-by: Amir Babazadeh <[email protected]>
  • Loading branch information
kehiy and amirvalhalla authored Jan 11, 2024
1 parent 93570b0 commit 3f36b3e
Show file tree
Hide file tree
Showing 21 changed files with 844 additions and 843 deletions.
4 changes: 2 additions & 2 deletions tests/transaction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import (
func sendRawTx(t *testing.T, raw []byte) error {
t.Helper()

_, err := tTransaction.SendRawTransaction(tCtx,
&pactus.SendRawTransactionRequest{Data: raw})
_, err := tTransaction.BroadcastTransaction(tCtx,
&pactus.BroadcastTransactionRequest{SignedTx: raw})
return err
}

Expand Down
4 changes: 2 additions & 2 deletions wallet/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ func (c *grpcClient) sendTx(trx *tx.Tx) (tx.ID, error) {
if err != nil {
return hash.UndefHash, err
}
res, err := c.transactionClient.SendRawTransaction(context.Background(), &pactus.SendRawTransactionRequest{
Data: data,
res, err := c.transactionClient.BroadcastTransaction(context.Background(), &pactus.BroadcastTransactionRequest{
SignedTx: data,
})
if err != nil {
return hash.UndefHash, err
Expand Down
10 changes: 5 additions & 5 deletions wallet/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,11 @@ func (s *transactionServer) CalculateFee(_ context.Context,
return &pactus.CalculateFeeResponse{Fee: 0}, nil
}

func (s *transactionServer) SendRawTransaction(_ context.Context,
req *pactus.SendRawTransactionRequest,
) (*pactus.SendRawTransactionResponse, error) {
trx, _ := tx.FromBytes(req.Data)
return &pactus.SendRawTransactionResponse{
func (s *transactionServer) BroadcastTransaction(_ context.Context,
req *pactus.BroadcastTransactionRequest,
) (*pactus.BroadcastTransactionResponse, error) {
trx, _ := tx.FromBytes(req.SignedTx)
return &pactus.BroadcastTransactionResponse{
Id: trx.ID().Bytes(),
}, nil
}
Expand Down
14 changes: 7 additions & 7 deletions www/grpc/buf/grpc-gateway.config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,23 @@ http:
- selector: pactus.Transaction.GetTransaction
get: "/v1/transactions/id/{id}/verbosity/{verbosity}"

- selector: pactus.Transaction.SendRawTransaction
put: "/v1/transactions/send/{data}"
- selector: pactus.Transaction.BroadcastTransaction
put: "/v1/transactions/broadcast/{signed_tx}"

- selector: pactus.Transaction.CalculateFee
get: "/v1/transactions/amount/{amount}/payloadType/{payloadType}"
get: "/v1/transactions/fee/amount/{amount}/payloadType/{payloadType}"

- selector: pactus.Transaction.GetRawTransferTransaction
get: "/v1/transactions/sender/{sender}/receiver/{receiver}/amount/{amount}/lock_time/{lock_time}/fee/{fee}/memo/{memo}"
get: "/v1/transactions/transfer/sender/{sender}/receiver/{receiver}/amount/{amount}/lock_time/{lock_time}/fee/{fee}/memo/{memo}"

- selector: pactus.Transaction.GetRawBondTransaction
get: "/v1/transactions/sender/{sender}/receiver/{receiver}/stake/{stake}/lock_time/{lock_time}/public_key/{public_key}/fee/{fee}/memo/{memo}"
get: "/v1/transactions/bond/sender/{sender}/receiver/{receiver}/stake/{stake}/lock_time/{lock_time}/public_key/{public_key}/fee/{fee}/memo/{memo}"

- selector: pactus.Transaction.GetRawUnBondTransaction
get: "/v1/transactions/validator_address/{validator_address}/lock_time/{lock_time}/memo/{memo}"
get: "/v1/transactions/unbond/validator_address/{validator_address}/lock_time/{lock_time}/memo/{memo}"

- selector: pactus.Transaction.GetRawWithdrawTransaction
get: "/v1/transactions/validator_address/{validator_address}/account_address/{account_address}/amount/{amount}/lock_time/{lock_time}/fee/{fee}/memo/{memo}"
get: "/v1/transactions/withdraw/validator_address/{validator_address}/account_address/{account_address}/amount/{amount}/lock_time/{lock_time}/fee/{fee}/memo/{memo}"

# Network APIs
- selector: pactus.Network.GetNetworkInfo
Expand Down
74 changes: 37 additions & 37 deletions www/grpc/gen/dart/transaction.pb.dart
Original file line number Diff line number Diff line change
Expand Up @@ -261,61 +261,61 @@ class CalculateFeeResponse extends $pb.GeneratedMessage {
void clearFee() => clearField(1);
}

class SendRawTransactionRequest extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SendRawTransactionRequest', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'pactus'), createEmptyInstance: create)
..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data', $pb.PbFieldType.OY)
class BroadcastTransactionRequest extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'BroadcastTransactionRequest', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'pactus'), createEmptyInstance: create)
..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'signedTx', $pb.PbFieldType.OY)
..hasRequiredFields = false
;

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

@$pb.TagNumber(1)
$core.List<$core.int> get data => $_getN(0);
$core.List<$core.int> get signedTx => $_getN(0);
@$pb.TagNumber(1)
set data($core.List<$core.int> v) { $_setBytes(0, v); }
set signedTx($core.List<$core.int> v) { $_setBytes(0, v); }
@$pb.TagNumber(1)
$core.bool hasData() => $_has(0);
$core.bool hasSignedTx() => $_has(0);
@$pb.TagNumber(1)
void clearData() => clearField(1);
void clearSignedTx() => clearField(1);
}

class SendRawTransactionResponse extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SendRawTransactionResponse', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'pactus'), createEmptyInstance: create)
class BroadcastTransactionResponse extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'BroadcastTransactionResponse', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'pactus'), createEmptyInstance: create)
..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id', $pb.PbFieldType.OY)
..hasRequiredFields = false
;

SendRawTransactionResponse._() : super();
factory SendRawTransactionResponse({
BroadcastTransactionResponse._() : super();
factory BroadcastTransactionResponse({
$core.List<$core.int>? id,
}) {
final _result = create();
Expand All @@ -324,26 +324,26 @@ class SendRawTransactionResponse extends $pb.GeneratedMessage {
}
return _result;
}
factory SendRawTransactionResponse.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory SendRawTransactionResponse.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
factory BroadcastTransactionResponse.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory BroadcastTransactionResponse.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')
SendRawTransactionResponse clone() => SendRawTransactionResponse()..mergeFromMessage(this);
BroadcastTransactionResponse clone() => BroadcastTransactionResponse()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
SendRawTransactionResponse copyWith(void Function(SendRawTransactionResponse) updates) => super.copyWith((message) => updates(message as SendRawTransactionResponse)) as SendRawTransactionResponse; // ignore: deprecated_member_use
BroadcastTransactionResponse copyWith(void Function(BroadcastTransactionResponse) updates) => super.copyWith((message) => updates(message as BroadcastTransactionResponse)) as BroadcastTransactionResponse; // ignore: deprecated_member_use
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static SendRawTransactionResponse create() => SendRawTransactionResponse._();
SendRawTransactionResponse createEmptyInstance() => create();
static $pb.PbList<SendRawTransactionResponse> createRepeated() => $pb.PbList<SendRawTransactionResponse>();
static BroadcastTransactionResponse create() => BroadcastTransactionResponse._();
BroadcastTransactionResponse createEmptyInstance() => create();
static $pb.PbList<BroadcastTransactionResponse> createRepeated() => $pb.PbList<BroadcastTransactionResponse>();
@$core.pragma('dart2js:noInline')
static SendRawTransactionResponse getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<SendRawTransactionResponse>(create);
static SendRawTransactionResponse? _defaultInstance;
static BroadcastTransactionResponse getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<BroadcastTransactionResponse>(create);
static BroadcastTransactionResponse? _defaultInstance;

@$pb.TagNumber(2)
$core.List<$core.int> get id => $_getN(0);
Expand Down Expand Up @@ -1461,9 +1461,9 @@ class TransactionApi {
var emptyResponse = CalculateFeeResponse();
return _client.invoke<CalculateFeeResponse>(ctx, 'Transaction', 'CalculateFee', request, emptyResponse);
}
$async.Future<SendRawTransactionResponse> sendRawTransaction($pb.ClientContext? ctx, SendRawTransactionRequest request) {
var emptyResponse = SendRawTransactionResponse();
return _client.invoke<SendRawTransactionResponse>(ctx, 'Transaction', 'SendRawTransaction', request, emptyResponse);
$async.Future<BroadcastTransactionResponse> broadcastTransaction($pb.ClientContext? ctx, BroadcastTransactionRequest request) {
var emptyResponse = BroadcastTransactionResponse();
return _client.invoke<BroadcastTransactionResponse>(ctx, 'Transaction', 'BroadcastTransaction', request, emptyResponse);
}
$async.Future<GetRawTransactionResponse> getRawTransferTransaction($pb.ClientContext? ctx, GetRawTransferTransactionRequest request) {
var emptyResponse = GetRawTransactionResponse();
Expand Down
30 changes: 15 additions & 15 deletions www/grpc/gen/dart/transaction.pbjson.dart
Original file line number Diff line number Diff line change
Expand Up @@ -78,26 +78,26 @@ const CalculateFeeResponse$json = const {

/// Descriptor for `CalculateFeeResponse`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List calculateFeeResponseDescriptor = $convert.base64Decode('ChRDYWxjdWxhdGVGZWVSZXNwb25zZRIQCgNmZWUYASABKANSA2ZlZQ==');
@$core.Deprecated('Use sendRawTransactionRequestDescriptor instead')
const SendRawTransactionRequest$json = const {
'1': 'SendRawTransactionRequest',
@$core.Deprecated('Use broadcastTransactionRequestDescriptor instead')
const BroadcastTransactionRequest$json = const {
'1': 'BroadcastTransactionRequest',
'2': const [
const {'1': 'data', '3': 1, '4': 1, '5': 12, '10': 'data'},
const {'1': 'signed_tx', '3': 1, '4': 1, '5': 12, '10': 'signedTx'},
],
};

/// Descriptor for `SendRawTransactionRequest`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List sendRawTransactionRequestDescriptor = $convert.base64Decode('ChlTZW5kUmF3VHJhbnNhY3Rpb25SZXF1ZXN0EhIKBGRhdGEYASABKAxSBGRhdGE=');
@$core.Deprecated('Use sendRawTransactionResponseDescriptor instead')
const SendRawTransactionResponse$json = const {
'1': 'SendRawTransactionResponse',
/// Descriptor for `BroadcastTransactionRequest`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List broadcastTransactionRequestDescriptor = $convert.base64Decode('ChtCcm9hZGNhc3RUcmFuc2FjdGlvblJlcXVlc3QSGwoJc2lnbmVkX3R4GAEgASgMUghzaWduZWRUeA==');
@$core.Deprecated('Use broadcastTransactionResponseDescriptor instead')
const BroadcastTransactionResponse$json = const {
'1': 'BroadcastTransactionResponse',
'2': const [
const {'1': 'id', '3': 2, '4': 1, '5': 12, '10': 'id'},
],
};

/// Descriptor for `SendRawTransactionResponse`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List sendRawTransactionResponseDescriptor = $convert.base64Decode('ChpTZW5kUmF3VHJhbnNhY3Rpb25SZXNwb25zZRIOCgJpZBgCIAEoDFICaWQ=');
/// Descriptor for `BroadcastTransactionResponse`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List broadcastTransactionResponseDescriptor = $convert.base64Decode('ChxCcm9hZGNhc3RUcmFuc2FjdGlvblJlc3BvbnNlEg4KAmlkGAIgASgMUgJpZA==');
@$core.Deprecated('Use getRawTransferTransactionRequestDescriptor instead')
const GetRawTransferTransactionRequest$json = const {
'1': 'GetRawTransferTransactionRequest',
Expand Down Expand Up @@ -255,7 +255,7 @@ const $core.Map<$core.String, $core.dynamic> TransactionServiceBase$json = const
'2': const [
const {'1': 'GetTransaction', '2': '.pactus.GetTransactionRequest', '3': '.pactus.GetTransactionResponse'},
const {'1': 'CalculateFee', '2': '.pactus.CalculateFeeRequest', '3': '.pactus.CalculateFeeResponse'},
const {'1': 'SendRawTransaction', '2': '.pactus.SendRawTransactionRequest', '3': '.pactus.SendRawTransactionResponse'},
const {'1': 'BroadcastTransaction', '2': '.pactus.BroadcastTransactionRequest', '3': '.pactus.BroadcastTransactionResponse'},
const {'1': 'GetRawTransferTransaction', '2': '.pactus.GetRawTransferTransactionRequest', '3': '.pactus.GetRawTransactionResponse'},
const {'1': 'GetRawBondTransaction', '2': '.pactus.GetRawBondTransactionRequest', '3': '.pactus.GetRawTransactionResponse'},
const {'1': 'GetRawUnBondTransaction', '2': '.pactus.GetRawUnBondTransactionRequest', '3': '.pactus.GetRawTransactionResponse'},
Expand All @@ -275,8 +275,8 @@ const $core.Map<$core.String, $core.Map<$core.String, $core.dynamic>> Transactio
'.pactus.PayloadWithdraw': PayloadWithdraw$json,
'.pactus.CalculateFeeRequest': CalculateFeeRequest$json,
'.pactus.CalculateFeeResponse': CalculateFeeResponse$json,
'.pactus.SendRawTransactionRequest': SendRawTransactionRequest$json,
'.pactus.SendRawTransactionResponse': SendRawTransactionResponse$json,
'.pactus.BroadcastTransactionRequest': BroadcastTransactionRequest$json,
'.pactus.BroadcastTransactionResponse': BroadcastTransactionResponse$json,
'.pactus.GetRawTransferTransactionRequest': GetRawTransferTransactionRequest$json,
'.pactus.GetRawTransactionResponse': GetRawTransactionResponse$json,
'.pactus.GetRawBondTransactionRequest': GetRawBondTransactionRequest$json,
Expand All @@ -285,4 +285,4 @@ const $core.Map<$core.String, $core.Map<$core.String, $core.dynamic>> Transactio
};

/// Descriptor for `Transaction`. Decode as a `google.protobuf.ServiceDescriptorProto`.
final $typed_data.Uint8List transactionServiceDescriptor = $convert.base64Decode('CgtUcmFuc2FjdGlvbhJPCg5HZXRUcmFuc2FjdGlvbhIdLnBhY3R1cy5HZXRUcmFuc2FjdGlvblJlcXVlc3QaHi5wYWN0dXMuR2V0VHJhbnNhY3Rpb25SZXNwb25zZRJJCgxDYWxjdWxhdGVGZWUSGy5wYWN0dXMuQ2FsY3VsYXRlRmVlUmVxdWVzdBocLnBhY3R1cy5DYWxjdWxhdGVGZWVSZXNwb25zZRJbChJTZW5kUmF3VHJhbnNhY3Rpb24SIS5wYWN0dXMuU2VuZFJhd1RyYW5zYWN0aW9uUmVxdWVzdBoiLnBhY3R1cy5TZW5kUmF3VHJhbnNhY3Rpb25SZXNwb25zZRJoChlHZXRSYXdUcmFuc2ZlclRyYW5zYWN0aW9uEigucGFjdHVzLkdldFJhd1RyYW5zZmVyVHJhbnNhY3Rpb25SZXF1ZXN0GiEucGFjdHVzLkdldFJhd1RyYW5zYWN0aW9uUmVzcG9uc2USYAoVR2V0UmF3Qm9uZFRyYW5zYWN0aW9uEiQucGFjdHVzLkdldFJhd0JvbmRUcmFuc2FjdGlvblJlcXVlc3QaIS5wYWN0dXMuR2V0UmF3VHJhbnNhY3Rpb25SZXNwb25zZRJkChdHZXRSYXdVbkJvbmRUcmFuc2FjdGlvbhImLnBhY3R1cy5HZXRSYXdVbkJvbmRUcmFuc2FjdGlvblJlcXVlc3QaIS5wYWN0dXMuR2V0UmF3VHJhbnNhY3Rpb25SZXNwb25zZRJoChlHZXRSYXdXaXRoZHJhd1RyYW5zYWN0aW9uEigucGFjdHVzLkdldFJhd1dpdGhkcmF3VHJhbnNhY3Rpb25SZXF1ZXN0GiEucGFjdHVzLkdldFJhd1RyYW5zYWN0aW9uUmVzcG9uc2U=');
final $typed_data.Uint8List transactionServiceDescriptor = $convert.base64Decode('CgtUcmFuc2FjdGlvbhJPCg5HZXRUcmFuc2FjdGlvbhIdLnBhY3R1cy5HZXRUcmFuc2FjdGlvblJlcXVlc3QaHi5wYWN0dXMuR2V0VHJhbnNhY3Rpb25SZXNwb25zZRJJCgxDYWxjdWxhdGVGZWUSGy5wYWN0dXMuQ2FsY3VsYXRlRmVlUmVxdWVzdBocLnBhY3R1cy5DYWxjdWxhdGVGZWVSZXNwb25zZRJhChRCcm9hZGNhc3RUcmFuc2FjdGlvbhIjLnBhY3R1cy5Ccm9hZGNhc3RUcmFuc2FjdGlvblJlcXVlc3QaJC5wYWN0dXMuQnJvYWRjYXN0VHJhbnNhY3Rpb25SZXNwb25zZRJoChlHZXRSYXdUcmFuc2ZlclRyYW5zYWN0aW9uEigucGFjdHVzLkdldFJhd1RyYW5zZmVyVHJhbnNhY3Rpb25SZXF1ZXN0GiEucGFjdHVzLkdldFJhd1RyYW5zYWN0aW9uUmVzcG9uc2USYAoVR2V0UmF3Qm9uZFRyYW5zYWN0aW9uEiQucGFjdHVzLkdldFJhd0JvbmRUcmFuc2FjdGlvblJlcXVlc3QaIS5wYWN0dXMuR2V0UmF3VHJhbnNhY3Rpb25SZXNwb25zZRJkChdHZXRSYXdVbkJvbmRUcmFuc2FjdGlvbhImLnBhY3R1cy5HZXRSYXdVbkJvbmRUcmFuc2FjdGlvblJlcXVlc3QaIS5wYWN0dXMuR2V0UmF3VHJhbnNhY3Rpb25SZXNwb25zZRJoChlHZXRSYXdXaXRoZHJhd1RyYW5zYWN0aW9uEigucGFjdHVzLkdldFJhd1dpdGhkcmF3VHJhbnNhY3Rpb25SZXF1ZXN0GiEucGFjdHVzLkdldFJhd1RyYW5zYWN0aW9uUmVzcG9uc2U=');
Loading

0 comments on commit 3f36b3e

Please sign in to comment.