sdk-triggerx 0.1.28 → 0.1.29
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/checkTgBalance.js +21 -26
- package/dist/api/jobs.js +12 -2
- package/dist/api/topupTg.js +58 -12
- package/dist/api/withdrawTg.js +19 -9
- package/dist/config.js +13 -1
- package/dist/contracts/JobRegistry.js +12 -5
- package/dist/contracts/contractUtils.d.ts +54 -0
- package/dist/contracts/contractUtils.js +125 -0
- package/dist/contracts/index.d.ts +1 -0
- package/dist/contracts/index.js +2 -0
- package/package.json +1 -1
|
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.checkTgBalance = void 0;
|
|
7
7
|
const ethers_1 = require("ethers");
|
|
8
8
|
const GasRegistry_json_1 = __importDefault(require("../contracts/abi/GasRegistry.json"));
|
|
9
|
-
const
|
|
9
|
+
const contractUtils_1 = require("../contracts/contractUtils");
|
|
10
10
|
const errors_1 = require("../utils/errors");
|
|
11
11
|
/**
|
|
12
12
|
* Check TG balance for a given signer using SDK-provided RPC
|
|
@@ -22,36 +22,31 @@ const checkTgBalance = async (signer, chainId) => {
|
|
|
22
22
|
return (0, errors_1.createErrorResponse)(new errors_1.ValidationError('signer', 'Signer is required'), 'Validation error');
|
|
23
23
|
}
|
|
24
24
|
try {
|
|
25
|
-
//
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
catch (providerError) {
|
|
34
|
-
// If user's RPC fails, we can't get chainId from it
|
|
35
|
-
// This is expected in cases where user's RPC is down
|
|
36
|
-
console.warn('Could not get network from signer provider, using provided chainId or will fail:', providerError);
|
|
25
|
+
// Resolve chain ID (use provided chainId or resolve from signer)
|
|
26
|
+
let resolvedChainId;
|
|
27
|
+
try {
|
|
28
|
+
resolvedChainId = await (0, contractUtils_1.resolveChainId)(signer, chainId);
|
|
29
|
+
}
|
|
30
|
+
catch (configError) {
|
|
31
|
+
if (configError instanceof errors_1.ConfigurationError) {
|
|
32
|
+
return (0, errors_1.createErrorResponse)(configError, 'Configuration error');
|
|
37
33
|
}
|
|
34
|
+
return (0, errors_1.createErrorResponse)(new errors_1.ConfigurationError('Failed to resolve chain ID', { originalError: configError }), 'Configuration error');
|
|
38
35
|
}
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
// Get contract address
|
|
37
|
+
let gasRegistryContractAddress;
|
|
38
|
+
try {
|
|
39
|
+
gasRegistryContractAddress = (0, contractUtils_1.getContractAddress)(resolvedChainId, 'gasRegistry');
|
|
41
40
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
catch (configError) {
|
|
42
|
+
if (configError instanceof errors_1.ConfigurationError) {
|
|
43
|
+
return (0, errors_1.createErrorResponse)(configError, 'Configuration error');
|
|
44
|
+
}
|
|
45
|
+
return (0, errors_1.createErrorResponse)(new errors_1.ConfigurationError('Failed to get contract address', { originalError: configError }), 'Configuration error');
|
|
46
46
|
}
|
|
47
|
-
//
|
|
47
|
+
// Create contract instance with SDK RPC provider (read-only)
|
|
48
48
|
// This ensures we can read balance even if user's RPC fails
|
|
49
|
-
const
|
|
50
|
-
if (!rpcProvider) {
|
|
51
|
-
return (0, errors_1.createErrorResponse)(new errors_1.ConfigurationError(`RPC URL not configured for chain ID: ${resolvedChainId}. Cannot check balance without RPC provider.`), 'Configuration error');
|
|
52
|
-
}
|
|
53
|
-
// Create contract instance with our RPC provider (read-only)
|
|
54
|
-
const contract = new ethers_1.ethers.Contract(gasRegistryContractAddress, GasRegistry_json_1.default, rpcProvider);
|
|
49
|
+
const contract = await (0, contractUtils_1.createContractWithSdkRpc)(gasRegistryContractAddress, GasRegistry_json_1.default, resolvedChainId, signer);
|
|
55
50
|
// Get address from signer (this doesn't require provider)
|
|
56
51
|
const address = await signer.getAddress();
|
|
57
52
|
// Read balance using our RPC provider
|
package/dist/api/jobs.js
CHANGED
|
@@ -372,7 +372,9 @@ async function createJob(client, params) {
|
|
|
372
372
|
noOfExecutions = jobInput.timeFrame / (jobInput.timeInterval ?? 0);
|
|
373
373
|
}
|
|
374
374
|
// Set job_cost_prediction
|
|
375
|
-
|
|
375
|
+
// ethers.parseEther expects a string, so we construct the ether amount string safely
|
|
376
|
+
let job_cost_prediction = Number(ethers_1.ethers.parseEther((0.1 * noOfExecutions).toString()).toString()); // default for static
|
|
377
|
+
// console.log('job_cost_prediction', job_cost_prediction);
|
|
376
378
|
if (argType === 2) {
|
|
377
379
|
// Dynamic: call backend API to get fee
|
|
378
380
|
const ipfs_url = jobInput.dynamicArgumentsScriptUrl;
|
|
@@ -383,6 +385,10 @@ async function createJob(client, params) {
|
|
|
383
385
|
let fee = 0;
|
|
384
386
|
try {
|
|
385
387
|
const feeRes = await client.get('/api/fees', { params: { ipfs_url } });
|
|
388
|
+
// console.log('feeRes', feeRes);
|
|
389
|
+
// console.log('feeRes.total_fee', feeRes.total_fee);
|
|
390
|
+
// console.log('typeof feeRes', typeof feeRes);
|
|
391
|
+
// console.log('typeof feeRes.total_fee', typeof feeRes.total_fee);
|
|
386
392
|
// The API now returns { total_fee: number }
|
|
387
393
|
if (feeRes && typeof feeRes.total_fee === 'number') {
|
|
388
394
|
fee = feeRes.total_fee;
|
|
@@ -399,8 +405,11 @@ async function createJob(client, params) {
|
|
|
399
405
|
const errorCode = (0, errors_1.determineErrorCode)(err, httpStatusCode);
|
|
400
406
|
return (0, errors_1.createErrorResponse)(new errors_1.ApiError('Failed to fetch job cost prediction', { originalError: err, ipfs_url }, httpStatusCode), 'API error');
|
|
401
407
|
}
|
|
408
|
+
// console.log('fee', fee);
|
|
409
|
+
// console.log('noOfExecutions', noOfExecutions);
|
|
402
410
|
job_cost_prediction = fee * noOfExecutions;
|
|
403
411
|
}
|
|
412
|
+
// console.log('job_cost_prediction', job_cost_prediction);
|
|
404
413
|
// Ask user if they want to proceed
|
|
405
414
|
// Since this is a library, we can't prompt in Node.js directly.
|
|
406
415
|
// We'll throw an error with the fee and let the caller handle the prompt/confirmation.
|
|
@@ -419,7 +428,7 @@ async function createJob(client, params) {
|
|
|
419
428
|
catch (err) {
|
|
420
429
|
return (0, errors_1.createErrorResponse)(new errors_1.BalanceError('Failed to check TG balance', { originalError: err }), 'Balance check error');
|
|
421
430
|
}
|
|
422
|
-
if (Number(
|
|
431
|
+
if (Number(tgBalanceWei) < job_cost_prediction) {
|
|
423
432
|
// Check if user has enabled auto topup
|
|
424
433
|
// For each job type, autotopupTG should be present in jobInput
|
|
425
434
|
const autoTopupTG = jobInput.autotopupTG === true;
|
|
@@ -434,6 +443,7 @@ async function createJob(client, params) {
|
|
|
434
443
|
// autotopupTG is true, automatically top up
|
|
435
444
|
const requiredTG = Math.ceil(job_cost_prediction); // 1 TG = 0.001 ETH
|
|
436
445
|
try {
|
|
446
|
+
console.log('topping up TG balance', requiredTG);
|
|
437
447
|
const topupResult = await (0, topupTg_1.topupTg)(requiredTG, signer);
|
|
438
448
|
if (!topupResult.success) {
|
|
439
449
|
return (0, errors_1.createErrorResponse)(new errors_1.BalanceError('Failed to top up TG balance', topupResult.details), 'Top-up error');
|
package/dist/api/topupTg.js
CHANGED
|
@@ -4,11 +4,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.topupTg = void 0;
|
|
7
|
-
const ethers_1 = require("ethers");
|
|
8
7
|
const GasRegistry_json_1 = __importDefault(require("../contracts/abi/GasRegistry.json"));
|
|
9
|
-
const
|
|
8
|
+
const contractUtils_1 = require("../contracts/contractUtils");
|
|
10
9
|
const errors_1 = require("../utils/errors");
|
|
11
10
|
const topupTg = async (tgAmount, signer) => {
|
|
11
|
+
console.log('topping up TG balance', tgAmount);
|
|
12
12
|
// Validate inputs
|
|
13
13
|
if (!tgAmount || tgAmount <= 0) {
|
|
14
14
|
return (0, errors_1.createErrorResponse)(new errors_1.ValidationError('tgAmount', 'TG amount must be a positive number'), 'Validation error');
|
|
@@ -17,20 +17,66 @@ const topupTg = async (tgAmount, signer) => {
|
|
|
17
17
|
return (0, errors_1.createErrorResponse)(new errors_1.ValidationError('signer', 'Signer is required'), 'Validation error');
|
|
18
18
|
}
|
|
19
19
|
try {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
// Get contract address and create contract instances with SDK RPC provider
|
|
21
|
+
// This ensures we can interact with the contract even if user's RPC fails
|
|
22
|
+
let gasRegistryContractAddress;
|
|
23
|
+
let contract;
|
|
24
|
+
let contractWithSigner;
|
|
25
|
+
let resolvedChainId;
|
|
26
|
+
let signerAddress;
|
|
27
|
+
try {
|
|
28
|
+
// Get signer address (this doesn't require the signer's provider to work)
|
|
29
|
+
signerAddress = await signer.getAddress();
|
|
30
|
+
// Resolve chain ID from signer
|
|
31
|
+
resolvedChainId = await (0, contractUtils_1.resolveChainId)(signer);
|
|
32
|
+
// Get contract address
|
|
33
|
+
gasRegistryContractAddress = (0, contractUtils_1.getContractAddress)(resolvedChainId, 'gasRegistry');
|
|
34
|
+
// Create contract instances with SDK RPC provider
|
|
35
|
+
const contractInstances = await (0, contractUtils_1.createContractWithSdkRpcAndSigner)(gasRegistryContractAddress, GasRegistry_json_1.default, signer, resolvedChainId);
|
|
36
|
+
contract = contractInstances.contract;
|
|
37
|
+
contractWithSigner = contractInstances.contractWithSigner;
|
|
38
|
+
}
|
|
39
|
+
catch (configError) {
|
|
40
|
+
if (configError instanceof errors_1.ConfigurationError) {
|
|
41
|
+
return (0, errors_1.createErrorResponse)(configError, 'Configuration error');
|
|
42
|
+
}
|
|
43
|
+
return (0, errors_1.createErrorResponse)(new errors_1.ConfigurationError('Failed to initialize contract', { originalError: configError }), 'Configuration error');
|
|
26
44
|
}
|
|
27
|
-
const contract = new ethers_1.ethers.Contract(gasRegistryContractAddress, GasRegistry_json_1.default, signer);
|
|
28
45
|
// Each TG costs 0.001 ETH, so calculate the ETH required for the given TG amount
|
|
46
|
+
console.log('tgAmount', tgAmount);
|
|
29
47
|
const amountInEthWei = tgAmount;
|
|
30
48
|
// const amountInEthWei = ethers.parseEther(amountInEth.toString());
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
49
|
+
console.log('amountInEthWei', amountInEthWei);
|
|
50
|
+
// Estimate gas for the transaction using SDK RPC provider
|
|
51
|
+
// This ensures gas estimation works even if user's RPC fails
|
|
52
|
+
let estimatedGas;
|
|
53
|
+
try {
|
|
54
|
+
console.log('Estimating gas using SDK RPC provider...');
|
|
55
|
+
// Use contract instance with SDK RPC provider for estimation
|
|
56
|
+
// Specify the signer's address in the estimation options
|
|
57
|
+
estimatedGas = await contract.purchaseTG.estimateGas(amountInEthWei, {
|
|
58
|
+
value: amountInEthWei,
|
|
59
|
+
from: signerAddress // Specify the sender address for accurate estimation
|
|
60
|
+
});
|
|
61
|
+
console.log('Estimated gas (using SDK RPC):', estimatedGas.toString());
|
|
62
|
+
// Add 10% buffer to ensure transaction doesn't fail
|
|
63
|
+
const gasWithBuffer = (estimatedGas * BigInt(110)) / BigInt(100);
|
|
64
|
+
console.log('Gas with 10% buffer:', gasWithBuffer.toString());
|
|
65
|
+
// Execute transaction using signer (for signing)
|
|
66
|
+
const tx = await contractWithSigner.purchaseTG(amountInEthWei, {
|
|
67
|
+
value: amountInEthWei,
|
|
68
|
+
gasLimit: gasWithBuffer
|
|
69
|
+
});
|
|
70
|
+
await tx.wait();
|
|
71
|
+
return { success: true, data: tx };
|
|
72
|
+
}
|
|
73
|
+
catch (gasEstimateError) {
|
|
74
|
+
// If gas estimation fails, try without gas limit (let provider estimate)
|
|
75
|
+
console.warn('Gas estimation failed (using SDK RPC), proceeding without gas limit:', gasEstimateError);
|
|
76
|
+
const tx = await contractWithSigner.purchaseTG(amountInEthWei, { value: amountInEthWei });
|
|
77
|
+
await tx.wait();
|
|
78
|
+
return { success: true, data: tx };
|
|
79
|
+
}
|
|
34
80
|
}
|
|
35
81
|
catch (error) {
|
|
36
82
|
console.error('Error topping up TG:', error);
|
package/dist/api/withdrawTg.js
CHANGED
|
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.withdrawTg = void 0;
|
|
7
7
|
const ethers_1 = require("ethers");
|
|
8
8
|
const GasRegistry_json_1 = __importDefault(require("../contracts/abi/GasRegistry.json"));
|
|
9
|
-
const
|
|
9
|
+
const contractUtils_1 = require("../contracts/contractUtils");
|
|
10
10
|
const errors_1 = require("../utils/errors");
|
|
11
11
|
/**
|
|
12
12
|
* Withdraw ETH in exchange for TG tokens.
|
|
@@ -23,17 +23,27 @@ const withdrawTg = async (signer, amountTG) => {
|
|
|
23
23
|
return (0, errors_1.createErrorResponse)(new errors_1.ValidationError('amountTG', 'Amount must be a positive number'), 'Validation error');
|
|
24
24
|
}
|
|
25
25
|
try {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
// Resolve chain ID and create contract instances with SDK RPC provider
|
|
27
|
+
let resolvedChainId;
|
|
28
|
+
let contractWithSigner;
|
|
29
|
+
try {
|
|
30
|
+
// Resolve chain ID from signer
|
|
31
|
+
resolvedChainId = await (0, contractUtils_1.resolveChainId)(signer);
|
|
32
|
+
// Get contract address
|
|
33
|
+
const gasRegistryContractAddress = (0, contractUtils_1.getContractAddress)(resolvedChainId, 'gasRegistry');
|
|
34
|
+
// Create contract instances with SDK RPC provider
|
|
35
|
+
const contractInstances = await (0, contractUtils_1.createContractWithSdkRpcAndSigner)(gasRegistryContractAddress, GasRegistry_json_1.default, signer, resolvedChainId);
|
|
36
|
+
contractWithSigner = contractInstances.contractWithSigner;
|
|
37
|
+
}
|
|
38
|
+
catch (configError) {
|
|
39
|
+
if (configError instanceof errors_1.ConfigurationError) {
|
|
40
|
+
return (0, errors_1.createErrorResponse)(configError, 'Configuration error');
|
|
41
|
+
}
|
|
42
|
+
return (0, errors_1.createErrorResponse)(new errors_1.ConfigurationError('Failed to initialize contract', { originalError: configError }), 'Configuration error');
|
|
32
43
|
}
|
|
33
|
-
const contract = new ethers_1.ethers.Contract(gasRegistryContractAddress, GasRegistry_json_1.default, signer);
|
|
34
44
|
// Assumes the contract has a function: claimEthForTg(uint256 amount)
|
|
35
45
|
const amountTGWei = ethers_1.ethers.parseEther(amountTG.toString());
|
|
36
|
-
const tx = await
|
|
46
|
+
const tx = await contractWithSigner.claimETHForTG(amountTGWei);
|
|
37
47
|
await tx.wait();
|
|
38
48
|
return { success: true, data: tx };
|
|
39
49
|
}
|
package/dist/config.js
CHANGED
|
@@ -75,7 +75,19 @@ function getRpcProvider(chainId) {
|
|
|
75
75
|
if (!rpcUrl) {
|
|
76
76
|
return null;
|
|
77
77
|
}
|
|
78
|
-
|
|
78
|
+
// Convert chainId to number for network configuration
|
|
79
|
+
const chainIdNum = chainId ? Number(chainId) : undefined;
|
|
80
|
+
if (!chainIdNum) {
|
|
81
|
+
// If no chainId, create provider without network (will auto-detect)
|
|
82
|
+
return new ethers_1.ethers.JsonRpcProvider(rpcUrl);
|
|
83
|
+
}
|
|
84
|
+
// Create a Network object with the chainId to explicitly set the network
|
|
85
|
+
// This prevents the provider from trying to auto-detect the network,
|
|
86
|
+
// which can cause timeouts when the RPC is slow or unresponsive
|
|
87
|
+
const network = ethers_1.ethers.Network.from(chainIdNum);
|
|
88
|
+
// Create provider with explicit network to skip network detection
|
|
89
|
+
// This prevents timeout issues when RPC is slow or unresponsive
|
|
90
|
+
return new ethers_1.ethers.JsonRpcProvider(rpcUrl, network);
|
|
79
91
|
}
|
|
80
92
|
function getChainAddresses(chainId) {
|
|
81
93
|
const chainKey = String(chainId ?? '');
|
|
@@ -2,12 +2,17 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createJobOnChain = createJobOnChain;
|
|
4
4
|
exports.deleteJobOnChain = deleteJobOnChain;
|
|
5
|
-
const
|
|
5
|
+
const contractUtils_1 = require("./contractUtils");
|
|
6
6
|
async function createJobOnChain({ jobTitle, jobType, timeFrame, targetContractAddress, encodedData, contractAddress, abi, signer, }) {
|
|
7
|
-
|
|
8
|
-
const
|
|
7
|
+
// Resolve chain ID and create contract with SDK RPC provider
|
|
8
|
+
const chainId = await (0, contractUtils_1.resolveChainId)(signer);
|
|
9
|
+
const { contract, contractWithSigner } = await (0, contractUtils_1.createContractWithSdkRpcAndSigner)(contractAddress, abi, signer, chainId);
|
|
10
|
+
// Use contractWithSigner for transaction (signing)
|
|
11
|
+
// Use contract for reading/parsing logs (SDK RPC)
|
|
12
|
+
const tx = await contractWithSigner.createJob(jobTitle, jobType, timeFrame, targetContractAddress, encodedData);
|
|
9
13
|
const receipt = await tx.wait();
|
|
10
14
|
// Try to extract jobId from event logs (assume event is JobCreated(jobId,...))
|
|
15
|
+
// Use contract (with SDK RPC) for parsing logs
|
|
11
16
|
const event = receipt.logs
|
|
12
17
|
.map((log) => {
|
|
13
18
|
try {
|
|
@@ -24,7 +29,9 @@ async function createJobOnChain({ jobTitle, jobType, timeFrame, targetContractAd
|
|
|
24
29
|
throw new Error('Job ID not found in contract events');
|
|
25
30
|
}
|
|
26
31
|
async function deleteJobOnChain({ jobId, contractAddress, abi, signer, }) {
|
|
27
|
-
|
|
28
|
-
const
|
|
32
|
+
// Resolve chain ID and create contract with SDK RPC provider
|
|
33
|
+
const chainId = await (0, contractUtils_1.resolveChainId)(signer);
|
|
34
|
+
const { contractWithSigner } = await (0, contractUtils_1.createContractWithSdkRpcAndSigner)(contractAddress, abi.abi || abi, signer, chainId);
|
|
35
|
+
const tx = await contractWithSigner.deleteJob(jobId);
|
|
29
36
|
await tx.wait();
|
|
30
37
|
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { ethers, Contract } from 'ethers';
|
|
2
|
+
/**
|
|
3
|
+
* Get SDK RPC provider for a given chain ID
|
|
4
|
+
* This ensures reliable connection even if user's RPC fails
|
|
5
|
+
* @param chainId - Chain ID as string or number
|
|
6
|
+
* @returns ethers.JsonRpcProvider instance
|
|
7
|
+
* @throws ConfigurationError if RPC provider is not available
|
|
8
|
+
*/
|
|
9
|
+
export declare function getSdkRpcProvider(chainId: string | number | undefined): ethers.JsonRpcProvider;
|
|
10
|
+
/**
|
|
11
|
+
* Resolve chain ID from signer's provider or use provided chainId
|
|
12
|
+
* @param signer - ethers.Signer instance
|
|
13
|
+
* @param chainId - Optional chain ID (takes precedence if provided)
|
|
14
|
+
* @returns Resolved chain ID as string
|
|
15
|
+
* @throws ConfigurationError if chain ID cannot be resolved
|
|
16
|
+
*/
|
|
17
|
+
export declare function resolveChainId(signer: ethers.Signer, chainId?: string | number): Promise<string>;
|
|
18
|
+
/**
|
|
19
|
+
* Create a contract instance with SDK RPC provider for read operations and gas estimation
|
|
20
|
+
* This ensures reliable contract interaction even if user's RPC fails
|
|
21
|
+
* @param contractAddress - Contract address
|
|
22
|
+
* @param abi - Contract ABI
|
|
23
|
+
* @param chainId - Chain ID (will be resolved if not provided)
|
|
24
|
+
* @param signer - Optional signer (used to resolve chainId if not provided)
|
|
25
|
+
* @returns Contract instance connected to SDK RPC provider
|
|
26
|
+
*/
|
|
27
|
+
export declare function createContractWithSdkRpc(contractAddress: string, abi: any, chainId: string | number | undefined, signer?: ethers.Signer): Promise<Contract>;
|
|
28
|
+
/**
|
|
29
|
+
* Create a contract instance with SDK RPC provider and connect signer for transactions
|
|
30
|
+
* This pattern is used for operations that need:
|
|
31
|
+
* - SDK RPC for reads/estimations (reliable even if user's RPC fails)
|
|
32
|
+
* - User's signer for transaction signing
|
|
33
|
+
* @param contractAddress - Contract address
|
|
34
|
+
* @param abi - Contract ABI
|
|
35
|
+
* @param signer - Signer instance (used for signing transactions)
|
|
36
|
+
* @param chainId - Optional chain ID (will be resolved from signer if not provided)
|
|
37
|
+
* @returns Object containing:
|
|
38
|
+
* - contract: Contract instance with SDK RPC (for reads/estimations)
|
|
39
|
+
* - contractWithSigner: Contract instance connected to signer (for transactions)
|
|
40
|
+
* - chainId: Resolved chain ID
|
|
41
|
+
*/
|
|
42
|
+
export declare function createContractWithSdkRpcAndSigner(contractAddress: string, abi: any, signer: ethers.Signer, chainId?: string | number): Promise<{
|
|
43
|
+
contract: Contract;
|
|
44
|
+
contractWithSigner: Contract;
|
|
45
|
+
chainId: string;
|
|
46
|
+
}>;
|
|
47
|
+
/**
|
|
48
|
+
* Get contract address for a given chain ID
|
|
49
|
+
* @param chainId - Chain ID as string or number
|
|
50
|
+
* @param contractType - Type of contract ('gasRegistry' | 'jobRegistry')
|
|
51
|
+
* @returns Contract address
|
|
52
|
+
* @throws ConfigurationError if contract address is not configured
|
|
53
|
+
*/
|
|
54
|
+
export declare function getContractAddress(chainId: string | number | undefined, contractType: 'gasRegistry' | 'jobRegistry'): string;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getSdkRpcProvider = getSdkRpcProvider;
|
|
4
|
+
exports.resolveChainId = resolveChainId;
|
|
5
|
+
exports.createContractWithSdkRpc = createContractWithSdkRpc;
|
|
6
|
+
exports.createContractWithSdkRpcAndSigner = createContractWithSdkRpcAndSigner;
|
|
7
|
+
exports.getContractAddress = getContractAddress;
|
|
8
|
+
const ethers_1 = require("ethers");
|
|
9
|
+
const config_1 = require("../config");
|
|
10
|
+
const errors_1 = require("../utils/errors");
|
|
11
|
+
/**
|
|
12
|
+
* Get SDK RPC provider for a given chain ID
|
|
13
|
+
* This ensures reliable connection even if user's RPC fails
|
|
14
|
+
* @param chainId - Chain ID as string or number
|
|
15
|
+
* @returns ethers.JsonRpcProvider instance
|
|
16
|
+
* @throws ConfigurationError if RPC provider is not available
|
|
17
|
+
*/
|
|
18
|
+
function getSdkRpcProvider(chainId) {
|
|
19
|
+
if (!chainId) {
|
|
20
|
+
throw new errors_1.ConfigurationError('Chain ID is required to get RPC provider');
|
|
21
|
+
}
|
|
22
|
+
const rpcProvider = (0, config_1.getRpcProvider)(chainId);
|
|
23
|
+
if (!rpcProvider) {
|
|
24
|
+
throw new errors_1.ConfigurationError(`RPC URL not configured for chain ID: ${chainId}`);
|
|
25
|
+
}
|
|
26
|
+
return rpcProvider;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Resolve chain ID from signer's provider or use provided chainId
|
|
30
|
+
* @param signer - ethers.Signer instance
|
|
31
|
+
* @param chainId - Optional chain ID (takes precedence if provided)
|
|
32
|
+
* @returns Resolved chain ID as string
|
|
33
|
+
* @throws ConfigurationError if chain ID cannot be resolved
|
|
34
|
+
*/
|
|
35
|
+
async function resolveChainId(signer, chainId) {
|
|
36
|
+
// If chainId is provided, use it
|
|
37
|
+
if (chainId) {
|
|
38
|
+
return chainId.toString();
|
|
39
|
+
}
|
|
40
|
+
// Try to get chainId from signer's provider
|
|
41
|
+
try {
|
|
42
|
+
const network = await signer.provider?.getNetwork();
|
|
43
|
+
if (network?.chainId) {
|
|
44
|
+
return network.chainId.toString();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch (providerError) {
|
|
48
|
+
// If user's RPC fails, we can't get chainId from it
|
|
49
|
+
console.warn('Could not get network from signer provider:', providerError);
|
|
50
|
+
}
|
|
51
|
+
throw new errors_1.ConfigurationError('Chain ID is required. Please provide chainId parameter or ensure signer has a working provider.');
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Create a contract instance with SDK RPC provider for read operations and gas estimation
|
|
55
|
+
* This ensures reliable contract interaction even if user's RPC fails
|
|
56
|
+
* @param contractAddress - Contract address
|
|
57
|
+
* @param abi - Contract ABI
|
|
58
|
+
* @param chainId - Chain ID (will be resolved if not provided)
|
|
59
|
+
* @param signer - Optional signer (used to resolve chainId if not provided)
|
|
60
|
+
* @returns Contract instance connected to SDK RPC provider
|
|
61
|
+
*/
|
|
62
|
+
async function createContractWithSdkRpc(contractAddress, abi, chainId, signer) {
|
|
63
|
+
// Resolve chain ID
|
|
64
|
+
let resolvedChainId;
|
|
65
|
+
if (chainId) {
|
|
66
|
+
resolvedChainId = chainId.toString();
|
|
67
|
+
}
|
|
68
|
+
else if (signer) {
|
|
69
|
+
resolvedChainId = await resolveChainId(signer);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
throw new errors_1.ConfigurationError('Chain ID or signer is required to create contract');
|
|
73
|
+
}
|
|
74
|
+
// Get SDK RPC provider
|
|
75
|
+
const rpcProvider = getSdkRpcProvider(resolvedChainId);
|
|
76
|
+
// Create contract instance with SDK RPC provider
|
|
77
|
+
return new ethers_1.ethers.Contract(contractAddress, abi, rpcProvider);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Create a contract instance with SDK RPC provider and connect signer for transactions
|
|
81
|
+
* This pattern is used for operations that need:
|
|
82
|
+
* - SDK RPC for reads/estimations (reliable even if user's RPC fails)
|
|
83
|
+
* - User's signer for transaction signing
|
|
84
|
+
* @param contractAddress - Contract address
|
|
85
|
+
* @param abi - Contract ABI
|
|
86
|
+
* @param signer - Signer instance (used for signing transactions)
|
|
87
|
+
* @param chainId - Optional chain ID (will be resolved from signer if not provided)
|
|
88
|
+
* @returns Object containing:
|
|
89
|
+
* - contract: Contract instance with SDK RPC (for reads/estimations)
|
|
90
|
+
* - contractWithSigner: Contract instance connected to signer (for transactions)
|
|
91
|
+
* - chainId: Resolved chain ID
|
|
92
|
+
*/
|
|
93
|
+
async function createContractWithSdkRpcAndSigner(contractAddress, abi, signer, chainId) {
|
|
94
|
+
// Resolve chain ID
|
|
95
|
+
const resolvedChainId = await resolveChainId(signer, chainId);
|
|
96
|
+
// Get SDK RPC provider
|
|
97
|
+
const rpcProvider = getSdkRpcProvider(resolvedChainId);
|
|
98
|
+
// Create contract instance with SDK RPC provider (for reads/estimations)
|
|
99
|
+
const contract = new ethers_1.ethers.Contract(contractAddress, abi, rpcProvider);
|
|
100
|
+
// Connect signer to contract (for transactions)
|
|
101
|
+
const contractWithSigner = contract.connect(signer);
|
|
102
|
+
return {
|
|
103
|
+
contract,
|
|
104
|
+
contractWithSigner,
|
|
105
|
+
chainId: resolvedChainId,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Get contract address for a given chain ID
|
|
110
|
+
* @param chainId - Chain ID as string or number
|
|
111
|
+
* @param contractType - Type of contract ('gasRegistry' | 'jobRegistry')
|
|
112
|
+
* @returns Contract address
|
|
113
|
+
* @throws ConfigurationError if contract address is not configured
|
|
114
|
+
*/
|
|
115
|
+
function getContractAddress(chainId, contractType) {
|
|
116
|
+
if (!chainId) {
|
|
117
|
+
throw new errors_1.ConfigurationError('Chain ID is required to get contract address');
|
|
118
|
+
}
|
|
119
|
+
const addresses = (0, config_1.getChainAddresses)(chainId);
|
|
120
|
+
const address = contractType === 'gasRegistry' ? addresses.gasRegistry : addresses.jobRegistry;
|
|
121
|
+
if (!address) {
|
|
122
|
+
throw new errors_1.ConfigurationError(`${contractType} address not configured for chain ID: ${chainId}`);
|
|
123
|
+
}
|
|
124
|
+
return address;
|
|
125
|
+
}
|
package/dist/contracts/index.js
CHANGED
|
@@ -19,3 +19,5 @@ __exportStar(require("./JobRegistry"), exports);
|
|
|
19
19
|
__exportStar(require("./safe/SafeFactory"), exports);
|
|
20
20
|
__exportStar(require("./safe/SafeWallet"), exports);
|
|
21
21
|
__exportStar(require("./TriggerXContract"), exports);
|
|
22
|
+
// Contract utilities for RPC provider management
|
|
23
|
+
__exportStar(require("./contractUtils"), exports);
|