Skip to content

Commit

Permalink
Add NodeVersionInfo SDK interaction
Browse files Browse the repository at this point in the history
  • Loading branch information
jribbink committed Mar 22, 2024
1 parent 9cc00a6 commit c2ef7e3
Show file tree
Hide file tree
Showing 23 changed files with 393 additions and 32 deletions.
11 changes: 11 additions & 0 deletions .changeset/pretty-bugs-bathe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"@onflow/fcl-react-native": minor
"@onflow/transport-grpc": minor
"@onflow/transport-http": minor
"@onflow/fcl-core": minor
"@onflow/typedefs": minor
"@onflow/fcl": minor
"@onflow/sdk": minor
---

Add GetNodeVersionInfo SDK Interaction
2 changes: 2 additions & 0 deletions packages/fcl-core/src/fcl-core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export {send} from "@onflow/sdk"
export {decode} from "@onflow/sdk"
export {account} from "@onflow/sdk"
export {block} from "@onflow/sdk"
export {nodeVersionInfo} from "@onflow/sdk"
export {isOk, isBad, why, pipe, build} from "@onflow/sdk"
export {withPrefix, sansPrefix, display} from "@onflow/util-address"
export {template as cadence} from "@onflow/util-template"
Expand All @@ -56,6 +57,7 @@ export {getCollection} from "@onflow/sdk"
export {getTransactionStatus} from "@onflow/sdk"
export {getTransaction} from "@onflow/sdk"
export {getNetworkParameters} from "@onflow/sdk"
export {getNodeVersionInfo} from "@onflow/sdk"
export {authorizations, authorization} from "@onflow/sdk"
export {subscribeEvents} from "@onflow/sdk"
export {args, arg} from "@onflow/sdk"
Expand Down
2 changes: 2 additions & 0 deletions packages/fcl-react-native/src/fcl-react-native.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export {
getTransactionStatus,
getTransaction,
getNetworkParameters,
getNodeVersionInfo,
authorizations,
authorization,
args,
Expand All @@ -59,6 +60,7 @@ export {
validator,
invariant,
subscribeEvents,
nodeVersionInfo,
} from "@onflow/fcl-core"

import {getMutate, getCurrentUser, initServiceRegistry, setIsReactNative} from "@onflow/fcl-core"
Expand Down
4 changes: 3 additions & 1 deletion packages/fcl/src/fcl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export {
getTransactionStatus,
getTransaction,
getNetworkParameters,
getNodeVersionInfo,
authorizations,
authorization,
args,
Expand All @@ -58,7 +59,8 @@ export {
param,
validator,
invariant,
subscribeEvents
subscribeEvents,
nodeVersionInfo,
} from "@onflow/fcl-core"

import {getMutate, getCurrentUser, initServiceRegistry } from "@onflow/fcl-core"
Expand Down
10 changes: 10 additions & 0 deletions packages/sdk/src/build/build-get-node-version-info.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import {initInteraction, isGetNodeVersionInfo} from "../interaction/interaction"
import {getNodeVersionInfo} from "./build-get-node-version-info"

describe("Build Get Node Version Info", () => {
test("Get Node Version Info", async () => {
let ix = await getNodeVersionInfo()(initInteraction())

expect(isGetNodeVersionInfo(ix)).toBe(true)
})
})
17 changes: 17 additions & 0 deletions packages/sdk/src/build/build-get-node-version-info.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Ok, makeGetNodeVerionInfo, pipe } from "../interaction/interaction"

/**
* @description - A builder function that returns the interaction to get a block header
* @param {boolean} [isSealed] - Whether or not the block should be sealed
* @returns {Function} - An interaction object
*/
export function getNodeVersionInfo(isSealed = null) {
return pipe([
makeGetNodeVerionInfo,
ix => {
ix.block.isSealed = isSealed
return Ok(ix)
},
])
}

8 changes: 7 additions & 1 deletion packages/sdk/src/decode/decode.js
Original file line number Diff line number Diff line change
Expand Up @@ -231,9 +231,15 @@ export const decodeResponse = async (response, customDecoders = {}) => {
chainId: formattedChainId,
}
} else if (response.streamConnection) {
return decodeStream(response.streamConnection, decodeResponse, customDecoders)
return decodeStream(
response.streamConnection,
decodeResponse,
customDecoders
)
} else if (response.heartbeat) {
return response.heartbeat
} else if (response.nodeVersionInfo) {
return response.nodeVersionInfo
}

return null
Expand Down
10 changes: 7 additions & 3 deletions packages/sdk/src/interaction/interaction.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {InteractionAccount} from "@onflow/typedefs"
import {resolveAccounts} from "../sdk"
import {InteractionAccount, prepAccount, initAccount, initInteraction} from "./interaction"
import {prepAccount, initAccount, initInteraction} from "./interaction"

