Skip to content

Commit fe75835

Browse files
feat(xrpl): add query helpers to clients
1 parent 675fe54 commit fe75835

File tree

4 files changed

+191
-0
lines changed

4 files changed

+191
-0
lines changed

xrpl/rpc/queries.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"github.com/Peersyst/xrpl-go/xrpl/queries/common"
88
ledger "github.com/Peersyst/xrpl-go/xrpl/queries/ledger"
99
nft "github.com/Peersyst/xrpl-go/xrpl/queries/nft"
10+
"github.com/Peersyst/xrpl-go/xrpl/queries/oracle"
1011
path "github.com/Peersyst/xrpl-go/xrpl/queries/path"
1112
server "github.com/Peersyst/xrpl-go/xrpl/queries/server"
1213
utility "github.com/Peersyst/xrpl-go/xrpl/queries/utility"
@@ -504,6 +505,24 @@ func (c *Client) GetServerState(req *server.StateRequest) (*server.StateResponse
504505
return &lr, nil
505506
}
506507

508+
// Oracle queries
509+
510+
// GetAggregatePrice retrieves the aggregate price of an asset.
511+
// It takes a GetAggregatePriceRequest as input and returns a GetAggregatePriceResponse,
512+
// along with any error encountered.
513+
func (c *Client) GetAggregatePrice(req *oracle.GetAggregatePriceRequest) (*oracle.GetAggregatePriceResponse, error) {
514+
res, err := c.Request(req)
515+
if err != nil {
516+
return nil, err
517+
}
518+
var lr oracle.GetAggregatePriceResponse
519+
err = res.GetResult(&lr)
520+
if err != nil {
521+
return nil, err
522+
}
523+
return &lr, nil
524+
}
525+
507526
// Utility queries
508527

509528
// Ping tests the connection to the server.

xrpl/rpc/queries_test.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
ledgertypes "github.com/Peersyst/xrpl-go/xrpl/queries/ledger/types"
1414
nft "github.com/Peersyst/xrpl-go/xrpl/queries/nft"
1515
nfttypes "github.com/Peersyst/xrpl-go/xrpl/queries/nft/types"
16+
"github.com/Peersyst/xrpl-go/xrpl/queries/oracle"
1617
path "github.com/Peersyst/xrpl-go/xrpl/queries/path"
1718
pathtypes "github.com/Peersyst/xrpl-go/xrpl/queries/path/types"
1819
server "github.com/Peersyst/xrpl-go/xrpl/queries/server"
@@ -2767,6 +2768,73 @@ func TestClient_GetServerState(t *testing.T) {
27672768
}
27682769
}
27692770

