@chainlink/cre-sdk 0.0.8-alpha → 0.0.10-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/pb.d.ts CHANGED
@@ -4,3 +4,4 @@ export * as HTTP_TRIGGER_PB from './generated/capabilities/networking/http/v1alp
4
4
  export * as CRON_TRIGGER_PB from './generated/capabilities/scheduler/cron/v1/trigger_pb';
5
5
  export * as SDK_PB from './generated/sdk/v1alpha/sdk_pb';
6
6
  export * as VALUES_PB from './generated/values/v1/values_pb';
7
+ export * as BUFBUILD_TYPES from './sdk/types/bufbuild-types';
package/dist/pb.js CHANGED
@@ -4,3 +4,4 @@ export * as HTTP_TRIGGER_PB from './generated/capabilities/networking/http/v1alp
4
4
  export * as CRON_TRIGGER_PB from './generated/capabilities/scheduler/cron/v1/trigger_pb';
5
5
  export * as SDK_PB from './generated/sdk/v1alpha/sdk_pb';
6
6
  export * as VALUES_PB from './generated/values/v1/values_pb';
7
+ export * as BUFBUILD_TYPES from './sdk/types/bufbuild-types';
@@ -11,7 +11,7 @@ import { CronCapability } from '../../generated-sdk/capabilities/scheduler/cron/
11
11
  export { type Log as EVMLog, TxStatus, } from '../../generated/capabilities/blockchain/evm/v1alpha/client_pb';
12
12
  export type { Payload as HTTPPayload } from '../../generated/capabilities/networking/http/v1alpha/trigger_pb';
13
13
  export type { Payload as CronPayload } from '../../generated/capabilities/scheduler/cron/v1/trigger_pb';
14
- export { ClientCapability as EVMClient } from '../../generated-sdk/capabilities/blockchain/evm/v1alpha/client_sdk_gen';
14
+ export { ClientCapability as EVMClient, type WriteCreReportRequest, type WriteCreReportRequestJson, } from '../../generated-sdk/capabilities/blockchain/evm/v1alpha/client_sdk_gen';
15
15
  export { ClientCapability as HTTPClient, type SendRequester as HTTPSendRequester, } from '../../generated-sdk/capabilities/networking/http/v1alpha/client_sdk_gen';
16
16
  export { HTTPCapability } from '../../generated-sdk/capabilities/networking/http/v1alpha/http_sdk_gen';
17
17
  export { CronCapability } from '../../generated-sdk/capabilities/scheduler/cron/v1/cron_sdk_gen';
@@ -12,7 +12,7 @@ import { handler } from '../workflow';
12
12
  */
13
13
  export { TxStatus, } from '../../generated/capabilities/blockchain/evm/v1alpha/client_pb';
14
14
  // EVM Capability
15
- export { ClientCapability as EVMClient } from '../../generated-sdk/capabilities/blockchain/evm/v1alpha/client_sdk_gen';
15
+ export { ClientCapability as EVMClient, } from '../../generated-sdk/capabilities/blockchain/evm/v1alpha/client_sdk_gen';
16
16
  // HTTP Capability
17
17
  export { ClientCapability as HTTPClient, } from '../../generated-sdk/capabilities/networking/http/v1alpha/client_sdk_gen';
18
18
  export { HTTPCapability } from '../../generated-sdk/capabilities/networking/http/v1alpha/http_sdk_gen';
@@ -6,7 +6,7 @@ export declare class NodeModeError extends Error {
6
6
  constructor();
7
7
  }
8
8
  export declare class SecretsError extends Error {
9
- sceretRequest: SecretRequest;
9
+ secretRequest: SecretRequest;
10
10
  error: String;
11
- constructor(sceretRequest: SecretRequest, error: String);
11
+ constructor(secretRequest: SecretRequest, error: String);
12
12
  }
@@ -11,11 +11,11 @@ export class NodeModeError extends Error {
11
11
  }
12
12
  }
