{"_id":"@atlas-oracle/pull-oracle-consumer-sdk","_rev":"2-4d74db0beaa3504d93501c8a415e3c84","name":"@atlas-oracle/pull-oracle-consumer-sdk","dist-tags":{"latest":"1.0.2"},"versions":{"1.0.1":{"name":"@atlas-oracle/pull-oracle-consumer-sdk","version":"1.0.1","license":"BUSL-1.1","_id":"@atlas-oracle/pull-oracle-consumer-sdk@1.0.1","maintainers":[{"name":"layne96","email":"same.h@atlasoracle.io"},{"name":"michael_wgy","email":"michael.wang@atlasoracle.io"}],"dist":{"shasum":"07ff786cab76836db0f5909b067f14eb220c9bb3","tarball":"https://registry.npmjs.org/@atlas-oracle/pull-oracle-consumer-sdk/-/pull-oracle-consumer-sdk-1.0.1.tgz","fileCount":8,"integrity":"sha512-7l9dSY7Rk/hBL7NOAlIjEuUDM80VRqoOVCE8cGylQAQZVtVqKwekb5HrPac0IM3xkrAV0TcNqiWLKG9+vKfd9A==","signatures":[{"sig":"MEYCIQDFaqUVOZdBxerxQriFaEnt1Zg/WWgeuOSdrZr3Q5e+/QIhAMVkRoIJwrKj9bjDIVln7to8cjqW0YzAPAuG1NGh7zmG","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":118458},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"d2520dcae1eb9f0705201f6a481833913b80889a","scripts":{"lint":"eslint src tests --no-error-on-unmatched-pattern","test":"vitest run","build":"tsup","format":"prettier --write .","release":"auto shipit","changelog":"auto changelog","typecheck":"tsc --noEmit","test:watch":"vitest","labels:create":"auto create-labels","test:coverage":"vitest run --coverage","version:check":"auto version"},"_npmUser":{"name":"layne96","email":"same.h@atlasoracle.io"},"_npmVersion":"10.8.2","description":"Pull Oracle Consumer TypeScript SDK","directories":{},"_nodeVersion":"20.20.2","dependencies":{"viem":"^2.21.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"ws":"^8.18.0","auto":"^11.3.6","tsup":"^8.3.0","eslint":"^9.15.0","vitest":"^2.1.0","prettier":"^3.4.0","@types/ws":"^8.5.13","typescript":"^5.7.0","typescript-eslint":"^8.15.0"},"peerDependencies":{"ws":"^8.0.0"},"peerDependenciesMeta":{"ws":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/pull-oracle-consumer-sdk_1.0.1_1781067836922_0.011194512564832504","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@atlas-oracle/pull-oracle-consumer-sdk","version":"1.0.2","description":"Pull Oracle Consumer TypeScript SDK","homepage":"https://github.com/oracle-atlas/pull-oracle-consumer-sdk#readme","repository":{"type":"git","url":"git+https://github.com/oracle-atlas/pull-oracle-consumer-sdk.git"},"bugs":{"url":"https://github.com/oracle-atlas/pull-oracle-consumer-sdk/issues"},"type":"module","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"scripts":{"build":"tsup","typecheck":"tsc --noEmit","test":"vitest run","test:watch":"vitest","test:coverage":"vitest run --coverage","lint":"eslint src tests --no-error-on-unmatched-pattern","format":"prettier --write .","release":"auto shipit","version:check":"auto version","changelog":"auto changelog","labels:create":"auto create-labels"},"publishConfig":{"registry":"https://registry.npmjs.org/","access":"public"},"engines":{"node":">=18"},"dependencies":{"viem":"^2.21.0"},"peerDependencies":{"ws":"^8.0.0"},"peerDependenciesMeta":{"ws":{"optional":true}},"devDependencies":{"@types/ws":"^8.5.13","auto":"^11.3.6","eslint":"^9.15.0","prettier":"^3.4.0","tsup":"^8.3.0","typescript":"^5.7.0","typescript-eslint":"^8.15.0","vitest":"^2.1.0","ws":"^8.18.0"},"license":"BUSL-1.1","_id":"@atlas-oracle/pull-oracle-consumer-sdk@1.0.2","gitHead":"78f9f5014c46b860cbd906985cf2fce3fb6f619d","_nodeVersion":"20.20.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-HQEnyIS+lGUn98IIqgSmdyCnUb7imZBVFUxUPFwrCkkHQtba8Tku58NArl+r7rxMZj4hlO9RnuuFy11e9S1VzA==","shasum":"99d66413cdc87b6b7b2476fd4526d5d081d50ff6","tarball":"https://registry.npmjs.org/@atlas-oracle/pull-oracle-consumer-sdk/-/pull-oracle-consumer-sdk-1.0.2.tgz","fileCount":8,"unpackedSize":118753,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIHwmDbudJWIZc8s4mrxbixNrT39WbarZFEf5MkgPDQEzAiAU0nQ469UMXMm9gz6n9KqVevFOLs3KZqmOKeIUEvD/8Q=="}]},"_npmUser":{"name":"layne96","email":"same.h@atlasoracle.io"},"directories":{},"maintainers":[{"name":"layne96","email":"same.h@atlasoracle.io"},{"name":"michael_wgy","email":"michael.wang@atlasoracle.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pull-oracle-consumer-sdk_1.0.2_1781068918091_0.7961326993424993"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-10T05:03:56.640Z","modified":"2026-06-10T05:21:58.379Z","1.0.1":"2026-06-10T05:03:57.077Z","1.0.2":"2026-06-10T05:21:58.231Z"},"license":"BUSL-1.1","description":"Pull Oracle Consumer TypeScript SDK","maintainers":[{"name":"layne96","email":"same.h@atlasoracle.io"},{"name":"michael_wgy","email":"michael.wang@atlasoracle.io"}],"readme":"# @atlas-oracle/pull-oracle-consumer-sdk\n\nTypeScript SDK for fetching signed Pull Oracle price data, validating payloads, building contract calldata, and submitting on-chain update transactions through a user-provided chain adapter.\n\n## What This SDK Does\n\n- Fetch signed price data over HTTP.\n- Optionally validate payload freshness and package constraints before use.\n- Build calldata by encoding your contract call and appending oracle `extraData`.\n- Subscribe to real-time price updates over WebSocket.\n- Submit transactions through a user-supplied `ChainAdapter`.\n\n## Scope\n\nThis SDK is intentionally focused on price data consumption and transaction preparation. It does not:\n\n- Manage wallets, private keys, signers, or seed phrases.\n- Replace `ethers`, `viem`, or another chain library.\n- Abstract full transaction orchestration such as nonce management, gas strategy, batching, or retries.\n- Handle backend credential storage or secret-management workflows for API keys.\n\n## Installation\n\n```bash\nnpm install @atlas-oracle/pull-oracle-consumer-sdk\n```\n\nIf you plan to use WebSocket subscriptions in Node.js, install `ws` alongside the SDK:\n\n```bash\nnpm install ws\n```\n\n`ws` provides the Node.js WebSocket implementation used by the SDK for subscriptions. In some Node.js environments, installing it can also avoid module-loading issues even if you currently only use HTTP.\n\n## Compatibility\n\n- Node.js >= 18\n- ESM and CommonJS supported\n- WebSocket subscriptions in Node.js require `ws`\n- Some Node.js environments may also require `ws` during module resolution, even for HTTP-only usage\n- Support outside Node.js is not guaranteed; validate your target runtime, especially its WebSocket implementation\n\n## Quick Start\n\n### Fetch price data\n\n```typescript\nimport { PullOracleConsumerClient } from '@atlas-oracle/pull-oracle-consumer-sdk';\n\nconst client = new PullOracleConsumerClient({\n  http: {\n    apiKey: 'YOUR_API_KEY',\n  },\n  validate: false,\n});\n\nconst priceData = await client.fetchPrices(['3323', '3325']);\n\nconsole.log(priceData.extraData);\n```\n\n### Execute an on-chain update\n\n```typescript\nimport {\n  PullOracleConsumerClient,\n  type ChainAdapter,\n  type Hex,\n} from '@atlas-oracle/pull-oracle-consumer-sdk';\n\nconst client = new PullOracleConsumerClient({\n  http: {\n    apiKey: 'YOUR_API_KEY',\n  },\n  validate: true,\n  maxDelay: 60,\n  maxFutureDrift: 5,\n  maxPackageCount: 10,\n});\n\nconst chainAdapter: ChainAdapter = {\n  async sendTransaction({ to, data, value }) {\n    const tx = await signer.sendTransaction({\n      to,\n      data,\n      value: value ?? 0n,\n    });\n\n    return tx.hash as Hex;\n  },\n};\n\nconst txHash = await client.execute({\n  feedIds: ['3323'],\n  abi: contractAbi,\n  functionName: 'updatePrice',\n  args: [3323n],\n  to: '0xContractAddress' as Hex,\n  chainAdapter,\n});\n\nconsole.log(txHash);\n```\n\n## API Overview\n\nMain entry point:\n\n- `PullOracleConsumerClient` — configures HTTP access, optional WebSocket transport, validation, and debug behavior.\n\nCore methods:\n\n- `fetchPrices(feedIds)` — fetch signed price data for one or more feeds.\n- `buildCalldata(params)` — encode a contract function call and append oracle `extraData`.\n- `sendTransaction(params)` — delegate a prepared transaction to your `ChainAdapter`.\n- `execute(params)` — fetch prices, build calldata, and send the transaction in one call.\n- `subscribe(feedIds, feedType, onUpdate, onError?)` — receive live price updates over WebSocket.\n\nAlso exported:\n\n- `ChainAdapter`, `PriceData`, `Hex`, and related config types.\n- `PullOracleConsumerValidationError` and `PullOracleConsumerTransportError`.\n\n## API Reference\n\n### `new PullOracleConsumerClient(config)`\n\nCreates a new client instance.\n\n#### HTTP configuration\n\n| Field | Type | Required | Description |\n|-------|------|----------|-------------|\n| `http.apiKey` | `string` | Yes | API key used for authenticated HTTP requests. |\n| `http.timeout` | `number` | No | Request timeout in milliseconds. Default: `10000`. |\n\n#### WebSocket configuration\n\nProvide `ws` configuration when you plan to call `subscribe`. In Node.js, install the `ws` package so the SDK has a compatible WebSocket implementation available. In some environments, installing `ws` may also help avoid module-loading issues even before you start using subscriptions.\n\n| Field | Type | Required | Description |\n|-------|------|----------|-------------|\n| `ws.apiKey` | `string` | Yes, when `ws` is provided | API key used for authenticated WebSocket connections. |\n| `ws.reconnect` | `boolean` | Yes, when `ws` is provided | Enables or disables automatic reconnection. |\n| `ws.reconnectInterval` | `number` | Required when `ws.reconnect: true` | Delay between reconnect attempts in milliseconds. |\n| `ws.maxReconnectAttempts` | `number` | Required when `ws.reconnect: true` | Maximum reconnect attempts before surfacing an error. |\n| `ws.pingInterval` | `number` | Required when `ws.reconnect: true` | Ping interval in milliseconds for keepalive behavior. |\n\n#### Validation configuration\n\n| Field | Type | Required | Description |\n|-------|------|----------|-------------|\n| `validate` | `boolean` | Yes | Enables or disables validation of returned oracle payloads. |\n| `maxDelay` | `number` | Required when `validate: true` | Maximum allowed payload staleness in seconds. |\n| `maxFutureDrift` | `number` | Required when `validate: true` | Maximum allowed future timestamp drift in seconds. |\n| `maxPackageCount` | `number` | Required when `validate: true` | Maximum number of packages allowed in a response. |\n\n#### Debug configuration\n\n| Field | Type | Required | Description |\n|-------|------|----------|-------------|\n| `debug` | `boolean` | No | Logs parsed payload details for debugging. Default: `false`. |\n\n### `client.fetchPrices(feedIds)`\n\nWhen to use: Use this when you need signed price data and want to decide yourself how to validate, encode, or submit the resulting data.\n\nFetch signed price data via HTTP. `feedIds` must be a non-empty array with no duplicates.\n\n```typescript\nconst priceData = await client.fetchPrices(['3323', '3325']);\n// priceData.extraData is ready to append to an on-chain call\n```\n\n### `client.buildCalldata(params)`\n\nWhen to use: Use this when you already have `extraData` and need transaction calldata for a contract call.\n\nBuild transaction calldata by encoding a function call and appending `extraData`.\n\n```typescript\nconst calldata = client.buildCalldata({\n  abi: contractAbi,\n  functionName: 'updatePrice',\n  args: [3323n],\n  extraData: priceData.extraData,\n});\n```\n\n### `client.sendTransaction(params)`\n\nWhen to use: Use this when your application already prepared the transaction payload and just wants the SDK to hand it to your adapter.\n\nSend a transaction via a `ChainAdapter`.\n\n```typescript\nconst txHash = await client.sendTransaction({\n  to: '0xContractAddress',\n  data: calldata,\n  chainAdapter: myAdapter,\n});\n```\n\n### `client.execute(params)`\n\nWhen to use: Use this when you want one helper that fetches prices, builds calldata, and submits the update transaction.\n\nOne-step helper: fetch prices, build calldata, and send the transaction.\n\n```typescript\nconst txHash = await client.execute({\n  feedIds: ['3323'],\n  abi: contractAbi,\n  functionName: 'updatePrice',\n  args: [3323n],\n  to: '0xContractAddress',\n  chainAdapter: myAdapter,\n});\n```\n\n### `client.subscribe(feedIds, feedType, onUpdate, onError?)`\n\nWhen to use: Use this when you need live updates over WebSocket instead of polling HTTP.\n\nSubscribe to real-time price updates via WebSocket. This requires `ws` configuration on the client. In Node.js, install the `ws` package when you plan to use subscriptions so the SDK can use a compatible WebSocket implementation.\n\n**Parameters:**\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `feedIds` | `string[]` | Yes | Non-empty array of feed ID strings with no duplicates. |\n| `feedType` | `'public' \\| 'private'` | Yes | Feed type: `'public'` for public feeds or `'private'` for private feeds. |\n| `onUpdate` | `(data: PriceData) => void` | Yes | Callback invoked on each price update. |\n| `onError` | `(err: Error) => void` | No | Callback invoked when a transport or processing error occurs. |\n\nWhen `validate: true`, WebSocket data that fails validation falls back to an HTTP fetch for the same feeds.\n\nEach call to `subscribe` creates a separate WebSocket connection and returns an unsubscribe function.\n\n```typescript\nconst unsubscribe = client.subscribe(\n  ['3323', '3325'],\n  'public',\n  (data) => {\n    console.log('Price update:', data.extraData);\n  },\n  (err) => {\n    console.error('Subscription error:', err);\n  },\n);\n\nunsubscribe();\n```\n\n## ChainAdapter\n\nThe SDK does not submit transactions directly. Instead, it prepares calldata and delegates transaction submission to a user-provided `ChainAdapter`, allowing you to integrate with `ethers`, `viem`, or another signer stack.\n\n```typescript\nimport type { ChainAdapter, Hex } from '@atlas-oracle/pull-oracle-consumer-sdk';\n```\n\n### ethers v6\n\n```typescript\nimport { ethers } from 'ethers';\n\nconst adapter: ChainAdapter = {\n  async sendTransaction({ to, data, value }) {\n    const signer = await provider.getSigner();\n    const tx = await signer.sendTransaction({\n      to,\n      data,\n      value: value ?? 0n,\n    });\n    return tx.hash as Hex;\n  },\n};\n```\n\n### viem\n\n```typescript\nimport { createWalletClient, http } from 'viem';\nimport { mainnet } from 'viem/chains';\n\nconst walletClient = createWalletClient({\n  chain: mainnet,\n  transport: http(),\n});\n\nconst adapter: ChainAdapter = {\n  async sendTransaction({ to, data, value }) {\n    return walletClient.sendTransaction({\n      to,\n      data,\n      value: value ?? 0n,\n      account: '0xYourAccount',\n    });\n  },\n};\n```\n\n## Error Handling\n\nThe SDK primarily throws two error types:\n\n- `PullOracleConsumerValidationError` for invalid inputs or payload validation failures.\n- `PullOracleConsumerTransportError` for HTTP, WebSocket, or transport-configuration problems.\n\n```typescript\nimport {\n  PullOracleConsumerValidationError,\n  PullOracleConsumerTransportError,\n} from '@atlas-oracle/pull-oracle-consumer-sdk';\n\ntry {\n  await client.fetchPrices(['3323']);\n} catch (err) {\n  if (err instanceof PullOracleConsumerValidationError) {\n    // err.code:\n    // 'EMPTY_FEED_IDS'\n    // | 'DUPLICATE_FEED_IDS'\n    // | 'EMPTY_EXTRA_DATA'\n    // | 'EXCEEDS_MAX_PACKAGE_COUNT'\n    // | 'FEED_EXPIRED'\n    // | 'FEED_FUTURE_DRIFT'\n    // | 'INVALID_EXTRA_DATA'\n    // | 'INVALID_MAGIC_MARKER'\n    // err.feedId: optional feed ID that caused the error\n  }\n\n  if (err instanceof PullOracleConsumerTransportError) {\n    // err.statusCode: HTTP status code (if applicable)\n    // err.cause: underlying error (standard ES2022 Error.cause)\n  }\n}\n```\n\n## Troubleshooting\n\n| Problem | Likely cause | What to do |\n|---------|--------------|------------|\n| `WebSocket transport is not configured` | `subscribe` was called without a `ws` config block in the client constructor. | Create the client with a `ws` configuration, for example `ws: { apiKey: 'YOUR_API_KEY', reconnect: false }`. |\n| `feedIds must not be empty` | `fetchPrices`, `subscribe`, or `execute` received an empty array. | Pass at least one feed ID. |\n| `feedIds must not contain duplicates` | The same feed ID was provided more than once. | Deduplicate the array before calling the SDK. |\n| Validation config errors when `validate: true` | `maxDelay`, `maxFutureDrift`, or `maxPackageCount` was omitted. | Provide all three validation fields whenever `validate` is set to `true`. |\n| WebSocket subscriptions fail in Node.js because `ws` is missing, or the SDK does not load cleanly without it | The SDK relies on `ws` for a compatible Node.js WebSocket implementation, and some environments may also expect it during module resolution. | Install it with `npm install ws`, then retry and verify that your runtime provides the WebSocket support you expect. |\n\n## Development\n\nFor contribution workflow and repository guidelines, see [CONTRIBUTING.md](./CONTRIBUTING.md).\n\n```bash\nnpm install\nnpm run build\nnpm run test\nnpm run lint\nnpm run typecheck\n```\n\n### Releases\n\nVersioning and publishing are managed by [Auto](https://intuit.github.io/auto/docs/welcome/getting-started):\n\n```bash\nnpm run version:check\nnpm run release\n```\n\nBefore publishing, replace the placeholder GitHub `owner` and `repo` values in `.autorc`, create Auto labels with `npm run labels:create`, and configure the `NPM_TOKEN` GitHub Actions secret.\n\n## Contributing\n\nContributions are welcome. Please review [CONTRIBUTING.md](./CONTRIBUTING.md) before opening a pull request.\n\n## Support\n\n- For bug reports and feature requests, please open an issue.\n- For security-sensitive reports, do not post sensitive details publicly in an issue. Ask the maintainers for a private contact path first if private coordination is needed.\n\n## License\n\nThis project uses the Business Source License 1.1 (`BUSL-1.1`).\n","readmeFilename":"README.md","homepage":"https://github.com/oracle-atlas/pull-oracle-consumer-sdk#readme","repository":{"type":"git","url":"git+https://github.com/oracle-atlas/pull-oracle-consumer-sdk.git"},"bugs":{"url":"https://github.com/oracle-atlas/pull-oracle-consumer-sdk/issues"}}