describe("prepAccount", () => {
test("prepAccount converts account object keyId to integer", async () => {
Expand All @@ -14,8 +15,11 @@ describe("prepAccount", () => {
}),
}

const ix = prepAccount(acct, {role: "proposer"})({...initInteraction(), accounts: {}})
expect(ix.accounts[ix.proposer||""].keyId).toBe(parseInt(keyId))
const ix = prepAccount(acct, {role: "proposer"})({
...initInteraction(),
accounts: {},
})
expect(ix.accounts[ix.proposer || ""].keyId).toBe(parseInt(keyId))
})

test("prepAccount converts authorization function keyId to integer", async () => {
Expand Down
6 changes: 6 additions & 0 deletions packages/sdk/src/interaction/interaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,9 @@ export const makeGetNetworkParameters /* */ = makeIx(
export const makeSubscribeEvents /* */ = makeIx(
InteractionTag.SUBSCRIBE_EVENTS
)
export const makeGetNodeVerionInfo /* */ = makeIx(
InteractionTag.GET_NODE_VERSION_INFO
)

const is = (wat: InteractionTag) => (ix: Interaction) => ix.tag === wat

Expand All @@ -291,6 +294,9 @@ export const isGetCollection /* */ = is(InteractionTag.GET_COLLECTION)
export const isGetNetworkParameters /* */ = is(
InteractionTag.GET_NETWORK_PARAMETERS
)
export const isGetNodeVersionInfo /* */ = is(
InteractionTag.GET_NODE_VERSION_INFO
)
export const isSubscribeEvents /* */ = is(
InteractionTag.SUBSCRIBE_EVENTS
)
Expand Down
14 changes: 14 additions & 0 deletions packages/sdk/src/node-version-info/node-version-info.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import {send} from "../send/send.js"
import {decodeResponse as decode} from "../decode/decode.js"
import {getNodeVersionInfo} from "../build/build-get-node-version-info"
import {NodeVersionInfo} from "@onflow/typedefs"

/**
* @description Returns the version information from to connected node
* @returns A promise that resolves to a block response
*/
export async function nodeVersionInfo(
opts: any = {}
): Promise<NodeVersionInfo> {
return send([getNodeVersionInfo()], opts).then(decode)
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ exports[`Response - Snapshot 1`] = `
"heartbeat": null,
"latestBlock": null,
"networkParameters": null,
"nodeVersionInfo": null,
"streamConnection": null,
"tag": null,
"transaction": null,
Expand Down
3 changes: 2 additions & 1 deletion packages/sdk/src/response/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ const DEFAULT_RESPONSE = {
"collection":null,
"networkParameters":null,
"streamConnection":null,
"heartbeat":null
"heartbeat":null,
"nodeVersionInfo": null,
}

export const response = () => ({...DEFAULT_RESPONSE})
2 changes: 2 additions & 0 deletions packages/sdk/src/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export {template as cdc} from "@onflow/util-template"
// Helpers
export {account} from "./account/account.js"
export {block} from "./block/block.js"
export {nodeVersionInfo} from "./node-version-info/node-version-info"

// Builders
export {authorizations, authorization} from "./build/build-authorizations.js"
Expand All @@ -61,6 +62,7 @@ export {getCollection} from "./build/build-get-collection"
export {getTransactionStatus} from "./build/build-get-transaction-status.js"
export {getTransaction} from "./build/build-get-transaction.js"
export {getNetworkParameters} from "./build/build-get-network-parameters.js"
export {getNodeVersionInfo} from "./build/build-get-node-version-info"
export {limit} from "./build/build-limit.js"
export {args, arg} from "./build/build-arguments"
export {proposer} from "./build/build-proposer.js"
Expand Down
1 change: 1 addition & 0 deletions packages/transport-grpc/src/sdk-send-grpc.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ export {sendGetTransactionStatus} from "./send-get-transaction-status.js"
export {sendPing} from "./send-ping.js"
export {sendTransaction} from "./send-transaction.js"
export {sendGetNetworkParameters} from "./send-get-network-parameters.js"
export {sendGetNodeVersionInfo} from "./send-get-node-version-info.js"
export {send} from "./send-grpc.js"
39 changes: 39 additions & 0 deletions packages/transport-grpc/src/send-get-node-version-info.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import {invariant} from "@onflow/util-invariant"
import {AccessAPI, GetNodeVersionInfoRequest} from "@onflow/protobuf"
import {unary as defaultUnary} from "./unary"

const u8ToHex = (u8, context) => context.Buffer.from(u8).toString("hex")

export async function sendGetNodeVersionInfo(ix, context = {}, opts = {}) {
invariant(
opts.node,
`SDK Send Get Node Version Info Error: opts.node must be defined.`
)
invariant(
context.response,
`SDK Send Get Node Version INfo Error: context.response must be defined.`
)

const unary = opts.unary || defaultUnary

ix = await ix

const req = new GetNodeVersionInfoRequest()

const res = await unary(opts.node, AccessAPI.GetNodeVersionInfo, req, context)

let ret = context.response()
ret.tag = ix.tag

let nodeVersionInfo = res.getInfo()
ret.nodeVersionInfo = {
semver: nodeVersionInfo.getSemver(),
commit: nodeVersionInfo.getCommit(),
sporkId: u8ToHex(nodeVersionInfo.getSporkId_asU8(), context),
protocolVersion: parseInt(nodeVersionInfo.getProtocolVersion()),
sporkRootBlockHeight: parseInt(nodeVersionInfo.getSporkRootBlockHeight()),
nodeRootBlockHeight: parseInt(nodeVersionInfo.getNodeRootBlockHeight()),
}

return ret
}
56 changes: 56 additions & 0 deletions packages/transport-grpc/src/send-get-node-version-info.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import {AccessAPI} from "@onflow/protobuf"
import {sendGetNodeVersionInfo} from "./send-get-node-version-info"
import {
build,
getNodeVersionInfo,
resolve,
response as responseADT,
} from "@onflow/sdk"

describe("Get Network Parameters", () => {
test("GetNetworkParametersResult", async () => {
const unaryMock = jest.fn()

unaryMock.mockReturnValue({
getInfo: () => ({
getSemver: () => "0.0.0",
getCommit: () => "0123456789abcdef",
getSporkId_asU8: () => new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),
getProtocolVersion: () => "999",
getSporkRootBlockHeight: () => "123",
getNodeRootBlockHeight: () => "456",
}),
})

const response = await sendGetNodeVersionInfo(
await resolve(await build([getNodeVersionInfo()])),
{
Buffer,
response: responseADT,
},
{
unary: unaryMock,
node: "localhost:3000",
}
)

expect(unaryMock.mock.calls.length).toEqual(1)

const unaryMockArgs = unaryMock.mock.calls[0]

expect(unaryMockArgs.length).toEqual(4)

const unaryType = unaryMock.mock.calls[0][1]

expect(unaryType).toEqual(AccessAPI.GetNodeVersionInfo)

expect(response.nodeVersionInfo).toStrictEqual({
semver: "0.0.0",
commit: "0123456789abcdef",
sporkId: "00010203040506070809",
protocolVersion: 999,
sporkRootBlockHeight: 123,
nodeRootBlockHeight: 456,
})
})
})
5 changes: 5 additions & 0 deletions packages/transport-grpc/src/send-grpc.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ export const send = async (ix, context = {}, opts = {}) => {
return opts.sendSubscribeEvents(ix, context, opts)
else
throw new Error(`SDK Send Error: subscribeEvents is not supported by this transport.`)
case context.ix.isGetNodeVersionInfo?.(ix):
if (opts.sendGetNodeVersionInfo)
return opts.sendGetNodeVersionInfo(ix, context, opts)
else
throw new Error(`SDK Send Error: getNodeVersionInfo is not supported by this transport.`)
default:
return ix
}
Expand Down
1 change: 1 addition & 0 deletions packages/transport-http/src/sdk-send-http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export {sendGetTransactionStatus} from "./send-get-transaction-status"
export {sendPing} from "./send-ping"
export {sendTransaction} from "./send-transaction"
export {sendGetNetworkParameters} from "./send-get-network-parameters"
export {sendGetNodeVersionInfo} from "./send-get-node-version-info"
export {connectSubscribeEvents} from "./connect-subscribe-events"
export {send} from "./send-http"
export {WebsocketError} from "./connect-ws"
Expand Down
60 changes: 60 additions & 0 deletions packages/transport-http/src/send-get-node-version-info.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import {sendGetNodeVersionInfo} from "./send-get-node-version-info"
import {
build,
getNodeVersionInfo,
resolve,
response as responseADT,
} from "@onflow/sdk"

describe("Get Node Version Info", () => {
test("GetNodeVersionInfo", async () => {
const httpRequestMock = jest.fn()

const returnedNodeVersionInfo = {
semver: "v0.33.11-access-register-cache",
commit: "4ffc02f147654ef3a936ab1b435e00a5d5d37701",
spork_id:
"709530929e4968daff19c303ef1fc5f0a7649b3a1ce7d5ee5202056969524c94",
protocol_version: "32",
spork_root_block_height: "65264619",
node_root_block_height: "65264619",
}

httpRequestMock.mockReturnValue(returnedNodeVersionInfo)

const response = await sendGetNodeVersionInfo(
await resolve(await build([getNodeVersionInfo()])),
{
response: responseADT,
},
{
httpRequest: httpRequestMock,
node: "localhost:8888",
}
)

expect(httpRequestMock.mock.calls.length).toEqual(1)

const httpRequestMockArgs = httpRequestMock.mock.calls[0]

expect(httpRequestMockArgs.length).toEqual(1)

const valueSent = httpRequestMock.mock.calls[0][0]

expect(valueSent).toEqual({
hostname: "localhost:8888",
path: "/v1/node_version_info",
method: "GET",
})

expect(response.nodeVersionInfo).toStrictEqual({
semver: "v0.33.11-access-register-cache",
commit: "4ffc02f147654ef3a936ab1b435e00a5d5d37701",
sporkId:
"709530929e4968daff19c303ef1fc5f0a7649b3a1ce7d5ee5202056969524c94",
protocolVersion: 32,
sporkRootBlockHeight: 65264619,
nodeRootBlockHeight: 65264619,
})
})
})
Loading

0 comments on commit c2ef7e3

Please sign in to comment.