@obolnetwork/obol-sdk 2.4.0 → 2.4.2

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@obolnetwork/obol-sdk",
3
- "version": "2.4.0",
3
+ "version": "2.4.2",
4
4
  "description": "A package for creating Distributed Validators using the Obol API.",
5
5
  "bugs": {
6
6
  "url": "https://github.com/obolnetwork/obol-sdk/issues"
@@ -22,9 +22,12 @@ var __importStar = (this && this.__importStar) || function (mod) {
22
22
  __setModuleDefault(result, mod);
23
23
  return result;
24
24
  };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
25
28
  Object.defineProperty(exports, "__esModule", { value: true });
26
29
  exports.PROVIDER_MAP = exports.OBOL_SDK_EMAIL = exports.DEFAULT_RETROACTIVE_FUNDING_TOTAL_SPLIT = exports.DEFAULT_RETROACTIVE_FUNDING_REWARDS_ONLY_SPLIT = exports.CHAIN_CONFIGURATION = exports.AVAILABLE_SPLITTER_CHAINS = exports.TERMS_AND_CONDITIONS_HASH = exports.TERMS_AND_CONDITIONS_URL = exports.TERMS_AND_CONDITIONS_VERSION = exports.ETHER_TO_GWEI = exports.DEFAULT_CHAIN_ID = exports.DEFAULT_BASE_VERSION = exports.DEFAULT_BASE_URL = exports.DefinitionFlow = exports.GENESIS_VALIDATOR_ROOT = exports.DOMAIN_DEPOSIT = exports.DOMAIN_APPLICATION_BUILDER = exports.SDK_VERSION = exports.CONFIG_VERSION = exports.DKG_ALGORITHM = exports.signEnrPayload = exports.signOperatorConfigHashPayload = exports.signCreatorConfigHashPayload = exports.ENRTypedMessage = exports.OperatorTypedMessage = exports.OperatorConfigHashSigningTypes = exports.EnrSigningTypes = exports.CreatorTypedMessage = exports.Domain = exports.TermsAndConditionsSigningTypes = exports.CreatorConfigHashSigningTypes = exports.EIP712_DOMAIN_VERSION = exports.EIP712_DOMAIN_NAME = exports.CONFLICT_ERROR_MSG = void 0;
27
- const pjson = __importStar(require("../package.json"));
30
+ const package_json_1 = __importDefault(require("../package.json"));
28
31
  const types_1 = require("./types");
29
32
  const bytecodes_1 = require("./bytecodes");
30
33
  const dotenv = __importStar(require("dotenv"));
@@ -108,7 +111,7 @@ const signEnrPayload = (payload, chainId) => {
108
111
  exports.signEnrPayload = signEnrPayload;
109
112
  exports.DKG_ALGORITHM = 'default';
110
113
  exports.CONFIG_VERSION = 'v1.8.0';
111
- exports.SDK_VERSION = pjson.version;
114
+ exports.SDK_VERSION = package_json_1.default.version;
112
115
  exports.DOMAIN_APPLICATION_BUILDER = '00000001';
113
116
  exports.DOMAIN_DEPOSIT = '03000000';
114
117
  exports.GENESIS_VALIDATOR_ROOT = '0000000000000000000000000000000000000000000000000000000000000000';
@@ -11,13 +11,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.Incentives = void 0;
13
13
  const utils_1 = require("./utils");
14
+ const types_1 = require("./types");
14
15
  const incentivesHalpers_1 = require("./incentivesHalpers");
15
16
  const constants_1 = require("./constants");
16
17
  class Incentives {
17
- constructor(signer, chainId, request) {
18
+ constructor(signer, chainId, request, provider) {
18
19
  this.signer = signer;
19
20
  this.chainId = chainId;
20
21
  this.request = request;
22
+ this.provider = provider;
21
23
  }
22
24
  /**
23
25
  * Claims obol incentives from a Merkle Distributor contract.
@@ -72,7 +74,7 @@ class Incentives {
72
74
  */
73
75
  isClaimed(contractAddress, index) {
74
76
  return __awaiter(this, void 0, void 0, function* () {
75
- return yield (0, incentivesHalpers_1.isClaimedFromMerkleDistributor)(this.chainId, contractAddress, index);
77
+ return yield (0, incentivesHalpers_1.isClaimedFromMerkleDistributor)(this.chainId, contractAddress, index, this.provider);
76
78
  });
77
79
  }
78
80
  /**
@@ -82,7 +84,8 @@ class Incentives {
82
84
  */
83
85
  getIncentivesByAddress(address) {
84
86
  return __awaiter(this, void 0, void 0, function* () {
85
- const incentives = yield this.request(`/${constants_1.DEFAULT_BASE_VERSION}/address/incentives/${address}`, {
87
+ const network = types_1.FORK_NAMES[this.chainId];
88
+ const incentives = yield this.request(`/${constants_1.DEFAULT_BASE_VERSION}/address/incentives/${network}/${address}`, {
86
89
  method: 'GET',
87
90
  });
88
91
  return incentives;
@@ -26,10 +26,10 @@ const claimIncentivesFromMerkleDistributor = (incentivesData) => __awaiter(void
26
26
  }
27
27
  });
28
28
  exports.claimIncentivesFromMerkleDistributor = claimIncentivesFromMerkleDistributor;
29
- const isClaimedFromMerkleDistributor = (chainId, contractAddress, index) => __awaiter(void 0, void 0, void 0, function* () {
29
+ const isClaimedFromMerkleDistributor = (chainId, contractAddress, index, provider) => __awaiter(void 0, void 0, void 0, function* () {
30
30
  try {
31
- const provider = (0, utils_1.getProvider)(chainId);
32
- const contract = new ethers_1.Contract(contractAddress, MerkleDistributorWithDeadline_1.MerkleDistributorABI.abi, provider);
31
+ const clientProvider = provider !== null && provider !== void 0 ? provider : (0, utils_1.getProvider)(chainId);
32
+ const contract = new ethers_1.Contract(contractAddress, MerkleDistributorWithDeadline_1.MerkleDistributorABI.abi, clientProvider);
33
33
  const claimed = yield contract.isClaimed(BigInt(index));
34
34
  return claimed;
35
35
  }
@@ -53,10 +53,13 @@ class Client extends base_js_1.Base {
53
53
  * An example of how to instantiate obol-sdk Client:
54
54
  * [obolClient](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts#L29)
55
55
  */
56
- constructor(config, signer) {
56
+ constructor(config, signer, provider) {
57
57
  super(config);
58
58
  this.signer = signer;
59
- this.incentives = new incentives_js_1.Incentives(this.signer, this.chainId, this.request.bind(this));
59
+ // Use the provided provider, or fall back to signer.provider if available
60
+ this.provider =
61
+ provider !== null && provider !== void 0 ? provider : (signer && 'provider' in signer ? signer.provider : undefined);
62
+ this.incentives = new incentives_js_1.Incentives(this.signer, this.chainId, this.request.bind(this), (this.provider = provider));
60
63
  }
61
64
  /**
62
65
  * Accepts Obol terms and conditions to be able to create or update data.
@@ -22,7 +22,7 @@ const utils_1 = require("@safe-global/protocol-kit/dist/src/utils");
22
22
  const utils_2 = require("../utils");
23
23
  const validateAddressSignature = ({ address, token, data, chainId, }) => __awaiter(void 0, void 0, void 0, function* () {
24
24
  try {
25
- const provider = (0, utils_2.getProvider)(chainId);
25
+ const provider = (0, utils_2.getProvider)(chainId); // [TODO Hanan], should expect it from signer.provider, or passed in client
26
26
  if (provider) {
27
27
  const contractAddress = yield (0, utils_2.isContractAvailable)(address, provider);
28
28
  if (contractAddress) {
@@ -116,7 +116,7 @@ describe('Client.incentives', () => {
116
116
  .mockImplementation(() => __awaiter(void 0, void 0, void 0, function* () { return yield Promise.resolve(true); }));
117
117
  const result = yield clientInstance.incentives.isClaimed(mockIncentivesData.contractAddress, mockIncentivesData.index);
118
118
  expect(result).toBe(true);
119
- expect(incentivesHelpers.isClaimedFromMerkleDistributor).toHaveBeenCalledWith(clientInstance.incentives.chainId, mockIncentivesData.contractAddress, mockIncentivesData.index);
119
+ expect(incentivesHelpers.isClaimedFromMerkleDistributor).toHaveBeenCalledWith(clientInstance.incentives.chainId, mockIncentivesData.contractAddress, mockIncentivesData.index, undefined);
120
120
  }));
121
121
  test('isClaimed should return false when incentive is not claimed', () => __awaiter(void 0, void 0, void 0, function* () {
122
122
  jest
@@ -133,18 +133,18 @@ describe('Client.incentives', () => {
133
133
  }));
134
134
  yield expect(clientInstance.incentives.isClaimed(mockIncentivesData.contractAddress, mockIncentivesData.index)).rejects.toThrow('Helper function error');
135
135
  }));
136
- test('isClaimed should work with a client without signer', () => __awaiter(void 0, void 0, void 0, function* () {
136
+ test('isClaimed should work with a provider and a without signer', () => __awaiter(void 0, void 0, void 0, function* () {
137
137
  // Create a client without a signer
138
138
  const clientWithoutSigner = new index_1.Client({
139
139
  baseUrl,
140
140
  chainId: 17000,
141
- });
141
+ }, undefined, provider);
142
142
  jest
143
143
  .spyOn(incentivesHelpers, 'isClaimedFromMerkleDistributor')
144
144
  .mockImplementation(() => __awaiter(void 0, void 0, void 0, function* () { return yield Promise.resolve(true); }));
145
145
  const result = yield clientWithoutSigner.incentives.isClaimed(mockIncentivesData.contractAddress, mockIncentivesData.index);
146
146
  expect(result).toBe(true);
147
- expect(incentivesHelpers.isClaimedFromMerkleDistributor).toHaveBeenCalledWith(clientWithoutSigner.incentives.chainId, mockIncentivesData.contractAddress, mockIncentivesData.index);
147
+ expect(incentivesHelpers.isClaimedFromMerkleDistributor).toHaveBeenCalledWith(clientWithoutSigner.incentives.chainId, mockIncentivesData.contractAddress, mockIncentivesData.index, provider);
148
148
  }));
149
149
  test('getIncentivesByAddress should make the correct API request', () => __awaiter(void 0, void 0, void 0, function* () {
150
150
  const mockAddress = '0x1234567890abcdef1234567890abcdef12345678';
@@ -163,7 +163,7 @@ describe('Client.incentives', () => {
163
163
  });
164
164
  const result = yield clientInstance.incentives.getIncentivesByAddress(mockAddress);
165
165
  expect(result).toEqual(mockIncentives);
166
- expect(global.fetch).toHaveBeenCalledWith(`${baseUrl}/${constants_1.DEFAULT_BASE_VERSION}/address/incentives/${mockAddress}`, expect.objectContaining({ method: 'GET' }));
166
+ expect(global.fetch).toHaveBeenCalledWith(`${baseUrl}/${constants_1.DEFAULT_BASE_VERSION}/address/incentives/holesky/${mockAddress}`, expect.objectContaining({ method: 'GET' }));
167
167
  }));
168
168
  test('getIncentivesByAddress should handle API errors', () => __awaiter(void 0, void 0, void 0, function* () {
169
169
  const mockAddress = '0x1234567890abcdef1234567890abcdef12345678';
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@obolnetwork/obol-sdk",
3
- "version": "2.4.0",
3
+ "version": "2.4.2",
4
4
  "description": "A package for creating Distributed Validators using the Obol API.",
5
5
  "bugs": {
6
6
  "url": "https://github.com/obolnetwork/obol-sdk/issues"
@@ -1,4 +1,4 @@
1
- import * as pjson from '../package.json';
1
+ import pjson from '../package.json';
2
2
  import { FORK_MAPPING } from './types';
3
3
  import { HOLESKY_MULTICALL_BYTECODE, HOLESKY_OWR_FACTORY_BYTECODE, HOLESKY_SPLITMAIN_BYTECODE, MAINNET_MULTICALL_BYTECODE, MAINNET_OWR_FACTORY_BYTECODE, MAINNET_SPLITMAIN_BYTECODE, } from './bytecodes';
4
4
  import * as dotenv from 'dotenv';
@@ -8,13 +8,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import { isContractAvailable } from './utils';
11
+ import { FORK_NAMES, } from './types';
11
12
  import { claimIncentivesFromMerkleDistributor, isClaimedFromMerkleDistributor, } from './incentivesHalpers';
12
13
  import { DEFAULT_BASE_VERSION } from './constants';
13
14
  export class Incentives {
14
- constructor(signer, chainId, request) {
15
+ constructor(signer, chainId, request, provider) {
15
16
  this.signer = signer;
16
17
  this.chainId = chainId;
17
18
  this.request = request;
19
+ this.provider = provider;
18
20
  }
19
21
  /**
20
22
  * Claims obol incentives from a Merkle Distributor contract.
@@ -69,7 +71,7 @@ export class Incentives {
69
71
  */
70
72
  isClaimed(contractAddress, index) {
71
73
  return __awaiter(this, void 0, void 0, function* () {
72
- return yield isClaimedFromMerkleDistributor(this.chainId, contractAddress, index);
74
+ return yield isClaimedFromMerkleDistributor(this.chainId, contractAddress, index, this.provider);
73
75
  });
74
76
  }
75
77
  /**
@@ -79,7 +81,8 @@ export class Incentives {
79
81
  */
80
82
  getIncentivesByAddress(address) {
81
83
  return __awaiter(this, void 0, void 0, function* () {
82
- const incentives = yield this.request(`/${DEFAULT_BASE_VERSION}/address/incentives/${address}`, {
84
+ const network = FORK_NAMES[this.chainId];
85
+ const incentives = yield this.request(`/${DEFAULT_BASE_VERSION}/address/incentives/${network}/${address}`, {
83
86
  method: 'GET',
84
87
  });
85
88
  return incentives;
@@ -7,7 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import { Contract } from 'ethers';
10
+ import { Contract, } from 'ethers';
11
11
  import { MerkleDistributorABI } from './abi/MerkleDistributorWithDeadline';
12
12
  import { getProvider } from './utils';
13
13
  export const claimIncentivesFromMerkleDistributor = (incentivesData) => __awaiter(void 0, void 0, void 0, function* () {
@@ -22,10 +22,10 @@ export const claimIncentivesFromMerkleDistributor = (incentivesData) => __awaite
22
22
  throw new Error(`Failed to claim incentives: ${error.message}`);
23
23
  }
24
24
  });
25
- export const isClaimedFromMerkleDistributor = (chainId, contractAddress, index) => __awaiter(void 0, void 0, void 0, function* () {
25
+ export const isClaimedFromMerkleDistributor = (chainId, contractAddress, index, provider) => __awaiter(void 0, void 0, void 0, function* () {
26
26
  try {
27
- const provider = getProvider(chainId);
28
- const contract = new Contract(contractAddress, MerkleDistributorABI.abi, provider);
27
+ const clientProvider = provider !== null && provider !== void 0 ? provider : getProvider(chainId);
28
+ const contract = new Contract(contractAddress, MerkleDistributorABI.abi, clientProvider);
29
29
  const claimed = yield contract.isClaimed(BigInt(index));
30
30
  return claimed;
31
31
  }
@@ -7,7 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import { ZeroAddress } from 'ethers';
10
+ import { ZeroAddress, } from 'ethers';
11
11
  import { v4 as uuidv4 } from 'uuid';
12
12
  import { Base } from './base.js';
13
13
  import { CONFLICT_ERROR_MSG, CreatorConfigHashSigningTypes, Domain, DKG_ALGORITHM, CONFIG_VERSION, OperatorConfigHashSigningTypes, EnrSigningTypes, TERMS_AND_CONDITIONS_VERSION, TermsAndConditionsSigningTypes, DEFAULT_BASE_VERSION, TERMS_AND_CONDITIONS_HASH, AVAILABLE_SPLITTER_CHAINS, CHAIN_CONFIGURATION, DEFAULT_RETROACTIVE_FUNDING_REWARDS_ONLY_SPLIT, DEFAULT_RETROACTIVE_FUNDING_TOTAL_SPLIT, OBOL_SDK_EMAIL, } from './constants.js';
@@ -36,10 +36,13 @@ export class Client extends Base {
36
36
  * An example of how to instantiate obol-sdk Client:
37
37
  * [obolClient](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts#L29)
38
38
  */
39
- constructor(config, signer) {
39
+ constructor(config, signer, provider) {
40
40
  super(config);
41
41
  this.signer = signer;
42
- this.incentives = new Incentives(this.signer, this.chainId, this.request.bind(this));
42
+ // Use the provided provider, or fall back to signer.provider if available
43
+ this.provider =
44
+ provider !== null && provider !== void 0 ? provider : (signer && 'provider' in signer ? signer.provider : undefined);
45
+ this.incentives = new Incentives(this.signer, this.chainId, this.request.bind(this), (this.provider = provider));
43
46
  }
44
47
  /**
45
48
  * Accepts Obol terms and conditions to be able to create or update data.
@@ -16,7 +16,7 @@ import { hashTypedData } from '@safe-global/protocol-kit/dist/src/utils';
16
16
  import { isContractAvailable, getProvider } from '../utils';
17
17
  export const validateAddressSignature = ({ address, token, data, chainId, }) => __awaiter(void 0, void 0, void 0, function* () {
18
18
  try {
19
- const provider = getProvider(chainId);
19
+ const provider = getProvider(chainId); // [TODO Hanan], should expect it from signer.provider, or passed in client
20
20
  if (provider) {
21
21
  const contractAddress = yield isContractAvailable(address, provider);
22
22
  if (contractAddress) {
@@ -91,7 +91,7 @@ describe('Client.incentives', () => {
91
91
  .mockImplementation(() => __awaiter(void 0, void 0, void 0, function* () { return yield Promise.resolve(true); }));
92
92
  const result = yield clientInstance.incentives.isClaimed(mockIncentivesData.contractAddress, mockIncentivesData.index);
93
93
  expect(result).toBe(true);
94
- expect(incentivesHelpers.isClaimedFromMerkleDistributor).toHaveBeenCalledWith(clientInstance.incentives.chainId, mockIncentivesData.contractAddress, mockIncentivesData.index);
94
+ expect(incentivesHelpers.isClaimedFromMerkleDistributor).toHaveBeenCalledWith(clientInstance.incentives.chainId, mockIncentivesData.contractAddress, mockIncentivesData.index, undefined);
95
95
  }));
96
96
  test('isClaimed should return false when incentive is not claimed', () => __awaiter(void 0, void 0, void 0, function* () {
97
97
  jest
@@ -108,18 +108,18 @@ describe('Client.incentives', () => {
108
108
  }));
109
109
  yield expect(clientInstance.incentives.isClaimed(mockIncentivesData.contractAddress, mockIncentivesData.index)).rejects.toThrow('Helper function error');
110
110
  }));
111
- test('isClaimed should work with a client without signer', () => __awaiter(void 0, void 0, void 0, function* () {
111
+ test('isClaimed should work with a provider and a without signer', () => __awaiter(void 0, void 0, void 0, function* () {
112
112
  // Create a client without a signer
113
113
  const clientWithoutSigner = new Client({
114
114
  baseUrl,
115
115
  chainId: 17000,
116
- });
116
+ }, undefined, provider);
117
117
  jest
118
118
  .spyOn(incentivesHelpers, 'isClaimedFromMerkleDistributor')
119
119
  .mockImplementation(() => __awaiter(void 0, void 0, void 0, function* () { return yield Promise.resolve(true); }));
120
120
  const result = yield clientWithoutSigner.incentives.isClaimed(mockIncentivesData.contractAddress, mockIncentivesData.index);
121
121
  expect(result).toBe(true);
122
- expect(incentivesHelpers.isClaimedFromMerkleDistributor).toHaveBeenCalledWith(clientWithoutSigner.incentives.chainId, mockIncentivesData.contractAddress, mockIncentivesData.index);
122
+ expect(incentivesHelpers.isClaimedFromMerkleDistributor).toHaveBeenCalledWith(clientWithoutSigner.incentives.chainId, mockIncentivesData.contractAddress, mockIncentivesData.index, provider);
123
123
  }));
124
124
  test('getIncentivesByAddress should make the correct API request', () => __awaiter(void 0, void 0, void 0, function* () {
125
125
  const mockAddress = '0x1234567890abcdef1234567890abcdef12345678';
@@ -138,7 +138,7 @@ describe('Client.incentives', () => {
138
138
  });
139
139
  const result = yield clientInstance.incentives.getIncentivesByAddress(mockAddress);
140
140
  expect(result).toEqual(mockIncentives);
141
- expect(global.fetch).toHaveBeenCalledWith(`${baseUrl}/${DEFAULT_BASE_VERSION}/address/incentives/${mockAddress}`, expect.objectContaining({ method: 'GET' }));
141
+ expect(global.fetch).toHaveBeenCalledWith(`${baseUrl}/${DEFAULT_BASE_VERSION}/address/incentives/holesky/${mockAddress}`, expect.objectContaining({ method: 'GET' }));
142
142
  }));
143
143
  test('getIncentivesByAddress should handle API errors', () => __awaiter(void 0, void 0, void 0, function* () {
144
144
  const mockAddress = '0x1234567890abcdef1234567890abcdef12345678';
@@ -1,10 +1,11 @@
1
- import { type Signer } from 'ethers';
1
+ import { type JsonRpcApiProvider, type JsonRpcProvider, type JsonRpcSigner, type Provider, type Signer } from 'ethers';
2
2
  import { type Incentives as IncentivesType, type ETH_ADDRESS } from './types';
3
3
  export declare class Incentives {
4
4
  private readonly signer;
5
- chainId: number;
5
+ readonly chainId: number;
6
6
  private readonly request;
7
- constructor(signer: Signer | undefined, chainId: number, request: (endpoint: string, options?: RequestInit) => Promise<any>);
7
+ readonly provider: Provider | JsonRpcProvider | JsonRpcApiProvider | undefined | null;
8
+ constructor(signer: Signer | JsonRpcSigner | undefined, chainId: number, request: (endpoint: string, options?: RequestInit) => Promise<any>, provider: Provider | JsonRpcProvider | JsonRpcApiProvider | undefined | null);
8
9
  /**
9
10
  * Claims obol incentives from a Merkle Distributor contract.
10
11
  *
@@ -1,5 +1,5 @@
1
1
  import { type ETH_ADDRESS } from './types';
2
- import { type Signer } from 'ethers';
2
+ import { type JsonRpcApiProvider, type JsonRpcProvider, type Provider, type Signer } from 'ethers';
3
3
  export declare const claimIncentivesFromMerkleDistributor: (incentivesData: {
4
4
  signer: Signer;
5
5
  contractAddress: ETH_ADDRESS;
@@ -10,4 +10,4 @@ export declare const claimIncentivesFromMerkleDistributor: (incentivesData: {
10
10
  }) => Promise<{
11
11
  txHash: string;
12
12
  }>;
13
- export declare const isClaimedFromMerkleDistributor: (chainId: number, contractAddress: ETH_ADDRESS, index: number) => Promise<boolean>;
13
+ export declare const isClaimedFromMerkleDistributor: (chainId: number, contractAddress: ETH_ADDRESS, index: number, provider: Provider | JsonRpcProvider | JsonRpcApiProvider | undefined | null) => Promise<boolean>;
@@ -1,4 +1,4 @@
1
- import { type Signer } from 'ethers';
1
+ import { type Provider, type Signer, type JsonRpcSigner, type JsonRpcProvider, type JsonRpcApiProvider } from 'ethers';
2
2
  import { Base } from './base.js';
3
3
  import { type RewardsSplitPayload, type ClusterDefinition, type ClusterLock, type ClusterPayload, type OperatorPayload, type TotalSplitPayload, type ClusterValidator, type ETH_ADDRESS, type OWRTranches } from './types.js';
4
4
  import { Incentives } from './incentives.js';
@@ -12,6 +12,7 @@ export * from './verification/common.js';
12
12
  export declare class Client extends Base {
13
13
  private readonly signer;
14
14
  incentives: Incentives;
15
+ provider: Provider | JsonRpcProvider | JsonRpcApiProvider | undefined | null;
15
16
  /**
16
17
  * @param config - Client configurations
17
18
  * @param config.baseUrl - obol-api url
@@ -25,7 +26,7 @@ export declare class Client extends Base {
25
26
  constructor(config: {
26
27
  baseUrl?: string;
27
28
  chainId?: number;
28
- }, signer?: Signer);
29
+ }, signer?: Signer | JsonRpcSigner, provider?: Provider | JsonRpcProvider);
29
30
  /**
30
31
  * Accepts Obol terms and conditions to be able to create or update data.
31
32
  * @returns {Promise<string>} terms and conditions acceptance success message.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@obolnetwork/obol-sdk",
3
- "version": "2.4.0",
3
+ "version": "2.4.2",
4
4
  "description": "A package for creating Distributed Validators using the Obol API.",
5
5
  "bugs": {
6
6
  "url": "https://github.com/obolnetwork/obol-sdk/issues"
package/src/constants.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { type TypedMessage } from '@metamask/eth-sig-util';
2
2
  import { type TypedDataDomain } from 'ethers';
3
- import * as pjson from '../package.json';
3
+ import pjson from '../package.json';
4
4
  import { FORK_MAPPING } from './types';
5
5
  import {
6
6
  HOLESKY_MULTICALL_BYTECODE,
package/src/incentives.ts CHANGED
@@ -1,6 +1,16 @@
1
- import { type Provider, type Signer } from 'ethers';
1
+ import {
2
+ type JsonRpcApiProvider,
3
+ type JsonRpcProvider,
4
+ type JsonRpcSigner,
5
+ type Provider,
6
+ type Signer,
7
+ } from 'ethers';
2
8
  import { isContractAvailable } from './utils';
3
- import { type Incentives as IncentivesType, type ETH_ADDRESS } from './types';
9
+ import {
10
+ type Incentives as IncentivesType,
11
+ type ETH_ADDRESS,
12
+ FORK_NAMES,
13
+ } from './types';
4
14
  import {
5
15
  claimIncentivesFromMerkleDistributor,
6
16
  isClaimedFromMerkleDistributor,
@@ -8,21 +18,35 @@ import {
8
18
  import { DEFAULT_BASE_VERSION } from './constants';
9
19
 
10
20
  export class Incentives {
11
- private readonly signer: Signer | undefined;
12
- public chainId: number;
21
+ private readonly signer: Signer | JsonRpcSigner | undefined;
22
+ public readonly chainId: number;
13
23
  private readonly request: (
14
24
  endpoint: string,
15
25
  options?: RequestInit,
16
26
  ) => Promise<any>;
17
27
 
28
+ public readonly provider:
29
+ | Provider
30
+ | JsonRpcProvider
31
+ | JsonRpcApiProvider
32
+ | undefined
33
+ | null;
34
+
18
35
  constructor(
19
- signer: Signer | undefined,
36
+ signer: Signer | JsonRpcSigner | undefined,
20
37
  chainId: number,
21
38
  request: (endpoint: string, options?: RequestInit) => Promise<any>,
39
+ provider:
40
+ | Provider
41
+ | JsonRpcProvider
42
+ | JsonRpcApiProvider
43
+ | undefined
44
+ | null,
22
45
  ) {
23
46
  this.signer = signer;
24
47
  this.chainId = chainId;
25
48
  this.request = request;
49
+ this.provider = provider;
26
50
  }
27
51
 
28
52
  /**
@@ -96,6 +120,7 @@ export class Incentives {
96
120
  this.chainId,
97
121
  contractAddress,
98
122
  index,
123
+ this.provider,
99
124
  );
100
125
  }
101
126
 
@@ -105,8 +130,9 @@ export class Incentives {
105
130
  * @throws On not found if address not found.
106
131
  */
107
132
  async getIncentivesByAddress(address: string): Promise<IncentivesType> {
133
+ const network = FORK_NAMES[this.chainId];
108
134
  const incentives: IncentivesType = await this.request(
109
- `/${DEFAULT_BASE_VERSION}/address/incentives/${address}`,
135
+ `/${DEFAULT_BASE_VERSION}/address/incentives/${network}/${address}`,
110
136
  {
111
137
  method: 'GET',
112
138
  },
@@ -1,5 +1,11 @@
1
1
  import { type ETH_ADDRESS } from './types';
2
- import { Contract, type Signer } from 'ethers';
2
+ import {
3
+ Contract,
4
+ type JsonRpcApiProvider,
5
+ type JsonRpcProvider,
6
+ type Provider,
7
+ type Signer,
8
+ } from 'ethers';
3
9
  import { MerkleDistributorABI } from './abi/MerkleDistributorWithDeadline';
4
10
  import { getProvider } from './utils';
5
11
 
@@ -38,14 +44,15 @@ export const isClaimedFromMerkleDistributor = async (
38
44
  chainId: number,
39
45
  contractAddress: ETH_ADDRESS,
40
46
  index: number,
47
+ provider: Provider | JsonRpcProvider | JsonRpcApiProvider | undefined | null,
41
48
  ): Promise<boolean> => {
42
49
  try {
43
- const provider = getProvider(chainId);
50
+ const clientProvider = provider ?? getProvider(chainId);
44
51
 
45
52
  const contract = new Contract(
46
53
  contractAddress,
47
54
  MerkleDistributorABI.abi,
48
- provider,
55
+ clientProvider,
49
56
  );
50
57
 
51
58
  const claimed = await contract.isClaimed(BigInt(index));
package/src/index.ts CHANGED
@@ -1,4 +1,11 @@
1
- import { ZeroAddress, type Provider, type Signer } from 'ethers';
1
+ import {
2
+ ZeroAddress,
3
+ type Provider,
4
+ type Signer,
5
+ type JsonRpcSigner,
6
+ type JsonRpcProvider,
7
+ type JsonRpcApiProvider,
8
+ } from 'ethers';
2
9
  import { v4 as uuidv4 } from 'uuid';
3
10
  import { Base } from './base.js';
4
11
  import {
@@ -57,8 +64,14 @@ export * from './verification/common.js';
57
64
  * Obol sdk Client can be used for creating, managing and activating distributed validators.
58
65
  */
59
66
  export class Client extends Base {
60
- private readonly signer: Signer | undefined;
67
+ private readonly signer: Signer | JsonRpcSigner | undefined;
61
68
  public incentives: Incentives;
69
+ public provider:
70
+ | Provider
71
+ | JsonRpcProvider
72
+ | JsonRpcApiProvider
73
+ | undefined
74
+ | null;
62
75
 
63
76
  /**
64
77
  * @param config - Client configurations
@@ -70,13 +83,22 @@ export class Client extends Base {
70
83
  * An example of how to instantiate obol-sdk Client:
71
84
  * [obolClient](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts#L29)
72
85
  */
73
- constructor(config: { baseUrl?: string; chainId?: number }, signer?: Signer) {
86
+ constructor(
87
+ config: { baseUrl?: string; chainId?: number },
88
+ signer?: Signer | JsonRpcSigner,
89
+ provider?: Provider | JsonRpcProvider,
90
+ ) {
74
91
  super(config);
75
92
  this.signer = signer;
93
+ // Use the provided provider, or fall back to signer.provider if available
94
+ this.provider =
95
+ provider ??
96
+ (signer && 'provider' in signer ? signer.provider : undefined);
76
97
  this.incentives = new Incentives(
77
98
  this.signer,
78
99
  this.chainId,
79
100
  this.request.bind(this),
101
+ (this.provider = provider),
80
102
  );
81
103
  }
82
104
 
@@ -23,7 +23,7 @@ export const validateAddressSignature = async ({
23
23
  chainId: number;
24
24
  }): Promise<boolean> => {
25
25
  try {
26
- const provider = getProvider(chainId);
26
+ const provider = getProvider(chainId); // [TODO Hanan], should expect it from signer.provider, or passed in client
27
27
  if (provider) {
28
28
  const contractAddress = await isContractAvailable(address, provider);
29
29
  if (contractAddress) {