diff --git a/.github/workflows/e2e-tests.yaml b/.github/workflows/e2e-tests.yaml index ba3b86f19..5b29c6d51 100644 --- a/.github/workflows/e2e-tests.yaml +++ b/.github/workflows/e2e-tests.yaml @@ -15,7 +15,7 @@ jobs: steps: - name: Checkout Repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install pnpm uses: pnpm/action-setup@v4 @@ -23,9 +23,9 @@ jobs: version: '9.15.4' - name: Setup Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: - node-version: "20.x" + node-version: "22.x" cache: "pnpm" - name: Install Dependencies @@ -48,7 +48,7 @@ jobs: steps: - name: Checkout Repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install pnpm uses: pnpm/action-setup@v4 @@ -56,9 +56,9 @@ jobs: version: '9.15.4' - name: Setup Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: - node-version: "20.x" + node-version: "22.x" cache: "pnpm" - name: Install Dependencies @@ -81,7 +81,7 @@ jobs: steps: - name: Checkout Repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install pnpm uses: pnpm/action-setup@v4 @@ -89,9 +89,9 @@ jobs: version: '9.15.4' - name: Setup Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: - node-version: "20.x" + node-version: "22.x" cache: "pnpm" - name: Install Dependencies diff --git a/.github/workflows/injective-e2e-tests.yaml b/.github/workflows/injective-e2e-tests.yaml index b6afd0949..a646c0b95 100644 --- a/.github/workflows/injective-e2e-tests.yaml +++ b/.github/workflows/injective-e2e-tests.yaml @@ -9,7 +9,7 @@ jobs: steps: - name: Checkout Repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install pnpm uses: pnpm/action-setup@v4 @@ -17,9 +17,9 @@ jobs: version: '9.15.4' - name: Setup Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: - node-version: "20.x" + node-version: "22.x" cache: "pnpm" - name: Install Dependencies diff --git a/.github/workflows/run-tests.yaml b/.github/workflows/run-tests.yaml index 81bf6e282..7f7ade8ae 100644 --- a/.github/workflows/run-tests.yaml +++ b/.github/workflows/run-tests.yaml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout Repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install pnpm uses: pnpm/action-setup@v4 @@ -23,9 +23,9 @@ jobs: version: '9.15.4' - name: Setup Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: - node-version: "20.x" + node-version: "22.x" cache: "pnpm" - name: Install Dependencies diff --git a/.github/workflows/solana-unit-tests.yaml b/.github/workflows/solana-unit-tests.yaml index aa5229b31..7bf36dba0 100644 --- a/.github/workflows/solana-unit-tests.yaml +++ b/.github/workflows/solana-unit-tests.yaml @@ -12,7 +12,7 @@ jobs: steps: - name: Checkout Repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install pnpm uses: pnpm/action-setup@v4 @@ -20,9 +20,9 @@ jobs: version: '9.15.4' - name: Setup Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: - node-version: "20.x" + node-version: "22.x" cache: "pnpm" - name: Install Dependencies diff --git a/README.md b/README.md index 1cac6ead3..f21dd775a 100644 --- a/README.md +++ b/README.md @@ -222,7 +222,7 @@ Then an authz example website will be created and users can take a look how sign | ---------------------------- | ------------------------------------------------------------- | | **Transactions** | [@interchainjs/cosmos](https://docs.hyperweb.io/interchain-js/networks/cosmos) | | **Cosmos Types** | [@interchainjs/cosmos-types](https://docs.hyperweb.io/interchain-js/libs/cosmos-types) | -| **Migration from `@cosmjs`** | [Migration Guide](https://docs.hyperweb.io/interchain-js/advanced/migration-from-cosmjs.mdx) | +| **Migration from `@cosmjs`** | [Migration Guide](https://docs.hyperweb.io/interchain-js/advanced/migration-from-cosmjs) | --- diff --git a/networks/ethereum/package.json b/networks/ethereum/package.json index b0ddba064..f24d36208 100644 --- a/networks/ethereum/package.json +++ b/networks/ethereum/package.json @@ -54,10 +54,6 @@ "prepack": "makage build" }, "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", "@interchainjs/auth": "workspace:*", "@interchainjs/encoding": "workspace:^", "@interchainjs/types": "workspace:*", diff --git a/networks/injective/package.json b/networks/injective/package.json index 2874a85a3..eb891a9fa 100644 --- a/networks/injective/package.json +++ b/networks/injective/package.json @@ -43,7 +43,6 @@ "prepack": "pnpm run build" }, "dependencies": { - "@ethersproject/transactions": "^5.7.0", "@interchainjs/auth": "workspace:*", "@interchainjs/cosmos": "workspace:*", "@interchainjs/cosmos-types": "workspace:*", diff --git a/packages/auth/package.json b/packages/auth/package.json index 7b5b60dde..045fcb379 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -40,16 +40,14 @@ "@interchainjs/crypto": "workspace:*", "@interchainjs/types": "workspace:*", "@interchainjs/utils": "workspace:*", - "@noble/curves": "^1.1.0", + "@noble/curves": "^1.9.7", "@noble/hashes": "^1.3.1", "@scure/bip32": "^1.0.10", "bech32": "^2.0.0", - "elliptic": "^6.5.4", "libsodium-wrappers-sumo": "^0.8.2" }, "devDependencies": { "@jest/globals": "^30.0.0", - "@types/elliptic": "^6.4.18", "@types/libsodium-wrappers-sumo": "^0.8.2", "makage": "^0.1.12" }, diff --git a/packages/auth/src/config/algorithms.ts b/packages/auth/src/config/algorithms.ts index 022b39023..06224175e 100644 --- a/packages/auth/src/config/algorithms.ts +++ b/packages/auth/src/config/algorithms.ts @@ -1,17 +1,14 @@ import { IAlgo } from '@interchainjs/types'; import { Secp256k1, Ed25519, Secp256k1Signature } from '@interchainjs/crypto'; -import elliptic from 'elliptic'; +import { secp256k1 } from '@noble/curves/secp256k1.js'; import sodium from 'libsodium-wrappers-sumo'; -const secp256k1 = new elliptic.ec('secp256k1'); - // Secp256k1 algorithm implementation export const Secp256k1Algo: IAlgo = { name: 'secp256k1', makeKeypair: (privateKey: Uint8Array) => { // Synchronous version of Secp256k1.makeKeypair - const keyPair = secp256k1.keyFromPrivate(privateKey); - const pubkey = new Uint8Array(keyPair.getPublic(false, 'array')); // uncompressed + const pubkey = secp256k1.getPublicKey(privateKey, false); // uncompressed return { privkey: privateKey, pubkey }; }, compress: (pubkey: Uint8Array) => { diff --git a/packages/crypto/package.json b/packages/crypto/package.json index 6087066af..19cf0247d 100644 --- a/packages/crypto/package.json +++ b/packages/crypto/package.json @@ -42,14 +42,13 @@ "@interchainjs/encoding": "workspace:*", "@interchainjs/math": "workspace:*", "@interchainjs/utils": "workspace:*", + "@noble/curves": "^1.9.7", "@noble/hashes": "^1", "bn.js": "^5.2.0", - "elliptic": "^6.5.4", "libsodium-wrappers-sumo": "^0.8.2" }, "devDependencies": { "@types/bn.js": "^5.2.0", - "@types/elliptic": "^6.4.18", "@types/libsodium-wrappers-sumo": "^0.8.2", "makage": "^0.1.12" } diff --git a/packages/crypto/src/secp256k1.ts b/packages/crypto/src/secp256k1.ts index 1ebe8d8c2..d44891fe4 100644 --- a/packages/crypto/src/secp256k1.ts +++ b/packages/crypto/src/secp256k1.ts @@ -1,11 +1,13 @@ -import { fromHex, toHex } from "@interchainjs/encoding"; -import BN from "bn.js"; -import elliptic from "elliptic"; +import { secp256k1 } from "@noble/curves/secp256k1.js"; +import { bytesToNumberBE, numberToBytesBE } from "@noble/curves/utils.js"; import { ExtendedSecp256k1Signature, Secp256k1Signature } from "./secp256k1signature"; -const secp256k1 = new elliptic.ec("secp256k1"); -const secp256k1N = new BN("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", "hex"); +function toUnpaddedBytes(n: bigint): Uint8Array { + const bytes = numberToBytesBE(n, 32); + const firstNonZero = bytes.findIndex((byte) => byte !== 0); + return bytes.slice(firstNonZero); +} export interface Secp256k1Keypair { /** A 32 byte private key */ @@ -35,25 +37,17 @@ export class Secp256k1 { throw new Error("input data is not a valid secp256k1 private key"); } - const keypair = secp256k1.keyFromPrivate(privkey); - if (keypair.validate().result !== true) { - throw new Error("input data is not a valid secp256k1 private key"); - } - - // range test that is not part of the elliptic implementation - const privkeyAsBigInteger = new BN(privkey); - if (privkeyAsBigInteger.gte(secp256k1N)) { - // not strictly smaller than N + if (!secp256k1.utils.isValidSecretKey(privkey)) { throw new Error("input data is not a valid secp256k1 private key"); } const out: Secp256k1Keypair = { - privkey: fromHex(keypair.getPrivate("hex")), + privkey: Uint8Array.from(privkey), // encodes uncompressed as // - 1-byte prefix "04" // - 32-byte x coordinate // - 32-byte y coordinate - pubkey: Uint8Array.from(keypair.getPublic("array")), + pubkey: secp256k1.getPublicKey(privkey, false), }; return out; } @@ -75,15 +69,9 @@ export class Secp256k1 { throw new Error("Message hash length must not exceed 32 bytes"); } - const keypair = secp256k1.keyFromPrivate(privkey); - // the `canonical` option ensures creation of lowS signature representations - const { r, s, recoveryParam } = keypair.sign(messageHash, { canonical: true }); - if (typeof recoveryParam !== "number") throw new Error("Recovery param missing"); - return new ExtendedSecp256k1Signature( - Uint8Array.from(r.toArray()), - Uint8Array.from(s.toArray()), - recoveryParam, - ); + const { r, s, recovery } = secp256k1.sign(messageHash, privkey, { prehash: false, lowS: true }); + if (typeof recovery !== "number") throw new Error("Recovery param missing"); + return new ExtendedSecp256k1Signature(toUnpaddedBytes(r), toUnpaddedBytes(s), recovery); } public static async verifySignature( @@ -98,33 +86,21 @@ export class Secp256k1 { throw new Error("Message hash length must not exceed 32 bytes"); } - const keypair = secp256k1.keyFromPublic(pubkey); - - // From https://github.com/indutny/elliptic: - // - // Sign the message's hash (input must be an array, or a hex-string) - // - // Signature MUST be either: - // 1) DER-encoded signature as hex-string; or - // 2) DER-encoded signature as buffer; or - // 3) object with two hex-string properties (r and s); or - // 4) object with two buffer properties (r and s) - // - // Uint8Array is not a Buffer, but elliptic seems to be happy with the interface - // common to both types. Uint8Array is not an array of ints but the interface is - // similar try { - return keypair.verify(messageHash, signature.toDer()); + return secp256k1.verify(new Uint8Array([...signature.r(32), ...signature.s(32)]), messageHash, pubkey, { prehash: false, lowS: false }); } catch (error) { return false; } } public static recoverPubkey(signature: ExtendedSecp256k1Signature, messageHash: Uint8Array): Uint8Array { - const signatureForElliptic = { r: toHex(signature.r()), s: toHex(signature.s()) }; - const point = secp256k1.recoverPubKey(messageHash, signatureForElliptic, signature.recovery); - const keypair = secp256k1.keyFromPublic(point); - return fromHex(keypair.getPublic(false, "hex")); + return new secp256k1.Signature( + bytesToNumberBE(signature.r()), + bytesToNumberBE(signature.s()), + signature.recovery, + ) + .recoverPublicKey(messageHash) + .toBytes(false); } /** @@ -137,7 +113,7 @@ export class Secp256k1 { case 33: return pubkey; case 65: - return Uint8Array.from(secp256k1.keyFromPublic(pubkey).getPublic(true, "array")); + return secp256k1.Point.fromBytes(pubkey).toBytes(true); default: throw new Error("Invalid pubkey length"); } @@ -151,7 +127,7 @@ export class Secp256k1 { public static uncompressPubkey(pubkey: Uint8Array): Uint8Array { switch (pubkey.length) { case 33: - return Uint8Array.from(secp256k1.keyFromPublic(pubkey).getPublic(false, "array")); + return secp256k1.Point.fromBytes(pubkey).toBytes(false); case 65: return pubkey; default: diff --git a/packages/crypto/src/slip10.ts b/packages/crypto/src/slip10.ts index 25c3c530e..79e7fab9b 100644 --- a/packages/crypto/src/slip10.ts +++ b/packages/crypto/src/slip10.ts @@ -1,7 +1,7 @@ -import { fromHex, toAscii } from "@interchainjs/encoding"; +import { toAscii } from "@interchainjs/encoding"; import { Uint32, Uint53 } from "@interchainjs/math"; +import { secp256k1 } from "@noble/curves/secp256k1.js"; import BN from "bn.js"; -import elliptic from "elliptic"; import { Hmac } from "./hmac"; import { Sha512 } from "./sha"; @@ -77,8 +77,6 @@ export class Slip10RawIndex extends Uint32 { */ export type HdPath = readonly Slip10RawIndex[]; -const secp256k1 = new elliptic.ec("secp256k1"); - // Universal private key derivation accoring to // https://github.com/satoshilabs/slips/blob/master/slip-0010.md export class Slip10 { @@ -123,7 +121,7 @@ export class Slip10 { // Calculate I = HMAC-SHA512(Key = c_par, Data = ser_P(point(k_par)) || ser_32(i)). // where the functions point() and ser_p() are defined in BIP-0032 const data = new Uint8Array([ - ...Slip10.serializedPoint(curve, new BN(parentPrivkey)), + ...Slip10.serializedPoint(curve, parentPrivkey), ...rawIndex.toBytesBigEndian(), ]); i = new Hmac(Sha512, parentChainCode).update(data).digest(); @@ -138,10 +136,10 @@ export class Slip10 { * * @see https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki */ - private static serializedPoint(curve: Slip10Curve, p: BN): Uint8Array { + private static serializedPoint(curve: Slip10Curve, privkey: Uint8Array): Uint8Array { switch (curve) { case Slip10Curve.Secp256k1: - return fromHex(secp256k1.g.mul(p).encodeCompressed("hex")); + return secp256k1.getPublicKey(privkey, true); default: throw new Error("curve not supported"); } diff --git a/packages/utils/src/clients/http-client.spec.ts b/packages/utils/src/clients/http-client.spec.ts new file mode 100644 index 000000000..13c75198a --- /dev/null +++ b/packages/utils/src/clients/http-client.spec.ts @@ -0,0 +1,86 @@ +import { NetworkError } from '@interchainjs/types'; + +import { HttpRpcClient } from './http-client'; + +function rpcResponse(result: unknown): Response { + return new Response(JSON.stringify({ jsonrpc: '2.0', id: 1, result }), { status: 200 }); +} + +function rateLimited(retryAfter?: string): Response { + return new Response('', { + status: 429, + statusText: 'Too Many Requests', + headers: retryAfter === undefined ? {} : { 'Retry-After': retryAfter } + }); +} + +describe('HttpRpcClient', () => { + const originalFetch = global.fetch; + let fetchMock: jest.Mock; + + beforeEach(() => { + fetchMock = jest.fn(); + global.fetch = fetchMock as unknown as typeof fetch; + }); + + afterEach(() => { + global.fetch = originalFetch; + }); + + it('retries after HTTP 429 and returns the result', async () => { + fetchMock + .mockResolvedValueOnce(rateLimited('0')) + .mockResolvedValueOnce(rateLimited('0')) + .mockResolvedValueOnce(rpcResponse('ok')); + + const client = new HttpRpcClient('http://rpc.test'); + + await expect(client.call('getHealth')).resolves.toBe('ok'); + expect(fetchMock).toHaveBeenCalledTimes(3); + }); + + it('throws once retries are exhausted', async () => { + fetchMock.mockResolvedValue(rateLimited('0')); + + const client = new HttpRpcClient('http://rpc.test', { maxRetries: 2 }); + + await expect(client.call('getHealth')).rejects.toThrow(new NetworkError('HTTP 429: Too Many Requests')); + expect(fetchMock).toHaveBeenCalledTimes(3); + }); + + it('does not retry when maxRetries is 0', async () => { + fetchMock.mockResolvedValue(rateLimited('0')); + + const client = new HttpRpcClient('http://rpc.test', { maxRetries: 0 }); + + await expect(client.call('getHealth')).rejects.toThrow('HTTP 429: Too Many Requests'); + expect(fetchMock).toHaveBeenCalledTimes(1); + }); + + it('backs off exponentially without Retry-After', async () => { + jest.useFakeTimers(); + try { + fetchMock.mockResolvedValueOnce(rateLimited()).mockResolvedValueOnce(rpcResponse(1)); + + const client = new HttpRpcClient('http://rpc.test'); + const pending = client.call('getSlot'); + + await jest.advanceTimersByTimeAsync(499); + expect(fetchMock).toHaveBeenCalledTimes(1); + await jest.advanceTimersByTimeAsync(1); + await expect(pending).resolves.toBe(1); + expect(fetchMock).toHaveBeenCalledTimes(2); + } finally { + jest.useRealTimers(); + } + }); + + it('does not retry other HTTP errors', async () => { + fetchMock.mockResolvedValue(new Response('', { status: 500, statusText: 'Internal Server Error' })); + + const client = new HttpRpcClient('http://rpc.test'); + + await expect(client.call('getHealth')).rejects.toThrow('HTTP 500: Internal Server Error'); + expect(fetchMock).toHaveBeenCalledTimes(1); + }); +}); diff --git a/packages/utils/src/clients/http-client.ts b/packages/utils/src/clients/http-client.ts index 585f03061..62f34da8e 100644 --- a/packages/utils/src/clients/http-client.ts +++ b/packages/utils/src/clients/http-client.ts @@ -7,12 +7,37 @@ export interface HttpEndpoint { headers?: Record; } +export interface HttpRpcClientOptions { + timeout?: number; + headers?: Record; + /** Retries after HTTP 429, waiting for `Retry-After` (or exponential backoff). Defaults to 3. */ + maxRetries?: number; +} + +const DEFAULT_MAX_RETRIES = 3; +const BASE_RETRY_DELAY_MS = 500; +const MAX_RETRY_DELAY_MS = 30000; + +function retryDelayMs(response: Response, attempt: number): number { + const retryAfter = response.headers.get('retry-after'); + if (retryAfter !== null) { + const seconds = Number(retryAfter); + const delay = Number.isFinite(seconds) ? seconds * 1000 : Date.parse(retryAfter) - Date.now(); + if (Number.isFinite(delay)) return Math.min(Math.max(delay, 0), MAX_RETRY_DELAY_MS); + } + return Math.min(BASE_RETRY_DELAY_MS * 2 ** attempt, MAX_RETRY_DELAY_MS); +} + +function sleep(ms: number): Promise { + return new Promise(resolve => setTimeout(resolve, ms)); +} + export class HttpRpcClient implements IRpcClient { private connected = false; constructor( private endpointConfig: string | HttpEndpoint, - private options: { timeout?: number; headers?: Record } = {} + private options: HttpRpcClientOptions = {} ) {} get endpoint(): string { @@ -37,20 +62,15 @@ export class HttpRpcClient implements IRpcClient { params?: TRequest ): Promise { const request = createJsonRpcRequest(method, params); + const maxRetries = this.options.maxRetries ?? DEFAULT_MAX_RETRIES; try { - const controller = new AbortController(); - const timeout = this.getTimeout(); - const timeoutId = setTimeout(() => controller.abort(), timeout); - - const response = await fetch(this.getUrl(), { - method: 'POST', - headers: this.getHeaders(), - body: JSON.stringify(request), - signal: controller.signal - }); - - clearTimeout(timeoutId); + let response = await this.post(request); + for (let attempt = 0; response.status === 429 && attempt < maxRetries; attempt++) { + await response.body?.cancel(); + await sleep(retryDelayMs(response, attempt)); + response = await this.post(request); + } if (!response.ok) { throw new NetworkError(`HTTP ${response.status}: ${response.statusText}`); @@ -81,6 +101,21 @@ export class HttpRpcClient implements IRpcClient { throw new Error('HTTP client does not support streaming operations'); } + private async post(request: unknown): Promise { + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), this.getTimeout()); + try { + return await fetch(this.getUrl(), { + method: 'POST', + headers: this.getHeaders(), + body: JSON.stringify(request), + signal: controller.signal + }); + } finally { + clearTimeout(timeoutId); + } + } + private getUrl(): string { return typeof this.endpointConfig === 'string' ? this.endpointConfig : this.endpointConfig.url; } diff --git a/packages/utils/src/clients/index.ts b/packages/utils/src/clients/index.ts index 24413dc98..6da70d22c 100644 --- a/packages/utils/src/clients/index.ts +++ b/packages/utils/src/clients/index.ts @@ -1,3 +1,3 @@ // packages/utils/src/clients/index.ts -export { HttpRpcClient, HttpEndpoint } from './http-client'; +export { HttpRpcClient, HttpEndpoint, HttpRpcClientOptions } from './http-client'; export { WebSocketRpcClient, WebSocketEndpoint, ReconnectOptions } from './websocket-client'; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a829e495d..580fada77 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -444,18 +444,6 @@ importers: networks/ethereum: dependencies: - "@ethersproject/bignumber": - specifier: ^5.7.0 - version: 5.8.0 - "@ethersproject/bytes": - specifier: ^5.7.0 - version: 5.8.0 - "@ethersproject/hash": - specifier: ^5.7.0 - version: 5.8.0 - "@ethersproject/transactions": - specifier: ^5.7.0 - version: 5.8.0 "@interchainjs/auth": specifier: workspace:* version: link:../../packages/auth/dist @@ -515,9 +503,6 @@ importers: networks/injective: dependencies: - "@ethersproject/transactions": - specifier: ^5.7.0 - version: 5.8.0 "@interchainjs/auth": specifier: workspace:* version: link:../../packages/auth/dist @@ -672,7 +657,7 @@ importers: specifier: workspace:* version: link:../utils/dist "@noble/curves": - specifier: ^1.1.0 + specifier: ^1.9.7 version: 1.9.7 "@noble/hashes": specifier: ^1.3.1 @@ -683,9 +668,6 @@ importers: bech32: specifier: ^2.0.0 version: 2.0.0 - elliptic: - specifier: ^6.5.4 - version: 6.6.1 libsodium-wrappers-sumo: specifier: ^0.8.2 version: 0.8.2 @@ -693,9 +675,6 @@ importers: "@jest/globals": specifier: ^30.0.0 version: 30.2.0 - "@types/elliptic": - specifier: ^6.4.18 - version: 6.4.18 "@types/libsodium-wrappers-sumo": specifier: ^0.8.2 version: 0.8.2 @@ -715,15 +694,15 @@ importers: "@interchainjs/utils": specifier: workspace:* version: link:../utils/dist + "@noble/curves": + specifier: ^1.9.7 + version: 1.9.7 "@noble/hashes": specifier: ^1 version: 1.8.0 bn.js: specifier: ^5.2.0 version: 5.2.3 - elliptic: - specifier: ^6.5.4 - version: 6.6.1 libsodium-wrappers-sumo: specifier: ^0.8.2 version: 0.8.2 @@ -731,9 +710,6 @@ importers: "@types/bn.js": specifier: ^5.2.0 version: 5.2.0 - "@types/elliptic": - specifier: ^6.4.18 - version: 6.4.18 "@types/libsodium-wrappers-sumo": specifier: ^0.8.2 version: 0.8.2 @@ -1994,108 +1970,6 @@ packages: } engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } - "@ethersproject/abstract-provider@5.8.0": - resolution: - { - integrity: sha512-wC9SFcmh4UK0oKuLJQItoQdzS/qZ51EJegK6EmAWlh+OptpQ/npECOR3QqECd8iGHC0RJb4WKbVdSfif4ammrg==, - } - - "@ethersproject/abstract-signer@5.8.0": - resolution: - { - integrity: sha512-N0XhZTswXcmIZQdYtUnd79VJzvEwXQw6PK0dTl9VoYrEBxxCPXqS0Eod7q5TNKRxe1/5WUMuR0u0nqTF/avdCA==, - } - - "@ethersproject/address@5.8.0": - resolution: - { - integrity: sha512-GhH/abcC46LJwshoN+uBNoKVFPxUuZm6dA257z0vZkKmU1+t8xTn8oK7B9qrj8W2rFRMch4gbJl6PmVxjxBEBA==, - } - - "@ethersproject/base64@5.8.0": - resolution: - { - integrity: sha512-lN0oIwfkYj9LbPx4xEkie6rAMJtySbpOAFXSDVQaBnAzYfB4X2Qr+FXJGxMoc3Bxp2Sm8OwvzMrywxyw0gLjIQ==, - } - - "@ethersproject/bignumber@5.8.0": - resolution: - { - integrity: sha512-ZyaT24bHaSeJon2tGPKIiHszWjD/54Sz8t57Toch475lCLljC6MgPmxk7Gtzz+ddNN5LuHea9qhAe0x3D+uYPA==, - } - - "@ethersproject/bytes@5.8.0": - resolution: - { - integrity: sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A==, - } - - "@ethersproject/constants@5.8.0": - resolution: - { - integrity: sha512-wigX4lrf5Vu+axVTIvNsuL6YrV4O5AXl5ubcURKMEME5TnWBouUh0CDTWxZ2GpnRn1kcCgE7l8O5+VbV9QTTcg==, - } - - "@ethersproject/hash@5.8.0": - resolution: - { - integrity: sha512-ac/lBcTbEWW/VGJij0CNSw/wPcw9bSRgCB0AIBz8CvED/jfvDoV9hsIIiWfvWmFEi8RcXtlNwp2jv6ozWOsooA==, - } - - "@ethersproject/keccak256@5.8.0": - resolution: - { - integrity: sha512-A1pkKLZSz8pDaQ1ftutZoaN46I6+jvuqugx5KYNeQOPqq+JZ0Txm7dlWesCHB5cndJSu5vP2VKptKf7cksERng==, - } - - "@ethersproject/logger@5.8.0": - resolution: - { - integrity: sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA==, - } - - "@ethersproject/networks@5.8.0": - resolution: - { - integrity: sha512-egPJh3aPVAzbHwq8DD7Po53J4OUSsA1MjQp8Vf/OZPav5rlmWUaFLiq8cvQiGK0Z5K6LYzm29+VA/p4RL1FzNg==, - } - - "@ethersproject/properties@5.8.0": - resolution: - { - integrity: sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw==, - } - - "@ethersproject/rlp@5.8.0": - resolution: - { - integrity: sha512-LqZgAznqDbiEunaUvykH2JAoXTT9NV0Atqk8rQN9nx9SEgThA/WMx5DnW8a9FOufo//6FZOCHZ+XiClzgbqV9Q==, - } - - "@ethersproject/signing-key@5.8.0": - resolution: - { - integrity: sha512-LrPW2ZxoigFi6U6aVkFN/fa9Yx/+4AtIUe4/HACTvKJdhm0eeb107EVCIQcrLZkxaSIgc/eCrX8Q1GtbH+9n3w==, - } - - "@ethersproject/strings@5.8.0": - resolution: - { - integrity: sha512-qWEAk0MAvl0LszjdfnZ2uC8xbR2wdv4cDabyHiBh3Cldq/T8dPH3V4BbBsAYJUeonwD+8afVXld274Ls+Y1xXg==, - } - - "@ethersproject/transactions@5.8.0": - resolution: - { - integrity: sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==, - } - - "@ethersproject/web@5.8.0": - resolution: - { - integrity: sha512-j7+Ksi/9KfGviws6Qtf9Q7KCqRhpwrYKQPs+JBA/rKVFF/yaWLHJEH3zfVP2plVu+eys0d2DlFmhoQJayFewcw==, - } - "@humanwhocodes/config-array@0.11.14": resolution: { @@ -3207,12 +3081,6 @@ packages: integrity: sha512-DLbJ1BPqxvQhIGbeu8VbUC1DiAiahHtAYvA0ZEAa4P31F7IaArc8z3C3BRQdWX4mtLQuABG4yzp76ZrS02Ui1Q==, } - "@types/elliptic@6.4.18": - resolution: - { - integrity: sha512-UseG6H5vjRiNpQvrhy4VF/JXdA3V/Fp5amvveaL+fs28BZ6xIKJBPnUPRlEaZpysD9MbpfaLi8lbl7PGUAkpWw==, - } - "@types/glob@7.2.0": resolution: { @@ -4130,12 +3998,6 @@ packages: integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==, } - bn.js@4.12.3: - resolution: - { - integrity: sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==, - } - bn.js@5.2.3: resolution: { @@ -4168,12 +4030,6 @@ packages: } engines: { node: ">=8" } - brorand@1.1.0: - resolution: - { - integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==, - } - browserslist@4.28.1: resolution: { @@ -4981,12 +4837,6 @@ packages: integrity: sha512-sM6HAN2LyK82IyPBpznDRqlTQAtuSaO+ShzFiWTvoMJLHyZ+Y39r8VMfHzwbU8MVBzQ4Wdn85+wlZl2TLGIlwg==, } - elliptic@6.6.1: - resolution: - { - integrity: sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==, - } - emittery@0.13.1: resolution: { @@ -5876,12 +5726,6 @@ packages: integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==, } - hash.js@1.1.7: - resolution: - { - integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==, - } - hasown@2.0.2: resolution: { @@ -5889,12 +5733,6 @@ packages: } engines: { node: ">= 0.4" } - hmac-drbg@1.0.1: - resolution: - { - integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==, - } - hosted-git-info@2.8.9: resolution: { @@ -6844,12 +6682,6 @@ packages: integrity: sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w==, } - js-sha3@0.8.0: - resolution: - { - integrity: sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==, - } - js-tokens@4.0.0: resolution: { @@ -7328,18 +7160,6 @@ packages: } engines: { node: ">=4" } - minimalistic-assert@1.0.1: - resolution: - { - integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==, - } - - minimalistic-crypto-utils@1.0.1: - resolution: - { - integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==, - } - minimatch@10.2.4: resolution: { @@ -10871,117 +10691,6 @@ snapshots: "@eslint/js@8.38.0": {} - "@ethersproject/abstract-provider@5.8.0": - dependencies: - "@ethersproject/bignumber": 5.8.0 - "@ethersproject/bytes": 5.8.0 - "@ethersproject/logger": 5.8.0 - "@ethersproject/networks": 5.8.0 - "@ethersproject/properties": 5.8.0 - "@ethersproject/transactions": 5.8.0 - "@ethersproject/web": 5.8.0 - - "@ethersproject/abstract-signer@5.8.0": - dependencies: - "@ethersproject/abstract-provider": 5.8.0 - "@ethersproject/bignumber": 5.8.0 - "@ethersproject/bytes": 5.8.0 - "@ethersproject/logger": 5.8.0 - "@ethersproject/properties": 5.8.0 - - "@ethersproject/address@5.8.0": - dependencies: - "@ethersproject/bignumber": 5.8.0 - "@ethersproject/bytes": 5.8.0 - "@ethersproject/keccak256": 5.8.0 - "@ethersproject/logger": 5.8.0 - "@ethersproject/rlp": 5.8.0 - - "@ethersproject/base64@5.8.0": - dependencies: - "@ethersproject/bytes": 5.8.0 - - "@ethersproject/bignumber@5.8.0": - dependencies: - "@ethersproject/bytes": 5.8.0 - "@ethersproject/logger": 5.8.0 - bn.js: 5.2.3 - - "@ethersproject/bytes@5.8.0": - dependencies: - "@ethersproject/logger": 5.8.0 - - "@ethersproject/constants@5.8.0": - dependencies: - "@ethersproject/bignumber": 5.8.0 - - "@ethersproject/hash@5.8.0": - dependencies: - "@ethersproject/abstract-signer": 5.8.0 - "@ethersproject/address": 5.8.0 - "@ethersproject/base64": 5.8.0 - "@ethersproject/bignumber": 5.8.0 - "@ethersproject/bytes": 5.8.0 - "@ethersproject/keccak256": 5.8.0 - "@ethersproject/logger": 5.8.0 - "@ethersproject/properties": 5.8.0 - "@ethersproject/strings": 5.8.0 - - "@ethersproject/keccak256@5.8.0": - dependencies: - "@ethersproject/bytes": 5.8.0 - js-sha3: 0.8.0 - - "@ethersproject/logger@5.8.0": {} - - "@ethersproject/networks@5.8.0": - dependencies: - "@ethersproject/logger": 5.8.0 - - "@ethersproject/properties@5.8.0": - dependencies: - "@ethersproject/logger": 5.8.0 - - "@ethersproject/rlp@5.8.0": - dependencies: - "@ethersproject/bytes": 5.8.0 - "@ethersproject/logger": 5.8.0 - - "@ethersproject/signing-key@5.8.0": - dependencies: - "@ethersproject/bytes": 5.8.0 - "@ethersproject/logger": 5.8.0 - "@ethersproject/properties": 5.8.0 - bn.js: 5.2.3 - elliptic: 6.6.1 - hash.js: 1.1.7 - - "@ethersproject/strings@5.8.0": - dependencies: - "@ethersproject/bytes": 5.8.0 - "@ethersproject/constants": 5.8.0 - "@ethersproject/logger": 5.8.0 - - "@ethersproject/transactions@5.8.0": - dependencies: - "@ethersproject/address": 5.8.0 - "@ethersproject/bignumber": 5.8.0 - "@ethersproject/bytes": 5.8.0 - "@ethersproject/constants": 5.8.0 - "@ethersproject/keccak256": 5.8.0 - "@ethersproject/logger": 5.8.0 - "@ethersproject/properties": 5.8.0 - "@ethersproject/rlp": 5.8.0 - "@ethersproject/signing-key": 5.8.0 - - "@ethersproject/web@5.8.0": - dependencies: - "@ethersproject/base64": 5.8.0 - "@ethersproject/bytes": 5.8.0 - "@ethersproject/logger": 5.8.0 - "@ethersproject/properties": 5.8.0 - "@ethersproject/strings": 5.8.0 - "@humanwhocodes/config-array@0.11.14": dependencies: "@humanwhocodes/object-schema": 2.0.3 @@ -12051,10 +11760,6 @@ snapshots: dependencies: "@types/node": 24.11.0 - "@types/elliptic@6.4.18": - dependencies: - "@types/bn.js": 5.2.0 - "@types/glob@7.2.0": dependencies: "@types/minimatch": 6.0.0 @@ -12609,8 +12314,6 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 - bn.js@4.12.3: {} - bn.js@5.2.3: {} brace-expansion@1.1.12: @@ -12630,8 +12333,6 @@ snapshots: dependencies: fill-range: 7.1.1 - brorand@1.1.0: {} - browserslist@4.28.1: dependencies: baseline-browser-mapping: 2.10.0 @@ -13084,16 +12785,6 @@ snapshots: electron-to-chromium@1.5.302: {} - elliptic@6.6.1: - dependencies: - bn.js: 4.12.3 - brorand: 1.1.0 - hash.js: 1.1.7 - hmac-drbg: 1.0.1 - inherits: 2.0.4 - minimalistic-assert: 1.0.1 - minimalistic-crypto-utils: 1.0.1 - emittery@0.13.1: {} emoji-regex@8.0.0: {} @@ -13663,21 +13354,10 @@ snapshots: has-unicode@2.0.1: {} - hash.js@1.1.7: - dependencies: - inherits: 2.0.4 - minimalistic-assert: 1.0.1 - hasown@2.0.2: dependencies: function-bind: 1.1.2 - hmac-drbg@1.0.1: - dependencies: - hash.js: 1.1.7 - minimalistic-assert: 1.0.1 - minimalistic-crypto-utils: 1.0.1 - hosted-git-info@2.8.9: {} hosted-git-info@4.1.0: @@ -14721,8 +14401,6 @@ snapshots: js-sdsl@4.4.2: {} - js-sha3@0.8.0: {} - js-tokens@4.0.0: {} js-yaml@3.14.2: @@ -15084,10 +14762,6 @@ snapshots: min-indent@1.0.1: {} - minimalistic-assert@1.0.1: {} - - minimalistic-crypto-utils@1.0.1: {} - minimatch@10.2.4: dependencies: brace-expansion: 5.0.4