13
13
  export class SecretsError extends Error {
14
- sceretRequest;
14
+ secretRequest;
15
15
  error;
16
- constructor(sceretRequest, error) {
17
- super(`error fetching ${sceretRequest}: ${error}`);
18
- this.sceretRequest = sceretRequest;
16
+ constructor(secretRequest, error) {
17
+ super(`error fetching ${secretRequest}: ${error}`);
18
+ this.secretRequest = secretRequest;
19
19
  this.error = error;
20
20
  }
21
21
  }
@@ -25,7 +25,7 @@ export declare class NodeRuntimeImpl<C> extends BaseRuntimeImpl<C> implements No
25
25
  export declare class RuntimeImpl<C> extends BaseRuntimeImpl<C> implements Runtime<C> {
26
26
  private nextNodeCallId;
27
27
  constructor(config: C, nextCallId: number, helpers: RuntimeHelpers, maxResponseSize: bigint);
28
- runInNodeMode<TArgs extends unknown[], TOutput>(fn: (nodeRuntime: NodeRuntime<C>, ...args: TArgs) => TOutput, consesusAggretation: ConsensusAggregation<TOutput, true>, unwrapOptions?: TOutput extends PrimitiveTypes ? never : UnwrapOptions<TOutput>): (...args: TArgs) => {
28
+ runInNodeMode<TArgs extends unknown[], TOutput>(fn: (nodeRuntime: NodeRuntime<C>, ...args: TArgs) => TOutput, consensusAggretation: ConsensusAggregation<TOutput, true>, unwrapOptions?: TOutput extends PrimitiveTypes ? never : UnwrapOptions<TOutput>): (...args: TArgs) => {
29
29
  result: () => TOutput;
30
30
  };
31
31
  getSecret(request: SecretRequest | SecretRequestJson): {
@@ -77,8 +77,18 @@ export class BaseRuntimeImpl {
77
77
  }
78
78
  const response = capabilityResponse.response;
79
79
  switch (response.case) {
80
- case 'payload':
81
- return anyUnpack(response.value, outputSchema);
80
+ case 'payload': {
81
+ try {
82
+ return anyUnpack(response.value, outputSchema);
83
+ }
84
+ catch {
85
+ throw new CapabilityError(`Error cannot unwrap payload`, {
86
+ capabilityId,
87
+ method,
88
+ callbackId,
89
+ });
90
+ }
91
+ }
82
92
  case 'error':
83
93
  throw new CapabilityError(`Error ${response.value}`, {
84
94
  capabilityId,
@@ -119,16 +129,16 @@ export class RuntimeImpl extends BaseRuntimeImpl {
119
129
  helpers.switchModes(Mode.DON);
120
130
  super(config, nextCallId, helpers, maxResponseSize, Mode.DON);
121
131
  }
122
- runInNodeMode(fn, consesusAggretation, unwrapOptions) {
132
+ runInNodeMode(fn, consensusAggretation, unwrapOptions) {
123
133
  return (...args) => {
124
134
  this.modeError = new DonModeError();
125
135
  const nodeRuntime = new NodeRuntimeImpl(this.config, this.nextNodeCallId, this.helpers, this.maxResponseSize);
126
136
  const consensusInput = create(SimpleConsensusInputsSchema, {
127
- descriptors: consesusAggretation.descriptor,
137
+ descriptors: consensusAggretation.descriptor,
128
138
  });
129
- if (consesusAggretation.defaultValue) {
139
+ if (consensusAggretation.defaultValue) {
130
140
  // This cast is safe, since ConsensusAggregation can only have true its second argument if T extends CreSerializable<TOutput>
131
- consensusInput.default = Value.from(consesusAggretation.defaultValue).proto();
141
+ consensusInput.default = Value.from(consensusAggretation.defaultValue).proto();
132
142
  }
133
143
  try {
134
144
  const observation = fn(nodeRuntime, ...args);
@@ -173,13 +183,13 @@ export class RuntimeImpl extends BaseRuntimeImpl {
173
183
  };
174
184
  }
175
185
  const secretRequest = request.$typeName
176
- ? create(SecretRequestSchema, request)
177
- : request;
186
+ ? request
187
+ : create(SecretRequestSchema, request);
178
188
  const id = this.nextCallId;
179
189
  this.nextCallId++;
180
190
  const secretsReq = create(GetSecretsRequestSchema, {
181
191
  callbackId: id,
182
- requests: [request],
192
+ requests: [secretRequest],
183
193
  });
184
194
  if (!this.helpers.getSecrets(secretsReq, this.maxResponseSize)) {
185
195
  return {
@@ -207,7 +217,7 @@ export class RuntimeImpl extends BaseRuntimeImpl {
207
217
  case 'error':
208
218
  throw new SecretsError(secretRequest, response.value.error);
209
219
  default:
210
- throw new SecretsError(secretRequest, 'cannot unmashal returned value from host');
220
+ throw new SecretsError(secretRequest, 'cannot unmarshal returned value from host');
211
221
  }
212
222
  },
213
223
  };
@@ -2,6 +2,7 @@ export * from './cre';
2
2
  export * from './report';
3
3
  export type * from './runtime';
4
4
  export * from './runtime';
5
+ export * from './types/bufbuild-types';
5
6
  export * from './utils';
6
7
  export * from './utils/capabilities/http/http-helpers';
7
8
  export * from './wasm';
package/dist/sdk/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from './cre';
2
2
  export * from './report';
3
3
  export * from './runtime';
4
+ export * from './types/bufbuild-types';
4
5
  export * from './utils';
5
6
  // Export HTTP response helpers
6
7
  export * from './utils/capabilities/http/http-helpers';
@@ -0,0 +1,4 @@
1
+ /**
2
+ * This file re-exports the types, internally used by the SDK capabilities, that are normally coming with @bufbuild/protobuf library.
3
+ */
4
+ export type { Any, AnyJson, Empty, EmptyJson, Struct, StructJson, Timestamp, TimestampJson, } from '@bufbuild/protobuf/wkt';
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ // This file ensures the module is properly loaded for TypeScript global augmentations
2
+ // The actual type definitions are in restricted-apis.d.ts
3
+ export {};
@@ -1,4 +1,5 @@
1
1
  import type { CallMsgJson } from '../../../../generated/capabilities/blockchain/evm/v1alpha/client_pb';
2
+ import type { ReportRequestJson } from '../../../../generated/sdk/v1alpha/sdk_pb';
2
3
  import type { Address, Hex } from 'viem';
3
4
  /**
4
5
  * EVM Capability Helper.
@@ -48,3 +49,19 @@ export interface EncodeCallMsgPayload {
48
49
  * @returns The encoded call message payload.
49
50
  */
50
51
  export declare const encodeCallMsg: (payload: EncodeCallMsgPayload) => CallMsgJson;
52
+ /**
53
+ * Default values expected by the EVM capability for report encoding.
54
+ */
55
+ export declare const EVM_DEFAULT_REPORT_ENCODER: {
56
+ encoderName: string;
57
+ signingAlgo: string;
58
+ hashingAlgo: string;
59
+ };
60
+ /**
61
+ * Prepares a report request for the EVM capability to pass to `.report()` function.
62
+ *
63
+ * @param hexEncodedPayload - The hex encoded payload to be signed.
64
+ * @param reportEncoder - The report encoder to be used. Defaults to EVM_DEFAULT_REPORT_ENCODER.
65
+ * @returns The prepared report request.
66
+ */
67
+ export declare const prepareReportRequest: (hexEncodedPayload: Hex, reportEncoder?: Exclude<ReportRequestJson, "encodedPayload">) => ReportRequestJson;
@@ -46,3 +46,22 @@ export const encodeCallMsg = (payload) => ({
46
46
  to: hexToBase64(payload.to),
47
47
  data: hexToBase64(payload.data),
48
48
  });
49
+ /**
50
+ * Default values expected by the EVM capability for report encoding.
51
+ */
52
+ export const EVM_DEFAULT_REPORT_ENCODER = {
53
+ encoderName: 'evm',
54
+ signingAlgo: 'ecdsa',
55
+ hashingAlgo: 'keccak256',
56
+ };
57
+ /**
58
+ * Prepares a report request for the EVM capability to pass to `.report()` function.
59
+ *
60
+ * @param hexEncodedPayload - The hex encoded payload to be signed.
61
+ * @param reportEncoder - The report encoder to be used. Defaults to EVM_DEFAULT_REPORT_ENCODER.
62
+ * @returns The prepared report request.
63
+ */
64
+ export const prepareReportRequest = (hexEncodedPayload, reportEncoder = EVM_DEFAULT_REPORT_ENCODER) => ({
65
+ encodedPayload: hexToBase64(hexEncodedPayload),
66
+ ...reportEncoder,
67
+ });
@@ -15,7 +15,18 @@ const defaultJsonParser = (config) => JSON.parse(Buffer.from(config).toString())
15
15
  export const configHandler = async (request, { configParser, configSchema } = {}) => {
16
16
  const config = request.config;
17
17
  const parser = configParser || defaultJsonParser;
18
- const intermediateConfig = parser(config);
18
+ let intermediateConfig;
19
+ try {
20
+ intermediateConfig = parser(config);
21
+ }
22
+ catch (error) {
23
+ if (error instanceof Error) {
24
+ throw new Error(`Failed to parse configuration: ${error.message}`);
25
+ }
26
+ else {
27
+ throw new Error(`Failed to parse configuration: unknown error`);
28
+ }
29
+ }
19
30
  return configSchema
20
31
  ? standardValidate(configSchema, intermediateConfig)
21
32
  : intermediateConfig;
@@ -5,10 +5,18 @@ export const hexToBytes = (hexStr) => {
5
5
  if (!hexStr.startsWith('0x')) {
6
6
  throw new Error(`Invalid hex string: ${hexStr}`);
7
7
  }
8
+ // Validate hexadecimal characters
9
+ if (!/^0x[0-9a-fA-F]*$/.test(hexStr)) {
10
+ throw new Error(`Invalid hex string: ${hexStr}`);
11
+ }
12
+ // Validate even length
13
+ if ((hexStr.length - 2) % 2 !== 0) {
14
+ throw new Error(`Hex string must have an even number of characters: ${hexStr}`);
15
+ }
8
16
  const hex = hexStr.slice(2);
9
17
  const bytes = new Uint8Array(hex.length / 2);
10
18
  for (let i = 0; i < hex.length; i += 2) {
11
- bytes[i / 2] = Number.parseInt(hex.substr(i, 2), 16);
19
+ bytes[i / 2] = Number.parseInt(hex.slice(i, i + 2), 16);
12
20
  }
13
21
  return bytes;
14
22
  };
@@ -19,7 +19,13 @@ export class Runner {
19
19
  }
20
20
  static getRequest() {
21
21
  const argsString = hostBindings.getWasiArgs();
22
- const args = JSON.parse(argsString);
22
+ let args;
23
+ try {
24
+ args = JSON.parse(argsString);
25
+ }
26
+ catch (e) {
27
+ throw new Error('Invalid request: could not parse arguments');
28
+ }
23
29
  // SDK expects exactly 2 args:
24
30
  // 1st is the script name
25
31
  // 2nd is the base64 encoded request
@@ -44,6 +50,8 @@ export class Runner {
44
50
  case 'trigger':
45
51
  result = this.handleExecutionPhase(this.request, workflow, runtime);
46
52
  break;
53
+ default:
54
+ throw new Error('Unknown request type');
47
55
  }
48
56
  }
49
57
  catch (e) {
@@ -60,6 +68,11 @@ export class Runner {
60
68
  throw new Error('cannot handle non-trigger request as a trigger');
61
69
  }
62
70
  const triggerMsg = req.request.value;
71
+ // We're about to cast bigint to number, so we need to check if it's safe
72
+ const id = BigInt(triggerMsg.id);
73
+ if (id > BigInt(Number.MAX_SAFE_INTEGER)) {
74
+ throw new Error(`Trigger ID ${id} exceeds safe integer range`);
75
+ }
63
76
  const index = Number(triggerMsg.id);
64
77
  if (Number.isFinite(index) && index >= 0 && index < workflow.length) {
65
78
  const entry = workflow[index];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chainlink/cre-sdk",
3
- "version": "0.0.8-alpha",
3
+ "version": "0.0.10-alpha",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -10,7 +10,8 @@
10
10
  "import": "./dist/index.js"
11
11
  },
12
12
  "./restricted-apis": {
13
- "types": "./dist/sdk/types/restricted-apis.d.ts"
13
+ "types": "./dist/sdk/types/restricted-apis.d.ts",
14
+ "import": "./dist/sdk/types/restricted-apis.js"
14
15
  },
15
16
  "./pb": {
16
17
  "types": "./dist/pb.d.ts",
@@ -54,7 +55,7 @@
54
55
  "dependencies": {
55
56
  "@bufbuild/protobuf": "2.6.3",
56
57
  "@bufbuild/protoc-gen-es": "2.6.3",
57
- "@chainlink/cre-sdk-javy-plugin": "0.0.6-alpha",
58
+ "@chainlink/cre-sdk-javy-plugin": "0.0.7-alpha",
58
59
  "@standard-schema/spec": "1.0.0",
59
60
  "viem": "2.34.0",
60
61
  "zod": "3.25.76"
@@ -51,8 +51,15 @@ export const main = async (inputFile?: string, outputFile?: string) => {
51
51
  try {
52
52
  await $`bun cre-compile-workflow ${resolvedInput} ${resolvedOutput}`
53
53
  } catch {
54
- // Use npm script which has the correct path setup
55
- await $`bun --bun ../cre-sdk-javy-plugin/bin/compile-workflow.ts ${resolvedInput} ${resolvedOutput}`
54
+ // Fallback: locate compile-workflow.ts relative to this script file
55
+ // From: packages/cre-sdk/scripts/src/compile-to-wasm.ts
56
+ // To: packages/cre-sdk-javy-plugin/bin/compile-workflow.ts
57
+ const scriptDir = import.meta.dir
58
+ const compilerPath = path.resolve(
59
+ scriptDir,
60
+ '../../../cre-sdk-javy-plugin/bin/compile-workflow.ts',
61
+ )
62
+ await $`bun --bun ${compilerPath} ${resolvedInput} ${resolvedOutput}`
56
63
  }
57
64
 
58
65
  console.info(`✅ Compiled: ${resolvedOutput}`)
@@ -79,14 +79,33 @@ const CHAIN_CONFIGS: ChainSelectorConfig[] = [
79
79
  ]
80
80
 
81
81
  const readYamlFile = (filename: string): string => {
82
- // Look for chain-selectors in workspace root node_modules (turborepo setup)
83
- const workspaceRoot = join(process.cwd(), '..', '..')
84
- const chainSelectorsPath = join(workspaceRoot, 'node_modules', 'chain-selectors', filename)
85
- try {
86
- return readFileSync(chainSelectorsPath, 'utf-8')
87
- } catch (error) {
88
- throw new Error(`Failed to read ${filename}: ${error}`)
82
+ // Look for chain-selectors in node_modules by trying multiple possible locations
83
+ // This handles different execution contexts (local dev, CI, etc.)
84
+ const possiblePaths = [
85
+ // Try workspace root (3 levels up from scripts/)
86
+ join(process.cwd(), '..', '..', '..', 'node_modules', 'chain-selectors', filename),
87
+ // Try 2 levels up (in case cwd is already in scripts/src/)
88
+ join(process.cwd(), '..', '..', 'node_modules', 'chain-selectors', filename),
89
+ // Try current directory's node_modules
90
+ join(process.cwd(), 'node_modules', 'chain-selectors', filename),
91
+ // Try parent directory's node_modules
92
+ join(process.cwd(), '..', 'node_modules', 'chain-selectors', filename),
93
+ ]
94
+
95
+ for (const path of possiblePaths) {
96
+ try {
97
+ return readFileSync(path, 'utf-8')
98
+ } catch {
99
+ // Try next path
100
+ continue
101
+ }
89
102
  }
103
+
104
+ throw new Error(
105
+ `Failed to find ${filename} in any of the expected locations. Tried:\n${possiblePaths.join(
106
+ '\n',
107
+ )}`,
108
+ )
90
109
  }
91
110
 
92
111
  const parseChainSelectors = (): NetworkInfo[] => {