feat_: share and parse transaction deep link
This commit is contained in:
parent
86cd41d04e
commit
4c889399eb
|
@ -45,10 +45,20 @@ type ContactURLData struct {
|
|||
PublicKey string `json:"publicKey"`
|
||||
}
|
||||
|
||||
type TransactionURLData struct {
|
||||
TxType int `json:"txType"`
|
||||
Address string `json:"address"`
|
||||
Amount string `json:"amount"`
|
||||
Asset string `json:"asset"`
|
||||
ChainID int `json:"chainId"`
|
||||
ToAsset string `json:"toAsset"`
|
||||
}
|
||||
|
||||
type URLDataResponse struct {
|
||||
Community *CommunityURLData `json:"community"`
|
||||
Channel *CommunityChannelURLData `json:"channel"`
|
||||
Contact *ContactURLData `json:"contact"`
|
||||
Transaction *TransactionURLData `json:"tx"`
|
||||
Shard *shard.Shard `json:"shard,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -58,12 +68,14 @@ const userWithDataPath = "u/"
|
|||
const communityPath = "c#"
|
||||
const communityWithDataPath = "c/"
|
||||
const channelPath = "cc/"
|
||||
const transactionPath = "tx/"
|
||||
|
||||
const sharedURLUserPrefix = baseShareURL + "/" + userPath
|
||||
const sharedURLUserPrefixWithData = baseShareURL + "/" + userWithDataPath
|
||||
const sharedURLCommunityPrefix = baseShareURL + "/" + communityPath
|
||||
const sharedURLCommunityPrefixWithData = baseShareURL + "/" + communityWithDataPath
|
||||
const sharedURLChannelPrefixWithData = baseShareURL + "/" + channelPath
|
||||
const sharedURLTransaction = baseShareURL + "/" + transactionPath
|
||||
|
||||
const channelUUIDRegExp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$"
|
||||
|
||||
|
@ -302,6 +314,77 @@ func (m *Messenger) prepareEncodedCommunityChannelData(community *communities.Co
|
|||
return encodedData, shortKey, nil
|
||||
}
|
||||
|
||||
func (m *Messenger) ShareTransactionURL(request *requests.TransactionShareURL) (string, error) {
|
||||
encodedData, err := m.prepareTransactionUrl(request)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return fmt.Sprintf("%s%s", sharedURLTransaction, encodedData), nil
|
||||
}
|
||||
|
||||
func (m *Messenger) prepareTransactionUrl(request *requests.TransactionShareURL) (string, error) {
|
||||
if err := request.Validate(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
txProto := &protobuf.Transaction{
|
||||
TxType: uint32(request.TxType),
|
||||
Address: request.Address,
|
||||
Amount: request.Amount,
|
||||
Asset: request.Asset,
|
||||
ChainId: uint32(request.ChainID),
|
||||
ToAsset: request.ToAsset,
|
||||
}
|
||||
txData, err := proto.Marshal(txProto)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
urlDataProto := &protobuf.URLData{
|
||||
Content: txData,
|
||||
}
|
||||
|
||||
urlData, err := proto.Marshal(urlDataProto)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
encodedData, err := encodeDataURL(urlData)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return encodedData, nil
|
||||
}
|
||||
|
||||
func parseTransactionURL(data string) (*URLDataResponse, error) {
|
||||
urlData, err := decodeDataURL(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var urlDataProto protobuf.URLData
|
||||
err = proto.Unmarshal(urlData, &urlDataProto)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var txProto protobuf.Transaction
|
||||
err = proto.Unmarshal(urlDataProto.Content, &txProto)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &URLDataResponse{
|
||||
Transaction: &TransactionURLData{
|
||||
TxType: int(txProto.TxType),
|
||||
Address: txProto.Address,
|
||||
Amount: txProto.Amount,
|
||||
Asset: txProto.Asset,
|
||||
ChainID: int(txProto.ChainId),
|
||||
ToAsset: txProto.ToAsset,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *Messenger) ShareCommunityChannelURLWithData(request *requests.CommunityChannelShareURL) (string, error) {
|
||||
if err := request.Validate(); err != nil {
|
||||
return "", err
|
||||
|
@ -518,7 +601,8 @@ func IsStatusSharedURL(url string) bool {
|
|||
strings.HasPrefix(url, sharedURLUserPrefixWithData) ||
|
||||
strings.HasPrefix(url, sharedURLCommunityPrefix) ||
|
||||
strings.HasPrefix(url, sharedURLCommunityPrefixWithData) ||
|
||||
strings.HasPrefix(url, sharedURLChannelPrefixWithData)
|
||||
strings.HasPrefix(url, sharedURLChannelPrefixWithData) ||
|
||||
strings.HasPrefix(url, sharedURLTransaction)
|
||||
}
|
||||
|
||||
func splitSharedURLData(data string) (string, string, error) {
|
||||
|
@ -576,6 +660,11 @@ func ParseSharedURL(url string) (*URLDataResponse, error) {
|
|||
return parseCommunityChannelURLWithData(encodedData, chatKey)
|
||||
}
|
||||
|
||||
if strings.HasPrefix(url, sharedURLTransaction) {
|
||||
trimmedURL := strings.TrimPrefix(url, sharedURLTransaction)
|
||||
return parseTransactionURL(trimmedURL)
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("not a status shared url")
|
||||
}
|
||||
|
||||
|
|
|
@ -497,3 +497,57 @@ func (s *MessengerShareUrlsSuite) TestShareAndParseUserURLWithData() {
|
|||
s.Require().Equal(contact.DisplayName, urlData.Contact.DisplayName)
|
||||
s.Require().Equal(shortKey, urlData.Contact.PublicKey)
|
||||
}
|
||||
|
||||
func (s *MessengerShareUrlsSuite) TestShareTransactionURL() {
|
||||
request := &requests.TransactionShareURL{
|
||||
TxType: 0,
|
||||
Address: "0x1234567890abcdef",
|
||||
Amount: "0.123",
|
||||
Asset: "ETH",
|
||||
ChainID: 123,
|
||||
ToAsset: "SNT",
|
||||
}
|
||||
url, err := s.m.ShareTransactionURL(request)
|
||||
s.Require().NoError(err)
|
||||
s.Require().NotEmpty(url)
|
||||
|
||||
data, err := s.m.prepareTransactionUrl(request)
|
||||
s.Require().NoError(err)
|
||||
|
||||
expectedURL := fmt.Sprintf("%s/tx/%s", baseShareURL, data)
|
||||
s.Require().Equal(expectedURL, url)
|
||||
}
|
||||
|
||||
func (s *MessengerShareUrlsSuite) TestShareTransactionURLInvalid() {
|
||||
request := &requests.TransactionShareURL{
|
||||
TxType: -1,
|
||||
}
|
||||
_, err := s.m.ShareTransactionURL(request)
|
||||
s.Require().Error(err)
|
||||
_, err = s.m.prepareTransactionUrl(request)
|
||||
s.Require().Error(err)
|
||||
}
|
||||
|
||||
func (s *MessengerShareUrlsSuite) TestShareAndParseTransactionURL() {
|
||||
request := &requests.TransactionShareURL{
|
||||
TxType: 0,
|
||||
Address: "0x1234567890abcdef",
|
||||
Amount: "0.123",
|
||||
Asset: "ETH",
|
||||
ChainID: 123,
|
||||
ToAsset: "SNT",
|
||||
}
|
||||
url, err := s.m.ShareTransactionURL(request)
|
||||
s.Require().NoError(err)
|
||||
|
||||
urlData, err := ParseSharedURL(url)
|
||||
s.Require().NoError(err)
|
||||
s.Require().NotNil(urlData)
|
||||
|
||||
s.Require().Equal(request.TxType, urlData.Transaction.TxType)
|
||||
s.Require().Equal(request.Address, urlData.Transaction.Address)
|
||||
s.Require().Equal(request.Amount, urlData.Transaction.Amount)
|
||||
s.Require().Equal(request.Asset, urlData.Transaction.Asset)
|
||||
s.Require().Equal(request.ChainID, urlData.Transaction.ChainID)
|
||||
s.Require().Equal(request.ToAsset, urlData.Transaction.ToAsset)
|
||||
}
|
||||
|
|
|
@ -28,8 +28,17 @@ message User {
|
|||
string color = 3;
|
||||
}
|
||||
|
||||
message Transaction {
|
||||
uint32 txType = 1;
|
||||
string address = 2;
|
||||
string amount = 3;
|
||||
string asset = 4;
|
||||
uint32 chainId = 5;
|
||||
string toAsset = 6;
|
||||
}
|
||||
|
||||
message URLData {
|
||||
// Community, Channel, or User
|
||||
// Community, Channel, User or Transaction
|
||||
bytes content = 1;
|
||||
Shard shard = 2;
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package requests
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrInvalidTransactionType = errors.New("transaction-share-url: invalid transaction type")
|
||||
)
|
||||
|
||||
type TransactionShareURL struct {
|
||||
TxType int `json:"txType"`
|
||||
Asset string `json:"asset"`
|
||||
Amount string `json:"amount"`
|
||||
Address string `json:"address"`
|
||||
ChainID int `json:"chainId"`
|
||||
ToAsset string `json:"toAsset"`
|
||||
}
|
||||
|
||||
func (r *TransactionShareURL) Validate() error {
|
||||
if r.TxType < 0 {
|
||||
return ErrInvalidTransactionType
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -1687,6 +1687,10 @@ func (api *PublicAPI) ShareUserURLWithData(pubKey string) (string, error) {
|
|||
return api.service.messenger.ShareUserURLWithData(pubKey)
|
||||
}
|
||||
|
||||
func (api *PublicAPI) ShareTransactionURL(txData *requests.TransactionShareURL) (string, error) {
|
||||
return api.service.messenger.ShareTransactionURL(txData)
|
||||
}
|
||||
|
||||
func (api *PublicAPI) ParseSharedURL(url string) (*protocol.URLDataResponse, error) {
|
||||
return protocol.ParseSharedURL(url)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue