sdk-triggerx 0.1.39 → 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 +2 -0
- package/dist/api/safeWallet.js +2 -0
- package/dist/client.js +3 -0
- package/dist/config.d.ts +18 -2
- package/dist/config.js +197 -26
- package/package.json +1 -1
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) {
|
package/dist/api/safeWallet.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
3
|
-
|
|
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
|
-
|
|
11
|
-
//
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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: '
|
|
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: '
|
|
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: '
|
|
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: '
|
|
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
|
-
|
|
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:
|
|
99
|
-
jobRegistry:
|
|
100
|
-
safeFactory:
|
|
101
|
-
safeModule:
|
|
102
|
-
safeSingleton:
|
|
103
|
-
multisendCallOnly:
|
|
104
|
-
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
|
}
|