From f937588184e1acd138d6b187e3c3ca3f63dfdab1 Mon Sep 17 00:00:00 2001 From: klim0v Date: Sun, 18 Oct 2020 19:38:06 +0300 Subject: [PATCH] add more helpers --- api/grpc_client/helpers.go | 2 +- api/http_client/models/candidate_response.go | 4 +- ...ents_response_event_helper_example_test.go | 24 ++ api/http_client/models/protobuf_any_edited.go | 13 + .../models/transaction_response_data.go | 319 ++++++++++++++++++ .../transaction_response_data_example_test.go | 35 ++ 6 files changed, 394 insertions(+), 3 deletions(-) create mode 100644 api/http_client/models/events_response_event_helper_example_test.go create mode 100644 api/http_client/models/transaction_response_data.go create mode 100644 api/http_client/models/transaction_response_data_example_test.go diff --git a/api/grpc_client/helpers.go b/api/grpc_client/helpers.go index 8d8a7fc..1bbeeeb 100644 --- a/api/grpc_client/helpers.go +++ b/api/grpc_client/helpers.go @@ -5,7 +5,7 @@ import ( _struct "google.golang.org/protobuf/types/known/structpb" ) -// ConvertStructToEvent returns +// ConvertStructToEvent returns Event model func ConvertStructToEvent(str *_struct.Struct) (api.Event, error) { value, err := str.Fields["value"].GetStructValue().MarshalJSON() if err != nil { diff --git a/api/http_client/models/candidate_response.go b/api/http_client/models/candidate_response.go index 6ba22a2..7b57bcd 100644 --- a/api/http_client/models/candidate_response.go +++ b/api/http_client/models/candidate_response.go @@ -46,10 +46,10 @@ type CandidateResponse struct { TotalStake string `json:"total_stake,omitempty"` // To be completed when requesting candidate steaks - UniqUsers uint64 `json:"uniq_users,omitempty"` + UniqUsers uint64 `json:"uniq_users,omitempty,string"` // To be completed when requesting candidate steaks - UsedSlots uint64 `json:"used_slots,omitempty"` + UsedSlots uint64 `json:"used_slots,omitempty,string"` } // Validate validates this candidate response diff --git a/api/http_client/models/events_response_event_helper_example_test.go b/api/http_client/models/events_response_event_helper_example_test.go new file mode 100644 index 0000000..7612934 --- /dev/null +++ b/api/http_client/models/events_response_event_helper_example_test.go @@ -0,0 +1,24 @@ +package models_test + +import ( + "github.com/MinterTeam/minter-go-sdk/v2/api" + "github.com/MinterTeam/minter-go-sdk/v2/api/http_client/models" +) + +func mark(address, publicKey string) {} +func doSomething(*api.StakeKickEvent) {} + +func ExampleConvertStructToEvent() { + data := map[string]interface{}{ + "type": api.TypeStakeKickEvent, + "value": map[string]interface{}{ + "address": "Mx", + "amount": "1000000000000", + "coin": "1", + "validator_pub_key": "Mp", + }, + } + event, _ := models.ConvertStructToEvent(data) + mark(event.GetAddress(), event.GetValidatorPublicKey()) + doSomething(event.(*api.StakeKickEvent)) +} diff --git a/api/http_client/models/protobuf_any_edited.go b/api/http_client/models/protobuf_any_edited.go index 1a7fef8..0eb1303 100644 --- a/api/http_client/models/protobuf_any_edited.go +++ b/api/http_client/models/protobuf_any_edited.go @@ -36,3 +36,16 @@ func (m *ProtobufAny) UnmarshalBinary(b []byte) error { return nil } + +func (m *ProtobufAny) UnmarshalTo(i interface{}) error { + binary, err := m.MarshalBinary() + if err != nil { + return err + } + + if err := swag.ReadJSON(binary, i); err != nil { + return err + } + + return nil +} diff --git a/api/http_client/models/transaction_response_data.go b/api/http_client/models/transaction_response_data.go new file mode 100644 index 0000000..9eb79c9 --- /dev/null +++ b/api/http_client/models/transaction_response_data.go @@ -0,0 +1,319 @@ +package models + +import ( + "encoding/json" + "fmt" + "strconv" +) + +type Data interface { + clone() Data +} + +type SendData struct { + Coin *Coin `json:"coin"` + To string `json:"to"` + Value string `json:"value"` +} + +type SellCoinData struct { + CoinToSell *Coin `json:"coin_to_sell"` + ValueToSell string `json:"value_to_sell"` + CoinToBuy *Coin `json:"coin_to_buy"` + MinimumValueToBuy string `json:"minimum_value_to_buy"` +} + +type SellAllCoinData struct { + CoinToSell *Coin `json:"coin_to_sell,omitempty"` + CoinToBuy *Coin `json:"coin_to_buy,omitempty"` + MinimumValueToBuy string `json:"minimum_value_to_buy,omitempty"` +} + +type BuyCoinData struct { + CoinToBuy *Coin `json:"coin_to_buy,omitempty"` + ValueToBuy string `json:"value_to_buy,omitempty"` + CoinToSell *Coin `json:"coin_to_sell,omitempty"` + MaximumValueToSell string `json:"maximum_value_to_sell,omitempty"` +} + +type CreateCoinData struct { + Name string `json:"name,omitempty"` + Symbol string `json:"symbol,omitempty"` + InitialAmount string `json:"initial_amount,omitempty"` + InitialReserve string `json:"initial_reserve,omitempty"` + ConstantReserveRatio uint64 `json:"constant_reserve_ratio,string,omitempty"` + MaxSupply string `json:"max_supply,omitempty"` +} + +type DeclareCandidacyData struct { + Address string `json:"address,omitempty"` + PubKey string `json:"pub_key,omitempty"` + Commission uint64 `json:"commission,string,omitempty"` + Coin *Coin `json:"coin,omitempty"` + Stake string `json:"stake,omitempty"` +} + +type DelegateData struct { + PubKey string `json:"pub_key,omitempty"` + Coin *Coin `json:"coin,omitempty"` + Value string `json:"value,omitempty"` +} + +type UnbondData struct { + PubKey string `json:"pub_key,omitempty"` + Coin *Coin `json:"coin,omitempty"` + Value string `json:"value,omitempty"` +} + +type RedeemCheckData struct { + RawCheck string `json:"raw_check,omitempty"` + Proof string `json:"proof,omitempty"` +} + +type SetCandidateOnData struct { + PubKey string `json:"pub_key,omitempty"` +} + +type SetCandidateOffData struct { + PubKey string `json:"pub_key,omitempty"` +} + +type CreateMultisigData struct { + Threshold uint64 `json:"threshold,string,omitempty"` + Weights []uint64 `json:"weights,omitempty"` + Addresses []string `json:"addresses,omitempty"` +} + +func (d *CreateMultisigData) UnmarshalJSON(data []byte) error { + type Alias CreateMultisigData + adx := struct { + Weights []string `json:"weights"` + *Alias + }{ + Alias: (*Alias)(d), + } + if err := json.Unmarshal(data, &adx); err != nil { + return err + } + + d.Weights = make([]uint64, 0, len(adx.Weights)) + for _, strWeight := range adx.Weights { + weight, _ := strconv.Atoi(strWeight) + d.Weights = append(d.Weights, uint64(weight)) + } + + return nil +} + +func (d *CreateMultisigData) MarshalJSON() ([]byte, error) { + type Alias CreateMultisigData + + var weights []string + for _, weight := range d.Weights { + weights = append(weights, strconv.Itoa(int(weight))) + } + return json.Marshal(&struct { + Weights []string `json:"weights"` + *Alias + }{ + Weights: weights, + Alias: (*Alias)(d), + }) +} + +type MultiSendData struct { + List []*SendData `json:"list,omitempty"` +} + +type EditCandidateData struct { + PubKey string `json:"pub_key,omitempty"` + RewardAddress string `json:"reward_address,omitempty"` + OwnerAddress string `json:"owner_address,omitempty"` + ControlAddress string `json:"control_address,omitempty"` +} + +type SetHaltBlockData struct { + PubKey string `json:"pub_key,omitempty"` + Height uint64 `json:"height,string,omitempty"` +} + +type RecreateCoinData struct { + Name string `json:"name,omitempty"` + Symbol string `json:"symbol,omitempty"` + InitialAmount string `json:"initial_amount,omitempty"` + InitialReserve string `json:"initial_reserve,omitempty"` + ConstantReserveRatio uint64 `json:"constant_reserve_ratio,string,omitempty"` + MaxSupply string `json:"max_supply,omitempty"` +} + +type EditCoinOwnerData struct { + Symbol string `json:"symbol,omitempty"` + NewOwner string `json:"new_owner,omitempty"` +} + +type EditMultisigData CreateMultisigData + +func (d *EditMultisigData) UnmarshalJSON(data []byte) error { + type Alias EditMultisigData + adx := struct { + Weights []string `json:"weights"` + *Alias + }{ + Alias: (*Alias)(d), + } + if err := json.Unmarshal(data, &adx); err != nil { + return err + } + + d.Weights = make([]uint64, 0, len(adx.Weights)) + for _, strWeight := range adx.Weights { + weight, _ := strconv.Atoi(strWeight) + d.Weights = append(d.Weights, uint64(weight)) + } + return nil +} + +func (d *EditMultisigData) MarshalJSON() ([]byte, error) { + type Alias EditMultisigData + + var weights []string + for _, weight := range d.Weights { + weights = append(weights, strconv.Itoa(int(weight))) + } + return json.Marshal(&struct { + Weights []string `json:"weights"` + *Alias + }{ + Weights: weights, + Alias: (*Alias)(d), + }) +} + +type PriceVoteData struct { + Price string `json:"price,omitempty"` +} + +type EditCandidatePublicKeyData struct { + PubKey string `json:"pub_key,omitempty"` + NewPubKey string `json:"new_pub_key,omitempty"` +} + +var data = map[uint64]Data{ + 1: &SendData{}, + 2: &SellCoinData{}, + 3: &SellAllCoinData{}, + 4: &BuyCoinData{}, + 5: &CreateCoinData{}, + 6: &DeclareCandidacyData{}, + 7: &DelegateData{}, + 8: &UnbondData{}, + 9: &RedeemCheckData{}, + 10: &SetCandidateOnData{}, + 11: &SetCandidateOffData{}, + 12: &CreateMultisigData{}, + 13: &MultiSendData{}, + 14: &EditCandidateData{}, + 15: &SetHaltBlockData{}, + 16: &RecreateCoinData{}, + 17: &EditCoinOwnerData{}, + 18: &EditMultisigData{}, + 19: &PriceVoteData{}, + 20: &EditCandidatePublicKeyData{}, +} + +func (e *SendData) clone() Data { + c := *e + return &c +} +func (e *SellCoinData) clone() Data { + c := *e + return &c +} +func (e *SellAllCoinData) clone() Data { + c := *e + return &c +} +func (e *BuyCoinData) clone() Data { + c := *e + return &c +} +func (e *CreateCoinData) clone() Data { + c := *e + return &c +} +func (e *DeclareCandidacyData) clone() Data { + c := *e + return &c +} +func (e *DelegateData) clone() Data { + c := *e + return &c +} +func (e *UnbondData) clone() Data { + c := *e + return &c +} +func (e *RedeemCheckData) clone() Data { + c := *e + return &c +} +func (e *SetCandidateOnData) clone() Data { + c := *e + return &c +} +func (e *SetCandidateOffData) clone() Data { + c := *e + return &c +} +func (e *CreateMultisigData) clone() Data { + c := *e + return &c +} +func (e *MultiSendData) clone() Data { + c := *e + return &c +} +func (e *EditCandidateData) clone() Data { + c := *e + return &c +} +func (e *SetHaltBlockData) clone() Data { + c := *e + return &c +} +func (e *RecreateCoinData) clone() Data { + c := *e + return &c +} +func (e *EditCoinOwnerData) clone() Data { + c := *e + return &c +} +func (e *EditMultisigData) clone() Data { + c := *e + return &c +} +func (e *PriceVoteData) clone() Data { + c := *e + return &c +} +func (e *EditCandidatePublicKeyData) clone() Data { + c := *e + return &c +} + +// ConvertToData returns Transaction Data model +func ConvertToData(t uint64, value *ProtobufAny) (Data, error) { + eventStruct, ok := data[t] + if !ok { + return nil, fmt.Errorf("data type unknown: %d", t) + } + + clone := eventStruct.clone() + err := value.UnmarshalTo(clone) + if err != nil { + return nil, err + } + + return clone, nil +} diff --git a/api/http_client/models/transaction_response_data_example_test.go b/api/http_client/models/transaction_response_data_example_test.go new file mode 100644 index 0000000..2331f51 --- /dev/null +++ b/api/http_client/models/transaction_response_data_example_test.go @@ -0,0 +1,35 @@ +package models_test + +import ( + "encoding/json" + "fmt" + "github.com/MinterTeam/minter-go-sdk/v2/api/http_client/models" +) + +func ExampleConvertToData() { + transactionResponse := models.TransactionResponse{ + Type: 18, + Data: &models.ProtobufAny{ + "threshold": "5", + "weights": []string{"1", "2", "3"}, + "addresses": []string{"Mx0", "Mx1", "Mx2"}, + }, + } + data, _ := models.ConvertToData(transactionResponse.Type, transactionResponse.Data) + + editMultisigData := data.(*models.EditMultisigData) + + fmt.Printf("%T %[1]v\n", editMultisigData.Threshold) + fmt.Printf("%T %[1]v\n", editMultisigData.Weights) + fmt.Printf("%T %[1]v\n", editMultisigData.Addresses) + + marshal, _ := json.Marshal(editMultisigData) + fmt.Printf("%s", marshal) + + // Output: + // uint64 5 + // []uint64 [1 2 3] + // []string [Mx0 Mx1 Mx2] + // {"weights":["1","2","3"],"threshold":"5","addresses":["Mx0","Mx1","Mx2"]} + +}