2771+
func TestClient_GetAggregatePrice(t *testing.T) {
2772+
tests := []struct {
2773+
name string
2774+
mockResponse string
2775+
mockStatus int
2776+
request *oracle.GetAggregatePriceRequest
2777+
expected oracle.GetAggregatePriceResponse
2778+
expectedError string
2779+
}{
2780+
{
2781+
name: "successful response",
2782+
mockResponse: `{
2783+
"result": {
2784+
"median": "123.45",
2785+
"time": 1234567890
2786+
}
2787+
}`,
2788+
mockStatus: 200,
2789+
request: &oracle.GetAggregatePriceRequest{},
2790+
expected: oracle.GetAggregatePriceResponse{
2791+
Median: "123.45",
2792+
Time: 1234567890,
2793+
},
2794+
},
2795+
{
2796+
name: "error response",
2797+
mockResponse: `{
2798+
"result": {
2799+
"error": "invalidParams",
2800+
"status": "error"
2801+
}
2802+
}`,
2803+
mockStatus: 200,
2804+
request: &oracle.GetAggregatePriceRequest{},
2805+
expectedError: "invalidParams",
2806+
},
2807+
}
2808+
2809+
for _, tt := range tests {
2810+
t.Run(tt.name, func(t *testing.T) {
2811+
mc := testutil.JSONRPCMockClient{}
2812+
mc.DoFunc = testutil.MockResponse(tt.mockResponse, tt.mockStatus, &mc)
2813+
2814+
cfg, err := NewClientConfig("http://testnode/", WithHTTPClient(&mc))
2815+
require.NoError(t, err)
2816+
2817+
client := NewClient(cfg)
2818+
2819+
resp, err := client.Request(tt.request)
2820+
2821+
if tt.expectedError != "" {
2822+
require.Error(t, err)
2823+
require.Contains(t, err.Error(), tt.expectedError)
2824+
return
2825+
}
2826+
2827+
require.NoError(t, err)
2828+
2829+
var priceResp oracle.GetAggregatePriceResponse
2830+
err = resp.GetResult(&priceResp)
2831+
require.NoError(t, err)
2832+
2833+
require.Equal(t, tt.expected, priceResp)
2834+
})
2835+
}
2836+
}
2837+
27702838
func TestClient_Ping(t *testing.T) {
27712839
tests := []struct {
27722840
name string

xrpl/websocket/queries.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"github.com/Peersyst/xrpl-go/xrpl/queries/common"
88
"github.com/Peersyst/xrpl-go/xrpl/queries/ledger"
99
"github.com/Peersyst/xrpl-go/xrpl/queries/nft"
10+
"github.com/Peersyst/xrpl-go/xrpl/queries/oracle"
1011
"github.com/Peersyst/xrpl-go/xrpl/queries/path"
1112
"github.com/Peersyst/xrpl-go/xrpl/queries/server"
1213
"github.com/Peersyst/xrpl-go/xrpl/queries/utility"
@@ -508,6 +509,24 @@ func (c *Client) GetServerState(req *server.StateRequest) (*server.StateResponse
508509
return &lr, nil
509510
}
510511

512+
// Oracle queries
513+
514+
// GetAggregatePrice retrieves the aggregate price of an asset.
515+
// It takes a GetAggregatePriceRequest as input and returns a GetAggregatePriceResponse,
516+
// along with any error encountered.
517+
func (c *Client) GetAggregatePrice(req *oracle.GetAggregatePriceRequest) (*oracle.GetAggregatePriceResponse, error) {
518+
res, err := c.Request(req)
519+
if err != nil {
520+
return nil, err
521+
}
522+
var lr oracle.GetAggregatePriceResponse
523+
err = res.GetResult(&lr)
524+
if err != nil {
525+
return nil, err
526+
}
527+
return &lr, nil
528+
}
529+
511530
// Utility queries
512531

513532
// Ping tests the connection to the server.

xrpl/websocket/queries_test.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
ledgertypes "github.com/Peersyst/xrpl-go/xrpl/queries/ledger/types"
1515
"github.com/Peersyst/xrpl-go/xrpl/queries/nft"
1616
nfttypes "github.com/Peersyst/xrpl-go/xrpl/queries/nft/types"
17+
"github.com/Peersyst/xrpl-go/xrpl/queries/oracle"
1718
"github.com/Peersyst/xrpl-go/xrpl/queries/path"
1819
pathtypes "github.com/Peersyst/xrpl-go/xrpl/queries/path/types"
1920
"github.com/Peersyst/xrpl-go/xrpl/queries/server"
@@ -2865,6 +2866,90 @@ func TestClient_GetServerState(t *testing.T) {
28652866
}
28662867
}
28672868

2869+
func TestClient_GetAggregatePrice(t *testing.T) {
2870+
tests := []struct {
2871+
name string
2872+
serverMessages []map[string]any
2873+
expected *oracle.GetAggregatePriceResponse
2874+
expectedErr error
2875+
}{
2876+
{
2877+
name: "Valid aggregate price",
2878+
serverMessages: []map[string]any{
2879+
{
2880+
"id": 1,
2881+
"result": map[string]any{
2882+
"median": "123.45",
2883+
"time": float64(1234567890),
2884+
},
2885+
},
2886+
},
2887+
expected: &oracle.GetAggregatePriceResponse{
2888+
Median: "123.45",
2889+
Time: 1234567890,
2890+
},
2891+
expectedErr: nil,
2892+
},
2893+
{
2894+
name: "error response",
2895+
serverMessages: []map[string]any{
2896+
{
2897+
"id": 1,
2898+
"error": "invalidParams",
2899+
"status": "error",
2900+
"type": "response",
2901+
},
2902+
},
2903+
expected: nil,
2904+
expectedErr: errors.New("invalidParams"),
2905+
},
2906+
}
2907+
2908+
for _, tt := range tests {
2909+
t.Run(tt.name, func(t *testing.T) {
2910+
ws := &testutil.MockWebSocketServer{Msgs: tt.serverMessages}
2911+
s := ws.TestWebSocketServer(func(c *websocket.Conn) {
2912+
for _, m := range tt.serverMessages {
2913+
err := c.WriteJSON(m)
2914+
if err != nil {
2915+
t.Errorf("error writing message: %v", err)
2916+
}
2917+
}
2918+
})
2919+
defer s.Close()
2920+
2921+
url, _ := testutil.ConvertHTTPToWS(s.URL)
2922+
cl := &Client{
2923+
cfg: ClientConfig{
2924+
host: url,
2925+
},
2926+
}
2927+
2928+
if err := cl.Connect(); err != nil {
2929+
t.Errorf("Error connecting to server: %v", err)
2930+
}
2931+
2932+
result, err := cl.GetAggregatePrice(&oracle.GetAggregatePriceRequest{})
2933+
2934+
if tt.expectedErr != nil {
2935+
if err == nil || err.Error() != tt.expectedErr.Error() {
2936+
t.Errorf("Expected error %v, but got %v", tt.expectedErr, err)
2937+
}
2938+
} else {
2939+
if err != nil {
2940+
t.Errorf("Unexpected error: %v", err)
2941+
}
2942+
}
2943+
2944+
if !reflect.DeepEqual(tt.expected, result) {
2945+
t.Errorf("Expected %+v, but got %+v", tt.expected, result)
2946+
}
2947+
2948+
cl.Disconnect()
2949+
})
2950+
}
2951+
}
2952+
28682953
func TestClient_Ping(t *testing.T) {
28692954
tests := []struct {
28702955
name string

0 commit comments

Comments
 (0)