github.com/Finschia/finschia-sdk@v0.48.1/server/rosetta/lib/internal/service/construction.go (about) 1 package service 2 3 import ( 4 "context" 5 "crypto/sha256" 6 "encoding/hex" 7 "strings" 8 9 "github.com/coinbase/rosetta-sdk-go/types" 10 11 "github.com/Finschia/finschia-sdk/server/rosetta/lib/errors" 12 ) 13 14 // ConstructionCombine Combine creates a network-specific transaction from an unsigned transaction 15 // and an array of provided signatures. The signed transaction returned from this method will be 16 // sent to the /construction/submit endpoint by the caller. 17 func (on OnlineNetwork) ConstructionCombine(ctx context.Context, request *types.ConstructionCombineRequest) (*types.ConstructionCombineResponse, *types.Error) { 18 txBytes, err := hex.DecodeString(request.UnsignedTransaction) 19 if err != nil { 20 return nil, errors.ToRosetta(err) 21 } 22 23 signedTx, err := on.client.SignedTx(ctx, txBytes, request.Signatures) 24 if err != nil { 25 return nil, errors.ToRosetta(err) 26 } 27 28 return &types.ConstructionCombineResponse{ 29 SignedTransaction: hex.EncodeToString(signedTx), 30 }, nil 31 } 32 33 // ConstructionDerive Derive returns the AccountIdentifier associated with a public key. 34 func (on OnlineNetwork) ConstructionDerive(_ context.Context, request *types.ConstructionDeriveRequest) (*types.ConstructionDeriveResponse, *types.Error) { 35 account, err := on.client.AccountIdentifierFromPublicKey(request.PublicKey) 36 if err != nil { 37 return nil, errors.ToRosetta(err) 38 } 39 return &types.ConstructionDeriveResponse{ 40 AccountIdentifier: account, 41 Metadata: nil, 42 }, nil 43 } 44 45 // ConstructionHash TransactionHash returns the network-specific transaction hash for a signed 46 // transaction. 47 func (on OnlineNetwork) ConstructionHash(ctx context.Context, request *types.ConstructionHashRequest) (*types.TransactionIdentifierResponse, *types.Error) { 48 bz, err := hex.DecodeString(request.SignedTransaction) 49 if err != nil { 50 return nil, errors.ToRosetta(errors.WrapError(errors.ErrInvalidTransaction, "error decoding tx")) 51 } 52 53 hash := sha256.Sum256(bz) 54 bzHash := hash[:] 55 hashString := hex.EncodeToString(bzHash) 56 57 return &types.TransactionIdentifierResponse{ 58 TransactionIdentifier: &types.TransactionIdentifier{ 59 Hash: strings.ToUpper(hashString), 60 }, 61 }, nil 62 } 63 64 // ConstructionMetadata Get any information required to construct a transaction for a specific 65 // network (i.e. ChainID, Gas, Memo, ...). 66 func (on OnlineNetwork) ConstructionMetadata(ctx context.Context, request *types.ConstructionMetadataRequest) (*types.ConstructionMetadataResponse, *types.Error) { 67 metadata, err := on.client.ConstructionMetadataFromOptions(ctx, request.Options) 68 if err != nil { 69 return nil, errors.ToRosetta(err) 70 } 71 72 return &types.ConstructionMetadataResponse{ 73 Metadata: metadata, 74 }, nil 75 } 76 77 // ConstructionParse Parse is called on both unsigned and signed transactions to understand the 78 // intent of the formulated transaction. This is run as a sanity check before signing (after 79 // /construction/payloads) and before broadcast (after /construction/combine). 80 func (on OnlineNetwork) ConstructionParse(ctx context.Context, request *types.ConstructionParseRequest) (*types.ConstructionParseResponse, *types.Error) { 81 txBytes, err := hex.DecodeString(request.Transaction) 82 if err != nil { 83 err := errors.WrapError(errors.ErrInvalidTransaction, err.Error()) 84 return nil, errors.ToRosetta(err) 85 } 86 ops, signers, err := on.client.TxOperationsAndSignersAccountIdentifiers(request.Signed, txBytes) 87 if err != nil { 88 return nil, errors.ToRosetta(err) 89 } 90 return &types.ConstructionParseResponse{ 91 Operations: ops, 92 AccountIdentifierSigners: signers, 93 Metadata: nil, 94 }, nil 95 } 96 97 // ConstructionPayloads Payloads is called with an array of operations and the response from 98 // /construction/metadata. It returns an unsigned transaction blob and a collection of payloads that 99 // must be signed by particular AccountIdentifiers using a certain SignatureType. 100 func (on OnlineNetwork) ConstructionPayloads(ctx context.Context, request *types.ConstructionPayloadsRequest) (*types.ConstructionPayloadsResponse, *types.Error) { 101 payload, err := on.client.ConstructionPayload(ctx, request) 102 if err != nil { 103 return nil, errors.ToRosetta(err) 104 } 105 return payload, nil 106 } 107 108 // ConstructionPreprocess Preprocess is called prior to /construction/payloads to construct a 109 // request for any metadata that is needed for transaction construction given (i.e. account nonce). 110 func (on OnlineNetwork) ConstructionPreprocess(ctx context.Context, request *types.ConstructionPreprocessRequest) (*types.ConstructionPreprocessResponse, *types.Error) { 111 options, err := on.client.PreprocessOperationsToOptions(ctx, request) 112 if err != nil { 113 return nil, errors.ToRosetta(err) 114 } 115 116 return options, nil 117 } 118 119 // ConstructionSubmit Submit a pre-signed transaction to the node. This call does not block on the 120 // transaction being included in a block. Rather, it returns immediately with an indication of 121 // whether or not the transaction was included in the mempool. 122 func (on OnlineNetwork) ConstructionSubmit(ctx context.Context, request *types.ConstructionSubmitRequest) (*types.TransactionIdentifierResponse, *types.Error) { 123 txBytes, err := hex.DecodeString(request.SignedTransaction) 124 if err != nil { 125 return nil, errors.ToRosetta(err) 126 } 127 128 res, meta, err := on.client.PostTx(txBytes) 129 if err != nil { 130 return nil, errors.ToRosetta(err) 131 } 132 133 return &types.TransactionIdentifierResponse{ 134 TransactionIdentifier: res, 135 Metadata: meta, 136 }, nil 137 }