diff --git a/.changeset/tasty-dragons-battle.md b/.changeset/tasty-dragons-battle.md new file mode 100644 index 0000000..dbbb3f4 --- /dev/null +++ b/.changeset/tasty-dragons-battle.md @@ -0,0 +1,5 @@ +--- +"@xcfx/node": patch +--- + +Added config files update cive version" diff --git a/.gitignore b/.gitignore index dab1c59..d312042 100644 --- a/.gitignore +++ b/.gitignore @@ -191,6 +191,8 @@ Temporary Items # iCloud generated files *.icloud *.js +index.d.ts +index.d.ts.map !conflux.js !conflux.d.ts ## pnpm ## diff --git a/README.md b/README.md index 4b47982..7c73f8b 100644 --- a/README.md +++ b/README.md @@ -28,20 +28,20 @@ npm install @xcfx/node ```ts import { createServer } from "@xcfx/node"; +import { http, createPublicClient } from "cive"; async function main() { - const server = await createServer(); + const server = await createServer({ + jsonrpcHttpPort: 12537, + }); await server.start(); - const options = { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: '{"jsonrpc":"2.0","method":"cfx_getStatus","id":1}', - }; + const client = createPublicClient({ + transport: http(`http://127.0.0.1:12537`), + }); - const response = await fetch("http://localhost:12537", options); - const data = await response.json(); + const status = await client.getStatus(); // safe to stop the server await server.stop(); @@ -55,7 +55,7 @@ await main(); import { createServer } from "@xcfx/node"; async function main() { - const server = await createServer({ ...serverConfig, ...ConfluxConfig }); + const server = await createServer({ ...ConfluxConfig }); } ``` @@ -99,21 +99,32 @@ export interface ConfluxConfig { */ logLevel?: string; /** - * The port of the websocket JSON-RPC server. - * @default 12535 + * The port of the websocket JSON-RPC server(public_rpc_apis is user defined). + * if not set, the JSON-RPC server will not be started. + * @default null */ jsonrpcWsPort?: number; /** - * The port of the HTTP JSON-RPC server. - * @default 12537 + * `tcp_port` is the TCP port that the process listens for P2P messages. The default is 32323. + * @default 32323 */ - jsonrpcHttpPort?: number; + tcpPort?: number; + /** + * `udp_port` is the UDP port used for node discovery. + * @default 32323 + */ + udpPort?: number; /** * Possible Core space names are: all, safe, cfx, pos, debug, pubsub, test, trace, txpool. * `safe` only includes `cfx` and `pubsub`, `txpool`. * @default "all" */ publicRpcApis?: string; + /** + * Possible eSpace names are: eth, ethpubsub, ethdebug. + * @default 'evm' + */ + publicEvmRpcApis?: string; /** * The chain ID of the network.(core space) * @default 1234 @@ -129,14 +140,20 @@ export interface ConfluxConfig { * @default "123456" */ devPosPrivateKeyEncryptionPassword?: string; - /** The private key of the genesis, every account will be receive 1000 CFX */ + /** The private key of the genesis, every account will be receive 10000 CFX */ genesisSecrets?: Array; - /** @default: false */ + /** + * If it's `true`, `DEFERRED_STATE_EPOCH_COUNT` blocks are generated after + * receiving a new tx through RPC calling to pack and execute this + * transaction + */ devPackTxImmediately?: boolean; - /** @default:0 */ + /** @default:1 */ posReferenceEnableHeight?: number; - /** @default: 1 */ + /** @default:2 */ defaultTransitionTime?: number; + /** @default:3 */ + cip1559TransitionHeight?: number; /** @default: temp dir */ confluxDataDir?: string; /** pos config path */ @@ -151,5 +168,62 @@ export interface ConfluxConfig { * @default sqlite */ blockDbType?: string; + /** bootnodes is a list of nodes that a conflux node trusts, and will be used to sync the blockchain when a node starts. */ + bootnodes?: string; + /** Window size for PoW manager */ + powProblemWindowSize?: number; + /** # Secret key for stratum. The value is 64-digit hex string. If not set, the RPC subscription will not check the authorization. */ + stratumSecret?: string; + /** `public_address` is the address of this node used */ + publicAddress?: string; + /** + * `jsonrpc_http_keep_alive` is used to control whether to set KeepAlive for rpc HTTP connections. + * @default false + */ + jsonrpcHttpKeepAlive?: boolean; + /** `print_memory_usage_period_s` is the period for printing memory usage. */ + printMemoryUsagePeriodS?: number; + /** + * The port of the http JSON-RPC server.public_rpc_apis is user defined). + * if not set, the JSON-RPC server will not be started. + * @default null + */ + jsonrpcHttpPort?: number; + /** + * The port of the tcp JSON-RPC server. public_rpc_apis is user defined). + * if not set, the JSON-RPC server will not be started. + * @default null + */ + jsonrpcTcpPort?: number; + /** + * The port of the http JSON-RPC server public_rpc_apis is user defined). + * if not set, the JSON-RPC server will not be started. + * @default null + */ + jsonrpcHttpEthPort?: number; + /** + * The port of the websocket JSON-RPC serverpublic_rpc_apis is user defined). + * if not set, the JSON-RPC server will not be started. + * @default null + */ + jsonrpcWsEthPort?: number; + /** + * The port of the tcp JSON-RPC server(public_rpc_apis is "all"). + * if not set, the JSON-RPC server will not be started. + * @default null + */ + jsonrpcLocalTcpPort?: number; + /** + * The port of the http JSON-RPC server(public_rpc_apis is "all"). + * if not set, the JSON-RPC server will not be started. + * @default null + */ + jsonrpcLocalHttpPort?: number; + /** + * The port of the websocket JSON-RPC server(public_rpc_apis is "all"). + * if not set, the JSON-RPC server will not be started. + * @default null + */ + jsonrpcLocalWsPort?: number; } ``` diff --git a/__test__/manualBlockGeneration.test.ts b/__test__/manualBlockGeneration.test.ts index 7e2aad6..a0bbcd9 100644 --- a/__test__/manualBlockGeneration.test.ts +++ b/__test__/manualBlockGeneration.test.ts @@ -1,4 +1,10 @@ -import { http, createPublicClient, createWalletClient, webSocket } from "cive"; +import { + http, + createPublicClient, + createTestClient, + createWalletClient, + webSocket, +} from "cive"; import { privateKeyToAccount } from "cive/accounts"; import { parseCFX } from "cive/utils"; import { beforeAll, describe, expect, test } from "vitest"; @@ -88,12 +94,14 @@ describe("manual block generation", async () => { transport: http(`http://127.0.0.1:${HTTP_PORT}`), }); + const testClient = createTestClient({ + chain: localChain, + transport: http(`http://127.0.0.1:${HTTP_PORT}`), + }); + const status = await client.getStatus(); - await client.request({ - method: "generate_empty_blocks", - params: [10], - }); + await testClient.mine({ blocks: 10 }); const status1 = await client.getStatus(); expect(status1.blockNumber).toBe(status.blockNumber + 10n); diff --git a/__test__/server.test.ts b/__test__/server.test.ts index aa66140..44eb204 100644 --- a/__test__/server.test.ts +++ b/__test__/server.test.ts @@ -13,7 +13,6 @@ describe("server", () => { }); await server.start(); const client = createPublicClient({ - chain: localChain, transport: http(`http://127.0.0.1:${jsonrpcHttpPort}`), }); diff --git a/index.ts b/index.ts index df84615..e193d68 100644 --- a/index.ts +++ b/index.ts @@ -1,4 +1,5 @@ import path from "node:path"; +import { http, createTestClient, webSocket } from "cive"; import { type ConfluxConfig, ConfluxNode } from "./conflux"; export type Config = { @@ -7,6 +8,8 @@ export type Config = { * @default false */ log?: boolean; + timeout?: number; + retryInterval?: number; } & ConfluxConfig; export type CreateServerReturnType = { @@ -21,6 +24,8 @@ export async function createServer( if (isServiceCreated) { throw new Error("The server has already been created"); } + const { timeout = 20000, retryInterval = 300 } = config; + isServiceCreated = true; const { log = false, ...userConfig } = config; @@ -41,7 +46,7 @@ export async function createServer( const node = new ConfluxNode(); return { async start() { - return new Promise((resolve, reject) => { + await new Promise((resolve, reject) => { node.startNode(filledConfig, (err) => { if (err) { reject(err); @@ -50,6 +55,15 @@ export async function createServer( } }); }); + + if (filledConfig.jsonrpcHttpPort || filledConfig.jsonrpcWsPort) { + await retryGetCurrentSyncPhase({ + httpPort: filledConfig.jsonrpcHttpPort, + wsPort: filledConfig.jsonrpcWsPort, + timeout: timeout, + retryInterval: retryInterval, + }); + } }, async stop() { return new Promise((resolve, reject) => { @@ -64,3 +78,46 @@ export async function createServer( }, }; } + +type retryGetCurrentSyncPhaseParameters = { + httpPort?: number; + wsPort?: number; + timeout: number; + retryInterval: number; +}; + +async function retryGetCurrentSyncPhase({ + httpPort, + wsPort, + timeout, + retryInterval, +}: retryGetCurrentSyncPhaseParameters) { + if (!httpPort && !wsPort) return; + + const testClient = createTestClient({ + transport: httpPort + ? http(`http://127.0.0.1:${httpPort}`) + : webSocket(`ws://127.0.0.1:${wsPort}`), + }); + + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), timeout); + + try { + while (!controller.signal.aborted) { + const phase = await testClient.getCurrentSyncPhase(); + if (phase === "NormalSyncPhase") { + clearTimeout(timeoutId); + return; + } + await new Promise((resolve) => setTimeout(resolve, retryInterval)); + } + } catch (error) { + if (!controller.signal.aborted) { + throw new Error("Get node sync phase timeout"); + } + throw error; + } finally { + clearTimeout(timeoutId); + } +} diff --git a/package.json b/package.json index 63484c2..16061f8 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ }, "license": "MIT", "keywords": ["conflux", "conflux-client"], - "files": ["index.d.ts", "index.js", "conflux.js", "conflux.d.ts"], + "files": ["index.d.ts", "index.js", "conflux.js", "conflux.d.ts", "configs"], "napi": { "binaryName": "node", "targets": [ @@ -43,7 +43,7 @@ "changeset:publish": "pnpm changeset:prepublish && changeset publish" }, "dependencies": { - "cive": "^0.6.0" + "cive": "0.7.0" }, "devDependencies": { "@biomejs/biome": "1.8.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index de80168..b17ae6d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: dependencies: cive: - specifier: ^0.6.0 - version: 0.6.0(typescript@5.6.3) + specifier: 0.7.0 + version: 0.7.0(typescript@5.6.3) optionalDependencies: '@xcfx/node-darwin-arm64': specifier: workspace:* @@ -992,8 +992,8 @@ packages: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} - cive@0.6.0: - resolution: {integrity: sha512-0K2EP76nfLnL1c5TpE7qNcYht6q69BORgvAAuN8gUnReMzkyi3a9N6kYhEoTD1l/vAmd9yoo4NxR0yltehNUkg==} + cive@0.7.0: + resolution: {integrity: sha512-Q4E2Slx2QGH4iMQn7RGg9l+8lT59gV4RZ7KWl4IAYcMi/2q+t7X0MvjXDviNmymz3DanxxUwBzyaUibm17YaOg==} cli-width@4.1.0: resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} @@ -1449,8 +1449,8 @@ packages: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} - viem@2.21.35: - resolution: {integrity: sha512-f3EFc5JILeA9veuNymUN8HG/nKP9ykC0NCgwFrZWuxcCc822GaP0IEnkRBsHGqmjwbz//FxJFmvtx7TBcdVs0A==} + viem@2.21.38: + resolution: {integrity: sha512-MxhURy+F3eRtxkOoj7YdJTStJxqnWcP0MQZycVsxsVB4eZLKZPZfh7AgpfPjWHmPHmeVZcOqaGzFTmuPpqp06w==} peerDependencies: typescript: '>=5.0.4' peerDependenciesMeta: @@ -2444,13 +2444,13 @@ snapshots: ci-info@3.9.0: {} - cive@0.6.0(typescript@5.6.3): + cive@0.7.0(typescript@5.6.3): dependencies: '@noble/curves': 1.6.0 '@noble/hashes': 1.5.0 '@scure/bip32': 1.5.0 '@scure/bip39': 1.4.0 - viem: 2.21.35(typescript@5.6.3)(zod@3.23.8) + viem: 2.21.38(typescript@5.6.3)(zod@3.23.8) zod: 3.23.8 transitivePeerDependencies: - bufferutil @@ -2871,7 +2871,7 @@ snapshots: universalify@0.1.2: {} - viem@2.21.35(typescript@5.6.3)(zod@3.23.8): + viem@2.21.38(typescript@5.6.3)(zod@3.23.8): dependencies: '@adraffy/ens-normalize': 1.11.0 '@noble/curves': 1.6.0 diff --git a/tsconfig.json b/tsconfig.json index 222f275..6432daf 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,8 +8,9 @@ "noUnusedParameters": true, "esModuleInterop": true, "allowSyntheticDefaultImports": true, - "skipLibCheck": true + "skipLibCheck": true, + "declaration": true }, - "include": ["."], + "include": ["./index.ts"], "exclude": ["node_modules", "benchmark", "__test__", "target", "pos_config"] }