diff --git a/integrations/viem-v2/package.json b/integrations/viem-v2/package.json index 180c8982..953d596e 100644 --- a/integrations/viem-v2/package.json +++ b/integrations/viem-v2/package.json @@ -29,7 +29,7 @@ "lint": "biome check .", "format": "biome format --write .", "clean": "rm -rf dist", - "test": "vitest --run", + "test": "vitest --run && timeout -k 5s 2s pnpm ts-node ./scripts/test.js", "build": "npm run build:cjs && npm run build:esm && npm run build:types", "build:cjs": "tsc --project ./tsconfig.build.json --module commonjs --outDir ./dist/_cjs --removeComments --verbatimModuleSyntax false && printf '{\"type\":\"commonjs\"}' > ./dist/_cjs/package.json && node scripts/rename-cjs.js", "build:esm": "tsc --project ./tsconfig.build.json --module es2015 --outDir ./dist/_esm && printf '{\"type\": \"module\",\"sideEffects\":false}' > ./dist/_esm/package.json", diff --git a/integrations/viem-v2/scripts/test.js b/integrations/viem-v2/scripts/test.js new file mode 100644 index 00000000..4092f0d5 --- /dev/null +++ b/integrations/viem-v2/scripts/test.js @@ -0,0 +1,32 @@ +/* +This script verifies that when Viem is used using Node via the CLI it won't +prevent Node from exiting cleanly. + +See: https://github.com/oasisprotocol/sapphire-paratime/pull/383 +*/ + +import { + createSapphireSerializer, + sapphireHttpTransport, + sapphireLocalnet, +} from "@oasisprotocol/sapphire-viem-v2"; +import { createPublicClient, defineChain } from "viem"; + +const transport = sapphireHttpTransport(); +const chain = sapphireLocalnet; +const publicClient = createPublicClient({ chain, transport }); +defineChain({ + id: 0x5afd, + name: "Oasis Sapphire Localnet", + network: "sapphire-localnet", + nativeCurrency: { name: "Sapphire Local Rose", symbol: "TEST", decimals: 18 }, + rpcUrls: { + default: { + http: ["http://localhost:8545"], + }, + }, + serializers: { + transaction: await createSapphireSerializer(publicClient), + }, + testnet: true, +}); diff --git a/integrations/viem-v2/src/index.ts b/integrations/viem-v2/src/index.ts index 02874b2b..a64e6a0a 100644 --- a/integrations/viem-v2/src/index.ts +++ b/integrations/viem-v2/src/index.ts @@ -119,13 +119,23 @@ export async function createSapphireSerializer< return originalSerializer; } - // As the serialized is synchronous, fetching keys while running + // As the serializer is synchronous, fetching keys while running const fetcher = new KeyFetcher(); const provider = client as EthereumProvider; await fetcher.fetch(provider); - setTimeout(async () => { + + // The fetcher runs in the background, routinely fetching the keys + // This means when the serializer requests a calldata public key one will + // have been retrieved pre-emptively. + const intervalId: NodeJS.Timeout | number = setInterval(async () => { await fetcher.fetch(provider); }, fetcher.timeoutMilliseconds); + // The interval ID is unreferenced to prevent Node from hanging at exit + // See discussion on https://github.com/oasisprotocol/sapphire-paratime/pull/379 + // This is only available in NodeJS, and not in browsers + if (typeof intervalId.unref === "function") { + intervalId.unref(); + } const wrappedSerializer = ((tx, sig?) => { if (!sig) {