diff --git a/model/client/clio/ledger_request.go b/model/client/clio/ledger_request.go new file mode 100644 index 00000000..e8ad6a88 --- /dev/null +++ b/model/client/clio/ledger_request.go @@ -0,0 +1,61 @@ +package clio + +import ( + "encoding/json" + + "github.com/xyield/xrpl-go/model/client/common" +) + +type LedgerRequest struct { + LedgerHash common.LedgerHash `json:"ledger_hash,omitempty"` + LedgerIndex common.LedgerSpecifier `json:"ledger_index,omitempty"` + Full bool `json:"full"` + Accounts bool `json:"accounts"` + Transactions bool `json:"transactions"` + Expand bool `json:"expand"` + OwnerFunds bool `json:"owner_funds"` + Binary bool `json:"binary"` + Queue bool `json:"queue"` + Diff bool `json:"diff"` +} + +func (*LedgerRequest) Method() string { + return "ledger" +} + +func (r *LedgerRequest) UnmarshalJSON(data []byte) error { + type lrHelper struct { + LedgerHash common.LedgerHash `json:"ledger_hash"` + LedgerIndex json.RawMessage `json:"ledger_index"` + Full bool `json:"full"` + Accounts bool `json:"accounts"` + Transactions bool `json:"transactions"` + Expand bool `json:"expand"` + OwnerFunds bool `json:"owner_funds"` + Binary bool `json:"binary"` + Queue bool `json:"queue"` + Diff bool `json:"diff"` + } + var h lrHelper + err := json.Unmarshal(data, &h) + if err != nil { + return err + } + *r = LedgerRequest{ + LedgerHash: h.LedgerHash, + Accounts: h.Accounts, + Full: h.Full, + Transactions: h.Transactions, + Expand: h.Expand, + OwnerFunds: h.OwnerFunds, + Binary: h.Binary, + Queue: h.Queue, + Diff: h.Diff, + } + r.LedgerIndex, err = common.UnmarshalLedgerSpecifier(h.LedgerIndex) + if err != nil { + return err + } + + return nil +} diff --git a/model/client/clio/ledger_response.go b/model/client/clio/ledger_response.go new file mode 100644 index 00000000..1a41f00b --- /dev/null +++ b/model/client/clio/ledger_response.go @@ -0,0 +1,90 @@ +package clio + +import ( + "encoding/json" + + "github.com/xyield/xrpl-go/model/client/common" + "github.com/xyield/xrpl-go/model/ledger" + "github.com/xyield/xrpl-go/model/transactions" + "github.com/xyield/xrpl-go/model/transactions/types" +) + +type LedgerResponse struct { + Ledger ClioLedger `json:"ledger"` + LedgerHash common.LedgerHash `json:"ledger_hash"` + LedgerIndex common.LedgerIndex `json:"ledger_index"` + Validated bool `json:"validated"` +} + +type ClioLedger struct { + AccountHash string `json:"account_hash"` + AccountState []ledger.LedgerObject `json:"accountState,omitempty"` + CloseFlags int `json:"close_flags"` + CloseTime uint `json:"close_time"` + CloseTimeHuman string `json:"close_time_human"` + CloseTimeResolution int `json:"close_time_resolution"` + Closed bool `json:"closed"` + LedgerHash common.LedgerHash `json:"ledger_hash"` + LedgerIndex string `json:"ledger_index"` + ParentCloseTime uint `json:"parent_close_time"` + ParentHash string `json:"parent_hash"` + TotalCoins types.XRPCurrencyAmount `json:"total_coins"` + TransactionHash string `json:"transaction_hash"` + Transactions []transactions.Tx `json:"transactions,omitempty"` +} + +func (l *ClioLedger) UnmarshalJSON(data []byte) error { + type clHelper struct { + AccountHash string `json:"account_hash"` + AccountState []json.RawMessage `json:"accountState,omitempty"` + CloseFlags int `json:"close_flags"` + CloseTime uint `json:"close_time"` + CloseTimeHuman string `json:"close_time_human"` + CloseTimeResolution int `json:"close_time_resolution"` + Closed bool `json:"closed"` + LedgerHash common.LedgerHash `json:"ledger_hash"` + LedgerIndex string `json:"ledger_index"` + ParentCloseTime uint `json:"parent_close_time"` + ParentHash string `json:"parent_hash"` + TotalCoins types.XRPCurrencyAmount `json:"total_coins"` + TransactionHash string `json:"transaction_hash"` + Transactions []json.RawMessage `json:"transactions"` + } + var h clHelper + err := json.Unmarshal(data, &h) + if err != nil { + return err + } + *l = ClioLedger{ + AccountHash: h.AccountHash, + CloseFlags: h.CloseFlags, + CloseTime: h.CloseTime, + CloseTimeHuman: h.CloseTimeHuman, + CloseTimeResolution: h.CloseTimeResolution, + Closed: h.Closed, + LedgerHash: h.LedgerHash, + LedgerIndex: h.LedgerIndex, + ParentCloseTime: h.ParentCloseTime, + ParentHash: h.ParentHash, + TotalCoins: h.TotalCoins, + TransactionHash: h.TransactionHash, + } + + for _, state := range h.AccountState { + obj, err := ledger.UnmarshalLedgerObject(state) + if err != nil { + return err + } + l.AccountState = append(l.AccountState, obj) + } + + for _, tx := range h.Transactions { + tx, err := transactions.UnmarshalTx(tx) + if err != nil { + return err + } + l.Transactions = append(l.Transactions, tx) + } + + return nil +} diff --git a/model/client/clio/ledger_test.go b/model/client/clio/ledger_test.go new file mode 100644 index 00000000..c2c7fb30 --- /dev/null +++ b/model/client/clio/ledger_test.go @@ -0,0 +1,75 @@ +package clio + +import ( + "testing" + + "github.com/xyield/xrpl-go/model/client/common" + "github.com/xyield/xrpl-go/test" +) + +func TestLedgerRequest(t *testing.T) { + s := LedgerRequest{ + LedgerIndex: common.VALIDATED, + } + j := `{ + "ledger_index": "validated", + "full": false, + "accounts": false, + "transactions": false, + "expand": false, + "owner_funds": false, + "binary": false, + "queue": false, + "diff": false +}` + + if err := test.SerializeAndDeserialize(t, s, j); err != nil { + t.Error(err) + } +} + +func TestLedgerResponse(t *testing.T) { + // TODO test AccountState + s := LedgerResponse{ + Ledger: ClioLedger{ + AccountHash: "10EFE192F59B3DE2A2BE5BCE2CA5DC83D066105696FCFC24C055359AAEBD6941", + CloseFlags: 0, + CloseTime: 711134782, + CloseTimeHuman: "2022-Jul-14 17:26:22.000000000 UTC", + CloseTimeResolution: 10, + Closed: true, + LedgerHash: "D3878EF6C92B84678AE2FBADC40961A161A128EA54AE59C2775CE076C2AE7A85", + LedgerIndex: "19977716", + ParentCloseTime: 711134781, + ParentHash: "D6DE54039FE5A22D86CD522F1A9B7794E487B74D9B6B8CBDE23F240F434B6749", + TotalCoins: 99987079398940307, + TransactionHash: "0000000000000000000000000000000000000000000000000000000000000000", + }, + LedgerHash: "D3878EF6C92B84678AE2FBADC40961A161A128EA54AE59C2775CE076C2AE7A85", + LedgerIndex: 19977716, + Validated: true, + } + j := `{ + "ledger": { + "account_hash": "10EFE192F59B3DE2A2BE5BCE2CA5DC83D066105696FCFC24C055359AAEBD6941", + "close_flags": 0, + "close_time": 711134782, + "close_time_human": "2022-Jul-14 17:26:22.000000000 UTC", + "close_time_resolution": 10, + "closed": true, + "ledger_hash": "D3878EF6C92B84678AE2FBADC40961A161A128EA54AE59C2775CE076C2AE7A85", + "ledger_index": "19977716", + "parent_close_time": 711134781, + "parent_hash": "D6DE54039FE5A22D86CD522F1A9B7794E487B74D9B6B8CBDE23F240F434B6749", + "total_coins": "99987079398940307", + "transaction_hash": "0000000000000000000000000000000000000000000000000000000000000000" + }, + "ledger_hash": "D3878EF6C92B84678AE2FBADC40961A161A128EA54AE59C2775CE076C2AE7A85", + "ledger_index": 19977716, + "validated": true +}` + + if err := test.SerializeAndDeserialize(t, s, j); err != nil { + t.Error(err) + } +} diff --git a/model/client/clio/nft_info_request.go b/model/client/clio/nft_info_request.go new file mode 100644 index 00000000..0ada2376 --- /dev/null +++ b/model/client/clio/nft_info_request.go @@ -0,0 +1,37 @@ +package clio + +import ( + "encoding/json" + + "github.com/xyield/xrpl-go/model/client/common" + "github.com/xyield/xrpl-go/model/transactions/types" +) + +type NFTInfoRequest struct { + NFTokenID types.NFTokenID `json:"nft_id"` + LedgerHash common.LedgerHash `json:"ledger_hash,omitempty"` + LedgerIndex common.LedgerSpecifier `json:"ledger_index,omitempty"` +} + +func (*NFTInfoRequest) Method() string { + return "nft_info" +} + +func (r *NFTInfoRequest) UnmarshalJSON(data []byte) error { + type nirHelper struct { + NFTokenID types.NFTokenID `json:"nft_id"` + LedgerHash common.LedgerHash `json:"ledger_hash,omitempty"` + LedgerIndex json.RawMessage `json:"ledger_index,omitempty"` + } + var h nirHelper + err := json.Unmarshal(data, &h) + if err != nil { + return err + } + *r = NFTInfoRequest{ + NFTokenID: h.NFTokenID, + LedgerHash: h.LedgerHash, + } + r.LedgerIndex, err = common.UnmarshalLedgerSpecifier(h.LedgerIndex) + return err +} diff --git a/model/client/clio/nft_info_response.go b/model/client/clio/nft_info_response.go new file mode 100644 index 00000000..0583b610 --- /dev/null +++ b/model/client/clio/nft_info_response.go @@ -0,0 +1,19 @@ +package clio + +import ( + "github.com/xyield/xrpl-go/model/client/common" + "github.com/xyield/xrpl-go/model/transactions/types" +) + +type NFTInfoResponse struct { + NFTokenID types.NFTokenID `json:"nft_id"` + LedgerIndex common.LedgerIndex `json:"ledger_index"` + Owner types.Address `json:"owner"` + IsBurned bool `json:"is_burned"` + Flags uint `json:"flags"` + TransferFee uint `json:"transfer_fee"` + Issuer types.Address `json:"issuer"` + NFTokenTaxon uint `json:"nft_taxon"` + NFTokenSequence uint `json:"nft_sequence"` + URI types.NFTokenURI `json:"uri,omitempty"` +} diff --git a/model/client/clio/nft_info_test.go b/model/client/clio/nft_info_test.go new file mode 100644 index 00000000..68f3a8d9 --- /dev/null +++ b/model/client/clio/nft_info_test.go @@ -0,0 +1,50 @@ +package clio + +import ( + "testing" + + "github.com/xyield/xrpl-go/model/client/common" + "github.com/xyield/xrpl-go/test" +) + +func TestNFTInfoRequest(t *testing.T) { + s := NFTInfoRequest{ + NFTokenID: "00080000B4F4AFC5FBCBD76873F18006173D2193467D3EE70000099B00000000", + LedgerIndex: common.VALIDATED, + } + + j := `{ + "nft_id": "00080000B4F4AFC5FBCBD76873F18006173D2193467D3EE70000099B00000000", + "ledger_index": "validated" +}` + + if err := test.SerializeAndDeserialize(t, s, j); err != nil { + t.Error(err) + } +} + +func TestNFTInfoResponse(t *testing.T) { + s := NFTInfoResponse{ + NFTokenID: "00080000B4F4AFC5FBCBD76873F18006173D2193467D3EE70000099B00000000", + LedgerIndex: 270, + Owner: "rG9gdNygQ6npA9JvDFWBoeXbiUcTYJnEnk", + IsBurned: true, + Flags: 8, + TransferFee: 0, + Issuer: "rHVokeuSnjPjz718qdb47bGXBBHNMP3KDQ", + } + j := `{ + "nft_id": "00080000B4F4AFC5FBCBD76873F18006173D2193467D3EE70000099B00000000", + "ledger_index": 270, + "owner": "rG9gdNygQ6npA9JvDFWBoeXbiUcTYJnEnk", + "is_burned": true, + "flags": 8, + "transfer_fee": 0, + "issuer": "rHVokeuSnjPjz718qdb47bGXBBHNMP3KDQ", + "nft_taxon": 0, + "nft_sequence": 0 +}` + if err := test.SerializeAndDeserialize(t, s, j); err != nil { + t.Error(err) + } +} diff --git a/model/client/clio/server_info_request.go b/model/client/clio/server_info_request.go new file mode 100644 index 00000000..a285d90f --- /dev/null +++ b/model/client/clio/server_info_request.go @@ -0,0 +1,8 @@ +package clio + +type ServerInfoRequest struct { +} + +func (*ServerInfoRequest) Method() string { + return "server_info" +} diff --git a/model/client/clio/server_info_response.go b/model/client/clio/server_info_response.go new file mode 100644 index 00000000..d569ccc8 --- /dev/null +++ b/model/client/clio/server_info_response.go @@ -0,0 +1,77 @@ +package clio + +import "github.com/xyield/xrpl-go/model/transactions/types" + +type ServerInfoResponse struct { + Info ClioServerInfo `json:"info"` + Validated bool `json:"validated"` + Status string `json:"status,omitempty"` +} + +type ClioServerInfo struct { + CompleteLedgers string `json:"complete_ledgers"` + Counters *ClioCounters `json:"counters,omitempty"` + LoadFactor int `json:"load_factor"` + ClioVersion string `json:"clio_version"` + ValidationQuorum int `json:"validation_quorum,omitempty"` + RippledVersion string `json:"rippled_version,omitempty"` + ValidatedLedger *ClioLedgerInfo `json:"validated_ledger,omitempty"` + ValidatorListExpires string `json:"validator_list_expires,omitempty"` + Cache ClioCache `json:"cache"` + ETL *ClioETL `json:"etl,omitempty"` +} + +type ClioCounters struct { + RPC map[string]ClioRPC `json:"rpc"` + Subscriptions ClioSubscriptions `json:"subscriptions"` +} + +type ClioRPC struct { + Started string `json:"started,omitempty"` + Finished string `json:"finished,omitempty"` + Errored string `json:"errored,omitempty"` + Forwarded string `json:"forwarded,omitempty"` + DurationUS string `json:"duration_us,omitempty"` +} + +type ClioSubscriptions struct { + Ledger int `json:"ledger"` + Transactions int `json:"transactions"` + TransactionsProposed int `json:"transactions_proposed"` + Manifests int `json:"manifests"` + Validations int `json:"validations"` + Account int `json:"account"` + AccountsProposed int `json:"accounts_proposed"` + Books int `json:"books"` +} + +type ClioLedgerInfo struct { + Age uint `json:"age"` + BaseFeeXRP float32 `json:"base_fee_xrp"` + Hash types.Hash256 `json:"hash"` + ReserveBaseXRP float32 `json:"reserve_base_xrp"` + ReserveIncXRP float32 `json:"reserve_inc_xrp"` + Seq uint `json:"seq"` +} + +type ClioCache struct { + Size int `json:"size"` + IsFull bool `json:"is_full"` + LatestLedgerSeq int `json:"latest_ledger_seq"` +} + +type ClioETL struct { + ETLSources []ClioETLSource `json:"etl_sources"` + IsWriter bool `json:"is_writer"` + ReadOnly bool `json:"read_only"` + LastPublishAgeSeconds string `json:"last_publish_age_seconds"` +} + +type ClioETLSource struct { + ValidatedRange string `json:"validated_range"` + IsConnected string `json:"is_connected"` + IP string `json:"ip"` + WSPort string `json:"ws_port"` + GRPCPort string `json:"grpc_port"` + LastMsgAgeSeconds string `json:"last_msg_age_seconds"` +} diff --git a/model/client/clio/server_info_test.go b/model/client/clio/server_info_test.go new file mode 100644 index 00000000..f261e2b0 --- /dev/null +++ b/model/client/clio/server_info_test.go @@ -0,0 +1,453 @@ +package clio + +import ( + "testing" + + "github.com/xyield/xrpl-go/test" +) + +func TestServerInfoResponseLocalhost(t *testing.T) { + s := ServerInfoResponse{ + Info: ClioServerInfo{ + CompleteLedgers: "19499132-19977628", + Counters: &ClioCounters{ + RPC: map[string]ClioRPC{ + "account_objects": { + Started: "1", + Finished: "1", + Errored: "0", + Forwarded: "0", + DurationUS: "991", + }, + "account_tx": { + Started: "1", + Finished: "1", + Errored: "0", + Forwarded: "0", + DurationUS: "91633", + }, + "account_lines": { + Started: "5", + Finished: "5", + Errored: "0", + Forwarded: "0", + DurationUS: "4915159", + }, + "submit_multisigned": { + Started: "2", + Finished: "2", + Errored: "0", + Forwarded: "2", + DurationUS: "4823", + }, + "ledger_entry": { + Started: "1", + Finished: "1", + Errored: "0", + Forwarded: "0", + DurationUS: "17806", + }, + "server_info": { + Started: "5", + Finished: "5", + Errored: "0", + Forwarded: "0", + DurationUS: "2375580", + }, + "account_info": { + Started: "5", + Finished: "5", + Errored: "0", + Forwarded: "5", + DurationUS: "9256", + }, + "account_currencies": { + Started: "4", + Finished: "4", + Errored: "0", + Forwarded: "0", + DurationUS: "517302", + }, + "noripple_check": { + Started: "1", + Finished: "1", + Errored: "0", + Forwarded: "1", + DurationUS: "2218", + }, + "tx": { + Started: "1", + Finished: "1", + Errored: "0", + Forwarded: "0", + DurationUS: "562", + }, + "gateway_balances": { + Started: "6", + Finished: "6", + Errored: "0", + Forwarded: "0", + DurationUS: "1395156", + }, + "channel_authorize": { + Started: "1", + Finished: "1", + Errored: "0", + Forwarded: "1", + DurationUS: "2017", + }, + "manifest": { + Started: "1", + Finished: "1", + Errored: "0", + Forwarded: "1", + DurationUS: "1707", + }, + "subscribe": { + Started: "6", + Finished: "6", + Errored: "0", + Forwarded: "0", + DurationUS: "116", + }, + "random": { + Started: "1", + Finished: "1", + Errored: "0", + Forwarded: "0", + DurationUS: "111", + }, + "ledger_data": { + Started: "14", + Finished: "3", + Errored: "11", + Forwarded: "0", + DurationUS: "6179145", + }, + "ripple_path_find": { + Started: "1", + Finished: "1", + Errored: "0", + Forwarded: "1", + DurationUS: "1409563", + }, + "account_channels": { + Started: "14", + Finished: "14", + Errored: "0", + Forwarded: "0", + DurationUS: "1062692", + }, + "submit": { + Started: "6", + Finished: "6", + Errored: "0", + Forwarded: "6", + DurationUS: "11383", + }, + "transaction_entry": { + Started: "8", + Finished: "5", + Errored: "3", + Forwarded: "0", + DurationUS: "494131", + }, + }, + Subscriptions: ClioSubscriptions{ + Ledger: 0, + Transactions: 0, + TransactionsProposed: 0, + Manifests: 2, + Validations: 2, + Account: 0, + AccountsProposed: 0, + Books: 0, + }, + }, + LoadFactor: 1, + ClioVersion: "0.3.0-b2", + ValidationQuorum: 8, + RippledVersion: "1.9.1-rc1", + ValidatedLedger: &ClioLedgerInfo{ + Age: 4, + Hash: "4CD25FB70D45646EE5822E76E58B66D39D5AE6BA0F70491FA803DA0DA218F434", + Seq: 19977628, + BaseFeeXRP: 1e-5, + ReserveBaseXRP: 1e1, + ReserveIncXRP: 2e0, + }, + Cache: ClioCache{ + Size: 8812733, + IsFull: true, + LatestLedgerSeq: 19977629, + }, + ETL: &ClioETL{ + ETLSources: []ClioETLSource{ + { + ValidatedRange: "19405538-19977629", + IsConnected: "1", + IP: "52.36.182.38", + WSPort: "6005", + GRPCPort: "50051", + LastMsgAgeSeconds: "0", + }, + }, + IsWriter: true, + ReadOnly: false, + LastPublishAgeSeconds: "2", + }, + }, + Validated: true, + } + j := `{ + "info": { + "complete_ledgers": "19499132-19977628", + "counters": { + "rpc": { + "account_channels": { + "started": "14", + "finished": "14", + "errored": "0", + "forwarded": "0", + "duration_us": "1062692" + }, + "account_currencies": { + "started": "4", + "finished": "4", + "errored": "0", + "forwarded": "0", + "duration_us": "517302" + }, + "account_info": { + "started": "5", + "finished": "5", + "errored": "0", + "forwarded": "5", + "duration_us": "9256" + }, + "account_lines": { + "started": "5", + "finished": "5", + "errored": "0", + "forwarded": "0", + "duration_us": "4915159" + }, + "account_objects": { + "started": "1", + "finished": "1", + "errored": "0", + "forwarded": "0", + "duration_us": "991" + }, + "account_tx": { + "started": "1", + "finished": "1", + "errored": "0", + "forwarded": "0", + "duration_us": "91633" + }, + "channel_authorize": { + "started": "1", + "finished": "1", + "errored": "0", + "forwarded": "1", + "duration_us": "2017" + }, + "gateway_balances": { + "started": "6", + "finished": "6", + "errored": "0", + "forwarded": "0", + "duration_us": "1395156" + }, + "ledger_data": { + "started": "14", + "finished": "3", + "errored": "11", + "forwarded": "0", + "duration_us": "6179145" + }, + "ledger_entry": { + "started": "1", + "finished": "1", + "errored": "0", + "forwarded": "0", + "duration_us": "17806" + }, + "manifest": { + "started": "1", + "finished": "1", + "errored": "0", + "forwarded": "1", + "duration_us": "1707" + }, + "noripple_check": { + "started": "1", + "finished": "1", + "errored": "0", + "forwarded": "1", + "duration_us": "2218" + }, + "random": { + "started": "1", + "finished": "1", + "errored": "0", + "forwarded": "0", + "duration_us": "111" + }, + "ripple_path_find": { + "started": "1", + "finished": "1", + "errored": "0", + "forwarded": "1", + "duration_us": "1409563" + }, + "server_info": { + "started": "5", + "finished": "5", + "errored": "0", + "forwarded": "0", + "duration_us": "2375580" + }, + "submit": { + "started": "6", + "finished": "6", + "errored": "0", + "forwarded": "6", + "duration_us": "11383" + }, + "submit_multisigned": { + "started": "2", + "finished": "2", + "errored": "0", + "forwarded": "2", + "duration_us": "4823" + }, + "subscribe": { + "started": "6", + "finished": "6", + "errored": "0", + "forwarded": "0", + "duration_us": "116" + }, + "transaction_entry": { + "started": "8", + "finished": "5", + "errored": "3", + "forwarded": "0", + "duration_us": "494131" + }, + "tx": { + "started": "1", + "finished": "1", + "errored": "0", + "forwarded": "0", + "duration_us": "562" + } + }, + "subscriptions": { + "ledger": 0, + "transactions": 0, + "transactions_proposed": 0, + "manifests": 2, + "validations": 2, + "account": 0, + "accounts_proposed": 0, + "books": 0 + } + }, + "load_factor": 1, + "clio_version": "0.3.0-b2", + "validation_quorum": 8, + "rippled_version": "1.9.1-rc1", + "validated_ledger": { + "age": 4, + "base_fee_xrp": 0.00001, + "hash": "4CD25FB70D45646EE5822E76E58B66D39D5AE6BA0F70491FA803DA0DA218F434", + "reserve_base_xrp": 10, + "reserve_inc_xrp": 2, + "seq": 19977628 + }, + "cache": { + "size": 8812733, + "is_full": true, + "latest_ledger_seq": 19977629 + }, + "etl": { + "etl_sources": [ + { + "validated_range": "19405538-19977629", + "is_connected": "1", + "ip": "52.36.182.38", + "ws_port": "6005", + "grpc_port": "50051", + "last_msg_age_seconds": "0" + } + ], + "is_writer": true, + "read_only": false, + "last_publish_age_seconds": "2" + } + }, + "validated": true +}` + + if err := test.SerializeAndDeserialize(t, s, j); err != nil { + t.Error(err) + } +} + +func TestServerInfoResponseRemote(t *testing.T) { + s := ServerInfoResponse{ + Info: ClioServerInfo{ + CompleteLedgers: "32570-73737719", + LoadFactor: 1, + ClioVersion: "1.0.2", + ValidationQuorum: 28, + RippledVersion: "1.9.1", + ValidatedLedger: &ClioLedgerInfo{ + Age: 7, + BaseFeeXRP: 0.00001, + Hash: "4ECDEAF9E6F8B37EFDE297953168AAB42DEED1082A565639EBB2D29E047341B4", + ReserveBaseXRP: 10, + ReserveIncXRP: 2, + Seq: 73737719, + }, + Cache: ClioCache{ + Size: 15258947, + IsFull: true, + LatestLedgerSeq: 73737719, + }, + }, + Validated: true, + Status: "success", + } + + j := `{ + "info": { + "complete_ledgers": "32570-73737719", + "load_factor": 1, + "clio_version": "1.0.2", + "validation_quorum": 28, + "rippled_version": "1.9.1", + "validated_ledger": { + "age": 7, + "base_fee_xrp": 0.00001, + "hash": "4ECDEAF9E6F8B37EFDE297953168AAB42DEED1082A565639EBB2D29E047341B4", + "reserve_base_xrp": 10, + "reserve_inc_xrp": 2, + "seq": 73737719 + }, + "cache": { + "size": 15258947, + "is_full": true, + "latest_ledger_seq": 73737719 + } + }, + "validated": true, + "status": "success" +}` + if err := test.SerializeAndDeserialize(t, s, j); err != nil { + t.Error(err) + } +} diff --git a/model/client/server/fee_request.go b/model/client/server/fee_request.go new file mode 100644 index 00000000..a90db311 --- /dev/null +++ b/model/client/server/fee_request.go @@ -0,0 +1,8 @@ +package server + +type FeeRequest struct { +} + +func (*FeeRequest) Method() string { + return "fee" +} diff --git a/model/client/server/fee_response.go b/model/client/server/fee_response.go new file mode 100644 index 00000000..d1d96b16 --- /dev/null +++ b/model/client/server/fee_response.go @@ -0,0 +1,30 @@ +package server + +import ( + "github.com/xyield/xrpl-go/model/client/common" + "github.com/xyield/xrpl-go/model/transactions/types" +) + +type FeeResponse struct { + CurrentLedgerSize string `json:"current_ledger_size"` + CurrentQueueSize string `json:"current_queue_size"` + Drops FeeDrops `json:"drops"` + ExpectedLedgerSize string `json:"expected_ledger_size"` + LedgerCurrentIndex common.LedgerIndex `json:"ledger_current_index"` + Levels FeeLevels `json:"levels"` + MaxQueueSize string `json:"max_queue_size"` +} + +type FeeDrops struct { + BaseFee types.XRPCurrencyAmount `json:"base_fee"` + MedianFee types.XRPCurrencyAmount `json:"median_fee"` + MinimumFee types.XRPCurrencyAmount `json:"minimum_fee"` + OpenLedgerFee types.XRPCurrencyAmount `json:"open_ledger_fee"` +} + +type FeeLevels struct { + MedianLevel types.XRPCurrencyAmount `json:"median_level"` + MinimumLevel types.XRPCurrencyAmount `json:"minimum_level"` + OpenLedgerLevel types.XRPCurrencyAmount `json:"open_ledger_level"` + ReferenceLevel types.XRPCurrencyAmount `json:"reference_level"` +} diff --git a/model/client/server/fee_test.go b/model/client/server/fee_test.go new file mode 100644 index 00000000..e7d707e4 --- /dev/null +++ b/model/client/server/fee_test.go @@ -0,0 +1,53 @@ +package server + +import ( + "testing" + + "github.com/xyield/xrpl-go/test" +) + +func TestFeeResponse(t *testing.T) { + s := FeeResponse{ + CurrentLedgerSize: "14", + CurrentQueueSize: "0", + Drops: FeeDrops{ + BaseFee: 10, + MedianFee: 11000, + MinimumFee: 10, + OpenLedgerFee: 10, + }, + ExpectedLedgerSize: "24", + LedgerCurrentIndex: 26575101, + Levels: FeeLevels{ + MedianLevel: 281600, + MinimumLevel: 256, + OpenLedgerLevel: 256, + ReferenceLevel: 256, + }, + MaxQueueSize: "480", + } + + j := `{ + "current_ledger_size": "14", + "current_queue_size": "0", + "drops": { + "base_fee": "10", + "median_fee": "11000", + "minimum_fee": "10", + "open_ledger_fee": "10" + }, + "expected_ledger_size": "24", + "ledger_current_index": 26575101, + "levels": { + "median_level": "281600", + "minimum_level": "256", + "open_ledger_level": "256", + "reference_level": "256" + }, + "max_queue_size": "480" +}` + + if err := test.SerializeAndDeserialize(t, s, j); err != nil { + t.Error(err) + } +} diff --git a/model/client/server/manifest_request.go b/model/client/server/manifest_request.go new file mode 100644 index 00000000..b48b0ca1 --- /dev/null +++ b/model/client/server/manifest_request.go @@ -0,0 +1,9 @@ +package server + +type ManifestRequest struct { + PublicKey string `json:"public_key"` +} + +func (*ManifestRequest) Method() string { + return "manifest" +} diff --git a/model/client/server/manifest_response.go b/model/client/server/manifest_response.go new file mode 100644 index 00000000..67d765f3 --- /dev/null +++ b/model/client/server/manifest_response.go @@ -0,0 +1,14 @@ +package server + +type ManifestResponse struct { + Details ManifestDetails `json:"details,omitempty"` + Manifest string `json:"manifest,omitempty"` + Requested string `json:"requested"` +} + +type ManifestDetails struct { + Domain string `json:"domain"` + EphemeralKey string `json:"ephemeral_key"` + MasterKey string `json:"master_key"` + Seq uint `json:"seq"` +} diff --git a/model/client/server/manifest_test.go b/model/client/server/manifest_test.go new file mode 100644 index 00000000..1a852330 --- /dev/null +++ b/model/client/server/manifest_test.go @@ -0,0 +1,49 @@ +package server + +import ( + "testing" + + "github.com/xyield/xrpl-go/test" +) + +func TestManifestRequest(t *testing.T) { + s := ManifestRequest{ + PublicKey: "nHUFE9prPXPrHcG3SkwP1UzAQbSphqyQkQK9ATXLZsfkezhhda3p", + } + + j := `{ + "public_key": "nHUFE9prPXPrHcG3SkwP1UzAQbSphqyQkQK9ATXLZsfkezhhda3p" +}` + + if err := test.SerializeAndDeserialize(t, s, j); err != nil { + t.Error(err) + } +} + +func TestManifestResponse(t *testing.T) { + s := ManifestResponse{ + Details: ManifestDetails{ + Domain: "", + EphemeralKey: "n9J67zk4B7GpbQV5jRQntbgdKf7TW6894QuG7qq1rE5gvjCu6snA", + MasterKey: "nHUFE9prPXPrHcG3SkwP1UzAQbSphqyQkQK9ATXLZsfkezhhda3p", + Seq: 1, + }, + Manifest: "JAAAAAFxIe3AkJgOyqs3y+UuiAI27Ff3Mrfbt8e7mjdo06bnGEp5XnMhAhRmvCZmWZXlwShVE9qXs2AVCvhVuA/WGYkTX/vVGBGwdkYwRAIgGnYpIGufURojN2cTXakAM7Vwa0GR7o3osdVlZShroXQCIH9R/Lx1v9rdb4YY2n5nrxdnhSSof3U6V/wIHJmeao5ucBJA9D1iAMo7YFCpb245N3Czc0L1R2Xac0YwQ6XdGT+cZ7yw2n8JbdC3hH8Xu9OUqc867Ee6JmlXtyDHzBdY/hdJCQ==", + Requested: "nHUFE9prPXPrHcG3SkwP1UzAQbSphqyQkQK9ATXLZsfkezhhda3p", + } + + j := `{ + "details": { + "domain": "", + "ephemeral_key": "n9J67zk4B7GpbQV5jRQntbgdKf7TW6894QuG7qq1rE5gvjCu6snA", + "master_key": "nHUFE9prPXPrHcG3SkwP1UzAQbSphqyQkQK9ATXLZsfkezhhda3p", + "seq": 1 + }, + "manifest": "JAAAAAFxIe3AkJgOyqs3y+UuiAI27Ff3Mrfbt8e7mjdo06bnGEp5XnMhAhRmvCZmWZXlwShVE9qXs2AVCvhVuA/WGYkTX/vVGBGwdkYwRAIgGnYpIGufURojN2cTXakAM7Vwa0GR7o3osdVlZShroXQCIH9R/Lx1v9rdb4YY2n5nrxdnhSSof3U6V/wIHJmeao5ucBJA9D1iAMo7YFCpb245N3Czc0L1R2Xac0YwQ6XdGT+cZ7yw2n8JbdC3hH8Xu9OUqc867Ee6JmlXtyDHzBdY/hdJCQ==", + "requested": "nHUFE9prPXPrHcG3SkwP1UzAQbSphqyQkQK9ATXLZsfkezhhda3p" +}` + + if err := test.SerializeAndDeserialize(t, s, j); err != nil { + t.Error(err) + } +} diff --git a/model/client/server/server_info_request.go b/model/client/server/server_info_request.go new file mode 100644 index 00000000..398bb383 --- /dev/null +++ b/model/client/server/server_info_request.go @@ -0,0 +1,8 @@ +package server + +type ServerInfoRequest struct { +} + +func (*ServerInfoRequest) Method() string { + return "server_info" +} diff --git a/model/client/server/server_info_response.go b/model/client/server/server_info_response.go new file mode 100644 index 00000000..bef65d1d --- /dev/null +++ b/model/client/server/server_info_response.go @@ -0,0 +1,78 @@ +package server + +import "github.com/xyield/xrpl-go/model/transactions/types" + +type ServerInfoResponse struct { + Info ServerInfo `json:"info"` +} + +type ServerInfo struct { + AmendmentBlocked bool `json:"amendment_blocked,omitempty"` + BuildVersion string `json:"build_version"` + ClosedLedger *ServerLedgerInfo `json:"closed_ledger,omitempty"` + CompleteLedgers string `json:"complete_ledgers"` + HostID string `json:"hostid"` + IOLatencyMS uint `json:"io_latency_ms"` + JQTransOverflow string `json:"jq_trans_overflow"` + LastClose *ServerClose `json:"last_close"` + Load *ServerLoad `json:"load,omitempty"` + LoadFactor uint `json:"load_factor"` + LoadFactorLocal uint `json:"load_factor_local,omitempty"` + LoadFactorNet uint `json:"load_factor_net,omitempty"` + LoadFactorCluster uint `json:"load_factor_cluster,omitempty"` + LoadFactorFeeEscelation uint `json:"load_factor_fee_escelation,omitempty"` + LoadFactorFeeQueue uint `json:"load_factor_fee_queue,omitempty"` + LoadFactorServer uint `json:"load_factor_server,omitempty"` + Peers uint `json:"peers,omitempty"` + PubkeyNode string `json:"pubkey_node"` + PubkeyValidator string `json:"pubkey_validator,omitempty"` + Reporting *ServerReporting `json:"reporting,omitempty"` + ServerState string `json:"server_state"` + ServerStateDurationUS string `json:"server_state_duration_us"` + StateAccounting map[string]ServerInfoAccounting `json:"state_accounting"` + Time string `json:"time"` + Uptime uint `json:"uptime"` + ValidatedLedger *ServerLedgerInfo `json:"validated_ledger,omitempty"` + ValidationQuorum uint `json:"validation_quorum"` + ValidatorListExpires string `json:"validator_list_expires,omitempty"` +} + +type ServerInfoAccounting struct { + DurationUS string `json:"duration_us"` + Transitions string `json:"transitions"` +} + +type ServerReporting struct { + ETLSources []ETLSource `json:"etl_sources"` + IsWriter bool `json:"is_writer"` + LastPublishTime string `json:"last_publish_time"` +} + +type ETLSource struct { + Connected bool `json:"connected"` + GRPCPort string `json:"grpc_port"` + IP string `json:"ip"` + LastMessageArrivalTime string `json:"last_message_arrival_time"` + ValidatedLedgersRange string `json:"validated_ledgers_range"` + WebsocketPort string `json:"websocket_port"` +} + +type ServerLoad struct { + // TODO determine job types array format + JobTypes []interface{} `json:"job_types"` + Threads uint `json:"threads"` +} + +type ServerClose struct { + ConvergeTimeS float32 `json:"converge_time_s"` + Proposers uint `json:"proposers"` +} + +type ServerLedgerInfo struct { + Age uint `json:"age"` + BaseFeeXRP float32 `json:"base_fee_xrp"` + Hash types.Hash256 `json:"hash"` + ReserveBaseXRP float32 `json:"reserve_base_xrp"` + ReserveIncXRP float32 `json:"reserve_inc_xrp"` + Seq uint `json:"seq"` +} diff --git a/model/client/server/server_info_test.go b/model/client/server/server_info_test.go new file mode 100644 index 00000000..089548e4 --- /dev/null +++ b/model/client/server/server_info_test.go @@ -0,0 +1,117 @@ +package server + +import ( + "testing" + + "github.com/xyield/xrpl-go/test" +) + +func TestServerInfoResponse(t *testing.T) { + s := ServerInfoResponse{ + Info: ServerInfo{ + BuildVersion: "1.9.4", + CompleteLedgers: "32570-75801736", + HostID: "ARMY", + IOLatencyMS: 1, + JQTransOverflow: "2282", + LastClose: &ServerClose{ + ConvergeTimeS: 3.002, + Proposers: 35, + }, + LoadFactor: 1, + Peers: 20, + PubkeyNode: "n9KKBZvwPZ95rQi4BP3an1MRctTyavYkZiLpQwasmFYTE6RYdeX3", + ServerState: "full", + ServerStateDurationUS: "69205850392", + StateAccounting: map[string]ServerInfoAccounting{ + "connected": { + DurationUS: "141058919", + Transitions: "7", + }, + "disconnected": { + DurationUS: "514136273", + Transitions: "3", + }, + "full": { + DurationUS: "4360230140761", + Transitions: "32", + }, + "syncing": { + DurationUS: "50606510", + Transitions: "30", + }, + "tracking": { + DurationUS: "40245486", + Transitions: "34", + }, + }, + Time: "2022-Nov-16 21:50:22.711679 UTC", + Uptime: 4360976, + ValidatedLedger: &ServerLedgerInfo{ + Age: 1, + BaseFeeXRP: 0.00001, + Hash: "3147A41F5F013209581FCDCBBB7A87A4F01EF6842963E13B2B14C8565E00A22B", + ReserveBaseXRP: 10, + ReserveIncXRP: 2, + Seq: 75801736, + }, + ValidationQuorum: 28, + }, + } + + j := `{ + "info": { + "build_version": "1.9.4", + "complete_ledgers": "32570-75801736", + "hostid": "ARMY", + "io_latency_ms": 1, + "jq_trans_overflow": "2282", + "last_close": { + "converge_time_s": 3.002, + "proposers": 35 + }, + "load_factor": 1, + "peers": 20, + "pubkey_node": "n9KKBZvwPZ95rQi4BP3an1MRctTyavYkZiLpQwasmFYTE6RYdeX3", + "server_state": "full", + "server_state_duration_us": "69205850392", + "state_accounting": { + "connected": { + "duration_us": "141058919", + "transitions": "7" + }, + "disconnected": { + "duration_us": "514136273", + "transitions": "3" + }, + "full": { + "duration_us": "4360230140761", + "transitions": "32" + }, + "syncing": { + "duration_us": "50606510", + "transitions": "30" + }, + "tracking": { + "duration_us": "40245486", + "transitions": "34" + } + }, + "time": "2022-Nov-16 21:50:22.711679 UTC", + "uptime": 4360976, + "validated_ledger": { + "age": 1, + "base_fee_xrp": 0.00001, + "hash": "3147A41F5F013209581FCDCBBB7A87A4F01EF6842963E13B2B14C8565E00A22B", + "reserve_base_xrp": 10, + "reserve_inc_xrp": 2, + "seq": 75801736 + }, + "validation_quorum": 28 + } +}` + + if err := test.SerializeAndDeserialize(t, s, j); err != nil { + t.Error(err) + } +} diff --git a/model/client/server/server_state_request.go b/model/client/server/server_state_request.go new file mode 100644 index 00000000..ed9f628b --- /dev/null +++ b/model/client/server/server_state_request.go @@ -0,0 +1,8 @@ +package server + +type ServerStateRequest struct { +} + +func (*ServerStateRequest) Method() string { + return "server_state" +} diff --git a/model/client/server/server_state_response.go b/model/client/server/server_state_response.go new file mode 100644 index 00000000..d7c99d4d --- /dev/null +++ b/model/client/server/server_state_response.go @@ -0,0 +1,53 @@ +package server + +type ServerStateResponse struct { + State ServerState `json:"state"` +} + +type ServerState struct { + AmendmentBlocked bool `json:"amendment_blocked,omitempty"` + BuildVersion string `json:"build_version"` + CompleteLedgers string `json:"complete_ledgers"` + ClosedLedger *ServerLedgerState `json:"closed_ledger,omitempty"` + IOLatencyMS uint `json:"io_latency_ms"` + JQTransOverflow string `json:"jq_trans_overflow"` + LastClose *ServerStateClose `json:"last_close"` + Load *ServerLoad `json:"load,omitempty"` + LoadBase int `json:"load_base"` + LoadFactor uint `json:"load_factor"` + LoadFactorFeeEscelation uint `json:"load_factor_fee_escalation,omitempty"` + LoadFactorFeeQueue uint `json:"load_factor_fee_queue,omitempty"` + LoadFactorFeeReference uint `json:"load_factor_fee_reference,omitempty"` + LoadFactorServer uint `json:"load_factor_server,omitempty"` + Peers uint `json:"peers,omitempty"` + PubkeyNode string `json:"pubkey_node"` + PubkeyValidator string `json:"pubkey_validator,omitempty"` + Reporting *ServerReporting `json:"reporting,omitempty"` + ServerState string `json:"server_state"` + ServerStateDurationUS string `json:"server_state_duration_us"` + StateAccounting map[string]ServerStateAccounting `json:"state_accounting"` + Time string `json:"time"` + Uptime uint `json:"uptime"` + ValidatedLedger *ServerLedgerState `json:"validated_ledger,omitempty"` + ValidationQuorum uint `json:"validation_quorum"` + ValidatorListExpires string `json:"validator_list_expires,omitempty"` +} + +type ServerLedgerState struct { + BaseFee uint `json:"base_fee"` + CloseTime uint `json:"close_time"` + Hash string `json:"hash"` + ReserveBase uint `json:"reserve_base"` + ReserveInc uint `json:"reserve_inc"` + Seq uint `json:"seq"` +} + +type ServerStateClose struct { + ConvergeTime uint `json:"converge_time"` + Proposers uint `json:"proposers"` +} + +type ServerStateAccounting struct { + DurationUS string `json:"duration_us"` + Transitions string `json:"transitions"` +} diff --git a/model/client/server/server_state_test.go b/model/client/server/server_state_test.go new file mode 100644 index 00000000..4aae2910 --- /dev/null +++ b/model/client/server/server_state_test.go @@ -0,0 +1,125 @@ +package server + +import ( + "testing" + + "github.com/xyield/xrpl-go/test" +) + +func TestServerStateResponse(t *testing.T) { + s := ServerStateResponse{ + State: ServerState{ + BuildVersion: "1.7.2", + CompleteLedgers: "64572720-65887201", + IOLatencyMS: 1, + JQTransOverflow: "0", + LastClose: &ServerStateClose{ + ConvergeTime: 3005, + Proposers: 41, + }, + LoadBase: 256, + LoadFactor: 256, + LoadFactorFeeEscelation: 256, + LoadFactorFeeQueue: 256, + LoadFactorFeeReference: 256, + LoadFactorServer: 256, + Peers: 216, + PubkeyNode: "n9MozjnGB3tpULewtTsVtuudg5JqYFyV3QFdAtVLzJaxHcBaxuXD", + ServerState: "full", + ServerStateDurationUS: "3588969453592", + StateAccounting: map[string]ServerStateAccounting{ + "connected": { + DurationUS: "301410595", + Transitions: "2", + }, + "disconnected": { + DurationUS: "1207534", + Transitions: "2", + }, + "full": { + DurationUS: "3589171798767", + Transitions: "2", + }, + "syncing": { + DurationUS: "6182323", + Transitions: "2", + }, + "tracking": { + DurationUS: "43", + Transitions: "2", + }, + }, + Time: "2021-Aug-24 20:44:43.466048 UTC", + Uptime: 3589480, + ValidatedLedger: &ServerLedgerState{ + BaseFee: 10, + CloseTime: 683153081, + Hash: "B52AC3876412A152FE9C0442801E685D148D05448D0238587DBA256330A98FD3", + ReserveBase: 20000000, + ReserveInc: 5000000, + Seq: 65887201, + }, + ValidationQuorum: 33, + }, + } + + j := `{ + "state": { + "build_version": "1.7.2", + "complete_ledgers": "64572720-65887201", + "io_latency_ms": 1, + "jq_trans_overflow": "0", + "last_close": { + "converge_time": 3005, + "proposers": 41 + }, + "load_base": 256, + "load_factor": 256, + "load_factor_fee_escalation": 256, + "load_factor_fee_queue": 256, + "load_factor_fee_reference": 256, + "load_factor_server": 256, + "peers": 216, + "pubkey_node": "n9MozjnGB3tpULewtTsVtuudg5JqYFyV3QFdAtVLzJaxHcBaxuXD", + "server_state": "full", + "server_state_duration_us": "3588969453592", + "state_accounting": { + "connected": { + "duration_us": "301410595", + "transitions": "2" + }, + "disconnected": { + "duration_us": "1207534", + "transitions": "2" + }, + "full": { + "duration_us": "3589171798767", + "transitions": "2" + }, + "syncing": { + "duration_us": "6182323", + "transitions": "2" + }, + "tracking": { + "duration_us": "43", + "transitions": "2" + } + }, + "time": "2021-Aug-24 20:44:43.466048 UTC", + "uptime": 3589480, + "validated_ledger": { + "base_fee": 10, + "close_time": 683153081, + "hash": "B52AC3876412A152FE9C0442801E685D148D05448D0238587DBA256330A98FD3", + "reserve_base": 20000000, + "reserve_inc": 5000000, + "seq": 65887201 + }, + "validation_quorum": 33 + } +}` + + if err := test.SerializeAndDeserialize(t, s, j); err != nil { + t.Error(err) + } +} diff --git a/model/client/utility/ping_request.go b/model/client/utility/ping_request.go new file mode 100644 index 00000000..1fe1a674 --- /dev/null +++ b/model/client/utility/ping_request.go @@ -0,0 +1,7 @@ +package utility + +type PingRequest struct{} + +func (*PingRequest) Method() string { + return "ping" +} diff --git a/model/client/utility/ping_response.go b/model/client/utility/ping_response.go new file mode 100644 index 00000000..c3afd43b --- /dev/null +++ b/model/client/utility/ping_response.go @@ -0,0 +1,3 @@ +package utility + +type PingResponse struct{} diff --git a/model/client/utility/random_request.go b/model/client/utility/random_request.go new file mode 100644 index 00000000..d0234240 --- /dev/null +++ b/model/client/utility/random_request.go @@ -0,0 +1,7 @@ +package utility + +type RandomRequest struct{} + +func (*RandomRequest) Method() string { + return "random" +} diff --git a/model/client/utility/random_response.go b/model/client/utility/random_response.go new file mode 100644 index 00000000..9d4378e9 --- /dev/null +++ b/model/client/utility/random_response.go @@ -0,0 +1,7 @@ +package utility + +import "github.com/xyield/xrpl-go/model/transactions/types" + +type RandomResponse struct { + Random types.Hash256 `json:"random"` +} diff --git a/model/client/utility/random_test.go b/model/client/utility/random_test.go new file mode 100644 index 00000000..608a36e3 --- /dev/null +++ b/model/client/utility/random_test.go @@ -0,0 +1,21 @@ +package utility + +import ( + "testing" + + "github.com/xyield/xrpl-go/test" +) + +func TestRandomResponse(t *testing.T) { + s := RandomResponse{ + Random: "8ED765AEBBD6767603C2C9375B2679AEC76E6A8133EF59F04F9FC1AAA70E41AF", + } + + j := `{ + "random": "8ED765AEBBD6767603C2C9375B2679AEC76E6A8133EF59F04F9FC1AAA70E41AF" +}` + + if err := test.SerializeAndDeserialize(t, s, j); err != nil { + t.Error(err) + } +} diff --git a/model/transactions/tx.go b/model/transactions/tx.go index bbb8603b..590e937e 100644 --- a/model/transactions/tx.go +++ b/model/transactions/tx.go @@ -17,6 +17,14 @@ func (*TxHash) TxType() TxType { return HashedTx } +type Binary struct { + TxBlob string `json:"tx_blob"` +} + +func (tx *Binary) TxType() TxType { + return BinaryTx +} + type BaseTx struct { Account types.Address TransactionType TxType @@ -95,11 +103,17 @@ func UnmarshalTx(data json.RawMessage) (Tx, error) { // TODO AMM endpoint support type txTypeParser struct { TransactionType TxType + TxBlob string `json:"tx_blob"` } var txType txTypeParser if err := json.Unmarshal(data, &txType); err != nil { return nil, err } + if len(txType.TxBlob) > 0 && len(txType.TransactionType) == 0 { + return &Binary{ + TxBlob: txType.TxBlob, + }, nil + } var tx Tx switch txType.TransactionType { case AccountSetTx: diff --git a/model/transactions/tx_type.go b/model/transactions/tx_type.go index 02fae2c7..15ab5dcd 100644 --- a/model/transactions/tx_type.go +++ b/model/transactions/tx_type.go @@ -32,5 +32,6 @@ const ( SignerListSetTx TxType = "SignerListSet" TrustSetTx TxType = "TrustSet" TicketCreateTx TxType = "TicketCreate" - HashedTx TxType = "HASH" // TX stored as a string, rather than complete tx obj + HashedTx TxType = "HASH" // TX stored as a string, rather than complete tx obj + BinaryTx TxType = "BINARY" // TX stored as a string, json tagged as 'tx_blob' )