@snapshot-labs/snapshot.js 0.14.4 → 0.14.6

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.
@@ -812,6 +812,7 @@ declare const _default: {
812
812
  utils: {
813
813
  call: typeof import("./utils").call;
814
814
  multicall: typeof import("./multicall").multicall;
815
+ fetch: typeof import("./utils").fetch;
815
816
  subgraphRequest: typeof import("./utils").subgraphRequest;
816
817
  ipfsGet: typeof import("./utils").ipfsGet;
817
818
  getUrl: typeof import("./utils").getUrl;
@@ -16,6 +16,41 @@ interface Strategy {
16
16
  export declare function call(provider: any, abi: any[], call: any[], options?: any): Promise<any>;
17
17
  export declare function subgraphRequest(url: string, query: any, options?: any): Promise<any>;
18
18
  export declare function getUrl(uri: any, gateway?: string): any;
19
+ interface FetchOptions extends RequestInit {
20
+ timeout?: number;
21
+ }
22
+ /**
23
+ * Enhanced fetch with timeout support - drop-in replacement for native fetch
24
+ *
25
+ * @param url - The URL to fetch
26
+ * @param options - Fetch options with optional timeout
27
+ * @param options.timeout - Request timeout in milliseconds (default: 30000ms). Set to 0 to disable timeout.
28
+ *
29
+ * @returns Promise that resolves to the Response object
30
+ *
31
+ * @throws {Error} Throws timeout error if request exceeds the specified timeout duration
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * // Uses default 30s timeout
36
+ * const response = await fetch('https://api.example.com/data');
37
+ *
38
+ * // Custom 5s timeout
39
+ * const response = await fetch('https://api.example.com/data', { timeout: 5000 });
40
+ *
41
+ * // Disable timeout
42
+ * const response = await fetch('https://api.example.com/data', { timeout: 0 });
43
+ *
44
+ * // With additional fetch options
45
+ * const response = await fetch('https://api.example.com/data', {
46
+ * timeout: 10000,
47
+ * method: 'POST',
48
+ * headers: { 'Content-Type': 'application/json' },
49
+ * body: JSON.stringify({ key: 'value' })
50
+ * });
51
+ * ```
52
+ */
53
+ export declare function fetch(url: string, options?: FetchOptions): Promise<Response>;
19
54
  export declare function getJSON(uri: any, options?: any): Promise<any>;
20
55
  export declare function ipfsGet(gateway: string, ipfsHash: string, protocolType?: string): Promise<any>;
21
56
  export declare function sendTransaction(web3: any, contractAddress: string, abi: any[], action: string, params: any[], overrides?: {}): Promise<any>;
@@ -31,7 +66,7 @@ export declare function getEnsTextRecord(ens: string, record: string, network?:
31
66
  export declare function getSpaceUri(id: string, network?: string, options?: any): Promise<string | null>;
32
67
  export declare function getEnsOwner(ens: string, network?: string, options?: any): Promise<string>;
33
68
  export declare function getShibariumNameOwner(id: string, network: string): Promise<string>;
34
- export declare function getSonicNameOwner(id: string, network: string): Promise<string>;
69
+ export declare function getUDNameOwner(id: string, network: string): Promise<string>;
35
70
  export declare function getSpaceController(id: string, network?: string, options?: any): Promise<string>;
36
71
  export declare function clone(item: any): any;
37
72
  export declare function sleep(time: any): Promise<unknown>;
@@ -43,6 +78,7 @@ export { getDelegatesBySpace, SNAPSHOT_SUBGRAPH_URL };
43
78
  declare const _default: {
44
79
  call: typeof call;
45
80
  multicall: typeof multicall;
81
+ fetch: typeof fetch;
46
82
  subgraphRequest: typeof subgraphRequest;
47
83
  ipfsGet: typeof ipfsGet;
48
84
  getUrl: typeof getUrl;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@snapshot-labs/snapshot.js",
3
- "version": "0.14.4",
3
+ "version": "0.14.6",
4
4
  "repository": "snapshot-labs/snapshot.js",
5
5
  "license": "MIT",
6
6
  "main": "dist/snapshot.cjs.js",
package/src/sign/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- import fetch from 'cross-fetch';
1
+ import { fetch } from '../utils';
2
2
  import { Web3Provider } from '@ethersproject/providers';
3
3
  import { Wallet } from '@ethersproject/wallet';
4
4
  import {
package/src/utils.ts CHANGED
@@ -1,4 +1,4 @@
1
- import fetch from 'cross-fetch';
1
+ import crossFetch from 'cross-fetch';
2
2
  import { Contract } from '@ethersproject/contracts';
3
3
  import { getAddress, isAddress } from '@ethersproject/address';
4
4
  import { parseUnits } from '@ethersproject/units';
@@ -43,14 +43,17 @@ const ENS_ABI = [
43
43
  'function text(bytes32 node, string calldata key) external view returns (string memory)',
44
44
  'function resolver(bytes32 node) view returns (address)' // ENS registry ABI
45
45
  ];
46
- const SONIC_ABI = [
47
- 'function ownerOf(uint256 tokenId) external view returns (address address)'
46
+ const UD_MAPPING = {
47
+ '146': {
48
+ tlds: ['.sonic'],
49
+ registryContract: '0xde1dadcf11a7447c3d093e97fdbd513f488ce3b4'
50
+ }
51
+ };
52
+ const UD_REGISTRY_ABI = [
53
+ 'function ownerOf(uint256 tokenId) view returns (address owner)'
48
54
  ];
49
- const SONIC_CONTRACT_ADDRESS = '0xde1dadcf11a7447c3d093e97fdbd513f488ce3b4';
50
55
  const ENS_CHAIN_IDS = ['1', '11155111'];
51
56
  const SHIBARIUM_CHAIN_IDS = ['109', '157'];
52
- const SONIC_CHAIN_IDS = ['146'];
53
- const SONIC_TLD = '.sonic';
54
57
  const SHIBARIUM_TLD = '.shib';
55
58
  const EMPTY_ADDRESS = '0x0000000000000000000000000000000000000000';
56
59
 
@@ -311,9 +314,76 @@ export function getUrl(uri, gateway = gateways[0]) {
311
314
  return uri;
312
315
  }
313
316
 
317
+ interface FetchOptions extends RequestInit {
318
+ timeout?: number;
319
+ }
320
+
321
+ /**
322
+ * Enhanced fetch with timeout support - drop-in replacement for native fetch
323
+ *
324
+ * @param url - The URL to fetch
325
+ * @param options - Fetch options with optional timeout
326
+ * @param options.timeout - Request timeout in milliseconds (default: 30000ms). Set to 0 to disable timeout.
327
+ *
328
+ * @returns Promise that resolves to the Response object
329
+ *
330
+ * @throws {Error} Throws timeout error if request exceeds the specified timeout duration
331
+ *
332
+ * @example
333
+ * ```typescript
334
+ * // Uses default 30s timeout
335
+ * const response = await fetch('https://api.example.com/data');
336
+ *
337
+ * // Custom 5s timeout
338
+ * const response = await fetch('https://api.example.com/data', { timeout: 5000 });
339
+ *
340
+ * // Disable timeout
341
+ * const response = await fetch('https://api.example.com/data', { timeout: 0 });
342
+ *
343
+ * // With additional fetch options
344
+ * const response = await fetch('https://api.example.com/data', {
345
+ * timeout: 10000,
346
+ * method: 'POST',
347
+ * headers: { 'Content-Type': 'application/json' },
348
+ * body: JSON.stringify({ key: 'value' })
349
+ * });
350
+ * ```
351
+ */
352
+ export async function fetch(
353
+ url: string,
354
+ options: FetchOptions = {}
355
+ ): Promise<Response> {
356
+ const { timeout = 30000, ...fetchOptions } = options;
357
+
358
+ if (timeout > 0) {
359
+ const controller = new AbortController();
360
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
361
+
362
+ try {
363
+ const response = await crossFetch(url, {
364
+ ...fetchOptions,
365
+ signal: controller.signal
366
+ });
367
+ return response;
368
+ } catch (error) {
369
+ if (error instanceof Error && error.name === 'AbortError') {
370
+ throw new Error(`Request timeout after ${timeout}ms`);
371
+ }
372
+ throw error;
373
+ } finally {
374
+ clearTimeout(timeoutId);
375
+ }
376
+ }
377
+
378
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
379
+ const { signal, ...cleanFetchOptions } = fetchOptions;
380
+ return crossFetch(url, cleanFetchOptions);
381
+ }
382
+
314
383
  export async function getJSON(uri, options: any = {}) {
315
384
  const url = getUrl(uri, options.gateways);
316
- return fetch(url).then((res) => res.json());
385
+ const response = await fetch(url, options);
386
+ return response.json();
317
387
  }
318
388
 
319
389
  export async function ipfsGet(
@@ -701,23 +771,24 @@ export async function getShibariumNameOwner(
701
771
  return data.result;
702
772
  }
703
773
 
704
- export async function getSonicNameOwner(
774
+ export async function getUDNameOwner(
705
775
  id: string,
706
776
  network: string
707
777
  ): Promise<string> {
708
- if (!id.endsWith(SONIC_TLD)) {
778
+ const tlds = UD_MAPPING[network]?.tlds || [];
779
+ if (!tlds.some((tld: string) => id.endsWith(tld))) {
709
780
  return Promise.resolve(EMPTY_ADDRESS);
710
781
  }
711
782
 
712
783
  try {
713
784
  const hash = namehash(ensNormalize(id));
714
- const tokenId = BigInt(hash).toString();
785
+ const tokenId = BigInt(hash);
715
786
  const provider = getProvider(network);
716
787
 
717
788
  return await call(
718
789
  provider,
719
- SONIC_ABI,
720
- [SONIC_CONTRACT_ADDRESS, 'ownerOf', [tokenId]],
790
+ UD_REGISTRY_ABI,
791
+ [UD_MAPPING[network].registryContract, 'ownerOf', [tokenId]],
721
792
  {
722
793
  blockTag: 'latest'
723
794
  }
@@ -736,8 +807,8 @@ export async function getSpaceController(
736
807
  return getEnsSpaceController(id, network, options);
737
808
  } else if (SHIBARIUM_CHAIN_IDS.includes(network)) {
738
809
  return getShibariumNameOwner(id, network);
739
- } else if (SONIC_CHAIN_IDS.includes(network)) {
740
- return getSonicNameOwner(id, network);
810
+ } else if (UD_MAPPING[String(network)]) {
811
+ return getUDNameOwner(id, network);
741
812
  }
742
813
 
743
814
  throw new Error(`Network not supported: ${network}`);
@@ -819,6 +890,7 @@ export { getDelegatesBySpace, SNAPSHOT_SUBGRAPH_URL };
819
890
  export default {
820
891
  call,
821
892
  multicall,
893
+ fetch,
822
894
  subgraphRequest,
823
895
  ipfsGet,
824
896
  getUrl,