diff --git a/packages/web3-eth-contract/package.json b/packages/web3-eth-contract/package.json
index 74edee8f90b..81a3a9f2a3a 100644
--- a/packages/web3-eth-contract/package.json
+++ b/packages/web3-eth-contract/package.json
@@ -45,6 +45,7 @@
"test:e2e:firefox": "npx cypress run --headless --browser firefox --env grep='ignore',invert=true"
},
"dependencies": {
+ "@ethereumjs/rlp": "^5.0.2",
"web3-core": "^4.4.0",
"web3-errors": "^1.2.0",
"web3-eth": "^4.7.0",
diff --git a/packages/web3-eth-contract/src/utils.ts b/packages/web3-eth-contract/src/utils.ts
index d2afe72a7b2..748203ffdf7 100644
--- a/packages/web3-eth-contract/src/utils.ts
+++ b/packages/web3-eth-contract/src/utils.ts
@@ -15,7 +15,8 @@ You should have received a copy of the GNU Lesser General Public License
along with web3.js. If not, see .
*/
-import { Web3ContractError } from 'web3-errors';
+import { RLP } from '@ethereumjs/rlp';
+import { InvalidAddressError, InvalidMethodParamsError, InvalidNumberError, Web3ContractError } from 'web3-errors';
import {
TransactionForAccessList,
AbiFunctionFragment,
@@ -26,8 +27,10 @@ import {
NonPayableCallOptions,
PayableCallOptions,
ContractOptions,
+ Numbers,
} from 'web3-types';
-import { isNullish, mergeDeep, isContractInitOptions } from 'web3-utils';
+import { isNullish, mergeDeep, isContractInitOptions, keccak256, toChecksumAddress, hexToNumber } from 'web3-utils';
+import { isAddress, isHexString } from 'web3-validator';
import { encodeMethodABI } from './encoding.js';
import { Web3ContractContext } from './types.js';
@@ -210,3 +213,42 @@ export const getCreateAccessListParams = ({
return txParams;
};
+
+
+export const createContractAddress = (from: Address, nonce: Numbers): Address => {
+ if(!isAddress(from))
+ throw new InvalidAddressError(`Invalid address given ${from}`);
+
+ let nonceValue = nonce;
+ if(typeof nonce === "string" && isHexString(nonce))
+ nonceValue = hexToNumber(nonce);
+ else if(typeof nonce === "string" && !isHexString(nonce))
+ throw new InvalidNumberError("Invalid nonce value format");
+
+ const rlpEncoded = RLP.encode(
+ [from, nonceValue]
+ );
+ const result = keccak256(rlpEncoded);
+
+ const contractAddress = '0x'.concat(result.substring(26));
+
+ return toChecksumAddress(contractAddress);
+}
+
+export const create2ContractAddress = (from: Address, salt: HexString, initCode: HexString): Address => {
+ if(!isAddress(from))
+ throw new InvalidAddressError(`Invalid address given ${from}`);
+
+ if(!isHexString(salt))
+ throw new InvalidMethodParamsError(`Invalid salt value ${salt}`);
+
+ if(!isHexString(initCode))
+ throw new InvalidMethodParamsError(`Invalid initCode value ${initCode}`);
+
+ const initCodeHash = keccak256(initCode);
+ const initCodeHashPadded = initCodeHash.padStart(64, '0'); // Pad to 32 bytes (64 hex characters)
+ const create2Params = ['0xff', from, salt, initCodeHashPadded].map(x => x.replace(/0x/, ''));
+ const create2Address = `0x${ create2Params.join('')}`;
+
+ return toChecksumAddress(`0x${ keccak256(create2Address).slice(26)}`); // Slice to get the last 20 bytes (40 hex characters) & checksum
+ }
\ No newline at end of file
diff --git a/packages/web3-eth-contract/test/fixtures/create.ts b/packages/web3-eth-contract/test/fixtures/create.ts
new file mode 100644
index 00000000000..0297828e5f1
--- /dev/null
+++ b/packages/web3-eth-contract/test/fixtures/create.ts
@@ -0,0 +1,134 @@
+/*
+This file is part of web3.js.
+
+web3.js is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+web3.js is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with web3.js. If not, see .
+*/
+
+import { Numbers } from "web3-types";
+
+export interface CreateTestData {
+ address: string;
+ input: {
+ from: string;
+ nonce: Numbers;
+ };
+ }
+
+export const testData: CreateTestData[] = [
+ {
+ address: '0x0C1B54fb6fdf63DEe15e65CAdBA8F2e028E26Bd0',
+
+ input: {
+ from: '0xe2597eb05cf9a87eb1309e86750c903ec38e527e',
+ nonce: 0,
+ }
+ },
+ {
+ address: '0x0C1B54fb6fdf63DEe15e65CAdBA8F2e028E26Bd0',
+
+ input: {
+ from: '0xe2597eb05cf9a87eb1309e86750c903ec38e527e',
+ nonce: BigInt(0),
+ }
+ },
+ {
+ address: '0x0C1B54fb6fdf63DEe15e65CAdBA8F2e028E26Bd0',
+
+ input: {
+ from: '0xe2597eb05cf9a87eb1309e86750c903ec38e527e',
+ nonce: "0x0",
+ }
+ },
+ {
+ address: '0x3474627D4F63A678266BC17171D87f8570936622',
+
+ input: {
+ from: '0xb2682160c482eb985ec9f3e364eec0a904c44c23',
+ nonce: 10,
+ }
+ },
+
+ {
+ address: '0x3474627D4F63A678266BC17171D87f8570936622',
+
+ input: {
+ from: '0xb2682160c482eb985ec9f3e364eec0a904c44c23',
+ nonce: "0xa",
+ }
+ },
+
+ {
+ address: '0x3474627D4F63A678266BC17171D87f8570936622',
+
+ input: {
+ from: '0xb2682160c482eb985ec9f3e364eec0a904c44c23',
+ nonce: "0x0a",
+ }
+ },
+
+ {
+ address: '0x271300790813f82638A8A6A8a86d65df6dF33c17',
+
+ input: {
+ from: '0x8ba1f109551bd432803012645ac136ddd64dba72',
+ nonce: "0x200",
+ }
+ },
+
+ {
+ address: '0x271300790813f82638A8A6A8a86d65df6dF33c17',
+
+ input: {
+ from: '0x8ba1f109551bd432803012645ac136ddd64dba72',
+ nonce: "0x0200",
+ }
+ },
+
+ {
+ address: '0x995C25706C407a1F1E84b3777775e3e619764933',
+
+ input: {
+ from: '0x8ba1f109551bd432803012645ac136ddd64dba72',
+ nonce: "0x1d",
+ }
+ },
+
+ {
+ address: '0x995C25706C407a1F1E84b3777775e3e619764933',
+
+ input: {
+ from: '0x8ba1f109551bd432803012645ac136ddd64dba72',
+ nonce: "0x001d",
+ }
+ },
+
+ {
+ address: '0x995C25706C407a1F1E84b3777775e3e619764933',
+
+ input: {
+ from: '0x8ba1f109551bd432803012645ac136ddd64dba72',
+ nonce: 29,
+ }
+ },
+
+
+ {
+ address: '0x0CcCC7507aEDf9FEaF8C8D731421746e16b4d39D',
+
+ input: {
+ from: '0xc6af6e1a78a6752c7f8cd63877eb789a2adb776c',
+ nonce: 0
+ }
+ },
+];
\ No newline at end of file
diff --git a/packages/web3-eth-contract/test/fixtures/create2.ts b/packages/web3-eth-contract/test/fixtures/create2.ts
new file mode 100644
index 00000000000..2cceb34f1bc
--- /dev/null
+++ b/packages/web3-eth-contract/test/fixtures/create2.ts
@@ -0,0 +1,70 @@
+/*
+This file is part of web3.js.
+
+web3.js is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+web3.js is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with web3.js. If not, see .
+*/
+
+import { Address, HexString } from "web3-types";
+
+export interface Create2TestData {
+ address: Address;
+ salt: HexString;
+ init_code: HexString;
+ result: Address;
+ }
+
+ export const create2TestData: Create2TestData[] = [
+ {
+ address: "0x0000000000000000000000000000000000000000",
+ salt: "0x0000000000000000000000000000000000000000000000000000000000000000",
+ init_code: "0x00",
+ result: "0x4D1A2e2bB4F88F0250f26Ffff098B0b30B26BF38"
+ },
+ {
+ address: "0xdeadbeef00000000000000000000000000000000",
+ salt: "0x0000000000000000000000000000000000000000000000000000000000000000",
+ init_code: "0x00",
+ result: "0xB928f69Bb1D91Cd65274e3c79d8986362984fDA3"
+ },
+ {
+ address: "0xdeadbeef00000000000000000000000000000000",
+ salt: "0x000000000000000000000000feed000000000000000000000000000000000000",
+ init_code: "0x00",
+ result: "0xD04116cDd17beBE565EB2422F2497E06cC1C9833"
+ },
+ {
+ address: "0x0000000000000000000000000000000000000000",
+ salt: "0x0000000000000000000000000000000000000000000000000000000000000000",
+ init_code: "0xdeadbeef",
+ result: "0x70f2b2914A2a4b783FaEFb75f459A580616Fcb5e"
+ },
+ {
+ address: "0x00000000000000000000000000000000deadbeef",
+ salt: "0x00000000000000000000000000000000000000000000000000000000cafebabe",
+ init_code: "0xdeadbeef",
+ result: "0x60f3f640a8508fC6a86d45DF051962668E1e8AC7"
+ },
+ {
+ address: "0x00000000000000000000000000000000deadbeef",
+ salt: "0x00000000000000000000000000000000000000000000000000000000cafebabe",
+ init_code: "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef",
+ result: "0x1d8bfDC5D46DC4f61D6b6115972536eBE6A8854C"
+ },
+ {
+ address: "0x0000000000000000000000000000000000000000",
+ salt: "0x0000000000000000000000000000000000000000000000000000000000000000",
+ init_code: "0x",
+ result: "0xE33C0C7F7df4809055C3ebA6c09CFe4BaF1BD9e0"
+ }
+ ];
\ No newline at end of file
diff --git a/packages/web3-eth-contract/test/integration/contract_deploy.test.ts b/packages/web3-eth-contract/test/integration/contract_deploy.test.ts
index b8036c123a3..2ff87f07177 100644
--- a/packages/web3-eth-contract/test/integration/contract_deploy.test.ts
+++ b/packages/web3-eth-contract/test/integration/contract_deploy.test.ts
@@ -16,7 +16,7 @@ along with web3.js. If not, see .
*/
import { Web3Eth } from 'web3-eth';
import { FMT_BYTES, FMT_NUMBER } from 'web3-types';
-import { Contract } from '../../src';
+import { Contract, createContractAddress } from '../../src';
import { sleep } from '../shared_fixtures/utils';
import { ERC721TokenAbi, ERC721TokenBytecode } from '../shared_fixtures/build/ERC721Token';
import { GreeterBytecode, GreeterAbi } from '../shared_fixtures/build/Greeter';
@@ -59,6 +59,18 @@ describe('contract', () => {
sendOptions = { from: acc.address, gas: '1000000' };
});
+ it('should get correct contract address before deploymet using CREATE', async () => {
+ const nonce = await web3Eth.getTransactionCount(sendOptions.from as string);
+
+ // get contract address before deployment
+ const address = createContractAddress(sendOptions.from as string, nonce);
+
+ const deployedContract = await contract.deploy(deployOptions).send(sendOptions);
+
+ expect(deployedContract).toBeDefined();
+ expect(deployedContract.options.address).toEqual(address);
+ });
+
afterAll(async () => {
await closeOpenConnection(web3Eth);
});
diff --git a/packages/web3-eth-contract/test/unit/utils.test.ts b/packages/web3-eth-contract/test/unit/utils.test.ts
new file mode 100644
index 00000000000..3b0b69a2bfc
--- /dev/null
+++ b/packages/web3-eth-contract/test/unit/utils.test.ts
@@ -0,0 +1,94 @@
+/*
+This file is part of web3.js.
+
+web3.js is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+web3.js is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with web3.js. If not, see .
+*/
+
+import { InvalidAddressError, InvalidNumberError } from "web3-errors";
+import { Address, Numbers } from "web3-types";
+import { CreateTestData, testData } from '../fixtures/create';
+import { create2ContractAddress, createContractAddress } from "../../src/utils";
+import { create2TestData } from "../fixtures/create2";
+
+
+describe('createContractAddress', () => {
+
+ it.each(testData)('creates correct contract address for input: %o', (testCase: CreateTestData) => {
+ const { address, input } = testCase;
+ const result = createContractAddress(input.from , input.nonce );
+ expect(result).toBe(address);
+ });
+
+ it('should throw InvalidAddressError for invalid address', () => {
+ expect(() => createContractAddress('invalid_address', 1)).toThrow(InvalidAddressError);
+ });
+
+ it('should throw Error for invalid nonce', () => {
+ expect(() => createContractAddress('0xe2597eb05cf9a87eb1309e86750c903ec38e527e', "")).toThrow(InvalidNumberError);
+ });
+
+ it('should handle different nonce types correctly', () => {
+ const from: Address = '0x6ac7ea33f8831ea9dcc53393aaa88b25a785dbf0';
+ const testCases: [Numbers, string][] = [
+ [1, '0x343c43A37D37dfF08AE8C4A11544c718AbB4fCF8'],
+ ['0x2', '0xf778B86FA74E846c4f0a1fBd1335FE81c00a0C91'],
+ [BigInt(3), '0xffFd933A0bC612844eaF0C6Fe3E5b8E9B6C1d19c'],
+ ];
+
+ testCases.forEach(([nonce, expectedAddress]) => {
+ const result = createContractAddress(from, nonce);
+ expect(result).toBe(expectedAddress);
+ });
+ });
+
+ it('should create different addresses for different nonces', () => {
+ const from: Address = '0x6ac7ea33f8831ea9dcc53393aaa88b25a785dbf0';
+ const address1 = createContractAddress(from, 0);
+ const address2 = createContractAddress(from, 1);
+
+ expect(address1).not.toBe(address2);
+ });
+
+ it('should create different addresses for different sender addresses', () => {
+ const from1: Address = '0x6ac7ea33f8831ea9dcc53393aaa88b25a785dbf0';
+ const from2: Address = '0x1234567890123456789012345678901234567890';
+ const nonce: Numbers = 0;
+
+ const address1 = createContractAddress(from1, nonce);
+ const address2 = createContractAddress(from2, nonce);
+
+ expect(address1).not.toBe(address2);
+ });
+});
+
+describe('create2ContractAddress', () => {
+
+ it.each(create2TestData)('creates correct contract address for input: %o', (testCase) => {
+ const result = create2ContractAddress(testCase.address, testCase.salt, testCase.init_code);
+ expect(result).toBe(testCase.result);
+ });
+
+ it('should throw an InvalidAddressError if the from address is invalid', () => {
+ expect(() => create2ContractAddress('0xinvalidaddress', create2TestData[0].salt, create2TestData[0].init_code)).toThrow('Invalid address given 0xinvalidaddress');
+ });
+
+ it('should throw an InvalidMethodParamsError if the salt is invalid', () => {
+ expect(() => create2ContractAddress(create2TestData[0].address, '0xinvalidsalt', create2TestData[0].init_code)).toThrow('Invalid salt value 0xinvalidsalt');
+ });
+
+ it('should throw an InvalidMethodParamsError if the initCode is invalid', () => {
+ expect(() => create2ContractAddress(create2TestData[0].address, create2TestData[0].salt, '0xinvalidcode')).toThrow('Invalid initCode value 0xinvalidcode');
+ });
+
+});
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index b0c3fe19f17..e85fa099abb 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -507,6 +507,11 @@
resolved "https://registry.yarnpkg.com/@ethereumjs/rlp/-/rlp-4.0.1.tgz#626fabfd9081baab3d0a3074b0c7ecaf674aaa41"
integrity sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==
+"@ethereumjs/rlp@^5.0.2":
+ version "5.0.2"
+ resolved "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-5.0.2.tgz#c89bd82f2f3bec248ab2d517ae25f5bbc4aac842"
+ integrity sha512-DziebCdg4JpGlEqEdGgXmjqcFoJi+JGulUXwEjsZGAscAQ7MyD/7LE/GVCP29vEQxKc7AAwjT3A2ywHp2xfoCA==
+
"@ethereumjs/tx@^3.3.0":
version "3.5.2"
resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-3.5.2.tgz#197b9b6299582ad84f9527ca961466fce2296c1c"
@@ -11458,7 +11463,7 @@ string-length@^4.0.1:
char-regex "^1.0.2"
strip-ansi "^6.0.0"
-"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
+"string-width-cjs@npm:string-width@^4.2.0":
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -11476,6 +11481,15 @@ string-width@^1.0.1:
is-fullwidth-code-point "^1.0.0"
strip-ansi "^3.0.0"
+"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
+ version "4.2.3"
+ resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
+ integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
+ dependencies:
+ emoji-regex "^8.0.0"
+ is-fullwidth-code-point "^3.0.0"
+ strip-ansi "^6.0.1"
+
string-width@^5.0.1, string-width@^5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794"
@@ -11522,7 +11536,7 @@ string_decoder@~1.1.1:
dependencies:
safe-buffer "~5.1.0"
-"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
+"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@@ -11536,6 +11550,13 @@ strip-ansi@^3.0.0, strip-ansi@^3.0.1:
dependencies:
ansi-regex "^2.0.0"
+strip-ansi@^6.0.0, strip-ansi@^6.0.1:
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
+ integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
+ dependencies:
+ ansi-regex "^5.0.1"
+
strip-ansi@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2"
@@ -12622,7 +12643,16 @@ workerpool@6.2.1:
resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343"
integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==
-"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
+"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
+ integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
+ dependencies:
+ ansi-styles "^4.0.0"
+ string-width "^4.1.0"
+ strip-ansi "^6.0.0"
+
+wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
@@ -12721,10 +12751,10 @@ ws@^8.11.0:
resolved "https://registry.yarnpkg.com/ws/-/ws-8.14.2.tgz#6c249a806eb2db7a20d26d51e7709eab7b2e6c7f"
integrity sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==
-ws@^8.8.1:
- version "8.8.1"
- resolved "https://registry.yarnpkg.com/ws/-/ws-8.8.1.tgz#5dbad0feb7ade8ecc99b830c1d77c913d4955ff0"
- integrity sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==
+ws@^8.17.1:
+ version "8.17.1"
+ resolved "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b"
+ integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==
xhr@^2.2.0:
version "2.6.0"
@@ -12855,4 +12885,4 @@ yocto-queue@^0.1.0:
zod@^3.21.4:
version "3.22.3"
resolved "https://registry.yarnpkg.com/zod/-/zod-3.22.3.tgz#2fbc96118b174290d94e8896371c95629e87a060"
- integrity sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==
\ No newline at end of file
+ integrity sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==