Skip to content

Commit 03b9219

Browse files
committed
gen InputObjects and QueryArgumentObjects and support to auto build query string
1 parent 49e432b commit 03b9219

20 files changed

+2035
-516
lines changed

client.go

+1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ func ExecuteQuery[DATA any](ctx context.Context, cli *Client, query string) (dat
8383
if err != nil {
8484
return data, fmt.Errorf("read response body failed: %w", err)
8585
}
86+
//fmt.Printf("!!! respBody(len:%d): %s\n", len(respBody), string(respBody))
8687

8788
var result struct {
8889
Data DATA `json:"data"`

client_block.go

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package fuel
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"github.com/sentioxyz/fuel-go/util/query"
7+
)
8+
9+
type GetBlockOption struct {
10+
WithTransactions bool
11+
OnlyTransactionID bool
12+
}
13+
14+
func (c *Client) GetBlock(ctx context.Context, param QueryBlockParams, opt GetBlockOption) (*Block, error) {
15+
var ignoreChecker query.IgnoreChecker
16+
if opt.WithTransactions {
17+
if opt.OnlyTransactionID {
18+
ignoreChecker = query.IgnoreOtherField(Transaction{}, "Id")
19+
} else {
20+
// Otherwise it will create circular dependencies
21+
ignoreChecker = query.IgnoreObjects(SuccessStatus{}, FailureStatus{})
22+
}
23+
} else {
24+
ignoreChecker = query.IgnoreObjects(Transaction{})
25+
}
26+
// Contract.Bytecode is not needed
27+
ignoreChecker = query.MergeIgnores(ignoreChecker, query.IgnoreField(Contract{}, "Bytecode"))
28+
q := fmt.Sprintf("{ block(%s) { %s } }",
29+
query.Simple.GenParam(param),
30+
query.Simple.GenObjectQuery(Block{}, ignoreChecker),
31+
)
32+
//fmt.Printf("!!! query: %s\n", q)
33+
type resultType struct {
34+
Block *Block `json:"block"`
35+
}
36+
result, err := ExecuteQuery[resultType](ctx, c, q)
37+
if err != nil {
38+
return nil, err
39+
}
40+
return result.Block, nil
41+
}

client_block_test.go

+309
Large diffs are not rendered by default.

client_chain.go

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package fuel
2+
3+
import "context"
4+
5+
func (c *Client) GetLatestBlockHeight(ctx context.Context) (U32, error) {
6+
query := `
7+
{
8+
chain {
9+
latestBlock {
10+
header {
11+
height
12+
}
13+
}
14+
}
15+
}
16+
`
17+
type chainInfoResult struct {
18+
Chain ChainInfo `json:"chain"`
19+
}
20+
chainInfo, err := ExecuteQuery[chainInfoResult](ctx, c, query)
21+
if err != nil {
22+
return 0, err
23+
}
24+
return chainInfo.Chain.LatestBlock.Header.Height, nil
25+
}
26+
27+
func (c *Client) GetLatestBlockHeader(ctx context.Context) (Header, error) {
28+
query := `
29+
{
30+
chain {
31+
latestBlock {
32+
header {
33+
id
34+
daHeight
35+
transactionsCount
36+
messageReceiptCount
37+
transactionsRoot
38+
messageReceiptRoot
39+
height
40+
prevRoot
41+
time
42+
applicationHash
43+
}
44+
}
45+
}
46+
}
47+
`
48+
type resultType struct {
49+
Chain ChainInfo `json:"chain"`
50+
}
51+
result, err := ExecuteQuery[resultType](ctx, c, query)
52+
if err != nil {
53+
return Header{}, err
54+
}
55+
return result.Chain.LatestBlock.Header, nil
56+
}

client_chain_test.go

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package fuel
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"github.com/stretchr/testify/assert"
7+
"testing"
8+
)
9+
10+
func Test_getLastestBlockHeight(t *testing.T) {
11+
cli := NewClient(testnetEndpoint)
12+
h, err := cli.GetLatestBlockHeight(context.Background())
13+
assert.NoError(t, err)
14+
fmt.Printf("%d\n", h)
15+
}
16+
17+
func Test_getLastestBlockHeader(t *testing.T) {
18+
cli := NewClient(testnetEndpoint)
19+
h, err := cli.GetLatestBlockHeader(context.Background())
20+
assert.NoError(t, err)
21+
fmt.Printf("%#v\n", h)
22+
}

