From 55192f7adca22f1a0b49799c07377af92dcbc6dc Mon Sep 17 00:00:00 2001 From: liutian <435757679@qq.com> Date: Wed, 8 Nov 2023 22:46:07 +0800 Subject: [PATCH 1/3] support subgraph post --- crypto/internal/util.go | 2 +- go.mod | 9 +-- go.sum | 30 ++++++++ subgraph/client.go | 68 +++++++++++++++++++ subgraph/client_test.go | 53 +++++++++++++++ subgraph/get_subgraph_req.go | 45 ++++++++++++ .../flow_transaction_detail.go | 58 ++++++++++++++++ subgraph/transactions/flow_transactions.go | 55 +++++++++++++++ 8 files changed, 315 insertions(+), 5 deletions(-) create mode 100644 subgraph/client.go create mode 100644 subgraph/client_test.go create mode 100644 subgraph/get_subgraph_req.go create mode 100644 subgraph/transaction_detail/flow_transaction_detail.go create mode 100644 subgraph/transactions/flow_transactions.go diff --git a/crypto/internal/util.go b/crypto/internal/util.go index d26dcff9f..397fd2f3e 100644 --- a/crypto/internal/util.go +++ b/crypto/internal/util.go @@ -29,7 +29,7 @@ import ( func ParseSignature(kmsSignature []byte, curve crypto.SignatureAlgorithm) ([]byte, error) { var parsedSig struct{ R, S *big.Int } if _, err := asn1.Unmarshal(kmsSignature, &parsedSig); err != nil { - return nil, fmt.Errorf("asn1.Unmarshal: %w", err) + return nil, fmt.Errorf("asn1.Unmarshal: %w", err) } curveOrderLen := curveOrder(curve) diff --git a/go.mod b/go.mod index 53334c405..ef8ab9fc4 100644 --- a/go.mod +++ b/go.mod @@ -42,6 +42,7 @@ require ( github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/fxamacker/cbor/v2 v2.4.1-0.20230228173756-c0c9f774e40c // indirect github.com/fxamacker/circlehash v0.3.0 // indirect + github.com/go-resty/resty/v2 v2.10.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/go-cmp v0.5.9 // indirect @@ -67,13 +68,13 @@ require ( github.com/zeebo/blake3 v0.2.3 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/otel v1.16.0 // indirect - golang.org/x/crypto v0.10.0 // indirect + golang.org/x/crypto v0.14.0 // indirect golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect - golang.org/x/net v0.10.0 // indirect + golang.org/x/net v0.17.0 // indirect golang.org/x/oauth2 v0.7.0 // indirect golang.org/x/sync v0.2.0 // indirect - golang.org/x/sys v0.9.0 // indirect - golang.org/x/text v0.10.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9 // indirect diff --git a/go.sum b/go.sum index 8fba7a273..a85fb0400 100644 --- a/go.sum +++ b/go.sum @@ -83,6 +83,7 @@ github.com/bits-and-blooms/bitset v1.5.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edY github.com/btcsuite/btcd/btcec/v2 v2.2.1 h1:xP60mv8fvp+0khmrN0zTdPC3cNm24rfeE6lh2R/Yv3E= github.com/btcsuite/btcd/btcec/v2 v2.2.1/go.mod h1:9/CSmJxmuvqzX9Wh2fXMWToLOHhPd11lSPuIupwTkI8= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -111,6 +112,8 @@ github.com/fxamacker/circlehash v0.3.0/go.mod h1:3aq3OfVvsWtkWMb6A1owjOQFA+TLsD5 github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-resty/resty/v2 v2.10.0 h1:Qla4W/+TMmv0fOeeRqzEpXPLfTUnR5HZ1+lGs+CkiCo= +github.com/go-resty/resty/v2 v2.10.0/go.mod h1:iiP/OpA0CkcL3IGt1O0+/SIItFUbkkyw5BGXiVdTu+A= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -172,6 +175,7 @@ github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= @@ -265,6 +269,7 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= github.com/zeebo/blake3 v0.2.3 h1:TFoLXsjeXqRNFxSbk35Dk4YtszE/MQQGK10BH4ptoTg= @@ -288,9 +293,12 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -326,6 +334,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -360,8 +370,12 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -383,6 +397,8 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -420,12 +436,20 @@ golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/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-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -434,11 +458,15 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 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/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -486,6 +514,8 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/subgraph/client.go b/subgraph/client.go new file mode 100644 index 000000000..0ab9d5710 --- /dev/null +++ b/subgraph/client.go @@ -0,0 +1,68 @@ +package subgraph + +import ( + "errors" + "fmt" + "github.com/onflow/flow-go-sdk/subgraph/transaction_detail" + "github.com/onflow/flow-go-sdk/subgraph/transactions" + "log" + + gresty "github.com/go-resty/resty/v2" +) + +const ( + flow_subgraph_mainnet = "https://api.findlabs.io/flowdiver/v1/graphql" + flow_subgraph_testnet = "https://api.findlabs.io/flowdiver_testnet/v1/graphql" +) + +var errSubGraphHTTPError = errors.New("SubGraph http error") + +type subgraphClient struct { + sgClient *gresty.Client +} + +func NewFlowClient(baseUrl string) (*subgraphClient, error) { + grestyClient := gresty.New() + grestyClient.SetBaseURL(baseUrl) + grestyClient.OnAfterResponse(func(c *gresty.Client, r *gresty.Response) error { + statusCode := r.StatusCode() + if statusCode >= 400 { + method := r.Request.Method + url := r.Request.URL + return fmt.Errorf("%d cannot %s %s: %w", statusCode, method, url, errSubGraphHTTPError) + } + return nil + }) + fclient := &subgraphClient{ + sgClient: grestyClient, + } + return fclient, nil +} + +func (f *subgraphClient) GetTransactionsByAddress(graphRequest *GetSubGraphRequest) (*transactions.FlowTransactionsResp, error) { + var resultTxList transactions.FlowTransactionsResp + response, err := f.sgClient.R().SetResult(&resultTxList).SetBody(graphRequest).Post("") + if err != nil { + log.Printf("GetTxListByAddress Error: %+v\n", err) + return nil, err + } + if response.StatusCode() != 200 { + log.Printf("GetTxListByAddress Error: %+v\n", err) + return nil, err + } + return &resultTxList, nil +} + +func (f *subgraphClient) GetTransactionById(graphRequest *GetSubGraphRequest) (*transaction_detail.FlowTransactionDetailResp, error) { + var resultTxDetail transaction_detail.FlowTransactionDetailResp + response, err := f.sgClient.R().SetResult(&resultTxDetail).SetBody(graphRequest).Post("") + if err != nil { + log.Printf("GetTransactionById Error: %+v\n", err) + return nil, err + } + if response.StatusCode() != 200 { + log.Printf("GetTransactionById Error: %+v\n", err) + return nil, err + } + return &resultTxDetail, nil +} diff --git a/subgraph/client_test.go b/subgraph/client_test.go new file mode 100644 index 000000000..d0d72ceaa --- /dev/null +++ b/subgraph/client_test.go @@ -0,0 +1,53 @@ +package subgraph + +import ( + "encoding/json" + "fmt" + "testing" +) + +func TestSubgraphClient_GetTransactionById(t *testing.T) { + client, err := NewFlowClient(flow_subgraph_mainnet) + if err != nil { + panic(err) + } + transactionDetailReq := client.GetTransactionDetailReq("c260981bb2d5fc80986436cac01b1f609144f369f4c218005c1795c5a25dbbc8") + transactionById, err := client.GetTransactionById(transactionDetailReq) + if err != nil { + panic(err) + } + + printJsonStr(transactionById) +} + +func TestSubgraphClient_GetTransactionsByAddress(t *testing.T) { + client, err := NewFlowClient(flow_subgraph_mainnet) + if err != nil { + panic(err) + } + transactionsByAddressReq := client.GetTransactionsByAddressReq(&TransactionListVariables{ + Address: "0x8f4f599546e2d7eb", + Limit: 25, + Offset: 0, + TimeFilter: make(map[string]interface{}), + TypeFilter: make(map[string]interface{}), + StatusFilter: make(map[string]interface{}), + ProposerFilter: make(map[string]interface{}), + PayerFilter: make(map[string]interface{}), + GasRangeFilter: make(map[string]interface{}), + EventCountFilter: make(map[string]interface{}), + BlockHeightFilter: make(map[string]interface{}), + AuthorizersFilter: make(map[string]interface{}), + ActorFilter: make([]interface{}, 0)}) + transactions, err := client.GetTransactionsByAddress(transactionsByAddressReq) + if err != nil { + panic(err) + } + printJsonStr(transactions) + +} + +func printJsonStr(param interface{}) { + marshal, _ := json.Marshal(param) + fmt.Println(string(marshal)) +} diff --git a/subgraph/get_subgraph_req.go b/subgraph/get_subgraph_req.go new file mode 100644 index 000000000..7702669a7 --- /dev/null +++ b/subgraph/get_subgraph_req.go @@ -0,0 +1,45 @@ +package subgraph + +type GetSubGraphRequest struct { + OperationName string `json:"operationName"` + Query string `json:"query"` + Variables interface{} `json:"variables"` +} + +type TransactionDetailVariables struct { + Id string `json:"id"` +} + +func (f *subgraphClient) GetTransactionDetailReq(id string) *GetSubGraphRequest { + return &GetSubGraphRequest{ + OperationName: "TransactionDetails", + Query: "query TransactionDetails($id: String) {\n transactions(where: {id: {_eq: $id}}) {\n ...BasicTransaction\n ...ExtraDetails\n __typename\n }\n}\nfragment BasicTransaction on transactions {\n id\n timestamp\n payer\n authorizers\n gas_used\n fee\n status\n block_height\n error\n transaction_body_hash\n __typename\n}\nfragment ExtraDetails on transactions {\n block_id\n proposer\n proposer_index\n proposer_sequence_number\n transaction_body_hash\n transaction_body {\n body\n __typename\n }\n execution_effort\n argument\n events {\n name\n fields\n event_index\n __typename\n }\n contract_transactions {\n contract {\n name\n address\n __typename\n }\n __typename\n }\n __typename\n}", + Variables: TransactionDetailVariables{ + Id: id, + }, + } +} + +type TransactionListVariables struct { + Address string `json:"address"` + ActorFilter []interface{} `json:"actorFilter" ` + AuthorizersFilter interface{} `json:"authorizersFilter" ` + BlockHeightFilter interface{} `json:"blockHeightFilter" ` + EventCountFilter interface{} `json:"eventCountFilter" ` + GasRangeFilter interface{} `json:"gasRangeFilter" ` + Limit uint64 `json:"limit"` + Offset uint64 `json:"offset"` + PayerFilter interface{} `json:"payerFilter"` + ProposerFilter interface{} `json:"proposerFilter"` + StatusFilter interface{} `json:"statusFilter"` + TimeFilter interface{} `json:"timeFilter"` + TypeFilter interface{} `json:"typeFilter"` +} + +func (f *subgraphClient) GetTransactionsByAddressReq(txsVariables *TransactionListVariables) *GetSubGraphRequest { + return &GetSubGraphRequest{ + OperationName: "AccountTransactions", + Query: "query AccountTransactions($limit: Int, $offset: Int, $address: String, $authorizersFilter: String_array_comparison_exp, $blockHeightFilter: bigint_comparison_exp, $eventCountFilter: Int_comparison_exp!, $gasRangeFilter: bigint_comparison_exp, $payerFilter: String_comparison_exp, $statusFilter: String_comparison_exp, $typeFilter: String_comparison_exp, $timeFilter: timestamptz_comparison_exp, $actorFilter: [transactions_bool_exp!], $proposerFilter: String_comparison_exp) @cached(ttl: 60) {\n participations(\n limit: $limit\n offset: $offset\n where: {address: {_eq: $address}, transaction: {_not: {_or: $actorFilter}, status: $statusFilter, block_height: $blockHeightFilter, transaction_body_hash: $typeFilter, authorizers: $authorizersFilter, payer: $payerFilter, proposer: $proposerFilter, gas_used: $gasRangeFilter, timestamp: $timeFilter, events_aggregate: {count: {predicate: $eventCountFilter}}}}\n order_by: {timestamp: desc_nulls_first}\n ) {\n roles\n transaction {\n ...BasicTransaction\n ...TransactionEvents\n ...TransactionContracts\n ...ProposerInfo\n events {\n event_index\n fields\n __typename\n }\n __typename\n }\n __typename\n }\n}\nfragment BasicTransaction on transactions {\n id\n timestamp\n payer\n authorizers\n gas_used\n fee\n status\n block_height\n error\n transaction_body_hash\n __typename\n}\nfragment TransactionEvents on transactions {\n events {\n id\n name\n event_index\n __typename\n }\n __typename\n}\nfragment TransactionContracts on transactions {\n contract_transactions {\n contract_id\n __typename\n }\n __typename\n}\nfragment ProposerInfo on transactions {\n proposer\n proposer_index\n proposer_sequence_number\n __typename\n}", + Variables: txsVariables, + } +} diff --git a/subgraph/transaction_detail/flow_transaction_detail.go b/subgraph/transaction_detail/flow_transaction_detail.go new file mode 100644 index 000000000..8d2c75514 --- /dev/null +++ b/subgraph/transaction_detail/flow_transaction_detail.go @@ -0,0 +1,58 @@ +package transaction_detail + +type FlowTransactionDetailResp struct { + Data Data `json:"data"` +} +type TransactionBody struct { + Body string `json:"body"` + Typename string `json:"__typename"` +} +type Argument struct { + Key string `json:"Key"` + Value interface{} `json:"Value"` +} +type Fields struct { + ID int `json:"id"` + Duration int `json:"duration"` + ExpiryTimestamp int `json:"expiryTimestamp"` +} +type Events struct { + Name string `json:"name"` + Fields Fields `json:"fields"` + EventIndex int `json:"event_index"` + Typename string `json:"__typename"` +} +type Contract struct { + Name string `json:"name"` + Address string `json:"address"` + Typename string `json:"__typename"` +} +type ContractTransactions struct { + Contract Contract `json:"contract"` + Typename string `json:"__typename"` +} +type Transactions struct { + ID string `json:"id"` + Timestamp string `json:"timestamp"` + Payer string `json:"payer"` + Authorizers []string `json:"authorizers"` + GasUsed int `json:"gas_used"` + Fee float64 `json:"fee"` + Status string `json:"status"` + BlockHeight int `json:"block_height"` + Error string `json:"error"` + TransactionBodyHash string `json:"transaction_body_hash"` + Typename string `json:"__typename"` + BlockID string `json:"block_id"` + Proposer string `json:"proposer"` + ProposerIndex int `json:"proposer_index"` + ProposerSequenceNumber int `json:"proposer_sequence_number"` + TransactionBody TransactionBody `json:"transaction_body"` + ExecutionEffort float64 `json:"execution_effort"` + Argument []Argument `json:"argument"` + Events []Events `json:"events"` + ContractTransactions []ContractTransactions `json:"contract_transactions"` +} +type Data struct { + Transactions []Transactions `json:"transactions"` +} diff --git a/subgraph/transactions/flow_transactions.go b/subgraph/transactions/flow_transactions.go new file mode 100644 index 000000000..bfee0f7d9 --- /dev/null +++ b/subgraph/transactions/flow_transactions.go @@ -0,0 +1,55 @@ +package transactions + +type FlowTransactionsResp struct { + Data Data `json:"data"` +} +type Fields struct { + NftID int `json:"nftID"` + Expiry int64 `json:"expiry"` + NftType string `json:"nftType"` + NftUUID int `json:"nftUUID"` + CustomID string `json:"customID"` + Purchased bool `json:"purchased"` + SalePrice int `json:"salePrice"` + CommissionAmount int `json:"commissionAmount"` + ListingResourceID int `json:"listingResourceID"` + SalePaymentVaultType string `json:"salePaymentVaultType"` + StorefrontResourceID int `json:"storefrontResourceID"` +} +type Events struct { + ID string `json:"id"` + Name string `json:"name"` + EventIndex int `json:"event_index"` + Typename string `json:"__typename"` + Fields Fields `json:"fields"` +} +type ContractTransactions struct { + ContractID string `json:"contract_id"` + Typename string `json:"__typename"` +} +type Transaction struct { + ID string `json:"id"` + Timestamp string `json:"timestamp"` + Payer string `json:"payer"` + Authorizers []string `json:"authorizers"` + GasUsed int `json:"gas_used"` + Fee float64 `json:"fee"` + Status string `json:"status"` + BlockHeight int `json:"block_height"` + Error string `json:"error"` + TransactionBodyHash string `json:"transaction_body_hash"` + Typename string `json:"__typename"` + Events []Events `json:"events"` + ContractTransactions []ContractTransactions `json:"contract_transactions"` + Proposer string `json:"proposer"` + ProposerIndex int `json:"proposer_index"` + ProposerSequenceNumber int `json:"proposer_sequence_number"` +} +type Participations struct { + Roles []string `json:"roles"` + Transaction Transaction `json:"transaction"` + Typename string `json:"__typename"` +} +type Data struct { + Participations []Participations `json:"participations"` +} From 610e44facb6e1ed026a351dd39ed6b1f134aab12 Mon Sep 17 00:00:00 2001 From: liutian <435757679@qq.com> Date: Wed, 8 Nov 2023 22:56:51 +0800 Subject: [PATCH 2/3] add examples --- .../get_transactions_by_subgraph.go | 49 +++++++++++++++++++ subgraph/client.go | 9 ++-- subgraph/client_test.go | 4 +- 3 files changed, 56 insertions(+), 6 deletions(-) create mode 100644 examples/get_transactions_by_subgraph/get_transactions_by_subgraph.go diff --git a/examples/get_transactions_by_subgraph/get_transactions_by_subgraph.go b/examples/get_transactions_by_subgraph/get_transactions_by_subgraph.go new file mode 100644 index 000000000..197499202 --- /dev/null +++ b/examples/get_transactions_by_subgraph/get_transactions_by_subgraph.go @@ -0,0 +1,49 @@ +package main + +import ( + "encoding/json" + "fmt" + + "github.com/onflow/flow-go-sdk/subgraph" +) + +func main() { + client, err := subgraph.NewFlowClient(subgraph.Flow_subgraph_mainnet) + if err != nil { + panic(err) + } + transactionDetailReq := client.GetTransactionDetailReq("c260981bb2d5fc80986436cac01b1f609144f369f4c218005c1795c5a25dbbc8") + transactionById, err := client.GetTransactionById(transactionDetailReq) + if err != nil { + panic(err) + } + + printJsonStr(transactionById) + + fmt.Println("--------------------------------------------------") + + transactionsByAddressReq := client.GetTransactionsByAddressReq(&subgraph.TransactionListVariables{ + Address: "0x8f4f599546e2d7eb", + Limit: 25, + Offset: 0, + TimeFilter: make(map[string]interface{}), + TypeFilter: make(map[string]interface{}), + StatusFilter: make(map[string]interface{}), + ProposerFilter: make(map[string]interface{}), + PayerFilter: make(map[string]interface{}), + GasRangeFilter: make(map[string]interface{}), + EventCountFilter: make(map[string]interface{}), + BlockHeightFilter: make(map[string]interface{}), + AuthorizersFilter: make(map[string]interface{}), + ActorFilter: make([]interface{}, 0)}) + transactions, err := client.GetTransactionsByAddress(transactionsByAddressReq) + if err != nil { + panic(err) + } + printJsonStr(transactions) +} + +func printJsonStr(param interface{}) { + marshal, _ := json.Marshal(param) + fmt.Println(string(marshal)) +} diff --git a/subgraph/client.go b/subgraph/client.go index 0ab9d5710..a1a18ee6a 100644 --- a/subgraph/client.go +++ b/subgraph/client.go @@ -3,16 +3,17 @@ package subgraph import ( "errors" "fmt" - "github.com/onflow/flow-go-sdk/subgraph/transaction_detail" - "github.com/onflow/flow-go-sdk/subgraph/transactions" "log" gresty "github.com/go-resty/resty/v2" + + "github.com/onflow/flow-go-sdk/subgraph/transaction_detail" + "github.com/onflow/flow-go-sdk/subgraph/transactions" ) const ( - flow_subgraph_mainnet = "https://api.findlabs.io/flowdiver/v1/graphql" - flow_subgraph_testnet = "https://api.findlabs.io/flowdiver_testnet/v1/graphql" + Flow_subgraph_mainnet = "https://api.findlabs.io/flowdiver/v1/graphql" + Flow_subgraph_testnet = "https://api.findlabs.io/flowdiver_testnet/v1/graphql" ) var errSubGraphHTTPError = errors.New("SubGraph http error") diff --git a/subgraph/client_test.go b/subgraph/client_test.go index d0d72ceaa..6e65799b9 100644 --- a/subgraph/client_test.go +++ b/subgraph/client_test.go @@ -7,7 +7,7 @@ import ( ) func TestSubgraphClient_GetTransactionById(t *testing.T) { - client, err := NewFlowClient(flow_subgraph_mainnet) + client, err := NewFlowClient(Flow_subgraph_mainnet) if err != nil { panic(err) } @@ -21,7 +21,7 @@ func TestSubgraphClient_GetTransactionById(t *testing.T) { } func TestSubgraphClient_GetTransactionsByAddress(t *testing.T) { - client, err := NewFlowClient(flow_subgraph_mainnet) + client, err := NewFlowClient(Flow_subgraph_mainnet) if err != nil { panic(err) } From d3d9862440a10359aa68ecbe9839c8a874e73740 Mon Sep 17 00:00:00 2001 From: tiantianlikeu <35363659+tiantianlikeu@users.noreply.github.com> Date: Thu, 9 Nov 2023 09:26:06 +0800 Subject: [PATCH 3/3] Update util.go --- crypto/internal/util.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/internal/util.go b/crypto/internal/util.go index 397fd2f3e..d26dcff9f 100644 --- a/crypto/internal/util.go +++ b/crypto/internal/util.go @@ -29,7 +29,7 @@ import ( func ParseSignature(kmsSignature []byte, curve crypto.SignatureAlgorithm) ([]byte, error) { var parsedSig struct{ R, S *big.Int } if _, err := asn1.Unmarshal(kmsSignature, &parsedSig); err != nil { - return nil, fmt.Errorf("asn1.Unmarshal: %w", err) + return nil, fmt.Errorf("asn1.Unmarshal: %w", err) } curveOrderLen := curveOrder(curve)