sdk-triggerx 0.1.38 → 0.1.40

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/api/jobs.js CHANGED
@@ -226,6 +226,8 @@ async function createJob(client, params) {
226
226
  return (0, errors_1.createErrorResponse)(new errors_1.NetworkError('Failed to get network information', { originalError: err }), 'Network error');
227
227
  }
228
228
  const chainIdStr = network?.chainId ? network.chainId.toString() : undefined;
229
+ // Wait for remote addresses if fetch is in-flight
230
+ await (0, config_1.ensureAddressesLoaded)();
229
231
  const { jobRegistry, safeModule, safeFactory, multisendCallOnly } = (0, config_1.getChainAddresses)(chainIdStr);
230
232
  const JOB_REGISTRY_ADDRESS = jobRegistry;
231
233
  if (!JOB_REGISTRY_ADDRESS) {
@@ -17,6 +17,8 @@ async function createSafeWallet(signer) {
17
17
  if (!network?.chainId)
18
18
  throw new Error('Could not get chainId from signer provider');
19
19
  const chainId = network.chainId.toString();
20
+ // Wait for remote addresses if fetch is in-flight
21
+ await (0, config_1.ensureAddressesLoaded)();
20
22
  const { safeFactory } = (0, config_1.getChainAddresses)(chainId);
21
23
  if (!safeFactory)
22
24
  throw new Error(`SafeFactory not configured for chain ${chainId}`);
package/dist/client.js CHANGED
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.TriggerXClient = void 0;
7
7
  const axios_1 = __importDefault(require("axios"));
8
+ const config_1 = require("./config");
8
9
  class TriggerXClient {
9
10
  constructor(apiKey, config) {
10
11
  this.apiKey = apiKey; // Initialize the apiKey
@@ -16,6 +17,8 @@ class TriggerXClient {
16
17
  timeout: 120000, // 120 second timeout
17
18
  ...config,
18
19
  });
20
+ // Kick off remote address fetch (non-blocking)
21
+ (0, config_1.initAddresses)();
19
22
  }
20
23
  // Method to get the API key
21
24
  getApiKey() {
package/dist/config.d.ts CHANGED
@@ -3,7 +3,7 @@ export interface SDKConfig {
3
3
  apiKey: string;
4
4
  apiUrl: string;
5
5
  }
6
- export declare const CONTRACT_ADDRESSES_BY_CHAIN: Record<string, {
6
+ export interface ChainAddresses {
7
7
  gasRegistry: string;
8
8
  jobRegistry: string;
9
9
  safeFactory?: string;
@@ -11,7 +11,19 @@ export declare const CONTRACT_ADDRESSES_BY_CHAIN: Record<string, {
11
11
  safeSingleton?: string;
12
12
  multisendCallOnly?: string;
13
13
  rpcUrl?: string;
14
- }>;
14
+ }
15
+ /**
16
+ * Initialize remote address loading (non-blocking).
17
+ * Call this early (e.g., when TriggerXClient is created) so addresses
18
+ * are ready by the time they're needed.
19
+ */
20
+ export declare function initAddresses(): void;
21
+ /**
22
+ * Await remote addresses if fetch is in-flight.
23
+ * Use this in async code paths before reading addresses.
24
+ */
25
+ export declare function ensureAddressesLoaded(): Promise<void>;
26
+ export declare const CONTRACT_ADDRESSES_BY_CHAIN: Record<string, ChainAddresses>;
15
27
  export declare function getConfig(): SDKConfig;
16
28
  /**
17
29
  * Get RPC provider for a given chain ID using SDK-configured RPC URLs
@@ -20,6 +32,10 @@ export declare function getConfig(): SDKConfig;
20
32
  * @returns ethers.JsonRpcProvider instance or null if chain not supported
21
33
  */
22
34
  export declare function getRpcProvider(chainId: string | number | undefined): ethers.JsonRpcProvider | null;
35
+ /**
36
+ * Get contract addresses for a given chain.
37
+ * Priority: remote (GitHub deployments) > hardcoded fallback
38
+ */
23
39
  export declare function getChainAddresses(chainId: string | number | undefined): {
24
40
  gasRegistry: string;
25
41
  jobRegistry: string;
package/dist/config.js CHANGED
@@ -1,31 +1,51 @@
1
1
  "use strict";
2
- // import dotenv from 'dotenv';
3
- // dotenv.config();
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
4
5
  Object.defineProperty(exports, "__esModule", { value: true });
5
6
  exports.CONTRACT_ADDRESSES_BY_CHAIN = void 0;
7
+ exports.initAddresses = initAddresses;
8
+ exports.ensureAddressesLoaded = ensureAddressesLoaded;
6
9
  exports.getConfig = getConfig;
7
10
  exports.getRpcProvider = getRpcProvider;
8
11
  exports.getChainAddresses = getChainAddresses;
9
12
  const ethers_1 = require("ethers");
10
- // Contract addresses per chain
11
- // Keyed by chainId as string to avoid bigint conversions throughout the SDK
12
- exports.CONTRACT_ADDRESSES_BY_CHAIN = {
13
- // TESTNET CONFIGURATIONS
14
- // OP Sepolia (11155420) - Optimism Sepolia Testnet
13
+ const axios_1 = __importDefault(require("axios"));
14
+ // ============================================================
15
+ // REMOTE ADDRESS SOURCES (triggerx-contracts deployments folder)
16
+ // ============================================================
17
+ const DEPLOYMENT_URLS = {
18
+ testnet: 'https://raw.githubusercontent.com/trigg3rX/triggerx-contracts/refs/heads/dev/deployments/testnet.json',
19
+ mainnet: 'https://raw.githubusercontent.com/trigg3rX/triggerx-contracts/refs/heads/dev/deployments/mainnet.json',
20
+ };
21
+ // ============================================================
22
+ // STATIC CONFIG (not part of contract deployments)
23
+ // These values don't change with contract upgrades
24
+ // ============================================================
25
+ const STATIC_CONFIG = {
26
+ '11155420': { rpcUrl: 'https://sepolia.optimism.io', multisendCallOnly: '0x9641d764fc13c8B624c04430C7356C1C7C8102e2' },
27
+ '11155111': { rpcUrl: 'https://rpc.sepolia.org', multisendCallOnly: '0x9641d764fc13c8B624c04430C7356C1C7C8102e2' },
28
+ '421614': { rpcUrl: 'https://sepolia-rollup.arbitrum.io/rpc', multisendCallOnly: '0x9641d764fc13c8B624c04430C7356C1C7C8102e2' },
29
+ '84532': { rpcUrl: 'https://sepolia.base.org', multisendCallOnly: '0x9641d764fc13c8B624c04430C7356C1C7C8102e2' },
30
+ '42161': { rpcUrl: 'https://arb1.arbitrum.io/rpc', multisendCallOnly: '0x9641d764fc13c8B624c04430C7356C1C7C8102e2' },
31
+ };
32
+ // ============================================================
33
+ // HARDCODED FALLBACK ADDRESSES (used if GitHub fetch fails)
34
+ // ============================================================
35
+ const FALLBACK_ADDRESSES = {
15
36
  '11155420': {
16
37
  gasRegistry: '0x248E9f1B99F1AC8068254233D1F271ed0e0903D6',
17
38
  jobRegistry: '0x476ACc7949a95e31144cC84b8F6BC7abF0967E4b',
18
39
  safeFactory: '0x04359eDC46Cd6C6BD7F6359512984222BE10F8Be',
19
- safeModule: '0x71BB931AfBE9a10a1030bAc1dc24fe45a2960b7a',
40
+ safeModule: '0xe90B66CDC6d3Da2F97cc4AA9e2ea24EA9EEd4cDB',
20
41
  multisendCallOnly: '0x9641d764fc13c8B624c04430C7356C1C7C8102e2',
21
42
  rpcUrl: 'https://sepolia.optimism.io',
22
43
  },
23
- // Ethereum Sepolia (11155111) - Ethereum Sepolia Testnet
24
44
  '11155111': {
25
45
  gasRegistry: '0x248E9f1B99F1AC8068254233D1F271ed0e0903D6',
26
46
  jobRegistry: '0x476ACc7949a95e31144cC84b8F6BC7abF0967E4b',
27
47
  safeFactory: '0xdf76E2A796a206D877086c717979054544B1D9Bc',
28
- safeModule: '0x71BB931AfBE9a10a1030bAc1dc24fe45a2960b7a',
48
+ safeModule: '0xe90B66CDC6d3Da2F97cc4AA9e2ea24EA9EEd4cDB',
29
49
  multisendCallOnly: '0x9641d764fc13c8B624c04430C7356C1C7C8102e2',
30
50
  rpcUrl: 'https://rpc.sepolia.org',
31
51
  },
@@ -34,17 +54,16 @@ exports.CONTRACT_ADDRESSES_BY_CHAIN = {
34
54
  gasRegistry: '0x248E9f1B99F1AC8068254233D1F271ed0e0903D6',
35
55
  jobRegistry: '0x476ACc7949a95e31144cC84b8F6BC7abF0967E4b',
36
56
  safeFactory: '0x04359eDC46Cd6C6BD7F6359512984222BE10F8Be',
37
- safeModule: '0x71BB931AfBE9a10a1030bAc1dc24fe45a2960b7a',
57
+ safeModule: '0xe90B66CDC6d3Da2F97cc4AA9e2ea24EA9EEd4cDB',
38
58
  multisendCallOnly: '0x9641d764fc13c8B624c04430C7356C1C7C8102e2',
39
59
  rpcUrl: 'https://sepolia-rollup.arbitrum.io/rpc',
40
- // safeSingleton can be provided per deployment (Safe or SafeL2)
41
60
  },
42
61
  // Base Sepolia (84532) - Base Sepolia Testnet
43
62
  '84532': {
44
63
  gasRegistry: '0x248E9f1B99F1AC8068254233D1F271ed0e0903D6',
45
64
  jobRegistry: '0x476ACc7949a95e31144cC84b8F6BC7abF0967E4b',
46
65
  safeFactory: '0x04359eDC46Cd6C6BD7F6359512984222BE10F8Be',
47
- safeModule: '0x71BB931AfBE9a10a1030bAc1dc24fe45a2960b7a',
66
+ safeModule: '0xe90B66CDC6d3Da2F97cc4AA9e2ea24EA9EEd4cDB',
48
67
  multisendCallOnly: '0x9641d764fc13c8B624c04430C7356C1C7C8102e2',
49
68
  rpcUrl: 'https://sepolia.base.org',
50
69
  },
@@ -58,8 +77,145 @@ exports.CONTRACT_ADDRESSES_BY_CHAIN = {
58
77
  multisendCallOnly: '0x9641d764fc13c8B624c04430C7356C1C7C8102e2',
59
78
  rpcUrl: 'https://arb1.arbitrum.io/rpc',
60
79
  },
61
- // Default/fallbacks can be extended as needed for other networks
62
80
  };
81
+ // ============================================================
82
+ // DEPLOYMENT JSON PARSING
83
+ // ============================================================
84
+ /**
85
+ * Extract proxy address from a deployment entry.
86
+ * Handles both formats: plain string or { proxy, implementation } object.
87
+ */
88
+ function getProxyAddress(entry) {
89
+ if (!entry)
90
+ return '';
91
+ if (typeof entry === 'string')
92
+ return entry;
93
+ if (typeof entry === 'object' && entry.proxy)
94
+ return entry.proxy;
95
+ return '';
96
+ }
97
+ /**
98
+ * Parse a single chain's deployment data into ChainAddresses.
99
+ * Merges with static config (rpcUrl, multisendCallOnly) if available.
100
+ */
101
+ function parseChainDeployment(chainId, deployment) {
102
+ const staticCfg = STATIC_CONFIG[chainId];
103
+ return {
104
+ gasRegistry: getProxyAddress(deployment.TriggerGasRegistry),
105
+ jobRegistry: getProxyAddress(deployment.JobRegistry),
106
+ safeFactory: getProxyAddress(deployment.TriggerXSafeFactory),
107
+ safeModule: getProxyAddress(deployment.TriggerXSafeModule),
108
+ multisendCallOnly: staticCfg?.multisendCallOnly || '',
109
+ rpcUrl: staticCfg?.rpcUrl || '',
110
+ };
111
+ }
112
+ /**
113
+ * Parse testnet.json format: { "chainId": { ...contracts } }
114
+ */
115
+ function parseTestnetDeployments(data) {
116
+ const result = {};
117
+ for (const chainId of Object.keys(data)) {
118
+ // Skip non-chain keys
119
+ if (!/^\d+$/.test(chainId))
120
+ continue;
121
+ result[chainId] = parseChainDeployment(chainId, data[chainId]);
122
+ }
123
+ return result;
124
+ }
125
+ /**
126
+ * Parse mainnet.json format: { L1: { chainId, ...contracts }, L2s: [{ chainId, ...contracts }] }
127
+ */
128
+ function parseMainnetDeployments(data) {
129
+ const result = {};
130
+ // Parse L1 (if it has contracts we need)
131
+ if (data.L1 && data.L1.chainId) {
132
+ const chainId = String(data.L1.chainId);
133
+ result[chainId] = parseChainDeployment(chainId, data.L1);
134
+ }
135
+ // Parse L2s array
136
+ if (Array.isArray(data.L2s)) {
137
+ for (const l2 of data.L2s) {
138
+ if (l2.chainId) {
139
+ const chainId = String(l2.chainId);
140
+ result[chainId] = parseChainDeployment(chainId, l2);
141
+ }
142
+ }
143
+ }
144
+ return result;
145
+ }
146
+ // ============================================================
147
+ // REMOTE ADDRESS FETCHING
148
+ // ============================================================
149
+ // Cache for fetched addresses — fetched once per SDK session
150
+ let _remoteAddresses = null;
151
+ let _fetchPromise = null;
152
+ let _fetchFailed = false;
153
+ /**
154
+ * Fetch deployment addresses from GitHub raw content (triggerx-contracts repo).
155
+ * Fetches both testnet.json and mainnet.json in parallel, merges results.
156
+ * Called once, then cached for the SDK session lifetime.
157
+ */
158
+ async function fetchRemoteAddresses() {
159
+ try {
160
+ const [testnetRes, mainnetRes] = await Promise.allSettled([
161
+ axios_1.default.get(DEPLOYMENT_URLS.testnet, { timeout: 5000 }),
162
+ axios_1.default.get(DEPLOYMENT_URLS.mainnet, { timeout: 5000 }),
163
+ ]);
164
+ const merged = {};
165
+ // Parse testnet
166
+ if (testnetRes.status === 'fulfilled' && testnetRes.value.data) {
167
+ const testnetAddresses = parseTestnetDeployments(testnetRes.value.data);
168
+ Object.assign(merged, testnetAddresses);
169
+ }
170
+ // Parse mainnet
171
+ if (mainnetRes.status === 'fulfilled' && mainnetRes.value.data) {
172
+ const mainnetAddresses = parseMainnetDeployments(mainnetRes.value.data);
173
+ Object.assign(merged, mainnetAddresses);
174
+ }
175
+ // Only succeed if we got at least one chain
176
+ if (Object.keys(merged).length > 0) {
177
+ return merged;
178
+ }
179
+ return null;
180
+ }
181
+ catch {
182
+ // Silent fail — will use hardcoded fallbacks
183
+ return null;
184
+ }
185
+ }
186
+ /**
187
+ * Initialize remote address loading (non-blocking).
188
+ * Call this early (e.g., when TriggerXClient is created) so addresses
189
+ * are ready by the time they're needed.
190
+ */
191
+ function initAddresses() {
192
+ if (!_fetchPromise && !_remoteAddresses && !_fetchFailed) {
193
+ _fetchPromise = fetchRemoteAddresses().then((result) => {
194
+ if (result) {
195
+ _remoteAddresses = result;
196
+ }
197
+ else {
198
+ _fetchFailed = true;
199
+ }
200
+ _fetchPromise = null;
201
+ return result;
202
+ });
203
+ }
204
+ }
205
+ /**
206
+ * Await remote addresses if fetch is in-flight.
207
+ * Use this in async code paths before reading addresses.
208
+ */
209
+ async function ensureAddressesLoaded() {
210
+ if (_fetchPromise) {
211
+ await _fetchPromise;
212
+ }
213
+ }
214
+ // Keep the old export name for backward compatibility
215
+ exports.CONTRACT_ADDRESSES_BY_CHAIN = FALLBACK_ADDRESSES;
216
+ // ============================================================
217
+ // PUBLIC API
218
+ // ============================================================
63
219
  function getConfig() {
64
220
  return {
65
221
  apiKey: '',
@@ -77,30 +233,45 @@ function getRpcProvider(chainId) {
77
233
  if (!rpcUrl) {
78
234
  return null;
79
235
  }
80
- // Convert chainId to number for network configuration
81
236
  const chainIdNum = chainId ? Number(chainId) : undefined;
82
237
  if (!chainIdNum) {
83
- // If no chainId, create provider without network (will auto-detect)
84
238
  return new ethers_1.ethers.JsonRpcProvider(rpcUrl);
85
239
  }
86
240
  // Create a Network object with the chainId to explicitly set the network
87
241
  // This prevents the provider from trying to auto-detect the network,
88
242
  // which can cause timeouts when the RPC is slow or unresponsive
89
243
  const network = ethers_1.ethers.Network.from(chainIdNum);
90
- // Create provider with explicit network to skip network detection
91
- // This prevents timeout issues when RPC is slow or unresponsive
92
244
  return new ethers_1.ethers.JsonRpcProvider(rpcUrl, network);
93
245
  }
246
+ /**
247
+ * Get contract addresses for a given chain.
248
+ * Priority: remote (GitHub deployments) > hardcoded fallback
249
+ */
94
250
  function getChainAddresses(chainId) {
95
251
  const chainKey = String(chainId ?? '');
96
- const mapped = exports.CONTRACT_ADDRESSES_BY_CHAIN[chainKey];
252
+ // Prefer remote addresses if available, fallback to hardcoded
253
+ const remote = _remoteAddresses?.[chainKey];
254
+ const fallback = FALLBACK_ADDRESSES[chainKey];
255
+ // If remote is available, merge with fallback for fields remote doesn't have (rpcUrl, multisendCallOnly)
256
+ if (remote) {
257
+ return {
258
+ gasRegistry: remote.gasRegistry || fallback?.gasRegistry || '',
259
+ jobRegistry: remote.jobRegistry || fallback?.jobRegistry || '',
260
+ safeFactory: remote.safeFactory || fallback?.safeFactory || '',
261
+ safeModule: remote.safeModule || fallback?.safeModule || '',
262
+ safeSingleton: remote.safeSingleton || fallback?.safeSingleton || '',
263
+ multisendCallOnly: remote.multisendCallOnly || fallback?.multisendCallOnly || '',
264
+ rpcUrl: remote.rpcUrl || fallback?.rpcUrl || '',
265
+ };
266
+ }
267
+ // Pure fallback
97
268
  return {
98
- gasRegistry: mapped ? mapped.gasRegistry : '',
99
- jobRegistry: mapped ? mapped.jobRegistry : '',
100
- safeFactory: mapped ? mapped.safeFactory : '',
101
- safeModule: mapped ? mapped.safeModule : '',
102
- safeSingleton: mapped ? mapped.safeSingleton : '',
103
- multisendCallOnly: mapped ? mapped.multisendCallOnly : '',
104
- rpcUrl: mapped ? mapped.rpcUrl : '',
269
+ gasRegistry: fallback ? fallback.gasRegistry : '',
270
+ jobRegistry: fallback ? fallback.jobRegistry : '',
271
+ safeFactory: fallback ? fallback.safeFactory : '',
272
+ safeModule: fallback ? fallback.safeModule : '',
273
+ safeSingleton: fallback ? fallback.safeSingleton : '',
274
+ multisendCallOnly: fallback ? fallback.multisendCallOnly : '',
275
+ rpcUrl: fallback ? fallback.rpcUrl : '',
105
276
  };
106
277
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sdk-triggerx",
3
- "version": "0.1.38",
3
+ "version": "0.1.40",
4
4
  "description": "SDK for interacting with the TriggerX backend and smart contracts.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",