client_test.go

+79-6
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,23 @@ package fuel
33
import (
44
"context"
55
"github.com/ethereum/go-ethereum/common"
6+
"github.com/sentioxyz/fuel-go/util"
7+
"github.com/sentioxyz/fuel-go/util/query"
68
"github.com/stretchr/testify/assert"
79
"testing"
810
"time"
911
)
1012

11-
func Test_executeQuery(t *testing.T) {
12-
cli := NewClient("https://beta-5.fuel.network/graphql")
13+
const testnetEndpoint = "https://beta-5.fuel.network/graphql"
14+
15+
func Test_ExecuteQuery(t *testing.T) {
16+
cli := NewClient(testnetEndpoint)
1317

1418
type result struct {
1519
Block Block `json:"block"`
1620
}
1721
{
18-
query := `
22+
q := `
1923
{
2024
block(height: "9758550") {
2125
id
@@ -25,7 +29,7 @@ func Test_executeQuery(t *testing.T) {
2529
}
2630
}
2731
}`
28-
r, err := ExecuteQuery[result](context.Background(), cli, query)
32+
r, err := ExecuteQuery[result](context.Background(), cli, q)
2933

3034
ti, _ := time.Parse(time.RFC3339, "2024-04-15T02:44:02Z")
3135
assert.NoError(t, err)
@@ -39,7 +43,7 @@ func Test_executeQuery(t *testing.T) {
3943
}
4044

4145
{
42-
query := `
46+
q := `
4347
{
4448
block(height: "9758550") {
4549
id
@@ -49,8 +53,77 @@ func Test_executeQuery(t *testing.T) {
4953
}
5054
}
5155
}`
52-
_, err := ExecuteQuery[result](context.Background(), cli, query)
56+
_, err := ExecuteQuery[result](context.Background(), cli, q)
5357

5458
assert.EqualError(t, err, "execute query failed: (line:7,column:7): Unknown field \"tim\" on type \"Header\". Did you mean \"time\"?")
5559
}
5660
}
61+
62+
func Test_GenObjectQuery(t *testing.T) {
63+
assert.Equal(t,
64+
"id header { id daHeight transactionsCount messageReceiptCount transactionsRoot messageReceiptRoot height prevRoot time applicationHash } consensus { __typename ... on Genesis { chainConfigHash coinsRoot contractsRoot messagesRoot } ... on PoAConsensus { signature } } ",
65+
query.Simple.GenObjectQuery(Block{}, query.IgnoreObjects(Transaction{})),
66+
)
67+
assert.Equal(t, `id
68+
header {
69+
id
70+
daHeight
71+
transactionsCount
72+
messageReceiptCount
73+
transactionsRoot
74+
messageReceiptRoot
75+
height
76+
prevRoot
77+
time
78+
applicationHash
79+
}
80+
consensus {
81+
__typename
82+
... on Genesis {
83+
chainConfigHash
84+
coinsRoot
85+
contractsRoot
86+
messagesRoot
87+
}
88+
... on PoAConsensus {
89+
signature
90+
}
91+
}
92+
`,
93+
query.Beauty.GenObjectQuery(Block{}, query.IgnoreObjects(Transaction{})),
94+
)
95+
96+
assert.Equal(t,
97+
"id header { id daHeight transactionsCount messageReceiptCount transactionsRoot messageReceiptRoot height prevRoot time applicationHash } consensus { __typename ... on Genesis { chainConfigHash coinsRoot contractsRoot messagesRoot } ... on PoAConsensus { signature } } transactions { id inputAssetIds inputContracts { id bytecode salt } inputContract { utxoId balanceRoot stateRoot txPointer contract { id bytecode salt } } policies { gasPrice witnessLimit maturity maxFee } gasPrice scriptGasLimit maturity mintAmount mintAssetId txPointer isScript isCreate isMint inputs { __typename ... on InputCoin { utxoId owner amount assetId txPointer witnessIndex maturity predicateGasUsed predicate predicateData } ... on InputContract { utxoId balanceRoot stateRoot txPointer contract { id bytecode salt } } ... on InputMessage { sender recipient amount nonce witnessIndex predicateGasUsed data predicate predicateData } } outputs { __typename ... on CoinOutput { to amount assetId } ... on ContractOutput { inputIndex balanceRoot stateRoot } ... on ChangeOutput { to amount assetId } ... on VariableOutput { to amount assetId } ... on ContractCreated { contract { id bytecode salt } stateRoot } } outputContract { inputIndex balanceRoot stateRoot } witnesses receiptsRoot status { __typename ... on SubmittedStatus { time } ... on SqueezedOutStatus { reason } } receipts { contract { id bytecode salt } pc is to { id bytecode salt } toAddress amount assetId gas param1 param2 val ptr digest reason ra rb rc rd len receiptType result gasUsed data sender recipient nonce contractId subId } script scriptData bytecodeWitnessIndex bytecodeLength salt storageSlots rawPayload } ",
98+
query.Simple.GenObjectQuery(Block{}, query.IgnoreObjects(SuccessStatus{}, FailureStatus{})),
99+
)
100+
}
101+
102+
func Test_GenParam(t *testing.T) {
103+
assert.Equal(t,
104+
`id: "0x5d7f48fc777144b21ea760525936db069329dee2ccce509550c1478c1c0b5b2c" height: "1234" `,
105+
query.Simple.GenParam(QueryBlockParams{
106+
Id: &BlockId{Hash: common.HexToHash("0x5d7f48fc777144b21ea760525936db069329dee2ccce509550c1478c1c0b5b2c")},
107+
Height: util.GetPointer[U32](1234),
108+
}),
109+
)
110+
assert.Equal(t,
111+
"id: \"0x5d7f48fc777144b21ea760525936db069329dee2ccce509550c1478c1c0b5b2c\"\nheight: \"1234\"\n",
112+
query.Beauty.GenParam(QueryBlockParams{
113+
Id: &BlockId{Hash: common.HexToHash("0x5d7f48fc777144b21ea760525936db069329dee2ccce509550c1478c1c0b5b2c")},
114+
Height: util.GetPointer[U32](1234),
115+
}),
116+
)
117+
assert.Equal(t,
118+
"height: \"1234\"\n",
119+
query.Beauty.GenParam(QueryBlockParams{
120+
Height: util.GetPointer[U32](1234),
121+
}),
122+
)
123+
assert.Equal(t,
124+
"id: \"0x5d7f48fc777144b21ea760525936db069329dee2ccce509550c1478c1c0b5b2c\"\n",
125+
query.Beauty.GenParam(QueryBlockParams{
126+
Id: &BlockId{Hash: common.HexToHash("0x5d7f48fc777144b21ea760525936db069329dee2ccce509550c1478c1c0b5b2c")},
127+
}),
128+
)
129+
}

client_transaction.go

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package fuel
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"github.com/sentioxyz/fuel-go/util/query"
7+
)
8+
9+
type GetTransactionOption struct {
10+
WithReceipts bool
11+
WithStatus bool
12+
}
13+
14+
func (c *Client) GetTransaction(
15+
ctx context.Context,
16+
param QueryTransactionParams,
17+
opt GetTransactionOption,
18+
) (*Transaction, error) {
19+
ignoreCheckers := []query.IgnoreChecker{
20+
query.IgnoreField(Block{}, "Transactions"),
21+
query.IgnoreField(Contract{}, "Bytecode"),
22+
query.IgnoreField(SuccessStatus{}, "Receipts"),
23+
query.IgnoreField(FailureStatus{}, "Receipts"),
24+
}
25+
if !opt.WithReceipts {
26+
ignoreCheckers = append(ignoreCheckers, query.IgnoreField(Transaction{}, "Receipts"))
27+
}
28+
if !opt.WithStatus {
29+
ignoreCheckers = append(ignoreCheckers, query.IgnoreField(Transaction{}, "Status"))
30+
}
31+
q := fmt.Sprintf("{ transaction(%s) { %s } }",
32+
query.Simple.GenParam(param),
33+
query.Simple.GenObjectQuery(Transaction{}, query.MergeIgnores(ignoreCheckers...)),
34+
)
35+
//fmt.Printf("!!! query: %s\n", q)
36+
type resultType struct {
37+
Transaction *Transaction `json:"transaction"`
38+
}
39+
result, err := ExecuteQuery[resultType](ctx, c, q)
40+
if err != nil {
41+
return nil, err
42+
}
43+
return result.Transaction, nil
44+
}

0 commit comments

Comments
 (0)