From f1427d9eef4698cd20bdaaac7004d056ab75a6bb Mon Sep 17 00:00:00 2001 From: Abdulkadir DILSIZ Date: Sat, 5 Mar 2022 23:03:09 +0300 Subject: [PATCH] Completed base project --- LICENSE | 191 ++++++++++++++++++++ LICENSE.fasthttp-websocket | 22 +++ README.md | 64 ++++++- client.go | 350 ++++++++++++++++++++++++++++++++++++- go.mod | 4 + go.sum | 25 +++ message.go | 34 ++++ transaction.go | 40 +++++ 8 files changed, 728 insertions(+), 2 deletions(-) create mode 100644 LICENSE create mode 100644 LICENSE.fasthttp-websocket create mode 100644 go.sum create mode 100644 message.go create mode 100644 transaction.go diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..5e340d4 --- /dev/null +++ b/LICENSE @@ -0,0 +1,191 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright 2013-2018 TransferChain A.G + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/LICENSE.fasthttp-websocket b/LICENSE.fasthttp-websocket new file mode 100644 index 0000000..7590376 --- /dev/null +++ b/LICENSE.fasthttp-websocket @@ -0,0 +1,22 @@ +Copyright (c) 2013 The Gorilla WebSocket Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/README.md b/README.md index 17724e8..456225a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,65 @@ # TCABCI Read Node Go WebSocket Client -**in preparation \ No newline at end of file +TransferChain Fastest Read Network WebSocket Client +Read Node Address: [https://read-node-01.transferchain.io](https://read-node-01.transferchain.io) +Read Node WebSocket Address: [wss://read-node-01.transferchain.io/ws](wss://read-node-01.transferchain.io/ws) + +## Installation + +```shell +$ go get github.com/TransferChain/tcabci-read-go-client +``` + +## Example + +**Subscribe, Listen and Unsubscribe Example** + +```go +package main + +import ( + "log" + "github.com/TransferChain/tcabci-read-go-client" +) + +func main() { + var wsClient = tcabci_read_go_client.NewClient("read-node-01.transferchain.io") + + if err := wsClient.Start(); err != nil { + log.Fatal(err) + } + + addresses := []string{ + "", + "", + } + + if err := wsClient.Subscribe(addresses); err != nil { + log.Fatal(err) + } + + done := make(chan struct{}) + // If a transaction has been sent to your addresses, the callback you set here will be called. + wsClient.SetListenCallback(func(transaction tcabci_read_go_client.Transaction) { + // + done <- struct{}{} + }) + + go func() { + if err := wsClient.Listen(); err != nil { + log.Fatal(err) + } + }() + + <-done + close(done) + + _ = wsClient.Unsubscribe() + wsClient.Stop() +} +``` + +## License + +tcabci-read-go-client is licensed under the Apache License, Version 2.0. See [LICENSE](LICENSE) for the full license +text. \ No newline at end of file diff --git a/client.go b/client.go index 555e3fd..e2d703a 100644 --- a/client.go +++ b/client.go @@ -1,3 +1,351 @@ +// Package tcabci_read_go_client +// +// Copyright 2013-2018 TransferChain A.G +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package tcabci_read_go_client -type Client struct{} +import ( + "context" + "encoding/json" + "errors" + "fmt" + "github.com/fasthttp/websocket" + "log" + "net/http" + "net/url" + "time" +) + +const ( + retryingSecond = 25 + retryingInterval = time.Second * retryingSecond + writeWait = 10 * time.Second + // Time allowed to read the next pong message from the peer. + pongWait = 10 * time.Second + // Send pings to peer with this period. Must be less than pongWait. + pingPeriod = (pongWait * 9) / 10 + // Maximum message size allowed from peer. + maxMessageSize = 5 * 1024 * 1024 + closedMessage = "CLOSE" +) + +// Client TCABCI Read Node Websocket Client +type Client interface { + Start() error + Stop() + SetListenCallback(func(transaction Transaction)) + Subscribe(addresses []string) error + Unsubscribe() error + Listen() error +} + +type client struct { + conn *websocket.Conn + address string + ctx context.Context + mainCtx context.Context + mainCtxCancel context.CancelFunc + version string + started bool + connected bool + subscribed bool + retrieverTicker *time.Ticker + listenCallback func(transaction Transaction) + subscribedAddresses map[string]bool + listenCtx context.Context + listenCtxCancel context.CancelFunc +} + +// NewClient make ws client +func NewClient(address string) Client { + c := new(client) + c.version = "v0.1.0" + c.address = address + c.ctx = context.Background() + c.retrieverTicker = time.NewTicker(retryingInterval) + c.subscribedAddresses = make(map[string]bool) + c.connected = false + c.subscribed = false + + return c +} + +func (c *client) retriever() { + if c.started { + return + } + for { + select { + case <-c.retrieverTicker.C: + c.makeConn() + } + } +} + +func (c *client) makeConn() { + if c.started { + return + } + var err error + headers := http.Header{} + headers.Set("X-Client", fmt.Sprintf("tcabaci-read-go-client%s", c.version)) + + wsURL := url.URL{ + Scheme: "ws", + Host: c.address, + Path: "/ws", + } + + c.conn, _, err = websocket.DefaultDialer.DialContext(c.ctx, + wsURL.String(), + headers) + if err != nil { + c.connected = false + log.Println("dial: ", err) + return + } + + if !c.connected && c.subscribed { + _ = c.unsubscribe(false) + if err := c.subscribe(true, nil); err != nil { + log.Println(fmt.Sprintf("client not subscribed. It will try again in %d seconds", retryingSecond)) + return + } + } + + c.conn.SetReadLimit(maxMessageSize) + _ = c.conn.SetReadDeadline(time.Now().Add(pongWait)) + c.conn.SetPongHandler(func(string) error { _ = c.conn.SetReadDeadline(time.Now().Add(pongWait)); return nil }) + c.connected = true +} + +// SetListenCallback Callback that will be called when the WS client captures a +// transaction event +func (c *client) SetListenCallback(fn func(transaction Transaction)) { + c.listenCallback = fn +} + +// Start contexts and ws client and client retriever +func (c *client) Start() error { + if c.started { + return errors.New("client has ben already started") + } + c.mainCtx, c.mainCtxCancel = context.WithCancel(c.ctx) + c.listenCtx, c.listenCtxCancel = context.WithCancel(c.mainCtx) + + c.makeConn() + go c.retriever() + + c.started = true + + return nil +} + +// Stop ws client and ws contexts +func (c *client) Stop() { + c.retrieverTicker.Stop() + + if c.connected { + _ = c.conn.Close() + } + // + c.listenCtxCancel() + c.mainCtxCancel() + c.subscribed = false + c.started = false +} + +// Subscribe to given addresses +func (c *client) Subscribe(addresses []string) error { + return c.subscribe(false, addresses) +} + +func (c *client) subscribe(already bool, addresses []string) error { + if err := c.check(); err != nil { + return err + } + + if c.connected && c.subscribed { + return errors.New("client has been already subscribed") + } + + tAddresses := make([]string, 0) + if already { + for address, _ := range c.subscribedAddresses { + tAddresses = append(tAddresses, address) + } + } else { + if len(addresses) == 0 { + return errors.New("addresses count is zero") + } + + tAddresses = addresses + + if len(c.subscribedAddresses) > 0 { + newAddress := make([]string, 0) + for i := 0; i < len(addresses); i++ { + if _, ok := c.subscribedAddresses[addresses[i]]; !ok { + newAddress = append(newAddress, addresses[i]) + } + } + + tAddresses = newAddress + } + } + + subscribeMessage := Message{ + IsWeb: false, + Type: Subscribe, + Addrs: tAddresses, + } + + b, err := json.Marshal(subscribeMessage) + if err != nil { + return err + } + + if err := c.conn.WriteMessage(websocket.TextMessage, b); err != nil { + return err + } + + for i := 0; i < len(tAddresses); i++ { + c.subscribedAddresses[tAddresses[i]] = true + } + + c.subscribed = true + + return nil +} + +// Unsubscribe to given addresses +func (c *client) Unsubscribe() error { + return c.unsubscribe(false) +} + +func (c *client) unsubscribe(_ bool) error { + if !c.subscribed { + return errors.New("client has not yet subscribed") + } + + if err := c.check(); err != nil { + return err + } + + addresses := make([]string, 0) + + for address, _ := range c.subscribedAddresses { + addresses = append(addresses, address) + } + + unsubscribeMessage := Message{ + Type: Unsubscribe, + Addrs: addresses, + } + + b, err := json.Marshal(unsubscribeMessage) + if err != nil { + return err + } + + if err := c.conn.WriteMessage(websocket.TextMessage, b); err != nil { + return err + } + + c.subscribed = false + + return nil +} + +func (c client) check() error { + if !c.connected { + return errors.New("client not connected") + } + + if c.conn == nil { + return errors.New("client is not initialized") + } + + return nil +} + +// Listen to given addresses +func (c client) Listen() error { + if err := c.check(); err != nil { + return err + } + + if !c.started { + return errors.New("client has not been started yet") + } + + retrying := false + closed := false + listening := true + for listening { + messageType, readingMessage, err := c.conn.ReadMessage() + if err != nil { + return err + } + + switch messageType { + case websocket.TextMessage: + if json.Valid(readingMessage) { + var transaction Transaction + if err := json.Unmarshal(readingMessage, &transaction); err == nil { + c.listenCallback(transaction) + } + } else { + // + } + + if string(readingMessage) == closedMessage { + listening = false + closed = true + continue + } + case websocket.PingMessage, + websocket.PongMessage, + websocket.BinaryMessage: + break + case websocket.CloseMessage: + listening = false + closed = true + continue + case websocket.CloseTryAgainLater: + listening = false + closed = true + retrying = true + continue + default: + break + } + } + + if closed { + c.Stop() + + if retrying { + c.started = false + if err := c.Start(); err != nil { + return err + } + if err := c.Listen(); err != nil { + return err + } + } + } + + return nil +} diff --git a/go.mod b/go.mod index 1319495..9a1cbaa 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,7 @@ module github.com/TransferChain/tcabci-read-go-client go 1.16 + +require ( + github.com/fasthttp/websocket v1.5.0 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..6acd2d4 --- /dev/null +++ b/go.sum @@ -0,0 +1,25 @@ +github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= +github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/fasthttp/websocket v1.5.0 h1:B4zbe3xXyvIdnqjOZrafVFklCUq5ZLo/TqCt5JA1wLE= +github.com/fasthttp/websocket v1.5.0/go.mod h1:n0BlOQvJdPbTuBkZT0O5+jk/sp/1/VCzquR1BehI2F4= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/klauspost/compress v1.14.1 h1:hLQYb23E8/fO+1u53d02A97a8UnsddcvYzq4ERRU4ds= +github.com/klauspost/compress v1.14.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/savsgio/gotils v0.0.0-20211223103454-d0aaa54c5899 h1:Orn7s+r1raRTBKLSc9DmbktTT04sL+vkzsbRD2Q8rOI= +github.com/savsgio/gotils v0.0.0-20211223103454-d0aaa54c5899/go.mod h1:oejLrk1Y/5zOF+c/aHtXqn3TFlzzbAgPWg8zBiAHDas= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.33.0 h1:mHBKd98J5NcXuBddgjvim1i3kWzlng1SzLhrnBOU9g8= +github.com/valyala/fasthttp v1.33.0/go.mod h1:KJRK/MXx0J+yd0c5hlR+s1tIHD72sniU8ZJjl97LIw4= +github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= +golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220111093109-d55c255bac03/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/message.go b/message.go new file mode 100644 index 0000000..371bffc --- /dev/null +++ b/message.go @@ -0,0 +1,34 @@ +// Package tcabci_read_go_client +// +// Copyright 2013-2018 TransferChain A.G +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tcabci_read_go_client + +// MessageType .. +type MessageType string + +const ( + // Subscribe message + Subscribe MessageType = "subscribe" + // Unsubscribe message + Unsubscribe MessageType = "unsubscribe" +) + +// Message .. +type Message struct { + IsWeb bool `json:"is_web"` + Type MessageType `json:"type"` + Addrs []string `json:"addrs"` +} diff --git a/transaction.go b/transaction.go new file mode 100644 index 0000000..8db37f8 --- /dev/null +++ b/transaction.go @@ -0,0 +1,40 @@ +// Package tcabci_read_go_client +// +// Copyright 2013-2018 TransferChain A.G +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tcabci_read_go_client + +import "time" + +type Transaction struct { + ID uint64 `db:"id" json:"id"` + BlockID uint64 `db:"block_id" json:"block_id"` + Height uint64 `db:"height" json:"height"` + Identifier string `db:"identifier" json:"identifier"` + Version uint `db:"version" json:"version"` + Typ string `db:"typ" json:"typ"` + SenderAddr string `db:"sender_addr" json:"sender_addr"` + RecipientAddr string `db:"recipient_addr" json:"recipient_addr"` + Data Bytea `db:"data" json:"data"` + Sign Bytea `db:"sign" json:"sign"` + Fee uint64 `db:"fee" json:"fee"` + Hash string `db:"hash" json:"hash"` + InsertedAt time.Time `db:"inserted_at" json:"inserted_at"` +} + +type Bytea struct { + Bytes []byte + Status int +}