From e5d080e0bb42d408498cbc7b5e16d0c25d2f90b4 Mon Sep 17 00:00:00 2001 From: Joshua Averett Date: Thu, 30 Jan 2025 16:27:39 -0800 Subject: [PATCH 01/53] Combined contracts, updated governance model --- src/BackwardsOptimized/BackwardsOptimized.sol | 67 --- src/{BackwardsOptimized => }/ExtStore.sol | 0 src/GuardianSetCore.sol | 91 ++++ src/RawDispatcher.sol | 13 + src/ThresholdCore.sol | 85 +++ src/ThresholdSigOptimized.sol | 50 -- src/VerificationV2.sol | 132 +++++ src/gscd/BytesLib.sol | 510 ------------------ src/gscd/Getters.sol | 71 --- src/gscd/Governance.sol | 227 -------- src/gscd/GovernanceStructs.sol | 183 ------- src/gscd/Implementation.sol | 80 --- src/gscd/Messages.sol | 252 --------- src/gscd/Setters.sol | 80 --- src/gscd/Setup.sol | 42 -- src/gscd/State.sol | 46 -- src/gscd/Wormhole.sol | 13 - 17 files changed, 321 insertions(+), 1621 deletions(-) delete mode 100644 src/BackwardsOptimized/BackwardsOptimized.sol rename src/{BackwardsOptimized => }/ExtStore.sol (100%) create mode 100644 src/GuardianSetCore.sol create mode 100644 src/RawDispatcher.sol create mode 100644 src/ThresholdCore.sol delete mode 100644 src/ThresholdSigOptimized.sol create mode 100644 src/VerificationV2.sol delete mode 100644 src/gscd/BytesLib.sol delete mode 100644 src/gscd/Getters.sol delete mode 100644 src/gscd/Governance.sol delete mode 100644 src/gscd/GovernanceStructs.sol delete mode 100644 src/gscd/Implementation.sol delete mode 100644 src/gscd/Messages.sol delete mode 100644 src/gscd/Setters.sol delete mode 100644 src/gscd/Setup.sol delete mode 100644 src/gscd/State.sol delete mode 100644 src/gscd/Wormhole.sol diff --git a/src/BackwardsOptimized/BackwardsOptimized.sol b/src/BackwardsOptimized/BackwardsOptimized.sol deleted file mode 100644 index 132ef86..0000000 --- a/src/BackwardsOptimized/BackwardsOptimized.sol +++ /dev/null @@ -1,67 +0,0 @@ -// SPDX-License-Identifier: Apache 2 - -pragma solidity ^0.8.24; - -import "wormhole-sdk/interfaces/IWormhole.sol"; -import "wormhole-sdk/libraries/BytesParsing.sol"; -import "wormhole-sdk/libraries/CoreBridge.sol"; -import {VaaLib} from "wormhole-sdk/libraries/VaaLib.sol"; -import { ProxyBase } from "wormhole-sdk/proxy/ProxyBase.sol"; -import "./ExtStore.sol"; - -contract BackwardsOptimized is ProxyBase, ExtStore { - using BytesParsing for bytes; - using VaaLib for bytes; - - mapping(uint32 => uint32) private _guardianSetExpirationTimes; - uint32 private _currentGuardianSetIndex; - - constructor() ExtStore() {} - - function _proxyConstructor(bytes calldata args) internal override { - // bytes memory data = new bytes(0); - // for (uint i = 0; i < guardians.length; ++i) - // data = abi.encodePacked(data, guardians[i]); - - //despite the "packed" it will actually pad each entry to 32 bytes - _currentGuardianSetIndex = uint32(_extWrite(abi.encodePacked(args))); - } - - function parseAndVerifyVM( - bytes calldata encodedVm - ) external view returns (IWormhole.VM memory vm, bool valid, string memory reason) { unchecked { - vm = encodedVm.decodeVmStructCd(); - - uint32 guardianSetIndex = vm.guardianSetIndex; - address[] memory guardianAddrs = _getGuardianAddresses(guardianSetIndex); - require( - CoreBridgeLib.isVerifiedByQuorumMem( - vm.hash, - VaaLib.asGuardianSignatures(vm.signatures), - guardianAddrs - ), - "VM not verified by quorum" - ); - - //backwards compatible nonsense: - valid = true; - reason = ""; - }} - - function getGuardianSet(uint32 index) external view returns (IWormhole.GuardianSet memory ret) { - ret.keys = _getGuardianAddresses(index); - ret.expirationTime = _guardianSetExpirationTimes[index]; - } - - function getCurrentGuardianSetIndex() external view returns (uint32) { unchecked { - return _currentGuardianSetIndex; - }} - - function _getGuardianAddresses(uint32 index) internal view returns (address[] memory ret) { - bytes memory data = _extRead(index); - assembly ("memory-safe") { - ret := data - mstore(ret, div(mload(ret), 32)) - } - } -} \ No newline at end of file diff --git a/src/BackwardsOptimized/ExtStore.sol b/src/ExtStore.sol similarity index 100% rename from src/BackwardsOptimized/ExtStore.sol rename to src/ExtStore.sol diff --git a/src/GuardianSetCore.sol b/src/GuardianSetCore.sol new file mode 100644 index 0000000..cadae9a --- /dev/null +++ b/src/GuardianSetCore.sol @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: Apache 2 + +pragma solidity ^0.8.0; + +import "./ExtStore.sol"; +import "wormhole-sdk/interfaces/IWormhole.sol"; + +contract GuardianSetVerification is ExtStore { + IWormhole private _coreV1; + + // Guardian set expiration time is stored in an array mapped from index to expiration time + uint32[] private _guardianSetExpirationTime; + + // Get the guardian addresses for a given guardian set index using the ExtStore + function getGuardianSetInfo(uint32 index) public view returns (uint32 expirationTime, address[] memory guardianAddrs) { + expirationTime = _guardianSetExpirationTime[index]; + + bytes memory data = _extRead(index); + assembly ("memory-safe") { + guardianAddrs := data + mstore(guardianAddrs, div(mload(guardianAddrs), 32)) + } + } + + function getCurrentGuardianSetInfo() public view returns (uint32 index, address[] memory guardianAddrs) { + // NOTE: Expiration time array is one entry shorter than the guardian set index + // because the current guardian set is not included in the array(no expiration time set) + index = uint32(_guardianSetExpirationTime.length - 1); + uint32 expirationTime; + (expirationTime, guardianAddrs) = this.getGuardianSetInfo(index); + return (index, guardianAddrs); + } + + // Verify a guardian set VAA + function verifyGuardianSetVAA(IWormhole.VM memory vm) public view returns (bool) { + unchecked { + // Get the guardian set info + uint32 vmGuardianSetIndex = vm.guardianSetIndex; + (uint32 currentGuardianSetIndex, address[] memory guardianAddrs) = this.getCurrentGuardianSetInfo(); + uint sigCount = vm.signatures.length; + uint guardianCount = guardianAddrs.length; + + // Validate the guardian set + require(guardianCount != 0, "invalid guardian set"); + require(sigCount > guardianCount * 2 / 3, "no quorum"); + if (vmGuardianSetIndex != currentGuardianSetIndex) { + require( + _guardianSetExpirationTime[vmGuardianSetIndex] >= block.timestamp, + "guardian set has expired" + ); + } + + // Verify the signatures + int lastIndex = -1; + for (uint i = 0; i < sigCount; ++i) { + IWormhole.Signature memory sig = vm.signatures[i]; + uint idx = sig.guardianIndex; + require(int(idx) > lastIndex, "signature indices must be ascending"); + require(ecrecover(vm.hash, sig.v, sig.r, sig.s) == guardianAddrs[idx], "VM signature invalid"); + lastIndex = int(idx); + } + + require(lastIndex < int(guardianCount), "guardian index out of bounds"); // FIXME: Do we need this check? if idx > guardianAddrs.length, it will revert already + return true; + } + } + + function pullGuardianSets() public { + // For each guardian set after the current one + uint32 coreGuardianSetIndex = _coreV1.getCurrentGuardianSetIndex(); + for (uint32 i = uint32(_guardianSetExpirationTime.length); i <= coreGuardianSetIndex; ++i) { + // Pull the guardian set from the core V1 contract + IWormhole.GuardianSet memory guardians = _coreV1.getGuardianSet(i); + + // Convert the guardian set to a byte array + address[] memory keys = guardians.keys; + bytes memory data; + assembly ("memory-safe") { + data := keys + mstore(data, mul(mload(data), 32)) + } + + // Write the guardian set to the ExtStore and verify the index + uint32 extIndex = uint32(_extWrite(data)); + require(extIndex == i, "ext index mismatch"); + + // Set the expiration time for the guardian set + _guardianSetExpirationTime.push(guardians.expirationTime); + } + } +} diff --git a/src/RawDispatcher.sol b/src/RawDispatcher.sol new file mode 100644 index 0000000..8d4331e --- /dev/null +++ b/src/RawDispatcher.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +abstract contract RawDispatcher { + uint8 public constant VERSION = 1; + + function exec768() external payable returns (bytes memory) { return _exec(msg.data[4:]); } + function get1959() external view returns (bytes memory) { return _get(msg.data[4:]); } + + function _exec(bytes calldata data) internal virtual returns (bytes memory); + function _get(bytes calldata data) internal view virtual returns (bytes memory); +} diff --git a/src/ThresholdCore.sol b/src/ThresholdCore.sol new file mode 100644 index 0000000..3ef1cae --- /dev/null +++ b/src/ThresholdCore.sol @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: Apache 2 + +pragma solidity ^0.8.0; + +import "wormhole-sdk/libraries/BytesParsing.sol"; +import "wormhole-sdk/libraries/VaaLib.sol"; + +contract ThresholdVerification { + using BytesParsing for bytes; + using VaaLib for bytes; + + // Current threshold info is stord in a single slot + // Format: + // index (32 bits) + // address (160 bits) + uint256 private _currentThresholdInfo; + + // Past threshold info is stored in an array + // Format: + // expiration time (32 bits) + // address (160 bits) + uint256[] private _pastThresholdInfo; + + // Get the current threshold signature info + function getCurrentThresholdInfo() public view returns (uint32 index, address addr) { + return ( + uint32(_currentThresholdInfo), + address(uint160(_currentThresholdInfo >> 32)) + ); + } + + // Get the past threshold signature info + function getPastThresholdInfo(uint32 index) public view returns (uint32 expirationTime, address addr) { + uint256 info = _pastThresholdInfo[index]; + return ( + uint32(info), + address(uint160(info >> 32)) + ); + } + + // Verify a threshold signature VAA + function verifyThresholdVAA(IWormhole.VM memory vm) public view returns (bool) { + require(vm.version == 2, "VM version must be 2 for threshold signatures"); + require(vm.signatures.length == 1, "Signature count must be 1"); + + // Get the current threshold info + ( uint32 currentThresholdIndex, + address currentThresholdAddr + ) = this.getCurrentThresholdInfo(); + + // Get the threshold address + address thresholdAddr; + uint32 vmGuardianSetIndex = vm.guardianSetIndex; + if (vmGuardianSetIndex != currentThresholdIndex) { + // If the guardian set index is not the current threshold index, we need to get the past threshold info + // and validate that it is not expired + (uint32 expirationTime, address addr) = this.getPastThresholdInfo(vmGuardianSetIndex); + require(addr != address(0), "invalid guardian set"); + require(expirationTime >= block.timestamp, "guardian set has expired"); + thresholdAddr = addr; + } else { + // If the guardian set index is the current threshold index, we can use the current threshold info + thresholdAddr = currentThresholdAddr; + } + + // Verify the threshold signature + IWormhole.Signature memory sig = vm.signatures[0]; + require(ecrecover(vm.hash, sig.v, sig.r, sig.s) == thresholdAddr, "threshold signature invalid"); + return true; + } + + function _appendThresholdKey(uint32 newIndex, address newAddr, uint32 oldExpirationTime) internal { + // Get the current threshold info and verify the new index is sequential + (uint32 index, address currentAddr) = this.getCurrentThresholdInfo(); + require(newIndex == index + 1, "non-sequential index"); + + // Store the current threshold info in past threshold info + uint256 oldInfo = (uint256(uint160(currentAddr)) << 32) | uint256(oldExpirationTime); + _pastThresholdInfo.push(oldInfo); + + // Update the current threshold info + uint256 newInfo = (uint256(uint160(newAddr)) << 32) | uint256(newIndex); + _currentThresholdInfo = newInfo; + } +} diff --git a/src/ThresholdSigOptimized.sol b/src/ThresholdSigOptimized.sol deleted file mode 100644 index 5648844..0000000 --- a/src/ThresholdSigOptimized.sol +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-License-Identifier: Apache 2 - -pragma solidity ^0.8.24; - -import "wormhole-sdk/interfaces/IWormhole.sol"; -import "wormhole-sdk/libraries/BytesParsing.sol"; -import "wormhole-sdk/libraries/VaaLib.sol"; -import { ProxyBase } from "wormhole-sdk/proxy/ProxyBase.sol"; - -contract ThresholdSigOptimized is ProxyBase { - using BytesParsing for bytes; - using VaaLib for bytes; - - mapping (uint32 => address) private _expiringThresholdAddrs; - mapping (uint32 => uint32) private _expirationTimes; - uint32 private _currentGuardianSetIndex; - address private _currentThresholdAddr; //put in same storage slot as _currentGuardianSetIndex - //to save gas on storage reads for most cases - - function _proxyConstructor(bytes calldata args) internal override { - _currentThresholdAddr = abi.decode(args, (address)); - } - - function parseAndVerifyVMThreshold( - bytes calldata encodedVaa - ) external view returns (VaaBody memory) { - ( uint32 guardianSetIndex, - GuardianSignature[] memory sigs, - uint envelopeOffset - ) = encodedVaa.decodeVaaHeaderCdUnchecked(); - - address thresholdAddr; - if (guardianSetIndex != _currentGuardianSetIndex) { - thresholdAddr = _expiringThresholdAddrs[guardianSetIndex]; - require(thresholdAddr != address(0), "invalid guardian set"); - require( - _expirationTimes[guardianSetIndex] >= block.timestamp, - "guardian set has expired" - ); - } - else - thresholdAddr = _currentThresholdAddr; - require(sigs.length == 1, "not a threshold signature vm"); - - bytes32 vaaHash = encodedVaa.calcVaaDoubleHashCd(envelopeOffset); - GuardianSignature memory sig = sigs[0]; - require(ecrecover(vaaHash, sig.v, sig.r, sig.s) == thresholdAddr, "threshold signature invalid"); - return encodedVaa.decodeVaaBodyStructCd(envelopeOffset); - } -} \ No newline at end of file diff --git a/src/VerificationV2.sol b/src/VerificationV2.sol new file mode 100644 index 0000000..47920ca --- /dev/null +++ b/src/VerificationV2.sol @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: Apache 2 + +pragma solidity ^0.8.0; + +import "wormhole-sdk/libraries/BytesParsing.sol"; +import "./RawDispatcher.sol"; +import "./ThresholdCore.sol"; +import "./GuardianSetCore.sol"; + +contract VerificationV2 is RawDispatcher, ThresholdVerification, GuardianSetVerification { + using BytesParsing for bytes; + using VaaLib for bytes; + + uint8 constant OP_GOVERNANCE = 0x00; + uint8 constant OP_PULL_GUARDIAN_SETS = 0x01; + + uint8 constant OP_VERIFY = 0x20; + uint8 constant OP_THRESHOLD_GET_CURRENT = 0x21; + uint8 constant OP_THRESHOLD_GET = 0x22; + uint8 constant OP_GUARDIAN_SET_GET_CURRENT = 0x23; + uint8 constant OP_GUARDIAN_SET_GET = 0x24; + + bytes32 constant MODULE_VERIFICATION_V2 = bytes32(0x0000000000000000000000000000000000000000000000000000000000545353); + + uint8 constant ACTION_APPEND_THRESHOLD_KEY = 0x01; + + function decodeAndVerifyVaa(bytes calldata encodedVaa) internal view returns (bool verified, IWormhole.VM memory vm) { + vm = encodedVaa.decodeVmStructCd(); + + if (vm.version == 2) { + verified = verifyThresholdVAA(vm); + } else if (vm.version == 1) { + verified = verifyGuardianSetVAA(vm); + } else { + revert("Unsupported VAA version"); + } + } + + function decodeThresholdVaaPayload(bytes memory payload) internal pure returns ( + bytes32 module, + uint8 action, + uint8 newThresholdIndex, + address newThresholdAddr, + uint32 oldExpirationTime + ) { + uint offset = 0; + (module, offset) = payload.asBytes32MemUnchecked(offset); + (action, offset) = payload.asUint8MemUnchecked(offset); + (newThresholdIndex, offset) = payload.asUint8MemUnchecked(offset); + (newThresholdAddr, offset) = payload.asAddressMemUnchecked(offset); + (oldExpirationTime, offset) = payload.asUint32MemUnchecked(offset); + } + + function _exec(bytes calldata data) internal override returns (bytes memory) { + uint offset = 0; + uint8 version; + (version, offset) = data.asUint8CdUnchecked(offset); + require(version == RawDispatcher.VERSION, "invalid version"); + + uint length = data.length; + while (offset < length) { + uint8 op; + (op, offset) = data.asUint8CdUnchecked(offset); + + if (op == OP_GOVERNANCE) { + // Read the VAA and verify it + uint32 dataLength; + (dataLength, offset) = data.asUint32CdUnchecked(offset); + + bytes calldata encodedVaa = data[offset:offset + dataLength]; + (bool verified, IWormhole.VM memory vm) = decodeAndVerifyVaa(encodedVaa); + require(verified, "invalid threshold vaa"); + + // Decode the payload + (bytes32 module, uint8 action, uint8 newThresholdIndex, address newThresholdAddr, uint32 oldExpirationTime) = decodeThresholdVaaPayload(vm.payload); + require(module == MODULE_VERIFICATION_V2, "invalid module"); + require(action == ACTION_APPEND_THRESHOLD_KEY, "invalid action"); + + // Append the threshold key + _appendThresholdKey(newThresholdIndex, newThresholdAddr, oldExpirationTime); + } else if (op == OP_PULL_GUARDIAN_SETS) { + pullGuardianSets(); + } + } + + return new bytes(0); + } + + function _get(bytes calldata data) internal view override returns (bytes memory) { + uint offset = 0; + uint8 version; + (version, offset) = data.asUint8CdUnchecked(offset); + require(version == RawDispatcher.VERSION, "invalid version"); + + bytes memory result; + uint length = data.length; + while (offset < length) { + uint8 op; + (op, offset) = data.asUint8CdUnchecked(offset); + + bytes memory result_entry; + if (op == OP_VERIFY) { + uint32 dataLength; + (dataLength, offset) = data.asUint32CdUnchecked(offset); + + bytes calldata encodedVaa = data[offset:offset + dataLength]; + (bool verified,) = decodeAndVerifyVaa(encodedVaa); + result_entry = abi.encodePacked(verified); + } else if (op == OP_THRESHOLD_GET_CURRENT) { + (uint32 thresholdIndex, address thresholdAddr) = getCurrentThresholdInfo(); + result_entry = abi.encodePacked(thresholdIndex, thresholdAddr); + } else if (op == OP_THRESHOLD_GET) { + uint32 index; + (index, offset) = data.asUint32CdUnchecked(offset); + (uint32 expirationTime, address thresholdAddr) = getPastThresholdInfo(index); + result_entry = abi.encodePacked(expirationTime, thresholdAddr); + } else if (op == OP_GUARDIAN_SET_GET_CURRENT) { + (uint32 guardianSetIndex, address[] memory guardianSetAddrs) = getCurrentGuardianSetInfo(); + result_entry = abi.encodePacked(guardianSetIndex, guardianSetAddrs); + } else if (op == OP_GUARDIAN_SET_GET) { + uint32 index; + (index, offset) = data.asUint32CdUnchecked(offset); + (uint32 expirationTime, address[] memory guardianSetAddrs) = getGuardianSetInfo(index); + result_entry = abi.encodePacked(expirationTime, guardianSetAddrs); + } + + result = abi.encodePacked(result, result_entry); + } + + return result; + } +} diff --git a/src/gscd/BytesLib.sol b/src/gscd/BytesLib.sol deleted file mode 100644 index 58b8f51..0000000 --- a/src/gscd/BytesLib.sol +++ /dev/null @@ -1,510 +0,0 @@ -// SPDX-License-Identifier: Unlicense -/* - * @title Solidity Bytes Arrays Utils - * @author Gonçalo Sá - * - * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity. - * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage. - */ -pragma solidity >=0.8.0 <0.9.0; - - -library BytesLib { - function concat( - bytes memory _preBytes, - bytes memory _postBytes - ) - internal - pure - returns (bytes memory) - { - bytes memory tempBytes; - - assembly { - // Get a location of some free memory and store it in tempBytes as - // Solidity does for memory variables. - tempBytes := mload(0x40) - - // Store the length of the first bytes array at the beginning of - // the memory for tempBytes. - let length := mload(_preBytes) - mstore(tempBytes, length) - - // Maintain a memory counter for the current write location in the - // temp bytes array by adding the 32 bytes for the array length to - // the starting location. - let mc := add(tempBytes, 0x20) - // Stop copying when the memory counter reaches the length of the - // first bytes array. - let end := add(mc, length) - - for { - // Initialize a copy counter to the start of the _preBytes data, - // 32 bytes into its memory. - let cc := add(_preBytes, 0x20) - } lt(mc, end) { - // Increase both counters by 32 bytes each iteration. - mc := add(mc, 0x20) - cc := add(cc, 0x20) - } { - // Write the _preBytes data into the tempBytes memory 32 bytes - // at a time. - mstore(mc, mload(cc)) - } - - // Add the length of _postBytes to the current length of tempBytes - // and store it as the new length in the first 32 bytes of the - // tempBytes memory. - length := mload(_postBytes) - mstore(tempBytes, add(length, mload(tempBytes))) - - // Move the memory counter back from a multiple of 0x20 to the - // actual end of the _preBytes data. - mc := end - // Stop copying when the memory counter reaches the new combined - // length of the arrays. - end := add(mc, length) - - for { - let cc := add(_postBytes, 0x20) - } lt(mc, end) { - mc := add(mc, 0x20) - cc := add(cc, 0x20) - } { - mstore(mc, mload(cc)) - } - - // Update the free-memory pointer by padding our last write location - // to 32 bytes: add 31 bytes to the end of tempBytes to move to the - // next 32 byte block, then round down to the nearest multiple of - // 32. If the sum of the length of the two arrays is zero then add - // one before rounding down to leave a blank 32 bytes (the length block with 0). - mstore(0x40, and( - add(add(end, iszero(add(length, mload(_preBytes)))), 31), - not(31) // Round down to the nearest 32 bytes. - )) - } - - return tempBytes; - } - - function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal { - assembly { - // Read the first 32 bytes of _preBytes storage, which is the length - // of the array. (We don't need to use the offset into the slot - // because arrays use the entire slot.) - let fslot := sload(_preBytes.slot) - // Arrays of 31 bytes or less have an even value in their slot, - // while longer arrays have an odd value. The actual length is - // the slot divided by two for odd values, and the lowest order - // byte divided by two for even values. - // If the slot is even, bitwise and the slot with 255 and divide by - // two to get the length. If the slot is odd, bitwise and the slot - // with -1 and divide by two. - let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2) - let mlength := mload(_postBytes) - let newlength := add(slength, mlength) - // slength can contain both the length and contents of the array - // if length < 32 bytes so let's prepare for that - // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage - switch add(lt(slength, 32), lt(newlength, 32)) - case 2 { - // Since the new array still fits in the slot, we just need to - // update the contents of the slot. - // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length - sstore( - _preBytes.slot, - // all the modifications to the slot are inside this - // next block - add( - // we can just add to the slot contents because the - // bytes we want to change are the LSBs - fslot, - add( - mul( - div( - // load the bytes from memory - mload(add(_postBytes, 0x20)), - // zero all bytes to the right - exp(0x100, sub(32, mlength)) - ), - // and now shift left the number of bytes to - // leave space for the length in the slot - exp(0x100, sub(32, newlength)) - ), - // increase length by the double of the memory - // bytes length - mul(mlength, 2) - ) - ) - ) - } - case 1 { - // The stored value fits in the slot, but the combined value - // will exceed it. - // get the keccak hash to get the contents of the array - mstore(0x0, _preBytes.slot) - let sc := add(keccak256(0x0, 0x20), div(slength, 32)) - - // save new length - sstore(_preBytes.slot, add(mul(newlength, 2), 1)) - - // The contents of the _postBytes array start 32 bytes into - // the structure. Our first read should obtain the `submod` - // bytes that can fit into the unused space in the last word - // of the stored array. To get this, we read 32 bytes starting - // from `submod`, so the data we read overlaps with the array - // contents by `submod` bytes. Masking the lowest-order - // `submod` bytes allows us to add that value directly to the - // stored value. - - let submod := sub(32, slength) - let mc := add(_postBytes, submod) - let end := add(_postBytes, mlength) - let mask := sub(exp(0x100, submod), 1) - - sstore( - sc, - add( - and( - fslot, - 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00 - ), - and(mload(mc), mask) - ) - ) - - for { - mc := add(mc, 0x20) - sc := add(sc, 1) - } lt(mc, end) { - sc := add(sc, 1) - mc := add(mc, 0x20) - } { - sstore(sc, mload(mc)) - } - - mask := exp(0x100, sub(mc, end)) - - sstore(sc, mul(div(mload(mc), mask), mask)) - } - default { - // get the keccak hash to get the contents of the array - mstore(0x0, _preBytes.slot) - // Start copying to the last used word of the stored array. - let sc := add(keccak256(0x0, 0x20), div(slength, 32)) - - // save new length - sstore(_preBytes.slot, add(mul(newlength, 2), 1)) - - // Copy over the first `submod` bytes of the new data as in - // case 1 above. - let slengthmod := mod(slength, 32) - let mlengthmod := mod(mlength, 32) - let submod := sub(32, slengthmod) - let mc := add(_postBytes, submod) - let end := add(_postBytes, mlength) - let mask := sub(exp(0x100, submod), 1) - - sstore(sc, add(sload(sc), and(mload(mc), mask))) - - for { - sc := add(sc, 1) - mc := add(mc, 0x20) - } lt(mc, end) { - sc := add(sc, 1) - mc := add(mc, 0x20) - } { - sstore(sc, mload(mc)) - } - - mask := exp(0x100, sub(mc, end)) - - sstore(sc, mul(div(mload(mc), mask), mask)) - } - } - } - - function slice( - bytes memory _bytes, - uint256 _start, - uint256 _length - ) - internal - pure - returns (bytes memory) - { - require(_length + 31 >= _length, "slice_overflow"); - require(_bytes.length >= _start + _length, "slice_outOfBounds"); - - bytes memory tempBytes; - - assembly { - switch iszero(_length) - case 0 { - // Get a location of some free memory and store it in tempBytes as - // Solidity does for memory variables. - tempBytes := mload(0x40) - - // The first word of the slice result is potentially a partial - // word read from the original array. To read it, we calculate - // the length of that partial word and start copying that many - // bytes into the array. The first word we copy will start with - // data we don't care about, but the last `lengthmod` bytes will - // land at the beginning of the contents of the new array. When - // we're done copying, we overwrite the full first word with - // the actual length of the slice. - let lengthmod := and(_length, 31) - - // The multiplication in the next line is necessary - // because when slicing multiples of 32 bytes (lengthmod == 0) - // the following copy loop was copying the origin's length - // and then ending prematurely not copying everything it should. - let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) - let end := add(mc, _length) - - for { - // The multiplication in the next line has the same exact purpose - // as the one above. - let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start) - } lt(mc, end) { - mc := add(mc, 0x20) - cc := add(cc, 0x20) - } { - mstore(mc, mload(cc)) - } - - mstore(tempBytes, _length) - - //update free-memory pointer - //allocating the array padded to 32 bytes like the compiler does now - mstore(0x40, and(add(mc, 31), not(31))) - } - //if we want a zero-length slice let's just return a zero-length array - default { - tempBytes := mload(0x40) - //zero out the 32 bytes slice we are about to return - //we need to do it because Solidity does not garbage collect - mstore(tempBytes, 0) - - mstore(0x40, add(tempBytes, 0x20)) - } - } - - return tempBytes; - } - - function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) { - require(_bytes.length >= _start + 20, "toAddress_outOfBounds"); - address tempAddress; - - assembly { - tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000) - } - - return tempAddress; - } - - function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) { - require(_bytes.length >= _start + 1 , "toUint8_outOfBounds"); - uint8 tempUint; - - assembly { - tempUint := mload(add(add(_bytes, 0x1), _start)) - } - - return tempUint; - } - - function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) { - require(_bytes.length >= _start + 2, "toUint16_outOfBounds"); - uint16 tempUint; - - assembly { - tempUint := mload(add(add(_bytes, 0x2), _start)) - } - - return tempUint; - } - - function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) { - require(_bytes.length >= _start + 4, "toUint32_outOfBounds"); - uint32 tempUint; - - assembly { - tempUint := mload(add(add(_bytes, 0x4), _start)) - } - - return tempUint; - } - - function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) { - require(_bytes.length >= _start + 8, "toUint64_outOfBounds"); - uint64 tempUint; - - assembly { - tempUint := mload(add(add(_bytes, 0x8), _start)) - } - - return tempUint; - } - - function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) { - require(_bytes.length >= _start + 12, "toUint96_outOfBounds"); - uint96 tempUint; - - assembly { - tempUint := mload(add(add(_bytes, 0xc), _start)) - } - - return tempUint; - } - - function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) { - require(_bytes.length >= _start + 16, "toUint128_outOfBounds"); - uint128 tempUint; - - assembly { - tempUint := mload(add(add(_bytes, 0x10), _start)) - } - - return tempUint; - } - - function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) { - require(_bytes.length >= _start + 32, "toUint256_outOfBounds"); - uint256 tempUint; - - assembly { - tempUint := mload(add(add(_bytes, 0x20), _start)) - } - - return tempUint; - } - - function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) { - require(_bytes.length >= _start + 32, "toBytes32_outOfBounds"); - bytes32 tempBytes32; - - assembly { - tempBytes32 := mload(add(add(_bytes, 0x20), _start)) - } - - return tempBytes32; - } - - function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) { - bool success = true; - - assembly { - let length := mload(_preBytes) - - // if lengths don't match the arrays are not equal - switch eq(length, mload(_postBytes)) - case 1 { - // cb is a circuit breaker in the for loop since there's - // no said feature for inline assembly loops - // cb = 1 - don't breaker - // cb = 0 - break - let cb := 1 - - let mc := add(_preBytes, 0x20) - let end := add(mc, length) - - for { - let cc := add(_postBytes, 0x20) - // the next line is the loop condition: - // while(uint256(mc < end) + cb == 2) - } eq(add(lt(mc, end), cb), 2) { - mc := add(mc, 0x20) - cc := add(cc, 0x20) - } { - // if any of these checks fails then arrays are not equal - if iszero(eq(mload(mc), mload(cc))) { - // unsuccess: - success := 0 - cb := 0 - } - } - } - default { - // unsuccess: - success := 0 - } - } - - return success; - } - - function equalStorage( - bytes storage _preBytes, - bytes memory _postBytes - ) - internal - view - returns (bool) - { - bool success = true; - - assembly { - // we know _preBytes_offset is 0 - let fslot := sload(_preBytes.slot) - // Decode the length of the stored array like in concatStorage(). - let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2) - let mlength := mload(_postBytes) - - // if lengths don't match the arrays are not equal - switch eq(slength, mlength) - case 1 { - // slength can contain both the length and contents of the array - // if length < 32 bytes so let's prepare for that - // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage - if iszero(iszero(slength)) { - switch lt(slength, 32) - case 1 { - // blank the last byte which is the length - fslot := mul(div(fslot, 0x100), 0x100) - - if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) { - // unsuccess: - success := 0 - } - } - default { - // cb is a circuit breaker in the for loop since there's - // no said feature for inline assembly loops - // cb = 1 - don't breaker - // cb = 0 - break - let cb := 1 - - // get the keccak hash to get the contents of the array - mstore(0x0, _preBytes.slot) - let sc := keccak256(0x0, 0x20) - - let mc := add(_postBytes, 0x20) - let end := add(mc, mlength) - - // the next line is the loop condition: - // while(uint256(mc < end) + cb == 2) - for {} eq(add(lt(mc, end), cb), 2) { - sc := add(sc, 1) - mc := add(mc, 0x20) - } { - if iszero(eq(sload(sc), mload(mc))) { - // unsuccess: - success := 0 - cb := 0 - } - } - } - } - } - default { - // unsuccess: - success := 0 - } - } - - return success; - } -} \ No newline at end of file diff --git a/src/gscd/Getters.sol b/src/gscd/Getters.sol deleted file mode 100644 index 1038be5..0000000 --- a/src/gscd/Getters.sol +++ /dev/null @@ -1,71 +0,0 @@ -// contracts/Getters.sol -// SPDX-License-Identifier: Apache 2 - -pragma solidity ^0.8.0; - -import "./State.sol"; - -contract Getters is State { - function getGuardianSet(uint32 index) public view returns (IWormhole.GuardianSet memory) { - return _state.guardianSets[index]; - } - - function getCurrentGuardianSetIndex() public view returns (uint32) { - return _state.guardianSetIndex; - } - - function getGuardianSetExpiry() public view returns (uint32) { - return _state.guardianSetExpiry; - } - - function governanceActionIsConsumed(bytes32 hash) public view returns (bool) { - return _state.consumedGovernanceActions[hash]; - } - - function isInitialized(address impl) public view returns (bool) { - return _state.initializedImplementations[impl]; - } - - function chainId() public view returns (uint16) { - return _state.provider.chainId; - } - - function evmChainId() public view returns (uint256) { - return _state.evmChainId; - } - - function isFork() public view returns (bool) { - return evmChainId() != block.chainid; - } - - function governanceChainId() public view returns (uint16){ - return _state.provider.governanceChainId; - } - - function governanceContract() public view returns (bytes32){ - return _state.provider.governanceContract; - } - - function messageFee() public view returns (uint256) { - return _state.messageFee; - } - - function nextSequence(address emitter) public view returns (uint64) { - return _state.sequences[emitter]; - } - - function getGuardianSetHash(uint32 index) public view returns (bytes32) { - return _state.guardianSetHashes[index]; - } - - function getEncodedGuardianSet(uint32 index) public view returns (bytes memory encodedGuardianSet) { - IWormhole.GuardianSet memory guardianSet = getGuardianSet(index); - - // Encode the guardian set. - uint256 guardianCount = guardianSet.keys.length; - for (uint256 i = 0; i < guardianCount; ++i) - encodedGuardianSet = abi.encodePacked(encodedGuardianSet, guardianSet.keys[i]); - - encodedGuardianSet = abi.encodePacked(encodedGuardianSet, guardianSet.expirationTime); - } -} \ No newline at end of file diff --git a/src/gscd/Governance.sol b/src/gscd/Governance.sol deleted file mode 100644 index 2b0788f..0000000 --- a/src/gscd/Governance.sol +++ /dev/null @@ -1,227 +0,0 @@ -// contracts/Governance.sol -// SPDX-License-Identifier: Apache 2 - -pragma solidity ^0.8.0; - -import "wormhole-sdk/interfaces/IWormhole.sol"; -import "./GovernanceStructs.sol"; -import "./Messages.sol"; -import "./Setters.sol"; - -import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol"; - -/** - * @dev `Governance` defines a means to enacting changes to the core bridge contract, - * guardianSets, message fees, and transfer fees - */ -abstract contract Governance is GovernanceStructs, Messages, Setters, ERC1967Upgrade { - event ContractUpgraded(address indexed oldContract, address indexed newContract); - event GuardianSetAdded(uint32 indexed index); - - // "Core" (left padded) - bytes32 constant module = 0x00000000000000000000000000000000000000000000000000000000436f7265; - - /** - * @dev Upgrades a contract via Governance VAA/VM - */ - function submitContractUpgrade(bytes calldata _vm) public { - require(!isFork(), "invalid fork"); - - IWormhole.VM memory vm = parseVM(_vm); - - // Verify the VAA is valid before processing it - (bool isValid, string memory reason) = verifyGovernanceVM(vm); - require(isValid, reason); - - GovernanceStructs.ContractUpgrade memory upgrade = parseContractUpgrade(vm.payload); - - // Verify the VAA is for this module - require(upgrade.module == module, "Invalid Module"); - - // Verify the VAA is for this chain - require(upgrade.chain == chainId(), "Invalid Chain"); - - // Record the governance action as consumed - setGovernanceActionConsumed(vm.hash); - - // Upgrades the implementation to the new contract - upgradeImplementation(upgrade.newContract); - } - - /** - * @dev Sets a `messageFee` via Governance VAA/VM - */ - function submitSetMessageFee(bytes calldata _vm) public { - IWormhole.VM memory vm = parseVM(_vm); - - // Verify the VAA is valid before processing it - (bool isValid, string memory reason) = verifyGovernanceVM(vm); - require(isValid, reason); - - GovernanceStructs.SetMessageFee memory upgrade = parseSetMessageFee(vm.payload); - - // Verify the VAA is for this module - require(upgrade.module == module, "Invalid Module"); - - // Verify the VAA is for this chain - require(upgrade.chain == chainId() && !isFork(), "Invalid Chain"); - - // Record the governance action as consumed to prevent reentry - setGovernanceActionConsumed(vm.hash); - - // Updates the messageFee - setMessageFee(upgrade.messageFee); - } - - /** - * @dev Deploys a new `guardianSet` via Governance VAA/VM - */ - function submitNewGuardianSet(bytes calldata _vm) public { - IWormhole.VM memory vm = parseVM(_vm); - - // Verify the VAA is valid before processing it - (bool isValid, string memory reason) = verifyGovernanceVM(vm); - require(isValid, reason); - - GovernanceStructs.GuardianSetUpgrade memory upgrade = parseGuardianSetUpgrade(vm.payload); - - // Verify the VAA is for this module - require(upgrade.module == module, "invalid Module"); - - // Verify the VAA is for this chain - require((upgrade.chain == chainId() && !isFork()) || upgrade.chain == 0, "invalid Chain"); - - // Verify the Guardian Set keys are not empty, this guards - // against the accidential upgrade to an empty GuardianSet - require(upgrade.newGuardianSet.keys.length > 0, "new guardian set is empty"); - - // Verify that the index is incrementing via a predictable +1 pattern - require(upgrade.newGuardianSetIndex == getCurrentGuardianSetIndex() + 1, "index must increase in steps of 1"); - - // Record the governance action as consumed to prevent reentry - setGovernanceActionConsumed(vm.hash); - - // Trigger a time-based expiry of current guardianSet - expireGuardianSet(getCurrentGuardianSetIndex()); - - // Update the hash of the expiring guardian set - setGuardianSetHash(getCurrentGuardianSetIndex()); - - // Add the new guardianSet to guardianSets - storeGuardianSet(upgrade.newGuardianSet, upgrade.newGuardianSetIndex); - - // Store the guardian set hash - setGuardianSetHash(upgrade.newGuardianSetIndex); - - // Makes the new guardianSet effective - updateGuardianSetIndex(upgrade.newGuardianSetIndex); - } - - /** - * @dev Submits transfer fees to the recipient via Governance VAA/VM - */ - function submitTransferFees(bytes calldata _vm) public { - IWormhole.VM memory vm = parseVM(_vm); - - // Verify the VAA is valid before processing it - (bool isValid, string memory reason) = verifyGovernanceVM(vm); - require(isValid, reason); - - // Obtains the transfer from the VAA payload - GovernanceStructs.TransferFees memory transfer = parseTransferFees(vm.payload); - - // Verify the VAA is for this module - require(transfer.module == module, "invalid Module"); - - // Verify the VAA is for this chain - require((transfer.chain == chainId() && !isFork()) || transfer.chain == 0, "invalid Chain"); - - // Record the governance action as consumed to prevent reentry - setGovernanceActionConsumed(vm.hash); - - // Obtains the recipient address to be paid transfer fees - address payable recipient = payable(address(uint160(uint256(transfer.recipient)))); - - // Transfers transfer fees to the recipient - recipient.transfer(transfer.amount); - } - - /** - * @dev Updates the `chainId` and `evmChainId` on a forked chain via Governance VAA/VM - */ - function submitRecoverChainId(bytes calldata _vm) public { - require(isFork(), "not a fork"); - - IWormhole.VM memory vm = parseVM(_vm); - - // Verify the VAA is valid before processing it - (bool isValid, string memory reason) = verifyGovernanceVM(vm); - require(isValid, reason); - - GovernanceStructs.RecoverChainId memory rci = parseRecoverChainId(vm.payload); - - // Verify the VAA is for this module - require(rci.module == module, "invalid Module"); - - // Verify the VAA is for this chain - require(rci.evmChainId == block.chainid, "invalid EVM Chain"); - - // Record the governance action as consumed to prevent reentry - setGovernanceActionConsumed(vm.hash); - - // Update the chainIds - setEvmChainId(rci.evmChainId); - setChainId(rci.newChainId); - } - - /** - * @dev Upgrades the `currentImplementation` with a `newImplementation` - */ - function upgradeImplementation(address newImplementation) internal { - address currentImplementation = _getImplementation(); - - _upgradeTo(newImplementation); - - // Call initialize function of the new implementation - (bool success, bytes memory reason) = newImplementation.delegatecall(abi.encodeWithSignature("initialize()")); - - require(success, string(reason)); - - emit ContractUpgraded(currentImplementation, newImplementation); - } - - /** - * @dev Verifies a Governance VAA/VM is valid - */ - function verifyGovernanceVM(IWormhole.VM memory vm) internal view returns (bool, string memory){ - // Verify the VAA is valid - (bool isValid, string memory reason) = verifyVM(vm); - if (!isValid){ - return (false, reason); - } - - // only current guardianset can sign governance packets - if (vm.guardianSetIndex != getCurrentGuardianSetIndex()) { - return (false, "not signed by current guardian set"); - } - - // Verify the VAA is from the governance chain (Solana) - if (uint16(vm.emitterChainId) != governanceChainId()) { - return (false, "wrong governance chain"); - } - - // Verify the emitter contract is the governance contract (0x4 left padded) - if (vm.emitterAddress != governanceContract()) { - return (false, "wrong governance contract"); - } - - // Verify this governance action hasn't already been - // consumed to prevent reentry and replay - if (governanceActionIsConsumed(vm.hash)){ - return (false, "governance action already consumed"); - } - - // Confirm the governance VAA/VM is valid - return (true, ""); - } -} \ No newline at end of file diff --git a/src/gscd/GovernanceStructs.sol b/src/gscd/GovernanceStructs.sol deleted file mode 100644 index 25c266d..0000000 --- a/src/gscd/GovernanceStructs.sol +++ /dev/null @@ -1,183 +0,0 @@ -// contracts/GovernanceIWormhole.sol -// SPDX-License-Identifier: Apache 2 - -pragma solidity ^0.8.0; - -import "wormhole-sdk/interfaces/IWormhole.sol"; -import "./BytesLib.sol"; - -/** - * @dev `GovernanceStructs` defines a set of structs and parsing functions - * for minimal struct validation - */ -contract GovernanceStructs { - using BytesLib for bytes; - - enum GovernanceAction { - UpgradeContract, - UpgradeGuardianset - } - - struct ContractUpgrade { - bytes32 module; - uint8 action; - uint16 chain; - - address newContract; - } - - struct GuardianSetUpgrade { - bytes32 module; - uint8 action; - uint16 chain; - - IWormhole.GuardianSet newGuardianSet; - uint32 newGuardianSetIndex; - } - - struct SetMessageFee { - bytes32 module; - uint8 action; - uint16 chain; - - uint256 messageFee; - } - - struct TransferFees { - bytes32 module; - uint8 action; - uint16 chain; - - uint256 amount; - bytes32 recipient; - } - - struct RecoverChainId { - bytes32 module; - uint8 action; - - uint256 evmChainId; - uint16 newChainId; - } - - /// @dev Parse a contract upgrade (action 1) with minimal validation - function parseContractUpgrade(bytes memory encodedUpgrade) public pure returns (ContractUpgrade memory cu) { - uint index = 0; - - cu.module = encodedUpgrade.toBytes32(index); - index += 32; - - cu.action = encodedUpgrade.toUint8(index); - index += 1; - - require(cu.action == 1, "invalid ContractUpgrade"); - - cu.chain = encodedUpgrade.toUint16(index); - index += 2; - - cu.newContract = address(uint160(uint256(encodedUpgrade.toBytes32(index)))); - index += 32; - - require(encodedUpgrade.length == index, "invalid ContractUpgrade"); - } - - /// @dev Parse a guardianSet upgrade (action 2) with minimal validation - function parseGuardianSetUpgrade(bytes memory encodedUpgrade) public pure returns (GuardianSetUpgrade memory gsu) { - uint index = 0; - - gsu.module = encodedUpgrade.toBytes32(index); - index += 32; - - gsu.action = encodedUpgrade.toUint8(index); - index += 1; - - require(gsu.action == 2, "invalid GuardianSetUpgrade"); - - gsu.chain = encodedUpgrade.toUint16(index); - index += 2; - - gsu.newGuardianSetIndex = encodedUpgrade.toUint32(index); - index += 4; - - uint8 guardianLength = encodedUpgrade.toUint8(index); - index += 1; - - gsu.newGuardianSet = IWormhole.GuardianSet({ - keys : new address[](guardianLength), - expirationTime : 0 - }); - - for(uint i = 0; i < guardianLength; i++) { - gsu.newGuardianSet.keys[i] = encodedUpgrade.toAddress(index); - index += 20; - } - - require(encodedUpgrade.length == index, "invalid GuardianSetUpgrade"); - } - - /// @dev Parse a setMessageFee (action 3) with minimal validation - function parseSetMessageFee(bytes memory encodedSetMessageFee) public pure returns (SetMessageFee memory smf) { - uint index = 0; - - smf.module = encodedSetMessageFee.toBytes32(index); - index += 32; - - smf.action = encodedSetMessageFee.toUint8(index); - index += 1; - - require(smf.action == 3, "invalid SetMessageFee"); - - smf.chain = encodedSetMessageFee.toUint16(index); - index += 2; - - smf.messageFee = encodedSetMessageFee.toUint256(index); - index += 32; - - require(encodedSetMessageFee.length == index, "invalid SetMessageFee"); - } - - /// @dev Parse a transferFees (action 4) with minimal validation - function parseTransferFees(bytes memory encodedTransferFees) public pure returns (TransferFees memory tf) { - uint index = 0; - - tf.module = encodedTransferFees.toBytes32(index); - index += 32; - - tf.action = encodedTransferFees.toUint8(index); - index += 1; - - require(tf.action == 4, "invalid TransferFees"); - - tf.chain = encodedTransferFees.toUint16(index); - index += 2; - - tf.amount = encodedTransferFees.toUint256(index); - index += 32; - - tf.recipient = encodedTransferFees.toBytes32(index); - index += 32; - - require(encodedTransferFees.length == index, "invalid TransferFees"); - } - - /// @dev Parse a recoverChainId (action 5) with minimal validation - function parseRecoverChainId(bytes memory encodedRecoverChainId) public pure returns (RecoverChainId memory rci) { - uint index = 0; - - rci.module = encodedRecoverChainId.toBytes32(index); - index += 32; - - rci.action = encodedRecoverChainId.toUint8(index); - index += 1; - - require(rci.action == 5, "invalid RecoverChainId"); - - rci.evmChainId = encodedRecoverChainId.toUint256(index); - index += 32; - - rci.newChainId = encodedRecoverChainId.toUint16(index); - index += 2; - - require(encodedRecoverChainId.length == index, "invalid RecoverChainId"); - } -} \ No newline at end of file diff --git a/src/gscd/Implementation.sol b/src/gscd/Implementation.sol deleted file mode 100644 index 5bb98cf..0000000 --- a/src/gscd/Implementation.sol +++ /dev/null @@ -1,80 +0,0 @@ -// contracts/Implementation.sol -// SPDX-License-Identifier: Apache 2 - -pragma solidity ^0.8.0; -pragma experimental ABIEncoderV2; - -import "./Governance.sol"; - -import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol"; - -contract Implementation is Governance { - event LogMessagePublished(address indexed sender, uint64 sequence, uint32 nonce, bytes payload, uint8 consistencyLevel); - - // Publish a message to be attested by the Wormhole network - function publishMessage( - uint32 nonce, - bytes memory payload, - uint8 consistencyLevel - ) public payable returns (uint64 sequence) { - // check fee - require(msg.value == messageFee(), "invalid fee"); - - sequence = useSequence(msg.sender); - // emit log - emit LogMessagePublished(msg.sender, sequence, nonce, payload, consistencyLevel); - } - - function useSequence(address emitter) internal returns (uint64 sequence) { - sequence = nextSequence(emitter); - setNextSequence(emitter, sequence + 1); - } - - function initialize() initializer public virtual { - // this function needs to be exposed for an upgrade to pass - if (evmChainId() == 0) { - uint256 evmChainId; - uint16 chain = chainId(); - - // Wormhole chain ids explicitly enumerated - if (chain == 2) { evmChainId = 1; // ethereum - } else if (chain == 4) { evmChainId = 56; // bsc - } else if (chain == 5) { evmChainId = 137; // polygon - } else if (chain == 6) { evmChainId = 43114; // avalanche - } else if (chain == 7) { evmChainId = 42262; // oasis - } else if (chain == 9) { evmChainId = 1313161554; // aurora - } else if (chain == 10) { evmChainId = 250; // fantom - } else if (chain == 11) { evmChainId = 686; // karura - } else if (chain == 12) { evmChainId = 787; // acala - } else if (chain == 13) { evmChainId = 8217; // klaytn - } else if (chain == 14) { evmChainId = 42220; // celo - } else if (chain == 16) { evmChainId = 1284; // moonbeam - } else if (chain == 17) { evmChainId = 245022934; // neon - } else if (chain == 23) { evmChainId = 42161; // arbitrum - } else if (chain == 24) { evmChainId = 10; // optimism - } else if (chain == 25) { evmChainId = 100; // gnosis - } else { - revert("Unknown chain id."); - } - - setEvmChainId(evmChainId); - } - } - - modifier initializer() { - address implementation = ERC1967Upgrade._getImplementation(); - - require( - !isInitialized(implementation), - "already initialized" - ); - - setInitialized(implementation); - - _; - } - - fallback() external payable {revert("unsupported");} - - receive() external payable {revert("the Wormhole contract does not accept assets");} -} diff --git a/src/gscd/Messages.sol b/src/gscd/Messages.sol deleted file mode 100644 index 2b22d81..0000000 --- a/src/gscd/Messages.sol +++ /dev/null @@ -1,252 +0,0 @@ -// contracts/Messages.sol -// SPDX-License-Identifier: Apache 2 - -pragma solidity ^0.8.0; -pragma experimental ABIEncoderV2; - -import "./Getters.sol"; -import "wormhole-sdk/libraries/BytesParsing.sol"; -import "wormhole-sdk/Utils.sol"; - -contract Messages is Getters { - using BytesParsing for bytes; - using {BytesParsing.checkBound, BytesParsing.checkLength} for uint256; - - uint8 private constant ADDRESS_SIZE = 20; // in bytes - uint8 private constant EXPIRATION_TIME_SIZE = 4; // in bytes - - function parseAndVerifyVMOptimized( - bytes calldata encodedVM, - bytes calldata guardianSet, - uint32 guardianSetIndex - ) public view returns (IWormhole.VM memory vm, bool valid, string memory reason) { - // Verify that the specified guardian set is a valid. - bytes32 guardianSetHash = getGuardianSetHash(guardianSetIndex); - require( - guardianSetHash == keccak256(guardianSet) && guardianSetHash != bytes32(0), - "invalid guardian set" - ); - - vm = parseVM(encodedVM); - - // Verify that the VM is signed with the same guardian set that was specified. - require(vm.guardianSetIndex == guardianSetIndex, "mismatched guardian set index"); - - (valid, reason) = verifyVMInternal(vm, parseGuardianSet(guardianSet), false); - } - - function parseGuardianSet(bytes calldata guardianSetData) public pure returns (IWormhole.GuardianSet memory guardianSet) { - uint256 guardianSetDataLength = guardianSetData.length; - uint256 guardianCount = (guardianSetDataLength - EXPIRATION_TIME_SIZE) / ADDRESS_SIZE; - - guardianSet = IWormhole.GuardianSet({ - keys : new address[](guardianCount), - expirationTime : 0 - }); - - uint256 offset = 0; - for(uint256 i = 0; i < guardianCount;) { - (guardianSet.keys[i], offset) = guardianSetData.asAddressCdUnchecked(offset); - unchecked { - ++i; - } - } - - (guardianSet.expirationTime, offset) = guardianSetData.asUint32CdUnchecked(offset); - - require(guardianSetDataLength == offset, "invalid guardian set data length"); - } - - /// @dev parseAndVerifyVM serves to parse an encodedVM and wholy validate it for consumption - function parseAndVerifyVM(bytes calldata encodedVM) public view returns (IWormhole.VM memory vm, bool valid, string memory reason) { - vm = parseVM(encodedVM); - /// setting checkHash to false as we can trust the hash field in this case given that parseVM computes and then sets the hash field above - (valid, reason) = verifyVMInternal(vm, getGuardianSet(vm.guardianSetIndex), false); - } - - /** - * @dev `verifyVM` serves to validate an arbitrary vm against a valid Guardian set - * - it aims to make sure the VM is for a known guardianSet - * - it aims to ensure the guardianSet is not expired - * - it aims to ensure the VM has reached quorum - * - it aims to verify the signatures provided against the guardianSet - * - it aims to verify the hash field provided against the contents of the vm - */ - function verifyVM(IWormhole.VM memory vm) public view returns (bool valid, string memory reason) { - (valid, reason) = verifyVMInternal(vm, getGuardianSet(vm.guardianSetIndex), true); - } - - /** - * @dev `verifyVMInternal` serves to validate an arbitrary vm against a valid Guardian set - * if checkHash is set then the hash field of the vm is verified against the hash of its contents - * in the case that the vm is securely parsed and the hash field can be trusted, checkHash can be set to false - * as the check would be redundant - */ - function verifyVMInternal(IWormhole.VM memory vm, IWormhole.GuardianSet memory guardianSet, bool checkHash) internal view returns (bool valid, string memory reason) { - /** - * Verify that the hash field in the vm matches with the hash of the contents of the vm if checkHash is set - * WARNING: This hash check is critical to ensure that the vm.hash provided matches with the hash of the body. - * Without this check, it would not be safe to call verifyVM on it's own as vm.hash can be a valid signed hash - * but the body of the vm could be completely different from what was actually signed by the guardians - */ - if(checkHash){ - bytes memory body = abi.encodePacked( - vm.timestamp, - vm.nonce, - vm.emitterChainId, - vm.emitterAddress, - vm.sequence, - vm.consistencyLevel, - vm.payload - ); - - bytes32 vmHash = keccak256(abi.encodePacked(keccak256(body))); - - if(vmHash != vm.hash){ - return (false, "vm.hash doesn't match body"); - } - } - - uint256 guardianCount = guardianSet.keys.length; - - /** - * @dev Checks whether the guardianSet has zero keys - * WARNING: This keys check is critical to ensure the guardianSet has keys present AND to ensure - * that guardianSet key size doesn't fall to zero and negatively impact quorum assessment. If guardianSet - * key length is 0 and vm.signatures length is 0, this could compromise the integrity of both vm and - * signature verification. - */ - if(guardianCount == 0){ - return (false, "invalid guardian set"); - } - - /// @dev Checks if VM guardian set index matches the current index (unless the current set is expired). - if(vm.guardianSetIndex != getCurrentGuardianSetIndex() && guardianSet.expirationTime < block.timestamp){ - return (false, "guardian set has expired"); - } - - /** - * @dev We're using a fixed point number transformation with 1 decimal to deal with rounding. - * WARNING: This quorum check is critical to assessing whether we have enough Guardian signatures to validate a VM - * if making any changes to this, obtain additional peer review. If guardianSet key length is 0 and - * vm.signatures length is 0, this could compromise the integrity of both vm and signature verification. - */ - if (vm.signatures.length < quorum(guardianCount)){ - return (false, "no quorum"); - } - - /// @dev Verify the proposed vm.signatures against the guardianSet - (bool signaturesValid, string memory invalidReason) = verifySignatures(vm.hash, vm.signatures, guardianSet); - if(!signaturesValid){ - return (false, invalidReason); - } - - /// If we are here, we've validated the VM is a valid multi-sig that matches the guardianSet. - return (true, ""); - } - - - /** - * @dev verifySignatures serves to validate arbitrary sigatures against an arbitrary guardianSet - * - it intentionally does not solve for expectations within guardianSet (you should use verifyVM if you need these protections) - * - it intentioanlly does not solve for quorum (you should use verifyVM if you need these protections) - * - it intentionally returns true when signatures is an empty set (you should use verifyVM if you need these protections) - */ - function verifySignatures(bytes32 hash, IWormhole.Signature[] memory signatures, IWormhole.GuardianSet memory guardianSet) public pure returns (bool valid, string memory reason) { - uint8 lastIndex = 0; - uint256 sigCount = signatures.length; - uint256 guardianCount = guardianSet.keys.length; - for (uint i = 0; i < sigCount;) { - IWormhole.Signature memory sig = signatures[i]; - address signatory = ecrecover(hash, sig.v, sig.r, sig.s); - // ecrecover returns 0 for invalid signatures. We explicitly require valid signatures to avoid unexpected - // behaviour due to the default storage slot value also being 0. - require(signatory != address(0), "ecrecover failed with signature"); - - /// Ensure that provided signature indices are ascending only - require(i == 0 || sig.guardianIndex > lastIndex, "signature indices must be ascending"); - lastIndex = sig.guardianIndex; - - /// @dev Ensure that the provided signature index is within the - /// bounds of the guardianSet. This is implicitly checked by the array - /// index operation below, so this check is technically redundant. - /// However, reverting explicitly here ensures that a bug is not - /// introduced accidentally later due to the nontrivial storage - /// semantics of solidity. - require(sig.guardianIndex < guardianCount, "guardian index out of bounds"); - - /// Check to see if the signer of the signature does not match a specific Guardian key at the provided index - if(signatory != guardianSet.keys[sig.guardianIndex]){ - return (false, "VM signature invalid"); - } - - unchecked { ++i; } - } - - /// If we are here, we've validated that the provided signatures are valid for the provided guardianSet - return (true, ""); - } - - /** - * @dev parseVM serves to parse an encodedVM into a vm struct - * - it intentionally performs no validation functions, it simply parses raw into a struct - */ - function parseVM(bytes calldata encodedVM) public view virtual returns (IWormhole.VM memory vm) { unchecked { - uint256 offset = 0; - - // SECURITY: Note that currently the VM.version is not part of the hash - // and for reasons described below it cannot be made part of the hash. - // This means that this field's integrity is not protected and cannot be trusted. - // This is not a problem today since there is only one accepted version, but it - // could be a problem if we wanted to allow other versions in the future. - (vm.version, offset) = encodedVM.asUint8CdUnchecked(offset); - require(vm.version == 1, "VM version incompatible"); - - // Guardian set index. - (vm.guardianSetIndex, offset) = encodedVM.asUint32CdUnchecked(offset); - - // Parse sigs. - uint256 signersLen; - (signersLen, offset) = encodedVM.asUint8CdUnchecked(offset); - - vm.signatures = new IWormhole.Signature[](signersLen); - for (uint i = 0; i < signersLen; ++i) { - (vm.signatures[i].guardianIndex, offset) = encodedVM.asUint8CdUnchecked(offset); - (vm.signatures[i].r, offset) = encodedVM.asBytes32CdUnchecked(offset); - (vm.signatures[i].s, offset) = encodedVM.asBytes32CdUnchecked(offset); - (vm.signatures[i].v, offset) = encodedVM.asUint8CdUnchecked(offset); - vm.signatures[i].v += 27; - } - - /* - Hash the body - - SECURITY: Do not change the way the hash of a VM is computed! - Changing it could result into two different hashes for the same observation. - But xDapps rely on the hash of an observation for replay protection. - */ - offset.checkBound(encodedVM.length); - bytes calldata body; - (body, ) = encodedVM.sliceCdUnchecked(offset, encodedVM.length - offset); - vm.hash = keccak256Word(keccak256Cd(body)); - - // Parse the body - (vm.timestamp, offset) = encodedVM.asUint32CdUnchecked(offset); - (vm.nonce, offset) = encodedVM.asUint32CdUnchecked(offset); - (vm.emitterChainId, offset) = encodedVM.asUint16CdUnchecked(offset); - (vm.emitterAddress, offset) = encodedVM.asBytes32CdUnchecked(offset); - (vm.sequence, offset) = encodedVM.asUint64CdUnchecked(offset); - (vm.consistencyLevel, offset) = encodedVM.asUint8CdUnchecked(offset); - offset.checkBound(encodedVM.length); - (vm.payload, offset) = encodedVM.sliceCdUnchecked(offset, encodedVM.length - offset); - }} - - /** - * @dev quorum serves solely to determine the number of signatures required to acheive quorum - */ - function quorum(uint numGuardians) public pure virtual returns (uint numSignaturesRequiredForQuorum) { - // The max number of guardians is 255 - require(numGuardians < 256, "too many guardians"); - return ((numGuardians * 2) / 3) + 1; - } -} diff --git a/src/gscd/Setters.sol b/src/gscd/Setters.sol deleted file mode 100644 index 1ede1ad..0000000 --- a/src/gscd/Setters.sol +++ /dev/null @@ -1,80 +0,0 @@ -// contracts/Setters.sol -// SPDX-License-Identifier: Apache 2 - -pragma solidity ^0.8.0; - -import "./State.sol"; - -contract Setters is State { - function updateGuardianSetIndex(uint32 newIndex) internal { - _state.guardianSetIndex = newIndex; - } - - function expireGuardianSet(uint32 index) internal { - _state.guardianSets[index].expirationTime = uint32(block.timestamp) + 86400; - } - - function storeGuardianSet(IWormhole.GuardianSet memory set, uint32 index) internal { - uint setLength = set.keys.length; - for (uint i = 0; i < setLength;) { - require(set.keys[i] != address(0), "Invalid key"); - unchecked { ++i; } - } - _state.guardianSets[index] = set; - } - - function setInitialized(address implementatiom) internal { - _state.initializedImplementations[implementatiom] = true; - } - - function setGovernanceActionConsumed(bytes32 hash) internal { - _state.consumedGovernanceActions[hash] = true; - } - - function setChainId(uint16 chainId) internal { - _state.provider.chainId = chainId; - } - - function setGovernanceChainId(uint16 chainId) internal { - _state.provider.governanceChainId = chainId; - } - - function setGovernanceContract(bytes32 governanceContract) internal { - _state.provider.governanceContract = governanceContract; - } - - function setMessageFee(uint256 newFee) internal { - _state.messageFee = newFee; - } - - function setNextSequence(address emitter, uint64 sequence) internal { - _state.sequences[emitter] = sequence; - } - - function setEvmChainId(uint256 evmChainId) internal { - require(evmChainId == block.chainid, "invalid evmChainId"); - _state.evmChainId = evmChainId; - } - - function setGuardianSetHash(uint32 index) public { - // Fetch the guardian set at the specified index. - IWormhole.GuardianSet memory guardianSet = _state.guardianSets[index]; - - uint256 guardianCount = guardianSet.keys.length; - - // Only allow setting the hash for a valid guardian set index - // Governance guards against updating to an empty guardian set - require(guardianCount > 0, "non-existent guardian set"); - - bytes memory encodedGuardianSet; - for (uint256 i = 0; i < guardianCount;) { - encodedGuardianSet = abi.encodePacked(encodedGuardianSet, guardianSet.keys[i]); - unchecked { i += 1; } - } - - // Store the hash. - _state.guardianSetHashes[index] = keccak256( - abi.encodePacked(encodedGuardianSet, guardianSet.expirationTime) - ); - } -} \ No newline at end of file diff --git a/src/gscd/Setup.sol b/src/gscd/Setup.sol deleted file mode 100644 index 1193985..0000000 --- a/src/gscd/Setup.sol +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: Apache 2 - -pragma solidity ^0.8.0; - -import "./Governance.sol"; - -import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol"; - -contract Setup is Setters, ERC1967Upgrade { - function setup( - address implementation, - address[] memory initialGuardians, - uint16 chainId, - uint16 governanceChainId, - bytes32 governanceContract, - uint256 evmChainId - ) public { - require(initialGuardians.length > 0, "no guardians specified"); - - IWormhole.GuardianSet memory initialGuardianSet = IWormhole.GuardianSet({ - keys : initialGuardians, - expirationTime : 0 - }); - - storeGuardianSet(initialGuardianSet, 0); - setGuardianSetHash(0); - // initial guardian set index is 0, which is the default value of the storage slot anyways - - setChainId(chainId); - - setGovernanceChainId(governanceChainId); - setGovernanceContract(governanceContract); - - setEvmChainId(evmChainId); - - _upgradeTo(implementation); - - // See https://github.com/wormhole-foundation/wormhole/issues/1930 for - // why we set this here - setInitialized(implementation); - } -} diff --git a/src/gscd/State.sol b/src/gscd/State.sol deleted file mode 100644 index a90a85e..0000000 --- a/src/gscd/State.sol +++ /dev/null @@ -1,46 +0,0 @@ -// contracts/State.sol -// SPDX-License-Identifier: Apache 2 - -pragma solidity ^0.8.0; - -import "wormhole-sdk/interfaces/IWormhole.sol"; - -contract State { - struct Provider { - uint16 chainId; - uint16 governanceChainId; - bytes32 governanceContract; - } - - struct WormholeState { - Provider provider; - - // Mapping of guardian_set_index => guardian set - mapping(uint32 => IWormhole.GuardianSet) guardianSets; - - // Current active guardian set index - uint32 guardianSetIndex; - - // Period for which a guardian set stays active after it has been replaced - uint32 guardianSetExpiry; - - // Sequence numbers per emitter - mapping(address => uint64) sequences; - - // Mapping of consumed governance actions - mapping(bytes32 => bool) consumedGovernanceActions; - - // Mapping of initialized implementations - mapping(address => bool) initializedImplementations; - - uint256 messageFee; - - // EIP-155 Chain ID - uint256 evmChainId; - - // Guardian set hashes. - mapping(uint32 => bytes32) guardianSetHashes; - } - - WormholeState _state; -} diff --git a/src/gscd/Wormhole.sol b/src/gscd/Wormhole.sol deleted file mode 100644 index a091789..0000000 --- a/src/gscd/Wormhole.sol +++ /dev/null @@ -1,13 +0,0 @@ -// contracts/Wormhole.sol -// SPDX-License-Identifier: Apache 2 - -pragma solidity ^0.8.0; - -import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; - -contract Wormhole is ERC1967Proxy { - constructor (address setup, bytes memory initData) ERC1967Proxy( - setup, - initData - ) { } -} \ No newline at end of file From 003c13e07e48008cd0c57c65973b8f342f30c6ba Mon Sep 17 00:00:00 2001 From: Joshua Averett Date: Fri, 14 Feb 2025 07:29:47 -0800 Subject: [PATCH 02/53] Updates for the new spec --- src/GuardianSetCore.sol | 91 ------------------ src/GuardianSetVerification.sol | 160 ++++++++++++++++++++++++++++++++ src/RawDispatcher.sol | 13 --- src/ThresholdCore.sol | 85 ----------------- src/ThresholdVerification.sol | 123 ++++++++++++++++++++++++ src/VerificationV2.sol | 71 ++++++++------ 6 files changed, 328 insertions(+), 215 deletions(-) delete mode 100644 src/GuardianSetCore.sol create mode 100644 src/GuardianSetVerification.sol delete mode 100644 src/RawDispatcher.sol delete mode 100644 src/ThresholdCore.sol create mode 100644 src/ThresholdVerification.sol diff --git a/src/GuardianSetCore.sol b/src/GuardianSetCore.sol deleted file mode 100644 index cadae9a..0000000 --- a/src/GuardianSetCore.sol +++ /dev/null @@ -1,91 +0,0 @@ -// SPDX-License-Identifier: Apache 2 - -pragma solidity ^0.8.0; - -import "./ExtStore.sol"; -import "wormhole-sdk/interfaces/IWormhole.sol"; - -contract GuardianSetVerification is ExtStore { - IWormhole private _coreV1; - - // Guardian set expiration time is stored in an array mapped from index to expiration time - uint32[] private _guardianSetExpirationTime; - - // Get the guardian addresses for a given guardian set index using the ExtStore - function getGuardianSetInfo(uint32 index) public view returns (uint32 expirationTime, address[] memory guardianAddrs) { - expirationTime = _guardianSetExpirationTime[index]; - - bytes memory data = _extRead(index); - assembly ("memory-safe") { - guardianAddrs := data - mstore(guardianAddrs, div(mload(guardianAddrs), 32)) - } - } - - function getCurrentGuardianSetInfo() public view returns (uint32 index, address[] memory guardianAddrs) { - // NOTE: Expiration time array is one entry shorter than the guardian set index - // because the current guardian set is not included in the array(no expiration time set) - index = uint32(_guardianSetExpirationTime.length - 1); - uint32 expirationTime; - (expirationTime, guardianAddrs) = this.getGuardianSetInfo(index); - return (index, guardianAddrs); - } - - // Verify a guardian set VAA - function verifyGuardianSetVAA(IWormhole.VM memory vm) public view returns (bool) { - unchecked { - // Get the guardian set info - uint32 vmGuardianSetIndex = vm.guardianSetIndex; - (uint32 currentGuardianSetIndex, address[] memory guardianAddrs) = this.getCurrentGuardianSetInfo(); - uint sigCount = vm.signatures.length; - uint guardianCount = guardianAddrs.length; - - // Validate the guardian set - require(guardianCount != 0, "invalid guardian set"); - require(sigCount > guardianCount * 2 / 3, "no quorum"); - if (vmGuardianSetIndex != currentGuardianSetIndex) { - require( - _guardianSetExpirationTime[vmGuardianSetIndex] >= block.timestamp, - "guardian set has expired" - ); - } - - // Verify the signatures - int lastIndex = -1; - for (uint i = 0; i < sigCount; ++i) { - IWormhole.Signature memory sig = vm.signatures[i]; - uint idx = sig.guardianIndex; - require(int(idx) > lastIndex, "signature indices must be ascending"); - require(ecrecover(vm.hash, sig.v, sig.r, sig.s) == guardianAddrs[idx], "VM signature invalid"); - lastIndex = int(idx); - } - - require(lastIndex < int(guardianCount), "guardian index out of bounds"); // FIXME: Do we need this check? if idx > guardianAddrs.length, it will revert already - return true; - } - } - - function pullGuardianSets() public { - // For each guardian set after the current one - uint32 coreGuardianSetIndex = _coreV1.getCurrentGuardianSetIndex(); - for (uint32 i = uint32(_guardianSetExpirationTime.length); i <= coreGuardianSetIndex; ++i) { - // Pull the guardian set from the core V1 contract - IWormhole.GuardianSet memory guardians = _coreV1.getGuardianSet(i); - - // Convert the guardian set to a byte array - address[] memory keys = guardians.keys; - bytes memory data; - assembly ("memory-safe") { - data := keys - mstore(data, mul(mload(data), 32)) - } - - // Write the guardian set to the ExtStore and verify the index - uint32 extIndex = uint32(_extWrite(data)); - require(extIndex == i, "ext index mismatch"); - - // Set the expiration time for the guardian set - _guardianSetExpirationTime.push(guardians.expirationTime); - } - } -} diff --git a/src/GuardianSetVerification.sol b/src/GuardianSetVerification.sol new file mode 100644 index 0000000..cf5d424 --- /dev/null +++ b/src/GuardianSetVerification.sol @@ -0,0 +1,160 @@ +// SPDX-License-Identifier: Apache 2 + +pragma solidity ^0.8.0; + +import "./ExtStore.sol"; +import "wormhole-sdk/interfaces/IWormhole.sol"; +import "wormhole-sdk/libraries/VaaLib.sol"; +import "wormhole-sdk/libraries/BytesParsing.sol"; +import "wormhole-sdk/libraries/UncheckedIndexing.sol"; + +contract GuardianSetVerification is ExtStore { + using UncheckedIndexing for address[]; + using BytesParsing for bytes; + using VaaLib for bytes; + + error VerificationFailed(); + + IWormhole private _coreV1; + + // Guardian set expiration time is stored in an array mapped from index to expiration time + uint32[] private _guardianSetExpirationTime; + + // Get the guardian addresses for a given guardian set index using the ExtStore + function getGuardianSetInfo(uint32 index) public view returns (uint32 expirationTime, address[] memory guardianAddrs) { + expirationTime = _guardianSetExpirationTime[index]; + + bytes memory data = _extRead(index); + assembly ("memory-safe") { + guardianAddrs := data + mstore(guardianAddrs, div(mload(guardianAddrs), 32)) + } + } + + function getCurrentGuardianSetInfo() public view returns (uint32 index, address[] memory guardianAddrs) { + // NOTE: Expiration time array is one entry shorter than the guardian set index + // because the current guardian set is not included in the array(no expiration time set) + index = uint32(_guardianSetExpirationTime.length - 1); + uint32 expirationTime; + (expirationTime, guardianAddrs) = this.getGuardianSetInfo(index); + return (index, guardianAddrs); + } + + // Verify a guardian set VAA + function verifyGuardianSetVAA(bytes calldata encodedVaa) public view returns (VaaBody memory) { + unchecked { + uint offset = VaaLib.checkVaaVersionCd(encodedVaa); + uint32 guardianSetIndex; + (guardianSetIndex, offset) = encodedVaa.asUint32CdUnchecked(offset); + + // Get the guardian set + (, address[] memory guardians) = this.getGuardianSetInfo(guardianSetIndex); + + uint guardianCount = guardians.length; //optimization puts var on stack thus avoids mload + + uint signatureCount; + (signatureCount, offset) = encodedVaa.asUint8CdUnchecked(offset); + + // This works for empty guardian sets, because the quorum when there are no guardians is 1 + uint quorumCount = guardianCount * 2 / 3 + 1; + if (signatureCount < quorumCount) revert VerificationFailed(); + + uint envelopeOffset = offset + signatureCount * VaaLib.GUARDIAN_SIGNATURE_SIZE; + bytes32 vaaHash = encodedVaa.calcVaaDoubleHashCd(envelopeOffset); + + bool isFirstSignature = true; //optimization instead of always checking i == 0 + uint prevGuardianIndex; + for (uint i = 0; i < signatureCount; ++i) { + uint guardianIndex; bytes32 r; bytes32 s; uint8 v; + (guardianIndex, r, s, v, offset) = encodedVaa.decodeGuardianSignatureCdUnchecked(offset); + + if (_failsVerification( + vaaHash, + guardianIndex, + r, s, v, + guardians, + guardianCount, + prevGuardianIndex, + isFirstSignature + )) revert VerificationFailed(); + + prevGuardianIndex = guardianIndex; + isFirstSignature = false; + } + + // Decode the VAA body + VaaBody memory vaaBody; + ( + vaaBody.envelope.timestamp, + vaaBody.envelope.nonce, + vaaBody.envelope.emitterChainId, + vaaBody.envelope.emitterAddress, + vaaBody.envelope.sequence, + vaaBody.envelope.consistencyLevel, + vaaBody.payload + ) = encodedVaa.decodeVaaBodyCd(envelopeOffset); + + return vaaBody; + } + } + + function pullGuardianSets() public { + // For each guardian set after the current one + uint32 coreGuardianSetIndex = _coreV1.getCurrentGuardianSetIndex(); + for (uint32 i = uint32(_guardianSetExpirationTime.length); i <= coreGuardianSetIndex; ++i) { + // Pull the guardian set from the core V1 contract + IWormhole.GuardianSet memory guardians = _coreV1.getGuardianSet(i); + + // Convert the guardian set to a byte array + address[] memory keys = guardians.keys; + bytes memory data; + assembly ("memory-safe") { + data := keys + mstore(data, mul(mload(data), 32)) + } + + // Write the guardian set to the ExtStore and verify the index + uint32 extIndex = uint32(_extWrite(data)); + require(extIndex == i, "ext index mismatch"); + + // Set the expiration time for the guardian set + _guardianSetExpirationTime.push(guardians.expirationTime); + } + } + + function _failsVerification( + bytes32 vaaHash, + uint guardianIndex, + bytes32 r, bytes32 s, uint8 v, + address[] memory guardians, + uint guardianCount, + uint prevGuardianIndex, + bool isFirstSignature + ) private pure returns (bool) { + address signatory = ecrecover(vaaHash, v, r, s); + address guardian = guardians.readUnchecked(guardianIndex); + //check that: + // * the guardian indicies are in strictly ascending order (only after the first signature) + // this is itself an optimization to efficiently prevent having the same guardian signature + // included twice + // * that the guardian index is not out of bounds + // * that the signatory is the guardian + // + // the core bridge also includes a separate check that signatory is not the zero address + // but this is already covered by comparing that the signatory matches the guardian which + // [can never be the zero address](https://github.com/wormhole-foundation/wormhole/blob/1dbe8459b96e182932d0dd5ae4b6bbce6f48cb09/ethereum/contracts/Setters.sol#L20) + return eagerOr( + eagerOr( + !eagerOr(isFirstSignature, guardianIndex > prevGuardianIndex), + guardianIndex >= guardianCount + ), + signatory != guardian + ); + } + + function eagerOr(bool lhs, bool rhs) private pure returns (bool ret) { + assembly ("memory-safe") { + ret := or(lhs, rhs) + } + } +} diff --git a/src/RawDispatcher.sol b/src/RawDispatcher.sol deleted file mode 100644 index 8d4331e..0000000 --- a/src/RawDispatcher.sol +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -abstract contract RawDispatcher { - uint8 public constant VERSION = 1; - - function exec768() external payable returns (bytes memory) { return _exec(msg.data[4:]); } - function get1959() external view returns (bytes memory) { return _get(msg.data[4:]); } - - function _exec(bytes calldata data) internal virtual returns (bytes memory); - function _get(bytes calldata data) internal view virtual returns (bytes memory); -} diff --git a/src/ThresholdCore.sol b/src/ThresholdCore.sol deleted file mode 100644 index 3ef1cae..0000000 --- a/src/ThresholdCore.sol +++ /dev/null @@ -1,85 +0,0 @@ -// SPDX-License-Identifier: Apache 2 - -pragma solidity ^0.8.0; - -import "wormhole-sdk/libraries/BytesParsing.sol"; -import "wormhole-sdk/libraries/VaaLib.sol"; - -contract ThresholdVerification { - using BytesParsing for bytes; - using VaaLib for bytes; - - // Current threshold info is stord in a single slot - // Format: - // index (32 bits) - // address (160 bits) - uint256 private _currentThresholdInfo; - - // Past threshold info is stored in an array - // Format: - // expiration time (32 bits) - // address (160 bits) - uint256[] private _pastThresholdInfo; - - // Get the current threshold signature info - function getCurrentThresholdInfo() public view returns (uint32 index, address addr) { - return ( - uint32(_currentThresholdInfo), - address(uint160(_currentThresholdInfo >> 32)) - ); - } - - // Get the past threshold signature info - function getPastThresholdInfo(uint32 index) public view returns (uint32 expirationTime, address addr) { - uint256 info = _pastThresholdInfo[index]; - return ( - uint32(info), - address(uint160(info >> 32)) - ); - } - - // Verify a threshold signature VAA - function verifyThresholdVAA(IWormhole.VM memory vm) public view returns (bool) { - require(vm.version == 2, "VM version must be 2 for threshold signatures"); - require(vm.signatures.length == 1, "Signature count must be 1"); - - // Get the current threshold info - ( uint32 currentThresholdIndex, - address currentThresholdAddr - ) = this.getCurrentThresholdInfo(); - - // Get the threshold address - address thresholdAddr; - uint32 vmGuardianSetIndex = vm.guardianSetIndex; - if (vmGuardianSetIndex != currentThresholdIndex) { - // If the guardian set index is not the current threshold index, we need to get the past threshold info - // and validate that it is not expired - (uint32 expirationTime, address addr) = this.getPastThresholdInfo(vmGuardianSetIndex); - require(addr != address(0), "invalid guardian set"); - require(expirationTime >= block.timestamp, "guardian set has expired"); - thresholdAddr = addr; - } else { - // If the guardian set index is the current threshold index, we can use the current threshold info - thresholdAddr = currentThresholdAddr; - } - - // Verify the threshold signature - IWormhole.Signature memory sig = vm.signatures[0]; - require(ecrecover(vm.hash, sig.v, sig.r, sig.s) == thresholdAddr, "threshold signature invalid"); - return true; - } - - function _appendThresholdKey(uint32 newIndex, address newAddr, uint32 oldExpirationTime) internal { - // Get the current threshold info and verify the new index is sequential - (uint32 index, address currentAddr) = this.getCurrentThresholdInfo(); - require(newIndex == index + 1, "non-sequential index"); - - // Store the current threshold info in past threshold info - uint256 oldInfo = (uint256(uint160(currentAddr)) << 32) | uint256(oldExpirationTime); - _pastThresholdInfo.push(oldInfo); - - // Update the current threshold info - uint256 newInfo = (uint256(uint160(newAddr)) << 32) | uint256(newIndex); - _currentThresholdInfo = newInfo; - } -} diff --git a/src/ThresholdVerification.sol b/src/ThresholdVerification.sol new file mode 100644 index 0000000..21624cd --- /dev/null +++ b/src/ThresholdVerification.sol @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: Apache 2 + +pragma solidity ^0.8.0; + +import "wormhole-sdk/libraries/BytesParsing.sol"; +import "wormhole-sdk/libraries/VaaLib.sol"; + +contract ThresholdVerification { + using BytesParsing for bytes; + using VaaLib for bytes; + + error InvalidVaa(bytes encodedVaa); + error InvalidSignatureCount(uint8 count); + error VerificationFailed(); + + // Current threshold info is stord in a single slot + // Format: + // index (32 bits) + // address (160 bits) + uint256 private _currentThresholdInfo; + + // Past threshold info is stored in an array + // Format: + // expiration time (32 bits) + // address (160 bits) + uint256[] private _pastThresholdInfo; + + bytes32[][] private _shards; + + // Get the current threshold signature info + function getCurrentThresholdInfo() public view returns (uint32 index, address addr) { + return ( + uint32(_currentThresholdInfo), + address(uint160(_currentThresholdInfo >> 32)) + ); + } + + // Get the past threshold signature info + function getPastThresholdInfo(uint32 index) public view returns (uint32 expirationTime, address addr) { + uint256 info = _pastThresholdInfo[index]; + return ( + uint32(info), + address(uint160(info >> 32)) + ); + } + + // Verify a threshold signature VAA + function verifyThresholdVAA(bytes calldata encodedVaa) public view returns (VaaBody memory) { + unchecked { + // Check the VAA version + uint offset = 0; + uint8 version; + (version, offset) = encodedVaa.asUint8CdUnchecked(offset); + if (version != 2) revert VaaLib.InvalidVersion(version); + + // Decode the guardian set index + uint32 guardianSetIndex; + (guardianSetIndex, offset) = encodedVaa.asUint32CdUnchecked(offset); + + // Get the current threshold info + ( uint32 currentThresholdIndex, + address currentThresholdAddr + ) = this.getCurrentThresholdInfo(); + + // Get the threshold address + address thresholdAddr; + if (guardianSetIndex != currentThresholdIndex) { + // If the guardian set index is not the current threshold index, we need to get the past threshold info + // and validate that it is not expired + (uint32 expirationTime, address addr) = this.getPastThresholdInfo(guardianSetIndex); + require(addr != address(0), "invalid guardian set"); + require(expirationTime >= block.timestamp, "guardian set has expired"); + thresholdAddr = addr; + } else { + // If the guardian set index is the current threshold index, we can use the current threshold info + thresholdAddr = currentThresholdAddr; + } + + // Calculate the VAA hash + uint envelopeOffset = offset + VaaLib.GUARDIAN_SIGNATURE_SIZE; + bytes32 vaaHash = encodedVaa.calcVaaDoubleHashCd(envelopeOffset); + + // Decode the guardian signature + uint guardianIndex; bytes32 r; bytes32 s; uint8 v; + (guardianIndex, r, s, v, offset) = encodedVaa.decodeGuardianSignatureCdUnchecked(offset); + + // Verify the threshold signature + if (ecrecover(vaaHash, v, r, s) != thresholdAddr) revert VerificationFailed(); + + // Decode the VAA body + VaaBody memory vaaBody; + ( + vaaBody.envelope.timestamp, + vaaBody.envelope.nonce, + vaaBody.envelope.emitterChainId, + vaaBody.envelope.emitterAddress, + vaaBody.envelope.sequence, + vaaBody.envelope.consistencyLevel, + vaaBody.payload + ) = encodedVaa.decodeVaaBodyCd(envelopeOffset); + + return vaaBody; + } + } + + function _appendThresholdKey(uint32 newIndex, address newAddr, uint32 expirationDelaySeconds, bytes32[] memory shards) internal { + // Get the current threshold info and verify the new index is sequential + (uint32 index, address currentAddr) = this.getCurrentThresholdInfo(); + require(newIndex == index + 1, "non-sequential index"); + + // Store the current threshold info in past threshold info + uint32 expirationTime = uint32(block.timestamp) + expirationDelaySeconds; + uint256 oldInfo = (uint256(uint160(currentAddr)) << 32) | uint256(expirationTime); + _pastThresholdInfo.push(oldInfo); + + // Update the current threshold info + uint256 newInfo = (uint256(uint160(newAddr)) << 32) | uint256(newIndex); + _currentThresholdInfo = newInfo; + + // Store the shards + _shards.push(shards); + } +} diff --git a/src/VerificationV2.sol b/src/VerificationV2.sol index 47920ca..506b7e1 100644 --- a/src/VerificationV2.sol +++ b/src/VerificationV2.sol @@ -3,14 +3,18 @@ pragma solidity ^0.8.0; import "wormhole-sdk/libraries/BytesParsing.sol"; -import "./RawDispatcher.sol"; -import "./ThresholdCore.sol"; -import "./GuardianSetCore.sol"; +import "wormhole-sdk/RawDispatcher.sol"; +import "./ThresholdVerification.sol"; +import "./GuardianSetVerification.sol"; contract VerificationV2 is RawDispatcher, ThresholdVerification, GuardianSetVerification { using BytesParsing for bytes; using VaaLib for bytes; + error InvalidDispatchVersion(uint8 version); + error InvalidModule(bytes32 module); + error InvalidAction(uint8 action); + uint8 constant OP_GOVERNANCE = 0x00; uint8 constant OP_PULL_GUARDIAN_SETS = 0x01; @@ -21,41 +25,49 @@ contract VerificationV2 is RawDispatcher, ThresholdVerification, GuardianSetVeri uint8 constant OP_GUARDIAN_SET_GET = 0x24; bytes32 constant MODULE_VERIFICATION_V2 = bytes32(0x0000000000000000000000000000000000000000000000000000000000545353); + uint8 constant RAW_DISPATCH_PROTOCOL_VERSION = 0x01; uint8 constant ACTION_APPEND_THRESHOLD_KEY = 0x01; - function decodeAndVerifyVaa(bytes calldata encodedVaa) internal view returns (bool verified, IWormhole.VM memory vm) { - vm = encodedVaa.decodeVmStructCd(); - - if (vm.version == 2) { - verified = verifyThresholdVAA(vm); - } else if (vm.version == 1) { - verified = verifyGuardianSetVAA(vm); + function decodeAndVerifyVaa(bytes calldata encodedVaa) internal view returns (VaaBody memory) { + uint8 version = uint8(encodedVaa[0]); + if (version == 2) { + return verifyThresholdVAA(encodedVaa); + } else if (version == 1) { + return verifyGuardianSetVAA(encodedVaa); } else { - revert("Unsupported VAA version"); + revert VaaLib.InvalidVersion(version); } } - function decodeThresholdVaaPayload(bytes memory payload) internal pure returns ( + function decodeThresholdKeyUpdatePayload(bytes memory payload) internal pure returns ( bytes32 module, uint8 action, - uint8 newThresholdIndex, + uint32 newThresholdIndex, address newThresholdAddr, - uint32 oldExpirationTime + uint32 expirationDelaySeconds, + bytes32[] memory shards ) { uint offset = 0; (module, offset) = payload.asBytes32MemUnchecked(offset); (action, offset) = payload.asUint8MemUnchecked(offset); - (newThresholdIndex, offset) = payload.asUint8MemUnchecked(offset); + (newThresholdIndex, offset) = payload.asUint32MemUnchecked(offset); (newThresholdAddr, offset) = payload.asAddressMemUnchecked(offset); - (oldExpirationTime, offset) = payload.asUint32MemUnchecked(offset); + (expirationDelaySeconds, offset) = payload.asUint32MemUnchecked(offset); + + uint8 shardsLength; + (shardsLength, offset) = payload.asUint8MemUnchecked(offset); + shards = new bytes32[](shardsLength); + for (uint8 i = 0; i < shardsLength; i++) { + (shards[i], offset) = payload.asBytes32MemUnchecked(offset); + } } function _exec(bytes calldata data) internal override returns (bytes memory) { uint offset = 0; uint8 version; (version, offset) = data.asUint8CdUnchecked(offset); - require(version == RawDispatcher.VERSION, "invalid version"); + if (version != RAW_DISPATCH_PROTOCOL_VERSION) revert InvalidDispatchVersion(version); uint length = data.length; while (offset < length) { @@ -68,16 +80,23 @@ contract VerificationV2 is RawDispatcher, ThresholdVerification, GuardianSetVeri (dataLength, offset) = data.asUint32CdUnchecked(offset); bytes calldata encodedVaa = data[offset:offset + dataLength]; - (bool verified, IWormhole.VM memory vm) = decodeAndVerifyVaa(encodedVaa); - require(verified, "invalid threshold vaa"); + VaaBody memory vaaBody = decodeAndVerifyVaa(encodedVaa); // Decode the payload - (bytes32 module, uint8 action, uint8 newThresholdIndex, address newThresholdAddr, uint32 oldExpirationTime) = decodeThresholdVaaPayload(vm.payload); - require(module == MODULE_VERIFICATION_V2, "invalid module"); - require(action == ACTION_APPEND_THRESHOLD_KEY, "invalid action"); + ( + bytes32 module, + uint8 action, + uint32 newThresholdIndex, + address newThresholdAddr, + uint32 expirationDelaySeconds, + bytes32[] memory shards + ) = decodeThresholdKeyUpdatePayload(vaaBody.payload); + + if (module != MODULE_VERIFICATION_V2) revert InvalidModule(module); + if (action != ACTION_APPEND_THRESHOLD_KEY) revert InvalidAction(action); // Append the threshold key - _appendThresholdKey(newThresholdIndex, newThresholdAddr, oldExpirationTime); + _appendThresholdKey(newThresholdIndex, newThresholdAddr, expirationDelaySeconds, shards); } else if (op == OP_PULL_GUARDIAN_SETS) { pullGuardianSets(); } @@ -90,7 +109,7 @@ contract VerificationV2 is RawDispatcher, ThresholdVerification, GuardianSetVeri uint offset = 0; uint8 version; (version, offset) = data.asUint8CdUnchecked(offset); - require(version == RawDispatcher.VERSION, "invalid version"); + if (version != RAW_DISPATCH_PROTOCOL_VERSION) revert InvalidDispatchVersion(version); bytes memory result; uint length = data.length; @@ -104,8 +123,8 @@ contract VerificationV2 is RawDispatcher, ThresholdVerification, GuardianSetVeri (dataLength, offset) = data.asUint32CdUnchecked(offset); bytes calldata encodedVaa = data[offset:offset + dataLength]; - (bool verified,) = decodeAndVerifyVaa(encodedVaa); - result_entry = abi.encodePacked(verified); + VaaBody memory vaaBody = decodeAndVerifyVaa(encodedVaa); + result_entry = abi.encode(vaaBody); } else if (op == OP_THRESHOLD_GET_CURRENT) { (uint32 thresholdIndex, address thresholdAddr) = getCurrentThresholdInfo(); result_entry = abi.encodePacked(thresholdIndex, thresholdAddr); From 01a12c1a01549b5eabb7269d3d7d788d8454a21c Mon Sep 17 00:00:00 2001 From: Joshua Averett Date: Fri, 14 Feb 2025 11:57:33 -0800 Subject: [PATCH 03/53] Remove old tests and add common interface for verification errors --- src/GuardianSetVerification.sol | 5 +- src/ThresholdVerification.sol | 4 +- src/WormholeVerifier.sol | 7 ++ test/BackwardsOptimized.t.sol | 26 ------ test/GasTestBase.sol | 153 ------------------------------- test/GscdGasCost.t.sol | 61 ------------ test/ManualSigning.sol | 64 ------------- test/OriginalGasCost.t.sol | 12 --- test/SingleSigGasCost.t.sol | 32 ------- test/ThirteenSigGasCost.t.sol | 30 ------ test/ThresholdSigOptimized.t.sol | 26 ------ test/WithCoreBridgeLib.t.sol | 17 ---- 12 files changed, 11 insertions(+), 426 deletions(-) create mode 100644 src/WormholeVerifier.sol delete mode 100644 test/BackwardsOptimized.t.sol delete mode 100644 test/GasTestBase.sol delete mode 100644 test/GscdGasCost.t.sol delete mode 100644 test/ManualSigning.sol delete mode 100644 test/OriginalGasCost.t.sol delete mode 100644 test/SingleSigGasCost.t.sol delete mode 100644 test/ThirteenSigGasCost.t.sol delete mode 100644 test/ThresholdSigOptimized.t.sol delete mode 100644 test/WithCoreBridgeLib.t.sol diff --git a/src/GuardianSetVerification.sol b/src/GuardianSetVerification.sol index cf5d424..c0eee63 100644 --- a/src/GuardianSetVerification.sol +++ b/src/GuardianSetVerification.sol @@ -7,14 +7,13 @@ import "wormhole-sdk/interfaces/IWormhole.sol"; import "wormhole-sdk/libraries/VaaLib.sol"; import "wormhole-sdk/libraries/BytesParsing.sol"; import "wormhole-sdk/libraries/UncheckedIndexing.sol"; +import "./WormholeVerifier.sol"; -contract GuardianSetVerification is ExtStore { +contract GuardianSetVerification is ExtStore, WormholeVerifier { using UncheckedIndexing for address[]; using BytesParsing for bytes; using VaaLib for bytes; - error VerificationFailed(); - IWormhole private _coreV1; // Guardian set expiration time is stored in an array mapped from index to expiration time diff --git a/src/ThresholdVerification.sol b/src/ThresholdVerification.sol index 21624cd..1d2d060 100644 --- a/src/ThresholdVerification.sol +++ b/src/ThresholdVerification.sol @@ -4,14 +4,14 @@ pragma solidity ^0.8.0; import "wormhole-sdk/libraries/BytesParsing.sol"; import "wormhole-sdk/libraries/VaaLib.sol"; +import "./WormholeVerifier.sol"; -contract ThresholdVerification { +contract ThresholdVerification is WormholeVerifier { using BytesParsing for bytes; using VaaLib for bytes; error InvalidVaa(bytes encodedVaa); error InvalidSignatureCount(uint8 count); - error VerificationFailed(); // Current threshold info is stord in a single slot // Format: diff --git a/src/WormholeVerifier.sol b/src/WormholeVerifier.sol new file mode 100644 index 0000000..892bc2a --- /dev/null +++ b/src/WormholeVerifier.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: Apache 2 + +pragma solidity ^0.8.0; + +abstract contract WormholeVerifier { + error VerificationFailed(); +} diff --git a/test/BackwardsOptimized.t.sol b/test/BackwardsOptimized.t.sol deleted file mode 100644 index 2ea1fbc..0000000 --- a/test/BackwardsOptimized.t.sol +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: Apache 2 - -pragma solidity ^0.8.24; - -import { ManualSigning } from "./ManualSigning.sol"; - -import { BackwardsOptimized } from "core-bridge/BackwardsOptimized/BackwardsOptimized.sol"; -import "wormhole-sdk/proxy/Proxy.sol"; - -contract BackwardsOptimizedGasCost is ManualSigning { - BackwardsOptimized private _backwardsOptimized; - - function setUp() public { - _setUpManualSigning(wormhole.getGuardianSet(wormhole.getCurrentGuardianSetIndex()).keys.length); - _backwardsOptimized = BackwardsOptimized(payable(address(new Proxy( - address(new BackwardsOptimized()), - abi.encodePacked(_guardianAddrs) - )))); - } - - function testBackwardsOptimized() public view { - (, bool success, string memory reason) = - _backwardsOptimized.parseAndVerifyVM(_vaa); - assertTrue(success, reason); - } -} \ No newline at end of file diff --git a/test/GasTestBase.sol b/test/GasTestBase.sol deleted file mode 100644 index 14b8b3a..0000000 --- a/test/GasTestBase.sol +++ /dev/null @@ -1,153 +0,0 @@ -// SPDX-License-Identifier: Apache 2 - -pragma solidity ^0.8.24; - -import "forge-std/Test.sol"; - -import { IWormhole } from "wormhole-sdk/interfaces/IWormhole.sol"; -import { PublishedMessage } from "wormhole-sdk/testing/WormholeOverride.sol"; -import { VaaEnvelope } from "wormhole-sdk/libraries/VaaLib.sol"; - -contract GasTestBase is Test { - IWormhole public wormhole; - - constructor() { - wormhole = IWormhole(0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B); - } - - function _tbPublishedMsg() internal pure returns (PublishedMessage memory) { - return PublishedMessage( - VaaEnvelope({ - timestamp: 0x670acde5, - emitterChainId: 0x17, - emitterAddress: 0x0000000000000000000000000b2402144bb366a632d14b83f244d2e0e21bd39c, - sequence: 0x45e61, - nonce: 0x163d234e, - consistencyLevel: 1 - }), - _tbPayload() - ); - } - - //source tx hash from ethereum mainnet: - // 0xedd3ac96bc37961cce21a33fd50449dba257737c168006b40aa65496aaf92449 - function _tbOriginalVaa() internal pure returns (bytes memory) { - bytes[] memory signatures = new bytes[](13); - signatures[0] = abi.encodePacked( - bytes1(0x00), //index - bytes32(0xd7c298ee56b3860ca3597e2ce51568e029585cf3b4706d65df785f763b90f74e), //r - bytes32(0x77c5e774eb2dcc0422ed2bad6ec7490fbfb18f4621b4a267cb583ba195797951), //s - bytes1(0x01) //v - ); - signatures[1] = abi.encodePacked( - bytes1(0x01), - bytes32(0x0391f369925909f013921495ca4c8d769746a63fa237a1f282c6557a1e121887), - bytes32(0x5666d4f4cfcb88a9156a1684194d845ec94789f022a8dd38a99de7298bb5436b), - bytes1(0x00) - ); - signatures[2] = abi.encodePacked( - bytes1(0x02), - bytes32(0xe5ebcbe493fb9e5dddc5619956620efce4ac9735acad92954e24bebc6a639d94), - bytes32(0x2d4512f823b248644f752e423f5087eb588ce188af5c68c51f7f32b70e18b801), - bytes1(0x00) - ); - signatures[3] = abi.encodePacked( - bytes1(0x03), - bytes32(0x7f54c89b8f646f940780d0029c50068c25e34ba312ae5450fdda0450c25143ce), - bytes32(0x7e10a54368e7412a4970c6b6872aa1cc1f75e62a8640c3df43641163ccba7432), - bytes1(0x01) - ); - signatures[4] = abi.encodePacked( - bytes1(0x04), - bytes32(0x4a70b8d851b3c8dcdcd30328c8b7802fe91b4b8bf97871f9055fbc3fd7ccb7dc), - bytes32(0x7a561005acde4932268ad79f80367b323dbfbffc911f395b02c0061dc6f4f5aa), - bytes1(0x01) - ); - signatures[5] = abi.encodePacked( - bytes1(0x07), - bytes32(0x3df702e117ca425813e4ddb073419ff7964df5a58f487839ad6241a46c6c0d44), - bytes32(0x2d4fe29797ea43732b60b00b4c32b9bf0165e2fbe0092144ee3ce6f8dc2e9936), - bytes1(0x00) - ); - signatures[6] = abi.encodePacked( - bytes1(0x09), - bytes32(0xc048a769158bca4473eb492e2d79af32fdcc6a2615a0715f3c881d3f8cf0d897), - bytes32(0x1039aeff11502fa76c55e72330e1996f540ce8f8f5523dee6c8e4c196e5d786f), - bytes1(0x01) - ); - signatures[7] = abi.encodePacked( - bytes1(0x0a), - bytes32(0x26997af10642283328110a4719c57beffd0b46d395cd71aeb4fac3c008060091), - bytes32(0x711279551534826d1823160433001aea254939e85a474838c255aea60b10fc49), - bytes1(0x01) - ); - signatures[8] = abi.encodePacked( - bytes1(0x0c), - bytes32(0x5bcf6fda82527ac97320dc63312d82f22f267d3dae2b5acbf9e231219d84e2ee), - bytes32(0x0bcdbc83fed098d491de778addd92d15a2e857b55c425ea594c15dd7de2a53c8), - bytes1(0x00) - ); - signatures[9] = abi.encodePacked( - bytes1(0x0d), - bytes32(0x8f091ad26b04859876d5d691a3bb178d13d4374bc76af94e0afcff6a4c6a9515), - bytes32(0x08b962526b842a70559376d7dc7b55f28477d7528a40596270b1c45fe01b880d), - bytes1(0x01) - ); - signatures[10] = abi.encodePacked( - bytes1(0x0e), - bytes32(0x1f4bb6680b8ccc46adab4f4599a9d3affb77464ddb15a829cd6f231c53a80b59), - bytes32(0x675039aa6d5c6c21a9b8dbae6270c8cc75c61b61137b4e21871d86d4076865b1), - bytes1(0x00) - ); - signatures[11] = abi.encodePacked( - bytes1(0x10), - bytes32(0xbc34ccbf4c7199b996e6af44cddbbf900b7cb2e6c2a930b280cae7c67f6513f2), - bytes32(0x686b63ec6bbd3c2efdf46084972c8490bdef290119f0a19f40871389247dba0f), - bytes1(0x00) - ); - signatures[12] = abi.encodePacked( - bytes1(0x12), - bytes32(0x1be73670f42a9819a25a10aacad7a3b8082c411d824953ca655245c43987ee51), - bytes32(0x1f0b0853ee4994b0c8f65b5f4fc748a1e5bbe4cc33d1ae2423e0e9469a1e0955), - bytes1(0x00) - ); - - return abi.encodePacked( - uint8(1), //version - uint32(4), //guardian set - uint8(13), //signature count - signatures[0], - signatures[1], - signatures[2], - signatures[3], - signatures[4], - signatures[5], - signatures[6], - signatures[7], - signatures[8], - signatures[9], - signatures[10], - signatures[11], - signatures[12], - _tbVaaPayload() - ); - } - - function _tbVaaPayload() internal pure returns (bytes memory) { - return abi.encodePacked( - bytes32(0x670acde5163d234e00170000000000000000000000000b2402144bb366a632d1), - bytes19(0x4b83f244d2e0e21bd39c0000000000045e6101), - _tbPayload() - ); - } - - function _tbPayload() internal pure returns (bytes memory) { - return abi.encodePacked( - bytes32(0x01000000000000000000000000000000000000000000000000000197020a499f), - bytes32(0x3c000000000000000000000000ff836a5821e69066c87e268bc51b849fab9424), - bytes32(0x0c00020000000000000000000000000a6c69327d517568e6308f1e1cd2fd2b2b), - bytes32(0x3cd4bf0002000000000000000000000000000000000000000000000000000000), - bytes5 (0x0000000000) - ); - } -} diff --git a/test/GscdGasCost.t.sol b/test/GscdGasCost.t.sol deleted file mode 100644 index 882902f..0000000 --- a/test/GscdGasCost.t.sol +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: Apache 2 - -pragma solidity ^0.8.24; - -import { ManualSigning } from "./ManualSigning.sol"; - -import { Wormhole } from "core-bridge/gscd/Wormhole.sol"; -import { Setup } from "core-bridge/gscd/Setup.sol"; -import { Implementation } from "core-bridge/gscd/Implementation.sol"; - -contract GscdGasCost is ManualSigning { - - Implementation private _gscdCore; - bytes private _encodedGuardianSet; - - function setUp() public { - _setUpManualSigning(wormhole.getGuardianSet(wormhole.getCurrentGuardianSetIndex()).keys.length); - - _gscdCore = Implementation(payable(address(new Wormhole( - address(new Setup()), - abi.encodeWithSignature( - "setup(address,address[],uint16,uint16,bytes32,uint256)", - address(new Implementation()), - _guardianAddrs, - wormhole.chainId(), - wormhole.governanceChainId(), - wormhole.governanceContract(), - wormhole.evmChainId() - ) - )))); - - _encodedGuardianSet = abi.encodePacked( - _guardianAddrs[0], - _guardianAddrs[1], - _guardianAddrs[2], - _guardianAddrs[3], - _guardianAddrs[4], - _guardianAddrs[5], - _guardianAddrs[6], - _guardianAddrs[7], - _guardianAddrs[8], - _guardianAddrs[9], - _guardianAddrs[10], - _guardianAddrs[11], - _guardianAddrs[12], - _guardianAddrs[13], - _guardianAddrs[14], - _guardianAddrs[15], - _guardianAddrs[16], - _guardianAddrs[17], - _guardianAddrs[18], - uint32(0) - ); - } - - function testGscdOptimizations() public view { - (, bool success, string memory reason) = - _gscdCore.parseAndVerifyVMOptimized(_vaa, _encodedGuardianSet, 0); - assertTrue(success, reason); - } -} \ No newline at end of file diff --git a/test/ManualSigning.sol b/test/ManualSigning.sol deleted file mode 100644 index f808471..0000000 --- a/test/ManualSigning.sol +++ /dev/null @@ -1,64 +0,0 @@ -// SPDX-License-Identifier: Apache 2 - -pragma solidity ^0.8.24; - -import { IWormhole } from "wormhole-sdk/interfaces/IWormhole.sol"; -import { BytesParsing } from "wormhole-sdk/libraries/BytesParsing.sol"; -import { GuardianSignature, Vaa, VaaLib } from "wormhole-sdk/libraries/VaaLib.sol"; -import { - PublishedMessage, - AdvancedWormholeOverride -} from "wormhole-sdk/testing/WormholeOverride.sol"; - -import { GasTestBase } from "./GasTestBase.sol"; - -contract ManualSigning is GasTestBase { - using VaaLib for IWormhole.VM; - using BytesParsing for bytes; - - bytes internal _vaa; - address[] internal _guardianAddrs; - - uint256[] private _guardianPrivateKeys; - - //not nicely exported by forge, so we copy it here - function _makeAddrAndKey( - string memory name - ) private returns (address addr, uint256 privateKey) { - privateKey = uint256(keccak256(abi.encodePacked(name))); - addr = vm.addr(privateKey); - vm.label(addr, name); - } - - function _sign( - PublishedMessage memory pm, - bytes memory signingGuardianIndices - ) private view returns (Vaa memory vaa) { unchecked { - vaa.header.guardianSetIndex = 0; - bytes32 hash = VaaLib.calcDoubleHash(pm); - vaa.header.signatures = new GuardianSignature[](signingGuardianIndices.length); - for (uint i = 0; i < signingGuardianIndices.length; ++i) { - (uint8 gi, ) = signingGuardianIndices.asUint8Mem(i); - (vaa.header.signatures[i].v, vaa.header.signatures[i].r, vaa.header.signatures[i].s) = - vm.sign(_guardianPrivateKeys[uint(gi)], hash); - vaa.header.signatures[i].guardianIndex = gi; - } - vaa.envelope = pm.envelope; - vaa.payload = pm.payload; - }} - - function _setUpManualSigning(uint guardianCount) internal { - for (uint i = 0; i < guardianCount; ++i) { - (address ga, uint256 gpk) = _makeAddrAndKey(string.concat("guardian", vm.toString(i + 1))); - _guardianAddrs.push(ga); - _guardianPrivateKeys.push(gpk); - } - - uint quorum = guardianCount * 2 / 3 + 1; - bytes memory signingGuardianIndices = new bytes(0); - for (uint i = 0; i < quorum; ++i) - signingGuardianIndices = abi.encodePacked(signingGuardianIndices, uint8(i)); - - _vaa = _sign(_tbPublishedMsg(), signingGuardianIndices).encode(); - } -} diff --git a/test/OriginalGasCost.t.sol b/test/OriginalGasCost.t.sol deleted file mode 100644 index 5d211f2..0000000 --- a/test/OriginalGasCost.t.sol +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: Apache 2 - -pragma solidity ^0.8.24; - -import { GasTestBase } from "./GasTestBase.sol"; - -contract OriginalGasCost is GasTestBase { - function testOriginalGasCost() public view { - (, bool success, string memory reason) = wormhole.parseAndVerifyVM(_tbOriginalVaa()); - assertTrue(success, reason); - } -} diff --git a/test/SingleSigGasCost.t.sol b/test/SingleSigGasCost.t.sol deleted file mode 100644 index 940b711..0000000 --- a/test/SingleSigGasCost.t.sol +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: Apache 2 - -pragma solidity ^0.8.24; - -import { GasTestBase } from "./GasTestBase.sol"; - -import { IWormhole } from "wormhole-sdk/interfaces/IWormhole.sol"; -import { DEVNET_GUARDIAN_PRIVATE_KEY } from "wormhole-sdk/testing/Constants.sol"; -import { VaaLib } from "wormhole-sdk/libraries/VaaLib.sol"; -import { - PublishedMessage, - AdvancedWormholeOverride -} from "wormhole-sdk/testing/WormholeOverride.sol"; - -contract SingleSigGasCost is GasTestBase { - using AdvancedWormholeOverride for IWormhole; - using VaaLib for IWormhole.VM; - - bytes private _vaa; - - function setUp() public { - uint256[] memory guardianSecrets = new uint256[](1); - guardianSecrets[0] = DEVNET_GUARDIAN_PRIVATE_KEY; - wormhole.setUpOverride(guardianSecrets); - _vaa = wormhole.sign(_tbPublishedMsg()).encode(); - } - - function testGasSingleSig() public view { - (, bool success, string memory reason) = wormhole.parseAndVerifyVM(_vaa); - assertTrue(success, reason); - } -} diff --git a/test/ThirteenSigGasCost.t.sol b/test/ThirteenSigGasCost.t.sol deleted file mode 100644 index 5ebfe6a..0000000 --- a/test/ThirteenSigGasCost.t.sol +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: Apache 2 - -pragma solidity ^0.8.24; - -import { GasTestBase } from "./GasTestBase.sol"; - -import { IWormhole } from "wormhole-sdk/interfaces/IWormhole.sol"; -import "wormhole-sdk/libraries/VaaLib.sol"; -import { - PublishedMessage, - AdvancedWormholeOverride -} from "wormhole-sdk/testing/WormholeOverride.sol"; - -//this test should have the same gas cost as OriginalGasCost -contract ThirteenSigGasCost is GasTestBase { - using AdvancedWormholeOverride for IWormhole; - using VaaLib for IWormhole.VM; - - bytes private _vaa; - - function setUp() public { - wormhole.setUpOverride(); - _vaa = wormhole.sign(_tbPublishedMsg()).encode(); - } - - function testGasMultipleSig() public view { - (, bool success, string memory reason) = wormhole.parseAndVerifyVM(_vaa); - assertTrue(success, reason); - } -} diff --git a/test/ThresholdSigOptimized.t.sol b/test/ThresholdSigOptimized.t.sol deleted file mode 100644 index f676c03..0000000 --- a/test/ThresholdSigOptimized.t.sol +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: Apache 2 - -pragma solidity ^0.8.24; - -import { ManualSigning } from "./ManualSigning.sol"; - -import { ThresholdSigOptimized } from "core-bridge/ThresholdSigOptimized.sol"; -import "wormhole-sdk/proxy/Proxy.sol"; - -contract ThresholdSigOptimizedGasCost is ManualSigning { - ThresholdSigOptimized private _thresholdSigOptimized; - - function setUp() public { - _setUpManualSigning(1); - _thresholdSigOptimized = new ThresholdSigOptimized(); - - _thresholdSigOptimized = ThresholdSigOptimized(payable(address(new Proxy( - address(new ThresholdSigOptimized()), - abi.encode(_guardianAddrs[0]) - )))); - } - - function testThresholdSigOptimizations() public view { - _thresholdSigOptimized.parseAndVerifyVMThreshold(_vaa); - } -} \ No newline at end of file diff --git a/test/WithCoreBridgeLib.t.sol b/test/WithCoreBridgeLib.t.sol deleted file mode 100644 index ee76fd3..0000000 --- a/test/WithCoreBridgeLib.t.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: Apache 2 - -pragma solidity ^0.8.24; - -import { GasTestBase } from "./GasTestBase.sol"; - -import { CoreBridgeLib } from "wormhole-sdk/libraries/CoreBridge.sol"; - -contract WithCoreBridgeLib is GasTestBase { - function testWithCoreBridgeLib() public view { - this.withCoreBridgeLibOptimized(_tbOriginalVaa()); - } - - function withCoreBridgeLibOptimized(bytes calldata encodedVaa) external view { - CoreBridgeLib.decodeAndVerifyVaaCd(address(wormhole), encodedVaa); - } -} \ No newline at end of file From 32d8de3872897e637ea715369793957ed0a55a49 Mon Sep 17 00:00:00 2001 From: Joshua Averett Date: Fri, 7 Mar 2025 21:56:07 -0800 Subject: [PATCH 04/53] First round of updates --- .gitmodules | 4 + src/GuardianSetVerification.sol | 184 ++++++++++++++++++++------------ src/ThresholdVerification.sol | 55 +++++----- src/VerificationV2.sol | 152 ++++++++++++++++---------- 4 files changed, 243 insertions(+), 152 deletions(-) create mode 100644 .gitmodules diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..ff152ca --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "lib/wormhole-solidity-sdk"] + path = lib/wormhole-solidity-sdk + url = https://github.com/wormhole-foundation/wormhole-solidity-sdk.git + branch = sr-refactor diff --git a/src/GuardianSetVerification.sol b/src/GuardianSetVerification.sol index c0eee63..90350b5 100644 --- a/src/GuardianSetVerification.sol +++ b/src/GuardianSetVerification.sol @@ -3,27 +3,43 @@ pragma solidity ^0.8.0; import "./ExtStore.sol"; -import "wormhole-sdk/interfaces/IWormhole.sol"; -import "wormhole-sdk/libraries/VaaLib.sol"; -import "wormhole-sdk/libraries/BytesParsing.sol"; -import "wormhole-sdk/libraries/UncheckedIndexing.sol"; +import {ICoreBridge, GuardianSet} from "wormhole-sdk/interfaces/ICoreBridge.sol"; +import {eagerOr} from "wormhole-sdk/Utils.sol"; +import {BytesParsing} from "wormhole-sdk/libraries/BytesParsing.sol"; +import {VaaLib} from "wormhole-sdk/libraries/VaaLib.sol"; + +import {CoreBridgeLib} from "wormhole-sdk/libraries/CoreBridge.sol"; +import {UncheckedIndexing} from "wormhole-sdk/libraries/UncheckedIndexing.sol"; import "./WormholeVerifier.sol"; contract GuardianSetVerification is ExtStore, WormholeVerifier { - using UncheckedIndexing for address[]; using BytesParsing for bytes; using VaaLib for bytes; + using UncheckedIndexing for address[]; - IWormhole private _coreV1; + ICoreBridge private _coreV1; // Guardian set expiration time is stored in an array mapped from index to expiration time uint32[] private _guardianSetExpirationTime; + constructor( + address coreV1, + uint pullLimit + ) { + _coreV1 = ICoreBridge(coreV1); + pullGuardianSets(pullLimit); + } + // Get the guardian addresses for a given guardian set index using the ExtStore + // On an invalid index, the function will panic function getGuardianSetInfo(uint32 index) public view returns (uint32 expirationTime, address[] memory guardianAddrs) { expirationTime = _guardianSetExpirationTime[index]; + // Read the guardian set data from the ExtStore bytes memory data = _extRead(index); + + // Convert the guardian set data to an array of addresses + // NOTE: The `data` array is temporary and is invalid after this block assembly ("memory-safe") { guardianAddrs := data mstore(guardianAddrs, div(mload(guardianAddrs), 32)) @@ -31,16 +47,22 @@ contract GuardianSetVerification is ExtStore, WormholeVerifier { } function getCurrentGuardianSetInfo() public view returns (uint32 index, address[] memory guardianAddrs) { - // NOTE: Expiration time array is one entry shorter than the guardian set index - // because the current guardian set is not included in the array(no expiration time set) - index = uint32(_guardianSetExpirationTime.length - 1); - uint32 expirationTime; - (expirationTime, guardianAddrs) = this.getGuardianSetInfo(index); - return (index, guardianAddrs); + unchecked { + index = uint32(_guardianSetExpirationTime.length - 1); + (, guardianAddrs) = this.getGuardianSetInfo(index); + } } // Verify a guardian set VAA - function verifyGuardianSetVAA(bytes calldata encodedVaa) public view returns (VaaBody memory) { + function verifyGuardianSetVAA(bytes calldata encodedVaa) public view returns ( + uint32 timestamp, + uint32 nonce, + uint16 emitterChainId, + bytes32 emitterAddress, + uint64 sequence, + uint8 consistencyLevel, + bytes calldata payload + ) { unchecked { uint offset = VaaLib.checkVaaVersionCd(encodedVaa); uint32 guardianSetIndex; @@ -49,24 +71,34 @@ contract GuardianSetVerification is ExtStore, WormholeVerifier { // Get the guardian set (, address[] memory guardians) = this.getGuardianSetInfo(guardianSetIndex); - uint guardianCount = guardians.length; //optimization puts var on stack thus avoids mload + // Get the number of guardians + // NOTE: Optimization puts var on stack thus avoids mload + uint guardianCount = guardians.length; + // Get the number of signatures uint signatureCount; (signatureCount, offset) = encodedVaa.asUint8CdUnchecked(offset); - // This works for empty guardian sets, because the quorum when there are no guardians is 1 - uint quorumCount = guardianCount * 2 / 3 + 1; + // Validate the number of signatures + // NOTE: This works for empty guardian sets, because the quorum when there are no guardians is 1 + uint quorumCount = CoreBridgeLib.minSigsForQuorum(guardianCount); if (signatureCount < quorumCount) revert VerificationFailed(); + // Calculate envelope offset and VAA hash uint envelopeOffset = offset + signatureCount * VaaLib.GUARDIAN_SIGNATURE_SIZE; bytes32 vaaHash = encodedVaa.calcVaaDoubleHashCd(envelopeOffset); - bool isFirstSignature = true; //optimization instead of always checking i == 0 + // Verify the signatures + // NOTE: Optimization instead of always checking i == 0 + bool isFirstSignature = true; uint prevGuardianIndex; + for (uint i = 0; i < signatureCount; ++i) { + // Decode the guardian index, r, s, and v uint guardianIndex; bytes32 r; bytes32 s; uint8 v; (guardianIndex, r, s, v, offset) = encodedVaa.decodeGuardianSignatureCdUnchecked(offset); + // Verify the signature if (_failsVerification( vaaHash, guardianIndex, @@ -82,45 +114,60 @@ contract GuardianSetVerification is ExtStore, WormholeVerifier { } // Decode the VAA body - VaaBody memory vaaBody; - ( - vaaBody.envelope.timestamp, - vaaBody.envelope.nonce, - vaaBody.envelope.emitterChainId, - vaaBody.envelope.emitterAddress, - vaaBody.envelope.sequence, - vaaBody.envelope.consistencyLevel, - vaaBody.payload - ) = encodedVaa.decodeVaaBodyCd(envelopeOffset); - - return vaaBody; + return encodedVaa.decodeVaaBodyCd(envelopeOffset); } } - function pullGuardianSets() public { - // For each guardian set after the current one - uint32 coreGuardianSetIndex = _coreV1.getCurrentGuardianSetIndex(); - for (uint32 i = uint32(_guardianSetExpirationTime.length); i <= coreGuardianSetIndex; ++i) { - // Pull the guardian set from the core V1 contract - IWormhole.GuardianSet memory guardians = _coreV1.getGuardianSet(i); - - // Convert the guardian set to a byte array - address[] memory keys = guardians.keys; - bytes memory data; - assembly ("memory-safe") { - data := keys - mstore(data, mul(mload(data), 32)) + function pullGuardianSets(uint limit) public { + unchecked { + // Get the guardian set lengths for the bridge and the local contract + uint currentGuardianSetLength = _coreV1.getCurrentGuardianSetIndex() + 1; + uint oldGuardianSetLength = _guardianSetExpirationTime.length; + + // If we have already pulled all the guardian sets, return + if (currentGuardianSetLength == oldGuardianSetLength) return; + + // Check if we need to update the current guardian set + if (oldGuardianSetLength > 0) { + // Pull and write the current guardian set expiration time + uint updateIndex = oldGuardianSetLength - 1; + (, uint32 expirationTime) = _pullGuardianSet(uint32(updateIndex)); + _guardianSetExpirationTime[updateIndex] = expirationTime; } - // Write the guardian set to the ExtStore and verify the index - uint32 extIndex = uint32(_extWrite(data)); - require(extIndex == i, "ext index mismatch"); + // Calculate the upper bound of the guardian sets to pull + uint upper = (limit == 0 || currentGuardianSetLength - oldGuardianSetLength < limit) ? currentGuardianSetLength : oldGuardianSetLength + limit; - // Set the expiration time for the guardian set - _guardianSetExpirationTime.push(guardians.expirationTime); + // Pull and append the guardian sets + for (uint i = oldGuardianSetLength; i < upper; i++) { + // Pull the guardian set, write the expiration time, and append the guardian set data to the ExtStore + (bytes memory data, uint32 expirationTime) = _pullGuardianSet(uint32(i)); + _guardianSetExpirationTime.push(expirationTime); + _extWrite(data); + } } } + function _pullGuardianSet(uint32 index) private view returns ( + bytes memory data, + uint32 expirationTime + ) { + // Get the guardian set from the core bridge + GuardianSet memory guardians = _coreV1.getGuardianSet(index); + + // Convert the guardian set to a byte array + // Result is stored in `data` + // NOTE: The `keys` array is temporary and is invalid after this block + address[] memory keys = guardians.keys; + assembly ("memory-safe") { + data := keys + mstore(data, mul(mload(data), 32)) + } + + // Return the expiration time + return (data, guardians.expirationTime); + } + function _failsVerification( bytes32 vaaHash, uint guardianIndex, @@ -131,29 +178,24 @@ contract GuardianSetVerification is ExtStore, WormholeVerifier { bool isFirstSignature ) private pure returns (bool) { address signatory = ecrecover(vaaHash, v, r, s); - address guardian = guardians.readUnchecked(guardianIndex); - //check that: - // * the guardian indicies are in strictly ascending order (only after the first signature) - // this is itself an optimization to efficiently prevent having the same guardian signature - // included twice - // * that the guardian index is not out of bounds - // * that the signatory is the guardian - // - // the core bridge also includes a separate check that signatory is not the zero address - // but this is already covered by comparing that the signatory matches the guardian which - // [can never be the zero address](https://github.com/wormhole-foundation/wormhole/blob/1dbe8459b96e182932d0dd5ae4b6bbce6f48cb09/ethereum/contracts/Setters.sol#L20) - return eagerOr( - eagerOr( - !eagerOr(isFirstSignature, guardianIndex > prevGuardianIndex), - guardianIndex >= guardianCount - ), - signatory != guardian - ); - } - - function eagerOr(bool lhs, bool rhs) private pure returns (bool ret) { - assembly ("memory-safe") { - ret := or(lhs, rhs) - } + address guardian = guardians.readUnchecked(guardianIndex); + + // Check that: + // * the guardian indicies are in strictly ascending order (only after the first signature) + // this is itself an optimization to efficiently prevent having the same guardian signature + // included twice + // * that the guardian index is not out of bounds + // * that the signatory is the guardian + // + // The core bridge also includes a separate check that signatory is not the zero address + // but this is already covered by comparing that the signatory matches the guardian which + // [can never be the zero address](https://github.com/wormhole-foundation/wormhole/blob/1dbe8459b96e182932d0dd5ae4b6bbce6f48cb09/ethereum/contracts/Setters.sol#L20) + return eagerOr( + eagerOr( + !eagerOr(isFirstSignature, guardianIndex > prevGuardianIndex), + guardianIndex >= guardianCount + ), + signatory != guardian + ); } } diff --git a/src/ThresholdVerification.sol b/src/ThresholdVerification.sol index 1d2d060..d79e0bc 100644 --- a/src/ThresholdVerification.sol +++ b/src/ThresholdVerification.sol @@ -12,11 +12,13 @@ contract ThresholdVerification is WormholeVerifier { error InvalidVaa(bytes encodedVaa); error InvalidSignatureCount(uint8 count); + error InvalidIndex(); // Current threshold info is stord in a single slot // Format: // index (32 bits) // address (160 bits) + // TODO: Extract this into its own functions uint256 private _currentThresholdInfo; // Past threshold info is stored in an array @@ -45,7 +47,15 @@ contract ThresholdVerification is WormholeVerifier { } // Verify a threshold signature VAA - function verifyThresholdVAA(bytes calldata encodedVaa) public view returns (VaaBody memory) { + function verifyThresholdVAA(bytes calldata encodedVaa) public view returns ( + uint32 timestamp, + uint32 nonce, + uint16 emitterChainId, + bytes32 emitterAddress, + uint64 sequence, + uint8 consistencyLevel, + bytes calldata payload + ) { unchecked { // Check the VAA version uint offset = 0; @@ -86,38 +96,29 @@ contract ThresholdVerification is WormholeVerifier { // Verify the threshold signature if (ecrecover(vaaHash, v, r, s) != thresholdAddr) revert VerificationFailed(); - - // Decode the VAA body - VaaBody memory vaaBody; - ( - vaaBody.envelope.timestamp, - vaaBody.envelope.nonce, - vaaBody.envelope.emitterChainId, - vaaBody.envelope.emitterAddress, - vaaBody.envelope.sequence, - vaaBody.envelope.consistencyLevel, - vaaBody.payload - ) = encodedVaa.decodeVaaBodyCd(envelopeOffset); - - return vaaBody; + + // Decode the VAA body and return it + return encodedVaa.decodeVaaBodyCd(envelopeOffset); } } function _appendThresholdKey(uint32 newIndex, address newAddr, uint32 expirationDelaySeconds, bytes32[] memory shards) internal { - // Get the current threshold info and verify the new index is sequential - (uint32 index, address currentAddr) = this.getCurrentThresholdInfo(); - require(newIndex == index + 1, "non-sequential index"); + unchecked { + // Get the current threshold info and verify the new index is sequential + (uint32 index, address currentAddr) = this.getCurrentThresholdInfo(); + if (newIndex != index + 1) revert InvalidIndex(); - // Store the current threshold info in past threshold info - uint32 expirationTime = uint32(block.timestamp) + expirationDelaySeconds; - uint256 oldInfo = (uint256(uint160(currentAddr)) << 32) | uint256(expirationTime); - _pastThresholdInfo.push(oldInfo); + // Store the current threshold info in past threshold info + uint32 expirationTime = uint32(block.timestamp) + expirationDelaySeconds; + uint256 oldInfo = (uint256(uint160(currentAddr)) << 32) | uint256(expirationTime); + _pastThresholdInfo.push(oldInfo); - // Update the current threshold info - uint256 newInfo = (uint256(uint160(newAddr)) << 32) | uint256(newIndex); - _currentThresholdInfo = newInfo; + // Update the current threshold info + uint256 newInfo = (uint256(uint160(newAddr)) << 32) | uint256(newIndex); + _currentThresholdInfo = newInfo; - // Store the shards - _shards.push(shards); + // Store the shards + _shards.push(shards); + } } } diff --git a/src/VerificationV2.sol b/src/VerificationV2.sol index 506b7e1..adc894d 100644 --- a/src/VerificationV2.sol +++ b/src/VerificationV2.sol @@ -2,35 +2,54 @@ pragma solidity ^0.8.0; -import "wormhole-sdk/libraries/BytesParsing.sol"; -import "wormhole-sdk/RawDispatcher.sol"; -import "./ThresholdVerification.sol"; -import "./GuardianSetVerification.sol"; +import {BytesParsing} from "wormhole-sdk/libraries/BytesParsing.sol"; +import {VaaLib} from "wormhole-sdk/libraries/VaaLib.sol"; +import {RawDispatcher} from "wormhole-sdk/RawDispatcher.sol"; +import {ThresholdVerification} from "./ThresholdVerification.sol"; +import {GuardianSetVerification} from "./GuardianSetVerification.sol"; + +// Raw dispatch operation IDs for exec +uint8 constant OP_GOVERNANCE = 0x00; +uint8 constant OP_PULL_GUARDIAN_SETS = 0x01; + +// Raw dispatch operation IDs for get +uint8 constant OP_VERIFY = 0x20; +uint8 constant OP_THRESHOLD_GET_CURRENT = 0x21; +uint8 constant OP_THRESHOLD_GET = 0x22; +uint8 constant OP_GUARDIAN_SET_GET_CURRENT = 0x23; +uint8 constant OP_GUARDIAN_SET_GET = 0x24; + +// Module ID for the VerificationV2 contract, ASCII "TSS" +bytes32 constant MODULE_VERIFICATION_V2 = bytes32(0x0000000000000000000000000000000000000000000000000000000000545353); + +// Action ID for appending a threshold key +uint8 constant ACTION_APPEND_THRESHOLD_KEY = 0x01; contract VerificationV2 is RawDispatcher, ThresholdVerification, GuardianSetVerification { using BytesParsing for bytes; using VaaLib for bytes; + using {BytesParsing.checkLength} for uint; error InvalidDispatchVersion(uint8 version); error InvalidModule(bytes32 module); error InvalidAction(uint8 action); - - uint8 constant OP_GOVERNANCE = 0x00; - uint8 constant OP_PULL_GUARDIAN_SETS = 0x01; - - uint8 constant OP_VERIFY = 0x20; - uint8 constant OP_THRESHOLD_GET_CURRENT = 0x21; - uint8 constant OP_THRESHOLD_GET = 0x22; - uint8 constant OP_GUARDIAN_SET_GET_CURRENT = 0x23; - uint8 constant OP_GUARDIAN_SET_GET = 0x24; - - bytes32 constant MODULE_VERIFICATION_V2 = bytes32(0x0000000000000000000000000000000000000000000000000000000000545353); - uint8 constant RAW_DISPATCH_PROTOCOL_VERSION = 0x01; - - uint8 constant ACTION_APPEND_THRESHOLD_KEY = 0x01; - - function decodeAndVerifyVaa(bytes calldata encodedVaa) internal view returns (VaaBody memory) { - uint8 version = uint8(encodedVaa[0]); + error InvalidValue(); + + constructor( + address coreV1, + uint pullLimit + ) ThresholdVerification() GuardianSetVerification(coreV1, pullLimit) {} + + function _decodeAndVerifyVaa(bytes calldata encodedVaa) internal view returns ( + uint32 timestamp, + uint32 nonce, + uint16 emitterChainId, + bytes32 emitterAddress, + uint64 sequence, + uint8 consistencyLevel, + bytes calldata payload + ) { + (uint8 version, ) = encodedVaa.asUint8CdUnchecked(0); if (version == 2) { return verifyThresholdVAA(encodedVaa); } else if (version == 1) { @@ -40,7 +59,7 @@ contract VerificationV2 is RawDispatcher, ThresholdVerification, GuardianSetVeri } } - function decodeThresholdKeyUpdatePayload(bytes memory payload) internal pure returns ( + function _decodeThresholdKeyUpdatePayload(bytes memory payload) internal pure returns ( bytes32 module, uint8 action, uint32 newThresholdIndex, @@ -58,29 +77,34 @@ contract VerificationV2 is RawDispatcher, ThresholdVerification, GuardianSetVeri uint8 shardsLength; (shardsLength, offset) = payload.asUint8MemUnchecked(offset); shards = new bytes32[](shardsLength); - for (uint8 i = 0; i < shardsLength; i++) { + for (uint i = 0; i < shardsLength; i++) { (shards[i], offset) = payload.asBytes32MemUnchecked(offset); } } function _exec(bytes calldata data) internal override returns (bytes memory) { - uint offset = 0; - uint8 version; - (version, offset) = data.asUint8CdUnchecked(offset); - if (version != RAW_DISPATCH_PROTOCOL_VERSION) revert InvalidDispatchVersion(version); + if (msg.value != 0) revert InvalidValue(); - uint length = data.length; - while (offset < length) { + uint offset = 0; + while (offset < data.length) { uint8 op; (op, offset) = data.asUint8CdUnchecked(offset); if (op == OP_GOVERNANCE) { - // Read the VAA and verify it - uint32 dataLength; - (dataLength, offset) = data.asUint32CdUnchecked(offset); + // Read the VAA + bytes calldata encodedVaa; + (encodedVaa, offset) = data.sliceUint16PrefixedCdUnchecked(offset); - bytes calldata encodedVaa = data[offset:offset + dataLength]; - VaaBody memory vaaBody = decodeAndVerifyVaa(encodedVaa); + // Decode the VAA + ( + , + , + , + , + , + , + bytes calldata payload + ) = _decodeAndVerifyVaa(encodedVaa); // Decode the payload ( @@ -90,7 +114,7 @@ contract VerificationV2 is RawDispatcher, ThresholdVerification, GuardianSetVeri address newThresholdAddr, uint32 expirationDelaySeconds, bytes32[] memory shards - ) = decodeThresholdKeyUpdatePayload(vaaBody.payload); + ) = _decodeThresholdKeyUpdatePayload(payload); if (module != MODULE_VERIFICATION_V2) revert InvalidModule(module); if (action != ACTION_APPEND_THRESHOLD_KEY) revert InvalidAction(action); @@ -98,54 +122,74 @@ contract VerificationV2 is RawDispatcher, ThresholdVerification, GuardianSetVeri // Append the threshold key _appendThresholdKey(newThresholdIndex, newThresholdAddr, expirationDelaySeconds, shards); } else if (op == OP_PULL_GUARDIAN_SETS) { - pullGuardianSets(); + uint32 limit; + (limit, offset) = data.asUint32CdUnchecked(offset); + + pullGuardianSets(limit); } } + // Verify the data has been consumed + data.length.checkLength(offset); + return new bytes(0); } function _get(bytes calldata data) internal view override returns (bytes memory) { uint offset = 0; - uint8 version; - (version, offset) = data.asUint8CdUnchecked(offset); - if (version != RAW_DISPATCH_PROTOCOL_VERSION) revert InvalidDispatchVersion(version); - bytes memory result; - uint length = data.length; - while (offset < length) { + while (offset < data.length) { uint8 op; (op, offset) = data.asUint8CdUnchecked(offset); - bytes memory result_entry; if (op == OP_VERIFY) { - uint32 dataLength; - (dataLength, offset) = data.asUint32CdUnchecked(offset); + // Read the VAA + bytes calldata encodedVaa; + (encodedVaa, offset) = data.sliceUint16PrefixedCdUnchecked(offset); - bytes calldata encodedVaa = data[offset:offset + dataLength]; - VaaBody memory vaaBody = decodeAndVerifyVaa(encodedVaa); - result_entry = abi.encode(vaaBody); + // Decode the VAA + ( + uint32 timestamp, + uint32 nonce, + uint16 emitterChainId, + bytes32 emitterAddress, + uint64 sequence, + uint8 consistencyLevel, + bytes calldata payload + ) = _decodeAndVerifyVaa(encodedVaa); + + result = abi.encodePacked( + result, + timestamp, + nonce, + emitterChainId, + emitterAddress, + sequence, + consistencyLevel, + payload + ); } else if (op == OP_THRESHOLD_GET_CURRENT) { (uint32 thresholdIndex, address thresholdAddr) = getCurrentThresholdInfo(); - result_entry = abi.encodePacked(thresholdIndex, thresholdAddr); + result = abi.encodePacked(result, thresholdIndex, thresholdAddr); } else if (op == OP_THRESHOLD_GET) { uint32 index; (index, offset) = data.asUint32CdUnchecked(offset); (uint32 expirationTime, address thresholdAddr) = getPastThresholdInfo(index); - result_entry = abi.encodePacked(expirationTime, thresholdAddr); + result = abi.encodePacked(result, expirationTime, thresholdAddr); } else if (op == OP_GUARDIAN_SET_GET_CURRENT) { (uint32 guardianSetIndex, address[] memory guardianSetAddrs) = getCurrentGuardianSetInfo(); - result_entry = abi.encodePacked(guardianSetIndex, guardianSetAddrs); + result = abi.encodePacked(result, guardianSetIndex, guardianSetAddrs); } else if (op == OP_GUARDIAN_SET_GET) { uint32 index; (index, offset) = data.asUint32CdUnchecked(offset); (uint32 expirationTime, address[] memory guardianSetAddrs) = getGuardianSetInfo(index); - result_entry = abi.encodePacked(expirationTime, guardianSetAddrs); + result = abi.encodePacked(result, expirationTime, guardianSetAddrs); } - - result = abi.encodePacked(result, result_entry); } + // Verify the data has been consumed + data.length.checkLength(offset); + return result; } } From ae0b6bc91a7d100779b4ec14f90b906d63a7b37b Mon Sep 17 00:00:00 2001 From: Joshua Averett Date: Tue, 11 Mar 2025 11:00:42 -0700 Subject: [PATCH 05/53] Add encode/decode functions --- src/ThresholdVerification.sol | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/ThresholdVerification.sol b/src/ThresholdVerification.sol index d79e0bc..c075740 100644 --- a/src/ThresholdVerification.sol +++ b/src/ThresholdVerification.sol @@ -29,21 +29,29 @@ contract ThresholdVerification is WormholeVerifier { bytes32[][] private _shards; + function _decodeThresholdInfo(uint256 info) internal pure returns (uint32 index, address addr) { + unchecked { + return ( + uint32(info), + address(uint160(info >> 32)) + ); + } + } + + function _encodeThresholdInfo(uint32 index, address addr) internal pure returns (uint256 info) { + unchecked { + return (uint256(uint160(addr)) << 32) | uint256(index); + } + } + // Get the current threshold signature info function getCurrentThresholdInfo() public view returns (uint32 index, address addr) { - return ( - uint32(_currentThresholdInfo), - address(uint160(_currentThresholdInfo >> 32)) - ); + return _decodeThresholdInfo(_currentThresholdInfo); } // Get the past threshold signature info function getPastThresholdInfo(uint32 index) public view returns (uint32 expirationTime, address addr) { - uint256 info = _pastThresholdInfo[index]; - return ( - uint32(info), - address(uint160(info >> 32)) - ); + return _decodeThresholdInfo(_pastThresholdInfo[index]); } // Verify a threshold signature VAA @@ -110,12 +118,10 @@ contract ThresholdVerification is WormholeVerifier { // Store the current threshold info in past threshold info uint32 expirationTime = uint32(block.timestamp) + expirationDelaySeconds; - uint256 oldInfo = (uint256(uint160(currentAddr)) << 32) | uint256(expirationTime); - _pastThresholdInfo.push(oldInfo); + _pastThresholdInfo.push(_encodeThresholdInfo(expirationTime, currentAddr)); // Update the current threshold info - uint256 newInfo = (uint256(uint160(newAddr)) << 32) | uint256(newIndex); - _currentThresholdInfo = newInfo; + _currentThresholdInfo = _encodeThresholdInfo(newIndex, newAddr); // Store the shards _shards.push(shards); From 8102478c6ba96ac9a805a4d6bc903c11077c5a95 Mon Sep 17 00:00:00 2001 From: Joshua Averett Date: Thu, 20 Mar 2025 12:18:53 -0700 Subject: [PATCH 06/53] Another round of corrections. --- src/GuardianSetVerification.sol | 366 ++++++++++++++++---------------- src/ThresholdVerification.sol | 259 +++++++++++----------- src/VerificationV2.sol | 334 ++++++++++++++--------------- src/WormholeVerifier.sol | 5 +- 4 files changed, 494 insertions(+), 470 deletions(-) diff --git a/src/GuardianSetVerification.sol b/src/GuardianSetVerification.sol index 90350b5..da57ba2 100644 --- a/src/GuardianSetVerification.sol +++ b/src/GuardianSetVerification.sol @@ -12,190 +12,196 @@ import {CoreBridgeLib} from "wormhole-sdk/libraries/CoreBridge.sol"; import {UncheckedIndexing} from "wormhole-sdk/libraries/UncheckedIndexing.sol"; import "./WormholeVerifier.sol"; -contract GuardianSetVerification is ExtStore, WormholeVerifier { - using BytesParsing for bytes; - using VaaLib for bytes; - using UncheckedIndexing for address[]; - - ICoreBridge private _coreV1; - - // Guardian set expiration time is stored in an array mapped from index to expiration time - uint32[] private _guardianSetExpirationTime; - - constructor( - address coreV1, - uint pullLimit - ) { - _coreV1 = ICoreBridge(coreV1); - pullGuardianSets(pullLimit); - } - - // Get the guardian addresses for a given guardian set index using the ExtStore - // On an invalid index, the function will panic - function getGuardianSetInfo(uint32 index) public view returns (uint32 expirationTime, address[] memory guardianAddrs) { - expirationTime = _guardianSetExpirationTime[index]; - - // Read the guardian set data from the ExtStore - bytes memory data = _extRead(index); - - // Convert the guardian set data to an array of addresses - // NOTE: The `data` array is temporary and is invalid after this block - assembly ("memory-safe") { - guardianAddrs := data - mstore(guardianAddrs, div(mload(guardianAddrs), 32)) - } - } - - function getCurrentGuardianSetInfo() public view returns (uint32 index, address[] memory guardianAddrs) { - unchecked { - index = uint32(_guardianSetExpirationTime.length - 1); - (, guardianAddrs) = this.getGuardianSetInfo(index); - } - } - - // Verify a guardian set VAA - function verifyGuardianSetVAA(bytes calldata encodedVaa) public view returns ( - uint32 timestamp, +contract GuardianSetVerification is ExtStore { + using BytesParsing for bytes; + using VaaLib for bytes; + using UncheckedIndexing for address[]; + + ICoreBridge private immutable _coreBridge; + + // Guardian set expiration time is stored in an array mapped from index to expiration time + uint32[] private _guardianSetExpirationTime; + + constructor( + address coreBridge, + uint pullLimit + ) { + _coreBridge = ICoreBridge(coreBridge); + pullGuardianSets(pullLimit); + } + + // Get the guardian addresses for a given guardian set index using the ExtStore + // On an invalid index, the function will panic + function getGuardianSetInfo(uint32 index) public view returns ( + uint32 expirationTime, + address[] memory guardianAddrs + ) { + if (index >= _guardianSetExpirationTime.length) revert InvalidIndex(); + expirationTime = _guardianSetExpirationTime[index]; + + // Read the guardian set data from the ExtStore + bytes memory data = _extRead(index); + + // Convert the guardian set data to an array of addresses + // NOTE: The `data` array is temporary and is invalid after this block + assembly ("memory-safe") { + guardianAddrs := data + mstore(guardianAddrs, div(mload(guardianAddrs), 32)) + } + } + + function getCurrentGuardianSetInfo() public view returns (uint32 index, address[] memory guardianAddrs) { + unchecked { + index = uint32(_guardianSetExpirationTime.length - 1); + (, guardianAddrs) = this.getGuardianSetInfo(index); + } + } + + // Verify a guardian set VAA + function verifyGuardianSetVAA(bytes calldata encodedVaa) public view returns ( + uint32 timestamp, uint32 nonce, uint16 emitterChainId, bytes32 emitterAddress, uint64 sequence, uint8 consistencyLevel, bytes calldata payload - ) { - unchecked { - uint offset = VaaLib.checkVaaVersionCd(encodedVaa); - uint32 guardianSetIndex; - (guardianSetIndex, offset) = encodedVaa.asUint32CdUnchecked(offset); - - // Get the guardian set - (, address[] memory guardians) = this.getGuardianSetInfo(guardianSetIndex); - - // Get the number of guardians - // NOTE: Optimization puts var on stack thus avoids mload - uint guardianCount = guardians.length; - - // Get the number of signatures - uint signatureCount; - (signatureCount, offset) = encodedVaa.asUint8CdUnchecked(offset); - - // Validate the number of signatures - // NOTE: This works for empty guardian sets, because the quorum when there are no guardians is 1 - uint quorumCount = CoreBridgeLib.minSigsForQuorum(guardianCount); - if (signatureCount < quorumCount) revert VerificationFailed(); - - // Calculate envelope offset and VAA hash - uint envelopeOffset = offset + signatureCount * VaaLib.GUARDIAN_SIGNATURE_SIZE; - bytes32 vaaHash = encodedVaa.calcVaaDoubleHashCd(envelopeOffset); - - // Verify the signatures - // NOTE: Optimization instead of always checking i == 0 - bool isFirstSignature = true; - uint prevGuardianIndex; - - for (uint i = 0; i < signatureCount; ++i) { - // Decode the guardian index, r, s, and v - uint guardianIndex; bytes32 r; bytes32 s; uint8 v; - (guardianIndex, r, s, v, offset) = encodedVaa.decodeGuardianSignatureCdUnchecked(offset); - - // Verify the signature - if (_failsVerification( - vaaHash, - guardianIndex, - r, s, v, - guardians, - guardianCount, - prevGuardianIndex, - isFirstSignature - )) revert VerificationFailed(); - - prevGuardianIndex = guardianIndex; - isFirstSignature = false; - } - - // Decode the VAA body - return encodedVaa.decodeVaaBodyCd(envelopeOffset); - } - } - - function pullGuardianSets(uint limit) public { - unchecked { - // Get the guardian set lengths for the bridge and the local contract - uint currentGuardianSetLength = _coreV1.getCurrentGuardianSetIndex() + 1; - uint oldGuardianSetLength = _guardianSetExpirationTime.length; - - // If we have already pulled all the guardian sets, return - if (currentGuardianSetLength == oldGuardianSetLength) return; - - // Check if we need to update the current guardian set - if (oldGuardianSetLength > 0) { - // Pull and write the current guardian set expiration time - uint updateIndex = oldGuardianSetLength - 1; - (, uint32 expirationTime) = _pullGuardianSet(uint32(updateIndex)); - _guardianSetExpirationTime[updateIndex] = expirationTime; - } - - // Calculate the upper bound of the guardian sets to pull - uint upper = (limit == 0 || currentGuardianSetLength - oldGuardianSetLength < limit) ? currentGuardianSetLength : oldGuardianSetLength + limit; - - // Pull and append the guardian sets - for (uint i = oldGuardianSetLength; i < upper; i++) { - // Pull the guardian set, write the expiration time, and append the guardian set data to the ExtStore - (bytes memory data, uint32 expirationTime) = _pullGuardianSet(uint32(i)); - _guardianSetExpirationTime.push(expirationTime); - _extWrite(data); - } - } - } - - function _pullGuardianSet(uint32 index) private view returns ( - bytes memory data, - uint32 expirationTime - ) { - // Get the guardian set from the core bridge - GuardianSet memory guardians = _coreV1.getGuardianSet(index); - - // Convert the guardian set to a byte array - // Result is stored in `data` - // NOTE: The `keys` array is temporary and is invalid after this block - address[] memory keys = guardians.keys; - assembly ("memory-safe") { - data := keys - mstore(data, mul(mload(data), 32)) - } - - // Return the expiration time - return (data, guardians.expirationTime); - } - - function _failsVerification( - bytes32 vaaHash, - uint guardianIndex, - bytes32 r, bytes32 s, uint8 v, - address[] memory guardians, - uint guardianCount, - uint prevGuardianIndex, - bool isFirstSignature - ) private pure returns (bool) { - address signatory = ecrecover(vaaHash, v, r, s); - address guardian = guardians.readUnchecked(guardianIndex); - - // Check that: - // * the guardian indicies are in strictly ascending order (only after the first signature) - // this is itself an optimization to efficiently prevent having the same guardian signature - // included twice - // * that the guardian index is not out of bounds - // * that the signatory is the guardian - // - // The core bridge also includes a separate check that signatory is not the zero address - // but this is already covered by comparing that the signatory matches the guardian which - // [can never be the zero address](https://github.com/wormhole-foundation/wormhole/blob/1dbe8459b96e182932d0dd5ae4b6bbce6f48cb09/ethereum/contracts/Setters.sol#L20) - return eagerOr( - eagerOr( - !eagerOr(isFirstSignature, guardianIndex > prevGuardianIndex), - guardianIndex >= guardianCount - ), - signatory != guardian - ); - } + ) { + unchecked { + uint offset = VaaLib.checkVaaVersionCd(encodedVaa); + uint32 guardianSetIndex; + (guardianSetIndex, offset) = encodedVaa.asUint32CdUnchecked(offset); + + // Get the guardian set + (, address[] memory guardians) = this.getGuardianSetInfo(guardianSetIndex); + + // Get the number of guardians + // NOTE: Optimization puts var on stack thus avoids mload + uint guardianCount = guardians.length; + + // Get the number of signatures + uint signatureCount; + (signatureCount, offset) = encodedVaa.asUint8CdUnchecked(offset); + + // Validate the number of signatures + // NOTE: This works for empty guardian sets, because the quorum when there + // are no guardians is 1 + uint quorumCount = CoreBridgeLib.minSigsForQuorum(guardianCount); + if (signatureCount < quorumCount) revert VerificationFailed(); + + // Calculate envelope offset and VAA hash + uint envelopeOffset = offset + signatureCount * VaaLib.GUARDIAN_SIGNATURE_SIZE; + bytes32 vaaHash = encodedVaa.calcVaaDoubleHashCd(envelopeOffset); + + // Verify the signatures + // NOTE: Optimization instead of always checking i == 0 + bool isFirstSignature = true; + uint prevGuardianIndex; + + for (uint i = 0; i < signatureCount; ++i) { + // Decode the guardian index, r, s, and v + uint guardianIndex; bytes32 r; bytes32 s; uint8 v; + (guardianIndex, r, s, v, offset) = encodedVaa.decodeGuardianSignatureCdUnchecked(offset); + + // Verify the signature + if (_failsVerification( + vaaHash, + guardianIndex, + r, s, v, + guardians, + guardianCount, + prevGuardianIndex, + isFirstSignature + )) revert VerificationFailed(); + + prevGuardianIndex = guardianIndex; + isFirstSignature = false; + } + + // Decode the VAA body + return encodedVaa.decodeVaaBodyCd(envelopeOffset); + } + } + + function pullGuardianSets(uint limit) public { + unchecked { + // Get the guardian set lengths for the bridge and the local contract + uint currentGuardianSetLength = _coreBridge.getCurrentGuardianSetIndex() + 1; + uint oldGuardianSetLength = _guardianSetExpirationTime.length; + + // If we have already pulled all the guardian sets, return + if (currentGuardianSetLength == oldGuardianSetLength) return; + + // Check if we need to update the current guardian set + if (oldGuardianSetLength > 0) { + // Pull and write the current guardian set expiration time + uint updateIndex = oldGuardianSetLength - 1; + (, uint32 expirationTime) = _pullGuardianSet(uint32(updateIndex)); + _guardianSetExpirationTime[updateIndex] = expirationTime; + } + + // Calculate the upper bound of the guardian sets to pull + uint upper = (limit == 0 || currentGuardianSetLength - oldGuardianSetLength < limit) + ? currentGuardianSetLength : oldGuardianSetLength + limit; + + // Pull and append the guardian sets + for (uint i = oldGuardianSetLength; i < upper; ++i) { + // Pull the guardian set, write the expiration time, and append the guardian set data to the ExtStore + (bytes memory data, uint32 expirationTime) = _pullGuardianSet(uint32(i)); + _guardianSetExpirationTime.push(expirationTime); + _extWrite(data); + } + } + } + + function _pullGuardianSet(uint32 index) private view returns ( + bytes memory data, + uint32 expirationTime + ) { + // Get the guardian set from the core bridge + GuardianSet memory guardians = _coreBridge.getGuardianSet(index); + + // Convert the guardian set to a byte array + // Result is stored in `data` + // NOTE: The `keys` array is temporary and is invalid after this block + address[] memory keys = guardians.keys; + assembly ("memory-safe") { + data := keys + mstore(data, mul(mload(data), 32)) + } + + // Return the expiration time + return (data, guardians.expirationTime); + } + + function _failsVerification( + bytes32 vaaHash, + uint guardianIndex, + bytes32 r, bytes32 s, uint8 v, + address[] memory guardians, + uint guardianCount, + uint prevGuardianIndex, + bool isFirstSignature + ) private pure returns (bool) { + address signatory = ecrecover(vaaHash, v, r, s); + address guardian = guardians.readUnchecked(guardianIndex); + + // Check that: + // * the guardian indicies are in strictly ascending order (only after the first signature) + // this is itself an optimization to efficiently prevent having the same guardian signature + // included twice + // * that the guardian index is not out of bounds + // * that the signatory is the guardian + // + // The core bridge also includes a separate check that signatory is not the zero address + // but this is already covered by comparing that the signatory matches the guardian which + // [can never be the zero address](https://github.com/wormhole-foundation/wormhole/blob/1dbe8459b96e182932d0dd5ae4b6bbce6f48cb09/ethereum/contracts/Setters.sol#L20) + return eagerOr( + eagerOr( + !eagerOr(isFirstSignature, guardianIndex > prevGuardianIndex), + guardianIndex >= guardianCount + ), + signatory != guardian + ); + } } diff --git a/src/ThresholdVerification.sol b/src/ThresholdVerification.sol index c075740..5601f6e 100644 --- a/src/ThresholdVerification.sol +++ b/src/ThresholdVerification.sol @@ -6,125 +6,142 @@ import "wormhole-sdk/libraries/BytesParsing.sol"; import "wormhole-sdk/libraries/VaaLib.sol"; import "./WormholeVerifier.sol"; -contract ThresholdVerification is WormholeVerifier { - using BytesParsing for bytes; - using VaaLib for bytes; - - error InvalidVaa(bytes encodedVaa); - error InvalidSignatureCount(uint8 count); - error InvalidIndex(); - - // Current threshold info is stord in a single slot - // Format: - // index (32 bits) - // address (160 bits) - // TODO: Extract this into its own functions - uint256 private _currentThresholdInfo; - - // Past threshold info is stored in an array - // Format: - // expiration time (32 bits) - // address (160 bits) - uint256[] private _pastThresholdInfo; - - bytes32[][] private _shards; - - function _decodeThresholdInfo(uint256 info) internal pure returns (uint32 index, address addr) { - unchecked { - return ( - uint32(info), - address(uint160(info >> 32)) - ); - } - } - - function _encodeThresholdInfo(uint32 index, address addr) internal pure returns (uint256 info) { - unchecked { - return (uint256(uint160(addr)) << 32) | uint256(index); - } - } - - // Get the current threshold signature info - function getCurrentThresholdInfo() public view returns (uint32 index, address addr) { - return _decodeThresholdInfo(_currentThresholdInfo); - } - - // Get the past threshold signature info - function getPastThresholdInfo(uint32 index) public view returns (uint32 expirationTime, address addr) { - return _decodeThresholdInfo(_pastThresholdInfo[index]); - } - - // Verify a threshold signature VAA - function verifyThresholdVAA(bytes calldata encodedVaa) public view returns ( - uint32 timestamp, - uint32 nonce, - uint16 emitterChainId, - bytes32 emitterAddress, - uint64 sequence, - uint8 consistencyLevel, - bytes calldata payload - ) { - unchecked { - // Check the VAA version - uint offset = 0; - uint8 version; - (version, offset) = encodedVaa.asUint8CdUnchecked(offset); - if (version != 2) revert VaaLib.InvalidVersion(version); - - // Decode the guardian set index - uint32 guardianSetIndex; - (guardianSetIndex, offset) = encodedVaa.asUint32CdUnchecked(offset); - - // Get the current threshold info - ( uint32 currentThresholdIndex, - address currentThresholdAddr - ) = this.getCurrentThresholdInfo(); - - // Get the threshold address - address thresholdAddr; - if (guardianSetIndex != currentThresholdIndex) { - // If the guardian set index is not the current threshold index, we need to get the past threshold info - // and validate that it is not expired - (uint32 expirationTime, address addr) = this.getPastThresholdInfo(guardianSetIndex); - require(addr != address(0), "invalid guardian set"); - require(expirationTime >= block.timestamp, "guardian set has expired"); - thresholdAddr = addr; - } else { - // If the guardian set index is the current threshold index, we can use the current threshold info - thresholdAddr = currentThresholdAddr; - } - - // Calculate the VAA hash - uint envelopeOffset = offset + VaaLib.GUARDIAN_SIGNATURE_SIZE; - bytes32 vaaHash = encodedVaa.calcVaaDoubleHashCd(envelopeOffset); - - // Decode the guardian signature - uint guardianIndex; bytes32 r; bytes32 s; uint8 v; - (guardianIndex, r, s, v, offset) = encodedVaa.decodeGuardianSignatureCdUnchecked(offset); - - // Verify the threshold signature - if (ecrecover(vaaHash, v, r, s) != thresholdAddr) revert VerificationFailed(); - - // Decode the VAA body and return it - return encodedVaa.decodeVaaBodyCd(envelopeOffset); - } - } - - function _appendThresholdKey(uint32 newIndex, address newAddr, uint32 expirationDelaySeconds, bytes32[] memory shards) internal { - unchecked { - // Get the current threshold info and verify the new index is sequential - (uint32 index, address currentAddr) = this.getCurrentThresholdInfo(); - if (newIndex != index + 1) revert InvalidIndex(); - - // Store the current threshold info in past threshold info - uint32 expirationTime = uint32(block.timestamp) + expirationDelaySeconds; - _pastThresholdInfo.push(_encodeThresholdInfo(expirationTime, currentAddr)); - - // Update the current threshold info - _currentThresholdInfo = _encodeThresholdInfo(newIndex, newAddr); - - // Store the shards - _shards.push(shards); - } - } +contract ThresholdVerification { + using BytesParsing for bytes; + using VaaLib for bytes; + + error InvalidVaa(bytes encodedVaa); + error InvalidSignatureCount(uint8 count); + error InvalidGuardianSet(); + error GuardianSetExpired(); + + // Current threshold info is stord in a single slot + // Format: + // index (32 bits) + // address (160 bits) + // TODO: Extract this into its own functions + uint256 private _currentThresholdInfo; + + // Past threshold info is stored in an array + // Format: + // expiration time (32 bits) + // address (160 bits) + uint256[] private _pastThresholdInfo; + + bytes32[][] private _shards; + + // Get the current threshold signature info + function getCurrentThresholdInfo() public view returns (uint32 index, address addr) { + return _decodeThresholdInfo(_currentThresholdInfo); + } + + // Get the past threshold signature info + function getPastThresholdInfo(uint32 index) public view returns ( + uint32 expirationTime, + address addr + ) { + if (index >= _pastThresholdInfo.length) revert InvalidIndex(); + return _decodeThresholdInfo(_pastThresholdInfo[index]); + } + + // Verify a threshold signature VAA + function verifyThresholdVAA(bytes calldata encodedVaa) public view returns ( + uint32 timestamp, + uint32 nonce, + uint16 emitterChainId, + bytes32 emitterAddress, + uint64 sequence, + uint8 consistencyLevel, + bytes calldata payload + ) { + unchecked { + // Check the VAA version + uint offset = 0; + uint8 version; + (version, offset) = encodedVaa.asUint8CdUnchecked(offset); + if (version != 2) revert VaaLib.InvalidVersion(version); + + // Decode the guardian set index + uint32 guardianSetIndex; + (guardianSetIndex, offset) = encodedVaa.asUint32CdUnchecked(offset); + + // Get the current threshold info + ( uint32 currentThresholdIndex, + address currentThresholdAddr + ) = this.getCurrentThresholdInfo(); + + // Get the threshold address + address thresholdAddr; + if (guardianSetIndex != currentThresholdIndex) { + // If the guardian set index is not the current threshold index, + // we need to get the past threshold info and validate that it is not expired + (uint32 expirationTime, address addr) = this.getPastThresholdInfo(guardianSetIndex); + if (expirationTime < block.timestamp) revert GuardianSetExpired(); + thresholdAddr = addr; + } else { + // If the guardian set index is the current threshold index, + // we can use the current threshold info + thresholdAddr = currentThresholdAddr; + } + + // Decode the guardian signature + bytes32 r; bytes32 s; uint8 v; + (r, s, v, offset) = _decodeThresholdSignatureCdUnchecked(encodedVaa, offset); + + // Verify the threshold signature + bytes32 vaaHash = encodedVaa.calcVaaDoubleHashCd(offset); + if (ecrecover(vaaHash, v, r, s) != thresholdAddr) revert VerificationFailed(); + + // Decode the VAA body and return it + return encodedVaa.decodeVaaBodyCd(offset); + } + } + + function _appendThresholdKey( + uint32 newIndex, + address newAddr, + uint32 expirationDelaySeconds, + bytes32[] memory shards + ) internal { + unchecked { + // Verify the new address is not the zero address + if (newAddr == address(0)) revert InvalidGuardianSet(); + + // Get the current threshold info and verify the new index is sequential + (uint32 index, address currentAddr) = this.getCurrentThresholdInfo(); + if (newIndex != index + 1) revert InvalidIndex(); + + // Store the current threshold info in past threshold info + uint32 expirationTime = uint32(block.timestamp) + expirationDelaySeconds; + _pastThresholdInfo.push(_encodeThresholdInfo(expirationTime, currentAddr)); + + // Update the current threshold info + _currentThresholdInfo = _encodeThresholdInfo(newIndex, newAddr); + + // Store the shards + _shards.push(shards); + } + } + + function _decodeThresholdSignatureCdUnchecked( + bytes calldata encodedVaa, + uint offset + ) internal pure returns (bytes32 r, bytes32 s, uint8 v, uint nextOffset) { + (r, offset) = encodedVaa.asBytes32CdUnchecked(offset); + (s, offset) = encodedVaa.asBytes32CdUnchecked(offset); + (v, offset) = encodedVaa.asUint8CdUnchecked(offset); + v += VaaLib.SIGNATURE_RECOVERY_MAGIC; + return (r, s, v, offset); + } + + function _decodeThresholdInfo(uint256 info) internal pure returns (uint32 index, address addr) { + return ( + uint32(info), + address(uint160(info >> 32)) + ); + } + + function _encodeThresholdInfo(uint32 index, address addr) internal pure returns (uint256 info) { + return (uint256(uint160(addr)) << 32) | uint256(index); + } } diff --git a/src/VerificationV2.sol b/src/VerificationV2.sol index adc894d..60d7f64 100644 --- a/src/VerificationV2.sol +++ b/src/VerificationV2.sol @@ -26,170 +26,172 @@ bytes32 constant MODULE_VERIFICATION_V2 = bytes32(0x0000000000000000000000000000 uint8 constant ACTION_APPEND_THRESHOLD_KEY = 0x01; contract VerificationV2 is RawDispatcher, ThresholdVerification, GuardianSetVerification { - using BytesParsing for bytes; - using VaaLib for bytes; - using {BytesParsing.checkLength} for uint; - - error InvalidDispatchVersion(uint8 version); - error InvalidModule(bytes32 module); - error InvalidAction(uint8 action); - error InvalidValue(); - - constructor( - address coreV1, - uint pullLimit - ) ThresholdVerification() GuardianSetVerification(coreV1, pullLimit) {} - - function _decodeAndVerifyVaa(bytes calldata encodedVaa) internal view returns ( - uint32 timestamp, - uint32 nonce, - uint16 emitterChainId, - bytes32 emitterAddress, - uint64 sequence, - uint8 consistencyLevel, - bytes calldata payload - ) { - (uint8 version, ) = encodedVaa.asUint8CdUnchecked(0); - if (version == 2) { - return verifyThresholdVAA(encodedVaa); - } else if (version == 1) { - return verifyGuardianSetVAA(encodedVaa); - } else { - revert VaaLib.InvalidVersion(version); - } - } - - function _decodeThresholdKeyUpdatePayload(bytes memory payload) internal pure returns ( - bytes32 module, - uint8 action, - uint32 newThresholdIndex, - address newThresholdAddr, - uint32 expirationDelaySeconds, - bytes32[] memory shards - ) { - uint offset = 0; - (module, offset) = payload.asBytes32MemUnchecked(offset); - (action, offset) = payload.asUint8MemUnchecked(offset); - (newThresholdIndex, offset) = payload.asUint32MemUnchecked(offset); - (newThresholdAddr, offset) = payload.asAddressMemUnchecked(offset); - (expirationDelaySeconds, offset) = payload.asUint32MemUnchecked(offset); - - uint8 shardsLength; - (shardsLength, offset) = payload.asUint8MemUnchecked(offset); - shards = new bytes32[](shardsLength); - for (uint i = 0; i < shardsLength; i++) { - (shards[i], offset) = payload.asBytes32MemUnchecked(offset); - } - } - - function _exec(bytes calldata data) internal override returns (bytes memory) { - if (msg.value != 0) revert InvalidValue(); - - uint offset = 0; - while (offset < data.length) { - uint8 op; - (op, offset) = data.asUint8CdUnchecked(offset); - - if (op == OP_GOVERNANCE) { - // Read the VAA - bytes calldata encodedVaa; - (encodedVaa, offset) = data.sliceUint16PrefixedCdUnchecked(offset); - - // Decode the VAA - ( - , - , - , - , - , - , - bytes calldata payload - ) = _decodeAndVerifyVaa(encodedVaa); - - // Decode the payload - ( - bytes32 module, - uint8 action, - uint32 newThresholdIndex, - address newThresholdAddr, - uint32 expirationDelaySeconds, - bytes32[] memory shards - ) = _decodeThresholdKeyUpdatePayload(payload); - - if (module != MODULE_VERIFICATION_V2) revert InvalidModule(module); - if (action != ACTION_APPEND_THRESHOLD_KEY) revert InvalidAction(action); - - // Append the threshold key - _appendThresholdKey(newThresholdIndex, newThresholdAddr, expirationDelaySeconds, shards); - } else if (op == OP_PULL_GUARDIAN_SETS) { - uint32 limit; - (limit, offset) = data.asUint32CdUnchecked(offset); - - pullGuardianSets(limit); - } - } - - // Verify the data has been consumed - data.length.checkLength(offset); - - return new bytes(0); - } - - function _get(bytes calldata data) internal view override returns (bytes memory) { - uint offset = 0; - bytes memory result; - while (offset < data.length) { - uint8 op; - (op, offset) = data.asUint8CdUnchecked(offset); - - if (op == OP_VERIFY) { - // Read the VAA - bytes calldata encodedVaa; - (encodedVaa, offset) = data.sliceUint16PrefixedCdUnchecked(offset); - - // Decode the VAA - ( - uint32 timestamp, - uint32 nonce, - uint16 emitterChainId, - bytes32 emitterAddress, - uint64 sequence, - uint8 consistencyLevel, - bytes calldata payload - ) = _decodeAndVerifyVaa(encodedVaa); - - result = abi.encodePacked( - result, - timestamp, - nonce, - emitterChainId, - emitterAddress, - sequence, - consistencyLevel, - payload - ); - } else if (op == OP_THRESHOLD_GET_CURRENT) { - (uint32 thresholdIndex, address thresholdAddr) = getCurrentThresholdInfo(); - result = abi.encodePacked(result, thresholdIndex, thresholdAddr); - } else if (op == OP_THRESHOLD_GET) { - uint32 index; - (index, offset) = data.asUint32CdUnchecked(offset); - (uint32 expirationTime, address thresholdAddr) = getPastThresholdInfo(index); - result = abi.encodePacked(result, expirationTime, thresholdAddr); - } else if (op == OP_GUARDIAN_SET_GET_CURRENT) { - (uint32 guardianSetIndex, address[] memory guardianSetAddrs) = getCurrentGuardianSetInfo(); - result = abi.encodePacked(result, guardianSetIndex, guardianSetAddrs); - } else if (op == OP_GUARDIAN_SET_GET) { - uint32 index; - (index, offset) = data.asUint32CdUnchecked(offset); - (uint32 expirationTime, address[] memory guardianSetAddrs) = getGuardianSetInfo(index); - result = abi.encodePacked(result, expirationTime, guardianSetAddrs); - } - } - - // Verify the data has been consumed - data.length.checkLength(offset); - - return result; - } + using BytesParsing for bytes; + using VaaLib for bytes; + using {BytesParsing.checkLength} for uint; + + error InvalidDispatchVersion(uint8 version); + error InvalidModule(bytes32 module); + error InvalidAction(uint8 action); + error InvalidValue(); + + constructor( + address coreV1, + uint pullLimit + ) ThresholdVerification() GuardianSetVerification(coreV1, pullLimit) {} + + function _decodeAndVerifyVaa(bytes calldata encodedVaa) internal view returns ( + uint32 timestamp, + uint32 nonce, + uint16 emitterChainId, + bytes32 emitterAddress, + uint64 sequence, + uint8 consistencyLevel, + bytes calldata payload + ) { + (uint8 version, ) = encodedVaa.asUint8CdUnchecked(0); + if (version == 2) { + return verifyThresholdVAA(encodedVaa); + } else if (version == 1) { + return verifyGuardianSetVAA(encodedVaa); + } else { + revert VaaLib.InvalidVersion(version); + } + } + + function _decodeThresholdKeyUpdatePayload(bytes memory payload) internal pure returns ( + bytes32 module, + uint8 action, + uint32 newThresholdIndex, + address newThresholdAddr, + uint32 expirationDelaySeconds, + bytes32[] memory shards + ) { + uint offset = 0; + (module, offset) = payload.asBytes32MemUnchecked(offset); + (action, offset) = payload.asUint8MemUnchecked(offset); + + // Verify the module and action + if (module != MODULE_VERIFICATION_V2) revert InvalidModule(module); + if (action != ACTION_APPEND_THRESHOLD_KEY) revert InvalidAction(action); + + (newThresholdIndex, offset) = payload.asUint32MemUnchecked(offset); + (newThresholdAddr, offset) = payload.asAddressMemUnchecked(offset); + (expirationDelaySeconds, offset) = payload.asUint32MemUnchecked(offset); + + uint8 shardsLength; + (shardsLength, offset) = payload.asUint8MemUnchecked(offset); + shards = new bytes32[](shardsLength); + for (uint i = 0; i < shardsLength; ++i) { + (shards[i], offset) = payload.asBytes32MemUnchecked(offset); + } + } + + function _exec(bytes calldata data) internal override returns (bytes memory) { + if (msg.value != 0) revert InvalidValue(); + + uint offset = 0; + while (offset < data.length) { + uint8 op; + (op, offset) = data.asUint8CdUnchecked(offset); + + if (op == OP_GOVERNANCE) { + // Read the VAA + bytes calldata encodedVaa; + (encodedVaa, offset) = data.sliceUint16PrefixedCdUnchecked(offset); + + // Decode and verify the VAA + ( + , + , + , + , + , + , + bytes calldata payload + ) = _decodeAndVerifyVaa(encodedVaa); + + // Decode the payload + ( + , + , + uint32 newThresholdIndex, + address newThresholdAddr, + uint32 expirationDelaySeconds, + bytes32[] memory shards + ) = _decodeThresholdKeyUpdatePayload(payload); + + // Append the threshold key + _appendThresholdKey(newThresholdIndex, newThresholdAddr, expirationDelaySeconds, shards); + } else if (op == OP_PULL_GUARDIAN_SETS) { + uint32 limit; + (limit, offset) = data.asUint32CdUnchecked(offset); + + pullGuardianSets(limit); + } + } + + // Verify the data has been consumed + data.length.checkLength(offset); + + return new bytes(0); + } + + function _get(bytes calldata data) internal view override returns (bytes memory) { + uint offset = 0; + bytes memory result; + while (offset < data.length) { + uint8 op; + (op, offset) = data.asUint8CdUnchecked(offset); + + if (op == OP_VERIFY) { + // Read the VAA + bytes calldata encodedVaa; + (encodedVaa, offset) = data.sliceUint16PrefixedCdUnchecked(offset); + + // Decode the VAA + ( + uint32 timestamp, + uint32 nonce, + uint16 emitterChainId, + bytes32 emitterAddress, + uint64 sequence, + uint8 consistencyLevel, + bytes calldata payload + ) = _decodeAndVerifyVaa(encodedVaa); + + result = abi.encodePacked( + result, + timestamp, + nonce, + emitterChainId, + emitterAddress, + sequence, + consistencyLevel, + payload + ); + } else if (op == OP_THRESHOLD_GET_CURRENT) { + (uint32 thresholdIndex, address thresholdAddr) = getCurrentThresholdInfo(); + result = abi.encodePacked(result, thresholdIndex, thresholdAddr); + } else if (op == OP_THRESHOLD_GET) { + uint32 index; + (index, offset) = data.asUint32CdUnchecked(offset); + (uint32 expirationTime, address thresholdAddr) = getPastThresholdInfo(index); + result = abi.encodePacked(result, expirationTime, thresholdAddr); + } else if (op == OP_GUARDIAN_SET_GET_CURRENT) { + (uint32 guardianSetIndex, address[] memory guardianSetAddrs) = getCurrentGuardianSetInfo(); + result = abi.encodePacked(result, guardianSetIndex, guardianSetAddrs); + } else if (op == OP_GUARDIAN_SET_GET) { + uint32 index; + (index, offset) = data.asUint32CdUnchecked(offset); + (uint32 expirationTime, address[] memory guardianSetAddrs) = getGuardianSetInfo(index); + result = abi.encodePacked(result, expirationTime, guardianSetAddrs); + } + } + + // Verify the data has been consumed + data.length.checkLength(offset); + + return result; + } } diff --git a/src/WormholeVerifier.sol b/src/WormholeVerifier.sol index 892bc2a..49615aa 100644 --- a/src/WormholeVerifier.sol +++ b/src/WormholeVerifier.sol @@ -2,6 +2,5 @@ pragma solidity ^0.8.0; -abstract contract WormholeVerifier { - error VerificationFailed(); -} +error InvalidIndex(); +error VerificationFailed(); From a51c8f81cccd0465b173e7cef0de264ebade188c Mon Sep 17 00:00:00 2001 From: NoiTaTuM Date: Tue, 1 Apr 2025 12:06:07 -0300 Subject: [PATCH 07/53] Make contract compile using the latest wormhole solidity sdk --- Makefile | 2 +- src/GuardianSetVerification.sol | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 7358e71..b25361a 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ test: dependencies LIB_DEPS = foundry-rs/forge-std LIB_DEPS += openzeppelin/openzeppelin-contracts@0457042d93d9dfd760dbaa06a4d2f1216fdbe297 #for gscd's optimizations -LIB_DEPS += wormhole-foundation/wormhole-solidity-sdk@67ca81c +LIB_DEPS += wormhole-foundation/wormhole-solidity-sdk@9206704 # dynamically generate install rule for each lib dependency and add to depdenencies $(foreach dep,$(LIB_DEPS), $(eval $(call install_lib,$(dep)))) diff --git a/src/GuardianSetVerification.sol b/src/GuardianSetVerification.sol index da57ba2..2ccac22 100644 --- a/src/GuardianSetVerification.sol +++ b/src/GuardianSetVerification.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.0; import "./ExtStore.sol"; -import {ICoreBridge, GuardianSet} from "wormhole-sdk/interfaces/ICoreBridge.sol"; +import {IWormhole} from "wormhole-sdk/interfaces/IWormhole.sol"; import {eagerOr} from "wormhole-sdk/Utils.sol"; import {BytesParsing} from "wormhole-sdk/libraries/BytesParsing.sol"; import {VaaLib} from "wormhole-sdk/libraries/VaaLib.sol"; @@ -17,7 +17,7 @@ contract GuardianSetVerification is ExtStore { using VaaLib for bytes; using UncheckedIndexing for address[]; - ICoreBridge private immutable _coreBridge; + IWormhole private immutable _coreBridge; // Guardian set expiration time is stored in an array mapped from index to expiration time uint32[] private _guardianSetExpirationTime; @@ -26,7 +26,7 @@ contract GuardianSetVerification is ExtStore { address coreBridge, uint pullLimit ) { - _coreBridge = ICoreBridge(coreBridge); + _coreBridge = IWormhole(coreBridge); pullGuardianSets(pullLimit); } @@ -159,7 +159,7 @@ contract GuardianSetVerification is ExtStore { uint32 expirationTime ) { // Get the guardian set from the core bridge - GuardianSet memory guardians = _coreBridge.getGuardianSet(index); + IWormhole.GuardianSet memory guardians = _coreBridge.getGuardianSet(index); // Convert the guardian set to a byte array // Result is stored in `data` From 5efbb407b0071bf188d6fe45e50bd225a9ed98b1 Mon Sep 17 00:00:00 2001 From: Joshua Averett Date: Fri, 11 Apr 2025 20:33:11 -0700 Subject: [PATCH 08/53] Move EVM code to its own folder and add checks for governance emitter --- package-lock.json | 6 +++++ package.json | 1 + src/{ => evm}/ExtStore.sol | 0 src/{ => evm}/GuardianSetVerification.sol | 0 src/{ => evm}/ThresholdVerification.sol | 0 src/{ => evm}/VerificationV2.sol | 29 ++++++++++++++++------- src/{ => evm}/WormholeVerifier.sol | 0 7 files changed, 27 insertions(+), 9 deletions(-) create mode 100644 package-lock.json create mode 100644 package.json rename src/{ => evm}/ExtStore.sol (100%) rename src/{ => evm}/GuardianSetVerification.sol (100%) rename src/{ => evm}/ThresholdVerification.sol (100%) rename src/{ => evm}/VerificationV2.sol (90%) rename src/{ => evm}/WormholeVerifier.sol (100%) diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..105e4b2 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "core-v2", + "lockfileVersion": 3, + "requires": true, + "packages": {} +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/package.json @@ -0,0 +1 @@ +{} diff --git a/src/ExtStore.sol b/src/evm/ExtStore.sol similarity index 100% rename from src/ExtStore.sol rename to src/evm/ExtStore.sol diff --git a/src/GuardianSetVerification.sol b/src/evm/GuardianSetVerification.sol similarity index 100% rename from src/GuardianSetVerification.sol rename to src/evm/GuardianSetVerification.sol diff --git a/src/ThresholdVerification.sol b/src/evm/ThresholdVerification.sol similarity index 100% rename from src/ThresholdVerification.sol rename to src/evm/ThresholdVerification.sol diff --git a/src/VerificationV2.sol b/src/evm/VerificationV2.sol similarity index 90% rename from src/VerificationV2.sol rename to src/evm/VerificationV2.sol index 60d7f64..8f85e44 100644 --- a/src/VerificationV2.sol +++ b/src/evm/VerificationV2.sol @@ -5,6 +5,7 @@ pragma solidity ^0.8.0; import {BytesParsing} from "wormhole-sdk/libraries/BytesParsing.sol"; import {VaaLib} from "wormhole-sdk/libraries/VaaLib.sol"; import {RawDispatcher} from "wormhole-sdk/RawDispatcher.sol"; +import {CHAIN_ID_SOLANA} from "wormhole-sdk/constants/Chains.sol"; import {ThresholdVerification} from "./ThresholdVerification.sol"; import {GuardianSetVerification} from "./GuardianSetVerification.sol"; @@ -19,6 +20,9 @@ uint8 constant OP_THRESHOLD_GET = 0x22; uint8 constant OP_GUARDIAN_SET_GET_CURRENT = 0x23; uint8 constant OP_GUARDIAN_SET_GET = 0x24; +// Emitter address for the VerificationV2 contract +bytes32 constant GOVERNANCE_ADDRESS = bytes32(0x0000000000000000000000000000000000000000000000000000000000000004); + // Module ID for the VerificationV2 contract, ASCII "TSS" bytes32 constant MODULE_VERIFICATION_V2 = bytes32(0x0000000000000000000000000000000000000000000000000000000000545353); @@ -35,6 +39,9 @@ contract VerificationV2 is RawDispatcher, ThresholdVerification, GuardianSetVeri error InvalidAction(uint8 action); error InvalidValue(); + error InvalidGovernanceChainId(); + error InvalidGovernanceAddress(); + constructor( address coreV1, uint pullLimit @@ -60,21 +67,23 @@ contract VerificationV2 is RawDispatcher, ThresholdVerification, GuardianSetVeri } function _decodeThresholdKeyUpdatePayload(bytes memory payload) internal pure returns ( - bytes32 module, - uint8 action, uint32 newThresholdIndex, address newThresholdAddr, uint32 expirationDelaySeconds, bytes32[] memory shards ) { + // Decode and verify the module and action uint offset = 0; + + bytes32 module; (module, offset) = payload.asBytes32MemUnchecked(offset); - (action, offset) = payload.asUint8MemUnchecked(offset); - - // Verify the module and action if (module != MODULE_VERIFICATION_V2) revert InvalidModule(module); + + uint8 action; + (action, offset) = payload.asUint8MemUnchecked(offset); if (action != ACTION_APPEND_THRESHOLD_KEY) revert InvalidAction(action); + // Decode the message body (newThresholdIndex, offset) = payload.asUint32MemUnchecked(offset); (newThresholdAddr, offset) = payload.asAddressMemUnchecked(offset); (expirationDelaySeconds, offset) = payload.asUint32MemUnchecked(offset); @@ -104,17 +113,19 @@ contract VerificationV2 is RawDispatcher, ThresholdVerification, GuardianSetVeri ( , , - , - , + uint16 emitterChainId, + bytes32 emitterAddress, , , bytes calldata payload ) = _decodeAndVerifyVaa(encodedVaa); + + // Verify the emitter + if (emitterChainId != CHAIN_ID_SOLANA) revert InvalidGovernanceChainId(); + if (emitterAddress != GOVERNANCE_ADDRESS) revert InvalidGovernanceAddress(); // Decode the payload ( - , - , uint32 newThresholdIndex, address newThresholdAddr, uint32 expirationDelaySeconds, diff --git a/src/WormholeVerifier.sol b/src/evm/WormholeVerifier.sol similarity index 100% rename from src/WormholeVerifier.sol rename to src/evm/WormholeVerifier.sol From ddeb014b06e308569b352613b3a7532c9b62c6e0 Mon Sep 17 00:00:00 2001 From: Joshua Averett Date: Fri, 11 Apr 2025 20:55:23 -0700 Subject: [PATCH 09/53] First pass of the solana code --- src/solana/.gitignore | 7 + src/solana/.prettierignore | 7 + src/solana/Anchor.toml | 19 + src/solana/Cargo.lock | 3035 +++++++++++++++++ src/solana/Cargo.toml | 14 + src/solana/migrations/deploy.ts | 12 + src/solana/package.json | 20 + src/solana/programs/solana/Cargo.toml | 23 + src/solana/programs/solana/Xargo.toml | 2 + .../src/append_threshold_key_message.rs | 55 + src/solana/programs/solana/src/lib.rs | 192 ++ src/solana/programs/solana/src/vaa.rs | 96 + src/solana/tests/solana.ts | 16 + src/solana/tsconfig.json | 10 + src/solana/yarn.lock | 1143 +++++++ 15 files changed, 4651 insertions(+) create mode 100644 src/solana/.gitignore create mode 100644 src/solana/.prettierignore create mode 100644 src/solana/Anchor.toml create mode 100644 src/solana/Cargo.lock create mode 100644 src/solana/Cargo.toml create mode 100644 src/solana/migrations/deploy.ts create mode 100644 src/solana/package.json create mode 100644 src/solana/programs/solana/Cargo.toml create mode 100644 src/solana/programs/solana/Xargo.toml create mode 100644 src/solana/programs/solana/src/append_threshold_key_message.rs create mode 100644 src/solana/programs/solana/src/lib.rs create mode 100644 src/solana/programs/solana/src/vaa.rs create mode 100644 src/solana/tests/solana.ts create mode 100644 src/solana/tsconfig.json create mode 100644 src/solana/yarn.lock diff --git a/src/solana/.gitignore b/src/solana/.gitignore new file mode 100644 index 0000000..2e0446b --- /dev/null +++ b/src/solana/.gitignore @@ -0,0 +1,7 @@ +.anchor +.DS_Store +target +**/*.rs.bk +node_modules +test-ledger +.yarn diff --git a/src/solana/.prettierignore b/src/solana/.prettierignore new file mode 100644 index 0000000..4142583 --- /dev/null +++ b/src/solana/.prettierignore @@ -0,0 +1,7 @@ +.anchor +.DS_Store +target +node_modules +dist +build +test-ledger diff --git a/src/solana/Anchor.toml b/src/solana/Anchor.toml new file mode 100644 index 0000000..bd5f962 --- /dev/null +++ b/src/solana/Anchor.toml @@ -0,0 +1,19 @@ +[toolchain] +package_manager = "yarn" + +[features] +resolution = true +skip-lint = false + +[programs.localnet] +solana = "CTyCJvaLgY18BTTY3M1ga1SmY5fuT3Jyu3j7s332Z3oz" + +[registry] +url = "https://api.apr.dev" + +[provider] +cluster = "localnet" +wallet = "~/.config/solana/id.json" + +[scripts] +test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" diff --git a/src/solana/Cargo.lock b/src/solana/Cargo.lock new file mode 100644 index 0000000..b6cf32c --- /dev/null +++ b/src/solana/Cargo.lock @@ -0,0 +1,3035 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aes-gcm-siv" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae0784134ba9375416d469ec31e7c5f9fa94405049cf08c5ce5b4698be673e0d" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "polyval", + "subtle", + "zeroize", +] + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy 0.7.35", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "anchor-attribute-access-control" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37013051defd745a5437d6842bd404e5480e14ad4e4f0441dd9a81a4b9aea1d6" +dependencies = [ + "anchor-syn", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-account" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92db0f793e924e18462b3fac53c5759a8248649a8072788b5e88a4af714998c8" +dependencies = [ + "anchor-syn", + "bs58", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-constant" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a98126ebfc96d6248899caadc9ea7c2403420c4f5c994e541802bce9f423674" +dependencies = [ + "anchor-syn", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-error" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8a4dcb403f872fbcd0910fc39a3e05bb6c43a8399f915a1878e62eb680fbb23" +dependencies = [ + "anchor-syn", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-event" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "420d651b2703ccff86f6c4b7c394140cb85049787c078a5f8280506121d48065" +dependencies = [ + "anchor-syn", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-program" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d258f3a9f47db7f4199888df0ee67e42b960a7acb8f5c336b585d4eb243b9665" +dependencies = [ + "anchor-lang-idl", + "anchor-syn", + "anyhow", + "bs58", + "heck", + "proc-macro2", + "quote", + "serde_json", + "syn 1.0.109", +] + +[[package]] +name = "anchor-derive-accounts" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "097147501de51105d8dbdad9bd5a96a1b17ecbb2cee9f200d6167031372eab3b" +dependencies = [ + "anchor-syn", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-derive-serde" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5a24721da4ed67f0a1391cac27ea7e51c255cbd94cdcc6728a0aa56227628d0" +dependencies = [ + "anchor-syn", + "borsh-derive-internal", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-derive-space" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f41986f84d238a2f7a807f3a98da5df0e97ebe23f29f7d67b8cdd4fd80bc1ba1" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-lang" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eba81a0543fee1b7b610fe9ebedbae6a14e8d3e85a6a6dd48871d48a08880195" +dependencies = [ + "anchor-attribute-access-control", + "anchor-attribute-account", + "anchor-attribute-constant", + "anchor-attribute-error", + "anchor-attribute-event", + "anchor-attribute-program", + "anchor-derive-accounts", + "anchor-derive-serde", + "anchor-derive-space", + "anchor-lang-idl", + "base64 0.21.7", + "bincode", + "borsh 0.10.4", + "bytemuck", + "solana-program", + "thiserror 1.0.69", +] + +[[package]] +name = "anchor-lang-idl" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e8599d21995f68e296265aa5ab0c3cef582fd58afec014d01bd0bce18a4418" +dependencies = [ + "anchor-lang-idl-spec", + "anyhow", + "heck", + "regex", + "serde", + "serde_json", + "sha2 0.10.8", +] + +[[package]] +name = "anchor-lang-idl-spec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bdf143115440fe621bdac3a29a1f7472e09f6cd82b2aa569429a0c13f103838" +dependencies = [ + "anyhow", + "serde", +] + +[[package]] +name = "anchor-spl" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9d989ebc64e6c1a9828d3a6f7b8e7a4d63cc8a4f667dcb191bd9067a3375c20" +dependencies = [ + "anchor-lang", + "mpl-token-metadata", + "spl-associated-token-account", + "spl-pod", + "spl-token", + "spl-token-2022", + "spl-token-group-interface", + "spl-token-metadata-interface", +] + +[[package]] +name = "anchor-syn" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "564685b759db12a2424d1b2688cfdf0fec26a023813bc461274754fb0e5d97b0" +dependencies = [ + "anyhow", + "bs58", + "cargo_toml", + "heck", + "proc-macro2", + "quote", + "serde", + "serde_json", + "sha2 0.10.8", + "syn 1.0.109", + "thiserror 1.0.69", +] + +[[package]] +name = "anyhow" +version = "1.0.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "base64" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" + +[[package]] +name = "blake3" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "389a099b34312839e16420d499a9cad9650541715937ffbdd40d36f49e77eeb3" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", + "digest 0.10.7", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "borsh" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115e54d64eb62cdebad391c19efc9dce4981c690c85a33a12199d99bb9546fee" +dependencies = [ + "borsh-derive 0.10.4", + "hashbrown 0.13.2", +] + +[[package]] +name = "borsh" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8646f98db542e39fc66e68a20b2144f6a732636df7c2354e74645faaa433ce" +dependencies = [ + "borsh-derive 1.5.7", + "cfg_aliases", +] + +[[package]] +name = "borsh-derive" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831213f80d9423998dd696e2c5345aba6be7a0bd8cd19e31c5243e13df1cef89" +dependencies = [ + "borsh-derive-internal", + "borsh-schema-derive-internal", + "proc-macro-crate 0.1.5", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "borsh-derive" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdd1d3c0c2f5833f22386f252fe8ed005c7f59fdcddeef025c01b4c3b9fd9ac3" +dependencies = [ + "once_cell", + "proc-macro-crate 3.3.0", + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "borsh-derive-internal" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65d6ba50644c98714aa2a70d13d7df3cd75cd2b523a2b452bf010443800976b3" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "borsh-schema-derive-internal" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "276691d96f063427be83e6692b86148e488ebba9f48f77788724ca027ba3b6d4" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "bumpalo" +version = "3.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" + +[[package]] +name = "bv" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8834bb1d8ee5dc048ee3124f2c7c1afcc6bc9aed03f11e9dfd8c69470a5db340" +dependencies = [ + "feature-probe", + "serde", +] + +[[package]] +name = "bytemuck" +version = "1.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ecc273b49b3205b83d648f0690daa588925572cc5063745bfe547fe7ec8e1a1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cargo_toml" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a98356df42a2eb1bd8f1793ae4ee4de48e384dd974ce5eac8eee802edb7492be" +dependencies = [ + "serde", + "toml 0.8.20", +] + +[[package]] +name = "cc" +version = "1.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e3a13707ac958681c13b39b458c073d0d9bc8a22cb1b2f4c8e55eb72c13f362" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "console_log" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89f72f65e8501878b8a004d5a1afb780987e2ce2b4532c562e367a72c57499f" +dependencies = [ + "log", + "web-sys", +] + +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crunchy" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "typenum", +] + +[[package]] +name = "crypto-mac" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto", + "rand_core 0.6.4", + "rustc_version", + "serde", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "derivation-path" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e5c37193a1db1d8ed868c03ec7b152175f26160a5b740e5e484143877e0adf0" + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "crypto-common", + "subtle", +] + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "feature-probe" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" + +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + +[[package]] +name = "five8_const" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26dec3da8bc3ef08f2c04f61eab298c3ab334523e55f076354d6d6f613799a7b" +dependencies = [ + "five8_core", +] + +[[package]] +name = "five8_core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2551bf44bc5f776c15044b9b94153a00198be06743e262afaaa61f11ac7523a5" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hmac" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" +dependencies = [ + "crypto-mac", + "digest 0.9.0", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "hmac-drbg" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" +dependencies = [ + "digest 0.9.0", + "generic-array", + "hmac 0.8.1", +] + +[[package]] +name = "indexmap" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" +dependencies = [ + "equivalent", + "hashbrown 0.15.2", +] + +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "generic-array", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.171" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" + +[[package]] +name = "libsecp256k1" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9d220bc1feda2ac231cb78c3d26f27676b8cf82c96971f7aeef3d0cf2797c73" +dependencies = [ + "arrayref", + "base64 0.12.3", + "digest 0.9.0", + "libsecp256k1-core 0.2.2", + "libsecp256k1-gen-ecmult 0.2.1", + "libsecp256k1-gen-genmult 0.2.1", + "rand 0.7.3", + "serde", + "sha2 0.9.9", +] + +[[package]] +name = "libsecp256k1" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e79019718125edc905a079a70cfa5f3820bc76139fc91d6f9abc27ea2a887139" +dependencies = [ + "arrayref", + "base64 0.22.1", + "digest 0.9.0", + "hmac-drbg", + "libsecp256k1-core 0.3.0", + "libsecp256k1-gen-ecmult 0.3.0", + "libsecp256k1-gen-genmult 0.3.0", + "rand 0.8.5", + "serde", + "sha2 0.9.9", + "typenum", +] + +[[package]] +name = "libsecp256k1-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0f6ab710cec28cef759c5f18671a27dae2a5f952cdaaee1d8e2908cb2478a80" +dependencies = [ + "crunchy", + "digest 0.9.0", + "subtle", +] + +[[package]] +name = "libsecp256k1-core" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be9b9bb642d8522a44d533eab56c16c738301965504753b03ad1de3425d5451" +dependencies = [ + "crunchy", + "digest 0.9.0", + "subtle", +] + +[[package]] +name = "libsecp256k1-gen-ecmult" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccab96b584d38fac86a83f07e659f0deafd0253dc096dab5a36d53efe653c5c3" +dependencies = [ + "libsecp256k1-core 0.2.2", +] + +[[package]] +name = "libsecp256k1-gen-ecmult" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3038c808c55c87e8a172643a7d87187fc6c4174468159cb3090659d55bcb4809" +dependencies = [ + "libsecp256k1-core 0.3.0", +] + +[[package]] +name = "libsecp256k1-gen-genmult" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67abfe149395e3aa1c48a2beb32b068e2334402df8181f818d3aee2b304c4f5d" +dependencies = [ + "libsecp256k1-core 0.2.2", +] + +[[package]] +name = "libsecp256k1-gen-genmult" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db8d6ba2cec9eacc40e6e8ccc98931840301f1006e95647ceb2dd5c3aa06f7c" +dependencies = [ + "libsecp256k1-core 0.3.0", +] + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "merlin" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" +dependencies = [ + "byteorder", + "keccak", + "rand_core 0.6.4", + "zeroize", +] + +[[package]] +name = "mpl-token-metadata" +version = "5.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "989e6a3000e761d3b2d685662a3a9ee99826f9369fb033bd1bc7011b1cf02ed9" +dependencies = [ + "borsh 0.10.4", + "num-derive 0.3.3", + "num-traits", + "solana-program", + "thiserror 1.0.69", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_enum" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" +dependencies = [ + "proc-macro-crate 3.3.0", + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "pbkdf2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "polyval" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy 0.8.24", +] + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml 0.5.11", +] + +[[package]] +name = "proc-macro-crate" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "qstring" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d464fae65fff2680baf48019211ce37aaec0c78e9264c84a3e484717f965104e" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.15", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "redox_syscall" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustversion" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "semver" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_bytes" +version = "0.11.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8437fd221bde2d4ca316d61b90e337e9e702b3820b87d63caa9ba6c02bd06d96" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "serde_json" +version = "1.0.140" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_spanned" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +dependencies = [ + "serde", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "smallvec" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" + +[[package]] +name = "solana-account" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f949fe4edaeaea78c844023bfc1c898e0b1f5a100f8a8d2d0f85d0a7b090258" +dependencies = [ + "solana-account-info", + "solana-clock", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", +] + +[[package]] +name = "solana-account-info" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0c17d606a298a205fae325489fbed88ee6dc4463c111672172327e741c8905d" +dependencies = [ + "bincode", + "serde", + "solana-program-error", + "solana-program-memory", + "solana-pubkey", +] + +[[package]] +name = "solana-address-lookup-table-interface" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1673f67efe870b64a65cb39e6194be5b26527691ce5922909939961a6e6b395" +dependencies = [ + "bincode", + "bytemuck", + "serde", + "serde_derive", + "solana-clock", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", + "solana-slot-hashes", +] + +[[package]] +name = "solana-atomic-u64" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52e52720efe60465b052b9e7445a01c17550666beec855cce66f44766697bc2" +dependencies = [ + "parking_lot", +] + +[[package]] +name = "solana-big-mod-exp" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75db7f2bbac3e62cfd139065d15bcda9e2428883ba61fc8d27ccb251081e7567" +dependencies = [ + "num-bigint", + "num-traits", + "solana-define-syscall", +] + +[[package]] +name = "solana-bincode" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19a3787b8cf9c9fe3dd360800e8b70982b9e5a8af9e11c354b6665dd4a003adc" +dependencies = [ + "bincode", + "serde", + "solana-instruction", +] + +[[package]] +name = "solana-blake3-hasher" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a0801e25a1b31a14494fc80882a036be0ffd290efc4c2d640bfcca120a4672" +dependencies = [ + "blake3", + "solana-define-syscall", + "solana-hash", + "solana-sanitize", +] + +[[package]] +name = "solana-borsh" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718333bcd0a1a7aed6655aa66bef8d7fb047944922b2d3a18f49cbc13e73d004" +dependencies = [ + "borsh 0.10.4", + "borsh 1.5.7", +] + +[[package]] +name = "solana-clock" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67c2177a1b9fe8326004f1151a5acd124420b737811080b1035df31349e4d892" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-cpi" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dc71126edddc2ba014622fc32d0f5e2e78ec6c5a1e0eb511b85618c09e9ea11" +dependencies = [ + "solana-account-info", + "solana-define-syscall", + "solana-instruction", + "solana-program-error", + "solana-pubkey", + "solana-stable-layout", +] + +[[package]] +name = "solana-curve25519" +version = "2.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d9499a822cd1acdac4fcec1acb500819f84b2f83042d6ae0d19cc45b32747f9" +dependencies = [ + "bytemuck", + "bytemuck_derive", + "curve25519-dalek", + "solana-define-syscall", + "subtle", + "thiserror 2.0.12", +] + +[[package]] +name = "solana-decode-error" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a6a6383af236708048f8bd8d03db8ca4ff7baf4a48e5d580f4cce545925470" +dependencies = [ + "num-traits", +] + +[[package]] +name = "solana-define-syscall" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf784bb2cb3e02cac9801813c30187344228d2ae952534902108f6150573a33d" + +[[package]] +name = "solana-derivation-path" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "939756d798b25c5ec3cca10e06212bdca3b1443cb9bb740a38124f58b258737b" +dependencies = [ + "derivation-path", + "qstring", + "uriparse", +] + +[[package]] +name = "solana-epoch-rewards" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b575d3dd323b9ea10bb6fe89bf6bf93e249b215ba8ed7f68f1a3633f384db7" +dependencies = [ + "serde", + "serde_derive", + "solana-hash", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-epoch-schedule" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fce071fbddecc55d727b1d7ed16a629afe4f6e4c217bc8d00af3b785f6f67ed" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-example-mocks" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84461d56cbb8bb8d539347151e0525b53910102e4bced875d49d5139708e39d3" +dependencies = [ + "serde", + "serde_derive", + "solana-address-lookup-table-interface", + "solana-clock", + "solana-hash", + "solana-instruction", + "solana-keccak-hasher", + "solana-message", + "solana-nonce", + "solana-pubkey", + "solana-sdk-ids", + "solana-system-interface", + "thiserror 2.0.12", +] + +[[package]] +name = "solana-feature-gate-interface" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f9c7fbf3e58b64a667c5f35e90af580538a95daea7001ff7806c0662d301bdf" +dependencies = [ + "bincode", + "serde", + "serde_derive", + "solana-account", + "solana-account-info", + "solana-instruction", + "solana-program-error", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", + "solana-system-interface", +] + +[[package]] +name = "solana-fee-calculator" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89bc408da0fb3812bc3008189d148b4d3e08252c79ad810b245482a3f70cd8d" +dependencies = [ + "log", + "serde", + "serde_derive", +] + +[[package]] +name = "solana-hash" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf7bcb14392900fe02e4e34e90234fbf0c673d4e327888410ba99fa2ba0f4e99" +dependencies = [ + "borsh 1.5.7", + "bs58", + "bytemuck", + "bytemuck_derive", + "js-sys", + "serde", + "serde_derive", + "solana-atomic-u64", + "solana-sanitize", + "wasm-bindgen", +] + +[[package]] +name = "solana-instruction" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce496a475e5062ba5de97215ab39d9c358f9c9df4bb7f3a45a1f1a8bd9065ed" +dependencies = [ + "bincode", + "borsh 1.5.7", + "getrandom 0.2.15", + "js-sys", + "num-traits", + "serde", + "serde_derive", + "solana-define-syscall", + "solana-pubkey", + "wasm-bindgen", +] + +[[package]] +name = "solana-instructions-sysvar" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "427f2d0d6dc0bb49f16cef5e7f975180d2e80aab9bdd3b2af68e2d029ec63f43" +dependencies = [ + "bitflags", + "solana-account-info", + "solana-instruction", + "solana-program-error", + "solana-pubkey", + "solana-sanitize", + "solana-sdk-ids", + "solana-serialize-utils", + "solana-sysvar-id", +] + +[[package]] +name = "solana-keccak-hasher" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7aeb957fbd42a451b99235df4942d96db7ef678e8d5061ef34c9b34cae12f79" +dependencies = [ + "sha3", + "solana-define-syscall", + "solana-hash", + "solana-sanitize", +] + +[[package]] +name = "solana-last-restart-slot" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a6360ac2fdc72e7463565cd256eedcf10d7ef0c28a1249d261ec168c1b55cdd" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-loader-v2-interface" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8ab08006dad78ae7cd30df8eea0539e207d08d91eaefb3e1d49a446e1c49654" +dependencies = [ + "serde", + "serde_bytes", + "serde_derive", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", +] + +[[package]] +name = "solana-loader-v3-interface" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4be76cfa9afd84ca2f35ebc09f0da0f0092935ccdac0595d98447f259538c2" +dependencies = [ + "serde", + "serde_bytes", + "serde_derive", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", + "solana-system-interface", +] + +[[package]] +name = "solana-loader-v4-interface" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "706a777242f1f39a83e2a96a2a6cb034cb41169c6ecbee2cf09cb873d9659e7e" +dependencies = [ + "serde", + "serde_bytes", + "serde_derive", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", + "solana-system-interface", +] + +[[package]] +name = "solana-message" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c6bf99c4570173710107a1f233f3bee226feea5fc817308707d4f7cb100a72d" +dependencies = [ + "bincode", + "blake3", + "lazy_static", + "serde", + "serde_derive", + "solana-bincode", + "solana-hash", + "solana-instruction", + "solana-pubkey", + "solana-sanitize", + "solana-sdk-ids", + "solana-short-vec", + "solana-system-interface", + "solana-transaction-error", + "wasm-bindgen", +] + +[[package]] +name = "solana-msg" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36a1a14399afaabc2781a1db09cb14ee4cc4ee5c7a5a3cfcc601811379a8092" +dependencies = [ + "solana-define-syscall", +] + +[[package]] +name = "solana-native-token" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33e9de00960197412e4be3902a6cd35e60817c511137aca6c34c66cd5d4017ec" + +[[package]] +name = "solana-nonce" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703e22eb185537e06204a5bd9d509b948f0066f2d1d814a6f475dafb3ddf1325" +dependencies = [ + "serde", + "serde_derive", + "solana-fee-calculator", + "solana-hash", + "solana-pubkey", + "solana-sha256-hasher", +] + +[[package]] +name = "solana-program" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "586469467e93ceb79048f8d8e3a619bf61d05396ee7de95cb40280301a589d05" +dependencies = [ + "bincode", + "blake3", + "borsh 0.10.4", + "borsh 1.5.7", + "bs58", + "bytemuck", + "console_error_panic_hook", + "console_log", + "getrandom 0.2.15", + "lazy_static", + "log", + "memoffset", + "num-bigint", + "num-derive 0.4.2", + "num-traits", + "rand 0.8.5", + "serde", + "serde_bytes", + "serde_derive", + "solana-account-info", + "solana-address-lookup-table-interface", + "solana-atomic-u64", + "solana-big-mod-exp", + "solana-bincode", + "solana-blake3-hasher", + "solana-borsh", + "solana-clock", + "solana-cpi", + "solana-decode-error", + "solana-define-syscall", + "solana-epoch-rewards", + "solana-epoch-schedule", + "solana-example-mocks", + "solana-feature-gate-interface", + "solana-fee-calculator", + "solana-hash", + "solana-instruction", + "solana-instructions-sysvar", + "solana-keccak-hasher", + "solana-last-restart-slot", + "solana-loader-v2-interface", + "solana-loader-v3-interface", + "solana-loader-v4-interface", + "solana-message", + "solana-msg", + "solana-native-token", + "solana-nonce", + "solana-program-entrypoint", + "solana-program-error", + "solana-program-memory", + "solana-program-option", + "solana-program-pack", + "solana-pubkey", + "solana-rent", + "solana-sanitize", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-secp256k1-recover", + "solana-serde-varint", + "solana-serialize-utils", + "solana-sha256-hasher", + "solana-short-vec", + "solana-slot-hashes", + "solana-slot-history", + "solana-stable-layout", + "solana-stake-interface", + "solana-system-interface", + "solana-sysvar", + "solana-sysvar-id", + "solana-vote-interface", + "thiserror 2.0.12", + "wasm-bindgen", +] + +[[package]] +name = "solana-program-entrypoint" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "473ffe73c68d93e9f2aa726ad2985fe52760052709aaab188100a42c618060ec" +dependencies = [ + "solana-account-info", + "solana-msg", + "solana-program-error", + "solana-pubkey", +] + +[[package]] +name = "solana-program-error" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8ae2c1a8d0d4ae865882d5770a7ebca92bab9c685e43f0461682c6c05a35bfa" +dependencies = [ + "borsh 1.5.7", + "num-traits", + "serde", + "serde_derive", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-pubkey", +] + +[[package]] +name = "solana-program-memory" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b0268f6c89825fb634a34bd0c3b8fdaeaecfc3728be1d622a8ee6dd577b60d4" +dependencies = [ + "num-traits", + "solana-define-syscall", +] + +[[package]] +name = "solana-program-option" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc677a2e9bc616eda6dbdab834d463372b92848b2bfe4a1ed4e4b4adba3397d0" + +[[package]] +name = "solana-program-pack" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "319f0ef15e6e12dc37c597faccb7d62525a509fec5f6975ecb9419efddeb277b" +dependencies = [ + "solana-program-error", +] + +[[package]] +name = "solana-pubkey" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40db1ff5a0f8aea2c158d78ab5f2cf897848964251d1df42fef78efd3c85b863" +dependencies = [ + "borsh 0.10.4", + "borsh 1.5.7", + "bs58", + "bytemuck", + "bytemuck_derive", + "curve25519-dalek", + "five8_const", + "getrandom 0.2.15", + "js-sys", + "num-traits", + "serde", + "serde_derive", + "solana-atomic-u64", + "solana-decode-error", + "solana-define-syscall", + "solana-sanitize", + "solana-sha256-hasher", + "wasm-bindgen", +] + +[[package]] +name = "solana-rent" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1aea8fdea9de98ca6e8c2da5827707fb3842833521b528a713810ca685d2480" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-sanitize" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61f1bc1357b8188d9c4a3af3fc55276e56987265eb7ad073ae6f8180ee54cecf" + +[[package]] +name = "solana-sdk-ids" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5d8b9cc68d5c88b062a33e23a6466722467dde0035152d8fb1afbcdf350a5f" +dependencies = [ + "solana-pubkey", +] + +[[package]] +name = "solana-sdk-macro" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86280da8b99d03560f6ab5aca9de2e38805681df34e0bb8f238e69b29433b9df" +dependencies = [ + "bs58", + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "solana-secp256k1-recover" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baa3120b6cdaa270f39444f5093a90a7b03d296d362878f7a6991d6de3bbe496" +dependencies = [ + "libsecp256k1 0.6.0", + "solana-define-syscall", + "thiserror 2.0.12", +] + +[[package]] +name = "solana-security-txt" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "468aa43b7edb1f9b7b7b686d5c3aeb6630dc1708e86e31343499dd5c4d775183" + +[[package]] +name = "solana-seed-derivable" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3beb82b5adb266c6ea90e5cf3967235644848eac476c5a1f2f9283a143b7c97f" +dependencies = [ + "solana-derivation-path", +] + +[[package]] +name = "solana-seed-phrase" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36187af2324f079f65a675ec22b31c24919cb4ac22c79472e85d819db9bbbc15" +dependencies = [ + "hmac 0.12.1", + "pbkdf2", + "sha2 0.10.8", +] + +[[package]] +name = "solana-serde-varint" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcc07d00200d82e6def2f7f7a45738e3406b17fe54a18adcf0defa16a97ccadb" +dependencies = [ + "serde", +] + +[[package]] +name = "solana-serialize-utils" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "817a284b63197d2b27afdba829c5ab34231da4a9b4e763466a003c40ca4f535e" +dependencies = [ + "solana-instruction", + "solana-pubkey", + "solana-sanitize", +] + +[[package]] +name = "solana-sha256-hasher" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0037386961c0d633421f53560ad7c80675c0447cba4d1bb66d60974dd486c7ea" +dependencies = [ + "sha2 0.10.8", + "solana-define-syscall", + "solana-hash", +] + +[[package]] +name = "solana-short-vec" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c54c66f19b9766a56fa0057d060de8378676cb64987533fa088861858fc5a69" +dependencies = [ + "serde", +] + +[[package]] +name = "solana-signature" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d251c8f3dc015f320b4161daac7f108156c837428e5a8cc61136d25beb11d6" +dependencies = [ + "bs58", + "solana-sanitize", +] + +[[package]] +name = "solana-signer" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c41991508a4b02f021c1342ba00bcfa098630b213726ceadc7cb032e051975b" +dependencies = [ + "solana-pubkey", + "solana-signature", + "solana-transaction-error", +] + +[[package]] +name = "solana-slot-hashes" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c8691982114513763e88d04094c9caa0376b867a29577939011331134c301ce" +dependencies = [ + "serde", + "serde_derive", + "solana-hash", + "solana-sdk-ids", + "solana-sysvar-id", +] + +[[package]] +name = "solana-slot-history" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97ccc1b2067ca22754d5283afb2b0126d61eae734fc616d23871b0943b0d935e" +dependencies = [ + "bv", + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sysvar-id", +] + +[[package]] +name = "solana-stable-layout" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f14f7d02af8f2bc1b5efeeae71bc1c2b7f0f65cd75bcc7d8180f2c762a57f54" +dependencies = [ + "solana-instruction", + "solana-pubkey", +] + +[[package]] +name = "solana-stake-interface" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5269e89fde216b4d7e1d1739cf5303f8398a1ff372a81232abbee80e554a838c" +dependencies = [ + "borsh 0.10.4", + "borsh 1.5.7", + "num-traits", + "serde", + "serde_derive", + "solana-clock", + "solana-cpi", + "solana-decode-error", + "solana-instruction", + "solana-program-error", + "solana-pubkey", + "solana-system-interface", + "solana-sysvar-id", +] + +[[package]] +name = "solana-system-interface" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94d7c18cb1a91c6be5f5a8ac9276a1d7c737e39a21beba9ea710ab4b9c63bc90" +dependencies = [ + "js-sys", + "num-traits", + "serde", + "serde_derive", + "solana-decode-error", + "solana-instruction", + "solana-pubkey", + "wasm-bindgen", +] + +[[package]] +name = "solana-sysvar" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf6b44740d7f0c9f375d045c165bc0aab4a90658f92d6835aeb0649afaeaff9a" +dependencies = [ + "base64 0.22.1", + "bincode", + "bytemuck", + "bytemuck_derive", + "lazy_static", + "serde", + "serde_derive", + "solana-account-info", + "solana-clock", + "solana-define-syscall", + "solana-epoch-rewards", + "solana-epoch-schedule", + "solana-fee-calculator", + "solana-hash", + "solana-instruction", + "solana-instructions-sysvar", + "solana-last-restart-slot", + "solana-program-entrypoint", + "solana-program-error", + "solana-program-memory", + "solana-pubkey", + "solana-rent", + "solana-sanitize", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-slot-hashes", + "solana-slot-history", + "solana-stake-interface", + "solana-sysvar-id", +] + +[[package]] +name = "solana-sysvar-id" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5762b273d3325b047cfda250787f8d796d781746860d5d0a746ee29f3e8812c1" +dependencies = [ + "solana-pubkey", + "solana-sdk-ids", +] + +[[package]] +name = "solana-transaction-error" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222a9dc8fdb61c6088baab34fc3a8b8473a03a7a5fd404ed8dd502fa79b67cb1" +dependencies = [ + "solana-instruction", + "solana-sanitize", +] + +[[package]] +name = "solana-vote-interface" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b630547b7f12ee742e1c5069951fedba0fe5cbd4786f6342a779384e2b11f71" +dependencies = [ + "bincode", + "num-derive 0.4.2", + "num-traits", + "serde", + "serde_derive", + "solana-clock", + "solana-decode-error", + "solana-hash", + "solana-instruction", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", + "solana-serde-varint", + "solana-serialize-utils", + "solana-short-vec", + "solana-system-interface", +] + +[[package]] +name = "solana-zk-sdk" +version = "2.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a891726b0eedc02be46f0cfd2685cafdd7a8ce9d9663f4f7cbd9c883d792896c" +dependencies = [ + "aes-gcm-siv", + "base64 0.22.1", + "bincode", + "bytemuck", + "bytemuck_derive", + "curve25519-dalek", + "itertools", + "js-sys", + "lazy_static", + "merlin", + "num-derive 0.4.2", + "num-traits", + "rand 0.8.5", + "serde", + "serde_derive", + "serde_json", + "sha3", + "solana-derivation-path", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", + "solana-seed-derivable", + "solana-seed-phrase", + "solana-signature", + "solana-signer", + "subtle", + "thiserror 2.0.12", + "wasm-bindgen", + "zeroize", +] + +[[package]] +name = "spl-associated-token-account" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76fee7d65013667032d499adc3c895e286197a35a0d3a4643c80e7fd3e9969e3" +dependencies = [ + "borsh 1.5.7", + "num-derive 0.4.2", + "num-traits", + "solana-program", + "spl-associated-token-account-client", + "spl-token", + "spl-token-2022", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-associated-token-account-client" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f8349dbcbe575f354f9a533a21f272f3eb3808a49e2fdc1c34393b88ba76cb" +dependencies = [ + "solana-instruction", + "solana-pubkey", +] + +[[package]] +name = "spl-discriminator" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7398da23554a31660f17718164e31d31900956054f54f52d5ec1be51cb4f4b3" +dependencies = [ + "bytemuck", + "solana-program-error", + "solana-sha256-hasher", + "spl-discriminator-derive", +] + +[[package]] +name = "spl-discriminator-derive" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9e8418ea6269dcfb01c712f0444d2c75542c04448b480e87de59d2865edc750" +dependencies = [ + "quote", + "spl-discriminator-syn", + "syn 2.0.100", +] + +[[package]] +name = "spl-discriminator-syn" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c1f05593b7ca9eac7caca309720f2eafb96355e037e6d373b909a80fe7b69b9" +dependencies = [ + "proc-macro2", + "quote", + "sha2 0.10.8", + "syn 2.0.100", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-elgamal-registry" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce0f668975d2b0536e8a8fd60e56a05c467f06021dae037f1d0cfed0de2e231d" +dependencies = [ + "bytemuck", + "solana-program", + "solana-zk-sdk", + "spl-pod", + "spl-token-confidential-transfer-proof-extraction", +] + +[[package]] +name = "spl-memo" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f09647c0974e33366efeb83b8e2daebb329f0420149e74d3a4bd2c08cf9f7cb" +dependencies = [ + "solana-account-info", + "solana-instruction", + "solana-msg", + "solana-program-entrypoint", + "solana-program-error", + "solana-pubkey", +] + +[[package]] +name = "spl-pod" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d994afaf86b779104b4a95ba9ca75b8ced3fdb17ee934e38cb69e72afbe17799" +dependencies = [ + "borsh 1.5.7", + "bytemuck", + "bytemuck_derive", + "num-derive 0.4.2", + "num-traits", + "solana-decode-error", + "solana-msg", + "solana-program-error", + "solana-program-option", + "solana-pubkey", + "solana-zk-sdk", + "thiserror 2.0.12", +] + +[[package]] +name = "spl-program-error" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d39b5186f42b2b50168029d81e58e800b690877ef0b30580d107659250da1d1" +dependencies = [ + "num-derive 0.4.2", + "num-traits", + "solana-program", + "spl-program-error-derive", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-program-error-derive" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d375dd76c517836353e093c2dbb490938ff72821ab568b545fd30ab3256b3e" +dependencies = [ + "proc-macro2", + "quote", + "sha2 0.10.8", + "syn 2.0.100", +] + +[[package]] +name = "spl-tlv-account-resolution" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd99ff1e9ed2ab86e3fd582850d47a739fec1be9f4661cba1782d3a0f26805f3" +dependencies = [ + "bytemuck", + "num-derive 0.4.2", + "num-traits", + "solana-account-info", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-program-error", + "solana-pubkey", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-type-length-value", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-token" +version = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed320a6c934128d4f7e54fe00e16b8aeaecf215799d060ae14f93378da6dc834" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive 0.4.2", + "num-traits", + "num_enum", + "solana-program", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-token-2022" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b27f7405010ef816587c944536b0eafbcc35206ab6ba0f2ca79f1d28e488f4f" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive 0.4.2", + "num-traits", + "num_enum", + "solana-program", + "solana-security-txt", + "solana-zk-sdk", + "spl-elgamal-registry", + "spl-memo", + "spl-pod", + "spl-token", + "spl-token-confidential-transfer-ciphertext-arithmetic", + "spl-token-confidential-transfer-proof-extraction", + "spl-token-confidential-transfer-proof-generation", + "spl-token-group-interface", + "spl-token-metadata-interface", + "spl-transfer-hook-interface", + "spl-type-length-value", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-token-confidential-transfer-ciphertext-arithmetic" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "170378693c5516090f6d37ae9bad2b9b6125069be68d9acd4865bbe9fc8499fd" +dependencies = [ + "base64 0.22.1", + "bytemuck", + "solana-curve25519", + "solana-zk-sdk", +] + +[[package]] +name = "spl-token-confidential-transfer-proof-extraction" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eff2d6a445a147c9d6dd77b8301b1e116c8299601794b558eafa409b342faf96" +dependencies = [ + "bytemuck", + "solana-curve25519", + "solana-program", + "solana-zk-sdk", + "spl-pod", + "thiserror 2.0.12", +] + +[[package]] +name = "spl-token-confidential-transfer-proof-generation" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8627184782eec1894de8ea26129c61303f1f0adeed65c20e0b10bc584f09356d" +dependencies = [ + "curve25519-dalek", + "solana-zk-sdk", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-token-group-interface" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d595667ed72dbfed8c251708f406d7c2814a3fa6879893b323d56a10bedfc799" +dependencies = [ + "bytemuck", + "num-derive 0.4.2", + "num-traits", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-program-error", + "solana-pubkey", + "spl-discriminator", + "spl-pod", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-token-metadata-interface" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfb9c89dbc877abd735f05547dcf9e6e12c00c11d6d74d8817506cab4c99fdbb" +dependencies = [ + "borsh 1.5.7", + "num-derive 0.4.2", + "num-traits", + "solana-borsh", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-program-error", + "solana-pubkey", + "spl-discriminator", + "spl-pod", + "spl-type-length-value", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-transfer-hook-interface" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4aa7503d52107c33c88e845e1351565050362c2314036ddf19a36cd25137c043" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive 0.4.2", + "num-traits", + "solana-account-info", + "solana-cpi", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-program-error", + "solana-pubkey", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-tlv-account-resolution", + "spl-type-length-value", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-type-length-value" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba70ef09b13af616a4c987797870122863cba03acc4284f226a4473b043923f9" +dependencies = [ + "bytemuck", + "num-derive 0.4.2", + "num-traits", + "solana-account-info", + "solana-decode-error", + "solana-msg", + "solana-program-error", + "spl-discriminator", + "spl-pod", + "thiserror 1.0.69", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +dependencies = [ + "thiserror-impl 2.0.12", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "tinyvec" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "toml" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + +[[package]] +name = "uriparse" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0200d0fc04d809396c2ad43f3c95da3582a2556eba8d453c1087f4120ee352ff" +dependencies = [ + "fnv", + "lazy_static", +] + +[[package]] +name = "verification_v2" +version = "0.1.0" +dependencies = [ + "anchor-lang", + "byteorder", + "libsecp256k1 0.7.2", + "wormhole-anchor-sdk", +] + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn 2.0.100", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63d3fcd9bba44b03821e7d699eeee959f3126dcc4aa8e4ae18ec617c2a5cea10" +dependencies = [ + "memchr", +] + +[[package]] +name = "wormhole-anchor-sdk" +version = "0.31.0" +source = "git+https://github.com/wormhole-foundation/wormhole-scaffolding.git#d2670240ce2dabe2d6505887bebfa030546e22ec" +dependencies = [ + "anchor-lang", + "anchor-spl", + "cfg-if", + "wormhole-io", +] + +[[package]] +name = "wormhole-io" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021a14ea7bcef9517ed9f81d4466c4a663dd90e726c5724707a976fa83ad8f3" + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "zerocopy-derive 0.7.35", +] + +[[package]] +name = "zerocopy" +version = "0.8.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" +dependencies = [ + "zerocopy-derive 0.8.24", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] diff --git a/src/solana/Cargo.toml b/src/solana/Cargo.toml new file mode 100644 index 0000000..f397704 --- /dev/null +++ b/src/solana/Cargo.toml @@ -0,0 +1,14 @@ +[workspace] +members = [ + "programs/*" +] +resolver = "2" + +[profile.release] +overflow-checks = true +lto = "fat" +codegen-units = 1 +[profile.release.build-override] +opt-level = 3 +incremental = false +codegen-units = 1 diff --git a/src/solana/migrations/deploy.ts b/src/solana/migrations/deploy.ts new file mode 100644 index 0000000..439431e --- /dev/null +++ b/src/solana/migrations/deploy.ts @@ -0,0 +1,12 @@ +// Migrations are an early feature. Currently, they're nothing more than this +// single deploy script that's invoked from the CLI, injecting a provider +// configured from the workspace's Anchor.toml. + +import * as anchor from "@coral-xyz/anchor"; + +module.exports = async function (provider: anchor.AnchorProvider) { + // Configure client to use the provider. + anchor.setProvider(provider); + + // Add your deploy script here. +}; diff --git a/src/solana/package.json b/src/solana/package.json new file mode 100644 index 0000000..4cbdbd0 --- /dev/null +++ b/src/solana/package.json @@ -0,0 +1,20 @@ +{ + "license": "ISC", + "scripts": { + "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", + "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" + }, + "dependencies": { + "@coral-xyz/anchor": "^0.31.0" + }, + "devDependencies": { + "chai": "^4.3.4", + "mocha": "^9.0.3", + "ts-mocha": "^10.0.0", + "@types/bn.js": "^5.1.0", + "@types/chai": "^4.3.0", + "@types/mocha": "^9.0.0", + "typescript": "^5.7.3", + "prettier": "^2.6.2" + } +} diff --git a/src/solana/programs/solana/Cargo.toml b/src/solana/programs/solana/Cargo.toml new file mode 100644 index 0000000..15101a2 --- /dev/null +++ b/src/solana/programs/solana/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "verification_v2" +version = "0.1.0" +description = "Wormhole threshold signature verification program" +edition = "2021" + +[lib] +crate-type = ["cdylib", "lib"] +name = "verification_v2" + +[features] +default = [] +cpi = ["no-entrypoint"] +no-entrypoint = [] +no-idl = [] +no-log-ix-name = [] +idl-build = ["anchor-lang/idl-build"] + +[dependencies] +anchor-lang = "0.31.0" +byteorder = "1.5.0" +libsecp256k1 = "0.7.2" +wormhole-anchor-sdk = { git = "https://github.com/wormhole-foundation/wormhole-scaffolding.git" } diff --git a/src/solana/programs/solana/Xargo.toml b/src/solana/programs/solana/Xargo.toml new file mode 100644 index 0000000..475fb71 --- /dev/null +++ b/src/solana/programs/solana/Xargo.toml @@ -0,0 +1,2 @@ +[target.bpfel-unknown-unknown.dependencies.std] +features = [] diff --git a/src/solana/programs/solana/src/append_threshold_key_message.rs b/src/solana/programs/solana/src/append_threshold_key_message.rs new file mode 100644 index 0000000..dd9fd6d --- /dev/null +++ b/src/solana/programs/solana/src/append_threshold_key_message.rs @@ -0,0 +1,55 @@ +use byteorder::{BigEndian, ReadBytesExt}; +use std::io::{Cursor, Read}; +use anchor_lang::prelude::*; + +pub struct AppendThresholdKeyMessage { + pub guardian_set_index: u32, + pub guardian_set_key: [u8; 20], + pub expiration_delay_seconds: u32, +} + +#[error_code] +pub enum AppendThresholdKeyDecodeError { + InvalidModule, + InvalidAction, +} + +// Module ID for the VerificationV2 contract, ASCII "TSS" +pub const MODULE_VERIFICATION_V2: [u8; 32] = [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x53, 0x53, +]; + +// Action ID for appending a threshold key +pub const ACTION_APPEND_THRESHOLD_KEY: u8 = 0x01; + +impl AppendThresholdKeyMessage { + pub fn deserialize(vaa_body: &[u8]) -> Result { + // Decode the VAA body + let mut cursor = Cursor::new(vaa_body); + let mut module = [0; 32]; + cursor.read_exact(&mut module)?; + let action = cursor.read_u8()?; + let guardian_set_index = cursor.read_u32::()?; + let mut guardian_set_key = [0u8; 20]; + cursor.read_exact(&mut guardian_set_key)?; + let expiration_delay_seconds = cursor.read_u32::()?; + + // Validate the module and action + if module != MODULE_VERIFICATION_V2 { + return Err(AppendThresholdKeyDecodeError::InvalidModule.into()); + } + + if action != ACTION_APPEND_THRESHOLD_KEY { + return Err(AppendThresholdKeyDecodeError::InvalidAction.into()); + } + + Ok( + Self { + guardian_set_index, + guardian_set_key, + expiration_delay_seconds, + } + ) + } +} diff --git a/src/solana/programs/solana/src/lib.rs b/src/solana/programs/solana/src/lib.rs new file mode 100644 index 0000000..f767a5c --- /dev/null +++ b/src/solana/programs/solana/src/lib.rs @@ -0,0 +1,192 @@ +#![allow(unexpected_cfgs)] + +declare_id!("CTyCJvaLgY18BTTY3M1ga1SmY5fuT3Jyu3j7s332Z3oz"); + +mod vaa; +mod append_threshold_key_message; + +use anchor_lang::prelude::*; +use anchor_lang::solana_program::clock::Clock; +use anchor_lang::solana_program::keccak::hash; + +use libsecp256k1::{Message, RecoveryId, Signature, recover}; + +use wormhole_anchor_sdk::wormhole::program::Wormhole; +use wormhole_anchor_sdk::wormhole::constants::CHAIN_ID_SOLANA; +use wormhole_anchor_sdk::wormhole::{SEED_PREFIX_POSTED_VAA, PostedVaaData}; + +use vaa::VAA; +use append_threshold_key_message::AppendThresholdKeyMessage; + +const GOVERNANCE_ADDRESS: [u8; 32] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4]; + +#[derive(Accounts)] +#[instruction(new_index: u32, vaa_hash: [u8; 32])] +pub struct AppendThresholdKey<'info> { + #[account(mut)] + pub payer: Signer<'info>, + + #[account( + seeds = [ + SEED_PREFIX_POSTED_VAA, + &vaa_hash + ], + bump, + seeds::program = wormhole_program.key + )] + pub vaa: Account<'info, PostedVaaData>, + + #[account( + init, + payer = payer, + space = 8 + ThresholdKey::INIT_SPACE, + seeds = [b"threshold_key", new_index.to_be_bytes().as_ref()], + bump, + )] + pub new_threshold_key: Account<'info, ThresholdKey>, + + #[account( + seeds = [b"threshold_key", &((new_index - 1).to_be_bytes())], + bump, + )] + pub old_threshold_key: Option>, + + pub wormhole_program: Program<'info, Wormhole>, + pub system_program: Program<'info, System>, +} + +#[derive(Accounts)] +#[instruction(vaa: Vec)] +pub struct VerifyVaa<'info> { + #[account( + seeds = [b"threshold_key", VAA::get_seed_bytes(&vaa)], + bump, + )] + pub threshold_key: Account<'info, ThresholdKey>, +} + +#[account] +#[derive(InitSpace)] +pub struct ThresholdKey { + pub bump: u8, + pub index: u32, // TODO: Is this needed? + pub key: [u8; 20], + pub expiration: u64, +} + +#[error_code] +pub enum VAAError { + #[msg("Invalid VAA version")] + InvalidVersion, + #[msg("Invalid VAA index")] + InvalidIndex, + #[msg("Guardian set expired")] + GuardianSetExpired, + #[msg("Invalid signature")] + InvalidSignature, + #[msg("Invalid governance chain ID")] + InvalidGovernanceChainId, + #[msg("Invalid governance address")] + InvalidGovernanceAddress, +} + +#[error_code] +pub enum AppendThresholdKeyError { + #[msg("Invalid governance chain ID")] + InvalidGovernanceChainId, + #[msg("Invalid governance address")] + InvalidGovernanceAddress, + #[msg("Index mismatch")] + IndexMismatch, + #[msg("Invalid old threshold key")] + InvalidOldThresholdKey, +} + +#[program] +pub mod verification_v2 { + use super::*; + + // TODO: Get the new index from the VAA? + pub fn append_threshold_key(ctx: Context, new_index: u32, _vaa_hash: [u8; 32]) -> Result<()> { + // Validate the VAA metadata + let vaa = &ctx.accounts.vaa; + if vaa.meta.emitter_chain != CHAIN_ID_SOLANA { + return Err(AppendThresholdKeyError::InvalidGovernanceChainId.into()); + } + + if vaa.meta.emitter_address != GOVERNANCE_ADDRESS { + return Err(AppendThresholdKeyError::InvalidGovernanceAddress.into()); + } + + // Decode the message + let message = AppendThresholdKeyMessage::deserialize(&vaa.payload)?; + + // Check the index matches the VAA index + if new_index != message.guardian_set_index { + return Err(AppendThresholdKeyError::IndexMismatch.into()); + } + + // Validate the old threshold key + if new_index == 0 { + if ctx.accounts.old_threshold_key.is_some() { + return Err(AppendThresholdKeyError::InvalidOldThresholdKey.into()); + } + } else { + if let Some(old_threshold_key) = &ctx.accounts.old_threshold_key { + if old_threshold_key.index != new_index - 1 { + return Err(AppendThresholdKeyError::InvalidOldThresholdKey.into()); + } + } else { + return Err(AppendThresholdKeyError::InvalidOldThresholdKey.into()); + } + } + + // Set the new threshold key + ctx.accounts.new_threshold_key.index = new_index; + ctx.accounts.new_threshold_key.key = message.guardian_set_key; + ctx.accounts.new_threshold_key.expiration = 0; + + // Set the old threshold key + if let Some(ref mut old_threshold_key) = &mut ctx.accounts.old_threshold_key { + let current_timestamp = Clock::get().unwrap().unix_timestamp as u64; + old_threshold_key.expiration = current_timestamp + message.expiration_delay_seconds as u64; + } + + Ok(()) + } + + pub fn verify_vaa(ctx: Context, raw_vaa: Vec) -> Result { + // Decode the VAA + let (vaa, double_hash) = VAA::deserialize(&raw_vaa)?; + + // Check if the VAA version is valid + if vaa.version != 2 { + return Err(VAAError::InvalidVersion.into()); + } + + // Check if the threshold key index matches the VAA index + let threshold_key = &mut ctx.accounts.threshold_key; + if threshold_key.index != vaa.guardian_set_index { + return Err(VAAError::InvalidIndex.into()); + } + + // Check if the threshold key has expired + if threshold_key.expiration != 0 && threshold_key.expiration < Clock::get().unwrap().unix_timestamp as u64 { + return Err(VAAError::GuardianSetExpired.into()); + } + + // Verify the VAA signature + let message = Message::parse(&double_hash); + let signature = Signature::parse_standard(&vaa.signature).map_err(|_| VAAError::InvalidSignature)?; + let recovery_id = RecoveryId::parse(vaa.recovery_id).map_err(|_| VAAError::InvalidSignature)?; + let recovered_key = recover(&message, &signature, &recovery_id).map_err(|_| VAAError::InvalidSignature)?; + let recovered_eth_key = &hash(&recovered_key.serialize()[1..]).to_bytes()[12..]; + + if recovered_eth_key != threshold_key.key { + return Err(VAAError::InvalidSignature.into()); + } + + // Return the VAA + Ok(vaa) + } +} diff --git a/src/solana/programs/solana/src/vaa.rs b/src/solana/programs/solana/src/vaa.rs new file mode 100644 index 0000000..d3befbf --- /dev/null +++ b/src/solana/programs/solana/src/vaa.rs @@ -0,0 +1,96 @@ +use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; +use std::io::{Cursor, Read, Write}; +use anchor_lang::prelude::*; +use anchor_lang::solana_program::keccak::hash; + +pub struct VAA { + // Header + pub version: u8, + pub guardian_set_index: u32, + pub signature: [u8; 64], + pub recovery_id: u8, + + // Body + pub timestamp: u64, + pub nonce: u64, + pub emitter_chain_id: u16, + pub emitter_address: [u8; 32], + pub sequence: u64, + pub consistency_level: u8, + pub payload: Vec, +} + +impl VAA { + pub const HEADER_SIZE: usize = 1 + 4 + 64 + 1; + pub const BODY_SIZE: usize = 8 + 8 + 2 + 32 + 8 + 1; + pub const PAYLOAD_OFFSET: usize = Self::HEADER_SIZE + Self::BODY_SIZE; + + pub fn get_seed_bytes(encoded_vaa: &[u8]) -> &[u8] { + // Extract the index from the encoded VAA + const INDEX_OFFSET: usize = 1; + const INDEX_SIZE: usize = (u32::BITS / u8::BITS) as usize; + &encoded_vaa[INDEX_OFFSET..INDEX_OFFSET + INDEX_SIZE] + } + + pub fn serialize(&self, data: &mut [u8]) -> Result<()> { + let mut cursor = Cursor::new(data); + + cursor.write_u8(self.version)?; + cursor.write_u32::(self.guardian_set_index)?; + cursor.write_all(&self.signature)?; + cursor.write_u8(self.recovery_id)?; + cursor.write_u64::(self.timestamp)?; + cursor.write_u64::(self.nonce)?; + cursor.write_u16::(self.emitter_chain_id)?; + cursor.write_all(&self.emitter_address)?; + cursor.write_u64::(self.sequence)?; + cursor.write_u8(self.consistency_level)?; + cursor.write_all(&self.payload)?; + + Ok(()) + } + + pub fn deserialize(data: &[u8]) -> Result<(Self, [u8; 32])> { + let mut cursor = Cursor::new(data); + + let version = cursor.read_u8()?; + let guardian_set_index = cursor.read_u32::()?; + let mut signature = [0; 64]; + cursor.read_exact(&mut signature)?; + let recovery_id = cursor.read_u8()?; + + let body_start = cursor.position() as usize; + + let timestamp = cursor.read_u64::()?; + let nonce = cursor.read_u64::()?; + let emitter_chain_id = cursor.read_u16::()?; + let mut emitter_address = [0; 32]; + cursor.read_exact(&mut emitter_address)?; + + let sequence = cursor.read_u64::()?; + let consistency_level = cursor.read_u8()?; + let mut payload = Vec::new(); + cursor.read_to_end(&mut payload)?; + + let double_hash = hash(&hash(&data[body_start..]).to_bytes()).to_bytes(); + + Ok( + ( + Self { + version, + guardian_set_index, + signature, + recovery_id, + timestamp, + nonce, + emitter_chain_id, + emitter_address, + sequence, + consistency_level, + payload, + }, + double_hash, + ) + ) + } +} diff --git a/src/solana/tests/solana.ts b/src/solana/tests/solana.ts new file mode 100644 index 0000000..61ecf62 --- /dev/null +++ b/src/solana/tests/solana.ts @@ -0,0 +1,16 @@ +import * as anchor from "@coral-xyz/anchor"; +import { Program } from "@coral-xyz/anchor"; +import { Solana } from "../target/types/solana"; + +describe("solana", () => { + // Configure the client to use the local cluster. + anchor.setProvider(anchor.AnchorProvider.env()); + + const program = anchor.workspace.solana as Program; + + it("Is initialized!", async () => { + // Add your test here. + const tx = await program.methods.initialize().rpc(); + console.log("Your transaction signature", tx); + }); +}); diff --git a/src/solana/tsconfig.json b/src/solana/tsconfig.json new file mode 100644 index 0000000..cd5d2e3 --- /dev/null +++ b/src/solana/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "types": ["mocha", "chai"], + "typeRoots": ["./node_modules/@types"], + "lib": ["es2015"], + "module": "commonjs", + "target": "es6", + "esModuleInterop": true + } +} diff --git a/src/solana/yarn.lock b/src/solana/yarn.lock new file mode 100644 index 0000000..3cb32ac --- /dev/null +++ b/src/solana/yarn.lock @@ -0,0 +1,1143 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/runtime@^7.25.0": + version "7.27.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.27.0.tgz#fbee7cf97c709518ecc1f590984481d5460d4762" + integrity sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw== + dependencies: + regenerator-runtime "^0.14.0" + +"@coral-xyz/anchor-errors@^0.31.0": + version "0.31.0" + resolved "https://registry.yarnpkg.com/@coral-xyz/anchor-errors/-/anchor-errors-0.31.0.tgz#dfc7329fca152b598842f68175efe5000825b51b" + integrity sha512-SUERksFSQ+4F11hkROIwHq4mcoSMXJxwVWLoklefi4dU679zVWFVcTq6O7otvjY8wlUaRXeE+iYcQWZTw2ll6w== + +"@coral-xyz/anchor@^0.31.0": + version "0.31.0" + resolved "https://registry.yarnpkg.com/@coral-xyz/anchor/-/anchor-0.31.0.tgz#76b84541e6fdfbd6c661584cdc418453a6416f12" + integrity sha512-Yb1NwP1s4cWhAw7wL7vOLHSWWw3cD5D9pRCVSeJpdqPaI+w7sfRLScnVJL6ViYMZynB7nAG/5HcUPKUnY0L9rw== + dependencies: + "@coral-xyz/anchor-errors" "^0.31.0" + "@coral-xyz/borsh" "^0.31.0" + "@noble/hashes" "^1.3.1" + "@solana/web3.js" "^1.69.0" + bn.js "^5.1.2" + bs58 "^4.0.1" + buffer-layout "^1.2.2" + camelcase "^6.3.0" + cross-fetch "^3.1.5" + eventemitter3 "^4.0.7" + pako "^2.0.3" + superstruct "^0.15.4" + toml "^3.0.0" + +"@coral-xyz/borsh@^0.31.0": + version "0.31.0" + resolved "https://registry.yarnpkg.com/@coral-xyz/borsh/-/borsh-0.31.0.tgz#eb77239b75f3ea9e771b1ee0821712caf664cb32" + integrity sha512-DwdQ5fuj+rGQCTKRnxnW1W2lvcpBaFc9m9M1TcGGlm+bwCcggmDgbLKLgF+LjIrKnc7Nd+bCACx5RA9YTK2I4Q== + dependencies: + bn.js "^5.1.2" + buffer-layout "^1.2.0" + +"@noble/curves@^1.4.2": + version "1.8.1" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.8.1.tgz#19bc3970e205c99e4bdb1c64a4785706bce497ff" + integrity sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ== + dependencies: + "@noble/hashes" "1.7.1" + +"@noble/hashes@1.7.1", "@noble/hashes@^1.3.1", "@noble/hashes@^1.4.0": + version "1.7.1" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.7.1.tgz#5738f6d765710921e7a751e00c20ae091ed8db0f" + integrity sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ== + +"@solana/buffer-layout@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@solana/buffer-layout/-/buffer-layout-4.0.1.tgz#b996235eaec15b1e0b5092a8ed6028df77fa6c15" + integrity sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA== + dependencies: + buffer "~6.0.3" + +"@solana/web3.js@^1.69.0": + version "1.98.0" + resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.98.0.tgz#21ecfe8198c10831df6f0cfde7f68370d0405917" + integrity sha512-nz3Q5OeyGFpFCR+erX2f6JPt3sKhzhYcSycBCSPkWjzSVDh/Rr1FqTVMRe58FKO16/ivTUcuJjeS5MyBvpkbzA== + dependencies: + "@babel/runtime" "^7.25.0" + "@noble/curves" "^1.4.2" + "@noble/hashes" "^1.4.0" + "@solana/buffer-layout" "^4.0.1" + agentkeepalive "^4.5.0" + bigint-buffer "^1.1.5" + bn.js "^5.2.1" + borsh "^0.7.0" + bs58 "^4.0.1" + buffer "6.0.3" + fast-stable-stringify "^1.0.0" + jayson "^4.1.1" + node-fetch "^2.7.0" + rpc-websockets "^9.0.2" + superstruct "^2.0.2" + +"@swc/helpers@^0.5.11": + version "0.5.15" + resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.15.tgz#79efab344c5819ecf83a43f3f9f811fc84b516d7" + integrity sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g== + dependencies: + tslib "^2.8.0" + +"@types/bn.js@^5.1.0": + version "5.1.6" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.6.tgz#9ba818eec0c85e4d3c679518428afdf611d03203" + integrity sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w== + dependencies: + "@types/node" "*" + +"@types/chai@^4.3.0": + version "4.3.20" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.20.tgz#cb291577ed342ca92600430841a00329ba05cecc" + integrity sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ== + +"@types/connect@^3.4.33": + version "3.4.38" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.38.tgz#5ba7f3bc4fbbdeaff8dded952e5ff2cc53f8d858" + integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== + dependencies: + "@types/node" "*" + +"@types/json5@^0.0.29": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== + +"@types/mocha@^9.0.0": + version "9.1.1" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-9.1.1.tgz#e7c4f1001eefa4b8afbd1eee27a237fee3bf29c4" + integrity sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw== + +"@types/node@*": + version "22.13.17" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.13.17.tgz#9ca6a81a0180cdcfd3719b9cf6c09186756e1754" + integrity sha512-nAJuQXoyPj04uLgu+obZcSmsfOenUg6DxPKogeUy6yNCFwWaj5sBF8/G/pNo8EtBJjAfSVgfIlugR/BCOleO+g== + dependencies: + undici-types "~6.20.0" + +"@types/node@^12.12.54": + version "12.20.55" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240" + integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ== + +"@types/uuid@^8.3.4": + version "8.3.4" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc" + integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw== + +"@types/ws@^7.4.4": + version "7.4.7" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" + integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== + dependencies: + "@types/node" "*" + +"@types/ws@^8.2.2": + version "8.18.1" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.1.tgz#48464e4bf2ddfd17db13d845467f6070ffea4aa9" + integrity sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg== + dependencies: + "@types/node" "*" + +"@ungap/promise-all-settled@1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" + integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== + +JSONStream@^1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" + integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== + dependencies: + jsonparse "^1.2.0" + through ">=2.2.7 <3" + +agentkeepalive@^4.5.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.6.0.tgz#35f73e94b3f40bf65f105219c623ad19c136ea6a" + integrity sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ== + dependencies: + humanize-ms "^1.2.1" + +ansi-colors@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +arrify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA== + +assertion-error@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" + integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base-x@^3.0.2: + version "3.0.11" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.11.tgz#40d80e2a1aeacba29792ccc6c5354806421287ff" + integrity sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA== + dependencies: + safe-buffer "^5.0.1" + +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +bigint-buffer@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/bigint-buffer/-/bigint-buffer-1.1.5.tgz#d038f31c8e4534c1f8d0015209bf34b4fa6dd442" + integrity sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA== + dependencies: + bindings "^1.3.0" + +binary-extensions@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" + integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== + +bindings@^1.3.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + +bn.js@^5.1.2, bn.js@^5.2.0, bn.js@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" + integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== + +borsh@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/borsh/-/borsh-0.7.0.tgz#6e9560d719d86d90dc589bca60ffc8a6c51fec2a" + integrity sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA== + dependencies: + bn.js "^5.2.0" + bs58 "^4.0.0" + text-encoding-utf-8 "^1.0.2" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@~3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" + integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== + dependencies: + fill-range "^7.1.1" + +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + +bs58@^4.0.0, bs58@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" + integrity sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw== + dependencies: + base-x "^3.0.2" + +buffer-from@^1.0.0, buffer-from@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +buffer-layout@^1.2.0, buffer-layout@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/buffer-layout/-/buffer-layout-1.2.2.tgz#b9814e7c7235783085f9ca4966a0cfff112259d5" + integrity sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA== + +buffer@6.0.3, buffer@^6.0.3, buffer@~6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + +bufferutil@^4.0.1: + version "4.0.9" + resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.9.tgz#6e81739ad48a95cad45a279588e13e95e24a800a" + integrity sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw== + dependencies: + node-gyp-build "^4.3.0" + +camelcase@^6.0.0, camelcase@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +chai@^4.3.4: + version "4.5.0" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.5.0.tgz#707e49923afdd9b13a8b0b47d33d732d13812fd8" + integrity sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw== + dependencies: + assertion-error "^1.1.0" + check-error "^1.0.3" + deep-eql "^4.1.3" + get-func-name "^2.0.2" + loupe "^2.3.6" + pathval "^1.1.1" + type-detect "^4.1.0" + +chalk@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +check-error@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.3.tgz#a6502e4312a7ee969f646e83bb3ddd56281bd694" + integrity sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg== + dependencies: + get-func-name "^2.0.2" + +chokidar@3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +commander@^2.20.3: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +cross-fetch@^3.1.5: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.2.0.tgz#34e9192f53bc757d6614304d9e5e6fb4edb782e3" + integrity sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q== + dependencies: + node-fetch "^2.7.0" + +debug@4.3.3: + version "4.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== + dependencies: + ms "2.1.2" + +decamelize@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" + integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== + +deep-eql@^4.1.3: + version "4.1.4" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.4.tgz#d0d3912865911bb8fac5afb4e3acfa6a28dc72b7" + integrity sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg== + dependencies: + type-detect "^4.0.0" + +delay@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/delay/-/delay-5.0.0.tgz#137045ef1b96e5071060dd5be60bf9334436bd1d" + integrity sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw== + +diff@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" + integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== + +diff@^3.1.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +es6-promise@^4.0.3: + version "4.2.8" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" + integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== + +es6-promisify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" + integrity sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ== + dependencies: + es6-promise "^4.0.3" + +escalade@^3.1.1: + version "3.2.0" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" + integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== + +escape-string-regexp@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eventemitter3@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + +eventemitter3@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" + integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== + +eyes@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" + integrity sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ== + +fast-stable-stringify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz#5c5543462b22aeeefd36d05b34e51c78cb86d313" + integrity sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag== + +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + +fill-range@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== + dependencies: + to-regex-range "^5.0.1" + +find-up@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-func-name@^2.0.1, get-func-name@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.2.tgz#0d7cf20cd13fda808669ffa88f4ffc7a3943fc41" + integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ== + +glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob@7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +growl@1.10.5: + version "1.10.5" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +he@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +humanize-ms@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" + integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== + dependencies: + ms "^2.0.0" + +ieee754@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-plain-obj@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +isomorphic-ws@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" + integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== + +jayson@^4.1.1: + version "4.1.3" + resolved "https://registry.yarnpkg.com/jayson/-/jayson-4.1.3.tgz#db9be2e4287d9fef4fc05b5fe367abe792c2eee8" + integrity sha512-LtXh5aYZodBZ9Fc3j6f2w+MTNcnxteMOrb+QgIouguGOulWi0lieEkOUg+HkjjFs0DGoWDds6bi4E9hpNFLulQ== + dependencies: + "@types/connect" "^3.4.33" + "@types/node" "^12.12.54" + "@types/ws" "^7.4.4" + JSONStream "^1.3.5" + commander "^2.20.3" + delay "^5.0.0" + es6-promisify "^5.0.0" + eyes "^0.1.8" + isomorphic-ws "^4.0.1" + json-stringify-safe "^5.0.1" + uuid "^8.3.2" + ws "^7.5.10" + +js-yaml@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +json-stringify-safe@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== + +json5@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" + integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== + dependencies: + minimist "^1.2.0" + +jsonparse@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" + integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +log-symbols@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +loupe@^2.3.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.7.tgz#6e69b7d4db7d3ab436328013d37d1c8c3540c697" + integrity sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA== + dependencies: + get-func-name "^2.0.1" + +make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + +minimatch@4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-4.2.1.tgz#40d9d511a46bdc4e563c22c3080cde9c0d8299b4" + integrity sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^3.0.4: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.0, minimist@^1.2.6: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +mkdirp@^0.5.1: + version "0.5.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + +mocha@^9.0.3: + version "9.2.2" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.2.tgz#d70db46bdb93ca57402c809333e5a84977a88fb9" + integrity sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g== + dependencies: + "@ungap/promise-all-settled" "1.1.2" + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.5.3" + debug "4.3.3" + diff "5.0.0" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.2.0" + growl "1.10.5" + he "1.2.0" + js-yaml "4.1.0" + log-symbols "4.1.0" + minimatch "4.2.1" + ms "2.1.3" + nanoid "3.3.1" + serialize-javascript "6.0.0" + strip-json-comments "3.1.1" + supports-color "8.1.1" + which "2.0.2" + workerpool "6.2.0" + yargs "16.2.0" + yargs-parser "20.2.4" + yargs-unparser "2.0.0" + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3, ms@^2.0.0: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +nanoid@3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" + integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== + +node-fetch@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" + integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== + dependencies: + whatwg-url "^5.0.0" + +node-gyp-build@^4.3.0: + version "4.8.4" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.4.tgz#8a70ee85464ae52327772a90d66c6077a900cfc8" + integrity sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ== + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +pako@^2.0.3: + version "2.1.0" + resolved "https://registry.yarnpkg.com/pako/-/pako-2.1.0.tgz#266cc37f98c7d883545d11335c00fbd4062c9a86" + integrity sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +pathval@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" + integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== + +picomatch@^2.0.4, picomatch@^2.2.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +prettier@^2.6.2: + version "2.8.8" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" + integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +regenerator-runtime@^0.14.0: + version "0.14.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" + integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +rpc-websockets@^9.0.2: + version "9.1.1" + resolved "https://registry.yarnpkg.com/rpc-websockets/-/rpc-websockets-9.1.1.tgz#5764336f3623ee1c5cc8653b7335183e3c0c78bd" + integrity sha512-1IXGM/TfPT6nfYMIXkJdzn+L4JEsmb0FL1O2OBjaH03V3yuUDdKFulGLMFG6ErV+8pZ5HVC0limve01RyO+saA== + dependencies: + "@swc/helpers" "^0.5.11" + "@types/uuid" "^8.3.4" + "@types/ws" "^8.2.2" + buffer "^6.0.3" + eventemitter3 "^5.0.1" + uuid "^8.3.2" + ws "^8.5.0" + optionalDependencies: + bufferutil "^4.0.1" + utf-8-validate "^5.0.2" + +safe-buffer@^5.0.1, safe-buffer@^5.1.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +serialize-javascript@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + +source-map-support@^0.5.6: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +string-width@^4.1.0, 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== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +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-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== + +strip-json-comments@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +superstruct@^0.15.4: + version "0.15.5" + resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-0.15.5.tgz#0f0a8d3ce31313f0d84c6096cd4fa1bfdedc9dab" + integrity sha512-4AOeU+P5UuE/4nOUkmcQdW5y7i9ndt1cQd/3iUe+LTz3RxESf/W/5lg4B74HbDMMv8PHnPnGCQFH45kBcrQYoQ== + +superstruct@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-2.0.2.tgz#3f6d32fbdc11c357deff127d591a39b996300c54" + integrity sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A== + +supports-color@8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +text-encoding-utf-8@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz#585b62197b0ae437e3c7b5d0af27ac1021e10d13" + integrity sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg== + +"through@>=2.2.7 <3": + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toml@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/toml/-/toml-3.0.0.tgz#342160f1af1904ec9d204d03a5d61222d762c5ee" + integrity sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w== + +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + +ts-mocha@^10.0.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/ts-mocha/-/ts-mocha-10.1.0.tgz#17a1c055f5f7733fd82447c4420740db87221bc8" + integrity sha512-T0C0Xm3/WqCuF2tpa0GNGESTBoKZaiqdUP8guNv4ZY316AFXlyidnrzQ1LUrCT0Wb1i3J0zFTgOh/55Un44WdA== + dependencies: + ts-node "7.0.1" + optionalDependencies: + tsconfig-paths "^3.5.0" + +ts-node@7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-7.0.1.tgz#9562dc2d1e6d248d24bc55f773e3f614337d9baf" + integrity sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw== + dependencies: + arrify "^1.0.0" + buffer-from "^1.1.0" + diff "^3.1.0" + make-error "^1.1.1" + minimist "^1.2.0" + mkdirp "^0.5.1" + source-map-support "^0.5.6" + yn "^2.0.0" + +tsconfig-paths@^3.5.0: + version "3.15.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz#5299ec605e55b1abb23ec939ef15edaf483070d4" + integrity sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg== + dependencies: + "@types/json5" "^0.0.29" + json5 "^1.0.2" + minimist "^1.2.6" + strip-bom "^3.0.0" + +tslib@^2.8.0: + version "2.8.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" + integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== + +type-detect@^4.0.0, type-detect@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.1.0.tgz#deb2453e8f08dcae7ae98c626b13dddb0155906c" + integrity sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw== + +typescript@^5.7.3: + version "5.8.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.8.2.tgz#8170b3702f74b79db2e5a96207c15e65807999e4" + integrity sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ== + +undici-types@~6.20.0: + version "6.20.0" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.20.0.tgz#8171bf22c1f588d1554d55bf204bc624af388433" + integrity sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg== + +utf-8-validate@^5.0.2: + version "5.0.10" + resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz#d7d10ea39318171ca982718b6b96a8d2442571a2" + integrity sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ== + dependencies: + node-gyp-build "^4.3.0" + +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + +which@2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +workerpool@6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.0.tgz#827d93c9ba23ee2019c3ffaff5c27fccea289e8b" + integrity sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A== + +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" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +ws@^7.5.10: + version "7.5.10" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9" + integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== + +ws@^8.5.0: + version "8.18.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.1.tgz#ea131d3784e1dfdff91adb0a4a116b127515e3cb" + integrity sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yargs-parser@20.2.4: + version "20.2.4" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" + integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== + +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs-unparser@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== + dependencies: + camelcase "^6.0.0" + decamelize "^4.0.0" + flat "^5.0.2" + is-plain-obj "^2.1.0" + +yargs@16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yn@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a" + integrity sha512-uTv8J/wiWTgUTg+9vLTi//leUl5vDQS6uii/emeTb2ssY7vl6QWf2fFbIIGjnhjvbdKlU0ed7QPgY1htTC86jQ== + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== From a5fcd5fe0c66429280d139c2f11d7260478ef39c Mon Sep 17 00:00:00 2001 From: Joshua Averett Date: Thu, 17 Apr 2025 12:53:52 -0700 Subject: [PATCH 10/53] Clean up account verification and a few other updates --- src/solana/Cargo.lock | 30 +++--- .../{solana => verification_v2}/Cargo.toml | 0 .../{solana => verification_v2}/Xargo.toml | 0 .../src/append_threshold_key_message.rs | 14 +-- .../{solana => verification_v2}/src/lib.rs | 94 ++++++------------- .../{solana => verification_v2}/src/vaa.rs | 23 ++--- 6 files changed, 57 insertions(+), 104 deletions(-) rename src/solana/programs/{solana => verification_v2}/Cargo.toml (100%) rename src/solana/programs/{solana => verification_v2}/Xargo.toml (100%) rename src/solana/programs/{solana => verification_v2}/src/append_threshold_key_message.rs (83%) rename src/solana/programs/{solana => verification_v2}/src/lib.rs (55%) rename src/solana/programs/{solana => verification_v2}/src/vaa.rs (73%) diff --git a/src/solana/Cargo.lock b/src/solana/Cargo.lock index b6cf32c..68d54bb 100644 --- a/src/solana/Cargo.lock +++ b/src/solana/Cargo.lock @@ -256,9 +256,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.97" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" [[package]] name = "arrayref" @@ -823,9 +823,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.171" +version = "0.2.172" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" +checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" [[package]] name = "libsecp256k1" @@ -1139,9 +1139,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.94" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] @@ -1527,9 +1527,9 @@ dependencies = [ [[package]] name = "solana-curve25519" -version = "2.2.8" +version = "2.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d9499a822cd1acdac4fcec1acb500819f84b2f83042d6ae0d19cc45b32747f9" +checksum = "4c7794a2cbb70f6ea1026b37c9a9418f4dc89de9abeb502afb01d1bac0978fdd" dependencies = [ "bytemuck", "bytemuck_derive", @@ -1952,9 +1952,9 @@ dependencies = [ [[package]] name = "solana-pubkey" -version = "2.2.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40db1ff5a0f8aea2c158d78ab5f2cf897848964251d1df42fef78efd3c85b863" +checksum = "cad77cf9f30b971a1eec48dde6a863dcac60ba005a34dfde23736afa5c7ac667" dependencies = [ "borsh 0.10.4", "borsh 1.5.7", @@ -2246,9 +2246,9 @@ dependencies = [ [[package]] name = "solana-vote-interface" -version = "2.2.3" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b630547b7f12ee742e1c5069951fedba0fe5cbd4786f6342a779384e2b11f71" +checksum = "78f039b0788337bedc6c5450d2f237718f938defb5ce0e0ad8ef507e78dcd370" dependencies = [ "bincode", "num-derive 0.4.2", @@ -2270,9 +2270,9 @@ dependencies = [ [[package]] name = "solana-zk-sdk" -version = "2.2.8" +version = "2.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a891726b0eedc02be46f0cfd2685cafdd7a8ce9d9663f4f7cbd9c883d792896c" +checksum = "b1cbd4a3f7dbd027fcd55bb5ecbe980c52fff099dc83b74a3555ae2a724885fb" dependencies = [ "aes-gcm-siv", "base64 0.22.1", @@ -2960,7 +2960,7 @@ dependencies = [ [[package]] name = "wormhole-anchor-sdk" version = "0.31.0" -source = "git+https://github.com/wormhole-foundation/wormhole-scaffolding.git#d2670240ce2dabe2d6505887bebfa030546e22ec" +source = "git+https://github.com/wormhole-foundation/wormhole-scaffolding.git#3be80a92579b108b5d6fffe234c6e18322e2c3b6" dependencies = [ "anchor-lang", "anchor-spl", diff --git a/src/solana/programs/solana/Cargo.toml b/src/solana/programs/verification_v2/Cargo.toml similarity index 100% rename from src/solana/programs/solana/Cargo.toml rename to src/solana/programs/verification_v2/Cargo.toml diff --git a/src/solana/programs/solana/Xargo.toml b/src/solana/programs/verification_v2/Xargo.toml similarity index 100% rename from src/solana/programs/solana/Xargo.toml rename to src/solana/programs/verification_v2/Xargo.toml diff --git a/src/solana/programs/solana/src/append_threshold_key_message.rs b/src/solana/programs/verification_v2/src/append_threshold_key_message.rs similarity index 83% rename from src/solana/programs/solana/src/append_threshold_key_message.rs rename to src/solana/programs/verification_v2/src/append_threshold_key_message.rs index dd9fd6d..596a702 100644 --- a/src/solana/programs/solana/src/append_threshold_key_message.rs +++ b/src/solana/programs/verification_v2/src/append_threshold_key_message.rs @@ -3,8 +3,8 @@ use std::io::{Cursor, Read}; use anchor_lang::prelude::*; pub struct AppendThresholdKeyMessage { - pub guardian_set_index: u32, - pub guardian_set_key: [u8; 20], + pub tss_index: u32, + pub tss_key: [u8; 20], pub expiration_delay_seconds: u32, } @@ -30,9 +30,9 @@ impl AppendThresholdKeyMessage { let mut module = [0; 32]; cursor.read_exact(&mut module)?; let action = cursor.read_u8()?; - let guardian_set_index = cursor.read_u32::()?; - let mut guardian_set_key = [0u8; 20]; - cursor.read_exact(&mut guardian_set_key)?; + let tss_index = cursor.read_u32::()?; + let mut tss_key = [0u8; 20]; + cursor.read_exact(&mut tss_key)?; let expiration_delay_seconds = cursor.read_u32::()?; // Validate the module and action @@ -46,8 +46,8 @@ impl AppendThresholdKeyMessage { Ok( Self { - guardian_set_index, - guardian_set_key, + tss_index, + tss_key, expiration_delay_seconds, } ) diff --git a/src/solana/programs/solana/src/lib.rs b/src/solana/programs/verification_v2/src/lib.rs similarity index 55% rename from src/solana/programs/solana/src/lib.rs rename to src/solana/programs/verification_v2/src/lib.rs index f767a5c..23adaf3 100644 --- a/src/solana/programs/solana/src/lib.rs +++ b/src/solana/programs/verification_v2/src/lib.rs @@ -13,7 +13,7 @@ use libsecp256k1::{Message, RecoveryId, Signature, recover}; use wormhole_anchor_sdk::wormhole::program::Wormhole; use wormhole_anchor_sdk::wormhole::constants::CHAIN_ID_SOLANA; -use wormhole_anchor_sdk::wormhole::{SEED_PREFIX_POSTED_VAA, PostedVaaData}; +use wormhole_anchor_sdk::wormhole::{PostedVaaData}; use vaa::VAA; use append_threshold_key_message::AppendThresholdKeyMessage; @@ -21,18 +21,14 @@ use append_threshold_key_message::AppendThresholdKeyMessage; const GOVERNANCE_ADDRESS: [u8; 32] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4]; #[derive(Accounts)] -#[instruction(new_index: u32, vaa_hash: [u8; 32])] pub struct AppendThresholdKey<'info> { #[account(mut)] pub payer: Signer<'info>, #[account( - seeds = [ - SEED_PREFIX_POSTED_VAA, - &vaa_hash - ], - bump, - seeds::program = wormhole_program.key + owner = wormhole_program.key(), + constraint = vaa.meta.emitter_chain == CHAIN_ID_SOLANA + && vaa.meta.emitter_address == GOVERNANCE_ADDRESS, )] pub vaa: Account<'info, PostedVaaData>, @@ -40,14 +36,12 @@ pub struct AppendThresholdKey<'info> { init, payer = payer, space = 8 + ThresholdKey::INIT_SPACE, - seeds = [b"threshold_key", new_index.to_be_bytes().as_ref()], - bump, )] pub new_threshold_key: Account<'info, ThresholdKey>, #[account( - seeds = [b"threshold_key", &((new_index - 1).to_be_bytes())], - bump, + mut, + constraint = old_threshold_key.expiration_timestamp == 0, )] pub old_threshold_key: Option>, @@ -59,8 +53,7 @@ pub struct AppendThresholdKey<'info> { #[instruction(vaa: Vec)] pub struct VerifyVaa<'info> { #[account( - seeds = [b"threshold_key", VAA::get_seed_bytes(&vaa)], - bump, + constraint = threshold_key.is_unexpired(), )] pub threshold_key: Account<'info, ThresholdKey>, } @@ -68,10 +61,15 @@ pub struct VerifyVaa<'info> { #[account] #[derive(InitSpace)] pub struct ThresholdKey { - pub bump: u8, - pub index: u32, // TODO: Is this needed? + pub index: u32, pub key: [u8; 20], - pub expiration: u64, + pub expiration_timestamp: u64, +} + +impl ThresholdKey { + pub fn is_unexpired(&self) -> bool { + self.expiration_timestamp == 0 || self.expiration_timestamp > Clock::get().unwrap().unix_timestamp as u64 + } } #[error_code] @@ -84,10 +82,6 @@ pub enum VAAError { GuardianSetExpired, #[msg("Invalid signature")] InvalidSignature, - #[msg("Invalid governance chain ID")] - InvalidGovernanceChainId, - #[msg("Invalid governance address")] - InvalidGovernanceAddress, } #[error_code] @@ -106,50 +100,25 @@ pub enum AppendThresholdKeyError { pub mod verification_v2 { use super::*; - // TODO: Get the new index from the VAA? - pub fn append_threshold_key(ctx: Context, new_index: u32, _vaa_hash: [u8; 32]) -> Result<()> { - // Validate the VAA metadata - let vaa = &ctx.accounts.vaa; - if vaa.meta.emitter_chain != CHAIN_ID_SOLANA { - return Err(AppendThresholdKeyError::InvalidGovernanceChainId.into()); - } + pub fn append_threshold_key(ctx: Context) -> Result<()> { + // Decode the VAA payload + let message = AppendThresholdKeyMessage::deserialize(&ctx.accounts.vaa.payload)?; - if vaa.meta.emitter_address != GOVERNANCE_ADDRESS { - return Err(AppendThresholdKeyError::InvalidGovernanceAddress.into()); - } - - // Decode the message - let message = AppendThresholdKeyMessage::deserialize(&vaa.payload)?; - - // Check the index matches the VAA index - if new_index != message.guardian_set_index { + // Validate the message index + let expected_index = ctx.accounts.old_threshold_key.as_ref().map_or(0, |key| key.index + 1); + if message.tss_index != expected_index { return Err(AppendThresholdKeyError::IndexMismatch.into()); } - // Validate the old threshold key - if new_index == 0 { - if ctx.accounts.old_threshold_key.is_some() { - return Err(AppendThresholdKeyError::InvalidOldThresholdKey.into()); - } - } else { - if let Some(old_threshold_key) = &ctx.accounts.old_threshold_key { - if old_threshold_key.index != new_index - 1 { - return Err(AppendThresholdKeyError::InvalidOldThresholdKey.into()); - } - } else { - return Err(AppendThresholdKeyError::InvalidOldThresholdKey.into()); - } - } - // Set the new threshold key - ctx.accounts.new_threshold_key.index = new_index; - ctx.accounts.new_threshold_key.key = message.guardian_set_key; - ctx.accounts.new_threshold_key.expiration = 0; + ctx.accounts.new_threshold_key.index = message.tss_index; + ctx.accounts.new_threshold_key.key = message.tss_key; + ctx.accounts.new_threshold_key.expiration_timestamp = 0; - // Set the old threshold key + // Set the old threshold key expiration timestamp if let Some(ref mut old_threshold_key) = &mut ctx.accounts.old_threshold_key { let current_timestamp = Clock::get().unwrap().unix_timestamp as u64; - old_threshold_key.expiration = current_timestamp + message.expiration_delay_seconds as u64; + old_threshold_key.expiration_timestamp = current_timestamp + message.expiration_delay_seconds as u64; } Ok(()) @@ -157,7 +126,7 @@ pub mod verification_v2 { pub fn verify_vaa(ctx: Context, raw_vaa: Vec) -> Result { // Decode the VAA - let (vaa, double_hash) = VAA::deserialize(&raw_vaa)?; + let (vaa, vaa_hash) = VAA::deserialize(&raw_vaa)?; // Check if the VAA version is valid if vaa.version != 2 { @@ -166,17 +135,12 @@ pub mod verification_v2 { // Check if the threshold key index matches the VAA index let threshold_key = &mut ctx.accounts.threshold_key; - if threshold_key.index != vaa.guardian_set_index { + if threshold_key.index != vaa.tss_index { return Err(VAAError::InvalidIndex.into()); } - // Check if the threshold key has expired - if threshold_key.expiration != 0 && threshold_key.expiration < Clock::get().unwrap().unix_timestamp as u64 { - return Err(VAAError::GuardianSetExpired.into()); - } - // Verify the VAA signature - let message = Message::parse(&double_hash); + let message = Message::parse(&vaa_hash); let signature = Signature::parse_standard(&vaa.signature).map_err(|_| VAAError::InvalidSignature)?; let recovery_id = RecoveryId::parse(vaa.recovery_id).map_err(|_| VAAError::InvalidSignature)?; let recovered_key = recover(&message, &signature, &recovery_id).map_err(|_| VAAError::InvalidSignature)?; diff --git a/src/solana/programs/solana/src/vaa.rs b/src/solana/programs/verification_v2/src/vaa.rs similarity index 73% rename from src/solana/programs/solana/src/vaa.rs rename to src/solana/programs/verification_v2/src/vaa.rs index d3befbf..62d3c0f 100644 --- a/src/solana/programs/solana/src/vaa.rs +++ b/src/solana/programs/verification_v2/src/vaa.rs @@ -6,7 +6,7 @@ use anchor_lang::solana_program::keccak::hash; pub struct VAA { // Header pub version: u8, - pub guardian_set_index: u32, + pub tss_index: u32, pub signature: [u8; 64], pub recovery_id: u8, @@ -21,22 +21,11 @@ pub struct VAA { } impl VAA { - pub const HEADER_SIZE: usize = 1 + 4 + 64 + 1; - pub const BODY_SIZE: usize = 8 + 8 + 2 + 32 + 8 + 1; - pub const PAYLOAD_OFFSET: usize = Self::HEADER_SIZE + Self::BODY_SIZE; - - pub fn get_seed_bytes(encoded_vaa: &[u8]) -> &[u8] { - // Extract the index from the encoded VAA - const INDEX_OFFSET: usize = 1; - const INDEX_SIZE: usize = (u32::BITS / u8::BITS) as usize; - &encoded_vaa[INDEX_OFFSET..INDEX_OFFSET + INDEX_SIZE] - } - pub fn serialize(&self, data: &mut [u8]) -> Result<()> { let mut cursor = Cursor::new(data); cursor.write_u8(self.version)?; - cursor.write_u32::(self.guardian_set_index)?; + cursor.write_u32::(self.tss_index)?; cursor.write_all(&self.signature)?; cursor.write_u8(self.recovery_id)?; cursor.write_u64::(self.timestamp)?; @@ -54,7 +43,7 @@ impl VAA { let mut cursor = Cursor::new(data); let version = cursor.read_u8()?; - let guardian_set_index = cursor.read_u32::()?; + let tss_index = cursor.read_u32::()?; let mut signature = [0; 64]; cursor.read_exact(&mut signature)?; let recovery_id = cursor.read_u8()?; @@ -72,13 +61,13 @@ impl VAA { let mut payload = Vec::new(); cursor.read_to_end(&mut payload)?; - let double_hash = hash(&hash(&data[body_start..]).to_bytes()).to_bytes(); + let hash = hash(&data[body_start..]).to_bytes(); Ok( ( Self { version, - guardian_set_index, + tss_index, signature, recovery_id, timestamp, @@ -89,7 +78,7 @@ impl VAA { consistency_level, payload, }, - double_hash, + hash, ) ) } From 35e9c34c5728b98c641e03ddf4b245a97a4c415f Mon Sep 17 00:00:00 2001 From: NoiTaTuM Date: Sat, 19 Apr 2025 08:58:47 -0300 Subject: [PATCH 11/53] Add Guardian TLS Registration to the contract --- src/evm/GuardianRegistryVerification.sol | 65 ++++++++++++++++++++++++ src/evm/VerificationV2.sol | 48 +++++++++++++++-- 2 files changed, 108 insertions(+), 5 deletions(-) create mode 100644 src/evm/GuardianRegistryVerification.sol diff --git a/src/evm/GuardianRegistryVerification.sol b/src/evm/GuardianRegistryVerification.sol new file mode 100644 index 0000000..ae0e943 --- /dev/null +++ b/src/evm/GuardianRegistryVerification.sol @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: Apache 2 + +pragma solidity ^0.8.0; + +import "./GuardianSetVerification.sol"; +import {eagerOr} from "wormhole-sdk/Utils.sol"; +import {BytesParsing} from "wormhole-sdk/libraries/BytesParsing.sol"; +import {VaaLib} from "wormhole-sdk/libraries/VaaLib.sol"; +import "./WormholeVerifier.sol"; + +error RegistrationMessageExpired(); + +contract GuardianRegistryVerification { + using BytesParsing for bytes; + using VaaLib for bytes; + + mapping (uint32 => bytes32[]) private _guardianTLSKeys; + + function registerTLSKey( + uint32 guardianSetIndex, + uint8 guardianIndex, + bytes32 tlsKey, + uint guardianSetSize + ) internal { + unchecked { + if (_guardianTLSKeys[guardianSetIndex].length == 0) { + _guardianTLSKeys[guardianSetIndex] = new bytes32[](guardianSetSize); + } + _guardianTLSKeys[guardianSetIndex][guardianIndex] = tlsKey; + } + } + + function getTLSKeys(uint32 guardianSetIndex) public view returns (bytes32[] memory tlsKeys) { + unchecked { + return _guardianTLSKeys[guardianSetIndex]; + } + } + + function verifyRegisterTLSKey( + address[] memory guardianAddrs, + uint32 guardianSetIndex, + uint32 expirationTime, + bytes32 tlsKey, + uint8 guardianIndex, + bytes32 r, bytes32 s, uint8 v + ) public view { + unchecked { + if (expirationTime < block.timestamp) revert RegistrationMessageExpired(); + bytes32 dataHash = keccak256(abi.encodePacked(guardianSetIndex, expirationTime, tlsKey)); + if (_failsVerificationSingleGuardian(dataHash, guardianIndex, r, s, v, guardianAddrs)) + revert VerificationFailed(); + } + } + + function _failsVerificationSingleGuardian( + bytes32 dataHash, + uint guardianIndex, + bytes32 r, bytes32 s, uint8 v, + address[] memory guardians + ) private pure returns (bool) { + address signatory = ecrecover(dataHash, v, r, s); + address guardian = guardians[guardianIndex]; + return signatory != guardian; + } +} diff --git a/src/evm/VerificationV2.sol b/src/evm/VerificationV2.sol index 8f85e44..0966d67 100644 --- a/src/evm/VerificationV2.sol +++ b/src/evm/VerificationV2.sol @@ -8,10 +8,12 @@ import {RawDispatcher} from "wormhole-sdk/RawDispatcher.sol"; import {CHAIN_ID_SOLANA} from "wormhole-sdk/constants/Chains.sol"; import {ThresholdVerification} from "./ThresholdVerification.sol"; import {GuardianSetVerification} from "./GuardianSetVerification.sol"; +import {GuardianRegistryVerification} from "./GuardianRegistryVerification.sol"; // Raw dispatch operation IDs for exec uint8 constant OP_GOVERNANCE = 0x00; uint8 constant OP_PULL_GUARDIAN_SETS = 0x01; +uint8 constant OP_REGISTER_TLS_KEY = 0x02; // Raw dispatch operation IDs for get uint8 constant OP_VERIFY = 0x20; @@ -19,6 +21,7 @@ uint8 constant OP_THRESHOLD_GET_CURRENT = 0x21; uint8 constant OP_THRESHOLD_GET = 0x22; uint8 constant OP_GUARDIAN_SET_GET_CURRENT = 0x23; uint8 constant OP_GUARDIAN_SET_GET = 0x24; +uint8 constant OP_GUARDIAN_TLS_GET = 0x25; // Emitter address for the VerificationV2 contract bytes32 constant GOVERNANCE_ADDRESS = bytes32(0x0000000000000000000000000000000000000000000000000000000000000004); @@ -29,7 +32,9 @@ bytes32 constant MODULE_VERIFICATION_V2 = bytes32(0x0000000000000000000000000000 // Action ID for appending a threshold key uint8 constant ACTION_APPEND_THRESHOLD_KEY = 0x01; -contract VerificationV2 is RawDispatcher, ThresholdVerification, GuardianSetVerification { +contract VerificationV2 is + RawDispatcher, ThresholdVerification, GuardianSetVerification, GuardianRegistryVerification +{ using BytesParsing for bytes; using VaaLib for bytes; using {BytesParsing.checkLength} for uint; @@ -42,10 +47,13 @@ contract VerificationV2 is RawDispatcher, ThresholdVerification, GuardianSetVeri error InvalidGovernanceChainId(); error InvalidGovernanceAddress(); - constructor( - address coreV1, - uint pullLimit - ) ThresholdVerification() GuardianSetVerification(coreV1, pullLimit) {} + error GuardianSetIsNotCurrent(); + + constructor(address coreV1, uint pullLimit) + ThresholdVerification() + GuardianSetVerification(coreV1, pullLimit) + GuardianRegistryVerification() + {} function _decodeAndVerifyVaa(bytes calldata encodedVaa) internal view returns ( uint32 timestamp, @@ -139,7 +147,29 @@ contract VerificationV2 is RawDispatcher, ThresholdVerification, GuardianSetVeri (limit, offset) = data.asUint32CdUnchecked(offset); pullGuardianSets(limit); + } else if (op == OP_REGISTER_TLS_KEY) { + uint32 guardianSetIndex; + (guardianSetIndex, offset) = data.asUint32CdUnchecked(offset); + uint32 expirationTime; + (expirationTime, offset) = data.asUint32CdUnchecked(offset); + bytes32 tlsKey; + (tlsKey, offset) = data.asBytes32CdUnchecked(offset); + uint8 guardianIndex; bytes32 r; bytes32 s; uint8 v; + (guardianIndex, r, s, v, offset) = data.decodeGuardianSignatureCdUnchecked(offset); + // We only allow registrations for the current guardian set + (uint32 currentSetIndex, address[] memory guardianAddrs) = this.getCurrentGuardianSetInfo(); + if (guardianSetIndex != currentSetIndex) revert GuardianSetIsNotCurrent(); + verifyRegisterTLSKey( + guardianAddrs, + guardianSetIndex, + expirationTime, + tlsKey, + guardianIndex, + r, s, v + ); + registerTLSKey(guardianSetIndex, guardianIndex, tlsKey, guardianAddrs.length); } + // TODO: Isn't this missing an else revert? } // Verify the data has been consumed @@ -197,7 +227,15 @@ contract VerificationV2 is RawDispatcher, ThresholdVerification, GuardianSetVeri (index, offset) = data.asUint32CdUnchecked(offset); (uint32 expirationTime, address[] memory guardianSetAddrs) = getGuardianSetInfo(index); result = abi.encodePacked(result, expirationTime, guardianSetAddrs); + } else if (op == OP_GUARDIAN_TLS_GET) { + uint32 guardianSetIndex; + (guardianSetIndex, offset) = data.asUint32CdUnchecked(offset); + uint8 guardianIndex; + (guardianIndex, offset) = data.asUint8CdUnchecked(offset); + bytes32[] memory tlsKeys = getTLSKeys(guardianSetIndex); + result = abi.encodePacked(result, tlsKeys); } + // TODO: Isn't this missing an else revert? } // Verify the data has been consumed From 187054fe1a959d2fb58318b23aef8649399a3a44 Mon Sep 17 00:00:00 2001 From: Joshua Averett Date: Tue, 22 Apr 2025 09:49:22 -0700 Subject: [PATCH 12/53] Minor changes and cargo update. Currently solana does not build. --- src/evm/ThresholdVerification.sol | 10 +- src/solana/Cargo.lock | 60 +- src/solana/package-lock.json | 2064 +++++++++++++++++ src/solana/package.json | 14 +- .../programs/verification_v2/Cargo.toml | 14 +- .../programs/verification_v2/src/lib.rs | 67 +- .../programs/verification_v2/src/vaa.rs | 12 +- src/solana/yarn.lock | 431 ++-- 8 files changed, 2377 insertions(+), 295 deletions(-) create mode 100644 src/solana/package-lock.json diff --git a/src/evm/ThresholdVerification.sol b/src/evm/ThresholdVerification.sol index 5601f6e..21b8f7e 100644 --- a/src/evm/ThresholdVerification.sol +++ b/src/evm/ThresholdVerification.sol @@ -61,9 +61,9 @@ contract ThresholdVerification { (version, offset) = encodedVaa.asUint8CdUnchecked(offset); if (version != 2) revert VaaLib.InvalidVersion(version); - // Decode the guardian set index - uint32 guardianSetIndex; - (guardianSetIndex, offset) = encodedVaa.asUint32CdUnchecked(offset); + // Decode the TSS key index + uint32 tssIndex; + (tssIndex, offset) = encodedVaa.asUint32CdUnchecked(offset); // Get the current threshold info ( uint32 currentThresholdIndex, @@ -72,10 +72,10 @@ contract ThresholdVerification { // Get the threshold address address thresholdAddr; - if (guardianSetIndex != currentThresholdIndex) { + if (tssIndex != currentThresholdIndex) { // If the guardian set index is not the current threshold index, // we need to get the past threshold info and validate that it is not expired - (uint32 expirationTime, address addr) = this.getPastThresholdInfo(guardianSetIndex); + (uint32 expirationTime, address addr) = this.getPastThresholdInfo(tssIndex); if (expirationTime < block.timestamp) revert GuardianSetExpired(); thresholdAddr = addr; } else { diff --git a/src/solana/Cargo.lock b/src/solana/Cargo.lock index 68d54bb..8446b63 100644 --- a/src/solana/Cargo.lock +++ b/src/solana/Cargo.lock @@ -61,9 +61,9 @@ dependencies = [ [[package]] name = "anchor-attribute-access-control" -version = "0.31.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37013051defd745a5437d6842bd404e5480e14ad4e4f0441dd9a81a4b9aea1d6" +checksum = "3f70fd141a4d18adf11253026b32504f885447048c7494faf5fa83b01af9c0cf" dependencies = [ "anchor-syn", "proc-macro2", @@ -73,9 +73,9 @@ dependencies = [ [[package]] name = "anchor-attribute-account" -version = "0.31.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92db0f793e924e18462b3fac53c5759a8248649a8072788b5e88a4af714998c8" +checksum = "715a261c57c7679581e06f07a74fa2af874ac30f86bd8ea07cca4a7e5388a064" dependencies = [ "anchor-syn", "bs58", @@ -86,9 +86,9 @@ dependencies = [ [[package]] name = "anchor-attribute-constant" -version = "0.31.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a98126ebfc96d6248899caadc9ea7c2403420c4f5c994e541802bce9f423674" +checksum = "730d6df8ae120321c5c25e0779e61789e4b70dc8297102248902022f286102e4" dependencies = [ "anchor-syn", "quote", @@ -97,9 +97,9 @@ dependencies = [ [[package]] name = "anchor-attribute-error" -version = "0.31.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8a4dcb403f872fbcd0910fc39a3e05bb6c43a8399f915a1878e62eb680fbb23" +checksum = "27e6e449cc3a37b2880b74dcafb8e5a17b954c0e58e376432d7adc646fb333ef" dependencies = [ "anchor-syn", "quote", @@ -108,9 +108,9 @@ dependencies = [ [[package]] name = "anchor-attribute-event" -version = "0.31.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "420d651b2703ccff86f6c4b7c394140cb85049787c078a5f8280506121d48065" +checksum = "d7710e4c54adf485affcd9be9adec5ef8846d9c71d7f31e16ba86ff9fc1dd49f" dependencies = [ "anchor-syn", "proc-macro2", @@ -120,9 +120,9 @@ dependencies = [ [[package]] name = "anchor-attribute-program" -version = "0.31.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d258f3a9f47db7f4199888df0ee67e42b960a7acb8f5c336b585d4eb243b9665" +checksum = "05ecfd49b2aeadeb32f35262230db402abed76ce87e27562b34f61318b2ec83c" dependencies = [ "anchor-lang-idl", "anchor-syn", @@ -137,9 +137,9 @@ dependencies = [ [[package]] name = "anchor-derive-accounts" -version = "0.31.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "097147501de51105d8dbdad9bd5a96a1b17ecbb2cee9f200d6167031372eab3b" +checksum = "be89d160793a88495af462a7010b3978e48e30a630c91de47ce2c1d3cb7a6149" dependencies = [ "anchor-syn", "quote", @@ -148,9 +148,9 @@ dependencies = [ [[package]] name = "anchor-derive-serde" -version = "0.31.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5a24721da4ed67f0a1391cac27ea7e51c255cbd94cdcc6728a0aa56227628d0" +checksum = "abc6ee78acb7bfe0c2dd2abc677aaa4789c0281a0c0ef01dbf6fe85e0fd9e6e4" dependencies = [ "anchor-syn", "borsh-derive-internal", @@ -161,9 +161,9 @@ dependencies = [ [[package]] name = "anchor-derive-space" -version = "0.31.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f41986f84d238a2f7a807f3a98da5df0e97ebe23f29f7d67b8cdd4fd80bc1ba1" +checksum = "134a01c0703f6fd355a0e472c033f6f3e41fac1ef6e370b20c50f4c8d022cea7" dependencies = [ "proc-macro2", "quote", @@ -172,9 +172,9 @@ dependencies = [ [[package]] name = "anchor-lang" -version = "0.31.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eba81a0543fee1b7b610fe9ebedbae6a14e8d3e85a6a6dd48871d48a08880195" +checksum = "e6bab117055905e930f762c196e08f861f8dfe7241b92cee46677a3b15561a0a" dependencies = [ "anchor-attribute-access-control", "anchor-attribute-account", @@ -221,9 +221,9 @@ dependencies = [ [[package]] name = "anchor-spl" -version = "0.31.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9d989ebc64e6c1a9828d3a6f7b8e7a4d63cc8a4f667dcb191bd9067a3375c20" +checksum = "3c08cb5d762c0694f74bd02c9a5b04ea53cefc496e2c27b3234acffca5cd076b" dependencies = [ "anchor-lang", "mpl-token-metadata", @@ -237,9 +237,9 @@ dependencies = [ [[package]] name = "anchor-syn" -version = "0.31.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "564685b759db12a2424d1b2688cfdf0fec26a023813bc461274754fb0e5d97b0" +checksum = "5dc7a6d90cc643df0ed2744862cdf180587d1e5d28936538c18fc8908489ed67" dependencies = [ "anyhow", "bs58", @@ -313,9 +313,9 @@ checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" [[package]] name = "blake3" -version = "1.8.1" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389a099b34312839e16420d499a9cad9650541715937ffbdd40d36f49e77eeb3" +checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" dependencies = [ "arrayref", "arrayvec", @@ -1527,9 +1527,9 @@ dependencies = [ [[package]] name = "solana-curve25519" -version = "2.2.10" +version = "2.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7794a2cbb70f6ea1026b37c9a9418f4dc89de9abeb502afb01d1bac0978fdd" +checksum = "1de13796959f32e52eb2d59a0dbfe0d55ee59b07e04b0ae5648e07ba1082dd98" dependencies = [ "bytemuck", "bytemuck_derive", @@ -2270,9 +2270,9 @@ dependencies = [ [[package]] name = "solana-zk-sdk" -version = "2.2.10" +version = "2.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1cbd4a3f7dbd027fcd55bb5ecbe980c52fff099dc83b74a3555ae2a724885fb" +checksum = "70d19fb9ff055569f32871dfd619355780f151f17285cabd23effcdd74167f73" dependencies = [ "aes-gcm-siv", "base64 0.22.1", diff --git a/src/solana/package-lock.json b/src/solana/package-lock.json new file mode 100644 index 0000000..2db085e --- /dev/null +++ b/src/solana/package-lock.json @@ -0,0 +1,2064 @@ +{ + "name": "solana", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "license": "ISC", + "dependencies": { + "@coral-xyz/anchor": "^0.31.0", + "@noble/hashes": "^1.7.2", + "@noble/secp256k1": "^2.2.3" + }, + "devDependencies": { + "@types/bn.js": "^5.1.0", + "@types/chai": "^4.3.0", + "@types/mocha": "^9.0.0", + "chai": "^4.3.4", + "mocha": "^9.0.3", + "prettier": "^2.6.2", + "ts-mocha": "^10.0.0", + "typescript": "^5.7.3" + } + }, + "node_modules/@babel/runtime": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz", + "integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==", + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@coral-xyz/anchor": { + "version": "0.31.0", + "resolved": "https://registry.npmjs.org/@coral-xyz/anchor/-/anchor-0.31.0.tgz", + "integrity": "sha512-Yb1NwP1s4cWhAw7wL7vOLHSWWw3cD5D9pRCVSeJpdqPaI+w7sfRLScnVJL6ViYMZynB7nAG/5HcUPKUnY0L9rw==", + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "@coral-xyz/anchor-errors": "^0.31.0", + "@coral-xyz/borsh": "^0.31.0", + "@noble/hashes": "^1.3.1", + "@solana/web3.js": "^1.69.0", + "bn.js": "^5.1.2", + "bs58": "^4.0.1", + "buffer-layout": "^1.2.2", + "camelcase": "^6.3.0", + "cross-fetch": "^3.1.5", + "eventemitter3": "^4.0.7", + "pako": "^2.0.3", + "superstruct": "^0.15.4", + "toml": "^3.0.0" + }, + "engines": { + "node": ">=17" + } + }, + "node_modules/@coral-xyz/anchor-errors": { + "version": "0.31.0", + "resolved": "https://registry.npmjs.org/@coral-xyz/anchor-errors/-/anchor-errors-0.31.0.tgz", + "integrity": "sha512-SUERksFSQ+4F11hkROIwHq4mcoSMXJxwVWLoklefi4dU679zVWFVcTq6O7otvjY8wlUaRXeE+iYcQWZTw2ll6w==", + "license": "Apache-2.0", + "engines": { + "node": ">=10" + } + }, + "node_modules/@coral-xyz/borsh": { + "version": "0.31.0", + "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.31.0.tgz", + "integrity": "sha512-DwdQ5fuj+rGQCTKRnxnW1W2lvcpBaFc9m9M1TcGGlm+bwCcggmDgbLKLgF+LjIrKnc7Nd+bCACx5RA9YTK2I4Q==", + "license": "Apache-2.0", + "dependencies": { + "bn.js": "^5.1.2", + "buffer-layout": "^1.2.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@solana/web3.js": "^1.69.0" + } + }, + "node_modules/@noble/curves": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.8.1.tgz", + "integrity": "sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.7.1" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/curves/node_modules/@noble/hashes": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.1.tgz", + "integrity": "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.2.tgz", + "integrity": "sha512-biZ0NUSxyjLLqo6KxEJ1b+C2NAx0wtDoFvCaXHGgUkeHzf3Xc1xKumFKREuT7f7DARNZ/slvYUwFG6B0f2b6hQ==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/secp256k1": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-2.2.3.tgz", + "integrity": "sha512-l7r5oEQym9Us7EAigzg30/PQAvynhMt2uoYtT3t26eGDVm9Yii5mZ5jWSWmZ/oSIR2Et0xfc6DXrG0bZ787V3w==", + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@solana/buffer-layout": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.1.tgz", + "integrity": "sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==", + "license": "MIT", + "dependencies": { + "buffer": "~6.0.3" + }, + "engines": { + "node": ">=5.10" + } + }, + "node_modules/@solana/web3.js": { + "version": "1.98.0", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.98.0.tgz", + "integrity": "sha512-nz3Q5OeyGFpFCR+erX2f6JPt3sKhzhYcSycBCSPkWjzSVDh/Rr1FqTVMRe58FKO16/ivTUcuJjeS5MyBvpkbzA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.25.0", + "@noble/curves": "^1.4.2", + "@noble/hashes": "^1.4.0", + "@solana/buffer-layout": "^4.0.1", + "agentkeepalive": "^4.5.0", + "bigint-buffer": "^1.1.5", + "bn.js": "^5.2.1", + "borsh": "^0.7.0", + "bs58": "^4.0.1", + "buffer": "6.0.3", + "fast-stable-stringify": "^1.0.0", + "jayson": "^4.1.1", + "node-fetch": "^2.7.0", + "rpc-websockets": "^9.0.2", + "superstruct": "^2.0.2" + } + }, + "node_modules/@solana/web3.js/node_modules/superstruct": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-2.0.2.tgz", + "integrity": "sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@swc/helpers": { + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", + "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@types/bn.js": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.6.tgz", + "integrity": "sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/chai": { + "version": "4.3.20", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.20.tgz", + "integrity": "sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/@types/mocha": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz", + "integrity": "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.13.17", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.17.tgz", + "integrity": "sha512-nAJuQXoyPj04uLgu+obZcSmsfOenUg6DxPKogeUy6yNCFwWaj5sBF8/G/pNo8EtBJjAfSVgfIlugR/BCOleO+g==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "node_modules/@types/uuid": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", + "license": "MIT" + }, + "node_modules/@types/ws": { + "version": "7.4.7", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", + "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true, + "license": "ISC" + }, + "node_modules/agentkeepalive": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz", + "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==", + "license": "MIT", + "dependencies": { + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/base-x": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.11.tgz", + "integrity": "sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/bigint-buffer": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/bigint-buffer/-/bigint-buffer-1.1.5.tgz", + "integrity": "sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "bindings": "^1.3.0" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "license": "MIT", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", + "license": "MIT" + }, + "node_modules/borsh": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/borsh/-/borsh-0.7.0.tgz", + "integrity": "sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==", + "license": "Apache-2.0", + "dependencies": { + "bn.js": "^5.2.0", + "bs58": "^4.0.0", + "text-encoding-utf-8": "^1.0.2" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true, + "license": "ISC" + }, + "node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "license": "MIT", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/buffer-layout": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/buffer-layout/-/buffer-layout-1.2.2.tgz", + "integrity": "sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==", + "license": "MIT", + "engines": { + "node": ">=4.5" + } + }, + "node_modules/bufferutil": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.9.tgz", + "integrity": "sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chai": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", + "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-fetch": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz", + "integrity": "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==", + "license": "MIT", + "dependencies": { + "node-fetch": "^2.7.0" + } + }, + "node_modules/debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-eql": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/delay": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", + "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "license": "MIT" + }, + "node_modules/es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", + "license": "MIT", + "dependencies": { + "es6-promise": "^4.0.3" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "license": "MIT" + }, + "node_modules/eyes": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", + "integrity": "sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==", + "engines": { + "node": "> 0.1.90" + } + }, + "node_modules/fast-stable-stringify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz", + "integrity": "sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==", + "license": "MIT" + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "license": "MIT" + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.x" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.0.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/isomorphic-ws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", + "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", + "license": "MIT", + "peerDependencies": { + "ws": "*" + } + }, + "node_modules/jayson": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/jayson/-/jayson-4.1.3.tgz", + "integrity": "sha512-LtXh5aYZodBZ9Fc3j6f2w+MTNcnxteMOrb+QgIouguGOulWi0lieEkOUg+HkjjFs0DGoWDds6bi4E9hpNFLulQ==", + "license": "MIT", + "dependencies": { + "@types/connect": "^3.4.33", + "@types/node": "^12.12.54", + "@types/ws": "^7.4.4", + "commander": "^2.20.3", + "delay": "^5.0.0", + "es6-promisify": "^5.0.0", + "eyes": "^0.1.8", + "isomorphic-ws": "^4.0.1", + "json-stringify-safe": "^5.0.1", + "JSONStream": "^1.3.5", + "uuid": "^8.3.2", + "ws": "^7.5.10" + }, + "bin": { + "jayson": "bin/jayson.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jayson/node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "license": "ISC" + }, + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "engines": [ + "node >= 0.2.0" + ], + "license": "MIT" + }, + "node_modules/JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true, + "license": "ISC" + }, + "node_modules/minimatch": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", + "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mocha": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", + "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.3", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "4.2.1", + "ms": "2.1.3", + "nanoid": "3.3.1", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "workerpool": "6.2.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", + "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", + "dev": true, + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "license": "MIT", + "optional": true, + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pako": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", + "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==", + "license": "(MIT AND Zlib)" + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rpc-websockets": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-9.1.1.tgz", + "integrity": "sha512-1IXGM/TfPT6nfYMIXkJdzn+L4JEsmb0FL1O2OBjaH03V3yuUDdKFulGLMFG6ErV+8pZ5HVC0limve01RyO+saA==", + "license": "LGPL-3.0-only", + "dependencies": { + "@swc/helpers": "^0.5.11", + "@types/uuid": "^8.3.4", + "@types/ws": "^8.2.2", + "buffer": "^6.0.3", + "eventemitter3": "^5.0.1", + "uuid": "^8.3.2", + "ws": "^8.5.0" + }, + "funding": { + "type": "paypal", + "url": "https://paypal.me/kozjak" + }, + "optionalDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + } + }, + "node_modules/rpc-websockets/node_modules/@types/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/rpc-websockets/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT" + }, + "node_modules/rpc-websockets/node_modules/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/superstruct": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-0.15.5.tgz", + "integrity": "sha512-4AOeU+P5UuE/4nOUkmcQdW5y7i9ndt1cQd/3iUe+LTz3RxESf/W/5lg4B74HbDMMv8PHnPnGCQFH45kBcrQYoQ==", + "license": "MIT" + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/text-encoding-utf-8": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz", + "integrity": "sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==" + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "license": "MIT" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toml": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", + "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==", + "license": "MIT" + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/ts-mocha": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/ts-mocha/-/ts-mocha-10.1.0.tgz", + "integrity": "sha512-T0C0Xm3/WqCuF2tpa0GNGESTBoKZaiqdUP8guNv4ZY316AFXlyidnrzQ1LUrCT0Wb1i3J0zFTgOh/55Un44WdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ts-node": "7.0.1" + }, + "bin": { + "ts-mocha": "bin/ts-mocha" + }, + "engines": { + "node": ">= 6.X.X" + }, + "optionalDependencies": { + "tsconfig-paths": "^3.5.0" + }, + "peerDependencies": { + "mocha": "^3.X.X || ^4.X.X || ^5.X.X || ^6.X.X || ^7.X.X || ^8.X.X || ^9.X.X || ^10.X.X || ^11.X.X" + } + }, + "node_modules/ts-node": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", + "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "arrify": "^1.0.0", + "buffer-from": "^1.1.0", + "diff": "^3.1.0", + "make-error": "^1.1.1", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "source-map-support": "^0.5.6", + "yn": "^2.0.0" + }, + "bin": { + "ts-node": "dist/bin.js" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/ts-node/node_modules/diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/typescript": { + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", + "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "license": "MIT" + }, + "node_modules/utf-8-validate": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", + "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/workerpool": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", + "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", + "integrity": "sha512-uTv8J/wiWTgUTg+9vLTi//leUl5vDQS6uii/emeTb2ssY7vl6QWf2fFbIIGjnhjvbdKlU0ed7QPgY1htTC86jQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/src/solana/package.json b/src/solana/package.json index 4cbdbd0..5013f7f 100644 --- a/src/solana/package.json +++ b/src/solana/package.json @@ -5,16 +5,18 @@ "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" }, "dependencies": { - "@coral-xyz/anchor": "^0.31.0" + "@coral-xyz/anchor": "^0.31.1", + "@noble/hashes": "^1.7.2", + "@noble/secp256k1": "^2.2.3" }, "devDependencies": { - "chai": "^4.3.4", - "mocha": "^9.0.3", - "ts-mocha": "^10.0.0", "@types/bn.js": "^5.1.0", "@types/chai": "^4.3.0", "@types/mocha": "^9.0.0", - "typescript": "^5.7.3", - "prettier": "^2.6.2" + "chai": "^4.3.4", + "mocha": "^9.0.3", + "prettier": "^2.6.2", + "ts-mocha": "^10.0.0", + "typescript": "^5.7.3" } } diff --git a/src/solana/programs/verification_v2/Cargo.toml b/src/solana/programs/verification_v2/Cargo.toml index 15101a2..ab69fa5 100644 --- a/src/solana/programs/verification_v2/Cargo.toml +++ b/src/solana/programs/verification_v2/Cargo.toml @@ -9,15 +9,21 @@ crate-type = ["cdylib", "lib"] name = "verification_v2" [features] -default = [] +default = ["mainnet"] +mainnet = ["wormhole-anchor-sdk/mainnet"] +testnet = ["wormhole-anchor-sdk/solana-devnet"] +devnet = ["wormhole-anchor-sdk/tilt-devnet"] cpi = ["no-entrypoint"] no-entrypoint = [] no-idl = [] no-log-ix-name = [] -idl-build = ["anchor-lang/idl-build"] +idl-build = [ + "anchor-lang/idl-build", + "wormhole-anchor-sdk/idl-build", +] [dependencies] -anchor-lang = "0.31.0" +anchor-lang = "0.31.1" byteorder = "1.5.0" libsecp256k1 = "0.7.2" -wormhole-anchor-sdk = { git = "https://github.com/wormhole-foundation/wormhole-scaffolding.git" } +wormhole-anchor-sdk = { git = "https://github.com/wormhole-foundation/wormhole-scaffolding.git", default-features = false, features = ["idl-build"] } diff --git a/src/solana/programs/verification_v2/src/lib.rs b/src/solana/programs/verification_v2/src/lib.rs index 23adaf3..3e5b5c2 100644 --- a/src/solana/programs/verification_v2/src/lib.rs +++ b/src/solana/programs/verification_v2/src/lib.rs @@ -20,15 +20,41 @@ use append_threshold_key_message::AppendThresholdKeyMessage; const GOVERNANCE_ADDRESS: [u8; 32] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4]; +#[error_code] +pub enum VAAError { + #[msg("Invalid VAA version")] + InvalidVersion, + #[msg("Invalid VAA index")] + InvalidIndex, + #[msg("TSS key expired")] + TSSKeyExpired, + #[msg("Invalid signature")] + InvalidSignature, +} + +#[error_code] +pub enum AppendThresholdKeyError { + #[msg("Invalid VAA")] + InvalidVAA, + #[msg("Invalid governance chain ID")] + InvalidGovernanceChainId, + #[msg("Invalid governance address")] + InvalidGovernanceAddress, + #[msg("Index mismatch")] + IndexMismatch, + #[msg("Invalid old threshold key")] + InvalidOldThresholdKey, +} + #[derive(Accounts)] pub struct AppendThresholdKey<'info> { #[account(mut)] pub payer: Signer<'info>, #[account( - owner = wormhole_program.key(), - constraint = vaa.meta.emitter_chain == CHAIN_ID_SOLANA - && vaa.meta.emitter_address == GOVERNANCE_ADDRESS, + owner = wormhole_program.key() @ AppendThresholdKeyError::InvalidVAA, + constraint = vaa.meta.emitter_chain == CHAIN_ID_SOLANA @ AppendThresholdKeyError::InvalidGovernanceChainId, + constraint = vaa.meta.emitter_address == GOVERNANCE_ADDRESS @ AppendThresholdKeyError::InvalidGovernanceAddress, )] pub vaa: Account<'info, PostedVaaData>, @@ -41,7 +67,7 @@ pub struct AppendThresholdKey<'info> { #[account( mut, - constraint = old_threshold_key.expiration_timestamp == 0, + constraint = old_threshold_key.expiration_timestamp == 0 @ AppendThresholdKeyError::InvalidOldThresholdKey, )] pub old_threshold_key: Option>, @@ -50,10 +76,9 @@ pub struct AppendThresholdKey<'info> { } #[derive(Accounts)] -#[instruction(vaa: Vec)] pub struct VerifyVaa<'info> { #[account( - constraint = threshold_key.is_unexpired(), + constraint = threshold_key.is_unexpired() @ VAAError::TSSKeyExpired, )] pub threshold_key: Account<'info, ThresholdKey>, } @@ -70,30 +95,11 @@ impl ThresholdKey { pub fn is_unexpired(&self) -> bool { self.expiration_timestamp == 0 || self.expiration_timestamp > Clock::get().unwrap().unix_timestamp as u64 } -} - -#[error_code] -pub enum VAAError { - #[msg("Invalid VAA version")] - InvalidVersion, - #[msg("Invalid VAA index")] - InvalidIndex, - #[msg("Guardian set expired")] - GuardianSetExpired, - #[msg("Invalid signature")] - InvalidSignature, -} -#[error_code] -pub enum AppendThresholdKeyError { - #[msg("Invalid governance chain ID")] - InvalidGovernanceChainId, - #[msg("Invalid governance address")] - InvalidGovernanceAddress, - #[msg("Index mismatch")] - IndexMismatch, - #[msg("Invalid old threshold key")] - InvalidOldThresholdKey, + pub fn update_expiration_timestamp(&mut self, new_expiration_timestamp: u64) { + let current_timestamp = Clock::get().unwrap().unix_timestamp as u64; + self.expiration_timestamp = current_timestamp + new_expiration_timestamp; + } } #[program] @@ -117,8 +123,7 @@ pub mod verification_v2 { // Set the old threshold key expiration timestamp if let Some(ref mut old_threshold_key) = &mut ctx.accounts.old_threshold_key { - let current_timestamp = Clock::get().unwrap().unix_timestamp as u64; - old_threshold_key.expiration_timestamp = current_timestamp + message.expiration_delay_seconds as u64; + old_threshold_key.update_expiration_timestamp(message.expiration_delay_seconds as u64); } Ok(()) diff --git a/src/solana/programs/verification_v2/src/vaa.rs b/src/solana/programs/verification_v2/src/vaa.rs index 62d3c0f..da301b8 100644 --- a/src/solana/programs/verification_v2/src/vaa.rs +++ b/src/solana/programs/verification_v2/src/vaa.rs @@ -11,8 +11,8 @@ pub struct VAA { pub recovery_id: u8, // Body - pub timestamp: u64, - pub nonce: u64, + pub timestamp: u32, + pub nonce: u32, pub emitter_chain_id: u16, pub emitter_address: [u8; 32], pub sequence: u64, @@ -28,8 +28,8 @@ impl VAA { cursor.write_u32::(self.tss_index)?; cursor.write_all(&self.signature)?; cursor.write_u8(self.recovery_id)?; - cursor.write_u64::(self.timestamp)?; - cursor.write_u64::(self.nonce)?; + cursor.write_u32::(self.timestamp)?; + cursor.write_u32::(self.nonce)?; cursor.write_u16::(self.emitter_chain_id)?; cursor.write_all(&self.emitter_address)?; cursor.write_u64::(self.sequence)?; @@ -50,8 +50,8 @@ impl VAA { let body_start = cursor.position() as usize; - let timestamp = cursor.read_u64::()?; - let nonce = cursor.read_u64::()?; + let timestamp = cursor.read_u32::()?; + let nonce = cursor.read_u32::()?; let emitter_chain_id = cursor.read_u16::()?; let mut emitter_address = [0; 32]; cursor.read_exact(&mut emitter_address)?; diff --git a/src/solana/yarn.lock b/src/solana/yarn.lock index 3cb32ac..2e868fb 100644 --- a/src/solana/yarn.lock +++ b/src/solana/yarn.lock @@ -4,19 +4,19 @@ "@babel/runtime@^7.25.0": version "7.27.0" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.27.0.tgz#fbee7cf97c709518ecc1f590984481d5460d4762" + resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz" integrity sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw== dependencies: regenerator-runtime "^0.14.0" "@coral-xyz/anchor-errors@^0.31.0": version "0.31.0" - resolved "https://registry.yarnpkg.com/@coral-xyz/anchor-errors/-/anchor-errors-0.31.0.tgz#dfc7329fca152b598842f68175efe5000825b51b" + resolved "https://registry.npmjs.org/@coral-xyz/anchor-errors/-/anchor-errors-0.31.0.tgz" integrity sha512-SUERksFSQ+4F11hkROIwHq4mcoSMXJxwVWLoklefi4dU679zVWFVcTq6O7otvjY8wlUaRXeE+iYcQWZTw2ll6w== "@coral-xyz/anchor@^0.31.0": version "0.31.0" - resolved "https://registry.yarnpkg.com/@coral-xyz/anchor/-/anchor-0.31.0.tgz#76b84541e6fdfbd6c661584cdc418453a6416f12" + resolved "https://registry.npmjs.org/@coral-xyz/anchor/-/anchor-0.31.0.tgz" integrity sha512-Yb1NwP1s4cWhAw7wL7vOLHSWWw3cD5D9pRCVSeJpdqPaI+w7sfRLScnVJL6ViYMZynB7nAG/5HcUPKUnY0L9rw== dependencies: "@coral-xyz/anchor-errors" "^0.31.0" @@ -35,7 +35,7 @@ "@coral-xyz/borsh@^0.31.0": version "0.31.0" - resolved "https://registry.yarnpkg.com/@coral-xyz/borsh/-/borsh-0.31.0.tgz#eb77239b75f3ea9e771b1ee0821712caf664cb32" + resolved "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.31.0.tgz" integrity sha512-DwdQ5fuj+rGQCTKRnxnW1W2lvcpBaFc9m9M1TcGGlm+bwCcggmDgbLKLgF+LjIrKnc7Nd+bCACx5RA9YTK2I4Q== dependencies: bn.js "^5.1.2" @@ -43,26 +43,36 @@ "@noble/curves@^1.4.2": version "1.8.1" - resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.8.1.tgz#19bc3970e205c99e4bdb1c64a4785706bce497ff" + resolved "https://registry.npmjs.org/@noble/curves/-/curves-1.8.1.tgz" integrity sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ== dependencies: "@noble/hashes" "1.7.1" -"@noble/hashes@1.7.1", "@noble/hashes@^1.3.1", "@noble/hashes@^1.4.0": +"@noble/hashes@^1.3.1", "@noble/hashes@^1.4.0", "@noble/hashes@^1.7.2": + version "1.7.2" + resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.2.tgz" + integrity sha512-biZ0NUSxyjLLqo6KxEJ1b+C2NAx0wtDoFvCaXHGgUkeHzf3Xc1xKumFKREuT7f7DARNZ/slvYUwFG6B0f2b6hQ== + +"@noble/hashes@1.7.1": version "1.7.1" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.7.1.tgz#5738f6d765710921e7a751e00c20ae091ed8db0f" + resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.1.tgz" integrity sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ== +"@noble/secp256k1@^2.2.3": + version "2.2.3" + resolved "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-2.2.3.tgz" + integrity sha512-l7r5oEQym9Us7EAigzg30/PQAvynhMt2uoYtT3t26eGDVm9Yii5mZ5jWSWmZ/oSIR2Et0xfc6DXrG0bZ787V3w== + "@solana/buffer-layout@^4.0.1": version "4.0.1" - resolved "https://registry.yarnpkg.com/@solana/buffer-layout/-/buffer-layout-4.0.1.tgz#b996235eaec15b1e0b5092a8ed6028df77fa6c15" + resolved "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.1.tgz" integrity sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA== dependencies: buffer "~6.0.3" "@solana/web3.js@^1.69.0": version "1.98.0" - resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.98.0.tgz#21ecfe8198c10831df6f0cfde7f68370d0405917" + resolved "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.98.0.tgz" integrity sha512-nz3Q5OeyGFpFCR+erX2f6JPt3sKhzhYcSycBCSPkWjzSVDh/Rr1FqTVMRe58FKO16/ivTUcuJjeS5MyBvpkbzA== dependencies: "@babel/runtime" "^7.25.0" @@ -83,111 +93,103 @@ "@swc/helpers@^0.5.11": version "0.5.15" - resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.15.tgz#79efab344c5819ecf83a43f3f9f811fc84b516d7" + resolved "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz" integrity sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g== dependencies: tslib "^2.8.0" "@types/bn.js@^5.1.0": version "5.1.6" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.6.tgz#9ba818eec0c85e4d3c679518428afdf611d03203" + resolved "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.6.tgz" integrity sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w== dependencies: "@types/node" "*" "@types/chai@^4.3.0": version "4.3.20" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.20.tgz#cb291577ed342ca92600430841a00329ba05cecc" + resolved "https://registry.npmjs.org/@types/chai/-/chai-4.3.20.tgz" integrity sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ== "@types/connect@^3.4.33": version "3.4.38" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.38.tgz#5ba7f3bc4fbbdeaff8dded952e5ff2cc53f8d858" + resolved "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz" integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== dependencies: "@types/node" "*" "@types/json5@^0.0.29": version "0.0.29" - resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== "@types/mocha@^9.0.0": version "9.1.1" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-9.1.1.tgz#e7c4f1001eefa4b8afbd1eee27a237fee3bf29c4" + resolved "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz" integrity sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw== "@types/node@*": version "22.13.17" - resolved "https://registry.yarnpkg.com/@types/node/-/node-22.13.17.tgz#9ca6a81a0180cdcfd3719b9cf6c09186756e1754" + resolved "https://registry.npmjs.org/@types/node/-/node-22.13.17.tgz" integrity sha512-nAJuQXoyPj04uLgu+obZcSmsfOenUg6DxPKogeUy6yNCFwWaj5sBF8/G/pNo8EtBJjAfSVgfIlugR/BCOleO+g== dependencies: undici-types "~6.20.0" "@types/node@^12.12.54": version "12.20.55" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240" + resolved "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz" integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ== "@types/uuid@^8.3.4": version "8.3.4" - resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc" + resolved "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz" integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw== "@types/ws@^7.4.4": version "7.4.7" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" + resolved "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz" integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== dependencies: "@types/node" "*" "@types/ws@^8.2.2": version "8.18.1" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.1.tgz#48464e4bf2ddfd17db13d845467f6070ffea4aa9" + resolved "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz" integrity sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg== dependencies: "@types/node" "*" "@ungap/promise-all-settled@1.1.2": version "1.1.2" - resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" + resolved "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz" integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== -JSONStream@^1.3.5: - version "1.3.5" - resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" - integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== - dependencies: - jsonparse "^1.2.0" - through ">=2.2.7 <3" - agentkeepalive@^4.5.0: version "4.6.0" - resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.6.0.tgz#35f73e94b3f40bf65f105219c623ad19c136ea6a" + resolved "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz" integrity sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ== dependencies: humanize-ms "^1.2.1" ansi-colors@4.1.1: version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz" integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== ansi-regex@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== dependencies: color-convert "^2.0.1" anymatch@~3.1.2: version "3.1.3" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz" integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== dependencies: normalize-path "^3.0.0" @@ -195,63 +197,63 @@ anymatch@~3.1.2: argparse@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== arrify@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + resolved "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz" integrity sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA== assertion-error@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" + resolved "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz" integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== balanced-match@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== base-x@^3.0.2: version "3.0.11" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.11.tgz#40d80e2a1aeacba29792ccc6c5354806421287ff" + resolved "https://registry.npmjs.org/base-x/-/base-x-3.0.11.tgz" integrity sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA== dependencies: safe-buffer "^5.0.1" base64-js@^1.3.1: version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== bigint-buffer@^1.1.5: version "1.1.5" - resolved "https://registry.yarnpkg.com/bigint-buffer/-/bigint-buffer-1.1.5.tgz#d038f31c8e4534c1f8d0015209bf34b4fa6dd442" + resolved "https://registry.npmjs.org/bigint-buffer/-/bigint-buffer-1.1.5.tgz" integrity sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA== dependencies: bindings "^1.3.0" binary-extensions@^2.0.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" + resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz" integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== bindings@^1.3.0: version "1.5.0" - resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + resolved "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz" integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== dependencies: file-uri-to-path "1.0.0" bn.js@^5.1.2, bn.js@^5.2.0, bn.js@^5.2.1: version "5.2.1" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" + resolved "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz" integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== borsh@^0.7.0: version "0.7.0" - resolved "https://registry.yarnpkg.com/borsh/-/borsh-0.7.0.tgz#6e9560d719d86d90dc589bca60ffc8a6c51fec2a" + resolved "https://registry.npmjs.org/borsh/-/borsh-0.7.0.tgz" integrity sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA== dependencies: bn.js "^5.2.0" @@ -260,7 +262,7 @@ borsh@^0.7.0: brace-expansion@^1.1.7: version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== dependencies: balanced-match "^1.0.0" @@ -268,36 +270,36 @@ brace-expansion@^1.1.7: braces@~3.0.2: version "3.0.3" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" + resolved "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz" integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== dependencies: fill-range "^7.1.1" browser-stdout@1.3.1: version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + resolved "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz" integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== bs58@^4.0.0, bs58@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" + resolved "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz" integrity sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw== dependencies: base-x "^3.0.2" buffer-from@^1.0.0, buffer-from@^1.1.0: version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== buffer-layout@^1.2.0, buffer-layout@^1.2.2: version "1.2.2" - resolved "https://registry.yarnpkg.com/buffer-layout/-/buffer-layout-1.2.2.tgz#b9814e7c7235783085f9ca4966a0cfff112259d5" + resolved "https://registry.npmjs.org/buffer-layout/-/buffer-layout-1.2.2.tgz" integrity sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA== -buffer@6.0.3, buffer@^6.0.3, buffer@~6.0.3: +buffer@^6.0.3, buffer@~6.0.3, buffer@6.0.3: version "6.0.3" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + resolved "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz" integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== dependencies: base64-js "^1.3.1" @@ -305,19 +307,19 @@ buffer@6.0.3, buffer@^6.0.3, buffer@~6.0.3: bufferutil@^4.0.1: version "4.0.9" - resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.9.tgz#6e81739ad48a95cad45a279588e13e95e24a800a" + resolved "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.9.tgz" integrity sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw== dependencies: node-gyp-build "^4.3.0" camelcase@^6.0.0, camelcase@^6.3.0: version "6.3.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== chai@^4.3.4: version "4.5.0" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.5.0.tgz#707e49923afdd9b13a8b0b47d33d732d13812fd8" + resolved "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz" integrity sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw== dependencies: assertion-error "^1.1.0" @@ -330,7 +332,7 @@ chai@^4.3.4: chalk@^4.1.0: version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== dependencies: ansi-styles "^4.1.0" @@ -338,14 +340,14 @@ chalk@^4.1.0: check-error@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.3.tgz#a6502e4312a7ee969f646e83bb3ddd56281bd694" + resolved "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz" integrity sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg== dependencies: get-func-name "^2.0.2" chokidar@3.5.3: version "3.5.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== dependencies: anymatch "~3.1.2" @@ -360,7 +362,7 @@ chokidar@3.5.3: cliui@^7.0.2: version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + resolved "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz" integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== dependencies: string-width "^4.2.0" @@ -369,129 +371,129 @@ cliui@^7.0.2: color-convert@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== dependencies: color-name "~1.1.4" color-name@~1.1.4: version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== commander@^2.20.3: version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== concat-map@0.0.1: version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== cross-fetch@^3.1.5: version "3.2.0" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.2.0.tgz#34e9192f53bc757d6614304d9e5e6fb4edb782e3" + resolved "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz" integrity sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q== dependencies: node-fetch "^2.7.0" debug@4.3.3: version "4.3.3" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + resolved "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz" integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== dependencies: ms "2.1.2" decamelize@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" + resolved "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz" integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== deep-eql@^4.1.3: version "4.1.4" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.4.tgz#d0d3912865911bb8fac5afb4e3acfa6a28dc72b7" + resolved "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz" integrity sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg== dependencies: type-detect "^4.0.0" delay@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/delay/-/delay-5.0.0.tgz#137045ef1b96e5071060dd5be60bf9334436bd1d" + resolved "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz" integrity sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw== -diff@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" - integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== - diff@^3.1.0: version "3.5.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + resolved "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz" integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== +diff@5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz" + integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== + emoji-regex@^8.0.0: version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== es6-promise@^4.0.3: version "4.2.8" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" + resolved "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz" integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== es6-promisify@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" + resolved "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz" integrity sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ== dependencies: es6-promise "^4.0.3" escalade@^3.1.1: version "3.2.0" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" + resolved "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz" integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== escape-string-regexp@4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== eventemitter3@^4.0.7: version "4.0.7" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== eventemitter3@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" + resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz" integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== eyes@^0.1.8: version "0.1.8" - resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" + resolved "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz" integrity sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ== fast-stable-stringify@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz#5c5543462b22aeeefd36d05b34e51c78cb86d313" + resolved "https://registry.npmjs.org/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz" integrity sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag== file-uri-to-path@1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + resolved "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz" integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== fill-range@^7.1.1: version "7.1.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz" integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== dependencies: to-regex-range "^5.0.1" find-up@5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== dependencies: locate-path "^6.0.0" @@ -499,39 +501,34 @@ find-up@5.0.0: flat@^5.0.2: version "5.0.2" - resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + resolved "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz" integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== fs.realpath@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== -fsevents@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" - integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== - get-caller-file@^2.0.5: version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== get-func-name@^2.0.1, get-func-name@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.2.tgz#0d7cf20cd13fda808669ffa88f4ffc7a3943fc41" + resolved "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz" integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ== glob-parent@~5.1.2: version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" glob@7.2.0: version "7.2.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + resolved "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz" integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== dependencies: fs.realpath "^1.0.0" @@ -543,34 +540,34 @@ glob@7.2.0: growl@1.10.5: version "1.10.5" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + resolved "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz" integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== has-flag@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== he@1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + resolved "https://registry.npmjs.org/he/-/he-1.2.0.tgz" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== humanize-ms@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" + resolved "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz" integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== dependencies: ms "^2.0.0" ieee754@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== inflight@^1.0.4: version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== dependencies: once "^1.3.0" @@ -578,110 +575,118 @@ inflight@^1.0.4: inherits@2: version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== is-binary-path@~2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== dependencies: binary-extensions "^2.0.0" is-extglob@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== is-fullwidth-code-point@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== is-glob@^4.0.1, is-glob@~4.0.1: version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== dependencies: is-extglob "^2.1.1" is-number@^7.0.0: version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== is-plain-obj@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz" integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== is-unicode-supported@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== isexe@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== isomorphic-ws@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" + resolved "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz" integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== jayson@^4.1.1: version "4.1.3" - resolved "https://registry.yarnpkg.com/jayson/-/jayson-4.1.3.tgz#db9be2e4287d9fef4fc05b5fe367abe792c2eee8" + resolved "https://registry.npmjs.org/jayson/-/jayson-4.1.3.tgz" integrity sha512-LtXh5aYZodBZ9Fc3j6f2w+MTNcnxteMOrb+QgIouguGOulWi0lieEkOUg+HkjjFs0DGoWDds6bi4E9hpNFLulQ== dependencies: "@types/connect" "^3.4.33" "@types/node" "^12.12.54" "@types/ws" "^7.4.4" - JSONStream "^1.3.5" commander "^2.20.3" delay "^5.0.0" es6-promisify "^5.0.0" eyes "^0.1.8" isomorphic-ws "^4.0.1" json-stringify-safe "^5.0.1" + JSONStream "^1.3.5" uuid "^8.3.2" ws "^7.5.10" js-yaml@4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== dependencies: argparse "^2.0.1" json-stringify-safe@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== json5@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" + resolved "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz" integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== dependencies: minimist "^1.2.0" jsonparse@^1.2.0: version "1.3.1" - resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" + resolved "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz" integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== +JSONStream@^1.3.5: + version "1.3.5" + resolved "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz" + integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== + dependencies: + jsonparse "^1.2.0" + through ">=2.2.7 <3" + locate-path@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== dependencies: p-locate "^5.0.0" log-symbols@4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz" integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== dependencies: chalk "^4.1.0" @@ -689,45 +694,45 @@ log-symbols@4.1.0: loupe@^2.3.6: version "2.3.7" - resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.7.tgz#6e69b7d4db7d3ab436328013d37d1c8c3540c697" + resolved "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz" integrity sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA== dependencies: get-func-name "^2.0.1" make-error@^1.1.1: version "1.3.6" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== -minimatch@4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-4.2.1.tgz#40d9d511a46bdc4e563c22c3080cde9c0d8299b4" - integrity sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g== - dependencies: - brace-expansion "^1.1.7" - minimatch@^3.0.4: version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== dependencies: brace-expansion "^1.1.7" +minimatch@4.2.1: + version "4.2.1" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz" + integrity sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g== + dependencies: + brace-expansion "^1.1.7" + minimist@^1.2.0, minimist@^1.2.6: version "1.2.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== mkdirp@^0.5.1: version "0.5.6" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz" integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== dependencies: minimist "^1.2.6" -mocha@^9.0.3: +"mocha@^3.X.X || ^4.X.X || ^5.X.X || ^6.X.X || ^7.X.X || ^8.X.X || ^9.X.X || ^10.X.X || ^11.X.X", mocha@^9.0.3: version "9.2.2" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.2.tgz#d70db46bdb93ca57402c809333e5a84977a88fb9" + resolved "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz" integrity sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g== dependencies: "@ungap/promise-all-settled" "1.1.2" @@ -755,116 +760,116 @@ mocha@^9.0.3: yargs-parser "20.2.4" yargs-unparser "2.0.0" +ms@^2.0.0, ms@2.1.3: + version "2.1.3" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + ms@2.1.2: version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@2.1.3, ms@^2.0.0: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - nanoid@3.3.1: version "3.3.1" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" + resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz" integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== node-fetch@^2.7.0: version "2.7.0" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" + resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz" integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== dependencies: whatwg-url "^5.0.0" node-gyp-build@^4.3.0: version "4.8.4" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.4.tgz#8a70ee85464ae52327772a90d66c6077a900cfc8" + resolved "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz" integrity sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ== normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== once@^1.3.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== dependencies: wrappy "1" p-limit@^3.0.2: version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== dependencies: yocto-queue "^0.1.0" p-locate@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz" integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== dependencies: p-limit "^3.0.2" pako@^2.0.3: version "2.1.0" - resolved "https://registry.yarnpkg.com/pako/-/pako-2.1.0.tgz#266cc37f98c7d883545d11335c00fbd4062c9a86" + resolved "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz" integrity sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug== path-exists@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== path-is-absolute@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== pathval@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" + resolved "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz" integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== picomatch@^2.0.4, picomatch@^2.2.1: version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== prettier@^2.6.2: version "2.8.8" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" + resolved "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz" integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== randombytes@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== dependencies: safe-buffer "^5.1.0" readdirp@~3.6.0: version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== dependencies: picomatch "^2.2.1" regenerator-runtime@^0.14.0: version "0.14.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" + resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz" integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== require-directory@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== rpc-websockets@^9.0.2: version "9.1.1" - resolved "https://registry.yarnpkg.com/rpc-websockets/-/rpc-websockets-9.1.1.tgz#5764336f3623ee1c5cc8653b7335183e3c0c78bd" + resolved "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-9.1.1.tgz" integrity sha512-1IXGM/TfPT6nfYMIXkJdzn+L4JEsmb0FL1O2OBjaH03V3yuUDdKFulGLMFG6ErV+8pZ5HVC0limve01RyO+saA== dependencies: "@swc/helpers" "^0.5.11" @@ -880,19 +885,19 @@ rpc-websockets@^9.0.2: safe-buffer@^5.0.1, safe-buffer@^5.1.0: version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== serialize-javascript@6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz" integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== dependencies: randombytes "^2.1.0" source-map-support@^0.5.6: version "0.5.21" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== dependencies: buffer-from "^1.0.0" @@ -900,12 +905,12 @@ source-map-support@^0.5.6: source-map@^0.6.0: version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== string-width@^4.1.0, string-width@^4.2.0: version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== dependencies: emoji-regex "^8.0.0" @@ -914,75 +919,75 @@ string-width@^4.1.0, string-width@^4.2.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" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: ansi-regex "^5.0.1" strip-bom@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== strip-json-comments@3.1.1: version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== superstruct@^0.15.4: version "0.15.5" - resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-0.15.5.tgz#0f0a8d3ce31313f0d84c6096cd4fa1bfdedc9dab" + resolved "https://registry.npmjs.org/superstruct/-/superstruct-0.15.5.tgz" integrity sha512-4AOeU+P5UuE/4nOUkmcQdW5y7i9ndt1cQd/3iUe+LTz3RxESf/W/5lg4B74HbDMMv8PHnPnGCQFH45kBcrQYoQ== superstruct@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-2.0.2.tgz#3f6d32fbdc11c357deff127d591a39b996300c54" + resolved "https://registry.npmjs.org/superstruct/-/superstruct-2.0.2.tgz" integrity sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A== -supports-color@8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - supports-color@^7.1.0: version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== dependencies: has-flag "^4.0.0" +supports-color@8.1.1: + version "8.1.1" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + text-encoding-utf-8@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz#585b62197b0ae437e3c7b5d0af27ac1021e10d13" + resolved "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz" integrity sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg== "through@>=2.2.7 <3": version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz" integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== to-regex-range@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== dependencies: is-number "^7.0.0" toml@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/toml/-/toml-3.0.0.tgz#342160f1af1904ec9d204d03a5d61222d762c5ee" + resolved "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz" integrity sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w== tr46@~0.0.3: version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== ts-mocha@^10.0.0: version "10.1.0" - resolved "https://registry.yarnpkg.com/ts-mocha/-/ts-mocha-10.1.0.tgz#17a1c055f5f7733fd82447c4420740db87221bc8" + resolved "https://registry.npmjs.org/ts-mocha/-/ts-mocha-10.1.0.tgz" integrity sha512-T0C0Xm3/WqCuF2tpa0GNGESTBoKZaiqdUP8guNv4ZY316AFXlyidnrzQ1LUrCT0Wb1i3J0zFTgOh/55Un44WdA== dependencies: ts-node "7.0.1" @@ -991,7 +996,7 @@ ts-mocha@^10.0.0: ts-node@7.0.1: version "7.0.1" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-7.0.1.tgz#9562dc2d1e6d248d24bc55f773e3f614337d9baf" + resolved "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz" integrity sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw== dependencies: arrify "^1.0.0" @@ -1005,7 +1010,7 @@ ts-node@7.0.1: tsconfig-paths@^3.5.0: version "3.15.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz#5299ec605e55b1abb23ec939ef15edaf483070d4" + resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz" integrity sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg== dependencies: "@types/json5" "^0.0.29" @@ -1015,44 +1020,44 @@ tsconfig-paths@^3.5.0: tslib@^2.8.0: version "2.8.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== type-detect@^4.0.0, type-detect@^4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.1.0.tgz#deb2453e8f08dcae7ae98c626b13dddb0155906c" + resolved "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz" integrity sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw== typescript@^5.7.3: version "5.8.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.8.2.tgz#8170b3702f74b79db2e5a96207c15e65807999e4" + resolved "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz" integrity sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ== undici-types@~6.20.0: version "6.20.0" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.20.0.tgz#8171bf22c1f588d1554d55bf204bc624af388433" + resolved "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz" integrity sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg== -utf-8-validate@^5.0.2: +utf-8-validate@^5.0.2, utf-8-validate@>=5.0.2: version "5.0.10" - resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz#d7d10ea39318171ca982718b6b96a8d2442571a2" + resolved "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz" integrity sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ== dependencies: node-gyp-build "^4.3.0" uuid@^8.3.2: version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== webidl-conversions@^3.0.0: version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz" integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== whatwg-url@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz" integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== dependencies: tr46 "~0.0.3" @@ -1060,19 +1065,19 @@ whatwg-url@^5.0.0: which@2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" workerpool@6.2.0: version "6.2.0" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.0.tgz#827d93c9ba23ee2019c3ffaff5c27fccea289e8b" + resolved "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz" integrity sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A== wrap-ansi@^7.0.0: version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== dependencies: ansi-styles "^4.0.0" @@ -1081,37 +1086,37 @@ wrap-ansi@^7.0.0: wrappy@1: version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== -ws@^7.5.10: +ws@*, ws@^7.5.10: version "7.5.10" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9" + resolved "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz" integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== ws@^8.5.0: version "8.18.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.1.tgz#ea131d3784e1dfdff91adb0a4a116b127515e3cb" + resolved "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz" integrity sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w== y18n@^5.0.5: version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== -yargs-parser@20.2.4: - version "20.2.4" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== - yargs-parser@^20.2.2: version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== +yargs-parser@20.2.4: + version "20.2.4" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz" + integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== + yargs-unparser@2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + resolved "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz" integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== dependencies: camelcase "^6.0.0" @@ -1121,7 +1126,7 @@ yargs-unparser@2.0.0: yargs@16.2.0: version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + resolved "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz" integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== dependencies: cliui "^7.0.2" @@ -1134,10 +1139,10 @@ yargs@16.2.0: yn@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a" + resolved "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz" integrity sha512-uTv8J/wiWTgUTg+9vLTi//leUl5vDQS6uii/emeTb2ssY7vl6QWf2fFbIIGjnhjvbdKlU0ed7QPgY1htTC86jQ== yocto-queue@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== From 530cbeb5f58cf1a39883a0bb2344831ff7c2a457 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Claudio=20Nale?= Date: Tue, 22 Apr 2025 15:28:02 -0300 Subject: [PATCH 13/53] solana: derives serialization traits for `VAA` --- src/solana/programs/verification_v2/src/vaa.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/solana/programs/verification_v2/src/vaa.rs b/src/solana/programs/verification_v2/src/vaa.rs index da301b8..0f27719 100644 --- a/src/solana/programs/verification_v2/src/vaa.rs +++ b/src/solana/programs/verification_v2/src/vaa.rs @@ -3,6 +3,7 @@ use std::io::{Cursor, Read, Write}; use anchor_lang::prelude::*; use anchor_lang::solana_program::keccak::hash; +#[derive(AnchorSerialize, AnchorDeserialize)] pub struct VAA { // Header pub version: u8, From 81c9409499f06803e3abf385a060131612359505 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Claudio=20Nale?= Date: Tue, 22 Apr 2025 15:57:10 -0300 Subject: [PATCH 14/53] solana: points at modified wormhole anchor bindings These set a bogus discriminator for `PostedVaaData`. The discriminator is only used to emit the IDL so it's safe in terms of contract code. The IDL should be fixed afterwards probably. --- src/solana/Cargo.lock | 2 +- src/solana/programs/verification_v2/Cargo.toml | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/solana/Cargo.lock b/src/solana/Cargo.lock index 8446b63..e6be5df 100644 --- a/src/solana/Cargo.lock +++ b/src/solana/Cargo.lock @@ -2960,7 +2960,7 @@ dependencies = [ [[package]] name = "wormhole-anchor-sdk" version = "0.31.0" -source = "git+https://github.com/wormhole-foundation/wormhole-scaffolding.git#3be80a92579b108b5d6fffe234c6e18322e2c3b6" +source = "git+https://github.com/XLabs/wormhole-scaffolding.git?rev=c008cf26c2449b914911a19ecbf8630fd9b4f5b5#c008cf26c2449b914911a19ecbf8630fd9b4f5b5" dependencies = [ "anchor-lang", "anchor-spl", diff --git a/src/solana/programs/verification_v2/Cargo.toml b/src/solana/programs/verification_v2/Cargo.toml index ab69fa5..f1949c5 100644 --- a/src/solana/programs/verification_v2/Cargo.toml +++ b/src/solana/programs/verification_v2/Cargo.toml @@ -26,4 +26,5 @@ idl-build = [ anchor-lang = "0.31.1" byteorder = "1.5.0" libsecp256k1 = "0.7.2" -wormhole-anchor-sdk = { git = "https://github.com/wormhole-foundation/wormhole-scaffolding.git", default-features = false, features = ["idl-build"] } +# wormhole-anchor-sdk = { git = "https://github.com/wormhole-foundation/wormhole-scaffolding.git", default-features = false } +wormhole-anchor-sdk = { git = "https://github.com/XLabs/wormhole-scaffolding.git", rev = "c008cf26c2449b914911a19ecbf8630fd9b4f5b5", default-features = false } From e6f5f8511efe66c47bd64eb5e917a9ad80c09f44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Claudio=20Nale?= Date: Wed, 23 Apr 2025 11:33:49 -0300 Subject: [PATCH 15/53] basic TS setup --- src/solana/Anchor.toml | 1 - src/solana/package-lock.json | 226 +++---- src/solana/package.json | 1 + src/solana/tsconfig.json | 9 +- src/solana/yarn.lock | 1148 ---------------------------------- 5 files changed, 127 insertions(+), 1258 deletions(-) delete mode 100644 src/solana/yarn.lock diff --git a/src/solana/Anchor.toml b/src/solana/Anchor.toml index bd5f962..db9e2ff 100644 --- a/src/solana/Anchor.toml +++ b/src/solana/Anchor.toml @@ -1,5 +1,4 @@ [toolchain] -package_manager = "yarn" [features] resolution = true diff --git a/src/solana/package-lock.json b/src/solana/package-lock.json index 2db085e..a5ef397 100644 --- a/src/solana/package-lock.json +++ b/src/solana/package-lock.json @@ -6,7 +6,7 @@ "": { "license": "ISC", "dependencies": { - "@coral-xyz/anchor": "^0.31.0", + "@coral-xyz/anchor": "^0.31.1", "@noble/hashes": "^1.7.2", "@noble/secp256k1": "^2.2.3" }, @@ -34,13 +34,13 @@ } }, "node_modules/@coral-xyz/anchor": { - "version": "0.31.0", - "resolved": "https://registry.npmjs.org/@coral-xyz/anchor/-/anchor-0.31.0.tgz", - "integrity": "sha512-Yb1NwP1s4cWhAw7wL7vOLHSWWw3cD5D9pRCVSeJpdqPaI+w7sfRLScnVJL6ViYMZynB7nAG/5HcUPKUnY0L9rw==", + "version": "0.31.1", + "resolved": "https://registry.npmjs.org/@coral-xyz/anchor/-/anchor-0.31.1.tgz", + "integrity": "sha512-QUqpoEK+gi2S6nlYc2atgT2r41TT3caWr/cPUEL8n8Md9437trZ68STknq897b82p5mW0XrTBNOzRbmIRJtfsA==", "license": "(MIT OR Apache-2.0)", "dependencies": { - "@coral-xyz/anchor-errors": "^0.31.0", - "@coral-xyz/borsh": "^0.31.0", + "@coral-xyz/anchor-errors": "^0.31.1", + "@coral-xyz/borsh": "^0.31.1", "@noble/hashes": "^1.3.1", "@solana/web3.js": "^1.69.0", "bn.js": "^5.1.2", @@ -58,18 +58,18 @@ } }, "node_modules/@coral-xyz/anchor-errors": { - "version": "0.31.0", - "resolved": "https://registry.npmjs.org/@coral-xyz/anchor-errors/-/anchor-errors-0.31.0.tgz", - "integrity": "sha512-SUERksFSQ+4F11hkROIwHq4mcoSMXJxwVWLoklefi4dU679zVWFVcTq6O7otvjY8wlUaRXeE+iYcQWZTw2ll6w==", + "version": "0.31.1", + "resolved": "https://registry.npmjs.org/@coral-xyz/anchor-errors/-/anchor-errors-0.31.1.tgz", + "integrity": "sha512-NhNEku4F3zzUSBtrYz84FzYWm48+9OvmT1Hhnwr6GnPQry2dsEqH/ti/7ASjjpoFTWRnPXrjAIT1qM6Isop+LQ==", "license": "Apache-2.0", "engines": { "node": ">=10" } }, "node_modules/@coral-xyz/borsh": { - "version": "0.31.0", - "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.31.0.tgz", - "integrity": "sha512-DwdQ5fuj+rGQCTKRnxnW1W2lvcpBaFc9m9M1TcGGlm+bwCcggmDgbLKLgF+LjIrKnc7Nd+bCACx5RA9YTK2I4Q==", + "version": "0.31.1", + "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.31.1.tgz", + "integrity": "sha512-9N8AU9F0ubriKfNE3g1WF0/4dtlGXoBN/hd1PvbNBamBNwRgHxH4P+o3Zt7rSEloW1HUs6LfZEchlx9fW7POYw==", "license": "Apache-2.0", "dependencies": { "bn.js": "^5.1.2", @@ -83,12 +83,12 @@ } }, "node_modules/@noble/curves": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.8.1.tgz", - "integrity": "sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.0.tgz", + "integrity": "sha512-7YDlXiNMdO1YZeH6t/kvopHHbIZzlxrCV9WLqCY6QhcXOoXiNCMDqJIglZ9Yjx5+w7Dz30TITFrlTjnRg7sKEg==", "license": "MIT", "dependencies": { - "@noble/hashes": "1.7.1" + "@noble/hashes": "1.8.0" }, "engines": { "node": "^14.21.3 || >=16" @@ -97,22 +97,10 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/@noble/curves/node_modules/@noble/hashes": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.1.tgz", - "integrity": "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==", - "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@noble/hashes": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.2.tgz", - "integrity": "sha512-biZ0NUSxyjLLqo6KxEJ1b+C2NAx0wtDoFvCaXHGgUkeHzf3Xc1xKumFKREuT7f7DARNZ/slvYUwFG6B0f2b6hQ==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", "license": "MIT", "engines": { "node": "^14.21.3 || >=16" @@ -142,18 +130,80 @@ "node": ">=5.10" } }, + "node_modules/@solana/codecs-core": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@solana/codecs-core/-/codecs-core-2.1.0.tgz", + "integrity": "sha512-SR7pKtmJBg2mhmkel2NeHA1pz06QeQXdMv8WJoIR9m8F/hw80K/612uaYbwTt2nkK0jg/Qn/rNSd7EcJ4SBGjw==", + "license": "MIT", + "dependencies": { + "@solana/errors": "2.1.0" + }, + "engines": { + "node": ">=20.18.0" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/codecs-numbers": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@solana/codecs-numbers/-/codecs-numbers-2.1.0.tgz", + "integrity": "sha512-XMu4yw5iCgQnMKsxSWPPOrGgtaohmupN3eyAtYv3K3C/MJEc5V90h74k5B1GUCiHvcrdUDO9RclNjD9lgbjFag==", + "license": "MIT", + "dependencies": { + "@solana/codecs-core": "2.1.0", + "@solana/errors": "2.1.0" + }, + "engines": { + "node": ">=20.18.0" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/errors": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@solana/errors/-/errors-2.1.0.tgz", + "integrity": "sha512-l+GxAv0Ar4d3c3PlZdA9G++wFYZREEbbRyAFP8+n8HSg0vudCuzogh/13io6hYuUhG/9Ve8ARZNamhV7UScKNw==", + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "commander": "^13.1.0" + }, + "bin": { + "errors": "bin/cli.mjs" + }, + "engines": { + "node": ">=20.18.0" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/errors/node_modules/chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/@solana/web3.js": { - "version": "1.98.0", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.98.0.tgz", - "integrity": "sha512-nz3Q5OeyGFpFCR+erX2f6JPt3sKhzhYcSycBCSPkWjzSVDh/Rr1FqTVMRe58FKO16/ivTUcuJjeS5MyBvpkbzA==", + "version": "1.98.1", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.98.1.tgz", + "integrity": "sha512-gRAq1YPbfSDAbmho4kY7P/8iLIjMWXAzBJdP9iENFR+dFQSBSueHzjK/ou8fxhqHP9j+J4Msl4p/oDemFcIjlg==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.25.0", "@noble/curves": "^1.4.2", "@noble/hashes": "^1.4.0", "@solana/buffer-layout": "^4.0.1", + "@solana/codecs-numbers": "^2.1.0", "agentkeepalive": "^4.5.0", - "bigint-buffer": "^1.1.5", "bn.js": "^5.2.1", "borsh": "^0.7.0", "bs58": "^4.0.1", @@ -175,9 +225,9 @@ } }, "node_modules/@swc/helpers": { - "version": "0.5.15", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", - "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", + "version": "0.5.17", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz", + "integrity": "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.8.0" @@ -380,19 +430,6 @@ ], "license": "MIT" }, - "node_modules/bigint-buffer": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/bigint-buffer/-/bigint-buffer-1.1.5.tgz", - "integrity": "sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==", - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "bindings": "^1.3.0" - }, - "engines": { - "node": ">= 10.0.0" - } - }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", @@ -406,15 +443,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "license": "MIT", - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, "node_modules/bn.js": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", @@ -661,10 +689,13 @@ "license": "MIT" }, "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "license": "MIT" + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", + "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", + "license": "MIT", + "engines": { + "node": ">=18" + } }, "node_modules/concat-map": { "version": "0.0.1", @@ -820,12 +851,6 @@ "integrity": "sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==", "license": "MIT" }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "license": "MIT" - }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -1113,9 +1138,9 @@ } }, "node_modules/jayson": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/jayson/-/jayson-4.1.3.tgz", - "integrity": "sha512-LtXh5aYZodBZ9Fc3j6f2w+MTNcnxteMOrb+QgIouguGOulWi0lieEkOUg+HkjjFs0DGoWDds6bi4E9hpNFLulQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/jayson/-/jayson-4.2.0.tgz", + "integrity": "sha512-VfJ9t1YLwacIubLhONk0KFeosUBwstRWQ0IRT1KDjEjnVnSOVHC3uwugyV7L0c7R9lpVyrUGT2XWiBA1UTtpyg==", "license": "MIT", "dependencies": { "@types/connect": "^3.4.33", @@ -1127,7 +1152,7 @@ "eyes": "^0.1.8", "isomorphic-ws": "^4.0.1", "json-stringify-safe": "^5.0.1", - "JSONStream": "^1.3.5", + "stream-json": "^1.9.1", "uuid": "^8.3.2", "ws": "^7.5.10" }, @@ -1144,6 +1169,12 @@ "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", "license": "MIT" }, + "node_modules/jayson/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "license": "MIT" + }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -1177,31 +1208,6 @@ "json5": "lib/cli.js" } }, - "node_modules/jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", - "engines": [ - "node >= 0.2.0" - ], - "license": "MIT" - }, - "node_modules/JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", - "license": "(MIT OR Apache-2.0)", - "dependencies": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - }, - "bin": { - "JSONStream": "bin.js" - }, - "engines": { - "node": "*" - } - }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -1649,6 +1655,21 @@ "source-map": "^0.6.0" } }, + "node_modules/stream-chain": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/stream-chain/-/stream-chain-2.2.5.tgz", + "integrity": "sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA==", + "license": "BSD-3-Clause" + }, + "node_modules/stream-json": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/stream-json/-/stream-json-1.9.1.tgz", + "integrity": "sha512-uWkjJ+2Nt/LO9Z/JyKZbMusL8Dkh97uUBTv3AJQ74y07lVahLY4eEFsPsE97pxYBwr8nnjMAIch5eqI0gPShyw==", + "license": "BSD-3-Clause", + "dependencies": { + "stream-chain": "^2.2.5" + } + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -1728,12 +1749,6 @@ "resolved": "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz", "integrity": "sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==" }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "license": "MIT" - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -1848,7 +1863,6 @@ "version": "5.8.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", - "dev": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", diff --git a/src/solana/package.json b/src/solana/package.json index 5013f7f..0a52040 100644 --- a/src/solana/package.json +++ b/src/solana/package.json @@ -1,5 +1,6 @@ { "license": "ISC", + "type": "module", "scripts": { "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" diff --git a/src/solana/tsconfig.json b/src/solana/tsconfig.json index cd5d2e3..0cb09ec 100644 --- a/src/solana/tsconfig.json +++ b/src/solana/tsconfig.json @@ -2,9 +2,12 @@ "compilerOptions": { "types": ["mocha", "chai"], "typeRoots": ["./node_modules/@types"], - "lib": ["es2015"], - "module": "commonjs", - "target": "es6", + "lib": ["es2023"], + "module": "NodeNext", + "moduleResolution": "NodeNext", + "target": "es2022", + "strict": true, + "skipLibCheck": true, "esModuleInterop": true } } diff --git a/src/solana/yarn.lock b/src/solana/yarn.lock deleted file mode 100644 index 2e868fb..0000000 --- a/src/solana/yarn.lock +++ /dev/null @@ -1,1148 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@babel/runtime@^7.25.0": - version "7.27.0" - resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz" - integrity sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw== - dependencies: - regenerator-runtime "^0.14.0" - -"@coral-xyz/anchor-errors@^0.31.0": - version "0.31.0" - resolved "https://registry.npmjs.org/@coral-xyz/anchor-errors/-/anchor-errors-0.31.0.tgz" - integrity sha512-SUERksFSQ+4F11hkROIwHq4mcoSMXJxwVWLoklefi4dU679zVWFVcTq6O7otvjY8wlUaRXeE+iYcQWZTw2ll6w== - -"@coral-xyz/anchor@^0.31.0": - version "0.31.0" - resolved "https://registry.npmjs.org/@coral-xyz/anchor/-/anchor-0.31.0.tgz" - integrity sha512-Yb1NwP1s4cWhAw7wL7vOLHSWWw3cD5D9pRCVSeJpdqPaI+w7sfRLScnVJL6ViYMZynB7nAG/5HcUPKUnY0L9rw== - dependencies: - "@coral-xyz/anchor-errors" "^0.31.0" - "@coral-xyz/borsh" "^0.31.0" - "@noble/hashes" "^1.3.1" - "@solana/web3.js" "^1.69.0" - bn.js "^5.1.2" - bs58 "^4.0.1" - buffer-layout "^1.2.2" - camelcase "^6.3.0" - cross-fetch "^3.1.5" - eventemitter3 "^4.0.7" - pako "^2.0.3" - superstruct "^0.15.4" - toml "^3.0.0" - -"@coral-xyz/borsh@^0.31.0": - version "0.31.0" - resolved "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.31.0.tgz" - integrity sha512-DwdQ5fuj+rGQCTKRnxnW1W2lvcpBaFc9m9M1TcGGlm+bwCcggmDgbLKLgF+LjIrKnc7Nd+bCACx5RA9YTK2I4Q== - dependencies: - bn.js "^5.1.2" - buffer-layout "^1.2.0" - -"@noble/curves@^1.4.2": - version "1.8.1" - resolved "https://registry.npmjs.org/@noble/curves/-/curves-1.8.1.tgz" - integrity sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ== - dependencies: - "@noble/hashes" "1.7.1" - -"@noble/hashes@^1.3.1", "@noble/hashes@^1.4.0", "@noble/hashes@^1.7.2": - version "1.7.2" - resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.2.tgz" - integrity sha512-biZ0NUSxyjLLqo6KxEJ1b+C2NAx0wtDoFvCaXHGgUkeHzf3Xc1xKumFKREuT7f7DARNZ/slvYUwFG6B0f2b6hQ== - -"@noble/hashes@1.7.1": - version "1.7.1" - resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.1.tgz" - integrity sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ== - -"@noble/secp256k1@^2.2.3": - version "2.2.3" - resolved "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-2.2.3.tgz" - integrity sha512-l7r5oEQym9Us7EAigzg30/PQAvynhMt2uoYtT3t26eGDVm9Yii5mZ5jWSWmZ/oSIR2Et0xfc6DXrG0bZ787V3w== - -"@solana/buffer-layout@^4.0.1": - version "4.0.1" - resolved "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.1.tgz" - integrity sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA== - dependencies: - buffer "~6.0.3" - -"@solana/web3.js@^1.69.0": - version "1.98.0" - resolved "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.98.0.tgz" - integrity sha512-nz3Q5OeyGFpFCR+erX2f6JPt3sKhzhYcSycBCSPkWjzSVDh/Rr1FqTVMRe58FKO16/ivTUcuJjeS5MyBvpkbzA== - dependencies: - "@babel/runtime" "^7.25.0" - "@noble/curves" "^1.4.2" - "@noble/hashes" "^1.4.0" - "@solana/buffer-layout" "^4.0.1" - agentkeepalive "^4.5.0" - bigint-buffer "^1.1.5" - bn.js "^5.2.1" - borsh "^0.7.0" - bs58 "^4.0.1" - buffer "6.0.3" - fast-stable-stringify "^1.0.0" - jayson "^4.1.1" - node-fetch "^2.7.0" - rpc-websockets "^9.0.2" - superstruct "^2.0.2" - -"@swc/helpers@^0.5.11": - version "0.5.15" - resolved "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz" - integrity sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g== - dependencies: - tslib "^2.8.0" - -"@types/bn.js@^5.1.0": - version "5.1.6" - resolved "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.6.tgz" - integrity sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w== - dependencies: - "@types/node" "*" - -"@types/chai@^4.3.0": - version "4.3.20" - resolved "https://registry.npmjs.org/@types/chai/-/chai-4.3.20.tgz" - integrity sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ== - -"@types/connect@^3.4.33": - version "3.4.38" - resolved "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz" - integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== - dependencies: - "@types/node" "*" - -"@types/json5@^0.0.29": - version "0.0.29" - resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz" - integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== - -"@types/mocha@^9.0.0": - version "9.1.1" - resolved "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz" - integrity sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw== - -"@types/node@*": - version "22.13.17" - resolved "https://registry.npmjs.org/@types/node/-/node-22.13.17.tgz" - integrity sha512-nAJuQXoyPj04uLgu+obZcSmsfOenUg6DxPKogeUy6yNCFwWaj5sBF8/G/pNo8EtBJjAfSVgfIlugR/BCOleO+g== - dependencies: - undici-types "~6.20.0" - -"@types/node@^12.12.54": - version "12.20.55" - resolved "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz" - integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ== - -"@types/uuid@^8.3.4": - version "8.3.4" - resolved "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz" - integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw== - -"@types/ws@^7.4.4": - version "7.4.7" - resolved "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz" - integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== - dependencies: - "@types/node" "*" - -"@types/ws@^8.2.2": - version "8.18.1" - resolved "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz" - integrity sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg== - dependencies: - "@types/node" "*" - -"@ungap/promise-all-settled@1.1.2": - version "1.1.2" - resolved "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz" - integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== - -agentkeepalive@^4.5.0: - version "4.6.0" - resolved "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz" - integrity sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ== - dependencies: - humanize-ms "^1.2.1" - -ansi-colors@4.1.1: - version "4.1.1" - resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -anymatch@~3.1.2: - version "3.1.3" - resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz" - integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -arrify@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz" - integrity sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA== - -assertion-error@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz" - integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -base-x@^3.0.2: - version "3.0.11" - resolved "https://registry.npmjs.org/base-x/-/base-x-3.0.11.tgz" - integrity sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA== - dependencies: - safe-buffer "^5.0.1" - -base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - -bigint-buffer@^1.1.5: - version "1.1.5" - resolved "https://registry.npmjs.org/bigint-buffer/-/bigint-buffer-1.1.5.tgz" - integrity sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA== - dependencies: - bindings "^1.3.0" - -binary-extensions@^2.0.0: - version "2.3.0" - resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz" - integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== - -bindings@^1.3.0: - version "1.5.0" - resolved "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz" - integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== - dependencies: - file-uri-to-path "1.0.0" - -bn.js@^5.1.2, bn.js@^5.2.0, bn.js@^5.2.1: - version "5.2.1" - resolved "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz" - integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== - -borsh@^0.7.0: - version "0.7.0" - resolved "https://registry.npmjs.org/borsh/-/borsh-0.7.0.tgz" - integrity sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA== - dependencies: - bn.js "^5.2.0" - bs58 "^4.0.0" - text-encoding-utf-8 "^1.0.2" - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@~3.0.2: - version "3.0.3" - resolved "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz" - integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== - dependencies: - fill-range "^7.1.1" - -browser-stdout@1.3.1: - version "1.3.1" - resolved "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz" - integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== - -bs58@^4.0.0, bs58@^4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz" - integrity sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw== - dependencies: - base-x "^3.0.2" - -buffer-from@^1.0.0, buffer-from@^1.1.0: - version "1.1.2" - resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - -buffer-layout@^1.2.0, buffer-layout@^1.2.2: - version "1.2.2" - resolved "https://registry.npmjs.org/buffer-layout/-/buffer-layout-1.2.2.tgz" - integrity sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA== - -buffer@^6.0.3, buffer@~6.0.3, buffer@6.0.3: - version "6.0.3" - resolved "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz" - integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.2.1" - -bufferutil@^4.0.1: - version "4.0.9" - resolved "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.9.tgz" - integrity sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw== - dependencies: - node-gyp-build "^4.3.0" - -camelcase@^6.0.0, camelcase@^6.3.0: - version "6.3.0" - resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz" - integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== - -chai@^4.3.4: - version "4.5.0" - resolved "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz" - integrity sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw== - dependencies: - assertion-error "^1.1.0" - check-error "^1.0.3" - deep-eql "^4.1.3" - get-func-name "^2.0.2" - loupe "^2.3.6" - pathval "^1.1.1" - type-detect "^4.1.0" - -chalk@^4.1.0: - version "4.1.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -check-error@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz" - integrity sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg== - dependencies: - get-func-name "^2.0.2" - -chokidar@3.5.3: - version "3.5.3" - resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -commander@^2.20.3: - version "2.20.3" - resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - -cross-fetch@^3.1.5: - version "3.2.0" - resolved "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz" - integrity sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q== - dependencies: - node-fetch "^2.7.0" - -debug@4.3.3: - version "4.3.3" - resolved "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz" - integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== - dependencies: - ms "2.1.2" - -decamelize@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz" - integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== - -deep-eql@^4.1.3: - version "4.1.4" - resolved "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz" - integrity sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg== - dependencies: - type-detect "^4.0.0" - -delay@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz" - integrity sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw== - -diff@^3.1.0: - version "3.5.0" - resolved "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz" - integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== - -diff@5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz" - integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -es6-promise@^4.0.3: - version "4.2.8" - resolved "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz" - integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== - -es6-promisify@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz" - integrity sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ== - dependencies: - es6-promise "^4.0.3" - -escalade@^3.1.1: - version "3.2.0" - resolved "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz" - integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== - -escape-string-regexp@4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -eventemitter3@^4.0.7: - version "4.0.7" - resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" - integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== - -eventemitter3@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz" - integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== - -eyes@^0.1.8: - version "0.1.8" - resolved "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz" - integrity sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ== - -fast-stable-stringify@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz" - integrity sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag== - -file-uri-to-path@1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz" - integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== - -fill-range@^7.1.1: - version "7.1.1" - resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz" - integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== - dependencies: - to-regex-range "^5.0.1" - -find-up@5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -flat@^5.0.2: - version "5.0.2" - resolved "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz" - integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - -get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-func-name@^2.0.1, get-func-name@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz" - integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ== - -glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob@7.2.0: - version "7.2.0" - resolved "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz" - integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -growl@1.10.5: - version "1.10.5" - resolved "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz" - integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -he@1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/he/-/he-1.2.0.tgz" - integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== - -humanize-ms@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz" - integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== - dependencies: - ms "^2.0.0" - -ieee754@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" - integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2: - version "2.0.4" - resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-glob@^4.0.1, is-glob@~4.0.1: - version "4.0.3" - resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-plain-obj@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz" - integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== - -is-unicode-supported@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz" - integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - -isomorphic-ws@^4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz" - integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== - -jayson@^4.1.1: - version "4.1.3" - resolved "https://registry.npmjs.org/jayson/-/jayson-4.1.3.tgz" - integrity sha512-LtXh5aYZodBZ9Fc3j6f2w+MTNcnxteMOrb+QgIouguGOulWi0lieEkOUg+HkjjFs0DGoWDds6bi4E9hpNFLulQ== - dependencies: - "@types/connect" "^3.4.33" - "@types/node" "^12.12.54" - "@types/ws" "^7.4.4" - commander "^2.20.3" - delay "^5.0.0" - es6-promisify "^5.0.0" - eyes "^0.1.8" - isomorphic-ws "^4.0.1" - json-stringify-safe "^5.0.1" - JSONStream "^1.3.5" - uuid "^8.3.2" - ws "^7.5.10" - -js-yaml@4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -json-stringify-safe@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" - integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== - -json5@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz" - integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== - dependencies: - minimist "^1.2.0" - -jsonparse@^1.2.0: - version "1.3.1" - resolved "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz" - integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== - -JSONStream@^1.3.5: - version "1.3.5" - resolved "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz" - integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== - dependencies: - jsonparse "^1.2.0" - through ">=2.2.7 <3" - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -log-symbols@4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz" - integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== - dependencies: - chalk "^4.1.0" - is-unicode-supported "^0.1.0" - -loupe@^2.3.6: - version "2.3.7" - resolved "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz" - integrity sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA== - dependencies: - get-func-name "^2.0.1" - -make-error@^1.1.1: - version "1.3.6" - resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" - integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== - -minimatch@^3.0.4: - version "3.1.2" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -minimatch@4.2.1: - version "4.2.1" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz" - integrity sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g== - dependencies: - brace-expansion "^1.1.7" - -minimist@^1.2.0, minimist@^1.2.6: - version "1.2.8" - resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" - integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== - -mkdirp@^0.5.1: - version "0.5.6" - resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz" - integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== - dependencies: - minimist "^1.2.6" - -"mocha@^3.X.X || ^4.X.X || ^5.X.X || ^6.X.X || ^7.X.X || ^8.X.X || ^9.X.X || ^10.X.X || ^11.X.X", mocha@^9.0.3: - version "9.2.2" - resolved "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz" - integrity sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g== - dependencies: - "@ungap/promise-all-settled" "1.1.2" - ansi-colors "4.1.1" - browser-stdout "1.3.1" - chokidar "3.5.3" - debug "4.3.3" - diff "5.0.0" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "7.2.0" - growl "1.10.5" - he "1.2.0" - js-yaml "4.1.0" - log-symbols "4.1.0" - minimatch "4.2.1" - ms "2.1.3" - nanoid "3.3.1" - serialize-javascript "6.0.0" - strip-json-comments "3.1.1" - supports-color "8.1.1" - which "2.0.2" - workerpool "6.2.0" - yargs "16.2.0" - yargs-parser "20.2.4" - yargs-unparser "2.0.0" - -ms@^2.0.0, ms@2.1.3: - version "2.1.3" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -nanoid@3.3.1: - version "3.3.1" - resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz" - integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== - -node-fetch@^2.7.0: - version "2.7.0" - resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz" - integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== - dependencies: - whatwg-url "^5.0.0" - -node-gyp-build@^4.3.0: - version "4.8.4" - resolved "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz" - integrity sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ== - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -once@^1.3.0: - version "1.4.0" - resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" - integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== - dependencies: - wrappy "1" - -p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - -pako@^2.0.3: - version "2.1.0" - resolved "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz" - integrity sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug== - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== - -pathval@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz" - integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== - -picomatch@^2.0.4, picomatch@^2.2.1: - version "2.3.1" - resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -prettier@^2.6.2: - version "2.8.8" - resolved "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz" - integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== - -randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - -regenerator-runtime@^0.14.0: - version "0.14.1" - resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz" - integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" - integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== - -rpc-websockets@^9.0.2: - version "9.1.1" - resolved "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-9.1.1.tgz" - integrity sha512-1IXGM/TfPT6nfYMIXkJdzn+L4JEsmb0FL1O2OBjaH03V3yuUDdKFulGLMFG6ErV+8pZ5HVC0limve01RyO+saA== - dependencies: - "@swc/helpers" "^0.5.11" - "@types/uuid" "^8.3.4" - "@types/ws" "^8.2.2" - buffer "^6.0.3" - eventemitter3 "^5.0.1" - uuid "^8.3.2" - ws "^8.5.0" - optionalDependencies: - bufferutil "^4.0.1" - utf-8-validate "^5.0.2" - -safe-buffer@^5.0.1, safe-buffer@^5.1.0: - version "5.2.1" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -serialize-javascript@6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz" - integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== - dependencies: - randombytes "^2.1.0" - -source-map-support@^0.5.6: - version "0.5.21" - resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" - integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.6.0: - version "0.6.1" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -string-width@^4.1.0, string-width@^4.2.0: - version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" - 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" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" - integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== - -strip-json-comments@3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -superstruct@^0.15.4: - version "0.15.5" - resolved "https://registry.npmjs.org/superstruct/-/superstruct-0.15.5.tgz" - integrity sha512-4AOeU+P5UuE/4nOUkmcQdW5y7i9ndt1cQd/3iUe+LTz3RxESf/W/5lg4B74HbDMMv8PHnPnGCQFH45kBcrQYoQ== - -superstruct@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/superstruct/-/superstruct-2.0.2.tgz" - integrity sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A== - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -supports-color@8.1.1: - version "8.1.1" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - -text-encoding-utf-8@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz" - integrity sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg== - -"through@>=2.2.7 <3": - version "2.3.8" - resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz" - integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -toml@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz" - integrity sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w== - -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== - -ts-mocha@^10.0.0: - version "10.1.0" - resolved "https://registry.npmjs.org/ts-mocha/-/ts-mocha-10.1.0.tgz" - integrity sha512-T0C0Xm3/WqCuF2tpa0GNGESTBoKZaiqdUP8guNv4ZY316AFXlyidnrzQ1LUrCT0Wb1i3J0zFTgOh/55Un44WdA== - dependencies: - ts-node "7.0.1" - optionalDependencies: - tsconfig-paths "^3.5.0" - -ts-node@7.0.1: - version "7.0.1" - resolved "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz" - integrity sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw== - dependencies: - arrify "^1.0.0" - buffer-from "^1.1.0" - diff "^3.1.0" - make-error "^1.1.1" - minimist "^1.2.0" - mkdirp "^0.5.1" - source-map-support "^0.5.6" - yn "^2.0.0" - -tsconfig-paths@^3.5.0: - version "3.15.0" - resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz" - integrity sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg== - dependencies: - "@types/json5" "^0.0.29" - json5 "^1.0.2" - minimist "^1.2.6" - strip-bom "^3.0.0" - -tslib@^2.8.0: - version "2.8.1" - resolved "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz" - integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== - -type-detect@^4.0.0, type-detect@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz" - integrity sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw== - -typescript@^5.7.3: - version "5.8.2" - resolved "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz" - integrity sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ== - -undici-types@~6.20.0: - version "6.20.0" - resolved "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz" - integrity sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg== - -utf-8-validate@^5.0.2, utf-8-validate@>=5.0.2: - version "5.0.10" - resolved "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz" - integrity sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ== - dependencies: - node-gyp-build "^4.3.0" - -uuid@^8.3.2: - version "8.3.2" - resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz" - integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== - -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - -which@2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -workerpool@6.2.0: - version "6.2.0" - resolved "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz" - integrity sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A== - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - -ws@*, ws@^7.5.10: - version "7.5.10" - resolved "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz" - integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== - -ws@^8.5.0: - version "8.18.1" - resolved "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz" - integrity sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w== - -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - -yargs-parser@^20.2.2: - version "20.2.9" - resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - -yargs-parser@20.2.4: - version "20.2.4" - resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== - -yargs-unparser@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz" - integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== - dependencies: - camelcase "^6.0.0" - decamelize "^4.0.0" - flat "^5.0.2" - is-plain-obj "^2.1.0" - -yargs@16.2.0: - version "16.2.0" - resolved "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - -yn@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz" - integrity sha512-uTv8J/wiWTgUTg+9vLTi//leUl5vDQS6uii/emeTb2ssY7vl6QWf2fFbIIGjnhjvbdKlU0ed7QPgY1htTC86jQ== - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== From 44ca5a63a781fe80a57b9f6359be3793b8e2710e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Claudio=20Nale?= Date: Wed, 23 Apr 2025 13:54:41 -0300 Subject: [PATCH 16/53] solana: fix import in test --- src/solana/tests/solana.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/solana/tests/solana.ts b/src/solana/tests/solana.ts index 61ecf62..33d0b60 100644 --- a/src/solana/tests/solana.ts +++ b/src/solana/tests/solana.ts @@ -1,12 +1,12 @@ import * as anchor from "@coral-xyz/anchor"; import { Program } from "@coral-xyz/anchor"; -import { Solana } from "../target/types/solana"; +import { VerificationV2 } from "../target/types/verification_v2.js"; describe("solana", () => { // Configure the client to use the local cluster. anchor.setProvider(anchor.AnchorProvider.env()); - const program = anchor.workspace.solana as Program; + const program = anchor.workspace.solana as Program; it("Is initialized!", async () => { // Add your test here. From 52088f9be51c7c07cd57182bb7dd2c0b88ae79f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Claudio=20Nale?= Date: Wed, 23 Apr 2025 14:10:28 -0300 Subject: [PATCH 17/53] solana: sets up mocha --- .gitignore | 3 +- src/solana/.mocharc.json | 4 + src/solana/Anchor.toml | 2 +- src/solana/package-lock.json | 1380 +++++++++++++++++++++++++--------- src/solana/package.json | 7 +- src/solana/tsconfig.json | 5 +- 6 files changed, 1040 insertions(+), 361 deletions(-) create mode 100644 src/solana/.mocharc.json diff --git a/.gitignore b/.gitignore index f55315b..90fda89 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,5 @@ out out.log broadcast dist -ts-types \ No newline at end of file +ts-types +ts-build \ No newline at end of file diff --git a/src/solana/.mocharc.json b/src/solana/.mocharc.json new file mode 100644 index 0000000..8b7ad23 --- /dev/null +++ b/src/solana/.mocharc.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://json.schemastore.org/mocharc.json", + "require": "tsx/esm" +} diff --git a/src/solana/Anchor.toml b/src/solana/Anchor.toml index db9e2ff..673be47 100644 --- a/src/solana/Anchor.toml +++ b/src/solana/Anchor.toml @@ -15,4 +15,4 @@ cluster = "localnet" wallet = "~/.config/solana/id.json" [scripts] -test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" +test = "yarn run mocha -t 1000000 tests/**/*.ts" diff --git a/src/solana/package-lock.json b/src/solana/package-lock.json index a5ef397..12d300b 100644 --- a/src/solana/package-lock.json +++ b/src/solana/package-lock.json @@ -13,11 +13,11 @@ "devDependencies": { "@types/bn.js": "^5.1.0", "@types/chai": "^4.3.0", - "@types/mocha": "^9.0.0", + "@types/mocha": "^10.0.10", "chai": "^4.3.4", - "mocha": "^9.0.3", + "mocha": "^11.1.0", "prettier": "^2.6.2", - "ts-mocha": "^10.0.0", + "tsx": "^4.19.3", "typescript": "^5.7.3" } }, @@ -82,6 +82,449 @@ "@solana/web3.js": "^1.69.0" } }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.3.tgz", + "integrity": "sha512-W8bFfPA8DowP8l//sxjJLSLkD8iEjMc7cBVyP+u4cEv9sM7mdUCkgsj+t0n/BWPFtv7WWCN5Yzj0N6FJNUUqBQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.3.tgz", + "integrity": "sha512-PuwVXbnP87Tcff5I9ngV0lmiSu40xw1At6i3GsU77U7cjDDB4s0X2cyFuBiDa1SBk9DnvWwnGvVaGBqoFWPb7A==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.3.tgz", + "integrity": "sha512-XelR6MzjlZuBM4f5z2IQHK6LkK34Cvv6Rj2EntER3lwCBFdg6h2lKbtRjpTTsdEjD/WSe1q8UyPBXP1x3i/wYQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.3.tgz", + "integrity": "sha512-ogtTpYHT/g1GWS/zKM0cc/tIebFjm1F9Aw1boQ2Y0eUQ+J89d0jFY//s9ei9jVIlkYi8AfOjiixcLJSGNSOAdQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.3.tgz", + "integrity": "sha512-eESK5yfPNTqpAmDfFWNsOhmIOaQA59tAcF/EfYvo5/QWQCzXn5iUSOnqt3ra3UdzBv073ykTtmeLJZGt3HhA+w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.3.tgz", + "integrity": "sha512-Kd8glo7sIZtwOLcPbW0yLpKmBNWMANZhrC1r6K++uDR2zyzb6AeOYtI6udbtabmQpFaxJ8uduXMAo1gs5ozz8A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.3.tgz", + "integrity": "sha512-EJiyS70BYybOBpJth3M0KLOus0n+RRMKTYzhYhFeMwp7e/RaajXvP+BWlmEXNk6uk+KAu46j/kaQzr6au+JcIw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.3.tgz", + "integrity": "sha512-Q+wSjaLpGxYf7zC0kL0nDlhsfuFkoN+EXrx2KSB33RhinWzejOd6AvgmP5JbkgXKmjhmpfgKZq24pneodYqE8Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.3.tgz", + "integrity": "sha512-dUOVmAUzuHy2ZOKIHIKHCm58HKzFqd+puLaS424h6I85GlSDRZIA5ycBixb3mFgM0Jdh+ZOSB6KptX30DD8YOQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.3.tgz", + "integrity": "sha512-xCUgnNYhRD5bb1C1nqrDV1PfkwgbswTTBRbAd8aH5PhYzikdf/ddtsYyMXFfGSsb/6t6QaPSzxtbfAZr9uox4A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.3.tgz", + "integrity": "sha512-yplPOpczHOO4jTYKmuYuANI3WhvIPSVANGcNUeMlxH4twz/TeXuzEP41tGKNGWJjuMhotpGabeFYGAOU2ummBw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.3.tgz", + "integrity": "sha512-P4BLP5/fjyihmXCELRGrLd793q/lBtKMQl8ARGpDxgzgIKJDRJ/u4r1A/HgpBpKpKZelGct2PGI4T+axcedf6g==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.3.tgz", + "integrity": "sha512-eRAOV2ODpu6P5divMEMa26RRqb2yUoYsuQQOuFUexUoQndm4MdpXXDBbUoKIc0iPa4aCO7gIhtnYomkn2x+bag==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.3.tgz", + "integrity": "sha512-ZC4jV2p7VbzTlnl8nZKLcBkfzIf4Yad1SJM4ZMKYnJqZFD4rTI+pBG65u8ev4jk3/MPwY9DvGn50wi3uhdaghg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.3.tgz", + "integrity": "sha512-LDDODcFzNtECTrUUbVCs6j9/bDVqy7DDRsuIXJg6so+mFksgwG7ZVnTruYi5V+z3eE5y+BJZw7VvUadkbfg7QA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.3.tgz", + "integrity": "sha512-s+w/NOY2k0yC2p9SLen+ymflgcpRkvwwa02fqmAwhBRI3SC12uiS10edHHXlVWwfAagYSY5UpmT/zISXPMW3tQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.3.tgz", + "integrity": "sha512-nQHDz4pXjSDC6UfOE1Fw9Q8d6GCAd9KdvMZpfVGWSJztYCarRgSDfOVBY5xwhQXseiyxapkiSJi/5/ja8mRFFA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.3.tgz", + "integrity": "sha512-1QaLtOWq0mzK6tzzp0jRN3eccmN3hezey7mhLnzC6oNlJoUJz4nym5ZD7mDnS/LZQgkrhEbEiTn515lPeLpgWA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.3.tgz", + "integrity": "sha512-i5Hm68HXHdgv8wkrt+10Bc50zM0/eonPb/a/OFVfB6Qvpiirco5gBA5bz7S2SHuU+Y4LWn/zehzNX14Sp4r27g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.3.tgz", + "integrity": "sha512-zGAVApJEYTbOC6H/3QBr2mq3upG/LBEXr85/pTtKiv2IXcgKV0RT0QA/hSXZqSvLEpXeIxah7LczB4lkiYhTAQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.3.tgz", + "integrity": "sha512-fpqctI45NnCIDKBH5AXQBsD0NDPbEFczK98hk/aa6HJxbl+UtLkJV2+Bvy5hLSLk3LHmqt0NTkKNso1A9y1a4w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.3.tgz", + "integrity": "sha512-ROJhm7d8bk9dMCUZjkS8fgzsPAZEjtRJqCAmVgB0gMrvG7hfmPmz9k1rwO4jSiblFjYmNvbECL9uhaPzONMfgA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.3.tgz", + "integrity": "sha512-YWcow8peiHpNBiIXHwaswPnAXLsLVygFwCB3A7Bh5jRkIBFWHGmNQ48AlX4xDvQNoMZlPYzjVOQDYEzWCqufMQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.3.tgz", + "integrity": "sha512-qspTZOIGoXVS4DpNqUYUs9UxVb04khS1Degaw/MnfMe7goQ3lTfQ13Vw4qY/Nj0979BGvMRpAYbs/BAxEvU8ew==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.3.tgz", + "integrity": "sha512-ICgUR+kPimx0vvRzf+N/7L7tVSQeE3BYY+NhHRHXS1kBuPO7z2+7ea2HbhDyZdTephgvNvKrlDDKUexuCVBVvg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@noble/curves": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.0.tgz", @@ -118,6 +561,17 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@solana/buffer-layout": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.1.tgz", @@ -259,18 +713,10 @@ "@types/node": "*" } }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true, - "license": "MIT", - "optional": true - }, "node_modules/@types/mocha": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz", - "integrity": "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==", + "version": "10.0.10", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz", + "integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==", "dev": true, "license": "MIT" }, @@ -298,13 +744,6 @@ "@types/node": "*" } }, - "node_modules/@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true, - "license": "ISC" - }, "node_modules/agentkeepalive": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz", @@ -318,9 +757,9 @@ } }, "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "dev": true, "license": "MIT", "engines": { @@ -328,13 +767,16 @@ } }, "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, "node_modules/ansi-styles": { @@ -374,16 +816,6 @@ "dev": true, "license": "Python-2.0" }, - "node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", @@ -461,14 +893,13 @@ } }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^1.0.0" } }, "node_modules/braces": { @@ -524,13 +955,6 @@ "ieee754": "^1.2.1" } }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true, - "license": "MIT" - }, "node_modules/buffer-layout": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/buffer-layout/-/buffer-layout-1.2.2.tgz", @@ -657,15 +1081,81 @@ } }, "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, "license": "ISC", "dependencies": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", + "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/color-convert": { @@ -697,13 +1187,6 @@ "node": ">=18" } }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, - "license": "MIT" - }, "node_modules/cross-fetch": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz", @@ -713,14 +1196,29 @@ "node-fetch": "^2.7.0" } }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dev": true, "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -731,13 +1229,6 @@ } } }, - "node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true, - "license": "MIT" - }, "node_modules/decamelize": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", @@ -777,19 +1268,26 @@ } }, "node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true, "license": "MIT" }, @@ -808,6 +1306,47 @@ "es6-promise": "^4.0.3" } }, + "node_modules/esbuild": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.3.tgz", + "integrity": "sha512-qKA6Pvai73+M2FtftpNKRxJ78GIjmFXFxd/1DVBqGo/qNhLSfv+G12n9pNoWdytJC8U00TrViOwpjT0zgqQS8Q==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.3", + "@esbuild/android-arm": "0.25.3", + "@esbuild/android-arm64": "0.25.3", + "@esbuild/android-x64": "0.25.3", + "@esbuild/darwin-arm64": "0.25.3", + "@esbuild/darwin-x64": "0.25.3", + "@esbuild/freebsd-arm64": "0.25.3", + "@esbuild/freebsd-x64": "0.25.3", + "@esbuild/linux-arm": "0.25.3", + "@esbuild/linux-arm64": "0.25.3", + "@esbuild/linux-ia32": "0.25.3", + "@esbuild/linux-loong64": "0.25.3", + "@esbuild/linux-mips64el": "0.25.3", + "@esbuild/linux-ppc64": "0.25.3", + "@esbuild/linux-riscv64": "0.25.3", + "@esbuild/linux-s390x": "0.25.3", + "@esbuild/linux-x64": "0.25.3", + "@esbuild/netbsd-arm64": "0.25.3", + "@esbuild/netbsd-x64": "0.25.3", + "@esbuild/openbsd-arm64": "0.25.3", + "@esbuild/openbsd-x64": "0.25.3", + "@esbuild/sunos-x64": "0.25.3", + "@esbuild/win32-arm64": "0.25.3", + "@esbuild/win32-ia32": "0.25.3", + "@esbuild/win32-x64": "0.25.3" + } + }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -891,12 +1430,37 @@ "flat": "cli.js" } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", "dev": true, - "license": "ISC" + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } }, "node_modules/get-caller-file": { "version": "2.0.5", @@ -918,22 +1482,35 @@ "node": "*" } }, + "node_modules/get-tsconfig": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.0.tgz", + "integrity": "sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, "license": "ISC", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" }, - "engines": { - "node": "*" + "bin": { + "glob": "dist/esm/bin.mjs" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -953,26 +1530,19 @@ } }, "node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" }, "engines": { - "node": "*" - } - }, - "node_modules/growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4.x" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/has-flag": { @@ -1024,24 +1594,6 @@ ], "license": "BSD-3-Clause" }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, - "license": "ISC" - }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -1137,6 +1689,22 @@ "ws": "*" } }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/jayson": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/jayson/-/jayson-4.2.0.tgz", @@ -1194,20 +1762,6 @@ "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", "license": "ISC" }, - "node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -1251,91 +1805,70 @@ "get-func-name": "^2.0.1" } }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "dev": true, "license": "ISC" }, "node_modules/minimatch": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", - "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "minimist": "^1.2.6" + "brace-expansion": "^2.0.1" }, - "bin": { - "mkdirp": "bin/cmd.js" + "engines": { + "node": ">=10" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" } }, "node_modules/mocha": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", - "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.3", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.2.0", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "4.2.1", - "ms": "2.1.3", - "nanoid": "3.3.1", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "which": "2.0.2", - "workerpool": "6.2.0", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.1.0.tgz", + "integrity": "sha512-8uJR5RTC2NgpY3GrYcgpZrsEd9zKbPDpob1RezyR2upGHRQtHWofmzTMzTMSV6dru3tj5Ukt0+Vnq1qhFEEwAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^10.4.5", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^17.7.2", + "yargs-parser": "^21.1.1", + "yargs-unparser": "^2.0.0" }, "bin": { "_mocha": "bin/_mocha", - "mocha": "bin/mocha" + "mocha": "bin/mocha.js" }, "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/ms": { @@ -1344,19 +1877,6 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, - "node_modules/nanoid": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", - "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", - "dev": true, - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", @@ -1399,16 +1919,6 @@ "node": ">=0.10.0" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -1441,6 +1951,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, "node_modules/pako": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", @@ -1457,14 +1974,31 @@ "node": ">=8" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/pathval": { @@ -1545,6 +2079,16 @@ "node": ">=0.10.0" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, "node_modules/rpc-websockets": { "version": "9.1.1", "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-9.1.1.tgz", @@ -1625,34 +2169,49 @@ "license": "MIT" }, "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" } }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/stream-chain": { @@ -1671,6 +2230,25 @@ } }, "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", @@ -1685,7 +2263,54 @@ "node": ">=8" } }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", @@ -1698,15 +2323,14 @@ "node": ">=8" } }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "license": "MIT", - "optional": true, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/strip-json-comments": { @@ -1774,81 +2398,32 @@ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "license": "MIT" }, - "node_modules/ts-mocha": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/ts-mocha/-/ts-mocha-10.1.0.tgz", - "integrity": "sha512-T0C0Xm3/WqCuF2tpa0GNGESTBoKZaiqdUP8guNv4ZY316AFXlyidnrzQ1LUrCT0Wb1i3J0zFTgOh/55Un44WdA==", + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tsx": { + "version": "4.19.3", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.3.tgz", + "integrity": "sha512-4H8vUNGNjQ4V2EOoGw005+c+dGuPSnhpPBPHBtsZdGZBk/iJb4kguGlPWaZTZ3q5nMtFOEsY0nRDlh9PJyd6SQ==", "dev": true, "license": "MIT", "dependencies": { - "ts-node": "7.0.1" + "esbuild": "~0.25.0", + "get-tsconfig": "^4.7.5" }, "bin": { - "ts-mocha": "bin/ts-mocha" + "tsx": "dist/cli.mjs" }, "engines": { - "node": ">= 6.X.X" + "node": ">=18.0.0" }, "optionalDependencies": { - "tsconfig-paths": "^3.5.0" - }, - "peerDependencies": { - "mocha": "^3.X.X || ^4.X.X || ^5.X.X || ^6.X.X || ^7.X.X || ^8.X.X || ^9.X.X || ^10.X.X || ^11.X.X" - } - }, - "node_modules/ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, - "license": "MIT", - "dependencies": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - }, - "bin": { - "ts-node": "dist/bin.js" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/ts-node/node_modules/diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/tsconfig-paths": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", - "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" + "fsevents": "~2.3.3" } }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, "node_modules/type-detect": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", @@ -1934,13 +2509,32 @@ } }, "node_modules/workerpool": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", - "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", "dev": true, "license": "Apache-2.0" }, "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", @@ -1958,12 +2552,63 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, - "license": "ISC" + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } }, "node_modules/ws": { "version": "7.5.10", @@ -1997,32 +2642,32 @@ } }, "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "license": "MIT", "dependencies": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.0", + "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "yargs-parser": "^21.1.1" }, "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, "license": "ISC", "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/yargs-unparser": { @@ -2041,24 +2686,49 @@ "node": ">=10" } }, - "node_modules/yargs/node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, - "license": "ISC", + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha512-uTv8J/wiWTgUTg+9vLTi//leUl5vDQS6uii/emeTb2ssY7vl6QWf2fFbIIGjnhjvbdKlU0ed7QPgY1htTC86jQ==", + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/yocto-queue": { diff --git a/src/solana/package.json b/src/solana/package.json index 0a52040..5a11689 100644 --- a/src/solana/package.json +++ b/src/solana/package.json @@ -2,6 +2,7 @@ "license": "ISC", "type": "module", "scripts": { + "build": "tsc --build ./tsconfig.json", "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" }, @@ -13,11 +14,11 @@ "devDependencies": { "@types/bn.js": "^5.1.0", "@types/chai": "^4.3.0", - "@types/mocha": "^9.0.0", + "@types/mocha": "^10.0.10", "chai": "^4.3.4", - "mocha": "^9.0.3", + "mocha": "^11.1.0", "prettier": "^2.6.2", - "ts-mocha": "^10.0.0", + "tsx": "^4.19.3", "typescript": "^5.7.3" } } diff --git a/src/solana/tsconfig.json b/src/solana/tsconfig.json index 0cb09ec..331743d 100644 --- a/src/solana/tsconfig.json +++ b/src/solana/tsconfig.json @@ -6,8 +6,11 @@ "module": "NodeNext", "moduleResolution": "NodeNext", "target": "es2022", + "outDir": "ts-build", "strict": true, + "composite": true, "skipLibCheck": true, "esModuleInterop": true - } + }, + "include": ["tests", "target/types"] } From 35826a5ffcde1c279a503df5211cc42f1d13e02e Mon Sep 17 00:00:00 2001 From: Joshua Averett Date: Wed, 23 Apr 2025 23:05:00 -0700 Subject: [PATCH 18/53] Updates to solidity based on code review --- src/evm/GuardianRegistryVerification.sol | 48 ++---- src/evm/GuardianSetVerification.sol | 199 ++++++----------------- src/evm/GuardianSetVerificationState.sol | 72 ++++++++ src/evm/ThresholdVerification.sol | 173 ++++++++------------ src/evm/ThresholdVerificationState.sol | 76 +++++++++ src/evm/VerificationV2.sol | 132 ++++++++------- src/evm/WormholeVerifier.sol | 6 - 7 files changed, 350 insertions(+), 356 deletions(-) create mode 100644 src/evm/GuardianSetVerificationState.sol create mode 100644 src/evm/ThresholdVerificationState.sol delete mode 100644 src/evm/WormholeVerifier.sol diff --git a/src/evm/GuardianRegistryVerification.sol b/src/evm/GuardianRegistryVerification.sol index ae0e943..9946955 100644 --- a/src/evm/GuardianRegistryVerification.sol +++ b/src/evm/GuardianRegistryVerification.sol @@ -2,64 +2,50 @@ pragma solidity ^0.8.0; -import "./GuardianSetVerification.sol"; import {eagerOr} from "wormhole-sdk/Utils.sol"; import {BytesParsing} from "wormhole-sdk/libraries/BytesParsing.sol"; import {VaaLib} from "wormhole-sdk/libraries/VaaLib.sol"; -import "./WormholeVerifier.sol"; - -error RegistrationMessageExpired(); contract GuardianRegistryVerification { using BytesParsing for bytes; using VaaLib for bytes; + error RegistrationMessageExpired(); + error GuardianSignatureVerificationFailed(); + mapping (uint32 => bytes32[]) private _guardianTLSKeys; - function registerTLSKey( + function _registerTLSKey( uint32 guardianSetIndex, uint8 guardianIndex, bytes32 tlsKey, uint guardianSetSize ) internal { - unchecked { - if (_guardianTLSKeys[guardianSetIndex].length == 0) { - _guardianTLSKeys[guardianSetIndex] = new bytes32[](guardianSetSize); - } - _guardianTLSKeys[guardianSetIndex][guardianIndex] = tlsKey; + if (_guardianTLSKeys[guardianSetIndex].length == 0) { + _guardianTLSKeys[guardianSetIndex] = new bytes32[](guardianSetSize); } + + _guardianTLSKeys[guardianSetIndex][guardianIndex] = tlsKey; } - function getTLSKeys(uint32 guardianSetIndex) public view returns (bytes32[] memory tlsKeys) { - unchecked { - return _guardianTLSKeys[guardianSetIndex]; - } + function _getTLSKeys(uint32 guardianSetIndex) internal view returns (bytes32[] memory tlsKeys) { + return _guardianTLSKeys[guardianSetIndex]; } - function verifyRegisterTLSKey( + function _verifyRegisterTLSKey( address[] memory guardianAddrs, uint32 guardianSetIndex, uint32 expirationTime, bytes32 tlsKey, uint8 guardianIndex, bytes32 r, bytes32 s, uint8 v - ) public view { - unchecked { - if (expirationTime < block.timestamp) revert RegistrationMessageExpired(); - bytes32 dataHash = keccak256(abi.encodePacked(guardianSetIndex, expirationTime, tlsKey)); - if (_failsVerificationSingleGuardian(dataHash, guardianIndex, r, s, v, guardianAddrs)) - revert VerificationFailed(); - } - } + ) internal view { + require(expirationTime > block.timestamp, RegistrationMessageExpired()); + bytes32 dataHash = keccak256(abi.encodePacked(guardianSetIndex, expirationTime, tlsKey)); - function _failsVerificationSingleGuardian( - bytes32 dataHash, - uint guardianIndex, - bytes32 r, bytes32 s, uint8 v, - address[] memory guardians - ) private pure returns (bool) { + // Verify the signature address signatory = ecrecover(dataHash, v, r, s); - address guardian = guardians[guardianIndex]; - return signatory != guardian; + address guardian = guardianAddrs[guardianIndex]; + require(signatory == guardian, GuardianSignatureVerificationFailed()); } } diff --git a/src/evm/GuardianSetVerification.sol b/src/evm/GuardianSetVerification.sol index 2ccac22..0b43214 100644 --- a/src/evm/GuardianSetVerification.sol +++ b/src/evm/GuardianSetVerification.sol @@ -2,92 +2,44 @@ pragma solidity ^0.8.0; -import "./ExtStore.sol"; -import {IWormhole} from "wormhole-sdk/interfaces/IWormhole.sol"; import {eagerOr} from "wormhole-sdk/Utils.sol"; import {BytesParsing} from "wormhole-sdk/libraries/BytesParsing.sol"; import {VaaLib} from "wormhole-sdk/libraries/VaaLib.sol"; - import {CoreBridgeLib} from "wormhole-sdk/libraries/CoreBridge.sol"; import {UncheckedIndexing} from "wormhole-sdk/libraries/UncheckedIndexing.sol"; -import "./WormholeVerifier.sol"; +import "./GuardianSetVerificationState.sol"; -contract GuardianSetVerification is ExtStore { +contract GuardianSetVerification is GuardianSetVerificationState { using BytesParsing for bytes; using VaaLib for bytes; using UncheckedIndexing for address[]; - IWormhole private immutable _coreBridge; - - // Guardian set expiration time is stored in an array mapped from index to expiration time - uint32[] private _guardianSetExpirationTime; - constructor( address coreBridge, - uint pullLimit - ) { - _coreBridge = IWormhole(coreBridge); - pullGuardianSets(pullLimit); - } - - // Get the guardian addresses for a given guardian set index using the ExtStore - // On an invalid index, the function will panic - function getGuardianSetInfo(uint32 index) public view returns ( - uint32 expirationTime, - address[] memory guardianAddrs - ) { - if (index >= _guardianSetExpirationTime.length) revert InvalidIndex(); - expirationTime = _guardianSetExpirationTime[index]; - - // Read the guardian set data from the ExtStore - bytes memory data = _extRead(index); - - // Convert the guardian set data to an array of addresses - // NOTE: The `data` array is temporary and is invalid after this block - assembly ("memory-safe") { - guardianAddrs := data - mstore(guardianAddrs, div(mload(guardianAddrs), 32)) - } - } - - function getCurrentGuardianSetInfo() public view returns (uint32 index, address[] memory guardianAddrs) { - unchecked { - index = uint32(_guardianSetExpirationTime.length - 1); - (, guardianAddrs) = this.getGuardianSetInfo(index); - } - } + uint32 pullLimit + ) GuardianSetVerificationState(coreBridge, pullLimit) {} - // Verify a guardian set VAA - function verifyGuardianSetVAA(bytes calldata encodedVaa) public view returns ( - uint32 timestamp, - uint32 nonce, - uint16 emitterChainId, - bytes32 emitterAddress, - uint64 sequence, - uint8 consistencyLevel, - bytes calldata payload - ) { + function _verifyGuardianSetVaaHeader(bytes calldata encodedVaa) internal view returns (uint payloadOffset) { unchecked { - uint offset = VaaLib.checkVaaVersionCd(encodedVaa); + uint offset = 0; uint32 guardianSetIndex; + uint signatureCount; + (guardianSetIndex, offset) = encodedVaa.asUint32CdUnchecked(offset); + (signatureCount, offset) = encodedVaa.asUint8CdUnchecked(offset); - // Get the guardian set + // Get the guardian set and the number of guardians (, address[] memory guardians) = this.getGuardianSetInfo(guardianSetIndex); - // Get the number of guardians - // NOTE: Optimization puts var on stack thus avoids mload - uint guardianCount = guardians.length; - // Get the number of signatures - uint signatureCount; - (signatureCount, offset) = encodedVaa.asUint8CdUnchecked(offset); + // NOTE: Optimization puts guardianCount on stack thus avoids mloads + uint guardianCount = guardians.length; // Validate the number of signatures // NOTE: This works for empty guardian sets, because the quorum when there // are no guardians is 1 uint quorumCount = CoreBridgeLib.minSigsForQuorum(guardianCount); - if (signatureCount < quorumCount) revert VerificationFailed(); + require(signatureCount >= quorumCount, VerificationFailed()); // Calculate envelope offset and VAA hash uint envelopeOffset = offset + signatureCount * VaaLib.GUARDIAN_SIGNATURE_SIZE; @@ -102,106 +54,51 @@ contract GuardianSetVerification is ExtStore { // Decode the guardian index, r, s, and v uint guardianIndex; bytes32 r; bytes32 s; uint8 v; (guardianIndex, r, s, v, offset) = encodedVaa.decodeGuardianSignatureCdUnchecked(offset); + + // Verify the signature + address signatory = ecrecover(vaaHash, v, r, s); + address guardian = guardians.readUnchecked(guardianIndex); + + // Check that: + // * the guardian indicies are in strictly ascending order (only after the first signature) + // this is itself an optimization to efficiently prevent having the same guardian signature + // included twice + // * that the guardian index is not out of bounds + // * that the signatory is the guardian + // + // The core bridge also includes a separate check that signatory is not the zero address + // but this is already covered by comparing that the signatory matches the guardian which + // [can never be the zero address](https://github.com/wormhole-foundation/wormhole/blob/1dbe8459b96e182932d0dd5ae4b6bbce6f48cb09/ethereum/contracts/Setters.sol#L20) + bool failed = eagerOr( + eagerOr( + !eagerOr(isFirstSignature, guardianIndex > prevGuardianIndex), + guardianIndex >= guardianCount + ), + signatory != guardian + ); // Verify the signature - if (_failsVerification( - vaaHash, - guardianIndex, - r, s, v, - guardians, - guardianCount, - prevGuardianIndex, - isFirstSignature - )) revert VerificationFailed(); + require(!failed, VerificationFailed()); prevGuardianIndex = guardianIndex; isFirstSignature = false; } - // Decode the VAA body - return encodedVaa.decodeVaaBodyCd(envelopeOffset); + return offset; } } - function pullGuardianSets(uint limit) public { - unchecked { - // Get the guardian set lengths for the bridge and the local contract - uint currentGuardianSetLength = _coreBridge.getCurrentGuardianSetIndex() + 1; - uint oldGuardianSetLength = _guardianSetExpirationTime.length; - - // If we have already pulled all the guardian sets, return - if (currentGuardianSetLength == oldGuardianSetLength) return; - - // Check if we need to update the current guardian set - if (oldGuardianSetLength > 0) { - // Pull and write the current guardian set expiration time - uint updateIndex = oldGuardianSetLength - 1; - (, uint32 expirationTime) = _pullGuardianSet(uint32(updateIndex)); - _guardianSetExpirationTime[updateIndex] = expirationTime; - } - - // Calculate the upper bound of the guardian sets to pull - uint upper = (limit == 0 || currentGuardianSetLength - oldGuardianSetLength < limit) - ? currentGuardianSetLength : oldGuardianSetLength + limit; - - // Pull and append the guardian sets - for (uint i = oldGuardianSetLength; i < upper; ++i) { - // Pull the guardian set, write the expiration time, and append the guardian set data to the ExtStore - (bytes memory data, uint32 expirationTime) = _pullGuardianSet(uint32(i)); - _guardianSetExpirationTime.push(expirationTime); - _extWrite(data); - } - } - } - - function _pullGuardianSet(uint32 index) private view returns ( - bytes memory data, - uint32 expirationTime + // Verify a guardian set VAA + function _verifyAndDecodeGuardianSetVaa(bytes calldata encodedVaa) internal view returns ( + uint32 timestamp, + uint32 nonce, + uint16 emitterChainId, + bytes32 emitterAddress, + uint64 sequence, + uint8 consistencyLevel, + bytes calldata payload ) { - // Get the guardian set from the core bridge - IWormhole.GuardianSet memory guardians = _coreBridge.getGuardianSet(index); - - // Convert the guardian set to a byte array - // Result is stored in `data` - // NOTE: The `keys` array is temporary and is invalid after this block - address[] memory keys = guardians.keys; - assembly ("memory-safe") { - data := keys - mstore(data, mul(mload(data), 32)) - } - - // Return the expiration time - return (data, guardians.expirationTime); - } - - function _failsVerification( - bytes32 vaaHash, - uint guardianIndex, - bytes32 r, bytes32 s, uint8 v, - address[] memory guardians, - uint guardianCount, - uint prevGuardianIndex, - bool isFirstSignature - ) private pure returns (bool) { - address signatory = ecrecover(vaaHash, v, r, s); - address guardian = guardians.readUnchecked(guardianIndex); - - // Check that: - // * the guardian indicies are in strictly ascending order (only after the first signature) - // this is itself an optimization to efficiently prevent having the same guardian signature - // included twice - // * that the guardian index is not out of bounds - // * that the signatory is the guardian - // - // The core bridge also includes a separate check that signatory is not the zero address - // but this is already covered by comparing that the signatory matches the guardian which - // [can never be the zero address](https://github.com/wormhole-foundation/wormhole/blob/1dbe8459b96e182932d0dd5ae4b6bbce6f48cb09/ethereum/contracts/Setters.sol#L20) - return eagerOr( - eagerOr( - !eagerOr(isFirstSignature, guardianIndex > prevGuardianIndex), - guardianIndex >= guardianCount - ), - signatory != guardian - ); + uint payloadOffset = _verifyGuardianSetVaaHeader(encodedVaa); + return encodedVaa.decodeVaaBodyCd(payloadOffset); } } diff --git a/src/evm/GuardianSetVerificationState.sol b/src/evm/GuardianSetVerificationState.sol new file mode 100644 index 0000000..6b32740 --- /dev/null +++ b/src/evm/GuardianSetVerificationState.sol @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: Apache 2 + +pragma solidity ^0.8.0; + +import {IWormhole} from "wormhole-sdk/interfaces/IWormhole.sol"; +import {UncheckedIndexing} from "wormhole-sdk/libraries/UncheckedIndexing.sol"; +import {ExtStore} from "./ExtStore.sol"; + +contract GuardianSetVerificationState is ExtStore { + using UncheckedIndexing for address[]; + + error InvalidGuardianSetIndex(); + + // Core bridge instance + IWormhole private immutable _coreBridge; + + // Guardian set expiration time is stored in an array mapped from index to expiration time + uint32[] private _guardianSetExpirationTime; + + constructor( + address coreBridge, + uint32 pullLimit + ) { + _coreBridge = IWormhole(coreBridge); + _pullGuardianSets(pullLimit); + } + + // Get the guardian addresses for a given guardian set index using the ExtStore + // On an invalid index, the function will panic + function _getGuardianSetInfo(uint32 index) internal view returns ( + uint32 expirationTime, + address[] memory guardianAddrs + ) { + require(index < _guardianSetExpirationTime.length, InvalidGuardianSetIndex()); + expirationTime = _guardianSetExpirationTime[index]; + + // Read the guardian set data from the ExtStore + bytes memory data = _extRead(index); + + // Convert the guardian set data to an array of addresses + // NOTE: The `data` array is temporary and is invalid after this block + assembly ("memory-safe") { + guardianAddrs := data + mstore(guardianAddrs, div(mload(guardianAddrs), 32)) + } + } + + function _getCurrentGuardianSetInfo() internal view returns (uint32 index, address[] memory guardianAddrs) { + unchecked { + index = uint32(_guardianSetExpirationTime.length - 1); + (, guardianAddrs) = _getGuardianSetInfo(index); + } + } + + function _pullGuardianSet(uint32 index) private view returns ( + bytes memory data, + uint32 expirationTime + ) { + // Get the guardian set from the core bridge + IWormhole.GuardianSet memory guardians = _coreBridge.getGuardianSet(index); + expirationTime = guardians.expirationTime; + + // Convert the guardian set to a byte array + // Result is stored in `data` + // NOTE: The `keys` array is temporary and is invalid after this block + address[] memory keys = guardians.keys; + assembly ("memory-safe") { + data := keys + mstore(data, mul(mload(data), 32)) + } + } +} diff --git a/src/evm/ThresholdVerification.sol b/src/evm/ThresholdVerification.sol index 21b8f7e..764566d 100644 --- a/src/evm/ThresholdVerification.sol +++ b/src/evm/ThresholdVerification.sol @@ -4,123 +4,66 @@ pragma solidity ^0.8.0; import "wormhole-sdk/libraries/BytesParsing.sol"; import "wormhole-sdk/libraries/VaaLib.sol"; -import "./WormholeVerifier.sol"; +import "./ThresholdVerificationState.sol"; -contract ThresholdVerification { +// Emitter address for the VerificationV2 contract +bytes32 constant GOVERNANCE_ADDRESS = bytes32(0x0000000000000000000000000000000000000000000000000000000000000004); + +// Module ID for the VerificationV2 contract, ASCII "TSS" +bytes32 constant MODULE_VERIFICATION_V2 = bytes32(0x0000000000000000000000000000000000000000000000000000000000545353); + +// Action ID for appending a threshold key +uint8 constant ACTION_APPEND_THRESHOLD_KEY = 0x01; + +uint constant VAA_V2_HEADER_SIZE = 1 + 4 + 32 + 32 + 1; + +contract ThresholdVerification is ThresholdVerificationState { using BytesParsing for bytes; using VaaLib for bytes; + using {BytesParsing.checkLength} for uint; - error InvalidVaa(bytes encodedVaa); - error InvalidSignatureCount(uint8 count); - error InvalidGuardianSet(); - error GuardianSetExpired(); - - // Current threshold info is stord in a single slot - // Format: - // index (32 bits) - // address (160 bits) - // TODO: Extract this into its own functions - uint256 private _currentThresholdInfo; - - // Past threshold info is stored in an array - // Format: - // expiration time (32 bits) - // address (160 bits) - uint256[] private _pastThresholdInfo; - - bytes32[][] private _shards; - - // Get the current threshold signature info - function getCurrentThresholdInfo() public view returns (uint32 index, address addr) { - return _decodeThresholdInfo(_currentThresholdInfo); - } - - // Get the past threshold signature info - function getPastThresholdInfo(uint32 index) public view returns ( - uint32 expirationTime, - address addr - ) { - if (index >= _pastThresholdInfo.length) revert InvalidIndex(); - return _decodeThresholdInfo(_pastThresholdInfo[index]); - } + error ThresholdKeyExpired(); + error ThresholdSignatureVerificationFailed(); + error InvalidModule(bytes32 module); + error InvalidAction(uint8 action); // Verify a threshold signature VAA - function verifyThresholdVAA(bytes calldata encodedVaa) public view returns ( - uint32 timestamp, - uint32 nonce, - uint16 emitterChainId, - bytes32 emitterAddress, - uint64 sequence, - uint8 consistencyLevel, - bytes calldata payload - ) { + function _verifyThresholdVaaHeader(bytes calldata encodedVaa) internal view returns (uint payloadOffset) { unchecked { - // Check the VAA version + // Decode the VAA header uint offset = 0; uint8 version; - (version, offset) = encodedVaa.asUint8CdUnchecked(offset); - if (version != 2) revert VaaLib.InvalidVersion(version); - - // Decode the TSS key index uint32 tssIndex; - (tssIndex, offset) = encodedVaa.asUint32CdUnchecked(offset); - - // Get the current threshold info - ( uint32 currentThresholdIndex, - address currentThresholdAddr - ) = this.getCurrentThresholdInfo(); - - // Get the threshold address - address thresholdAddr; - if (tssIndex != currentThresholdIndex) { - // If the guardian set index is not the current threshold index, - // we need to get the past threshold info and validate that it is not expired - (uint32 expirationTime, address addr) = this.getPastThresholdInfo(tssIndex); - if (expirationTime < block.timestamp) revert GuardianSetExpired(); - thresholdAddr = addr; - } else { - // If the guardian set index is the current threshold index, - // we can use the current threshold info - thresholdAddr = currentThresholdAddr; - } - - // Decode the guardian signature bytes32 r; bytes32 s; uint8 v; + + (version, offset) = encodedVaa.asUint8CdUnchecked(offset); + (tssIndex, offset) = encodedVaa.asUint32CdUnchecked(offset); (r, s, v, offset) = _decodeThresholdSignatureCdUnchecked(encodedVaa, offset); - // Verify the threshold signature + // Validate and return the VAA body + require(version == 2, VaaLib.InvalidVersion(version)); + + (address thresholdAddr, uint32 expirationTime) = _getThresholdInfo(tssIndex); + require(expirationTime > block.timestamp, ThresholdKeyExpired()); + bytes32 vaaHash = encodedVaa.calcVaaDoubleHashCd(offset); - if (ecrecover(vaaHash, v, r, s) != thresholdAddr) revert VerificationFailed(); + require(ecrecover(vaaHash, v, r, s) == thresholdAddr, ThresholdSignatureVerificationFailed()); - // Decode the VAA body and return it - return encodedVaa.decodeVaaBodyCd(offset); + return offset; } } - function _appendThresholdKey( - uint32 newIndex, - address newAddr, - uint32 expirationDelaySeconds, - bytes32[] memory shards - ) internal { - unchecked { - // Verify the new address is not the zero address - if (newAddr == address(0)) revert InvalidGuardianSet(); - - // Get the current threshold info and verify the new index is sequential - (uint32 index, address currentAddr) = this.getCurrentThresholdInfo(); - if (newIndex != index + 1) revert InvalidIndex(); - - // Store the current threshold info in past threshold info - uint32 expirationTime = uint32(block.timestamp) + expirationDelaySeconds; - _pastThresholdInfo.push(_encodeThresholdInfo(expirationTime, currentAddr)); - - // Update the current threshold info - _currentThresholdInfo = _encodeThresholdInfo(newIndex, newAddr); - - // Store the shards - _shards.push(shards); - } + function _verifyAndDecodeThresholdVaa(bytes calldata encodedVaa) internal view returns ( + uint32 timestamp, + uint32 nonce, + uint16 emitterChainId, + bytes32 emitterAddress, + uint64 sequence, + uint8 consistencyLevel, + bytes calldata payload + ) { + uint payloadOffset = _verifyThresholdVaaHeader(encodedVaa); + return encodedVaa.decodeVaaBodyCd(payloadOffset); } function _decodeThresholdSignatureCdUnchecked( @@ -134,14 +77,28 @@ contract ThresholdVerification { return (r, s, v, offset); } - function _decodeThresholdInfo(uint256 info) internal pure returns (uint32 index, address addr) { - return ( - uint32(info), - address(uint160(info >> 32)) - ); - } - - function _encodeThresholdInfo(uint32 index, address addr) internal pure returns (uint256 info) { - return (uint256(uint160(addr)) << 32) | uint256(index); + // TODO: Fix this to use calldata + function _decodeThresholdKeyUpdatePayload(bytes calldata payload) internal pure returns ( + uint32 newThresholdIndex, + address newThresholdAddr, + uint32 expirationDelaySeconds, + bytes calldata shards + ) { + // Decode the payload + uint offset = 0; + uint8 action; + bytes32 module; + + (module, offset) = payload.asBytes32MemUnchecked(offset); + (action, offset) = payload.asUint8MemUnchecked(offset); + (newThresholdIndex, offset) = payload.asUint32MemUnchecked(offset); + (newThresholdAddr, offset) = payload.asAddressMemUnchecked(offset); + (expirationDelaySeconds, offset) = payload.asUint32MemUnchecked(offset); + (shards, offset) = payload.sliceUint16PrefixedCdUnchecked(offset); + payload.length.checkLength(offset); + + // Verify the module and action + require(module == MODULE_VERIFICATION_V2, InvalidModule(module)); + require(action == ACTION_APPEND_THRESHOLD_KEY, InvalidAction(action)); } } diff --git a/src/evm/ThresholdVerificationState.sol b/src/evm/ThresholdVerificationState.sol new file mode 100644 index 0000000..98f766d --- /dev/null +++ b/src/evm/ThresholdVerificationState.sol @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: Apache 2 + +pragma solidity ^0.8.0; + +contract ThresholdVerificationState { + error InvalidThresholdKeyIndex(); + error InvalidThresholdKeyAddress(); + + // Current threshold info is stored in a single slot + // Format: + // index (32 bits) + // address (160 bits) + uint256 private _currentThresholdInfo; + + // Past threshold info is stored in an array + // Format: + // expiration time (32 bits) + // address (160 bits) + uint256[] private _pastThresholdInfo; + + bytes32[][] private _shards; + + function _decodeThresholdInfo(uint256 info) private pure returns (address addr, uint32 index) { + return (address(uint160(info >> 32)), uint32(info & 0xFFFFFFFF)); + } + + function _encodeThresholdInfo(address addr, uint32 index) private pure returns (uint256) { + return (uint256(uint160(addr)) << 32) | uint256(index); + } + + // Get the current threshold signature info + function _getCurrentThresholdInfo() internal view returns (address addr, uint32 index) { + return _decodeThresholdInfo(_currentThresholdInfo); + } + + // Get the past threshold signature info + function _getPastThresholdInfo(uint32 index) internal view returns ( + address addr, + uint32 expirationTime + ) { + require(index < _pastThresholdInfo.length, InvalidThresholdKeyIndex()); + return _decodeThresholdInfo(_pastThresholdInfo[index]); + } + + function _getThresholdInfo(uint32 index) internal view returns (address thresholdAddr, uint32 expirationTime) { + (address currentAddr, uint32 currentIndex) = _getCurrentThresholdInfo(); + return index == currentIndex ? (currentAddr, 0) : _getPastThresholdInfo(index); + } + + function _appendThresholdKey( + uint32 newIndex, + address newAddr, + uint32 expirationDelaySeconds, + bytes32[] calldata shards + ) internal { + unchecked { + // Verify the new address is not the zero address + // This prevents errors from ecrecover returning the zero address + require(newAddr != address(0), InvalidThresholdKeyAddress()); + + // Get the current threshold info and verify the new index is sequential + (address currentAddr, uint32 index) = _getCurrentThresholdInfo(); + require(newIndex == index + 1, InvalidThresholdKeyIndex()); + + // Store the expiration time and current threshold address in past threshold info + uint32 expirationTime = uint32(block.timestamp) + expirationDelaySeconds; + _pastThresholdInfo.push(_encodeThresholdInfo(currentAddr, expirationTime)); + + // Update the current threshold info + _currentThresholdInfo = _encodeThresholdInfo(newAddr, newIndex); + + // Store the shards + _shards.push(shards); + } + } +} diff --git a/src/evm/VerificationV2.sol b/src/evm/VerificationV2.sol index 0966d67..5b1b49a 100644 --- a/src/evm/VerificationV2.sol +++ b/src/evm/VerificationV2.sol @@ -23,15 +23,6 @@ uint8 constant OP_GUARDIAN_SET_GET_CURRENT = 0x23; uint8 constant OP_GUARDIAN_SET_GET = 0x24; uint8 constant OP_GUARDIAN_TLS_GET = 0x25; -// Emitter address for the VerificationV2 contract -bytes32 constant GOVERNANCE_ADDRESS = bytes32(0x0000000000000000000000000000000000000000000000000000000000000004); - -// Module ID for the VerificationV2 contract, ASCII "TSS" -bytes32 constant MODULE_VERIFICATION_V2 = bytes32(0x0000000000000000000000000000000000000000000000000000000000545353); - -// Action ID for appending a threshold key -uint8 constant ACTION_APPEND_THRESHOLD_KEY = 0x01; - contract VerificationV2 is RawDispatcher, ThresholdVerification, GuardianSetVerification, GuardianRegistryVerification { @@ -39,11 +30,8 @@ contract VerificationV2 is using VaaLib for bytes; using {BytesParsing.checkLength} for uint; - error InvalidDispatchVersion(uint8 version); - error InvalidModule(bytes32 module); - error InvalidAction(uint8 action); error InvalidValue(); - + error InvalidOperation(uint8 op); error InvalidGovernanceChainId(); error InvalidGovernanceAddress(); @@ -55,55 +43,37 @@ contract VerificationV2 is GuardianRegistryVerification() {} - function _decodeAndVerifyVaa(bytes calldata encodedVaa) internal view returns ( + function _verifyVaa(bytes calldata data, uint offset) private view { + (uint8 version, ) = data.asUint8CdUnchecked(offset); + if (version == 2) { + _verifyThresholdVaa(data, offset); + } else if (version == 1) { + _verifyGuardianSetVaa(data, offset); + } else { + revert VaaLib.InvalidVersion(version); + } + } + + function _verifyAndDecodeVaa(bytes calldata data, uint offset) private view returns ( uint32 timestamp, uint32 nonce, uint16 emitterChainId, bytes32 emitterAddress, uint64 sequence, uint8 consistencyLevel, - bytes calldata payload + bytes calldata payload, + uint resultOffset ) { - (uint8 version, ) = encodedVaa.asUint8CdUnchecked(0); + (uint8 version, ) = data.asUint8CdUnchecked(offset); if (version == 2) { - return verifyThresholdVAA(encodedVaa); + return _verifyAndDecodeThresholdVaa(data, offset); } else if (version == 1) { - return verifyGuardianSetVAA(encodedVaa); + return _verifyAndDecodeGuardianSetVaa(data, offset); } else { revert VaaLib.InvalidVersion(version); } } - function _decodeThresholdKeyUpdatePayload(bytes memory payload) internal pure returns ( - uint32 newThresholdIndex, - address newThresholdAddr, - uint32 expirationDelaySeconds, - bytes32[] memory shards - ) { - // Decode and verify the module and action - uint offset = 0; - - bytes32 module; - (module, offset) = payload.asBytes32MemUnchecked(offset); - if (module != MODULE_VERIFICATION_V2) revert InvalidModule(module); - - uint8 action; - (action, offset) = payload.asUint8MemUnchecked(offset); - if (action != ACTION_APPEND_THRESHOLD_KEY) revert InvalidAction(action); - - // Decode the message body - (newThresholdIndex, offset) = payload.asUint32MemUnchecked(offset); - (newThresholdAddr, offset) = payload.asAddressMemUnchecked(offset); - (expirationDelaySeconds, offset) = payload.asUint32MemUnchecked(offset); - - uint8 shardsLength; - (shardsLength, offset) = payload.asUint8MemUnchecked(offset); - shards = new bytes32[](shardsLength); - for (uint i = 0; i < shardsLength; ++i) { - (shards[i], offset) = payload.asBytes32MemUnchecked(offset); - } - } - function _exec(bytes calldata data) internal override returns (bytes memory) { if (msg.value != 0) revert InvalidValue(); @@ -118,6 +88,8 @@ contract VerificationV2 is (encodedVaa, offset) = data.sliceUint16PrefixedCdUnchecked(offset); // Decode and verify the VAA + // TODO: Might be better to have a custom function to do the decoding here + // so we don't drop so many fields ( , , @@ -126,7 +98,7 @@ contract VerificationV2 is , , bytes calldata payload - ) = _decodeAndVerifyVaa(encodedVaa); + ) = _verifyAndDecodeGuardianSetVaa(encodedVaa); // Verify the emitter if (emitterChainId != CHAIN_ID_SOLANA) revert InvalidGovernanceChainId(); @@ -137,7 +109,7 @@ contract VerificationV2 is uint32 newThresholdIndex, address newThresholdAddr, uint32 expirationDelaySeconds, - bytes32[] memory shards + bytes32[] calldata shards ) = _decodeThresholdKeyUpdatePayload(payload); // Append the threshold key @@ -148,17 +120,22 @@ contract VerificationV2 is pullGuardianSets(limit); } else if (op == OP_REGISTER_TLS_KEY) { + // Decode the payload uint32 guardianSetIndex; - (guardianSetIndex, offset) = data.asUint32CdUnchecked(offset); uint32 expirationTime; - (expirationTime, offset) = data.asUint32CdUnchecked(offset); bytes32 tlsKey; - (tlsKey, offset) = data.asBytes32CdUnchecked(offset); uint8 guardianIndex; bytes32 r; bytes32 s; uint8 v; + + // TODO: EIP-712 signature + (guardianSetIndex, offset) = data.asUint32CdUnchecked(offset); + (expirationTime, offset) = data.asUint32CdUnchecked(offset); + (tlsKey, offset) = data.asBytes32CdUnchecked(offset); (guardianIndex, r, s, v, offset) = data.decodeGuardianSignatureCdUnchecked(offset); + // We only allow registrations for the current guardian set (uint32 currentSetIndex, address[] memory guardianAddrs) = this.getCurrentGuardianSetInfo(); - if (guardianSetIndex != currentSetIndex) revert GuardianSetIsNotCurrent(); + require(guardianSetIndex == currentSetIndex, GuardianSetIsNotCurrent()); + verifyRegisterTLSKey( guardianAddrs, guardianSetIndex, @@ -167,9 +144,11 @@ contract VerificationV2 is guardianIndex, r, s, v ); + registerTLSKey(guardianSetIndex, guardianIndex, tlsKey, guardianAddrs.length); + } else { + revert InvalidOperation(op); } - // TODO: Isn't this missing an else revert? } // Verify the data has been consumed @@ -185,12 +164,12 @@ contract VerificationV2 is uint8 op; (op, offset) = data.asUint8CdUnchecked(offset); - if (op == OP_VERIFY) { + if (op == OP_VERIFY_AND_DECODE_VAA) { // Read the VAA bytes calldata encodedVaa; (encodedVaa, offset) = data.sliceUint16PrefixedCdUnchecked(offset); - // Decode the VAA + // Verify and decode the VAA ( uint32 timestamp, uint32 nonce, @@ -199,7 +178,7 @@ contract VerificationV2 is uint64 sequence, uint8 consistencyLevel, bytes calldata payload - ) = _decodeAndVerifyVaa(encodedVaa); + ) = _verifyAndDecodeVaa(encodedVaa); result = abi.encodePacked( result, @@ -211,31 +190,48 @@ contract VerificationV2 is consistencyLevel, payload ); + } else if (op == OP_VERIFY_VAA) { + // Read the VAA + bytes calldata encodedVaa; + (encodedVaa, offset) = data.sliceUint16PrefixedCdUnchecked(offset); + + // Verify the VAA + _verifyVaa(encodedVaa); } else if (op == OP_THRESHOLD_GET_CURRENT) { (uint32 thresholdIndex, address thresholdAddr) = getCurrentThresholdInfo(); + result = abi.encodePacked(result, thresholdIndex, thresholdAddr); } else if (op == OP_THRESHOLD_GET) { uint32 index; (index, offset) = data.asUint32CdUnchecked(offset); + (uint32 expirationTime, address thresholdAddr) = getPastThresholdInfo(index); + result = abi.encodePacked(result, expirationTime, thresholdAddr); } else if (op == OP_GUARDIAN_SET_GET_CURRENT) { (uint32 guardianSetIndex, address[] memory guardianSetAddrs) = getCurrentGuardianSetInfo(); + result = abi.encodePacked(result, guardianSetIndex, guardianSetAddrs); } else if (op == OP_GUARDIAN_SET_GET) { uint32 index; (index, offset) = data.asUint32CdUnchecked(offset); + (uint32 expirationTime, address[] memory guardianSetAddrs) = getGuardianSetInfo(index); + result = abi.encodePacked(result, expirationTime, guardianSetAddrs); } else if (op == OP_GUARDIAN_TLS_GET) { uint32 guardianSetIndex; (guardianSetIndex, offset) = data.asUint32CdUnchecked(offset); + uint8 guardianIndex; (guardianIndex, offset) = data.asUint8CdUnchecked(offset); + bytes32[] memory tlsKeys = getTLSKeys(guardianSetIndex); + result = abi.encodePacked(result, tlsKeys); + } else { + revert InvalidOperation(op); } - // TODO: Isn't this missing an else revert? } // Verify the data has been consumed @@ -243,4 +239,20 @@ contract VerificationV2 is return result; } -} + + function verifyVaa(bytes calldata encodedVaa) internal view { + _verifyVaa(encodedVaa); + } + + function verifyAndDecodeVaa(bytes calldata encodedVaa) internal view returns ( + uint32 timestamp, + uint32 nonce, + uint16 emitterChainId, + bytes32 emitterAddress, + uint64 sequence, + uint8 consistencyLevel, + bytes calldata payload + ) { + return _verifyAndDecodeVaa(encodedVaa); + } +} \ No newline at end of file diff --git a/src/evm/WormholeVerifier.sol b/src/evm/WormholeVerifier.sol deleted file mode 100644 index 49615aa..0000000 --- a/src/evm/WormholeVerifier.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: Apache 2 - -pragma solidity ^0.8.0; - -error InvalidIndex(); -error VerificationFailed(); From 2f2b4c321f9193a61305373d43423cb8a45a5c0c Mon Sep 17 00:00:00 2001 From: Joshua Averett Date: Thu, 24 Apr 2025 12:21:40 -0700 Subject: [PATCH 19/53] Fix for missing pullGuardianSets --- src/evm/GuardianSetVerificationState.sol | 31 ++++++++++++++++++++++++ src/evm/VerificationV2.sol | 2 +- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/evm/GuardianSetVerificationState.sol b/src/evm/GuardianSetVerificationState.sol index 6b32740..9a0f3ad 100644 --- a/src/evm/GuardianSetVerificationState.sol +++ b/src/evm/GuardianSetVerificationState.sol @@ -51,6 +51,37 @@ contract GuardianSetVerificationState is ExtStore { (, guardianAddrs) = _getGuardianSetInfo(index); } } + + function _pullGuardianSets(uint limit) internal { + unchecked { + // Get the guardian set lengths for the bridge and the local contract + uint currentGuardianSetLength = _coreBridge.getCurrentGuardianSetIndex() + 1; + uint oldGuardianSetLength = _guardianSetExpirationTime.length; + + // If we have already pulled all the guardian sets, return + if (currentGuardianSetLength == oldGuardianSetLength) return; + + // Check if we need to update the current guardian set + if (oldGuardianSetLength > 0) { + // Pull and write the current guardian set expiration time + uint updateIndex = oldGuardianSetLength - 1; + (, uint32 expirationTime) = _pullGuardianSet(uint32(updateIndex)); + _guardianSetExpirationTime[updateIndex] = expirationTime; + } + + // Calculate the upper bound of the guardian sets to pull + uint upper = (limit == 0 || currentGuardianSetLength - oldGuardianSetLength < limit) + ? currentGuardianSetLength : oldGuardianSetLength + limit; + + // Pull and append the guardian sets + for (uint i = oldGuardianSetLength; i < upper; ++i) { + // Pull the guardian set, write the expiration time, and append the guardian set data to the ExtStore + (bytes memory data, uint32 expirationTime) = _pullGuardianSet(uint32(i)); + _guardianSetExpirationTime.push(expirationTime); + _extWrite(data); + } + } + } function _pullGuardianSet(uint32 index) private view returns ( bytes memory data, diff --git a/src/evm/VerificationV2.sol b/src/evm/VerificationV2.sol index 5b1b49a..003572d 100644 --- a/src/evm/VerificationV2.sol +++ b/src/evm/VerificationV2.sol @@ -118,7 +118,7 @@ contract VerificationV2 is uint32 limit; (limit, offset) = data.asUint32CdUnchecked(offset); - pullGuardianSets(limit); + _pullGuardianSets(limit); } else if (op == OP_REGISTER_TLS_KEY) { // Decode the payload uint32 guardianSetIndex; From a9d5a949cd20278e6d7f88c5120121a49939eed4 Mon Sep 17 00:00:00 2001 From: Joshua Averett Date: Thu, 24 Apr 2025 15:22:21 -0700 Subject: [PATCH 20/53] Second round of code review --- src/evm/GuardianSetVerification.sol | 22 ++++--- src/evm/GuardianSetVerificationState.sol | 12 ++-- src/evm/ThresholdVerification.sol | 69 +++++++++++++--------- src/evm/ThresholdVerificationState.sol | 14 ++++- src/evm/VerificationV2.sol | 74 +++++++++++++----------- 5 files changed, 112 insertions(+), 79 deletions(-) diff --git a/src/evm/GuardianSetVerification.sol b/src/evm/GuardianSetVerification.sol index 0b43214..49882c9 100644 --- a/src/evm/GuardianSetVerification.sol +++ b/src/evm/GuardianSetVerification.sol @@ -14,22 +14,30 @@ contract GuardianSetVerification is GuardianSetVerificationState { using VaaLib for bytes; using UncheckedIndexing for address[]; + error QuorumNotMet(); + error GuardianSetSignatureVerificationFailed(); + constructor( address coreBridge, - uint32 pullLimit + uint256 pullLimit ) GuardianSetVerificationState(coreBridge, pullLimit) {} - function _verifyGuardianSetVaaHeader(bytes calldata encodedVaa) internal view returns (uint payloadOffset) { + function _verifyGuardianSetVaaHeader(bytes calldata encodedVaa) internal view returns (uint envelopeOffset) { unchecked { uint offset = 0; + uint8 version; uint32 guardianSetIndex; uint signatureCount; + (version, offset) = encodedVaa.asUint8CdUnchecked(offset); (guardianSetIndex, offset) = encodedVaa.asUint32CdUnchecked(offset); (signatureCount, offset) = encodedVaa.asUint8CdUnchecked(offset); + // Validate the version + require(version == 1, VaaLib.InvalidVersion(version)); + // Get the guardian set and the number of guardians - (, address[] memory guardians) = this.getGuardianSetInfo(guardianSetIndex); + (, address[] memory guardians) = _getGuardianSetInfo(guardianSetIndex); // Get the number of signatures // NOTE: Optimization puts guardianCount on stack thus avoids mloads @@ -39,10 +47,10 @@ contract GuardianSetVerification is GuardianSetVerificationState { // NOTE: This works for empty guardian sets, because the quorum when there // are no guardians is 1 uint quorumCount = CoreBridgeLib.minSigsForQuorum(guardianCount); - require(signatureCount >= quorumCount, VerificationFailed()); + require(signatureCount >= quorumCount, QuorumNotMet()); // Calculate envelope offset and VAA hash - uint envelopeOffset = offset + signatureCount * VaaLib.GUARDIAN_SIGNATURE_SIZE; + envelopeOffset = offset + signatureCount * VaaLib.GUARDIAN_SIGNATURE_SIZE; bytes32 vaaHash = encodedVaa.calcVaaDoubleHashCd(envelopeOffset); // Verify the signatures @@ -78,13 +86,11 @@ contract GuardianSetVerification is GuardianSetVerificationState { ); // Verify the signature - require(!failed, VerificationFailed()); + require(!failed, GuardianSetSignatureVerificationFailed()); prevGuardianIndex = guardianIndex; isFirstSignature = false; } - - return offset; } } diff --git a/src/evm/GuardianSetVerificationState.sol b/src/evm/GuardianSetVerificationState.sol index 9a0f3ad..96ee3c2 100644 --- a/src/evm/GuardianSetVerificationState.sol +++ b/src/evm/GuardianSetVerificationState.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.0; -import {IWormhole} from "wormhole-sdk/interfaces/IWormhole.sol"; +import {ICoreBridge, GuardianSet} from "wormhole-sdk/interfaces/ICoreBridge.sol"; import {UncheckedIndexing} from "wormhole-sdk/libraries/UncheckedIndexing.sol"; import {ExtStore} from "./ExtStore.sol"; @@ -12,16 +12,16 @@ contract GuardianSetVerificationState is ExtStore { error InvalidGuardianSetIndex(); // Core bridge instance - IWormhole private immutable _coreBridge; + ICoreBridge private immutable _coreBridge; // Guardian set expiration time is stored in an array mapped from index to expiration time uint32[] private _guardianSetExpirationTime; constructor( address coreBridge, - uint32 pullLimit + uint256 pullLimit ) { - _coreBridge = IWormhole(coreBridge); + _coreBridge = ICoreBridge(coreBridge); _pullGuardianSets(pullLimit); } @@ -52,7 +52,7 @@ contract GuardianSetVerificationState is ExtStore { } } - function _pullGuardianSets(uint limit) internal { + function _pullGuardianSets(uint256 limit) internal { unchecked { // Get the guardian set lengths for the bridge and the local contract uint currentGuardianSetLength = _coreBridge.getCurrentGuardianSetIndex() + 1; @@ -88,7 +88,7 @@ contract GuardianSetVerificationState is ExtStore { uint32 expirationTime ) { // Get the guardian set from the core bridge - IWormhole.GuardianSet memory guardians = _coreBridge.getGuardianSet(index); + GuardianSet memory guardians = _coreBridge.getGuardianSet(index); expirationTime = guardians.expirationTime; // Convert the guardian set to a byte array diff --git a/src/evm/ThresholdVerification.sol b/src/evm/ThresholdVerification.sol index 764566d..412096d 100644 --- a/src/evm/ThresholdVerification.sol +++ b/src/evm/ThresholdVerification.sol @@ -6,9 +6,6 @@ import "wormhole-sdk/libraries/BytesParsing.sol"; import "wormhole-sdk/libraries/VaaLib.sol"; import "./ThresholdVerificationState.sol"; -// Emitter address for the VerificationV2 contract -bytes32 constant GOVERNANCE_ADDRESS = bytes32(0x0000000000000000000000000000000000000000000000000000000000000004); - // Module ID for the VerificationV2 contract, ASCII "TSS" bytes32 constant MODULE_VERIFICATION_V2 = bytes32(0x0000000000000000000000000000000000000000000000000000000000545353); @@ -28,7 +25,7 @@ contract ThresholdVerification is ThresholdVerificationState { error InvalidAction(uint8 action); // Verify a threshold signature VAA - function _verifyThresholdVaaHeader(bytes calldata encodedVaa) internal view returns (uint payloadOffset) { + function _verifyThresholdVaaHeader(bytes calldata encodedVaa) internal view returns (uint envelopeOffset) { unchecked { // Decode the VAA header uint offset = 0; @@ -70,35 +67,53 @@ contract ThresholdVerification is ThresholdVerificationState { bytes calldata encodedVaa, uint offset ) internal pure returns (bytes32 r, bytes32 s, uint8 v, uint nextOffset) { - (r, offset) = encodedVaa.asBytes32CdUnchecked(offset); - (s, offset) = encodedVaa.asBytes32CdUnchecked(offset); - (v, offset) = encodedVaa.asUint8CdUnchecked(offset); - v += VaaLib.SIGNATURE_RECOVERY_MAGIC; - return (r, s, v, offset); + unchecked { + (r, offset) = encodedVaa.asBytes32CdUnchecked(offset); + (s, offset) = encodedVaa.asBytes32CdUnchecked(offset); + (v, offset) = encodedVaa.asUint8CdUnchecked(offset); + v += VaaLib.SIGNATURE_RECOVERY_MAGIC; + return (r, s, v, offset); + } } - // TODO: Fix this to use calldata function _decodeThresholdKeyUpdatePayload(bytes calldata payload) internal pure returns ( uint32 newThresholdIndex, address newThresholdAddr, uint32 expirationDelaySeconds, - bytes calldata shards + ShardInfo[] memory shards ) { - // Decode the payload - uint offset = 0; - uint8 action; - bytes32 module; - - (module, offset) = payload.asBytes32MemUnchecked(offset); - (action, offset) = payload.asUint8MemUnchecked(offset); - (newThresholdIndex, offset) = payload.asUint32MemUnchecked(offset); - (newThresholdAddr, offset) = payload.asAddressMemUnchecked(offset); - (expirationDelaySeconds, offset) = payload.asUint32MemUnchecked(offset); - (shards, offset) = payload.sliceUint16PrefixedCdUnchecked(offset); - payload.length.checkLength(offset); - - // Verify the module and action - require(module == MODULE_VERIFICATION_V2, InvalidModule(module)); - require(action == ACTION_APPEND_THRESHOLD_KEY, InvalidAction(action)); + unchecked { + // Decode the payload + uint offset = 0; + uint8 action; + bytes32 module; + uint shardCount; + + (module, offset) = payload.asBytes32MemUnchecked(offset); + (action, offset) = payload.asUint8MemUnchecked(offset); + (newThresholdIndex, offset) = payload.asUint32MemUnchecked(offset); + (newThresholdAddr, offset) = payload.asAddressMemUnchecked(offset); + (expirationDelaySeconds, offset) = payload.asUint32MemUnchecked(offset); + (shardCount, offset) = payload.asUint8MemUnchecked(offset); // TODO: We should probably pass this in and get it from the guardian set to ensure the mapping is correct + + // Decode shards + shards = new ShardInfo[](shardCount); + for (uint i = 0; i < shardCount; i++) { + (shards[i], offset) = _decodeShardInfo(payload, offset); + } + + // Validate the length of the payload + payload.length.checkLength(offset); + + // Verify the module and action + require(module == MODULE_VERIFICATION_V2, InvalidModule(module)); + require(action == ACTION_APPEND_THRESHOLD_KEY, InvalidAction(action)); + } + } + + function _decodeShardInfo(bytes calldata data, uint256 offset) internal pure returns (ShardInfo memory shardInfo, uint256 nextOffset) { + (shardInfo.shard, offset) = data.asBytes32CdUnchecked(offset); + (shardInfo.tlsKey, offset) = data.asBytes32CdUnchecked(offset); + return (shardInfo, offset); } } diff --git a/src/evm/ThresholdVerificationState.sol b/src/evm/ThresholdVerificationState.sol index 98f766d..de30568 100644 --- a/src/evm/ThresholdVerificationState.sol +++ b/src/evm/ThresholdVerificationState.sol @@ -3,9 +3,17 @@ pragma solidity ^0.8.0; contract ThresholdVerificationState { + uint256 constant SHARD_INFO_SIZE = 32 + 32; + error InvalidThresholdKeyIndex(); error InvalidThresholdKeyAddress(); + // TODO: Add the registry data here + struct ShardInfo { + bytes32 shard; + bytes32 tlsKey; // TODO: Replace the mapping in the guardian registry with this + } + // Current threshold info is stored in a single slot // Format: // index (32 bits) @@ -18,7 +26,7 @@ contract ThresholdVerificationState { // address (160 bits) uint256[] private _pastThresholdInfo; - bytes32[][] private _shards; + ShardInfo[][] private _shards; function _decodeThresholdInfo(uint256 info) private pure returns (address addr, uint32 index) { return (address(uint160(info >> 32)), uint32(info & 0xFFFFFFFF)); @@ -51,7 +59,7 @@ contract ThresholdVerificationState { uint32 newIndex, address newAddr, uint32 expirationDelaySeconds, - bytes32[] calldata shards + ShardInfo[] memory shards ) internal { unchecked { // Verify the new address is not the zero address @@ -69,7 +77,7 @@ contract ThresholdVerificationState { // Update the current threshold info _currentThresholdInfo = _encodeThresholdInfo(newAddr, newIndex); - // Store the shards + // Push the shards _shards.push(shards); } } diff --git a/src/evm/VerificationV2.sol b/src/evm/VerificationV2.sol index 003572d..419cb9e 100644 --- a/src/evm/VerificationV2.sol +++ b/src/evm/VerificationV2.sol @@ -16,12 +16,16 @@ uint8 constant OP_PULL_GUARDIAN_SETS = 0x01; uint8 constant OP_REGISTER_TLS_KEY = 0x02; // Raw dispatch operation IDs for get -uint8 constant OP_VERIFY = 0x20; -uint8 constant OP_THRESHOLD_GET_CURRENT = 0x21; -uint8 constant OP_THRESHOLD_GET = 0x22; -uint8 constant OP_GUARDIAN_SET_GET_CURRENT = 0x23; -uint8 constant OP_GUARDIAN_SET_GET = 0x24; -uint8 constant OP_GUARDIAN_TLS_GET = 0x25; +uint8 constant OP_VERIFY_AND_DECODE_VAA = 0x20; +uint8 constant OP_VERIFY_VAA = 0x21; +uint8 constant OP_THRESHOLD_GET_CURRENT = 0x22; +uint8 constant OP_THRESHOLD_GET = 0x23; +uint8 constant OP_GUARDIAN_SET_GET_CURRENT = 0x24; +uint8 constant OP_GUARDIAN_SET_GET = 0x25; +uint8 constant OP_GUARDIAN_TLS_GET = 0x26; + +// Emitter address for the VerificationV2 contract +bytes32 constant GOVERNANCE_ADDRESS = bytes32(0x0000000000000000000000000000000000000000000000000000000000000004); contract VerificationV2 is RawDispatcher, ThresholdVerification, GuardianSetVerification, GuardianRegistryVerification @@ -37,38 +41,38 @@ contract VerificationV2 is error GuardianSetIsNotCurrent(); - constructor(address coreV1, uint pullLimit) + // TODO: Consider how to initialize the contract, pulling in guardian sets and threshold keys + constructor(address coreV1, uint256 pullLimit) ThresholdVerification() GuardianSetVerification(coreV1, pullLimit) GuardianRegistryVerification() {} - function _verifyVaa(bytes calldata data, uint offset) private view { - (uint8 version, ) = data.asUint8CdUnchecked(offset); + function _verifyVaa(bytes calldata data) private view { + (uint8 version, ) = data.asUint8CdUnchecked(0); if (version == 2) { - _verifyThresholdVaa(data, offset); + _verifyThresholdVaaHeader(data); } else if (version == 1) { - _verifyGuardianSetVaa(data, offset); + _verifyGuardianSetVaaHeader(data); } else { revert VaaLib.InvalidVersion(version); } } - function _verifyAndDecodeVaa(bytes calldata data, uint offset) private view returns ( - uint32 timestamp, - uint32 nonce, - uint16 emitterChainId, + function _verifyAndDecodeVaa(bytes calldata data) private view returns ( + uint32 timestamp, + uint32 nonce, + uint16 emitterChainId, bytes32 emitterAddress, - uint64 sequence, - uint8 consistencyLevel, - bytes calldata payload, - uint resultOffset + uint64 sequence, + uint8 consistencyLevel, + bytes calldata payload ) { - (uint8 version, ) = data.asUint8CdUnchecked(offset); + (uint8 version, ) = data.asUint8CdUnchecked(0); if (version == 2) { - return _verifyAndDecodeThresholdVaa(data, offset); + return _verifyAndDecodeThresholdVaa(data); } else if (version == 1) { - return _verifyAndDecodeGuardianSetVaa(data, offset); + return _verifyAndDecodeGuardianSetVaa(data); } else { revert VaaLib.InvalidVersion(version); } @@ -109,7 +113,7 @@ contract VerificationV2 is uint32 newThresholdIndex, address newThresholdAddr, uint32 expirationDelaySeconds, - bytes32[] calldata shards + ShardInfo[] memory shards ) = _decodeThresholdKeyUpdatePayload(payload); // Append the threshold key @@ -133,10 +137,10 @@ contract VerificationV2 is (guardianIndex, r, s, v, offset) = data.decodeGuardianSignatureCdUnchecked(offset); // We only allow registrations for the current guardian set - (uint32 currentSetIndex, address[] memory guardianAddrs) = this.getCurrentGuardianSetInfo(); + (uint32 currentSetIndex, address[] memory guardianAddrs) = _getCurrentGuardianSetInfo(); require(guardianSetIndex == currentSetIndex, GuardianSetIsNotCurrent()); - verifyRegisterTLSKey( + _verifyRegisterTLSKey( guardianAddrs, guardianSetIndex, expirationTime, @@ -145,7 +149,7 @@ contract VerificationV2 is r, s, v ); - registerTLSKey(guardianSetIndex, guardianIndex, tlsKey, guardianAddrs.length); + _registerTLSKey(guardianSetIndex, guardianIndex, tlsKey, guardianAddrs.length); } else { revert InvalidOperation(op); } @@ -198,27 +202,27 @@ contract VerificationV2 is // Verify the VAA _verifyVaa(encodedVaa); } else if (op == OP_THRESHOLD_GET_CURRENT) { - (uint32 thresholdIndex, address thresholdAddr) = getCurrentThresholdInfo(); + (address thresholdAddr, uint32 thresholdIndex) = _getCurrentThresholdInfo(); - result = abi.encodePacked(result, thresholdIndex, thresholdAddr); + result = abi.encodePacked(result, thresholdAddr, thresholdIndex); } else if (op == OP_THRESHOLD_GET) { uint32 index; (index, offset) = data.asUint32CdUnchecked(offset); - (uint32 expirationTime, address thresholdAddr) = getPastThresholdInfo(index); + (address thresholdAddr, uint32 expirationTime) = _getPastThresholdInfo(index); - result = abi.encodePacked(result, expirationTime, thresholdAddr); + result = abi.encodePacked(result, thresholdAddr, expirationTime); } else if (op == OP_GUARDIAN_SET_GET_CURRENT) { - (uint32 guardianSetIndex, address[] memory guardianSetAddrs) = getCurrentGuardianSetInfo(); + (uint32 guardianSetIndex, address[] memory guardianSetAddrs) = _getCurrentGuardianSetInfo(); - result = abi.encodePacked(result, guardianSetIndex, guardianSetAddrs); + result = abi.encodePacked(result, guardianSetAddrs, guardianSetIndex); } else if (op == OP_GUARDIAN_SET_GET) { uint32 index; (index, offset) = data.asUint32CdUnchecked(offset); - (uint32 expirationTime, address[] memory guardianSetAddrs) = getGuardianSetInfo(index); + (uint32 expirationTime, address[] memory guardianSetAddrs) = _getGuardianSetInfo(index); - result = abi.encodePacked(result, expirationTime, guardianSetAddrs); + result = abi.encodePacked(result, guardianSetAddrs, expirationTime); } else if (op == OP_GUARDIAN_TLS_GET) { uint32 guardianSetIndex; (guardianSetIndex, offset) = data.asUint32CdUnchecked(offset); @@ -226,7 +230,7 @@ contract VerificationV2 is uint8 guardianIndex; (guardianIndex, offset) = data.asUint8CdUnchecked(offset); - bytes32[] memory tlsKeys = getTLSKeys(guardianSetIndex); + bytes32[] memory tlsKeys = _getTLSKeys(guardianSetIndex); result = abi.encodePacked(result, tlsKeys); } else { From 680e9e0107054f2bc417146ac2f6a11b30e4beab Mon Sep 17 00:00:00 2001 From: NoiTaTuM Date: Fri, 25 Apr 2025 00:39:06 -0300 Subject: [PATCH 21/53] Update Wormhole Solidity SDK dependency --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b25361a..a53c003 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ test: dependencies LIB_DEPS = foundry-rs/forge-std LIB_DEPS += openzeppelin/openzeppelin-contracts@0457042d93d9dfd760dbaa06a4d2f1216fdbe297 #for gscd's optimizations -LIB_DEPS += wormhole-foundation/wormhole-solidity-sdk@9206704 +LIB_DEPS += wormhole-foundation/wormhole-solidity-sdk@d6a9368 # dynamically generate install rule for each lib dependency and add to depdenencies $(foreach dep,$(LIB_DEPS), $(eval $(call install_lib,$(dep)))) From 7495c9b7e87e0108e889bb0672e06e34d09e7ecb Mon Sep 17 00:00:00 2001 From: Joshua Averett Date: Mon, 28 Apr 2025 11:02:59 -0700 Subject: [PATCH 22/53] Initial tests for solana --- src/solana/Anchor.toml | 2 +- src/solana/package-lock.json | 5251 ++++++++++++++++++++++++++- src/solana/package.json | 8 +- src/solana/tests/solana.ts | 16 - src/solana/tests/testing_helpers.ts | 142 + src/solana/tests/verification_v2.ts | 166 + 6 files changed, 5377 insertions(+), 208 deletions(-) delete mode 100644 src/solana/tests/solana.ts create mode 100644 src/solana/tests/testing_helpers.ts create mode 100644 src/solana/tests/verification_v2.ts diff --git a/src/solana/Anchor.toml b/src/solana/Anchor.toml index 673be47..dc7342a 100644 --- a/src/solana/Anchor.toml +++ b/src/solana/Anchor.toml @@ -5,7 +5,7 @@ resolution = true skip-lint = false [programs.localnet] -solana = "CTyCJvaLgY18BTTY3M1ga1SmY5fuT3Jyu3j7s332Z3oz" +verification_v2 = "CTyCJvaLgY18BTTY3M1ga1SmY5fuT3Jyu3j7s332Z3oz" [registry] url = "https://api.apr.dev" diff --git a/src/solana/package-lock.json b/src/solana/package-lock.json index 12d300b..537d9af 100644 --- a/src/solana/package-lock.json +++ b/src/solana/package-lock.json @@ -6,15 +6,19 @@ "": { "license": "ISC", "dependencies": { + "@certusone/wormhole-sdk": "^0.10.18", "@coral-xyz/anchor": "^0.31.1", "@noble/hashes": "^1.7.2", - "@noble/secp256k1": "^2.2.3" + "@noble/secp256k1": "^2.2.3", + "chai-as-promised": "^8.0.1", + "diff": "^7.0.0" }, "devDependencies": { "@types/bn.js": "^5.1.0", "@types/chai": "^4.3.0", + "@types/chai-as-promised": "^8.0.2", "@types/mocha": "^10.0.10", - "chai": "^4.3.4", + "chai": "^4.5.0", "mocha": "^11.1.0", "prettier": "^2.6.2", "tsx": "^4.19.3", @@ -33,6 +37,186 @@ "node": ">=6.9.0" } }, + "node_modules/@bangjelkoski/store2": { + "version": "2.14.3", + "resolved": "https://registry.npmjs.org/@bangjelkoski/store2/-/store2-2.14.3.tgz", + "integrity": "sha512-ZG6ZDOHU5MZ4yxA3yY3gcZYnkcPtPaOwGOJrWD4Drar/u1TTBy1tWnP70atBa6LGm1+Ll1nb2GwS+HyWuFOWkw==", + "license": "MIT", + "optional": true + }, + "node_modules/@certusone/wormhole-sdk": { + "version": "0.10.18", + "resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk/-/wormhole-sdk-0.10.18.tgz", + "integrity": "sha512-VuN4AGB018ELkzTT/jN+yWgE6TWqXsHilxxCVWqGctzow2hKSFd8ADUhxhHigies436rS0vPvrgXi6m0J1+Ecw==", + "deprecated": "Please use the new Wormhole TypeScript SDK instead: @wormhole-foundation/sdk", + "license": "Apache-2.0", + "dependencies": { + "@certusone/wormhole-sdk-proto-web": "0.0.7", + "@certusone/wormhole-sdk-wasm": "^0.0.1", + "@coral-xyz/borsh": "0.2.6", + "@mysten/sui.js": "0.32.2", + "@project-serum/anchor": "^0.25.0", + "@solana/spl-token": "^0.3.5", + "@solana/web3.js": "^1.66.2", + "@terra-money/terra.js": "3.1.9", + "@xpla/xpla.js": "^0.2.1", + "algosdk": "^2.4.0", + "aptos": "1.5.0", + "axios": "^0.24.0", + "bech32": "^2.0.0", + "binary-parser": "^2.2.1", + "bs58": "^4.0.1", + "elliptic": "^6.5.4", + "js-base64": "^3.6.1", + "near-api-js": "^1.0.0" + }, + "optionalDependencies": { + "@injectivelabs/networks": "1.10.12", + "@injectivelabs/sdk-ts": "1.10.72", + "@injectivelabs/utils": "1.10.12" + } + }, + "node_modules/@certusone/wormhole-sdk-proto-web": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk-proto-web/-/wormhole-sdk-proto-web-0.0.7.tgz", + "integrity": "sha512-GCe1/bcqMS0Mt+hsWp4SE4NLL59pWmK0lhQXO0oqAKl0G9AuuTdudySMDF/sLc7z5H2w34bSuSrIEKvPuuSC+w==", + "license": "Apache-2.0", + "dependencies": { + "@improbable-eng/grpc-web": "^0.15.0", + "protobufjs": "^7.0.0", + "rxjs": "^7.5.6" + } + }, + "node_modules/@certusone/wormhole-sdk-wasm": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk-wasm/-/wormhole-sdk-wasm-0.0.1.tgz", + "integrity": "sha512-LdIwLhOyr4pPs2jqYubqC7d4UkqYBX0EG/ppspQlW3qlVE0LZRMrH6oVzzLMyHtV0Rw7O9sIKzORW/T3mrJv2w==", + "license": "Apache-2.0", + "dependencies": { + "@types/long": "^4.0.2", + "@types/node": "^18.0.3" + } + }, + "node_modules/@certusone/wormhole-sdk-wasm/node_modules/@types/node": { + "version": "18.19.87", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.87.tgz", + "integrity": "sha512-OIAAu6ypnVZHmsHCeJ+7CCSub38QNBS9uceMQeg7K5Ur0Jr+wG9wEOEvvMbhp09pxD5czIUy/jND7s7Tb6Nw7A==", + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@certusone/wormhole-sdk-wasm/node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "license": "MIT" + }, + "node_modules/@certusone/wormhole-sdk/node_modules/@coral-xyz/borsh": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.2.6.tgz", + "integrity": "sha512-y6nmHw1bFcJib7sMHsQPpC8r47xhqDZVvhUdna7NUPzpSbOZG6f46N21+aXsQ2w/tG8Ggls488J/ZmwbgVmyjg==", + "license": "Apache-2.0", + "dependencies": { + "bn.js": "^5.1.2", + "buffer-layout": "^1.2.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@solana/web3.js": "^1.2.0" + } + }, + "node_modules/@classic-terra/terra.proto": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@classic-terra/terra.proto/-/terra.proto-1.1.0.tgz", + "integrity": "sha512-bYhQG5LUaGF0KPRY9hYT/HEcd1QExZPQd6zLV/rQkCe/eDxfwFRLzZHpaaAdfWoAAZjsRWqJbUCqCg7gXBbJpw==", + "license": "Apache-2.0", + "dependencies": { + "@improbable-eng/grpc-web": "^0.14.1", + "google-protobuf": "^3.17.3", + "long": "^4.0.0", + "protobufjs": "~6.11.2" + } + }, + "node_modules/@classic-terra/terra.proto/node_modules/@improbable-eng/grpc-web": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@improbable-eng/grpc-web/-/grpc-web-0.14.1.tgz", + "integrity": "sha512-XaIYuunepPxoiGVLLHmlnVminUGzBTnXr8Wv7khzmLWbNw4TCwJKX09GSMJlKhu/TRk6gms0ySFxewaETSBqgw==", + "license": "Apache-2.0", + "dependencies": { + "browser-headers": "^0.4.1" + }, + "peerDependencies": { + "google-protobuf": "^3.14.0" + } + }, + "node_modules/@classic-terra/terra.proto/node_modules/protobufjs": { + "version": "6.11.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz", + "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, + "node_modules/@confio/ics23": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/@confio/ics23/-/ics23-0.6.8.tgz", + "integrity": "sha512-wB6uo+3A50m0sW/EWcU64xpV/8wShZ6bMTa7pF8eYsTrSkQA7oLUIJcs/wb8g4y2Oyq701BaGiO6n/ak5WXO1w==", + "deprecated": "Unmaintained. The codebase for this package was moved to https://github.com/cosmos/ics23 but then the JS implementation was removed in https://github.com/cosmos/ics23/pull/353. Please consult the maintainers of https://github.com/cosmos for further assistance.", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@noble/hashes": "^1.0.0", + "protobufjs": "^6.8.8" + } + }, + "node_modules/@confio/ics23/node_modules/protobufjs": { + "version": "6.11.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz", + "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, "node_modules/@coral-xyz/anchor": { "version": "0.31.1", "resolved": "https://registry.npmjs.org/@coral-xyz/anchor/-/anchor-0.31.1.tgz", @@ -82,6 +266,198 @@ "@solana/web3.js": "^1.69.0" } }, + "node_modules/@cosmjs/amino": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/@cosmjs/amino/-/amino-0.30.1.tgz", + "integrity": "sha512-yNHnzmvAlkETDYIpeCTdVqgvrdt1qgkOXwuRVi8s27UKI5hfqyE9fJ/fuunXE6ZZPnKkjIecDznmuUOMrMvw4w==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@cosmjs/crypto": "^0.30.1", + "@cosmjs/encoding": "^0.30.1", + "@cosmjs/math": "^0.30.1", + "@cosmjs/utils": "^0.30.1" + } + }, + "node_modules/@cosmjs/crypto": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/@cosmjs/crypto/-/crypto-0.30.1.tgz", + "integrity": "sha512-rAljUlake3MSXs9xAm87mu34GfBLN0h/1uPPV6jEwClWjNkAMotzjC0ab9MARy5FFAvYHL3lWb57bhkbt2GtzQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@cosmjs/encoding": "^0.30.1", + "@cosmjs/math": "^0.30.1", + "@cosmjs/utils": "^0.30.1", + "@noble/hashes": "^1", + "bn.js": "^5.2.0", + "elliptic": "^6.5.4", + "libsodium-wrappers": "^0.7.6" + } + }, + "node_modules/@cosmjs/encoding": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.30.1.tgz", + "integrity": "sha512-rXmrTbgqwihORwJ3xYhIgQFfMSrwLu1s43RIK9I8EBudPx3KmnmyAKzMOVsRDo9edLFNuZ9GIvysUCwQfq3WlQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "base64-js": "^1.3.0", + "bech32": "^1.1.4", + "readonly-date": "^1.0.0" + } + }, + "node_modules/@cosmjs/encoding/node_modules/bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", + "license": "MIT", + "optional": true + }, + "node_modules/@cosmjs/json-rpc": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/@cosmjs/json-rpc/-/json-rpc-0.30.1.tgz", + "integrity": "sha512-pitfC/2YN9t+kXZCbNuyrZ6M8abnCC2n62m+JtU9vQUfaEtVsgy+1Fk4TRQ175+pIWSdBMFi2wT8FWVEE4RhxQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@cosmjs/stream": "^0.30.1", + "xstream": "^11.14.0" + } + }, + "node_modules/@cosmjs/math": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.30.1.tgz", + "integrity": "sha512-yaoeI23pin9ZiPHIisa6qqLngfnBR/25tSaWpkTm8Cy10MX70UF5oN4+/t1heLaM6SSmRrhk3psRkV4+7mH51Q==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bn.js": "^5.2.0" + } + }, + "node_modules/@cosmjs/proto-signing": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/@cosmjs/proto-signing/-/proto-signing-0.30.1.tgz", + "integrity": "sha512-tXh8pPYXV4aiJVhTKHGyeZekjj+K9s2KKojMB93Gcob2DxUjfKapFYBMJSgfKPuWUPEmyr8Q9km2hplI38ILgQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@cosmjs/amino": "^0.30.1", + "@cosmjs/crypto": "^0.30.1", + "@cosmjs/encoding": "^0.30.1", + "@cosmjs/math": "^0.30.1", + "@cosmjs/utils": "^0.30.1", + "cosmjs-types": "^0.7.1", + "long": "^4.0.0" + } + }, + "node_modules/@cosmjs/socket": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/@cosmjs/socket/-/socket-0.30.1.tgz", + "integrity": "sha512-r6MpDL+9N+qOS/D5VaxnPaMJ3flwQ36G+vPvYJsXArj93BjgyFB7BwWwXCQDzZ+23cfChPUfhbINOenr8N2Kow==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@cosmjs/stream": "^0.30.1", + "isomorphic-ws": "^4.0.1", + "ws": "^7", + "xstream": "^11.14.0" + } + }, + "node_modules/@cosmjs/stargate": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/@cosmjs/stargate/-/stargate-0.30.1.tgz", + "integrity": "sha512-RdbYKZCGOH8gWebO7r6WvNnQMxHrNXInY/gPHPzMjbQF6UatA6fNM2G2tdgS5j5u7FTqlCI10stNXrknaNdzog==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@confio/ics23": "^0.6.8", + "@cosmjs/amino": "^0.30.1", + "@cosmjs/encoding": "^0.30.1", + "@cosmjs/math": "^0.30.1", + "@cosmjs/proto-signing": "^0.30.1", + "@cosmjs/stream": "^0.30.1", + "@cosmjs/tendermint-rpc": "^0.30.1", + "@cosmjs/utils": "^0.30.1", + "cosmjs-types": "^0.7.1", + "long": "^4.0.0", + "protobufjs": "~6.11.3", + "xstream": "^11.14.0" + } + }, + "node_modules/@cosmjs/stargate/node_modules/protobufjs": { + "version": "6.11.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz", + "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, + "node_modules/@cosmjs/stream": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/@cosmjs/stream/-/stream-0.30.1.tgz", + "integrity": "sha512-Fg0pWz1zXQdoxQZpdHRMGvUH5RqS6tPv+j9Eh7Q953UjMlrwZVo0YFLC8OTf/HKVf10E4i0u6aM8D69Q6cNkgQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "xstream": "^11.14.0" + } + }, + "node_modules/@cosmjs/tendermint-rpc": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.30.1.tgz", + "integrity": "sha512-Z3nCwhXSbPZJ++v85zHObeUggrEHVfm1u18ZRwXxFE9ZMl5mXTybnwYhczuYOl7KRskgwlB+rID0WYACxj4wdQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@cosmjs/crypto": "^0.30.1", + "@cosmjs/encoding": "^0.30.1", + "@cosmjs/json-rpc": "^0.30.1", + "@cosmjs/math": "^0.30.1", + "@cosmjs/socket": "^0.30.1", + "@cosmjs/stream": "^0.30.1", + "@cosmjs/utils": "^0.30.1", + "axios": "^0.21.2", + "readonly-date": "^1.0.0", + "xstream": "^11.14.0" + } + }, + "node_modules/@cosmjs/tendermint-rpc/node_modules/axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "license": "MIT", + "optional": true, + "dependencies": { + "follow-redirects": "^1.14.0" + } + }, + "node_modules/@cosmjs/utils": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.30.1.tgz", + "integrity": "sha512-KvvX58MGMWh7xA+N+deCfunkA/ZNDvFLw4YbOmX3f/XBIkqrVY7qlotfy2aNb1kgp6h4B6Yc8YawJPDTfvWX7g==", + "license": "Apache-2.0", + "optional": true + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.25.3", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.3.tgz", @@ -507,112 +883,1811 @@ "node": ">=18" } }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "license": "ISC", + "node_modules/@ethereumjs/common": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.5.tgz", + "integrity": "sha512-lRyVQOeCDaIVtgfbowla32pzeDv2Obr8oR8Put5RdUBNRGr1VGPGQNGP6elWIpgK3YdpzqTOh4GyUGOureVeeA==", + "license": "MIT", + "optional": true, "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" + "crc-32": "^1.2.0", + "ethereumjs-util": "^7.1.5" } }, - "node_modules/@noble/curves": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.0.tgz", - "integrity": "sha512-7YDlXiNMdO1YZeH6t/kvopHHbIZzlxrCV9WLqCY6QhcXOoXiNCMDqJIglZ9Yjx5+w7Dz30TITFrlTjnRg7sKEg==", - "license": "MIT", + "node_modules/@ethereumjs/tx": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.5.2.tgz", + "integrity": "sha512-gQDNJWKrSDGu2w7w0PzVXVBNMzb7wwdDOmOqczmhNjqFxFuIbhVJDwiGEnxFNC2/b8ifcZzY7MLcluizohRzNw==", + "license": "MPL-2.0", + "optional": true, "dependencies": { - "@noble/hashes": "1.8.0" - }, - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" + "@ethereumjs/common": "^2.6.4", + "ethereumjs-util": "^7.1.5" } }, - "node_modules/@noble/hashes": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "node_modules/@ethersproject/abi": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.8.0.tgz", + "integrity": "sha512-b9YS/43ObplgyV6SlyQsG53/vkSal0MNA1fskSC4mbnCMi8R+NkcH8K9FPYNESf6jUefBUniE4SOKms0E/KK1Q==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@noble/secp256k1": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-2.2.3.tgz", - "integrity": "sha512-l7r5oEQym9Us7EAigzg30/PQAvynhMt2uoYtT3t26eGDVm9Yii5mZ5jWSWmZ/oSIR2Et0xfc6DXrG0bZ787V3w==", + "optional": true, + "dependencies": { + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/hash": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/@ethersproject/abstract-provider": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.8.0.tgz", + "integrity": "sha512-wC9SFcmh4UK0oKuLJQItoQdzS/qZ51EJegK6EmAWlh+OptpQ/npECOR3QqECd8iGHC0RJb4WKbVdSfif4ammrg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], "license": "MIT", - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, + "optional": true, + "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" + } + }, + "node_modules/@ethersproject/abstract-signer": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.8.0.tgz", + "integrity": "sha512-N0XhZTswXcmIZQdYtUnd79VJzvEwXQw6PK0dTl9VoYrEBxxCPXqS0Eod7q5TNKRxe1/5WUMuR0u0nqTF/avdCA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], "license": "MIT", "optional": true, - "engines": { - "node": ">=14" + "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" } }, - "node_modules/@solana/buffer-layout": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.1.tgz", - "integrity": "sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==", + "node_modules/@ethersproject/address": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.8.0.tgz", + "integrity": "sha512-GhH/abcC46LJwshoN+uBNoKVFPxUuZm6dA257z0vZkKmU1+t8xTn8oK7B9qrj8W2rFRMch4gbJl6PmVxjxBEBA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], "license": "MIT", + "optional": true, "dependencies": { - "buffer": "~6.0.3" - }, - "engines": { - "node": ">=5.10" + "@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" } }, - "node_modules/@solana/codecs-core": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@solana/codecs-core/-/codecs-core-2.1.0.tgz", - "integrity": "sha512-SR7pKtmJBg2mhmkel2NeHA1pz06QeQXdMv8WJoIR9m8F/hw80K/612uaYbwTt2nkK0jg/Qn/rNSd7EcJ4SBGjw==", + "node_modules/@ethersproject/base64": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.8.0.tgz", + "integrity": "sha512-lN0oIwfkYj9LbPx4xEkie6rAMJtySbpOAFXSDVQaBnAzYfB4X2Qr+FXJGxMoc3Bxp2Sm8OwvzMrywxyw0gLjIQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], "license": "MIT", + "optional": true, "dependencies": { - "@solana/errors": "2.1.0" - }, - "engines": { - "node": ">=20.18.0" - }, - "peerDependencies": { - "typescript": ">=5" + "@ethersproject/bytes": "^5.8.0" } }, - "node_modules/@solana/codecs-numbers": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@solana/codecs-numbers/-/codecs-numbers-2.1.0.tgz", - "integrity": "sha512-XMu4yw5iCgQnMKsxSWPPOrGgtaohmupN3eyAtYv3K3C/MJEc5V90h74k5B1GUCiHvcrdUDO9RclNjD9lgbjFag==", + "node_modules/@ethersproject/basex": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.8.0.tgz", + "integrity": "sha512-PIgTszMlDRmNwW9nhS6iqtVfdTAKosA7llYXNmGPw4YAI1PUyMv28988wAb41/gHF/WqGdoLv0erHaRcHRKW2Q==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/properties": "^5.8.0" + } + }, + "node_modules/@ethersproject/bignumber": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.8.0.tgz", + "integrity": "sha512-ZyaT24bHaSeJon2tGPKIiHszWjD/54Sz8t57Toch475lCLljC6MgPmxk7Gtzz+ddNN5LuHea9qhAe0x3D+uYPA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "bn.js": "^5.2.1" + } + }, + "node_modules/@ethersproject/bytes": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.8.0.tgz", + "integrity": "sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/@ethersproject/constants": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.8.0.tgz", + "integrity": "sha512-wigX4lrf5Vu+axVTIvNsuL6YrV4O5AXl5ubcURKMEME5TnWBouUh0CDTWxZ2GpnRn1kcCgE7l8O5+VbV9QTTcg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bignumber": "^5.8.0" + } + }, + "node_modules/@ethersproject/contracts": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.8.0.tgz", + "integrity": "sha512-0eFjGz9GtuAi6MZwhb4uvUM216F38xiuR0yYCjKJpNfSEy4HUM8hvqqBj9Jmm0IUz8l0xKEhWwLIhPgxNY0yvQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/abi": "^5.8.0", + "@ethersproject/abstract-provider": "^5.8.0", + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/transactions": "^5.8.0" + } + }, + "node_modules/@ethersproject/hash": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.8.0.tgz", + "integrity": "sha512-ac/lBcTbEWW/VGJij0CNSw/wPcw9bSRgCB0AIBz8CvED/jfvDoV9hsIIiWfvWmFEi8RcXtlNwp2jv6ozWOsooA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "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" + } + }, + "node_modules/@ethersproject/hdnode": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.8.0.tgz", + "integrity": "sha512-4bK1VF6E83/3/Im0ERnnUeWOY3P1BZml4ZD3wcH8Ys0/d1h1xaFt6Zc+Dh9zXf9TapGro0T4wvO71UTCp3/uoA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/basex": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/pbkdf2": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/sha2": "^5.8.0", + "@ethersproject/signing-key": "^5.8.0", + "@ethersproject/strings": "^5.8.0", + "@ethersproject/transactions": "^5.8.0", + "@ethersproject/wordlists": "^5.8.0" + } + }, + "node_modules/@ethersproject/json-wallets": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.8.0.tgz", + "integrity": "sha512-HxblNck8FVUtNxS3VTEYJAcwiKYsBIF77W15HufqlBF9gGfhmYOJtYZp8fSDZtn9y5EaXTE87zDwzxRoTFk11w==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/address": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/hdnode": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/pbkdf2": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/random": "^5.8.0", + "@ethersproject/strings": "^5.8.0", + "@ethersproject/transactions": "^5.8.0", + "aes-js": "3.0.0", + "scrypt-js": "3.0.1" + } + }, + "node_modules/@ethersproject/keccak256": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.8.0.tgz", + "integrity": "sha512-A1pkKLZSz8pDaQ1ftutZoaN46I6+jvuqugx5KYNeQOPqq+JZ0Txm7dlWesCHB5cndJSu5vP2VKptKf7cksERng==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/@ethersproject/logger": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.8.0.tgz", + "integrity": "sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT" + }, + "node_modules/@ethersproject/networks": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.8.0.tgz", + "integrity": "sha512-egPJh3aPVAzbHwq8DD7Po53J4OUSsA1MjQp8Vf/OZPav5rlmWUaFLiq8cvQiGK0Z5K6LYzm29+VA/p4RL1FzNg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/@ethersproject/pbkdf2": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.8.0.tgz", + "integrity": "sha512-wuHiv97BrzCmfEaPbUFpMjlVg/IDkZThp9Ri88BpjRleg4iePJaj2SW8AIyE8cXn5V1tuAaMj6lzvsGJkGWskg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/sha2": "^5.8.0" + } + }, + "node_modules/@ethersproject/properties": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.8.0.tgz", + "integrity": "sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/@ethersproject/providers": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.8.0.tgz", + "integrity": "sha512-3Il3oTzEx3o6kzcg9ZzbE+oCZYyY+3Zh83sKkn4s1DZfTUjIegHnN2Cm0kbn9YFy45FDVcuCLLONhU7ny0SsCw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/abstract-provider": "^5.8.0", + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/address": "^5.8.0", + "@ethersproject/base64": "^5.8.0", + "@ethersproject/basex": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/hash": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/networks": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/random": "^5.8.0", + "@ethersproject/rlp": "^5.8.0", + "@ethersproject/sha2": "^5.8.0", + "@ethersproject/strings": "^5.8.0", + "@ethersproject/transactions": "^5.8.0", + "@ethersproject/web": "^5.8.0", + "bech32": "1.1.4", + "ws": "8.18.0" + } + }, + "node_modules/@ethersproject/providers/node_modules/bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", + "license": "MIT", + "optional": true + }, + "node_modules/@ethersproject/providers/node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/@ethersproject/random": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.8.0.tgz", + "integrity": "sha512-E4I5TDl7SVqyg4/kkA/qTfuLWAQGXmSOgYyO01So8hLfwgKvYK5snIlzxJMk72IFdG/7oh8yuSqY2KX7MMwg+A==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/@ethersproject/rlp": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.8.0.tgz", + "integrity": "sha512-LqZgAznqDbiEunaUvykH2JAoXTT9NV0Atqk8rQN9nx9SEgThA/WMx5DnW8a9FOufo//6FZOCHZ+XiClzgbqV9Q==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/@ethersproject/sha2": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.8.0.tgz", + "integrity": "sha512-dDOUrXr9wF/YFltgTBYS0tKslPEKr6AekjqDW2dbn1L1xmjGR+9GiKu4ajxovnrDbwxAKdHjW8jNcwfz8PAz4A==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/signing-key": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.8.0.tgz", + "integrity": "sha512-LrPW2ZxoigFi6U6aVkFN/fa9Yx/+4AtIUe4/HACTvKJdhm0eeb107EVCIQcrLZkxaSIgc/eCrX8Q1GtbH+9n3w==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "bn.js": "^5.2.1", + "elliptic": "6.6.1", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/solidity": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.8.0.tgz", + "integrity": "sha512-4CxFeCgmIWamOHwYN9d+QWGxye9qQLilpgTU0XhYs1OahkclF+ewO+3V1U0mvpiuQxm5EHHmv8f7ClVII8EHsA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/sha2": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/@ethersproject/strings": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.8.0.tgz", + "integrity": "sha512-qWEAk0MAvl0LszjdfnZ2uC8xbR2wdv4cDabyHiBh3Cldq/T8dPH3V4BbBsAYJUeonwD+8afVXld274Ls+Y1xXg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/@ethersproject/transactions": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.8.0.tgz", + "integrity": "sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "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" + } + }, + "node_modules/@ethersproject/units": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.8.0.tgz", + "integrity": "sha512-lxq0CAnc5kMGIiWW4Mr041VT8IhNM+Pn5T3haO74XZWFulk7wH1Gv64HqE96hT4a7iiNMdOCFEBgaxWuk8ETKQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/@ethersproject/wallet": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.8.0.tgz", + "integrity": "sha512-G+jnzmgg6UxurVKRKvw27h0kvG75YKXZKdlLYmAHeF32TGUzHkOFd7Zn6QHOTYRFWnfjtSSFjBowKo7vfrXzPA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/abstract-provider": "^5.8.0", + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/hash": "^5.8.0", + "@ethersproject/hdnode": "^5.8.0", + "@ethersproject/json-wallets": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/random": "^5.8.0", + "@ethersproject/signing-key": "^5.8.0", + "@ethersproject/transactions": "^5.8.0", + "@ethersproject/wordlists": "^5.8.0" + } + }, + "node_modules/@ethersproject/web": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.8.0.tgz", + "integrity": "sha512-j7+Ksi/9KfGviws6Qtf9Q7KCqRhpwrYKQPs+JBA/rKVFF/yaWLHJEH3zfVP2plVu+eys0d2DlFmhoQJayFewcw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "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" + } + }, + "node_modules/@ethersproject/wordlists": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.8.0.tgz", + "integrity": "sha512-2df9bbXicZws2Sb5S6ET493uJ0Z84Fjr3pC4tu/qlnZERibZCeUVuqdtt+7Tv9xxhUxHoIekIA7avrKUWHrezg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/hash": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/@graphql-typed-document-node/core": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz", + "integrity": "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==", + "license": "MIT", + "optional": true, + "peerDependencies": { + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@improbable-eng/grpc-web": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@improbable-eng/grpc-web/-/grpc-web-0.15.0.tgz", + "integrity": "sha512-ERft9/0/8CmYalqOVnJnpdDry28q+j+nAlFFARdjyxXDJ+Mhgv9+F600QC8BR9ygOfrXRlAk6CvST2j+JCpQPg==", + "license": "Apache-2.0", + "dependencies": { + "browser-headers": "^0.4.1" + }, + "peerDependencies": { + "google-protobuf": "^3.14.0" + } + }, + "node_modules/@injectivelabs/core-proto-ts": { + "version": "0.0.14", + "resolved": "https://registry.npmjs.org/@injectivelabs/core-proto-ts/-/core-proto-ts-0.0.14.tgz", + "integrity": "sha512-NZWlgBzgVrXow9IknFQHvcYKX4QkUD25taRigoNYQK8PDn4+VXd9xM5WFUDRhzm2smTCguyl/+MghpEp4oTPWw==", + "license": "MIT", + "optional": true, + "dependencies": { + "@injectivelabs/grpc-web": "^0.0.1", + "google-protobuf": "^3.14.0", + "protobufjs": "^7.0.0", + "rxjs": "^7.4.0" + } + }, + "node_modules/@injectivelabs/exceptions": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/@injectivelabs/exceptions/-/exceptions-1.15.1.tgz", + "integrity": "sha512-dUL6ks9G8I5VJYw7hXehf9OOYaN8bcB5/WCaseKfdzeBwe+yn/Dz/wXQ76NG+Rtknx85eqEkLZHX3LZMVU48cw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "http-status-codes": "^2.3.0" + } + }, + "node_modules/@injectivelabs/grpc-web": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@injectivelabs/grpc-web/-/grpc-web-0.0.1.tgz", + "integrity": "sha512-Pu5YgaZp+OvR5UWfqbrPdHer3+gDf+b5fQoY+t2VZx1IAVHX8bzbN9EreYTvTYtFeDpYRWM8P7app2u4EX5wTw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "browser-headers": "^0.4.1" + }, + "peerDependencies": { + "google-protobuf": "^3.14.0" + } + }, + "node_modules/@injectivelabs/grpc-web-node-http-transport": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@injectivelabs/grpc-web-node-http-transport/-/grpc-web-node-http-transport-0.0.2.tgz", + "integrity": "sha512-rpyhXLiGY/UMs6v6YmgWHJHiO9l0AgDyVNv+jcutNVt4tQrmNvnpvz2wCAGOFtq5LuX/E9ChtTVpk3gWGqXcGA==", + "license": "Apache-2.0", + "optional": true, + "peerDependencies": { + "@injectivelabs/grpc-web": ">=0.0.1" + } + }, + "node_modules/@injectivelabs/grpc-web-react-native-transport": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@injectivelabs/grpc-web-react-native-transport/-/grpc-web-react-native-transport-0.0.2.tgz", + "integrity": "sha512-mk+aukQXnYNgPsPnu3KBi+FD0ZHQpazIlaBZ2jNZG7QAVmxTWtv3R66Zoq99Wx2dnE946NsZBYAoa0K5oSjnow==", + "license": "Apache-2.0", + "optional": true, + "peerDependencies": { + "@injectivelabs/grpc-web": ">=0.0.1" + } + }, + "node_modules/@injectivelabs/indexer-proto-ts": { + "version": "1.10.8-rc.4", + "resolved": "https://registry.npmjs.org/@injectivelabs/indexer-proto-ts/-/indexer-proto-ts-1.10.8-rc.4.tgz", + "integrity": "sha512-IwbepTfsHHAv3Z36As6yH/+HIplOEpUu6SFHBCVgdSIaQ8GuvTib4HETiVnV4mjYqoyVgWs+zLSAfih46rdMJQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "@injectivelabs/grpc-web": "^0.0.1", + "google-protobuf": "^3.14.0", + "protobufjs": "^7.0.0", + "rxjs": "^7.4.0" + } + }, + "node_modules/@injectivelabs/mito-proto-ts": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@injectivelabs/mito-proto-ts/-/mito-proto-ts-1.0.9.tgz", + "integrity": "sha512-+TZMvJ4SHwcn6SFPdqaiQFZdNhjH7hyRFozY15nOTC2utdGij9jEsjz1NsyOejfYDA0s1z5Wm1SgrMYKaVpAmQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "@injectivelabs/grpc-web": "^0.0.1", + "google-protobuf": "^3.14.0", + "protobufjs": "^7.0.0", + "rxjs": "^7.4.0" + } + }, + "node_modules/@injectivelabs/networks": { + "version": "1.10.12", + "resolved": "https://registry.npmjs.org/@injectivelabs/networks/-/networks-1.10.12.tgz", + "integrity": "sha512-tTHyLls1Nik5QTs/S03qqG2y/ITvNwI8CJOQbMmmsr1CL2CdjJBtzRYn9Dyx2p8XgzRFf9hmlybpe20tq9O3SA==", + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@injectivelabs/exceptions": "^1.10.12", + "@injectivelabs/ts-types": "^1.10.12", + "@injectivelabs/utils": "^1.10.12", + "link-module-alias": "^1.2.0", + "shx": "^0.3.2" + } + }, + "node_modules/@injectivelabs/sdk-ts": { + "version": "1.10.72", + "resolved": "https://registry.npmjs.org/@injectivelabs/sdk-ts/-/sdk-ts-1.10.72.tgz", + "integrity": "sha512-A5mHNNBgO4fI1c/7CZ0bGfVXliy8laP+VaYZ++aWh1YyudoZw4CTCEmLetZRy7AUU3XcfbHa8sAImRi7db+v6Q==", + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@apollo/client": "^3.5.8", + "@cosmjs/amino": "^0.30.1", + "@cosmjs/proto-signing": "^0.30.1", + "@cosmjs/stargate": "^0.30.1", + "@ethersproject/bytes": "^5.7.0", + "@injectivelabs/core-proto-ts": "^0.0.14", + "@injectivelabs/exceptions": "^1.10.12", + "@injectivelabs/grpc-web": "^0.0.1", + "@injectivelabs/grpc-web-node-http-transport": "^0.0.2", + "@injectivelabs/grpc-web-react-native-transport": "^0.0.2", + "@injectivelabs/indexer-proto-ts": "1.10.8-rc.4", + "@injectivelabs/mito-proto-ts": "1.0.9", + "@injectivelabs/networks": "^1.10.12", + "@injectivelabs/test-utils": "^1.10.12", + "@injectivelabs/token-metadata": "^1.10.42", + "@injectivelabs/ts-types": "^1.10.12", + "@injectivelabs/utils": "^1.10.12", + "@metamask/eth-sig-util": "^4.0.0", + "axios": "^0.27.2", + "bech32": "^2.0.0", + "bip39": "^3.0.4", + "cosmjs-types": "^0.7.1", + "eth-crypto": "^2.6.0", + "ethereumjs-util": "^7.1.4", + "ethers": "^5.7.2", + "google-protobuf": "^3.21.0", + "graphql": "^16.3.0", + "http-status-codes": "^2.2.0", + "js-sha3": "^0.8.0", + "jscrypto": "^1.0.3", + "keccak256": "^1.0.6", + "link-module-alias": "^1.2.0", + "rxjs": "^7.8.0", + "secp256k1": "^4.0.3", + "shx": "^0.3.2", + "snakecase-keys": "^5.4.1" + } + }, + "node_modules/@injectivelabs/sdk-ts/node_modules/@apollo/client": { + "version": "3.13.8", + "resolved": "https://registry.npmjs.org/@apollo/client/-/client-3.13.8.tgz", + "integrity": "sha512-YM9lQpm0VfVco4DSyKooHS/fDTiKQcCHfxr7i3iL6a0kP/jNO5+4NFK6vtRDxaYisd5BrwOZHLJpPBnvRVpKPg==", + "license": "MIT", + "optional": true, + "dependencies": { + "@graphql-typed-document-node/core": "^3.1.1", + "@wry/caches": "^1.0.0", + "@wry/equality": "^0.5.6", + "@wry/trie": "^0.5.0", + "graphql-tag": "^2.12.6", + "hoist-non-react-statics": "^3.3.2", + "optimism": "^0.18.0", + "prop-types": "^15.7.2", + "rehackt": "^0.1.0", + "symbol-observable": "^4.0.0", + "ts-invariant": "^0.10.3", + "tslib": "^2.3.0", + "zen-observable-ts": "^1.2.5" + }, + "peerDependencies": { + "graphql": "^15.0.0 || ^16.0.0", + "graphql-ws": "^5.5.5 || ^6.0.3", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc", + "subscriptions-transport-ws": "^0.9.0 || ^0.11.0" + }, + "peerDependenciesMeta": { + "graphql-ws": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "subscriptions-transport-ws": { + "optional": true + } + } + }, + "node_modules/@injectivelabs/sdk-ts/node_modules/axios": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + } + }, + "node_modules/@injectivelabs/sdk-ts/node_modules/symbol-observable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", + "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/@injectivelabs/test-utils": { + "version": "1.14.41", + "resolved": "https://registry.npmjs.org/@injectivelabs/test-utils/-/test-utils-1.14.41.tgz", + "integrity": "sha512-++xeSobV62Yd67cIK6xCepZIU+YxQx/I9I5UT1pMOfostiCxQusKWsJhAKNjwkWbKNvFZifEw6TWwU3UYhneBQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@injectivelabs/exceptions": "^1.14.41", + "@injectivelabs/networks": "^1.14.41", + "@injectivelabs/ts-types": "^1.14.41", + "@injectivelabs/utils": "^1.14.41", + "axios": "^1.6.4", + "bignumber.js": "^9.0.1", + "shx": "^0.3.2", + "snakecase-keys": "^5.1.2", + "store2": "^2.12.0" + } + }, + "node_modules/@injectivelabs/test-utils/node_modules/@injectivelabs/networks": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/@injectivelabs/networks/-/networks-1.15.2.tgz", + "integrity": "sha512-b1fvxzUdgrvw2aFgWjf7tIMDnqhIImmAMnkLBdOP1f4/eZKEk3NgoBJxdoixhGWW/v9XFfR66X5PVB0mNz85TA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@injectivelabs/ts-types": "^1.15.2" + } + }, + "node_modules/@injectivelabs/test-utils/node_modules/@injectivelabs/utils": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/@injectivelabs/utils/-/utils-1.15.2.tgz", + "integrity": "sha512-Fs1FuNhkTijrzUEDjBH6N3xuqdOaAWob/l+6IonUuGFcmLdmiFFFgUnepnkKgn2vgQDlqu2vc+JpfWSE4BSNoQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@bangjelkoski/store2": "^2.14.3", + "@injectivelabs/exceptions": "^1.15.1", + "@injectivelabs/networks": "^1.15.2", + "@injectivelabs/ts-types": "^1.15.2", + "axios": "^1.8.1", + "bignumber.js": "^9.1.2", + "http-status-codes": "^2.3.0" + } + }, + "node_modules/@injectivelabs/test-utils/node_modules/axios": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz", + "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==", + "license": "MIT", + "optional": true, + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/@injectivelabs/token-metadata": { + "version": "1.14.11", + "resolved": "https://registry.npmjs.org/@injectivelabs/token-metadata/-/token-metadata-1.14.11.tgz", + "integrity": "sha512-WKJlvjKiTRHxpOeez4kYrzIwgWmpspD1IMxWclkTysAcwGltUfUsvUhu1cKuACleIjFFWmiZv/HoGRFdvEAZ8w==", + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@injectivelabs/exceptions": "^1.14.11", + "@injectivelabs/networks": "^1.14.11", + "@injectivelabs/ts-types": "^1.14.11", + "@injectivelabs/utils": "^1.14.11", + "@types/lodash.values": "^4.3.6", + "copyfiles": "^2.4.1", + "jsonschema": "^1.4.0", + "link-module-alias": "^1.2.0", + "lodash": "^4.17.21", + "lodash.values": "^4.3.0", + "shx": "^0.3.2" + } + }, + "node_modules/@injectivelabs/token-metadata/node_modules/@injectivelabs/networks": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/@injectivelabs/networks/-/networks-1.15.2.tgz", + "integrity": "sha512-b1fvxzUdgrvw2aFgWjf7tIMDnqhIImmAMnkLBdOP1f4/eZKEk3NgoBJxdoixhGWW/v9XFfR66X5PVB0mNz85TA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@injectivelabs/ts-types": "^1.15.2" + } + }, + "node_modules/@injectivelabs/token-metadata/node_modules/@injectivelabs/utils": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/@injectivelabs/utils/-/utils-1.15.2.tgz", + "integrity": "sha512-Fs1FuNhkTijrzUEDjBH6N3xuqdOaAWob/l+6IonUuGFcmLdmiFFFgUnepnkKgn2vgQDlqu2vc+JpfWSE4BSNoQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@bangjelkoski/store2": "^2.14.3", + "@injectivelabs/exceptions": "^1.15.1", + "@injectivelabs/networks": "^1.15.2", + "@injectivelabs/ts-types": "^1.15.2", + "axios": "^1.8.1", + "bignumber.js": "^9.1.2", + "http-status-codes": "^2.3.0" + } + }, + "node_modules/@injectivelabs/token-metadata/node_modules/axios": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz", + "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==", + "license": "MIT", + "optional": true, + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/@injectivelabs/ts-types": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/@injectivelabs/ts-types/-/ts-types-1.15.2.tgz", + "integrity": "sha512-NE0yYKP/HIP1+V1gDH6ooAf/kq5UpY14BXHb1a4DOljudSv0znj5WSqeDLPcSoUkzdycrCj+MuxtDBAogi55nw==", + "license": "Apache-2.0", + "optional": true + }, + "node_modules/@injectivelabs/utils": { + "version": "1.10.12", + "resolved": "https://registry.npmjs.org/@injectivelabs/utils/-/utils-1.10.12.tgz", + "integrity": "sha512-c8al79nxIJgV1cBAdW2TPDGldj/8gm5k0h5TIN/AJs8/AeIjpTwwVGfLY3QvPOpRsxuQ9CjBkTXrAcSL1wwkcw==", + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@injectivelabs/exceptions": "^1.10.12", + "@injectivelabs/ts-types": "^1.10.12", + "axios": "^0.21.1", + "bignumber.js": "^9.0.1", + "http-status-codes": "^2.2.0", + "link-module-alias": "^1.2.0", + "shx": "^0.3.2", + "snakecase-keys": "^5.1.2", + "store2": "^2.12.0" + } + }, + "node_modules/@injectivelabs/utils/node_modules/axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "license": "MIT", + "optional": true, + "dependencies": { + "follow-redirects": "^1.14.0" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@metamask/eth-sig-util": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", + "integrity": "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==", + "license": "ISC", + "optional": true, + "dependencies": { + "ethereumjs-abi": "^0.6.8", + "ethereumjs-util": "^6.2.1", + "ethjs-util": "^0.1.6", + "tweetnacl": "^1.0.3", + "tweetnacl-util": "^0.15.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@metamask/eth-sig-util/node_modules/@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@metamask/eth-sig-util/node_modules/bn.js": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", + "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "license": "MIT", + "optional": true + }, + "node_modules/@metamask/eth-sig-util/node_modules/ethereumjs-util": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", + "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", + "license": "MPL-2.0", + "optional": true, + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/@mysten/bcs": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@mysten/bcs/-/bcs-0.7.1.tgz", + "integrity": "sha512-wFPb8bkhwrbiStfZMV5rFM7J+umpke59/dNjDp+UYJKykNlW23LCk2ePyEUvGdb62HGJM1jyOJ8g4egE3OmdKA==", + "license": "Apache-2.0", + "dependencies": { + "bs58": "^5.0.0" + } + }, + "node_modules/@mysten/bcs/node_modules/base-x": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.1.tgz", + "integrity": "sha512-uAZ8x6r6S3aUM9rbHGVOIsR15U/ZSc82b3ymnCPsT45Gk1DDvhDPdIgB5MrhirZWt+5K0EEPQH985kNqZgNPFw==", + "license": "MIT" + }, + "node_modules/@mysten/bcs/node_modules/bs58": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz", + "integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==", + "license": "MIT", + "dependencies": { + "base-x": "^4.0.0" + } + }, + "node_modules/@mysten/sui.js": { + "version": "0.32.2", + "resolved": "https://registry.npmjs.org/@mysten/sui.js/-/sui.js-0.32.2.tgz", + "integrity": "sha512-/Hm4xkGolJhqj8FvQr7QSHDTlxIvL52mtbOao9f75YjrBh7y1Uh9kbJSY7xiTF1NY9sv6p5hUVlYRJuM0Hvn9A==", + "deprecated": "This package has been renamed to @mysten/sui, please update to use the renamed package.", + "license": "Apache-2.0", + "dependencies": { + "@mysten/bcs": "0.7.1", + "@noble/curves": "^1.0.0", + "@noble/hashes": "^1.3.0", + "@scure/bip32": "^1.3.0", + "@scure/bip39": "^1.2.0", + "@suchipi/femver": "^1.0.0", + "jayson": "^4.0.0", + "rpc-websockets": "^7.5.1", + "superstruct": "^1.0.3", + "tweetnacl": "^1.0.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@mysten/sui.js/node_modules/rpc-websockets": { + "version": "7.11.2", + "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.11.2.tgz", + "integrity": "sha512-pL9r5N6AVHlMN/vT98+fcO+5+/UcPLf/4tq+WUaid/PPUGS/ttJ3y8e9IqmaWKtShNAysMSjkczuEA49NuV7UQ==", + "license": "LGPL-3.0-only", + "dependencies": { + "eventemitter3": "^4.0.7", + "uuid": "^8.3.2", + "ws": "^8.5.0" + }, + "funding": { + "type": "paypal", + "url": "https://paypal.me/kozjak" + }, + "optionalDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + } + }, + "node_modules/@mysten/sui.js/node_modules/superstruct": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-1.0.4.tgz", + "integrity": "sha512-7JpaAoX2NGyoFlI9NBh66BQXGONc+uE+MRS5i2iOBKuS4e+ccgMDjATgZldkah+33DakBxDHiss9kvUcGAO8UQ==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@mysten/sui.js/node_modules/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/@noble/curves": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.0.tgz", + "integrity": "sha512-7YDlXiNMdO1YZeH6t/kvopHHbIZzlxrCV9WLqCY6QhcXOoXiNCMDqJIglZ9Yjx5+w7Dz30TITFrlTjnRg7sKEg==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.8.0" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/secp256k1": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-2.2.3.tgz", + "integrity": "sha512-l7r5oEQym9Us7EAigzg30/PQAvynhMt2uoYtT3t26eGDVm9Yii5mZ5jWSWmZ/oSIR2Et0xfc6DXrG0bZ787V3w==", + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@project-serum/anchor": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@project-serum/anchor/-/anchor-0.25.0.tgz", + "integrity": "sha512-E6A5Y/ijqpfMJ5psJvbw0kVTzLZFUcOFgs6eSM2M2iWE1lVRF18T6hWZVNl6zqZsoz98jgnNHtVGJMs+ds9A7A==", + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "@project-serum/borsh": "^0.2.5", + "@solana/web3.js": "^1.36.0", + "base64-js": "^1.5.1", + "bn.js": "^5.1.2", + "bs58": "^4.0.1", + "buffer-layout": "^1.2.2", + "camelcase": "^5.3.1", + "cross-fetch": "^3.1.5", + "crypto-hash": "^1.3.0", + "eventemitter3": "^4.0.7", + "js-sha256": "^0.9.0", + "pako": "^2.0.3", + "snake-case": "^3.0.4", + "superstruct": "^0.15.4", + "toml": "^3.0.0" + }, + "engines": { + "node": ">=11" + } + }, + "node_modules/@project-serum/anchor/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/@project-serum/borsh": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@project-serum/borsh/-/borsh-0.2.5.tgz", + "integrity": "sha512-UmeUkUoKdQ7rhx6Leve1SssMR/Ghv8qrEiyywyxSWg7ooV7StdpPBhciiy5eB3T0qU1BXvdRNC8TdrkxK7WC5Q==", + "license": "Apache-2.0", + "dependencies": { + "bn.js": "^5.1.2", + "buffer-layout": "^1.2.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@solana/web3.js": "^1.2.0" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause" + }, + "node_modules/@scure/base": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.5.tgz", + "integrity": "sha512-9rE6EOVeIQzt5TSu4v+K523F8u6DhBsoZWPGKlnCshhlDhy0kJzUX4V+tr2dWmzF1GdekvThABoEQBGBQI7xZw==", + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.7.0.tgz", + "integrity": "sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==", + "license": "MIT", + "dependencies": { + "@noble/curves": "~1.9.0", + "@noble/hashes": "~1.8.0", + "@scure/base": "~1.2.5" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip39": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.6.0.tgz", + "integrity": "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "~1.8.0", + "@scure/base": "~1.2.5" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@solana/buffer-layout": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.1.tgz", + "integrity": "sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==", + "license": "MIT", + "dependencies": { + "buffer": "~6.0.3" + }, + "engines": { + "node": ">=5.10" + } + }, + "node_modules/@solana/buffer-layout-utils": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@solana/buffer-layout-utils/-/buffer-layout-utils-0.2.0.tgz", + "integrity": "sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==", + "license": "Apache-2.0", + "dependencies": { + "@solana/buffer-layout": "^4.0.0", + "@solana/web3.js": "^1.32.0", + "bigint-buffer": "^1.1.5", + "bignumber.js": "^9.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@solana/codecs": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/codecs/-/codecs-2.0.0-rc.1.tgz", + "integrity": "sha512-qxoR7VybNJixV51L0G1RD2boZTcxmwUWnKCaJJExQ5qNKwbpSyDdWfFJfM5JhGyKe9DnPVOZB+JHWXnpbZBqrQ==", + "license": "MIT", + "dependencies": { + "@solana/codecs-core": "2.0.0-rc.1", + "@solana/codecs-data-structures": "2.0.0-rc.1", + "@solana/codecs-numbers": "2.0.0-rc.1", + "@solana/codecs-strings": "2.0.0-rc.1", + "@solana/options": "2.0.0-rc.1" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/codecs-core": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@solana/codecs-core/-/codecs-core-2.1.0.tgz", + "integrity": "sha512-SR7pKtmJBg2mhmkel2NeHA1pz06QeQXdMv8WJoIR9m8F/hw80K/612uaYbwTt2nkK0jg/Qn/rNSd7EcJ4SBGjw==", + "license": "MIT", + "dependencies": { + "@solana/errors": "2.1.0" + }, + "engines": { + "node": ">=20.18.0" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/codecs-data-structures": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/codecs-data-structures/-/codecs-data-structures-2.0.0-rc.1.tgz", + "integrity": "sha512-rinCv0RrAVJ9rE/rmaibWJQxMwC5lSaORSZuwjopSUE6T0nb/MVg6Z1siNCXhh/HFTOg0l8bNvZHgBcN/yvXog==", + "license": "MIT", + "dependencies": { + "@solana/codecs-core": "2.0.0-rc.1", + "@solana/codecs-numbers": "2.0.0-rc.1", + "@solana/errors": "2.0.0-rc.1" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/codecs-data-structures/node_modules/@solana/codecs-core": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/codecs-core/-/codecs-core-2.0.0-rc.1.tgz", + "integrity": "sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ==", + "license": "MIT", + "dependencies": { + "@solana/errors": "2.0.0-rc.1" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/codecs-data-structures/node_modules/@solana/codecs-numbers": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/codecs-numbers/-/codecs-numbers-2.0.0-rc.1.tgz", + "integrity": "sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ==", + "license": "MIT", + "dependencies": { + "@solana/codecs-core": "2.0.0-rc.1", + "@solana/errors": "2.0.0-rc.1" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/codecs-data-structures/node_modules/@solana/errors": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/errors/-/errors-2.0.0-rc.1.tgz", + "integrity": "sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ==", + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "commander": "^12.1.0" + }, + "bin": { + "errors": "bin/cli.mjs" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/codecs-data-structures/node_modules/chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@solana/codecs-data-structures/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@solana/codecs-numbers": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@solana/codecs-numbers/-/codecs-numbers-2.1.0.tgz", + "integrity": "sha512-XMu4yw5iCgQnMKsxSWPPOrGgtaohmupN3eyAtYv3K3C/MJEc5V90h74k5B1GUCiHvcrdUDO9RclNjD9lgbjFag==", + "license": "MIT", + "dependencies": { + "@solana/codecs-core": "2.1.0", + "@solana/errors": "2.1.0" + }, + "engines": { + "node": ">=20.18.0" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/codecs-strings": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/codecs-strings/-/codecs-strings-2.0.0-rc.1.tgz", + "integrity": "sha512-9/wPhw8TbGRTt6mHC4Zz1RqOnuPTqq1Nb4EyuvpZ39GW6O2t2Q7Q0XxiB3+BdoEjwA2XgPw6e2iRfvYgqty44g==", + "license": "MIT", + "dependencies": { + "@solana/codecs-core": "2.0.0-rc.1", + "@solana/codecs-numbers": "2.0.0-rc.1", + "@solana/errors": "2.0.0-rc.1" + }, + "peerDependencies": { + "fastestsmallesttextencoderdecoder": "^1.0.22", + "typescript": ">=5" + } + }, + "node_modules/@solana/codecs-strings/node_modules/@solana/codecs-core": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/codecs-core/-/codecs-core-2.0.0-rc.1.tgz", + "integrity": "sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ==", + "license": "MIT", + "dependencies": { + "@solana/errors": "2.0.0-rc.1" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/codecs-strings/node_modules/@solana/codecs-numbers": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/codecs-numbers/-/codecs-numbers-2.0.0-rc.1.tgz", + "integrity": "sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ==", + "license": "MIT", + "dependencies": { + "@solana/codecs-core": "2.0.0-rc.1", + "@solana/errors": "2.0.0-rc.1" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/codecs-strings/node_modules/@solana/errors": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/errors/-/errors-2.0.0-rc.1.tgz", + "integrity": "sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ==", + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "commander": "^12.1.0" + }, + "bin": { + "errors": "bin/cli.mjs" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/codecs-strings/node_modules/chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@solana/codecs-strings/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@solana/codecs/node_modules/@solana/codecs-core": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/codecs-core/-/codecs-core-2.0.0-rc.1.tgz", + "integrity": "sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ==", + "license": "MIT", + "dependencies": { + "@solana/errors": "2.0.0-rc.1" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/codecs/node_modules/@solana/codecs-numbers": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/codecs-numbers/-/codecs-numbers-2.0.0-rc.1.tgz", + "integrity": "sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ==", + "license": "MIT", + "dependencies": { + "@solana/codecs-core": "2.0.0-rc.1", + "@solana/errors": "2.0.0-rc.1" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/codecs/node_modules/@solana/errors": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/errors/-/errors-2.0.0-rc.1.tgz", + "integrity": "sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ==", + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "commander": "^12.1.0" + }, + "bin": { + "errors": "bin/cli.mjs" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/codecs/node_modules/chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", "license": "MIT", - "dependencies": { - "@solana/codecs-core": "2.1.0", - "@solana/errors": "2.1.0" - }, "engines": { - "node": ">=20.18.0" + "node": "^12.17.0 || ^14.13 || >=16.0.0" }, - "peerDependencies": { - "typescript": ">=5" + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@solana/codecs/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "license": "MIT", + "engines": { + "node": ">=18" } }, "node_modules/@solana/errors": { @@ -646,6 +2721,117 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/@solana/options": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/options/-/options-2.0.0-rc.1.tgz", + "integrity": "sha512-mLUcR9mZ3qfHlmMnREdIFPf9dpMc/Bl66tLSOOWxw4ml5xMT2ohFn7WGqoKcu/UHkT9CrC6+amEdqCNvUqI7AA==", + "license": "MIT", + "dependencies": { + "@solana/codecs-core": "2.0.0-rc.1", + "@solana/codecs-data-structures": "2.0.0-rc.1", + "@solana/codecs-numbers": "2.0.0-rc.1", + "@solana/codecs-strings": "2.0.0-rc.1", + "@solana/errors": "2.0.0-rc.1" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/options/node_modules/@solana/codecs-core": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/codecs-core/-/codecs-core-2.0.0-rc.1.tgz", + "integrity": "sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ==", + "license": "MIT", + "dependencies": { + "@solana/errors": "2.0.0-rc.1" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/options/node_modules/@solana/codecs-numbers": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/codecs-numbers/-/codecs-numbers-2.0.0-rc.1.tgz", + "integrity": "sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ==", + "license": "MIT", + "dependencies": { + "@solana/codecs-core": "2.0.0-rc.1", + "@solana/errors": "2.0.0-rc.1" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/options/node_modules/@solana/errors": { + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@solana/errors/-/errors-2.0.0-rc.1.tgz", + "integrity": "sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ==", + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "commander": "^12.1.0" + }, + "bin": { + "errors": "bin/cli.mjs" + }, + "peerDependencies": { + "typescript": ">=5" + } + }, + "node_modules/@solana/options/node_modules/chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@solana/options/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@solana/spl-token": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.3.11.tgz", + "integrity": "sha512-bvohO3rIMSVL24Pb+I4EYTJ6cL82eFpInEXD/I8K8upOGjpqHsKUoAempR/RnUlI1qSFNyFlWJfu6MNUgfbCQQ==", + "license": "Apache-2.0", + "dependencies": { + "@solana/buffer-layout": "^4.0.0", + "@solana/buffer-layout-utils": "^0.2.0", + "@solana/spl-token-metadata": "^0.1.2", + "buffer": "^6.0.3" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "@solana/web3.js": "^1.88.0" + } + }, + "node_modules/@solana/spl-token-metadata": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@solana/spl-token-metadata/-/spl-token-metadata-0.1.6.tgz", + "integrity": "sha512-7sMt1rsm/zQOQcUWllQX9mD2O6KhSAtY1hFR2hfFwgqfFWzSY9E9GDvFVNYUI1F0iQKcm6HmePU9QbKRXTEBiA==", + "license": "Apache-2.0", + "dependencies": { + "@solana/codecs": "2.0.0-rc.1" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "@solana/web3.js": "^1.95.3" + } + }, "node_modules/@solana/web3.js": { "version": "1.98.1", "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.98.1.tgz", @@ -678,6 +2864,12 @@ "node": ">=14.0.0" } }, + "node_modules/@suchipi/femver": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@suchipi/femver/-/femver-1.0.0.tgz", + "integrity": "sha512-bprE8+K5V+DPX7q2e2K57ImqNBdfGHDIWaGI5xHxZoxbKOuQZn4wzPiUxOAHnsUr3w3xHrWXwN7gnG/iIuEMIg==", + "license": "MIT" + }, "node_modules/@swc/helpers": { "version": "0.5.17", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz", @@ -687,11 +2879,133 @@ "tslib": "^2.8.0" } }, + "node_modules/@terra-money/legacy.proto": { + "name": "@terra-money/terra.proto", + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@terra-money/terra.proto/-/terra.proto-0.1.7.tgz", + "integrity": "sha512-NXD7f6pQCulvo6+mv6MAPzhOkUzRjgYVuHZE/apih+lVnPG5hDBU0rRYnOGGofwvKT5/jQoOENnFn/gioWWnyQ==", + "license": "Apache-2.0", + "dependencies": { + "google-protobuf": "^3.17.3", + "long": "^4.0.0", + "protobufjs": "~6.11.2" + } + }, + "node_modules/@terra-money/legacy.proto/node_modules/protobufjs": { + "version": "6.11.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz", + "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, + "node_modules/@terra-money/terra.js": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@terra-money/terra.js/-/terra.js-3.1.9.tgz", + "integrity": "sha512-JulSvOHLM56fL7s+cIjIbZeWPBluq883X1soWxA4TG5rKkDythT/DHeLXr3jP5Ld/26VENPSg6lNvK7cEYKpiw==", + "license": "MIT", + "dependencies": { + "@classic-terra/terra.proto": "^1.1.0", + "@terra-money/terra.proto": "^2.1.0", + "axios": "^0.27.2", + "bech32": "^2.0.0", + "bip32": "^2.0.6", + "bip39": "^3.0.3", + "bufferutil": "^4.0.3", + "decimal.js": "^10.2.1", + "jscrypto": "^1.0.1", + "readable-stream": "^3.6.0", + "secp256k1": "^4.0.2", + "tmp": "^0.2.1", + "utf-8-validate": "^5.0.5", + "ws": "^7.5.9" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@terra-money/terra.js/node_modules/axios": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + } + }, + "node_modules/@terra-money/terra.proto": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@terra-money/terra.proto/-/terra.proto-2.1.0.tgz", + "integrity": "sha512-rhaMslv3Rkr+QsTQEZs64FKA4QlfO0DfQHaR6yct/EovenMkibDEQ63dEL6yJA6LCaEQGYhyVB9JO9pTUA8ybw==", + "license": "Apache-2.0", + "dependencies": { + "@improbable-eng/grpc-web": "^0.14.1", + "google-protobuf": "^3.17.3", + "long": "^4.0.0", + "protobufjs": "~6.11.2" + } + }, + "node_modules/@terra-money/terra.proto/node_modules/@improbable-eng/grpc-web": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@improbable-eng/grpc-web/-/grpc-web-0.14.1.tgz", + "integrity": "sha512-XaIYuunepPxoiGVLLHmlnVminUGzBTnXr8Wv7khzmLWbNw4TCwJKX09GSMJlKhu/TRk6gms0ySFxewaETSBqgw==", + "license": "Apache-2.0", + "dependencies": { + "browser-headers": "^0.4.1" + }, + "peerDependencies": { + "google-protobuf": "^3.14.0" + } + }, + "node_modules/@terra-money/terra.proto/node_modules/protobufjs": { + "version": "6.11.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz", + "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, "node_modules/@types/bn.js": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.6.tgz", "integrity": "sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w==", - "dev": true, "license": "MIT", "dependencies": { "@types/node": "*" @@ -704,6 +3018,16 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/chai-as-promised": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-8.0.2.tgz", + "integrity": "sha512-meQ1wDr1K5KRCSvG2lX7n7/5wf70BeptTKst0axGvnN6zqaVpRqegoIbugiAPSqOW9K9aL8gDVrm7a2LXOtn2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "*" + } + }, "node_modules/@types/connect": { "version": "3.4.38", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", @@ -713,6 +3037,29 @@ "@types/node": "*" } }, + "node_modules/@types/lodash": { + "version": "4.17.16", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.16.tgz", + "integrity": "sha512-HX7Em5NYQAXKW+1T+FiuG27NGwzJfCX3s1GjOa7ujxZa52kjJLOr4FUxT+giF6Tgxv1e+/czV/iTtBw27WTU9g==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/lodash.values": { + "version": "4.3.9", + "resolved": "https://registry.npmjs.org/@types/lodash.values/-/lodash.values-4.3.9.tgz", + "integrity": "sha512-IJ20OEfqNwm3k8ENwoM3q0yOs4UMpgtD4GqxB4lwBHToGthHWqhyh5DdSgQjioocz0QK2SSBkJfCq95ZTV8BTw==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", + "license": "MIT" + }, "node_modules/@types/mocha": { "version": "10.0.10", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz", @@ -729,6 +3076,24 @@ "undici-types": "~6.20.0" } }, + "node_modules/@types/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/secp256k1": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.6.tgz", + "integrity": "sha512-hHxJU6PAEUn0TP4S/ZOzuTUvJWuZ6eIKeNKb5RBpODvSl6hp1Wrw4s7ATY50rklRCScUDpHzVA/DQdSjJ3UoYQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/uuid": { "version": "8.3.4", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", @@ -744,6 +3109,118 @@ "@types/node": "*" } }, + "node_modules/@wry/caches": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@wry/caches/-/caches-1.0.1.tgz", + "integrity": "sha512-bXuaUNLVVkD20wcGBWRyo7j9N3TxePEWFZj2Y+r9OoUzfqmavM84+mFykRicNsBqatba5JLay1t48wxaXaWnlA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wry/context": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.7.4.tgz", + "integrity": "sha512-jmT7Sb4ZQWI5iyu3lobQxICu2nC/vbUhP0vIdd6tHC9PTfenmRmuIFqktc6GH9cgi+ZHnsLWPvfSvc4DrYmKiQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wry/equality": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.5.7.tgz", + "integrity": "sha512-BRFORjsTuQv5gxcXsuDXx6oGRhuVsEGwZy6LOzRRfgu+eSfxbhUQ9L9YtSEIuIjY/o7g3iWFjrc5eSY1GXP2Dw==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wry/trie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wry/trie/-/trie-0.5.0.tgz", + "integrity": "sha512-FNoYzHawTMk/6KMQoEG5O4PuioX19UbwdQKF44yw0nLfOypfQdjtfZzo/UIJWAJ23sNIFbD1Ug9lbaDGMwbqQA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@xpla/xpla.js": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@xpla/xpla.js/-/xpla.js-0.2.3.tgz", + "integrity": "sha512-Tfk7hCGWXtwr08reY3Pi6dmzIqFbzri9jcyzJdfNmdo4cN0PMwpRJuZZcPmtxiIUnNef3AN1E/6nJUD5MKniuA==", + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/keccak256": "^5.6.1", + "@ethersproject/signing-key": "^5.6.2", + "@terra-money/legacy.proto": "npm:@terra-money/terra.proto@^0.1.7", + "@terra-money/terra.proto": "^2.1.0", + "axios": "^0.26.1", + "bech32": "^2.0.0", + "bip32": "^2.0.6", + "bip39": "^3.0.3", + "bufferutil": "^4.0.3", + "crypto-addr-codec": "^0.1.7", + "decimal.js": "^10.2.1", + "elliptic": "^6.5.4", + "ethereumjs-util": "^7.1.5", + "jscrypto": "^1.0.1", + "readable-stream": "^3.6.0", + "secp256k1": "^4.0.2", + "tmp": "^0.2.1", + "utf-8-validate": "^5.0.5", + "ws": "^7.5.8" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@xpla/xpla.js/node_modules/axios": { + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.14.8" + } + }, + "node_modules/acorn": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", + "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", + "license": "MIT", + "optional": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/aes-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", + "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", + "license": "MIT", + "optional": true + }, "node_modules/agentkeepalive": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz", @@ -756,6 +3233,35 @@ "node": ">= 8.0.0" } }, + "node_modules/algo-msgpack-with-bigint": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/algo-msgpack-with-bigint/-/algo-msgpack-with-bigint-2.1.1.tgz", + "integrity": "sha512-F1tGh056XczEaEAqu7s+hlZUDWwOBT70Eq0lfMpBP2YguSQVyxRbprLq5rELXKQOyOaixTWYhMeMQMzP0U5FoQ==", + "license": "ISC", + "engines": { + "node": ">= 10" + } + }, + "node_modules/algosdk": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/algosdk/-/algosdk-2.11.0.tgz", + "integrity": "sha512-MJ9xrjBKqG6ItCAR0Z974DG7nvifXsQxlj7HbWkBat4+h/IygwKPEH/v0dQPOYWdTcf5/5lfu+OyEVOsjxvyRQ==", + "license": "MIT", + "dependencies": { + "algo-msgpack-with-bigint": "^2.1.1", + "buffer": "^6.0.3", + "hi-base32": "^0.5.1", + "js-sha256": "^0.9.0", + "js-sha3": "^0.8.0", + "js-sha512": "^0.8.0", + "json-bigint": "^1.0.0", + "tweetnacl": "^1.0.3", + "vlq": "^2.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", @@ -783,7 +3289,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -795,18 +3301,82 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "license": "ISC", + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/aptos": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/aptos/-/aptos-1.5.0.tgz", + "integrity": "sha512-N7OuRtU7IYHkDkNx+4QS3g/QQGCp+36KzYn3oXPmT7Kttfuv+UKliQVdjy3cLmwd/DCQSh9ObTovwdxnHjUn0g==", + "deprecated": "Package aptos is no longer supported, please migrate to https://www.npmjs.com/package/@aptos-labs/ts-sdk", + "license": "Apache-2.0", + "dependencies": { + "@noble/hashes": "1.1.3", + "@scure/bip39": "1.1.0", + "axios": "0.27.2", + "form-data": "4.0.0", + "tweetnacl": "1.0.3" + }, + "engines": { + "node": ">=11.0.0" + } + }, + "node_modules/aptos/node_modules/@noble/hashes": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.1.3.tgz", + "integrity": "sha512-CE0FCR57H2acVI5UOzIGSSIYxZ6v/HOhDR0Ro9VLyhnzLwx0o8W1mmgaqlEUx4049qJDlIBRztv5k+MM8vbO3A==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT" + }, + "node_modules/aptos/node_modules/@scure/base": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", + "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/aptos/node_modules/@scure/bip39": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.0.tgz", + "integrity": "sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT", + "dependencies": { + "@noble/hashes": "~1.1.1", + "@scure/base": "~1.1.0" + } + }, + "node_modules/aptos/node_modules/axios": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "license": "MIT", "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" } }, "node_modules/argparse": { @@ -820,17 +3390,31 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, "license": "MIT", "engines": { "node": "*" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/axios": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz", + "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.14.4" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/base-x": { @@ -862,6 +3446,43 @@ ], "license": "MIT" }, + "node_modules/bech32": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", + "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==", + "license": "MIT" + }, + "node_modules/big-integer": { + "version": "1.6.36", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.36.tgz", + "integrity": "sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg==", + "license": "Unlicense", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/bigint-buffer": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/bigint-buffer/-/bigint-buffer-1.1.5.tgz", + "integrity": "sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "bindings": "^1.3.0" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/bignumber.js": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.0.tgz", + "integrity": "sha512-EM7aMFTXbptt/wZdMlBv2t8IViwQL+h6SLHosp8Yf0dqJMTnY6iL32opnAB6kAdL0SZPuvcAzFr31o0c/R3/RA==", + "license": "MIT", + "engines": { + "node": "*" + } + }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", @@ -875,6 +3496,73 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/binary-parser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/binary-parser/-/binary-parser-2.2.1.tgz", + "integrity": "sha512-5ATpz/uPDgq5GgEDxTB4ouXCde7q2lqAQlSdBRQVl/AJnxmQmhIfyxJx+0MGu//D5rHQifkfGbWWlaysG0o9NA==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "license": "MIT", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bip32": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/bip32/-/bip32-2.0.6.tgz", + "integrity": "sha512-HpV5OMLLGTjSVblmrtYRfFFKuQB+GArM0+XP8HGWfJ5vxYBqo+DesvJwOdC2WJ3bCkZShGf0QIfoIpeomVzVdA==", + "license": "MIT", + "dependencies": { + "@types/node": "10.12.18", + "bs58check": "^2.1.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "tiny-secp256k1": "^1.1.3", + "typeforce": "^1.11.5", + "wif": "^2.0.6" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/bip32/node_modules/@types/node": { + "version": "10.12.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz", + "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==", + "license": "MIT" + }, + "node_modules/bip39": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.1.0.tgz", + "integrity": "sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A==", + "license": "ISC", + "dependencies": { + "@noble/hashes": "^1.2.0" + } + }, + "node_modules/bip66": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", + "integrity": "sha512-nemMHz95EmS38a26XbbdxIYj5csHd3RMP3H5bwQknX0WYHF01qhpufP42mLOwVICuH2JmhIhXiWs89MfUGL7Xw==", + "license": "MIT", + "optional": true, + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", + "license": "MIT" + }, "node_modules/bn.js": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", @@ -915,6 +3603,18 @@ "node": ">=8" } }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", + "license": "MIT" + }, + "node_modules/browser-headers": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/browser-headers/-/browser-headers-0.4.1.tgz", + "integrity": "sha512-CA9hsySZVo9371qEHjHZtYxV2cFtVj5Wj/ZHi8ooEsrtm4vOnl9Y9HmyYWk9q+05d7K3rdoAE0j3MVEFVvtQtg==", + "license": "Apache-2.0" + }, "node_modules/browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", @@ -922,6 +3622,20 @@ "dev": true, "license": "ISC" }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "license": "MIT", + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, "node_modules/bs58": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", @@ -931,6 +3645,17 @@ "base-x": "^3.0.2" } }, + "node_modules/bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "license": "MIT", + "dependencies": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, "node_modules/buffer": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", @@ -964,13 +3689,18 @@ "node": ">=4.5" } }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", + "license": "MIT" + }, "node_modules/bufferutil": { "version": "4.0.9", "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.9.tgz", "integrity": "sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw==", "hasInstallScript": true, "license": "MIT", - "optional": true, "dependencies": { "node-gyp-build": "^4.3.0" }, @@ -990,11 +3720,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/capability": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/capability/-/capability-0.2.5.tgz", + "integrity": "sha512-rsJZYVCgXd08sPqwmaIqjAd5SUTfonV0z/gDJ8D6cN8wQphky1kkAYEqQ+hmDxTw7UihvBfjUVUSY+DBEe44jg==", + "license": "MIT" + }, "node_modules/chai": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", - "dev": true, "license": "MIT", "dependencies": { "assertion-error": "^1.1.0", @@ -1009,6 +3744,27 @@ "node": ">=4" } }, + "node_modules/chai-as-promised": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-8.0.1.tgz", + "integrity": "sha512-OIEJtOL8xxJSH8JJWbIoRjybbzR52iFuDHuF8eb+nTPD6tgXLjRqsgnUGqQfFODxYvq5QdirT0pN9dZ0+Gz6rA==", + "license": "MIT", + "dependencies": { + "check-error": "^2.0.0" + }, + "peerDependencies": { + "chai": ">= 2.1.2 < 6" + } + }, + "node_modules/chai-as-promised/node_modules/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -1043,7 +3799,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", - "dev": true, "license": "MIT", "dependencies": { "get-func-name": "^2.0.2" @@ -1080,6 +3835,19 @@ "fsevents": "~2.3.2" } }, + "node_modules/cipher-base": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.6.tgz", + "integrity": "sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.4", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -1095,29 +3863,218 @@ "node": ">=12" } }, - "node_modules/cliui/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", + "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "license": "MIT", + "optional": true + }, + "node_modules/copyfiles": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/copyfiles/-/copyfiles-2.4.1.tgz", + "integrity": "sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg==", + "license": "MIT", + "optional": true, + "dependencies": { + "glob": "^7.0.5", + "minimatch": "^3.0.3", + "mkdirp": "^1.0.4", + "noms": "0.0.0", + "through2": "^2.0.1", + "untildify": "^4.0.0", + "yargs": "^16.1.0" + }, + "bin": { + "copyfiles": "copyfiles", + "copyup": "copyfiles" + } + }, + "node_modules/copyfiles/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/copyfiles/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "license": "MIT", + "optional": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/copyfiles/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "license": "ISC", + "optional": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/copyfiles/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT", + "optional": true + }, + "node_modules/copyfiles/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "license": "ISC", + "optional": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/copyfiles/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "optional": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, "engines": { - "node": ">=8" + "node": "*" } }, - "node_modules/cliui/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/cliui/node_modules/string-width": { + "node_modules/copyfiles/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "license": "MIT", + "optional": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -1127,12 +4084,12 @@ "node": ">=8" } }, - "node_modules/cliui/node_modules/strip-ansi": { + "node_modules/copyfiles/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "license": "MIT", + "optional": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -1140,12 +4097,12 @@ "node": ">=8" } }, - "node_modules/cliui/node_modules/wrap-ansi": { + "node_modules/copyfiles/node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "license": "MIT", + "optional": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -1158,33 +4115,118 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, + "node_modules/copyfiles/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "license": "MIT", + "optional": true, "dependencies": { - "color-name": "~1.1.4" + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" }, "engines": { - "node": ">=7.0.0" + "node": ">=10" } }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "license": "MIT" + "node_modules/copyfiles/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "license": "ISC", + "optional": true, + "engines": { + "node": ">=10" + } }, - "node_modules/commander": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", - "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "license": "MIT", + "optional": true + }, + "node_modules/cosmjs-types": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.7.2.tgz", + "integrity": "sha512-vf2uLyktjr/XVAgEq0DjMxeAWh1yYREe7AMHDKd7EiHVqxBPCaBS+qEEQUkXbR9ndnckqr1sUG8BQhazh4X5lA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "long": "^4.0.0", + "protobufjs": "~6.11.2" + } + }, + "node_modules/cosmjs-types/node_modules/protobufjs": { + "version": "6.11.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz", + "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "license": "Apache-2.0", + "optional": true, + "bin": { + "crc32": "bin/crc32.njs" + }, "engines": { - "node": ">=18" + "node": ">=0.8" + } + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" } }, "node_modules/cross-fetch": { @@ -1211,6 +4253,33 @@ "node": ">= 8" } }, + "node_modules/crypto-addr-codec": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/crypto-addr-codec/-/crypto-addr-codec-0.1.8.tgz", + "integrity": "sha512-GqAK90iLLgP3FvhNmHbpT3wR6dEdaM8hZyZtLX29SPardh3OA13RFLHDR6sntGCgRWOfiHqW6sIyohpNqOtV/g==", + "license": "MIT", + "dependencies": { + "base-x": "^3.0.8", + "big-integer": "1.6.36", + "blakejs": "^1.1.0", + "bs58": "^4.0.1", + "ripemd160-min": "0.0.6", + "safe-buffer": "^5.2.0", + "sha3": "^2.1.1" + } + }, + "node_modules/crypto-hash": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/crypto-hash/-/crypto-hash-1.3.0.tgz", + "integrity": "sha512-lyAZ0EMyjDkVvz8WOeVnuCPvKVBXcMv1l5SVqO1yC7PzTwrD/pPje/BIRbWhMoPe436U+Y2nD7f5bFx0kt+Sbg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/debug": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", @@ -1242,11 +4311,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/decimal.js": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.5.0.tgz", + "integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==", + "license": "MIT" + }, "node_modules/deep-eql": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", - "dev": true, "license": "MIT", "dependencies": { "type-detect": "^4.0.0" @@ -1255,6 +4329,42 @@ "node": ">=6" } }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "optional": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "license": "MIT", + "optional": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/delay": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", @@ -1267,16 +4377,58 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/diff": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", - "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", - "dev": true, + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", + "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/drbg.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", + "integrity": "sha512-F4wZ06PvqxYLFEZKkFxTDcns9oFNk34hvmJSEwdzsxVQ8YI5YaxtACgQatkYgv2VI2CFkUd2Y+xosPQnHv809g==", + "license": "MIT", + "optional": true, + "dependencies": { + "browserify-aes": "^1.0.6", + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -1284,6 +4436,88 @@ "dev": true, "license": "MIT" }, + "node_modules/eccrypto": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/eccrypto/-/eccrypto-1.1.6.tgz", + "integrity": "sha512-d78ivVEzu7Tn0ZphUUaL43+jVPKTMPFGtmgtz1D0LrFn7cY3K8CdrvibuLz2AAkHBLKZtR8DMbB2ukRYFk987A==", + "hasInstallScript": true, + "license": "CC0-1.0", + "optional": true, + "dependencies": { + "acorn": "7.1.1", + "elliptic": "6.5.4", + "es6-promise": "4.2.8", + "nan": "2.14.0" + }, + "optionalDependencies": { + "secp256k1": "3.7.1" + } + }, + "node_modules/eccrypto/node_modules/bn.js": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", + "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "license": "MIT", + "optional": true + }, + "node_modules/eccrypto/node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/eccrypto/node_modules/secp256k1": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.7.1.tgz", + "integrity": "sha512-1cf8sbnRreXrQFdH6qsg2H71Xw91fCCS9Yp021GnUNJzWJS/py96fS4lHbnTnouLp08Xj6jBoBB6V78Tdbdu5g==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bindings": "^1.5.0", + "bip66": "^1.1.5", + "bn.js": "^4.11.8", + "create-hash": "^1.2.0", + "drbg.js": "^1.0.1", + "elliptic": "^6.4.1", + "nan": "^2.14.0", + "safe-buffer": "^5.1.2" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/elliptic": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz", + "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", + "license": "MIT", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", + "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "license": "MIT" + }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -1291,6 +4525,37 @@ "dev": true, "license": "MIT" }, + "node_modules/error-polyfill": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/error-polyfill/-/error-polyfill-0.1.3.tgz", + "integrity": "sha512-XHJk60ufE+TG/ydwp4lilOog549iiQF2OAPhkk9DdiYWMrltz5yhDz/xnKuenNwP7gy3dsibssO5QpVhkrSzzg==", + "license": "MIT", + "dependencies": { + "capability": "^0.2.5", + "o3": "^1.0.3", + "u3": "^0.1.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es6-promise": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", @@ -1351,7 +4616,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=6" @@ -1370,12 +4635,212 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/eth-crypto": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eth-crypto/-/eth-crypto-2.8.0.tgz", + "integrity": "sha512-QtVmfLZK+N0k4+RA65ORbVCBM2ndzPM0Q/VFhkYYrGY16+4OAwuxG+eyFlWyDO3HBFMlPnMLa69OZCKOoQkcdQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "@babel/runtime": "7.27.0", + "@ethereumjs/tx": "3.5.2", + "@types/bn.js": "5.1.6", + "eccrypto": "1.1.6", + "ethereumjs-util": "7.1.5", + "ethers": "5.8.0", + "secp256k1": "5.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/pubkey" + } + }, + "node_modules/eth-crypto/node_modules/node-addon-api": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==", + "license": "MIT", + "optional": true + }, + "node_modules/eth-crypto/node_modules/secp256k1": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-5.0.1.tgz", + "integrity": "sha512-lDFs9AAIaWP9UCdtWrotXWWF9t8PWgQDcxqgAnpM9rMqxb3Oaq2J0thzPVSxBwdJgyQtkU/sYtFtbM1RSt/iYA==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "elliptic": "^6.5.7", + "node-addon-api": "^5.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "license": "MIT", + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/ethereumjs-abi": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", + "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", + "deprecated": "This library has been deprecated and usage is discouraged.", + "license": "MIT", + "optional": true, + "dependencies": { + "bn.js": "^4.11.8", + "ethereumjs-util": "^6.0.0" + } + }, + "node_modules/ethereumjs-abi/node_modules/@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/ethereumjs-abi/node_modules/bn.js": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", + "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "license": "MIT", + "optional": true + }, + "node_modules/ethereumjs-abi/node_modules/ethereumjs-util": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", + "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", + "license": "MPL-2.0", + "optional": true, + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/ethereumjs-util": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", + "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", + "license": "MPL-2.0", + "dependencies": { + "@types/bn.js": "^5.1.0", + "bn.js": "^5.1.2", + "create-hash": "^1.1.2", + "ethereum-cryptography": "^0.1.3", + "rlp": "^2.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ethers": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.8.0.tgz", + "integrity": "sha512-DUq+7fHrCg1aPDFCHx6UIPb3nmt2XMpM7Y/g2gLhsl3lIBqeAfOJIl1qEvRf2uq3BiKxmh6Fh5pfp2ieyek7Kg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@ethersproject/abi": "5.8.0", + "@ethersproject/abstract-provider": "5.8.0", + "@ethersproject/abstract-signer": "5.8.0", + "@ethersproject/address": "5.8.0", + "@ethersproject/base64": "5.8.0", + "@ethersproject/basex": "5.8.0", + "@ethersproject/bignumber": "5.8.0", + "@ethersproject/bytes": "5.8.0", + "@ethersproject/constants": "5.8.0", + "@ethersproject/contracts": "5.8.0", + "@ethersproject/hash": "5.8.0", + "@ethersproject/hdnode": "5.8.0", + "@ethersproject/json-wallets": "5.8.0", + "@ethersproject/keccak256": "5.8.0", + "@ethersproject/logger": "5.8.0", + "@ethersproject/networks": "5.8.0", + "@ethersproject/pbkdf2": "5.8.0", + "@ethersproject/properties": "5.8.0", + "@ethersproject/providers": "5.8.0", + "@ethersproject/random": "5.8.0", + "@ethersproject/rlp": "5.8.0", + "@ethersproject/sha2": "5.8.0", + "@ethersproject/signing-key": "5.8.0", + "@ethersproject/solidity": "5.8.0", + "@ethersproject/strings": "5.8.0", + "@ethersproject/transactions": "5.8.0", + "@ethersproject/units": "5.8.0", + "@ethersproject/wallet": "5.8.0", + "@ethersproject/web": "5.8.0", + "@ethersproject/wordlists": "5.8.0" + } + }, + "node_modules/ethjs-util": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", + "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", + "license": "MIT", + "optional": true, + "dependencies": { + "is-hex-prefixed": "1.0.0", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, "node_modules/eventemitter3": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", "license": "MIT" }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "license": "MIT", + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, "node_modules/eyes": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", @@ -1390,6 +4855,19 @@ "integrity": "sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==", "license": "MIT" }, + "node_modules/fastestsmallesttextencoderdecoder": { + "version": "1.0.22", + "resolved": "https://registry.npmjs.org/fastestsmallesttextencoderdecoder/-/fastestsmallesttextencoderdecoder-1.0.22.tgz", + "integrity": "sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==", + "license": "CC0-1.0", + "peer": true + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "license": "MIT" + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -1430,6 +4908,26 @@ "flat": "cli.js" } }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/foreground-child": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", @@ -1447,6 +4945,27 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "license": "ISC", + "optional": true + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -1462,11 +4981,21 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "optional": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, + "devOptional": true, "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" @@ -1476,7 +5005,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", - "dev": true, "license": "MIT", "engines": { "node": "*" @@ -1545,6 +5073,68 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/google-protobuf": { + "version": "3.21.4", + "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.21.4.tgz", + "integrity": "sha512-MnG7N936zcKTco4Jd2PX2U96Kf9PxygAPKBug+74LHzmHXmceN16MmRcdgZv+DGef/S9YvQAfRsNCn4cjf9yyQ==", + "license": "(BSD-3-Clause AND Apache-2.0)" + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graphql": { + "version": "16.10.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.10.0.tgz", + "integrity": "sha512-AjqGKbDGUFRKIRCP9tCKiIGHyriz2oHEbPIbEtcSLSs4YjReZOIPQQWek4+6hjw62H9QShXHyaGivGiYVLeYFQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" + } + }, + "node_modules/graphql-tag": { + "version": "2.12.6", + "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz", + "integrity": "sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "graphql": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -1555,6 +5145,56 @@ "node": ">=8" } }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", + "optional": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -1565,6 +5205,65 @@ "he": "bin/he" } }, + "node_modules/hi-base32": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/hi-base32/-/hi-base32-0.5.1.tgz", + "integrity": "sha512-EmBBpvdYh/4XxsnUybsPag6VikPYnN30td+vQk+GI3qpahVEG9+gTkG0aXVxTjBqQ5T6ijbWIu77O+C5WFWsnA==", + "license": "MIT" + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "license": "MIT", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-errors/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-status-codes": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.3.0.tgz", + "integrity": "sha512-RJ8XvFvpPM/Dmc5SV+dC4y5PCeOhT3x1Hq0NU3rjGeg5a/CqlhZ7uudknPwZFz4aeAXDcbAyaeP7GAo9lvngtA==", + "license": "MIT", + "optional": true + }, "node_modules/humanize-ms": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", @@ -1594,6 +5293,34 @@ ], "license": "BSD-3-Clause" }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "license": "ISC", + "optional": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -1607,6 +5334,22 @@ "node": ">=8" } }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "license": "MIT", + "optional": true, + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -1621,7 +5364,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=8" @@ -1640,6 +5383,17 @@ "node": ">=0.10.0" } }, + "node_modules/is-hex-prefixed": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", + "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -1673,6 +5427,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "license": "MIT", + "optional": true + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -1728,40 +5489,237 @@ "jayson": "bin/jayson.js" }, "engines": { - "node": ">=8" + "node": ">=8" + } + }, + "node_modules/jayson/node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", + "license": "MIT" + }, + "node_modules/jayson/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "license": "MIT" + }, + "node_modules/js-base64": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.7.tgz", + "integrity": "sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==", + "license": "BSD-3-Clause" + }, + "node_modules/js-sha256": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", + "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==", + "license": "MIT" + }, + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", + "license": "MIT" + }, + "node_modules/js-sha512": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha512/-/js-sha512-0.8.0.tgz", + "integrity": "sha512-PWsmefG6Jkodqt+ePTvBZCSMFgN7Clckjd0O7su3I0+BW2QWUTJNzjktHsztGLhncP2h8mcF9V9Y2Ha59pAViQ==", + "license": "MIT" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT", + "optional": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jscrypto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/jscrypto/-/jscrypto-1.0.3.tgz", + "integrity": "sha512-lryZl0flhodv4SZHOqyb1bx5sKcJxj0VBo0Kzb4QMAg3L021IC9uGpl0RCZa+9KJwlRGSK2C80ITcwbe19OKLQ==", + "license": "MIT", + "bin": { + "jscrypto": "bin/cli.js" + } + }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "license": "MIT", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "license": "ISC" + }, + "node_modules/jsonschema": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.5.0.tgz", + "integrity": "sha512-K+A9hhqbn0f3pJX17Q/7H6yQfD/5OXgdrR5UE12gMXCiN9D5Xq2o5mddV2QEcX/bjla99ASsAAQUyMCCRWAEhw==", + "license": "MIT", + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/keccak": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.4.tgz", + "integrity": "sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/keccak256": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/keccak256/-/keccak256-1.0.6.tgz", + "integrity": "sha512-8GLiM01PkdJVGUhR1e6M/AvWnSqYS0HaERI+K/QtStGDGlSTx2B1zTqZk4Zlqu5TxHJNTxWAdP9Y+WI50OApUw==", + "license": "MIT", + "optional": true, + "dependencies": { + "bn.js": "^5.2.0", + "buffer": "^6.0.3", + "keccak": "^3.0.2" + } + }, + "node_modules/libsodium": { + "version": "0.7.15", + "resolved": "https://registry.npmjs.org/libsodium/-/libsodium-0.7.15.tgz", + "integrity": "sha512-sZwRknt/tUpE2AwzHq3jEyUU5uvIZHtSssktXq7owd++3CSgn8RGrv6UZJJBpP7+iBghBqe7Z06/2M31rI2NKw==", + "license": "ISC", + "optional": true + }, + "node_modules/libsodium-wrappers": { + "version": "0.7.15", + "resolved": "https://registry.npmjs.org/libsodium-wrappers/-/libsodium-wrappers-0.7.15.tgz", + "integrity": "sha512-E4anqJQwcfiC6+Yrl01C1m8p99wEhLmJSs0VQqST66SbQXXBoaJY0pF4BNjRYa/sOQAxx6lXAaAFIlx+15tXJQ==", + "license": "ISC", + "optional": true, + "dependencies": { + "libsodium": "^0.7.15" + } + }, + "node_modules/link-module-alias": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/link-module-alias/-/link-module-alias-1.2.0.tgz", + "integrity": "sha512-ahPjXepbSVKbahTB6LxR//VHm8HPfI+QQygCH+E82spBY4HR5VPJTvlhKBc9F7muVxnS6C1rRfoPOXAbWO/fyw==", + "license": "MIT", + "optional": true, + "dependencies": { + "chalk": "^2.4.1" + }, + "bin": { + "link-module-alias": "index.js" + }, + "engines": { + "node": "> 8.0.0" + } + }, + "node_modules/link-module-alias/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "license": "MIT", + "optional": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/link-module-alias/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/jayson/node_modules/@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", - "license": "MIT" + "node_modules/link-module-alias/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", + "optional": true, + "dependencies": { + "color-name": "1.1.3" + } }, - "node_modules/jayson/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "license": "MIT" + "node_modules/link-module-alias/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT", + "optional": true }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, + "node_modules/link-module-alias/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/link-module-alias/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/link-module-alias/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "license": "MIT", + "optional": true, "dependencies": { - "argparse": "^2.0.1" + "has-flag": "^3.0.0" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "engines": { + "node": ">=4" } }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "license": "ISC" - }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -1778,6 +5736,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT", + "optional": true + }, + "node_modules/lodash.values": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.values/-/lodash.values-4.3.0.tgz", + "integrity": "sha512-r0RwvdCv8id9TUblb/O7rYPwVy6lerCbcawrfdo9iC/1t1wsNMJknO79WNBgwkH0hIeJ08jmvvESbFpNb4jH0Q==", + "license": "MIT", + "optional": true + }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -1795,16 +5767,43 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", + "license": "Apache-2.0" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "optional": true, + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, "node_modules/loupe": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", - "dev": true, "license": "MIT", "dependencies": { "get-func-name": "^2.0.1" } }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + } + }, "node_modules/lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", @@ -1812,6 +5811,63 @@ "dev": true, "license": "ISC" }, + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "license": "MIT", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "license": "ISC" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", + "license": "MIT" + }, "node_modules/minimatch": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", @@ -1825,6 +5881,16 @@ "node": ">=10" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "optional": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/minipass": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", @@ -1835,6 +5901,19 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "license": "MIT", + "optional": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/mocha": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.1.0.tgz", @@ -1871,12 +5950,72 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/mocha/node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, + "node_modules/mustache": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", + "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", + "license": "MIT", + "bin": { + "mustache": "bin/mustache" + } + }, + "node_modules/nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "license": "MIT" + }, + "node_modules/near-api-js": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/near-api-js/-/near-api-js-1.1.0.tgz", + "integrity": "sha512-qYKv1mYsaDZc2uYndhS+ttDhR9+60qFc+ZjD6lWsAxr3ZskMjRwPffDGQZYhC7BRDQMe1HEbk6d5mf+TVm0Lqg==", + "license": "(MIT AND Apache-2.0)", + "dependencies": { + "bn.js": "5.2.1", + "borsh": "^0.7.0", + "bs58": "^4.0.0", + "depd": "^2.0.0", + "error-polyfill": "^0.1.3", + "http-errors": "^1.7.2", + "js-sha256": "^0.9.0", + "mustache": "^4.0.0", + "node-fetch": "^2.6.1", + "text-encoding-utf-8": "^1.0.2", + "tweetnacl": "^1.0.1" + } + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "license": "MIT", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", + "license": "MIT" + }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", @@ -1902,13 +6041,43 @@ "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", "license": "MIT", - "optional": true, "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", "node-gyp-build-test": "build-test.js" } }, + "node_modules/noms": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/noms/-/noms-0.0.0.tgz", + "integrity": "sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow==", + "license": "ISC", + "optional": true, + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "~1.0.31" + } + }, + "node_modules/noms/node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", + "license": "MIT", + "optional": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/noms/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "license": "MIT", + "optional": true + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -1919,6 +6088,58 @@ "node": ">=0.10.0" } }, + "node_modules/o3": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/o3/-/o3-1.0.3.tgz", + "integrity": "sha512-f+4n+vC6s4ysy7YO7O2gslWZBUu8Qj2i2OUJOvjRxQva7jVjYjB29jrr9NCjmxZQR0gzrOcv1RnqoYOeMs5VRQ==", + "license": "MIT", + "dependencies": { + "capability": "^0.2.5" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "optional": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optimism": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.18.1.tgz", + "integrity": "sha512-mLXNwWPa9dgFyDqkNi54sjDyNJ9/fTI6WGBLgnXku1vdKY/jovHfZT5r+aiVeFFLOz+foPNOm5YJ4mqgld2GBQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "@wry/caches": "^1.0.0", + "@wry/context": "^0.7.0", + "@wry/trie": "^0.5.0", + "tslib": "^2.3.0" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -1974,6 +6195,16 @@ "node": ">=8" } }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -1984,6 +6215,13 @@ "node": ">=8" } }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT", + "optional": true + }, "node_modules/path-scurry": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", @@ -2005,12 +6243,27 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true, "license": "MIT", "engines": { "node": "*" } }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "license": "MIT", + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -2040,16 +6293,92 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT", + "optional": true + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "optional": true, + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/protobufjs": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.0.tgz", + "integrity": "sha512-Z2E/kOY1QjoMlCytmexzYfDm/w5fKAiRwpSzGtdnXW1zC88Z2yXazHHrOtwCzn+7wSxyE8PYM4rvVcMphF9sOA==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/protobufjs/node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT", + "optional": true + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" } }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT", + "optional": true + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -2063,22 +6392,81 @@ "node": ">=8.10.0" } }, - "node_modules/regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "license": "MIT" - }, + "node_modules/readonly-date": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/readonly-date/-/readonly-date-1.0.0.tgz", + "integrity": "sha512-tMKIV7hlk0h4mO3JTmmVuIlJVXjKk3Sep9Bf5OH0O+758ruuVkUy2J9SttDLm91IEX/WHlXPSpxMGjPj4beMIQ==", + "license": "Apache-2.0", + "optional": true + }, + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "optional": true, + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" + }, + "node_modules/rehackt": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/rehackt/-/rehackt-0.1.0.tgz", + "integrity": "sha512-7kRDOuLHB87D/JESKxQoRwv4DzbIdwkAGQ7p6QKGdVlY1IZheUnVhlk/4UZlNUVxdAXpyxikE3URsG067ybVzw==", + "license": "MIT", + "optional": true, + "peerDependencies": { + "@types/react": "*", + "react": "*" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react": { + "optional": true + } + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "license": "MIT", + "optional": true, + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/resolve-pkg-maps": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", @@ -2089,6 +6477,36 @@ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "license": "MIT", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/ripemd160-min": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/ripemd160-min/-/ripemd160-min-0.0.6.tgz", + "integrity": "sha512-+GcJgQivhs6S9qvLogusiTcS9kQUfgR75whKuy5jIhuiOfQuJ8fjqxV6EGD5duH1Y/FawFUMtMhyeq3Fbnib8A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/rlp": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", + "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^5.2.0" + }, + "bin": { + "rlp": "bin/rlp" + } + }, "node_modules/rpc-websockets": { "version": "9.1.1", "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-9.1.1.tgz", @@ -2148,6 +6566,15 @@ } } }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -2168,6 +6595,33 @@ ], "license": "MIT" }, + "node_modules/scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", + "license": "MIT" + }, + "node_modules/secp256k1": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.4.tgz", + "integrity": "sha512-6JfvwvjUOn8F/jUoBY2Q1v5WY5XS+rj8qSe0v8Y4ezH4InLgTEeOOPQsRll9OV429Pvo6BCHGavIyJfr3TAhsw==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "elliptic": "^6.5.7", + "node-addon-api": "^5.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/secp256k1/node_modules/node-addon-api": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==", + "license": "MIT" + }, "node_modules/serialize-javascript": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", @@ -2178,6 +6632,40 @@ "randombytes": "^2.1.0" } }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "license": "MIT" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "license": "(MIT AND BSD-3-Clause)", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/sha3": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/sha3/-/sha3-2.1.4.tgz", + "integrity": "sha512-S8cNxbyb0UGUM2VhRD4Poe5N58gJnJsLJ5vC7FYWGUmGhcsj4++WaIOBFVDxlG0W3To6xBuiRh+i0Qp2oNCOtg==", + "license": "MIT", + "dependencies": { + "buffer": "6.0.3" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -2201,6 +6689,87 @@ "node": ">=8" } }, + "node_modules/shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/shelljs/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "license": "MIT", + "optional": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/shelljs/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "license": "ISC", + "optional": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/shelljs/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "optional": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/shx": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/shx/-/shx-0.3.4.tgz", + "integrity": "sha512-N6A9MLVqjxZYcVn8hLmtneQWIJtp8IKzMP4eMnx+nqkvXoqinUPCbUFLp2UcWTEIUONhlk0ewxr/jaVGlc+J+g==", + "license": "MIT", + "optional": true, + "dependencies": { + "minimist": "^1.2.3", + "shelljs": "^0.8.5" + }, + "bin": { + "shx": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", @@ -2214,6 +6783,47 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "license": "MIT", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/snakecase-keys": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/snakecase-keys/-/snakecase-keys-5.5.0.tgz", + "integrity": "sha512-r3kRtnoPu3FxGJ3fny6PKNnU3pteb29o6qAa0ugzhSseKNWRkw1dw8nIjXMyyKaU9vQxxVIE62Mb3bKbdrgpiw==", + "license": "MIT", + "optional": true, + "dependencies": { + "map-obj": "^4.1.0", + "snake-case": "^3.0.4", + "type-fest": "^3.12.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/store2": { + "version": "2.14.4", + "resolved": "https://registry.npmjs.org/store2/-/store2-2.14.4.tgz", + "integrity": "sha512-srTItn1GOvyvOycgxjAnPA63FZNwy0PTyUBFMHRM+hVFltAeoh0LmNBz9SZqUS9mMqGk8rfyWyXn3GH5ReJ8Zw==", + "license": "MIT", + "optional": true + }, "node_modules/stream-chain": { "version": "2.2.5", "resolved": "https://registry.npmjs.org/stream-chain/-/stream-chain-2.2.5.tgz", @@ -2229,6 +6839,15 @@ "stream-chain": "^2.2.5" } }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", @@ -2333,6 +6952,20 @@ "node": ">=8" } }, + "node_modules/strip-hex-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", + "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", + "license": "MIT", + "optional": true, + "dependencies": { + "is-hex-prefixed": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -2368,11 +7001,117 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/symbol-observable": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-2.0.3.tgz", + "integrity": "sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10" + } + }, "node_modules/text-encoding-utf-8": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz", "integrity": "sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==" }, + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/through2/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT", + "optional": true + }, + "node_modules/through2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "optional": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/through2/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT", + "optional": true + }, + "node_modules/through2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "optional": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/tiny-secp256k1": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/tiny-secp256k1/-/tiny-secp256k1-1.1.7.tgz", + "integrity": "sha512-eb+F6NabSnjbLwNoC+2o5ItbmP1kg7HliWue71JgLegQt6A5mTN8YbvTLCazdlg6e5SV6A+r8OGvZYskdlmhqQ==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "bindings": "^1.3.0", + "bn.js": "^4.11.8", + "create-hmac": "^1.1.7", + "elliptic": "^6.4.0", + "nan": "^2.13.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/tiny-secp256k1/node_modules/bn.js": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", + "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "license": "MIT" + }, + "node_modules/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -2386,6 +7125,15 @@ "node": ">=8.0" } }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, "node_modules/toml": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", @@ -2398,6 +7146,19 @@ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "license": "MIT" }, + "node_modules/ts-invariant": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.10.3.tgz", + "integrity": "sha512-uivwYcQaxAucv1CzRp2n/QdYPo4ILf9VXgH19zEIjFx2EJufV16P0JtJVpYHy89DItG6Kwj2oIUjrcK5au+4tQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -2424,16 +7185,47 @@ "fsevents": "~2.3.3" } }, + "node_modules/tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", + "license": "Unlicense" + }, + "node_modules/tweetnacl-util": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", + "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==", + "license": "Unlicense", + "optional": true + }, "node_modules/type-detect": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", - "dev": true, "license": "MIT", "engines": { "node": ">=4" } }, + "node_modules/type-fest": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", + "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", + "license": "(MIT OR CC0-1.0)", + "optional": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typeforce": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz", + "integrity": "sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==", + "license": "MIT" + }, "node_modules/typescript": { "version": "5.8.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", @@ -2447,19 +7239,34 @@ "node": ">=14.17" } }, + "node_modules/u3": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/u3/-/u3-0.1.1.tgz", + "integrity": "sha512-+J5D5ir763y+Am/QY6hXNRlwljIeRMZMGs0cT6qqZVVzzT3X3nFPXVyPOFRMOR4kupB0T8JnCdpWdp6Q/iXn3w==", + "license": "MIT" + }, "node_modules/undici-types": { "version": "6.20.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", "license": "MIT" }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + } + }, "node_modules/utf-8-validate": { "version": "5.0.10", "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", "hasInstallScript": true, "license": "MIT", - "optional": true, "dependencies": { "node-gyp-build": "^4.3.0" }, @@ -2467,6 +7274,12 @@ "node": ">=6.14.2" } }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, "node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", @@ -2476,6 +7289,12 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/vlq": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vlq/-/vlq-2.0.4.tgz", + "integrity": "sha512-aodjPa2wPQFkra1G8CzJBTHXhgk3EVSwxSWXNPr1fgdFLUb8kvLV1iEb6rFgasIsjP82HWI6dsb5Io26DDnasA==", + "license": "MIT" + }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", @@ -2508,6 +7327,15 @@ "node": ">= 8" } }, + "node_modules/wif": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/wif/-/wif-2.0.6.tgz", + "integrity": "sha512-HIanZn1zmduSF+BQhkE+YXIbEiH0xPr1012QbFEGB0xsKqJii0/SqJjyn8dFv6y36kOznMgMB+LGcbZTJ1xACQ==", + "license": "MIT", + "dependencies": { + "bs58check": "<3.0.0" + } + }, "node_modules/workerpool": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", @@ -2610,6 +7438,13 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC", + "optional": true + }, "node_modules/ws": { "version": "7.5.10", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", @@ -2631,11 +7466,32 @@ } } }, + "node_modules/xstream": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/xstream/-/xstream-11.14.0.tgz", + "integrity": "sha512-1bLb+kKKtKPbgTK6i/BaoAn03g47PpFstlbe1BA+y3pNS/LfvcaghS5BFf9+EE1J+KwSQsEpfJvFN5GqFtiNmw==", + "license": "MIT", + "optional": true, + "dependencies": { + "globalthis": "^1.0.1", + "symbol-observable": "^2.0.3" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.4" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, + "devOptional": true, "license": "ISC", "engines": { "node": ">=10" @@ -2743,6 +7599,23 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zen-observable": { + "version": "0.8.15", + "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz", + "integrity": "sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==", + "license": "MIT", + "optional": true + }, + "node_modules/zen-observable-ts": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-1.2.5.tgz", + "integrity": "sha512-QZWQekv6iB72Naeake9hS1KxHlotfRpe+WGNbNx5/ta+R3DNjVO2bswf63gXlWDcs+EMd7XY8HfVQyP1X6T4Zg==", + "license": "MIT", + "optional": true, + "dependencies": { + "zen-observable": "0.8.15" + } } } } diff --git a/src/solana/package.json b/src/solana/package.json index 5a11689..4e1b7f1 100644 --- a/src/solana/package.json +++ b/src/solana/package.json @@ -7,15 +7,19 @@ "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" }, "dependencies": { + "@certusone/wormhole-sdk": "^0.10.18", "@coral-xyz/anchor": "^0.31.1", "@noble/hashes": "^1.7.2", - "@noble/secp256k1": "^2.2.3" + "@noble/secp256k1": "^2.2.3", + "chai-as-promised": "^8.0.1", + "diff": "^7.0.0" }, "devDependencies": { "@types/bn.js": "^5.1.0", "@types/chai": "^4.3.0", + "@types/chai-as-promised": "^8.0.2", "@types/mocha": "^10.0.10", - "chai": "^4.3.4", + "chai": "^4.5.0", "mocha": "^11.1.0", "prettier": "^2.6.2", "tsx": "^4.19.3", diff --git a/src/solana/tests/solana.ts b/src/solana/tests/solana.ts deleted file mode 100644 index 33d0b60..0000000 --- a/src/solana/tests/solana.ts +++ /dev/null @@ -1,16 +0,0 @@ -import * as anchor from "@coral-xyz/anchor"; -import { Program } from "@coral-xyz/anchor"; -import { VerificationV2 } from "../target/types/verification_v2.js"; - -describe("solana", () => { - // Configure the client to use the local cluster. - anchor.setProvider(anchor.AnchorProvider.env()); - - const program = anchor.workspace.solana as Program; - - it("Is initialized!", async () => { - // Add your test here. - const tx = await program.methods.initialize().rpc(); - console.log("Your transaction signature", tx); - }); -}); diff --git a/src/solana/tests/testing_helpers.ts b/src/solana/tests/testing_helpers.ts new file mode 100644 index 0000000..d9a054b --- /dev/null +++ b/src/solana/tests/testing_helpers.ts @@ -0,0 +1,142 @@ + + +import * as fs from "fs" +import * as toml from "toml" + +import { Connection, LAMPORTS_PER_SOL, PublicKey, Signer, Transaction, TransactionInstruction, ComputeBudgetProgram, sendAndConfirmTransaction } from "@solana/web3.js" +import { NodeWallet, postVaaSolana, signSendAndConfirmTransaction } from "@certusone/wormhole-sdk/lib/cjs/solana" +import { MockGuardians } from "@certusone/wormhole-sdk/lib/cjs/mock" +import { CONTRACTS } from "@certusone/wormhole-sdk"; + +import { expect, use as chaiUse } from "chai" +import chaiAsPromised from "chai-as-promised" +chaiUse(chaiAsPromised) + +// Copied from @wormhole-foundation/wormhole-scaffolding/solana/ts/helpers/utils.ts +// TODO: There's probably some way to import this? + +export const MOCK_GUARDIANS = new MockGuardians(0, ["cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0"]) + +class SendIxError extends Error { + logs: string; + + constructor(originalError: Error & { logs?: string[] }) { + //The newlines don't actually show up correctly in chai's assertion error, but at least + // we have all the information and can just replace '\n' with a newline manually to see + // what's happening without having to change the code. + const logs = originalError.logs?.join('\n') || "error had no logs"; + super(originalError.message + "\nlogs:\n" + logs); + this.stack = originalError.stack; + this.logs = logs; + } +} + +export const boilerPlateReduction = (connection: Connection, defaultSigner: Signer) => { + // for signing wormhole messages + const defaultNodeWallet = NodeWallet.fromSecretKey(defaultSigner.secretKey); + + const payerToWallet = (payer?: Signer) => + !payer || payer === defaultSigner + ? defaultNodeWallet + : NodeWallet.fromSecretKey(payer.secretKey); + + const requestAirdrop = async (account: PublicKey) => + connection.confirmTransaction( + await connection.requestAirdrop(account, 1000 * LAMPORTS_PER_SOL) + ); + + const guardianSign = (message: Buffer) => + MOCK_GUARDIANS.addSignatures(message, [0]) + + const postSignedMsgAsVaaOnSolana = async (signedMsg: Buffer, payer?: Signer) => { + const wallet = payerToWallet(payer); + const coreV1 = new PublicKey(CONTRACTS.DEVNET.solana.core); + await postVaaSolana( + connection, + wallet.signTransaction, + coreV1, + wallet.key(), + signedMsg + ); + } + + const sendAndConfirmIx = async ( + ix: TransactionInstruction | Promise, + signerOrSignersOrComputeUnits?: Signer | Signer[] | number, + computeUnits?: number, + ) => { + let [signers, units] = (() => { + if (!signerOrSignersOrComputeUnits) + return [[defaultSigner], computeUnits]; + + if (typeof signerOrSignersOrComputeUnits === "number") { + if(computeUnits !== undefined) + throw new Error("computeUnits can't be specified twice"); + return [[defaultSigner], signerOrSignersOrComputeUnits]; + } + + return [ + Array.isArray(signerOrSignersOrComputeUnits) + ? signerOrSignersOrComputeUnits + : [signerOrSignersOrComputeUnits], + computeUnits + ]; + })(); + + const tx = new Transaction().add(await ix); + if (units) + tx.add(ComputeBudgetProgram.setComputeUnitLimit({units})); + try { + return await sendAndConfirmTransaction(connection, tx, signers); + } + catch (error: any) { + throw new SendIxError(error); + } + } + + const expectIxToSucceed = async ( + ix: TransactionInstruction | Promise, + signerOrSignersOrComputeUnits?: Signer | Signer[] | number, + computeUnits?: number, + ) => + expect(sendAndConfirmIx(ix, signerOrSignersOrComputeUnits, computeUnits)).to.be.fulfilled; + + const expectIxToFailWithError = async ( + ix: TransactionInstruction | Promise, + errorMessage: string, + signerOrSignersOrComputeUnits?: Signer | Signer[] | number, + computeUnits?: number, + ) => { + try { + await sendAndConfirmIx(ix, signerOrSignersOrComputeUnits, computeUnits); + } catch (error) { + expect((error as SendIxError).logs).includes(errorMessage); + return; + } + expect.fail("Expected transaction to fail"); + } + + const expectTxToSucceed = async ( + tx: Transaction | Promise, + payer?: Signer, + ) => { + const wallet = payerToWallet(payer); + return expect( + signSendAndConfirmTransaction( + connection, + wallet.key(), + wallet.signTransaction, + await tx, + )).to.be.fulfilled; + } + + return { + requestAirdrop, + guardianSign, + postSignedMsgAsVaaOnSolana, + sendAndConfirmIx, + expectIxToSucceed, + expectIxToFailWithError, + expectTxToSucceed, + }; +} diff --git a/src/solana/tests/verification_v2.ts b/src/solana/tests/verification_v2.ts new file mode 100644 index 0000000..411859f --- /dev/null +++ b/src/solana/tests/verification_v2.ts @@ -0,0 +1,166 @@ +import * as fs from "fs" +import * as toml from "toml" + +import * as anchor from "@coral-xyz/anchor" +import { PublicKey } from "@solana/web3.js" +import { VerificationV2 } from "../target/types/verification_v2.js" + +import { MockGuardians } from "@certusone/wormhole-sdk/lib/cjs/mock" +import * as coreV1 from "@certusone/wormhole-sdk/lib/cjs/solana/wormhole"; + +import { sign } from "@noble/secp256k1" +import { keccak_256 } from "@noble/hashes/sha3" + +import { assert, expect } from "chai" +import { boilerPlateReduction } from "./testing_helpers.js" +import { Program } from "@coral-xyz/anchor" +import { CONTRACTS } from "@certusone/wormhole-sdk" + +const encodeU16BE = (value: number) => [value >> 8, value & 0xFF] + +const encodeU32BE = (value: number) => [ + ...encodeU16BE(value >> 16), + ...encodeU16BE(value & 0xFFFF), +] + +const encodeU64BE = (value: number | bigint) => [ + ...encodeU32BE(Number(BigInt(value) >> BigInt(32))), + ...encodeU32BE(Number(BigInt(value) & BigInt(0xFFFFFFFF))), +] + +export interface VAABody { + readonly timestamp: number + readonly nonce: number + readonly emitterChainId: number + readonly emitterAddress: Uint8Array + readonly sequence: number + readonly consistencyLevel: number + readonly payload: Uint8Array +} + +export const createVAAv2 = (tssIndex: number, body: VAABody, privateKey: Uint8Array) => { + const vaaBody = new Uint8Array([ + ...encodeU32BE(body.timestamp), + ...encodeU32BE(body.nonce), + ...encodeU16BE(body.emitterChainId), + ...body.emitterAddress, + ...encodeU64BE(body.sequence), + body.consistencyLevel, + ...body.payload, + ]) + + const signature = sign(keccak_256(vaaBody), privateKey) + + const TSS_VAA_VERSION = 0x02 + + return new Uint8Array([ + TSS_VAA_VERSION, + ...encodeU32BE(tssIndex), + ...signature.toCompactRawBytes(), + signature.recovery, + ...vaaBody, + ]) +} + +export interface AppendThresholdKeyMessage { + readonly tssIndex: number + readonly tssKey: Uint8Array + readonly expirationDelaySeconds: number +} + +export const createAppendThresholdKeyMessage = (tssIndex: number, tssKey: Uint8Array, expirationDelaySeconds: number) => { + const MODULE_VERIFICATION_V2 = new Uint8Array([ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x53, 0x53, + ]) + + const ACTION_APPEND_THRESHOLD_KEY = 0x01 + + assert(tssKey.length === 20, "TSS key must be 20 bytes") + + return new Uint8Array([ + ...MODULE_VERIFICATION_V2, + ACTION_APPEND_THRESHOLD_KEY, + ...encodeU32BE(tssIndex), + ...tssKey, + ...encodeU32BE(expirationDelaySeconds), + ]) +} + +describe("Verification V2", () => { + // Configure the client to use the local cluster. + anchor.setProvider(anchor.AnchorProvider.env()) + + const connection = anchor.getProvider().connection + const payer = anchor.getProvider().wallet?.payer + assert(payer, "Payer not found") + + const mockGuardians = new MockGuardians(0, ["cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0"]) + + const coreV2 = anchor.workspace.VerificationV2 as Program + + const { + requestAirdrop, + guardianSign, + postSignedMsgAsVaaOnSolana, + expectIxToSucceed, + expectIxToFailWithError, + } = boilerPlateReduction(connection, payer) + + it("Initializes wormhole program", async () => { + const guardianSetExpirationTime = 86400 + const fee = 100n + const devnetGuardian = mockGuardians.getPublicKeys()[0] + const initialGuardians = [devnetGuardian] + const coreV1Address = new PublicKey(CONTRACTS.DEVNET.solana.core) + + await expectIxToSucceed( + coreV1.createInitializeInstruction( + coreV1Address, + payer.publicKey, + guardianSetExpirationTime, + fee, + initialGuardians, + ) + ) + + const accounts = await connection.getProgramAccounts(coreV1Address) + expect(accounts).has.length(2) + + const info = await coreV1.getWormholeBridgeData(connection, coreV1Address) + expect(info.guardianSetIndex).equals(0) + expect(info.config.guardianSetExpirationTime).equals(guardianSetExpirationTime) + expect(info.config.fee).equals(fee) + + const guardianSet = await coreV1.getGuardianSet(connection, coreV1Address, info.guardianSetIndex) + expect(guardianSet.index).equals(0) + expect(guardianSet.keys).has.length(1) + expect(devnetGuardian).deep.equal(guardianSet.keys[0]) + }) + + it("Add initial TSS key", async () => { + }) + + it("Verifies VAAv2", async () => { + + }) + + it("Add new TSS key", async () => { + + }) + + it("Verifies VAA with new TSS key", async () => { + + }) + + it("Invalidates TSS key after timeout", async () => { + + }) + + it("Does not verify VAA with invalid TSS key", async () => { + + }) + + it("Does not verify VAA with invalid signature", async () => { + }) +}) From 3ed4a2d48300cfd4199e3fcdbc9319ea0e0fcc65 Mon Sep 17 00:00:00 2001 From: Joshua Averett Date: Tue, 29 Apr 2025 22:12:01 -0700 Subject: [PATCH 23/53] Tests run again! --- src/solana/Anchor.toml | 12 +- src/solana/imports/wormhole.so | Bin 0 -> 973360 bytes src/solana/package.json | 6 +- .../programs/verification_v2/src/lib.rs | 2 +- src/solana/tests/verification_v2.ts | 130 +++++++----------- 5 files changed, 65 insertions(+), 85 deletions(-) create mode 100644 src/solana/imports/wormhole.so diff --git a/src/solana/Anchor.toml b/src/solana/Anchor.toml index dc7342a..873c37b 100644 --- a/src/solana/Anchor.toml +++ b/src/solana/Anchor.toml @@ -5,7 +5,7 @@ resolution = true skip-lint = false [programs.localnet] -verification_v2 = "CTyCJvaLgY18BTTY3M1ga1SmY5fuT3Jyu3j7s332Z3oz" +verification_v2 = "GbFfTqMqKDgAMRH8VmDmoLTdvDd1853TnkkEwpydv3J6" [registry] url = "https://api.apr.dev" @@ -16,3 +16,13 @@ wallet = "~/.config/solana/id.json" [scripts] test = "yarn run mocha -t 1000000 tests/**/*.ts" + +[test] +startup_wait = 5000 +shutdown_wait = 2000 +upgradeable = false + +[[test.genesis]] +name = "wormhole" +address = "worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth" +program = "imports/wormhole.so" diff --git a/src/solana/imports/wormhole.so b/src/solana/imports/wormhole.so new file mode 100644 index 0000000000000000000000000000000000000000..ef0a0bd62469326e41165a9ff42198c8da208031 GIT binary patch literal 973360 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�eizx=-PzXe4p==1OQqdeJ!7^z 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ά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 { - // Configure the client to use the local cluster. - anchor.setProvider(anchor.AnchorProvider.env()) - - const connection = anchor.getProvider().connection - const payer = anchor.getProvider().wallet?.payer - assert(payer, "Payer not found") - - const mockGuardians = new MockGuardians(0, ["cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0"]) - - const coreV2 = anchor.workspace.VerificationV2 as Program - - const { - requestAirdrop, - guardianSign, - postSignedMsgAsVaaOnSolana, - expectIxToSucceed, - expectIxToFailWithError, - } = boilerPlateReduction(connection, payer) - - it("Initializes wormhole program", async () => { - const guardianSetExpirationTime = 86400 - const fee = 100n - const devnetGuardian = mockGuardians.getPublicKeys()[0] - const initialGuardians = [devnetGuardian] - const coreV1Address = new PublicKey(CONTRACTS.DEVNET.solana.core) - - await expectIxToSucceed( - coreV1.createInitializeInstruction( - coreV1Address, - payer.publicKey, - guardianSetExpirationTime, - fee, - initialGuardians, - ) - ) - - const accounts = await connection.getProgramAccounts(coreV1Address) - expect(accounts).has.length(2) - - const info = await coreV1.getWormholeBridgeData(connection, coreV1Address) - expect(info.guardianSetIndex).equals(0) - expect(info.config.guardianSetExpirationTime).equals(guardianSetExpirationTime) - expect(info.config.fee).equals(fee) - - const guardianSet = await coreV1.getGuardianSet(connection, coreV1Address, info.guardianSetIndex) - expect(guardianSet.index).equals(0) - expect(guardianSet.keys).has.length(1) - expect(devnetGuardian).deep.equal(guardianSet.keys[0]) - }) - - it("Add initial TSS key", async () => { - }) - - it("Verifies VAAv2", async () => { - - }) - - it("Add new TSS key", async () => { - - }) - - it("Verifies VAA with new TSS key", async () => { - - }) - - it("Invalidates TSS key after timeout", async () => { - - }) - - it("Does not verify VAA with invalid TSS key", async () => { - - }) - - it("Does not verify VAA with invalid signature", async () => { - }) -}) +// ------------------------------------------------------------------------------------------------ + +// Configure the client to use the local cluster. +anchor.setProvider(anchor.AnchorProvider.env()) + +const connection = anchor.getProvider().connection +const payer = anchor.getProvider().wallet?.payer +assert(payer, "Payer not found") + +const mockGuardians = new MockGuardians(0, ["cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0"]) + +const coreV2 = anchor.workspace.VerificationV2 as Program + +const { + requestAirdrop, + guardianSign, + postSignedMsgAsVaaOnSolana, + expectIxToSucceed, + expectIxToFailWithError, +} = boilerPlateReduction(connection, payer) + +const guardianSetExpirationTime = 86400 +const fee = 100n +const devnetGuardian = mockGuardians.getPublicKeys()[0] +const initialGuardians = [devnetGuardian] +const coreV1Address = new PublicKey('worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth') + +await expectIxToSucceed( + coreV1.createInitializeInstruction( + coreV1Address, + payer.publicKey, + guardianSetExpirationTime, + fee, + initialGuardians, + ) +) + +const accounts = await connection.getProgramAccounts(coreV1Address) +assert(accounts.length === 2, "Expected 2 accounts") + +const info = await coreV1.getWormholeBridgeData(connection, coreV1Address) +assert(info.guardianSetIndex === 0, "Expected guardian set index to be 0") +assert(info.config.guardianSetExpirationTime === guardianSetExpirationTime, "Expected guardian set expiration time to be 86400") +assert(info.config.fee === fee, "Expected fee to be 100") + +const guardianSet = await coreV1.getGuardianSet(connection, coreV1Address, info.guardianSetIndex) +assert(guardianSet.index === 0, "Expected guardian set index to be 0") +assert(guardianSet.keys.length === 1, "Expected guardian set keys to have length 1") +assert(devnetGuardian.equals(guardianSet.keys[0]), "Expected guardian set keys to be the devnet guardian") From 466e11ca6bb4903e2d91955d62bf849ce123b3ea Mon Sep 17 00:00:00 2001 From: NoiTaTuM Date: Mon, 5 May 2025 14:04:29 -0300 Subject: [PATCH 24/53] Move TLS data to shards and add EIP712 encoding support --- src/evm/EIP712Encoding.sol | 56 ++++++++++++++++++++++++ src/evm/GuardianRegistryVerification.sol | 27 +++--------- src/evm/ThresholdVerificationState.sol | 27 +++++++++++- src/evm/VerificationV2.sol | 22 +++++----- 4 files changed, 97 insertions(+), 35 deletions(-) create mode 100644 src/evm/EIP712Encoding.sol diff --git a/src/evm/EIP712Encoding.sol b/src/evm/EIP712Encoding.sol new file mode 100644 index 0000000..81a4be1 --- /dev/null +++ b/src/evm/EIP712Encoding.sol @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: Apache 2 + +pragma solidity ^0.8.0; + +import {eagerOr} from "wormhole-sdk/Utils.sol"; +import {BytesParsing} from "wormhole-sdk/libraries/BytesParsing.sol"; +import {VaaLib} from "wormhole-sdk/libraries/VaaLib.sol"; + +contract EIP712Encoding { + + bytes32 constant EIP712_DOMAIN_TYPE_HASH = keccak256( + "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" + ); + bytes32 constant EIP712_NAME_HASH = keccak256("Wormhole VerificationV2"); + bytes32 constant EIP712_VERSION_HASH = keccak256("1"); + + bytes32 constant TLS_TYPE_HASH = keccak256( + "TLSKeyRegister(uint32 guardianSetIndex,uint32 expirationTime,bytes32 tlsKey)" + ); + + bytes32 private _domainSeparator; + + constructor () { + _domainSeparator = getDomainSeparator(block.chainid, address(this)); + } + + function getDomainSeparator( + uint256 eth_chain_id, address verifyingContract + ) internal pure returns (bytes32) { + return keccak256(abi.encode( + EIP712_DOMAIN_TYPE_HASH, + EIP712_NAME_HASH, + EIP712_VERSION_HASH, + eth_chain_id, + verifyingContract + )); + } + + function getRegisterTLSKeyHash( + uint32 guardianSetIndex, uint32 expirationTime, bytes32 tlsKey + ) internal pure returns (bytes32) { + return keccak256(abi.encode( + TLS_TYPE_HASH, + guardianSetIndex, + expirationTime, + tlsKey + )); + } + + function getRegisterTLSDigest( + uint32 guardianSetIndex, uint32 expirationTime, bytes32 tlsKey + ) internal view returns (bytes32) { + bytes32 tlsHash = getRegisterTLSKeyHash(guardianSetIndex, expirationTime, tlsKey); + return keccak256(abi.encodePacked("\x19\x01", _domainSeparator, tlsHash)); + } +} \ No newline at end of file diff --git a/src/evm/GuardianRegistryVerification.sol b/src/evm/GuardianRegistryVerification.sol index 9946955..719a135 100644 --- a/src/evm/GuardianRegistryVerification.sol +++ b/src/evm/GuardianRegistryVerification.sol @@ -5,33 +5,16 @@ pragma solidity ^0.8.0; import {eagerOr} from "wormhole-sdk/Utils.sol"; import {BytesParsing} from "wormhole-sdk/libraries/BytesParsing.sol"; import {VaaLib} from "wormhole-sdk/libraries/VaaLib.sol"; +import {EIP712Encoding} from "./EIP712Encoding.sol"; +import {ThresholdVerificationState} from "./ThresholdVerificationState.sol"; -contract GuardianRegistryVerification { +contract GuardianRegistryVerification is EIP712Encoding { using BytesParsing for bytes; using VaaLib for bytes; error RegistrationMessageExpired(); error GuardianSignatureVerificationFailed(); - mapping (uint32 => bytes32[]) private _guardianTLSKeys; - - function _registerTLSKey( - uint32 guardianSetIndex, - uint8 guardianIndex, - bytes32 tlsKey, - uint guardianSetSize - ) internal { - if (_guardianTLSKeys[guardianSetIndex].length == 0) { - _guardianTLSKeys[guardianSetIndex] = new bytes32[](guardianSetSize); - } - - _guardianTLSKeys[guardianSetIndex][guardianIndex] = tlsKey; - } - - function _getTLSKeys(uint32 guardianSetIndex) internal view returns (bytes32[] memory tlsKeys) { - return _guardianTLSKeys[guardianSetIndex]; - } - function _verifyRegisterTLSKey( address[] memory guardianAddrs, uint32 guardianSetIndex, @@ -41,10 +24,10 @@ contract GuardianRegistryVerification { bytes32 r, bytes32 s, uint8 v ) internal view { require(expirationTime > block.timestamp, RegistrationMessageExpired()); - bytes32 dataHash = keccak256(abi.encodePacked(guardianSetIndex, expirationTime, tlsKey)); + bytes32 digest = getRegisterTLSDigest(guardianSetIndex, expirationTime, tlsKey); // Verify the signature - address signatory = ecrecover(dataHash, v, r, s); + address signatory = ecrecover(digest, v, r, s); address guardian = guardianAddrs[guardianIndex]; require(signatory == guardian, GuardianSignatureVerificationFailed()); } diff --git a/src/evm/ThresholdVerificationState.sol b/src/evm/ThresholdVerificationState.sol index de30568..de9606c 100644 --- a/src/evm/ThresholdVerificationState.sol +++ b/src/evm/ThresholdVerificationState.sol @@ -8,10 +8,9 @@ contract ThresholdVerificationState { error InvalidThresholdKeyIndex(); error InvalidThresholdKeyAddress(); - // TODO: Add the registry data here struct ShardInfo { bytes32 shard; - bytes32 tlsKey; // TODO: Replace the mapping in the guardian registry with this + bytes32 tlsKey; } // Current threshold info is stored in a single slot @@ -81,4 +80,28 @@ contract ThresholdVerificationState { _shards.push(shards); } } + + function _getShards(uint32 guardianSetIndex) internal view returns (ShardInfo[] memory shards) { + return _shards[guardianSetIndex]; + } + + function _getShardsRaw( + uint32 guardianSetIndex + ) internal view returns (uint shardCount, bytes32[] memory rawShards) { + ShardInfo[] memory shards = _getShards(guardianSetIndex); + shardCount = shards.length; + assembly { + rawShards := shards + mstore(rawShards, mul(shardCount, 2)) + } + } + + function _registerTLSKey( + uint32 guardianSetIndex, + uint8 guardianIndex, + bytes32 tlsKey + ) internal { + _shards[guardianSetIndex][guardianIndex].tlsKey = tlsKey; + } + } diff --git a/src/evm/VerificationV2.sol b/src/evm/VerificationV2.sol index 419cb9e..e0ede63 100644 --- a/src/evm/VerificationV2.sol +++ b/src/evm/VerificationV2.sol @@ -22,7 +22,7 @@ uint8 constant OP_THRESHOLD_GET_CURRENT = 0x22; uint8 constant OP_THRESHOLD_GET = 0x23; uint8 constant OP_GUARDIAN_SET_GET_CURRENT = 0x24; uint8 constant OP_GUARDIAN_SET_GET = 0x25; -uint8 constant OP_GUARDIAN_TLS_GET = 0x26; +uint8 constant OP_GUARDIAN_SHARDS_GET = 0x26; // Emitter address for the VerificationV2 contract bytes32 constant GOVERNANCE_ADDRESS = bytes32(0x0000000000000000000000000000000000000000000000000000000000000004); @@ -130,7 +130,6 @@ contract VerificationV2 is bytes32 tlsKey; uint8 guardianIndex; bytes32 r; bytes32 s; uint8 v; - // TODO: EIP-712 signature (guardianSetIndex, offset) = data.asUint32CdUnchecked(offset); (expirationTime, offset) = data.asUint32CdUnchecked(offset); (tlsKey, offset) = data.asBytes32CdUnchecked(offset); @@ -149,7 +148,7 @@ contract VerificationV2 is r, s, v ); - _registerTLSKey(guardianSetIndex, guardianIndex, tlsKey, guardianAddrs.length); + _registerTLSKey(guardianSetIndex, guardianIndex, tlsKey); } else { revert InvalidOperation(op); } @@ -214,25 +213,26 @@ contract VerificationV2 is result = abi.encodePacked(result, thresholdAddr, expirationTime); } else if (op == OP_GUARDIAN_SET_GET_CURRENT) { (uint32 guardianSetIndex, address[] memory guardianSetAddrs) = _getCurrentGuardianSetInfo(); - - result = abi.encodePacked(result, guardianSetAddrs, guardianSetIndex); + uint8 guardianCount = uint8(guardianSetAddrs.length); + + result = abi.encodePacked(result, guardianCount, guardianSetAddrs, guardianSetIndex); } else if (op == OP_GUARDIAN_SET_GET) { uint32 index; (index, offset) = data.asUint32CdUnchecked(offset); (uint32 expirationTime, address[] memory guardianSetAddrs) = _getGuardianSetInfo(index); + uint8 guardianCount = uint8(guardianSetAddrs.length); - result = abi.encodePacked(result, guardianSetAddrs, expirationTime); - } else if (op == OP_GUARDIAN_TLS_GET) { + result = abi.encodePacked(result, guardianCount, guardianSetAddrs, expirationTime); + } else if (op == OP_GUARDIAN_SHARDS_GET) { uint32 guardianSetIndex; - (guardianSetIndex, offset) = data.asUint32CdUnchecked(offset); - uint8 guardianIndex; + (guardianSetIndex, offset) = data.asUint32CdUnchecked(offset); (guardianIndex, offset) = data.asUint8CdUnchecked(offset); - bytes32[] memory tlsKeys = _getTLSKeys(guardianSetIndex); + (uint shardCount, bytes32[] memory shards) = _getShardsRaw(guardianSetIndex); - result = abi.encodePacked(result, tlsKeys); + result = abi.encodePacked(result, uint8(shardCount), shards); } else { revert InvalidOperation(op); } From 27045fb72011d7340aabfe2a48b5999cf8ec643c Mon Sep 17 00:00:00 2001 From: NoiTaTuM Date: Tue, 6 May 2025 13:52:21 -0300 Subject: [PATCH 25/53] Changed names according to the spec --- src/evm/EIP712Encoding.sol | 22 ++++++------- src/evm/GuardianRegistryVerification.sol | 14 ++++---- src/evm/GuardianSetVerification.sol | 22 ++++++------- src/evm/ThresholdVerification.sol | 2 +- src/evm/ThresholdVerificationState.sol | 19 ++++------- src/evm/VerificationV2.sol | 42 ++++++++++++------------ 6 files changed, 57 insertions(+), 64 deletions(-) diff --git a/src/evm/EIP712Encoding.sol b/src/evm/EIP712Encoding.sol index 81a4be1..97cb23a 100644 --- a/src/evm/EIP712Encoding.sol +++ b/src/evm/EIP712Encoding.sol @@ -14,8 +14,8 @@ contract EIP712Encoding { bytes32 constant EIP712_NAME_HASH = keccak256("Wormhole VerificationV2"); bytes32 constant EIP712_VERSION_HASH = keccak256("1"); - bytes32 constant TLS_TYPE_HASH = keccak256( - "TLSKeyRegister(uint32 guardianSetIndex,uint32 expirationTime,bytes32 tlsKey)" + bytes32 constant REGISTER_TYPE_HASH = keccak256( + "GuardianRegister(uint32 guardianSet,uint32 expirationTime,bytes32 id)" ); bytes32 private _domainSeparator; @@ -36,21 +36,21 @@ contract EIP712Encoding { )); } - function getRegisterTLSKeyHash( - uint32 guardianSetIndex, uint32 expirationTime, bytes32 tlsKey + function getRegisterGuardianHash( + uint32 guardianSet, uint32 expirationTime, bytes32 id ) internal pure returns (bytes32) { return keccak256(abi.encode( - TLS_TYPE_HASH, - guardianSetIndex, + REGISTER_TYPE_HASH, + guardianSet, expirationTime, - tlsKey + id )); } - function getRegisterTLSDigest( - uint32 guardianSetIndex, uint32 expirationTime, bytes32 tlsKey + function getRegisterGuardianDigest( + uint32 guardianSet, uint32 expirationTime, bytes32 id ) internal view returns (bytes32) { - bytes32 tlsHash = getRegisterTLSKeyHash(guardianSetIndex, expirationTime, tlsKey); - return keccak256(abi.encodePacked("\x19\x01", _domainSeparator, tlsHash)); + bytes32 idHash = getRegisterGuardianHash(guardianSet, expirationTime, id); + return keccak256(abi.encodePacked("\x19\x01", _domainSeparator, idHash)); } } \ No newline at end of file diff --git a/src/evm/GuardianRegistryVerification.sol b/src/evm/GuardianRegistryVerification.sol index 719a135..b812869 100644 --- a/src/evm/GuardianRegistryVerification.sol +++ b/src/evm/GuardianRegistryVerification.sol @@ -15,20 +15,18 @@ contract GuardianRegistryVerification is EIP712Encoding { error RegistrationMessageExpired(); error GuardianSignatureVerificationFailed(); - function _verifyRegisterTLSKey( + function _verifyRegisterGuardian( address[] memory guardianAddrs, - uint32 guardianSetIndex, + uint32 guardianSet, uint32 expirationTime, - bytes32 tlsKey, - uint8 guardianIndex, + bytes32 id, + uint8 guardian, bytes32 r, bytes32 s, uint8 v ) internal view { require(expirationTime > block.timestamp, RegistrationMessageExpired()); - bytes32 digest = getRegisterTLSDigest(guardianSetIndex, expirationTime, tlsKey); - + bytes32 digest = getRegisterGuardianDigest(guardianSet, expirationTime, id); // Verify the signature address signatory = ecrecover(digest, v, r, s); - address guardian = guardianAddrs[guardianIndex]; - require(signatory == guardian, GuardianSignatureVerificationFailed()); + require(signatory == guardianAddrs[guardian], GuardianSignatureVerificationFailed()); } } diff --git a/src/evm/GuardianSetVerification.sol b/src/evm/GuardianSetVerification.sol index 49882c9..9bcbf5d 100644 --- a/src/evm/GuardianSetVerification.sol +++ b/src/evm/GuardianSetVerification.sol @@ -26,18 +26,18 @@ contract GuardianSetVerification is GuardianSetVerificationState { unchecked { uint offset = 0; uint8 version; - uint32 guardianSetIndex; + uint32 guardianSet; uint signatureCount; (version, offset) = encodedVaa.asUint8CdUnchecked(offset); - (guardianSetIndex, offset) = encodedVaa.asUint32CdUnchecked(offset); + (guardianSet, offset) = encodedVaa.asUint32CdUnchecked(offset); (signatureCount, offset) = encodedVaa.asUint8CdUnchecked(offset); // Validate the version require(version == 1, VaaLib.InvalidVersion(version)); // Get the guardian set and the number of guardians - (, address[] memory guardians) = _getGuardianSetInfo(guardianSetIndex); + (, address[] memory guardians) = _getGuardianSetInfo(guardianSet); // Get the number of signatures // NOTE: Optimization puts guardianCount on stack thus avoids mloads @@ -56,16 +56,16 @@ contract GuardianSetVerification is GuardianSetVerificationState { // Verify the signatures // NOTE: Optimization instead of always checking i == 0 bool isFirstSignature = true; - uint prevGuardianIndex; + uint prevGuardian; for (uint i = 0; i < signatureCount; ++i) { // Decode the guardian index, r, s, and v - uint guardianIndex; bytes32 r; bytes32 s; uint8 v; - (guardianIndex, r, s, v, offset) = encodedVaa.decodeGuardianSignatureCdUnchecked(offset); + uint guardian; bytes32 r; bytes32 s; uint8 v; + (guardian, r, s, v, offset) = encodedVaa.decodeGuardianSignatureCdUnchecked(offset); // Verify the signature address signatory = ecrecover(vaaHash, v, r, s); - address guardian = guardians.readUnchecked(guardianIndex); + address guardianAddress = guardians.readUnchecked(guardian); // Check that: // * the guardian indicies are in strictly ascending order (only after the first signature) @@ -79,16 +79,16 @@ contract GuardianSetVerification is GuardianSetVerificationState { // [can never be the zero address](https://github.com/wormhole-foundation/wormhole/blob/1dbe8459b96e182932d0dd5ae4b6bbce6f48cb09/ethereum/contracts/Setters.sol#L20) bool failed = eagerOr( eagerOr( - !eagerOr(isFirstSignature, guardianIndex > prevGuardianIndex), - guardianIndex >= guardianCount + !eagerOr(isFirstSignature, guardian > prevGuardian), + guardian >= guardianCount ), - signatory != guardian + signatory != guardianAddress ); // Verify the signature require(!failed, GuardianSetSignatureVerificationFailed()); - prevGuardianIndex = guardianIndex; + prevGuardian = guardian; isFirstSignature = false; } } diff --git a/src/evm/ThresholdVerification.sol b/src/evm/ThresholdVerification.sol index 412096d..a8d1e21 100644 --- a/src/evm/ThresholdVerification.sol +++ b/src/evm/ThresholdVerification.sol @@ -113,7 +113,7 @@ contract ThresholdVerification is ThresholdVerificationState { function _decodeShardInfo(bytes calldata data, uint256 offset) internal pure returns (ShardInfo memory shardInfo, uint256 nextOffset) { (shardInfo.shard, offset) = data.asBytes32CdUnchecked(offset); - (shardInfo.tlsKey, offset) = data.asBytes32CdUnchecked(offset); + (shardInfo.id, offset) = data.asBytes32CdUnchecked(offset); return (shardInfo, offset); } } diff --git a/src/evm/ThresholdVerificationState.sol b/src/evm/ThresholdVerificationState.sol index de9606c..06a0de9 100644 --- a/src/evm/ThresholdVerificationState.sol +++ b/src/evm/ThresholdVerificationState.sol @@ -10,7 +10,7 @@ contract ThresholdVerificationState { struct ShardInfo { bytes32 shard; - bytes32 tlsKey; + bytes32 id; } // Current threshold info is stored in a single slot @@ -81,14 +81,14 @@ contract ThresholdVerificationState { } } - function _getShards(uint32 guardianSetIndex) internal view returns (ShardInfo[] memory shards) { - return _shards[guardianSetIndex]; + function _getShards(uint32 guardianSet) internal view returns (ShardInfo[] memory shards) { + return _shards[guardianSet]; } function _getShardsRaw( - uint32 guardianSetIndex + uint32 guardianSet ) internal view returns (uint shardCount, bytes32[] memory rawShards) { - ShardInfo[] memory shards = _getShards(guardianSetIndex); + ShardInfo[] memory shards = _getShards(guardianSet); shardCount = shards.length; assembly { rawShards := shards @@ -96,12 +96,7 @@ contract ThresholdVerificationState { } } - function _registerTLSKey( - uint32 guardianSetIndex, - uint8 guardianIndex, - bytes32 tlsKey - ) internal { - _shards[guardianSetIndex][guardianIndex].tlsKey = tlsKey; + function _registerGuardian(uint32 guardianSet, uint8 guardian, bytes32 id) internal { + _shards[guardianSet][guardian].id = id; } - } diff --git a/src/evm/VerificationV2.sol b/src/evm/VerificationV2.sol index e0ede63..096d3ea 100644 --- a/src/evm/VerificationV2.sol +++ b/src/evm/VerificationV2.sol @@ -13,7 +13,7 @@ import {GuardianRegistryVerification} from "./GuardianRegistryVerification.sol"; // Raw dispatch operation IDs for exec uint8 constant OP_GOVERNANCE = 0x00; uint8 constant OP_PULL_GUARDIAN_SETS = 0x01; -uint8 constant OP_REGISTER_TLS_KEY = 0x02; +uint8 constant OP_REGISTER_GUARDIAN = 0x02; // Raw dispatch operation IDs for get uint8 constant OP_VERIFY_AND_DECODE_VAA = 0x20; @@ -123,32 +123,32 @@ contract VerificationV2 is (limit, offset) = data.asUint32CdUnchecked(offset); _pullGuardianSets(limit); - } else if (op == OP_REGISTER_TLS_KEY) { + } else if (op == OP_REGISTER_GUARDIAN) { // Decode the payload - uint32 guardianSetIndex; + uint32 guardianSet; uint32 expirationTime; - bytes32 tlsKey; - uint8 guardianIndex; bytes32 r; bytes32 s; uint8 v; + bytes32 guardianId; + uint8 guardian; bytes32 r; bytes32 s; uint8 v; - (guardianSetIndex, offset) = data.asUint32CdUnchecked(offset); + (guardianSet, offset) = data.asUint32CdUnchecked(offset); (expirationTime, offset) = data.asUint32CdUnchecked(offset); - (tlsKey, offset) = data.asBytes32CdUnchecked(offset); - (guardianIndex, r, s, v, offset) = data.decodeGuardianSignatureCdUnchecked(offset); + (guardianId, offset) = data.asBytes32CdUnchecked(offset); + (guardian, r, s, v, offset) = data.decodeGuardianSignatureCdUnchecked(offset); // We only allow registrations for the current guardian set (uint32 currentSetIndex, address[] memory guardianAddrs) = _getCurrentGuardianSetInfo(); - require(guardianSetIndex == currentSetIndex, GuardianSetIsNotCurrent()); + require(guardianSet == currentSetIndex, GuardianSetIsNotCurrent()); - _verifyRegisterTLSKey( + _verifyRegisterGuardian( guardianAddrs, - guardianSetIndex, + guardianSet, expirationTime, - tlsKey, - guardianIndex, + guardianId, + guardian, r, s, v ); - _registerTLSKey(guardianSetIndex, guardianIndex, tlsKey); + _registerGuardian(guardianSet, guardian, guardianId); } else { revert InvalidOperation(op); } @@ -212,10 +212,10 @@ contract VerificationV2 is result = abi.encodePacked(result, thresholdAddr, expirationTime); } else if (op == OP_GUARDIAN_SET_GET_CURRENT) { - (uint32 guardianSetIndex, address[] memory guardianSetAddrs) = _getCurrentGuardianSetInfo(); + (uint32 guardianSet, address[] memory guardianSetAddrs) = _getCurrentGuardianSetInfo(); uint8 guardianCount = uint8(guardianSetAddrs.length); - result = abi.encodePacked(result, guardianCount, guardianSetAddrs, guardianSetIndex); + result = abi.encodePacked(result, guardianCount, guardianSetAddrs, guardianSet); } else if (op == OP_GUARDIAN_SET_GET) { uint32 index; (index, offset) = data.asUint32CdUnchecked(offset); @@ -225,12 +225,12 @@ contract VerificationV2 is result = abi.encodePacked(result, guardianCount, guardianSetAddrs, expirationTime); } else if (op == OP_GUARDIAN_SHARDS_GET) { - uint32 guardianSetIndex; - uint8 guardianIndex; - (guardianSetIndex, offset) = data.asUint32CdUnchecked(offset); - (guardianIndex, offset) = data.asUint8CdUnchecked(offset); + uint32 guardianSet; + uint8 guardian; + (guardianSet, offset) = data.asUint32CdUnchecked(offset); + (guardian, offset) = data.asUint8CdUnchecked(offset); - (uint shardCount, bytes32[] memory shards) = _getShardsRaw(guardianSetIndex); + (uint shardCount, bytes32[] memory shards) = _getShardsRaw(guardianSet); result = abi.encodePacked(result, uint8(shardCount), shards); } else { From b9f78476386695e2e8eb3aedb99195223a881d3a Mon Sep 17 00:00:00 2001 From: Joshua Averett Date: Tue, 6 May 2025 14:37:41 -0700 Subject: [PATCH 26/53] Try to send a TSS update VAA for testing --- src/solana/tests/testing_helpers.ts | 33 ++++++--- src/solana/tests/verification_v2.ts | 105 ++++++++++++++++++++-------- 2 files changed, 102 insertions(+), 36 deletions(-) diff --git a/src/solana/tests/testing_helpers.ts b/src/solana/tests/testing_helpers.ts index d9a054b..14d517b 100644 --- a/src/solana/tests/testing_helpers.ts +++ b/src/solana/tests/testing_helpers.ts @@ -1,12 +1,6 @@ - - -import * as fs from "fs" -import * as toml from "toml" - import { Connection, LAMPORTS_PER_SOL, PublicKey, Signer, Transaction, TransactionInstruction, ComputeBudgetProgram, sendAndConfirmTransaction } from "@solana/web3.js" import { NodeWallet, postVaaSolana, signSendAndConfirmTransaction } from "@certusone/wormhole-sdk/lib/cjs/solana" import { MockGuardians } from "@certusone/wormhole-sdk/lib/cjs/mock" -import { CONTRACTS } from "@certusone/wormhole-sdk"; import { expect, use as chaiUse } from "chai" import chaiAsPromised from "chai-as-promised" @@ -48,9 +42,8 @@ export const boilerPlateReduction = (connection: Connection, defaultSigner: Sign const guardianSign = (message: Buffer) => MOCK_GUARDIANS.addSignatures(message, [0]) - const postSignedMsgAsVaaOnSolana = async (signedMsg: Buffer, payer?: Signer) => { + const postSignedMsgAsVaaOnSolana = async (coreV1: PublicKey, signedMsg: Buffer, payer?: Signer) => { const wallet = payerToWallet(payer); - const coreV1 = new PublicKey(CONTRACTS.DEVNET.solana.core); await postVaaSolana( connection, wallet.signTransaction, @@ -130,6 +123,12 @@ export const boilerPlateReduction = (connection: Connection, defaultSigner: Sign )).to.be.fulfilled; } + const signAndPost = async (coreV1: PublicKey, message: Buffer, payer?: Signer) => { + const signedMsg = guardianSign(message); + await postSignedMsgAsVaaOnSolana(coreV1, signedMsg, payer); + return signedMsg; + }; + return { requestAirdrop, guardianSign, @@ -138,5 +137,23 @@ export const boilerPlateReduction = (connection: Connection, defaultSigner: Sign expectIxToSucceed, expectIxToFailWithError, expectTxToSucceed, + signAndPost, + }; +} + +export function findPda(programId: PublicKey, seeds: Array) { + const [address, bump] = PublicKey.findProgramAddressSync( + seeds.map((seed) => { + if (typeof seed === 'string') { + return Buffer.from(seed); + } else { + return seed; + } + }), + programId, + ); + return { + address, + bump, }; } diff --git a/src/solana/tests/verification_v2.ts b/src/solana/tests/verification_v2.ts index 51beab9..9234181 100644 --- a/src/solana/tests/verification_v2.ts +++ b/src/solana/tests/verification_v2.ts @@ -1,18 +1,22 @@ import assert from "assert" import * as anchor from "@coral-xyz/anchor" -import { PublicKey } from "@solana/web3.js" +import { Keypair, PublicKey, SendTransactionError, Transaction, TransactionMessage, VersionedTransaction } from "@solana/web3.js" import { VerificationV2 } from "../target/types/verification_v2.js" import { MockGuardians } from "@certusone/wormhole-sdk/lib/cjs/mock" import * as coreV1 from "@certusone/wormhole-sdk/lib/cjs/solana/wormhole"; -import { sign } from "@noble/secp256k1" +import { getPublicKey, sign } from "@noble/secp256k1" import { keccak_256 } from "@noble/hashes/sha3" -import { boilerPlateReduction } from "./testing_helpers.js" +import { boilerPlateReduction, findPda } from "./testing_helpers.js" import { Program } from "@coral-xyz/anchor" -import { CONTRACTS } from "@certusone/wormhole-sdk" +import { randomBytes } from "@noble/hashes/utils" +import { createPostSignedVaaTransactions } from "@certusone/wormhole-sdk/lib/cjs/solana/sendAndConfirmPostVaa.js" +import { parseVaa } from "@certusone/wormhole-sdk" +import { createPostVaaInstructionSolana } from "@certusone/wormhole-sdk/lib/cjs/solana/index.js" +import { deriveGuardianSetKey } from "@certusone/wormhole-sdk/lib/cjs/solana/wormhole" const encodeU16BE = (value: number) => [value >> 8, value & 0xFF] @@ -94,43 +98,88 @@ const connection = anchor.getProvider().connection const payer = anchor.getProvider().wallet?.payer assert(payer, "Payer not found") -const mockGuardians = new MockGuardians(0, ["cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0"]) - -const coreV2 = anchor.workspace.VerificationV2 as Program - const { requestAirdrop, guardianSign, postSignedMsgAsVaaOnSolana, expectIxToSucceed, expectIxToFailWithError, + signAndPost, } = boilerPlateReduction(connection, payer) -const guardianSetExpirationTime = 86400 -const fee = 100n -const devnetGuardian = mockGuardians.getPublicKeys()[0] -const initialGuardians = [devnetGuardian] const coreV1Address = new PublicKey('worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth') +const mockGuardians = new MockGuardians(0, ["cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0"]) +const guardianSetExpirationTime = 86400 + +{ + const fee = 100n + const devnetGuardian = mockGuardians.getPublicKeys()[0] + const initialGuardians = [devnetGuardian] + + await expectIxToSucceed( + coreV1.createInitializeInstruction( + coreV1Address, + payer.publicKey, + guardianSetExpirationTime, + fee, + initialGuardians, + ) + ) + + const accounts = await connection.getProgramAccounts(coreV1Address) + assert(accounts.length === 2, "Expected 2 accounts") + + const info = await coreV1.getWormholeBridgeData(connection, coreV1Address) + assert(info.guardianSetIndex === 0, "Expected guardian set index to be 0") + assert(info.config.guardianSetExpirationTime === guardianSetExpirationTime, "Expected guardian set expiration time to be 86400") + assert(info.config.fee === fee, "Expected fee to be 100") + + const guardianSet = await coreV1.getGuardianSet(connection, coreV1Address, info.guardianSetIndex) + assert(guardianSet.index === 0, "Expected guardian set index to be 0") + assert(guardianSet.keys.length === 1, "Expected guardian set keys to have length 1") + assert(devnetGuardian.equals(guardianSet.keys[0]), "Expected guardian set keys to be the devnet guardian") +} -await expectIxToSucceed( - coreV1.createInitializeInstruction( +const coreV2 = anchor.workspace.VerificationV2 as Program + +const guardianPrivateKey = randomBytes(32) +const guardianPublicKey = keccak_256(getPublicKey(guardianPrivateKey)).slice(12) + +{ + const message = createAppendThresholdKeyMessage( + 0, + guardianPublicKey, + guardianSetExpirationTime, + ) + + const signedVaa = await guardianSign(Buffer.from(message)) + + const signatureSet = Keypair.generate() + + const verifySignaturesInstructions = await coreV1.createVerifySignaturesInstructions( + connection, coreV1Address, payer.publicKey, - guardianSetExpirationTime, - fee, - initialGuardians, + signedVaa, + signatureSet.publicKey, ) -) -const accounts = await connection.getProgramAccounts(coreV1Address) -assert(accounts.length === 2, "Expected 2 accounts") + for (let i = 0; i < verifySignaturesInstructions.length; i += 2) { + const tx = new Transaction().add(...verifySignaturesInstructions.slice(i, i + 2)) + tx.feePayer = payer.publicKey + const txSig = await connection.sendTransaction(tx, [payer, signatureSet]) + assert(txSig, "Expected tx to succeed") + } -const info = await coreV1.getWormholeBridgeData(connection, coreV1Address) -assert(info.guardianSetIndex === 0, "Expected guardian set index to be 0") -assert(info.config.guardianSetExpirationTime === guardianSetExpirationTime, "Expected guardian set expiration time to be 86400") -assert(info.config.fee === fee, "Expected fee to be 100") + const postVaaInstruction = createPostVaaInstructionSolana( + coreV1Address, + payer.publicKey, + signedVaa, + signatureSet.publicKey, + ) -const guardianSet = await coreV1.getGuardianSet(connection, coreV1Address, info.guardianSetIndex) -assert(guardianSet.index === 0, "Expected guardian set index to be 0") -assert(guardianSet.keys.length === 1, "Expected guardian set keys to have length 1") -assert(devnetGuardian.equals(guardianSet.keys[0]), "Expected guardian set keys to be the devnet guardian") + const postVaaTx = new Transaction().add(postVaaInstruction) + postVaaTx.feePayer = payer.publicKey + const postVaaSig = await connection.sendTransaction(postVaaTx, [payer]) + assert(postVaaSig, "Expected postVaa tx to succeed") +} From bb49a582faa5612914ae76493dcd43f69c0f5b20 Mon Sep 17 00:00:00 2001 From: Joshua Averett Date: Mon, 12 May 2025 15:27:33 -0700 Subject: [PATCH 27/53] Use Schnorr signatures --- src/evm/ThresholdVerification.sol | 61 +++++++----- src/evm/ThresholdVerificationState.sol | 123 +++++++++++++++---------- src/evm/VerificationV2.sol | 8 +- 3 files changed, 117 insertions(+), 75 deletions(-) diff --git a/src/evm/ThresholdVerification.sol b/src/evm/ThresholdVerification.sol index a8d1e21..b63f41c 100644 --- a/src/evm/ThresholdVerification.sol +++ b/src/evm/ThresholdVerification.sol @@ -6,19 +6,21 @@ import "wormhole-sdk/libraries/BytesParsing.sol"; import "wormhole-sdk/libraries/VaaLib.sol"; import "./ThresholdVerificationState.sol"; -// Module ID for the VerificationV2 contract, ASCII "TSS" -bytes32 constant MODULE_VERIFICATION_V2 = bytes32(0x0000000000000000000000000000000000000000000000000000000000545353); - -// Action ID for appending a threshold key -uint8 constant ACTION_APPEND_THRESHOLD_KEY = 0x01; - -uint constant VAA_V2_HEADER_SIZE = 1 + 4 + 32 + 32 + 1; - contract ThresholdVerification is ThresholdVerificationState { using BytesParsing for bytes; using VaaLib for bytes; using {BytesParsing.checkLength} for uint; + + // Module ID for the VerificationV2 contract, ASCII "TSS" + bytes32 constant MODULE_VERIFICATION_V2 = bytes32(0x0000000000000000000000000000000000000000000000000000000000545353); + + // Action ID for appending a threshold key + uint8 constant ACTION_APPEND_THRESHOLD_KEY = 0x01; + + // Curve order for secp256k1 + uint256 constant public Q = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141; + error ThresholdKeyExpired(); error ThresholdSignatureVerificationFailed(); error InvalidModule(bytes32 module); @@ -31,20 +33,39 @@ contract ThresholdVerification is ThresholdVerificationState { uint offset = 0; uint8 version; uint32 tssIndex; - bytes32 r; bytes32 s; uint8 v; + address r; uint256 s; (version, offset) = encodedVaa.asUint8CdUnchecked(offset); (tssIndex, offset) = encodedVaa.asUint32CdUnchecked(offset); - (r, s, v, offset) = _decodeThresholdSignatureCdUnchecked(encodedVaa, offset); + (r, s, offset) = _decodeThresholdSignatureCdUnchecked(encodedVaa, offset); - // Validate and return the VAA body + // Validate the VAA version require(version == 2, VaaLib.InvalidVersion(version)); - (address thresholdAddr, uint32 expirationTime) = _getThresholdInfo(tssIndex); + // Validate the threshold key expiration time + (uint256 pubkey, uint32 expirationTime) = _getThresholdInfo(tssIndex); require(expirationTime > block.timestamp, ThresholdKeyExpired()); + // Get the message hash bytes32 vaaHash = encodedVaa.calcVaaDoubleHashCd(offset); - require(ecrecover(vaaHash, v, r, s) == thresholdAddr, ThresholdSignatureVerificationFailed()); + + // Extract the parity and public key + uint8 parity = (pubkey & 1) != 0 ? 28 : 27; + uint256 px = pubkey >> 1; + + // Validate the threshold signature + bytes32 e = keccak256(abi.encodePacked(r, pubkey, vaaHash)); + bytes32 sp = bytes32(Q - mulmod(s, px, Q)); + bytes32 ep = bytes32(Q - mulmod(uint256(e), px, Q)); + require(sp != 0, ThresholdSignatureVerificationFailed()); + + // the ecrecover precompile implementation checks that the `r` and `s` + // inputs are non-zero (in this case, `px` and `ep`), thus we don't need to + // check if they're zero. + address R = ecrecover(sp, parity, bytes32(px), ep); + require(R != address(0), ThresholdSignatureVerificationFailed()); + bytes32 expected = keccak256(abi.encodePacked(R, pubkey, vaaHash)); + require(e == expected, ThresholdSignatureVerificationFailed()); return offset; } @@ -66,19 +87,17 @@ contract ThresholdVerification is ThresholdVerificationState { function _decodeThresholdSignatureCdUnchecked( bytes calldata encodedVaa, uint offset - ) internal pure returns (bytes32 r, bytes32 s, uint8 v, uint nextOffset) { + ) internal pure returns (address r, uint256 s, uint nextOffset) { unchecked { - (r, offset) = encodedVaa.asBytes32CdUnchecked(offset); - (s, offset) = encodedVaa.asBytes32CdUnchecked(offset); - (v, offset) = encodedVaa.asUint8CdUnchecked(offset); - v += VaaLib.SIGNATURE_RECOVERY_MAGIC; - return (r, s, v, offset); + (r, offset) = encodedVaa.asAddressCdUnchecked(offset); + (s, offset) = encodedVaa.asUint256CdUnchecked(offset); + return (r, s, offset); } } function _decodeThresholdKeyUpdatePayload(bytes calldata payload) internal pure returns ( uint32 newThresholdIndex, - address newThresholdAddr, + uint256 newThresholdAddr, uint32 expirationDelaySeconds, ShardInfo[] memory shards ) { @@ -92,7 +111,7 @@ contract ThresholdVerification is ThresholdVerificationState { (module, offset) = payload.asBytes32MemUnchecked(offset); (action, offset) = payload.asUint8MemUnchecked(offset); (newThresholdIndex, offset) = payload.asUint32MemUnchecked(offset); - (newThresholdAddr, offset) = payload.asAddressMemUnchecked(offset); + (newThresholdAddr, offset) = payload.asUint256MemUnchecked(offset); (expirationDelaySeconds, offset) = payload.asUint32MemUnchecked(offset); (shardCount, offset) = payload.asUint8MemUnchecked(offset); // TODO: We should probably pass this in and get it from the guardian set to ensure the mapping is correct diff --git a/src/evm/ThresholdVerificationState.sol b/src/evm/ThresholdVerificationState.sol index 06a0de9..64e04b4 100644 --- a/src/evm/ThresholdVerificationState.sol +++ b/src/evm/ThresholdVerificationState.sol @@ -3,86 +3,80 @@ pragma solidity ^0.8.0; contract ThresholdVerificationState { - uint256 constant SHARD_INFO_SIZE = 32 + 32; - error InvalidThresholdKeyIndex(); error InvalidThresholdKeyAddress(); + error InvalidGuardianIndex(); struct ShardInfo { bytes32 shard; bytes32 id; } - // Current threshold info is stored in a single slot - // Format: - // index (32 bits) - // address (160 bits) - uint256 private _currentThresholdInfo; - - // Past threshold info is stored in an array - // Format: - // expiration time (32 bits) - // address (160 bits) - uint256[] private _pastThresholdInfo; - - ShardInfo[][] private _shards; - - function _decodeThresholdInfo(uint256 info) private pure returns (address addr, uint32 index) { - return (address(uint160(info >> 32)), uint32(info & 0xFFFFFFFF)); - } - - function _encodeThresholdInfo(address addr, uint32 index) private pure returns (uint256) { - return (uint256(uint160(addr)) << 32) | uint256(index); - } + // Threshold data is stored in a single array with stride 2: + // pubkey (32 bytes) + // expiration time (4 bytes) + // shard base (5 bytes) + // shard count (1 byte) + uint256[] private _thresholdData; + bytes32[] private _shardData; // Get the current threshold signature info - function _getCurrentThresholdInfo() internal view returns (address addr, uint32 index) { - return _decodeThresholdInfo(_currentThresholdInfo); - } - - // Get the past threshold signature info - function _getPastThresholdInfo(uint32 index) internal view returns ( - address addr, - uint32 expirationTime - ) { - require(index < _pastThresholdInfo.length, InvalidThresholdKeyIndex()); - return _decodeThresholdInfo(_pastThresholdInfo[index]); + function _getCurrentThresholdInfo() internal view returns (uint256 pubkey, uint32 index) { + unchecked { + uint256 length = _thresholdData.length; + // NOTE: We assume that at least one threshold key has been set + pubkey = _thresholdData[length - 2]; + index = uint32(length >> 1); + } } - function _getThresholdInfo(uint32 index) internal view returns (address thresholdAddr, uint32 expirationTime) { - (address currentAddr, uint32 currentIndex) = _getCurrentThresholdInfo(); - return index == currentIndex ? (currentAddr, 0) : _getPastThresholdInfo(index); + function _getThresholdInfo(uint32 index) internal view returns (uint256 pubkey, uint32 expirationTime) { + uint256 offset = index << 1; + require(offset < _thresholdData.length, InvalidThresholdKeyIndex()); + pubkey = _thresholdData[offset]; + expirationTime = _thresholdDataExpirationTime(_thresholdData[offset + 1]); } function _appendThresholdKey( uint32 newIndex, - address newAddr, + uint256 pubkey, uint32 expirationDelaySeconds, ShardInfo[] memory shards ) internal { unchecked { // Verify the new address is not the zero address // This prevents errors from ecrecover returning the zero address - require(newAddr != address(0), InvalidThresholdKeyAddress()); + require(pubkey != 0, InvalidThresholdKeyAddress()); // Get the current threshold info and verify the new index is sequential - (address currentAddr, uint32 index) = _getCurrentThresholdInfo(); + (, uint32 index) = _getCurrentThresholdInfo(); require(newIndex == index + 1, InvalidThresholdKeyIndex()); // Store the expiration time and current threshold address in past threshold info uint32 expirationTime = uint32(block.timestamp) + expirationDelaySeconds; - _pastThresholdInfo.push(_encodeThresholdInfo(currentAddr, expirationTime)); + _setThresholdDataExpirationTime(index, expirationTime); - // Update the current threshold info - _currentThresholdInfo = _encodeThresholdInfo(newAddr, newIndex); - - // Push the shards - _shards.push(shards); + // Store the new threshold info + _thresholdData.push(pubkey); + _thresholdData.push(_createThresholdData(uint8(shards.length), uint40(_shardData.length))); } } - function _getShards(uint32 guardianSet) internal view returns (ShardInfo[] memory shards) { - return _shards[guardianSet]; + function _getShards(uint32 guardianSet) internal view returns (ShardInfo[] memory) { + unchecked { + uint256 offset = guardianSet << 1; + require(offset < _thresholdData.length, InvalidThresholdKeyIndex()); + (uint8 shardCount, uint40 shardBase) = _thresholdDataShardSlice(_thresholdData[offset + 1]); + + ShardInfo[] memory shards = new ShardInfo[](shardCount); + uint256 ptr = shardBase; + for (uint256 i = 0; i < shardCount; i++) { + shards[i].shard = _shardData[ptr++]; + shards[i].id = _shardData[ptr++]; + } + + return shards; + } } function _getShardsRaw( @@ -90,13 +84,42 @@ contract ThresholdVerificationState { ) internal view returns (uint shardCount, bytes32[] memory rawShards) { ShardInfo[] memory shards = _getShards(guardianSet); shardCount = shards.length; - assembly { + assembly ("memory-safe") { rawShards := shards mstore(rawShards, mul(shardCount, 2)) } } function _registerGuardian(uint32 guardianSet, uint8 guardian, bytes32 id) internal { - _shards[guardianSet][guardian].id = id; + unchecked { + uint256 offset = guardianSet << 1; + require(offset < _thresholdData.length, InvalidThresholdKeyIndex()); + (uint8 shardCount, uint40 shardBase) = _thresholdDataShardSlice(_thresholdData[offset + 1]); + require(guardian < shardCount, InvalidGuardianIndex()); + _shardData[shardBase + (guardian << 1)] = id; + } + } + + function _createThresholdData(uint8 shardCount, uint40 shardBase) internal pure returns (uint256) { + return (shardCount << 32) | (shardBase << 40); + } + + function _thresholdDataExpirationTime(uint256 data) internal pure returns (uint32) { + unchecked { + return uint32(data & 0xFFFFFFFF); + } + } + + function _thresholdDataShardSlice(uint256 data) internal pure returns (uint8 shardCount, uint40 shardBase) { + unchecked { + shardCount = uint8((data >> 32) & 0xFF); + shardBase = uint40(data >> 40); + } + } + + function _setThresholdDataExpirationTime(uint32 index, uint32 expirationTime) internal { + unchecked { + _thresholdData[index << 1] |= expirationTime; + } } } diff --git a/src/evm/VerificationV2.sol b/src/evm/VerificationV2.sol index 096d3ea..4c437be 100644 --- a/src/evm/VerificationV2.sol +++ b/src/evm/VerificationV2.sol @@ -79,7 +79,7 @@ contract VerificationV2 is } function _exec(bytes calldata data) internal override returns (bytes memory) { - if (msg.value != 0) revert InvalidValue(); + require(msg.value == 0, InvalidValue()); uint offset = 0; while (offset < data.length) { @@ -111,7 +111,7 @@ contract VerificationV2 is // Decode the payload ( uint32 newThresholdIndex, - address newThresholdAddr, + uint256 newThresholdAddr, uint32 expirationDelaySeconds, ShardInfo[] memory shards ) = _decodeThresholdKeyUpdatePayload(payload); @@ -201,14 +201,14 @@ contract VerificationV2 is // Verify the VAA _verifyVaa(encodedVaa); } else if (op == OP_THRESHOLD_GET_CURRENT) { - (address thresholdAddr, uint32 thresholdIndex) = _getCurrentThresholdInfo(); + (uint256 thresholdAddr, uint32 thresholdIndex) = _getCurrentThresholdInfo(); result = abi.encodePacked(result, thresholdAddr, thresholdIndex); } else if (op == OP_THRESHOLD_GET) { uint32 index; (index, offset) = data.asUint32CdUnchecked(offset); - (address thresholdAddr, uint32 expirationTime) = _getPastThresholdInfo(index); + (uint256 thresholdAddr, uint32 expirationTime) = _getThresholdInfo(index); result = abi.encodePacked(result, thresholdAddr, expirationTime); } else if (op == OP_GUARDIAN_SET_GET_CURRENT) { From 7f79de3c0af37a5fd384e01067c00571b899d5b9 Mon Sep 17 00:00:00 2001 From: Joshua Averett Date: Wed, 14 May 2025 20:09:51 -0700 Subject: [PATCH 28/53] Updated to use Chainlink signature scheme --- src/evm/ThresholdVerification.sol | 46 +++++++++++++++++--------- src/evm/ThresholdVerificationState.sol | 12 ++++--- 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/src/evm/ThresholdVerification.sol b/src/evm/ThresholdVerification.sol index b63f41c..1589ebb 100644 --- a/src/evm/ThresholdVerification.sol +++ b/src/evm/ThresholdVerification.sol @@ -20,6 +20,7 @@ contract ThresholdVerification is ThresholdVerificationState { // Curve order for secp256k1 uint256 constant public Q = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141; + uint256 constant public HALF_Q = Q >> 1; error ThresholdKeyExpired(); error ThresholdSignatureVerificationFailed(); @@ -42,30 +43,34 @@ contract ThresholdVerification is ThresholdVerificationState { // Validate the VAA version require(version == 2, VaaLib.InvalidVersion(version)); + // Validate the threshold signature + // NOTE: The first condition prevents signature malleability from multiple representations for ℤ/Qℤ elements + require(s < Q, ThresholdSignatureVerificationFailed()); + require(r != address(0), ThresholdSignatureVerificationFailed()); + require(s != 0, ThresholdSignatureVerificationFailed()); + // Validate the threshold key expiration time (uint256 pubkey, uint32 expirationTime) = _getThresholdInfo(tssIndex); require(expirationTime > block.timestamp, ThresholdKeyExpired()); - // Get the message hash + // Get the message hash and public key data bytes32 vaaHash = encodedVaa.calcVaaDoubleHashCd(offset); + (uint256 px, bool parity) = _decodePubkey(pubkey); - // Extract the parity and public key - uint8 parity = (pubkey & 1) != 0 ? 28 : 27; - uint256 px = pubkey >> 1; + // Calculate the challenge value + uint256 e = uint256(keccak256(abi.encodePacked(px, parity, vaaHash, r))); - // Validate the threshold signature - bytes32 e = keccak256(abi.encodePacked(r, pubkey, vaaHash)); - bytes32 sp = bytes32(Q - mulmod(s, px, Q)); - bytes32 ep = bytes32(Q - mulmod(uint256(e), px, Q)); + // Calculate the recovery inputs, ensuring that sp(the unchecked input for ecrecover) is non-zero + bytes32 sp = bytes32(Q - mulmod(px, s, Q)); + bytes32 ep = bytes32(mulmod(e, px, Q)); require(sp != 0, ThresholdSignatureVerificationFailed()); - // the ecrecover precompile implementation checks that the `r` and `s` + // The ecrecover precompile implementation checks that the `r` and `s` // inputs are non-zero (in this case, `px` and `ep`), thus we don't need to - // check if they're zero. - address R = ecrecover(sp, parity, bytes32(px), ep); - require(R != address(0), ThresholdSignatureVerificationFailed()); - bytes32 expected = keccak256(abi.encodePacked(R, pubkey, vaaHash)); - require(e == expected, ThresholdSignatureVerificationFailed()); + // check if they're zero. We additionally know that px is non-zero because + // it's checked in the _appendThresholdKey function. + address recovered = ecrecover(sp, parity ? 28 : 27, bytes32(px), ep); + require(r == recovered, ThresholdSignatureVerificationFailed()); return offset; } @@ -97,7 +102,7 @@ contract ThresholdVerification is ThresholdVerificationState { function _decodeThresholdKeyUpdatePayload(bytes calldata payload) internal pure returns ( uint32 newThresholdIndex, - uint256 newThresholdAddr, + uint256 newThresholdPubkey, uint32 expirationDelaySeconds, ShardInfo[] memory shards ) { @@ -111,10 +116,14 @@ contract ThresholdVerification is ThresholdVerificationState { (module, offset) = payload.asBytes32MemUnchecked(offset); (action, offset) = payload.asUint8MemUnchecked(offset); (newThresholdIndex, offset) = payload.asUint32MemUnchecked(offset); - (newThresholdAddr, offset) = payload.asUint256MemUnchecked(offset); + (newThresholdPubkey, offset) = payload.asUint256MemUnchecked(offset); (expirationDelaySeconds, offset) = payload.asUint32MemUnchecked(offset); (shardCount, offset) = payload.asUint8MemUnchecked(offset); // TODO: We should probably pass this in and get it from the guardian set to ensure the mapping is correct + // Validate the threshold key is less than HALF_Q + (uint256 px,) = _decodePubkey(newThresholdPubkey); + require(px <= HALF_Q, InvalidThresholdKeyAddress()); + // Decode shards shards = new ShardInfo[](shardCount); for (uint i = 0; i < shardCount; i++) { @@ -135,4 +144,9 @@ contract ThresholdVerification is ThresholdVerificationState { (shardInfo.id, offset) = data.asBytes32CdUnchecked(offset); return (shardInfo, offset); } + + function _decodePubkey(uint256 pubkey) internal pure returns (uint256 px, bool parity) { + parity = (pubkey & 1) != 0; + px = pubkey >> 1; + } } diff --git a/src/evm/ThresholdVerificationState.sol b/src/evm/ThresholdVerificationState.sol index 64e04b4..0b56d1a 100644 --- a/src/evm/ThresholdVerificationState.sol +++ b/src/evm/ThresholdVerificationState.sol @@ -31,10 +31,12 @@ contract ThresholdVerificationState { } function _getThresholdInfo(uint32 index) internal view returns (uint256 pubkey, uint32 expirationTime) { - uint256 offset = index << 1; - require(offset < _thresholdData.length, InvalidThresholdKeyIndex()); - pubkey = _thresholdData[offset]; - expirationTime = _thresholdDataExpirationTime(_thresholdData[offset + 1]); + unchecked { + uint256 offset = index << 1; + require(offset < _thresholdData.length, InvalidThresholdKeyIndex()); + pubkey = _thresholdData[offset]; + expirationTime = _thresholdDataExpirationTime(_thresholdData[offset + 1]); + } } function _appendThresholdKey( @@ -46,6 +48,8 @@ contract ThresholdVerificationState { unchecked { // Verify the new address is not the zero address // This prevents errors from ecrecover returning the zero address + // NOTE: This is actually already checked in ecrecover, but there's no harm in preventing that case here + // NOTE: The pubkey is also known to be <= HALF_Q, based on the decoding in _decodeThresholdKeyUpdatePayload require(pubkey != 0, InvalidThresholdKeyAddress()); // Get the current threshold info and verify the new index is sequential From aa1177200e3f7e9b43ecc3fa663e891061ea47a8 Mon Sep 17 00:00:00 2001 From: Joshua Averett Date: Tue, 20 May 2025 12:33:56 -0700 Subject: [PATCH 29/53] Big refactor and switch to schnorr --- src/evm/ThresholdVerification.sol | 1 + src/solana/Cargo.lock | 173 ++++++++++++++++ .../programs/verification_v2/Cargo.toml | 1 + .../src/append_threshold_key_message.rs | 7 +- .../programs/verification_v2/src/lib.rs | 86 ++++---- .../verification_v2/src/threshold_key.rs | 125 ++++++++++++ .../programs/verification_v2/src/vaa.rs | 190 +++++++++++------- 7 files changed, 466 insertions(+), 117 deletions(-) create mode 100644 src/solana/programs/verification_v2/src/threshold_key.rs diff --git a/src/evm/ThresholdVerification.sol b/src/evm/ThresholdVerification.sol index 1589ebb..c41f5b3 100644 --- a/src/evm/ThresholdVerification.sol +++ b/src/evm/ThresholdVerification.sol @@ -122,6 +122,7 @@ contract ThresholdVerification is ThresholdVerificationState { // Validate the threshold key is less than HALF_Q (uint256 px,) = _decodePubkey(newThresholdPubkey); + require(px != 0, InvalidThresholdKeyAddress()); require(px <= HALF_Q, InvalidThresholdKeyAddress()); // Decode shards diff --git a/src/solana/Cargo.lock b/src/solana/Cargo.lock index e6be5df..ac9f875 100644 --- a/src/solana/Cargo.lock +++ b/src/solana/Cargo.lock @@ -311,6 +311,18 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "blake3" version = "1.8.2" @@ -436,6 +448,12 @@ dependencies = [ "serde", ] +[[package]] +name = "byte-slice-cast" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7575182f7272186991736b70173b0ea045398f984bf5ebbb3804736ce1330c9d" + [[package]] name = "bytemuck" version = "1.22.0" @@ -523,6 +541,26 @@ dependencies = [ "web-sys", ] +[[package]] +name = "const_format" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126f97965c8ad46d6d9163268ff28432e8f6a1196a55578867832e3049df63dd" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + [[package]] name = "constant_time_eq" version = "0.3.1" @@ -668,12 +706,30 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2551bf44bc5f776c15044b9b94153a00198be06743e262afaaa61f11ac7523a5" +[[package]] +name = "fixed-hash" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" +dependencies = [ + "byteorder", + "rand 0.8.5", + "rustc-hex", + "static_assertions", +] + [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + [[package]] name = "generic-array" version = "0.14.7" @@ -732,6 +788,12 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "hmac" version = "0.8.1" @@ -762,6 +824,26 @@ dependencies = [ "hmac 0.8.1", ] +[[package]] +name = "impl-codec" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d40b9d5e17727407e55028eafc22b2dc68781786e6d7eb8a21103f5058e3a14" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "indexmap" version = "2.9.0" @@ -1060,6 +1142,34 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" +[[package]] +name = "parity-scale-codec" +version = "3.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799781ae679d79a948e13d4824a40970bfa500058d245760dd857301059810fa" +dependencies = [ + "arrayvec", + "bitvec", + "byte-slice-cast", + "const_format", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "rustversion", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34b4653168b563151153c9e4c08ebed57fb8262bebfa79711552fa983c623e7a" +dependencies = [ + "proc-macro-crate 3.3.0", + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "parking_lot" version = "0.12.3" @@ -1119,6 +1229,17 @@ dependencies = [ "zerocopy 0.8.24", ] +[[package]] +name = "primitive-types" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d15600a7d856470b7d278b3fe0e311fe28c2526348549f8ef2ff7db3299c87f5" +dependencies = [ + "fixed-hash", + "impl-codec", + "uint", +] + [[package]] name = "proc-macro-crate" version = "0.1.5" @@ -1164,6 +1285,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + [[package]] name = "rand" version = "0.7.3" @@ -1273,6 +1400,12 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + [[package]] name = "rustc_version" version = "0.4.1" @@ -2624,6 +2757,12 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "subtle" version = "2.6.1" @@ -2652,6 +2791,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "thiserror" version = "1.0.69" @@ -2756,6 +2901,18 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +[[package]] +name = "uint" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "909988d098b2f738727b161a106cfc7cab00c539c2687a8836f8e565976fb53e" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + [[package]] name = "unicode-ident" version = "1.0.18" @@ -2768,6 +2925,12 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + [[package]] name = "universal-hash" version = "0.5.1" @@ -2795,6 +2958,7 @@ dependencies = [ "anchor-lang", "byteorder", "libsecp256k1 0.7.2", + "primitive-types", "wormhole-anchor-sdk", ] @@ -2974,6 +3138,15 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b021a14ea7bcef9517ed9f81d4466c4a663dd90e726c5724707a976fa83ad8f3" +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + [[package]] name = "zerocopy" version = "0.7.35" diff --git a/src/solana/programs/verification_v2/Cargo.toml b/src/solana/programs/verification_v2/Cargo.toml index f1949c5..702413b 100644 --- a/src/solana/programs/verification_v2/Cargo.toml +++ b/src/solana/programs/verification_v2/Cargo.toml @@ -26,5 +26,6 @@ idl-build = [ anchor-lang = "0.31.1" byteorder = "1.5.0" libsecp256k1 = "0.7.2" +primitive-types = "0.13.1" # wormhole-anchor-sdk = { git = "https://github.com/wormhole-foundation/wormhole-scaffolding.git", default-features = false } wormhole-anchor-sdk = { git = "https://github.com/XLabs/wormhole-scaffolding.git", rev = "c008cf26c2449b914911a19ecbf8630fd9b4f5b5", default-features = false } diff --git a/src/solana/programs/verification_v2/src/append_threshold_key_message.rs b/src/solana/programs/verification_v2/src/append_threshold_key_message.rs index 596a702..9a491d1 100644 --- a/src/solana/programs/verification_v2/src/append_threshold_key_message.rs +++ b/src/solana/programs/verification_v2/src/append_threshold_key_message.rs @@ -2,9 +2,11 @@ use byteorder::{BigEndian, ReadBytesExt}; use std::io::{Cursor, Read}; use anchor_lang::prelude::*; +use crate::threshold_key::ThresholdKey; + pub struct AppendThresholdKeyMessage { pub tss_index: u32, - pub tss_key: [u8; 20], + pub tss_key: ThresholdKey, pub expiration_delay_seconds: u32, } @@ -31,8 +33,7 @@ impl AppendThresholdKeyMessage { cursor.read_exact(&mut module)?; let action = cursor.read_u8()?; let tss_index = cursor.read_u32::()?; - let mut tss_key = [0u8; 20]; - cursor.read_exact(&mut tss_key)?; + let tss_key = ThresholdKey::deserialize_reader(&mut cursor)?; let expiration_delay_seconds = cursor.read_u32::()?; // Validate the module and action diff --git a/src/solana/programs/verification_v2/src/lib.rs b/src/solana/programs/verification_v2/src/lib.rs index a9edee0..a4ab6ea 100644 --- a/src/solana/programs/verification_v2/src/lib.rs +++ b/src/solana/programs/verification_v2/src/lib.rs @@ -4,12 +4,10 @@ declare_id!("GbFfTqMqKDgAMRH8VmDmoLTdvDd1853TnkkEwpydv3J6"); mod vaa; mod append_threshold_key_message; +mod threshold_key; use anchor_lang::prelude::*; use anchor_lang::solana_program::clock::Clock; -use anchor_lang::solana_program::keccak::hash; - -use libsecp256k1::{Message, RecoveryId, Signature, recover}; use wormhole_anchor_sdk::wormhole::program::Wormhole; use wormhole_anchor_sdk::wormhole::constants::CHAIN_ID_SOLANA; @@ -17,6 +15,7 @@ use wormhole_anchor_sdk::wormhole::{PostedVaaData}; use vaa::VAA; use append_threshold_key_message::AppendThresholdKeyMessage; +use threshold_key::ThresholdKey; const GOVERNANCE_ADDRESS: [u8; 32] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4]; @@ -44,8 +43,30 @@ pub enum AppendThresholdKeyError { IndexMismatch, #[msg("Invalid old threshold key")] InvalidOldThresholdKey, + #[msg("Invalid TSS key")] + InvalidTSSKey, +} + +#[account] +#[derive(InitSpace)] +pub struct ThresholdKeyAccount { + pub index: u32, + pub key: ThresholdKey, + pub expiration_timestamp: u64, } +impl ThresholdKeyAccount { + pub fn is_unexpired(&self) -> bool { + self.expiration_timestamp == 0 || self.expiration_timestamp > Clock::get().unwrap().unix_timestamp as u64 + } + + pub fn update_expiration_timestamp(&mut self, new_expiration_timestamp: u64) { + let current_timestamp = Clock::get().unwrap().unix_timestamp as u64; + self.expiration_timestamp = current_timestamp + new_expiration_timestamp; + } +} + +// TODO: Refactor this to have one accounts/instruction per file #[derive(Accounts)] pub struct AppendThresholdKey<'info> { #[account(mut)] @@ -61,15 +82,15 @@ pub struct AppendThresholdKey<'info> { #[account( init, payer = payer, - space = 8 + ThresholdKey::INIT_SPACE, + space = 8 + ThresholdKeyAccount::INIT_SPACE, )] - pub new_threshold_key: Account<'info, ThresholdKey>, + pub new_threshold_key: Account<'info, ThresholdKeyAccount>, #[account( mut, constraint = old_threshold_key.expiration_timestamp == 0 @ AppendThresholdKeyError::InvalidOldThresholdKey, )] - pub old_threshold_key: Option>, + pub old_threshold_key: Option>, pub wormhole_program: Program<'info, Wormhole>, pub system_program: Program<'info, System>, @@ -80,26 +101,7 @@ pub struct VerifyVaa<'info> { #[account( constraint = threshold_key.is_unexpired() @ VAAError::TSSKeyExpired, )] - pub threshold_key: Account<'info, ThresholdKey>, -} - -#[account] -#[derive(InitSpace)] -pub struct ThresholdKey { - pub index: u32, - pub key: [u8; 20], - pub expiration_timestamp: u64, -} - -impl ThresholdKey { - pub fn is_unexpired(&self) -> bool { - self.expiration_timestamp == 0 || self.expiration_timestamp > Clock::get().unwrap().unix_timestamp as u64 - } - - pub fn update_expiration_timestamp(&mut self, new_expiration_timestamp: u64) { - let current_timestamp = Clock::get().unwrap().unix_timestamp as u64; - self.expiration_timestamp = current_timestamp + new_expiration_timestamp; - } + pub threshold_key: Account<'info, ThresholdKeyAccount>, } #[program] @@ -110,7 +112,9 @@ pub mod verification_v2 { // Decode the VAA payload let message = AppendThresholdKeyMessage::deserialize(&ctx.accounts.vaa.payload)?; - // Validate the message index + // Check that if there is no old threshold key, the index is 0 + // Otherwise, check that the index is increasing from the previous index + // FIXME: There's nothing preventing us from creating many chains of valid threshold keys unless we use PDAs based on index let expected_index = ctx.accounts.old_threshold_key.as_ref().map_or(0, |key| key.index + 1); if message.tss_index != expected_index { return Err(AppendThresholdKeyError::IndexMismatch.into()); @@ -124,6 +128,8 @@ pub mod verification_v2 { // Set the old threshold key expiration timestamp if let Some(ref mut old_threshold_key) = &mut ctx.accounts.old_threshold_key { old_threshold_key.update_expiration_timestamp(message.expiration_delay_seconds as u64); + } else if expected_index > 0 { + return Err(AppendThresholdKeyError::InvalidOldThresholdKey.into()); } Ok(()) @@ -131,30 +137,22 @@ pub mod verification_v2 { pub fn verify_vaa(ctx: Context, raw_vaa: Vec) -> Result { // Decode the VAA - let (vaa, vaa_hash) = VAA::deserialize(&raw_vaa)?; + let vaa = VAA::deserialize(&mut raw_vaa.as_slice())?; - // Check if the VAA version is valid - if vaa.version != 2 { - return Err(VAAError::InvalidVersion.into()); - } - - // Check if the threshold key index matches the VAA index + // Check that the threshold key index matches the VAA index let threshold_key = &mut ctx.accounts.threshold_key; - if threshold_key.index != vaa.tss_index { + if threshold_key.index != vaa.header.tss_index { return Err(VAAError::InvalidIndex.into()); } - // Verify the VAA signature - let message = Message::parse(&vaa_hash); - let signature = Signature::parse_standard(&vaa.signature).map_err(|_| VAAError::InvalidSignature)?; - let recovery_id = RecoveryId::parse(vaa.recovery_id).map_err(|_| VAAError::InvalidSignature)?; - let recovered_key = recover(&message, &signature, &recovery_id).map_err(|_| VAAError::InvalidSignature)?; - let recovered_eth_key = &hash(&recovered_key.serialize()[1..]).to_bytes()[12..]; - - if recovered_eth_key != threshold_key.key { - return Err(VAAError::InvalidSignature.into()); + // Check that the threshold key is unexpired + if !threshold_key.is_unexpired() { + return Err(VAAError::TSSKeyExpired.into()); } + // Check that the signature is valid + threshold_key.key.check_signature(&vaa.message_hash()?, &vaa.header.signature)?; + // Return the VAA Ok(vaa) } diff --git a/src/solana/programs/verification_v2/src/threshold_key.rs b/src/solana/programs/verification_v2/src/threshold_key.rs new file mode 100644 index 0000000..74b4c05 --- /dev/null +++ b/src/solana/programs/verification_v2/src/threshold_key.rs @@ -0,0 +1,125 @@ +use anchor_lang::prelude::*; +use primitive_types::U256; +use std::io::{Cursor, Read, Write}; +use std::ops::{Rem, Shr, Sub}; +use anchor_lang::solana_program::keccak::{Hash, hash}; +use libsecp256k1::{Message, RecoveryId, Signature, recover}; +use crate::vaa::VAAThresholdSignature; + +#[derive(Clone, Debug)] +pub struct ThresholdKey { + pub key: U256, +} + +#[cfg(feature = "idl-build")] +impl anchor_lang::IdlBuild for ThresholdKey {} + +#[error_code] +pub enum ThresholdKeyError { + #[msg("Invalid scalar value")] + InvalidScalar, + #[msg("Invalid signature")] + InvalidSignature, +} + +impl ThresholdKey { + pub fn q() -> U256 { + // TODO: Move this to a constant + U256::from_str_radix("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16).unwrap() + } + + pub fn half_q() -> U256 { + // TODO: Move this to a constant + Self::q().shr(U256::one()) + } + + pub fn px(&self) -> U256 { + self.key.shr(U256::one()) + } + + pub fn parity(&self) -> bool { + self.key.bit(0) + } + + pub fn is_valid(&self) -> bool { + let px = self.px(); + !px.is_zero() && px.le(&Self::half_q()) + } + + pub fn check_signature(&self, message_hash: &Hash, signature: &VAAThresholdSignature) -> Result<()> { + let px = self.px(); + let parity = self.parity(); + let q = Self::q(); + let r = signature.r; + let s = signature.s; + + // Calculate the message challenge + let mut hash_bytes = Vec::new(); + hash_bytes.extend_from_slice(&px.to_big_endian()); + hash_bytes.push(parity as u8); + hash_bytes.extend_from_slice(&message_hash.to_bytes()); + hash_bytes.extend_from_slice(&r); + + let e = U256::from_big_endian(&hash(&hash_bytes).to_bytes()); + + // Calculate the recovery inputs + // FIXME: Is the overflow correct on the sp/ep calculations? + let sp = q.sub(Self::mulmod(px, s, q)); + let ep = Self::mulmod(e, px, q); + + if sp.is_zero() || ep.is_zero() { + return Err(ThresholdKeyError::InvalidSignature.into()); + } + + // Recover the signer address + let mut signature_bytes = [0u8; 64]; + signature_bytes[0..32].copy_from_slice(&px.to_big_endian()); + signature_bytes[32..64].copy_from_slice(&ep.to_big_endian()); + + let message = Message::parse_slice(&sp.to_big_endian()).unwrap(); + let signature = Signature::parse_standard(&signature_bytes).unwrap(); + let recovery_id = RecoveryId::parse(parity as u8).unwrap(); + let recovered = recover(&message, &signature, &recovery_id).unwrap(); + let recovered_address = &hash(&recovered.serialize()[1..]).to_bytes()[12..]; + + if recovered_address != r { + return Err(ThresholdKeyError::InvalidSignature.into()); + } + + Ok(()) + } + + fn mulmod(a: U256, b: U256, c: U256) -> U256 { + let result = a.full_mul(b).rem(c); + U256(result.0[0..3].try_into().unwrap()) + } +} + +impl Space for ThresholdKey { + const INIT_SPACE: usize = 32; +} + +impl AnchorSerialize for ThresholdKey { + fn serialize(&self, writer: &mut W) -> std::result::Result<(), std::io::Error> { + writer.write_all(&self.key.to_big_endian())?; + Ok(()) + } +} + +impl AnchorDeserialize for ThresholdKey { + fn deserialize(data: &mut &[u8]) -> std::result::Result { + Self::deserialize_reader(&mut Cursor::new(data)) + } + + fn deserialize_reader(reader: &mut R) -> std::result::Result { + let mut key = [0u8; 32]; + reader.read_exact(&mut key)?; + let key = ThresholdKey { key: U256::from_big_endian(&key) }; + + if !key.is_valid() { + return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "Invalid threshold key")); + } + + Ok(key) + } +} diff --git a/src/solana/programs/verification_v2/src/vaa.rs b/src/solana/programs/verification_v2/src/vaa.rs index 0f27719..78b93cb 100644 --- a/src/solana/programs/verification_v2/src/vaa.rs +++ b/src/solana/programs/verification_v2/src/vaa.rs @@ -1,86 +1,136 @@ -use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; -use std::io::{Cursor, Read, Write}; use anchor_lang::prelude::*; -use anchor_lang::solana_program::keccak::hash; +use anchor_lang::solana_program::keccak::{Hash, hash}; +use primitive_types::U256; +use borsh::{BorshSerialize, BorshDeserialize}; +use std::io::{Cursor, Read, Write}; +use byteorder::{BigEndian, ReadBytesExt}; -#[derive(AnchorSerialize, AnchorDeserialize)] -pub struct VAA { - // Header - pub version: u8, - pub tss_index: u32, - pub signature: [u8; 64], - pub recovery_id: u8, +use crate::threshold_key::ThresholdKey; + +pub struct VAAThresholdSignature { + pub r: [u8; 20], + pub s: U256, +} + +impl VAAThresholdSignature { + pub fn is_valid(&self) -> bool { + !self.s.is_zero() && self.s.lt(&ThresholdKey::q()) && !self.r.iter().all(|r| *r == 0) + } +} + +impl AnchorSerialize for VAAThresholdSignature { + fn serialize(&self, writer: &mut W) -> std::result::Result<(), std::io::Error> { + writer.write_all(&self.r)?; + writer.write_all(&self.s.to_big_endian())?; + Ok(()) + } +} + +impl AnchorDeserialize for VAAThresholdSignature { + fn deserialize(data: &mut &[u8]) -> std::result::Result { + Self::deserialize_reader(&mut Cursor::new(data)) + } + + fn deserialize_reader(reader: &mut R) -> std::result::Result { + let mut r = [0u8; 20]; + reader.read_exact(&mut r)?; + let mut s = [0u8; 32]; + reader.read_exact(&mut s)?; + Ok(Self { r, s: U256::from_big_endian(&s) }) + } +} + +pub struct VAAHeader { + pub version: u8, + pub tss_index: u32, + pub signature: VAAThresholdSignature, +} + +impl VAAHeader { + pub fn is_valid(&self) -> bool { + self.version == 2 && self.signature.is_valid() + } +} + +impl AnchorSerialize for VAAHeader { + fn serialize(&self, writer: &mut W) -> std::result::Result<(), std::io::Error> { + writer.write_all(&[self.version])?; + writer.write_all(&self.tss_index.to_be_bytes())?; + self.signature.serialize(writer)?; + Ok(()) + } +} + +impl AnchorDeserialize for VAAHeader { + fn deserialize(data: &mut &[u8]) -> std::result::Result { + Self::deserialize_reader(&mut Cursor::new(data)) + } + + fn deserialize_reader(reader: &mut R) -> std::result::Result { + let version = reader.read_u8()?; + let tss_index = reader.read_u32::()?; + let signature = VAAThresholdSignature::deserialize_reader(reader)?; + Ok(Self { version, tss_index, signature }) + } +} - // Body +pub struct VAAEnvelope { pub timestamp: u32, pub nonce: u32, pub emitter_chain_id: u16, pub emitter_address: [u8; 32], pub sequence: u64, pub consistency_level: u8, - pub payload: Vec, } -impl VAA { - pub fn serialize(&self, data: &mut [u8]) -> Result<()> { - let mut cursor = Cursor::new(data); - - cursor.write_u8(self.version)?; - cursor.write_u32::(self.tss_index)?; - cursor.write_all(&self.signature)?; - cursor.write_u8(self.recovery_id)?; - cursor.write_u32::(self.timestamp)?; - cursor.write_u32::(self.nonce)?; - cursor.write_u16::(self.emitter_chain_id)?; - cursor.write_all(&self.emitter_address)?; - cursor.write_u64::(self.sequence)?; - cursor.write_u8(self.consistency_level)?; - cursor.write_all(&self.payload)?; - +impl AnchorSerialize for VAAEnvelope { + fn serialize(&self, writer: &mut W) -> std::result::Result<(), std::io::Error> { + writer.write_all(&self.timestamp.to_be_bytes())?; + writer.write_all(&self.nonce.to_be_bytes())?; + writer.write_all(&self.emitter_chain_id.to_be_bytes())?; + writer.write_all(&self.emitter_address)?; + writer.write_all(&self.sequence.to_be_bytes())?; + writer.write_all(&[self.consistency_level])?; Ok(()) } +} + +impl AnchorDeserialize for VAAEnvelope { + fn deserialize(data: &mut &[u8]) -> std::result::Result { + Self::deserialize_reader(&mut Cursor::new(data)) + } + + fn deserialize_reader(reader: &mut R) -> std::result::Result { + let timestamp = reader.read_u32::()?; + let nonce = reader.read_u32::()?; + let emitter_chain_id = reader.read_u16::()?; + let mut emitter_address = [0u8; 32]; + reader.read_exact(&mut emitter_address)?; + let sequence = reader.read_u64::()?; + let consistency_level = reader.read_u8()?; + Ok(Self { timestamp, nonce, emitter_chain_id, emitter_address, sequence, consistency_level }) + } +} + +#[derive(BorshSerialize, BorshDeserialize)] +pub struct VAA { + pub header: VAAHeader, + pub envelope: VAAEnvelope, + pub payload: Vec, +} + +#[cfg(feature = "idl-build")] +impl anchor_lang::IdlBuild for VAA {} + +impl VAA { + pub fn is_valid(&self) -> bool { + self.header.is_valid() + } - pub fn deserialize(data: &[u8]) -> Result<(Self, [u8; 32])> { - let mut cursor = Cursor::new(data); - - let version = cursor.read_u8()?; - let tss_index = cursor.read_u32::()?; - let mut signature = [0; 64]; - cursor.read_exact(&mut signature)?; - let recovery_id = cursor.read_u8()?; - - let body_start = cursor.position() as usize; - - let timestamp = cursor.read_u32::()?; - let nonce = cursor.read_u32::()?; - let emitter_chain_id = cursor.read_u16::()?; - let mut emitter_address = [0; 32]; - cursor.read_exact(&mut emitter_address)?; - - let sequence = cursor.read_u64::()?; - let consistency_level = cursor.read_u8()?; - let mut payload = Vec::new(); - cursor.read_to_end(&mut payload)?; - - let hash = hash(&data[body_start..]).to_bytes(); - - Ok( - ( - Self { - version, - tss_index, - signature, - recovery_id, - timestamp, - nonce, - emitter_chain_id, - emitter_address, - sequence, - consistency_level, - payload, - }, - hash, - ) - ) + pub fn message_hash(&self) -> Result { + let mut cursor = Cursor::new(Vec::new()); + self.envelope.serialize(&mut cursor)?; + cursor.write_all(&self.payload)?; + Ok(hash(&cursor.get_ref())) } } From 2619a388fe63fe1c3eccd9cd62e15681488583c1 Mon Sep 17 00:00:00 2001 From: Joshua Averett Date: Thu, 22 May 2025 13:42:53 -0700 Subject: [PATCH 30/53] Handle initialization a bit more carefully. Still needs some more thought. --- src/evm/GuardianSetVerification.sol | 32 +++++++++++---- src/evm/GuardianSetVerificationState.sol | 2 + src/evm/ThresholdVerification.sol | 50 +++++++++++------------- src/evm/ThresholdVerificationState.sol | 33 +++++++++++----- src/evm/VerificationV2.sol | 19 ++++----- 5 files changed, 81 insertions(+), 55 deletions(-) diff --git a/src/evm/GuardianSetVerification.sol b/src/evm/GuardianSetVerification.sol index 9bcbf5d..1b75020 100644 --- a/src/evm/GuardianSetVerification.sol +++ b/src/evm/GuardianSetVerification.sol @@ -16,28 +16,32 @@ contract GuardianSetVerification is GuardianSetVerificationState { error QuorumNotMet(); error GuardianSetSignatureVerificationFailed(); + error GuardianSetExpired(); constructor( address coreBridge, uint256 pullLimit ) GuardianSetVerificationState(coreBridge, pullLimit) {} - function _verifyGuardianSetVaaHeader(bytes calldata encodedVaa) internal view returns (uint envelopeOffset) { + function _verifyGuardianSetVaaHeader(bytes calldata encodedVaa) internal view returns (uint envelopeOffset, uint32 guardianSetIndex, address[] memory guardians) { unchecked { uint offset = 0; uint8 version; - uint32 guardianSet; uint signatureCount; (version, offset) = encodedVaa.asUint8CdUnchecked(offset); - (guardianSet, offset) = encodedVaa.asUint32CdUnchecked(offset); + (guardianSetIndex, offset) = encodedVaa.asUint32CdUnchecked(offset); (signatureCount, offset) = encodedVaa.asUint8CdUnchecked(offset); // Validate the version require(version == 1, VaaLib.InvalidVersion(version)); - // Get the guardian set and the number of guardians - (, address[] memory guardians) = _getGuardianSetInfo(guardianSet); + // Get the guardian set and validate it's not expired + // FIXME: Do we want to do this expiration check? If we miss the expiration, + // I'm not sure what happens. + uint32 expirationTime; + (expirationTime, guardians) = _getGuardianSetInfo(guardianSetIndex); + require(expirationTime > block.timestamp, GuardianSetExpired()); // Get the number of signatures // NOTE: Optimization puts guardianCount on stack thus avoids mloads @@ -102,9 +106,21 @@ contract GuardianSetVerification is GuardianSetVerificationState { bytes32 emitterAddress, uint64 sequence, uint8 consistencyLevel, - bytes calldata payload + bytes calldata payload, + uint32 guardianSetIndex, + address[] memory guardians ) { - uint payloadOffset = _verifyGuardianSetVaaHeader(encodedVaa); - return encodedVaa.decodeVaaBodyCd(payloadOffset); + uint payloadOffset; + (payloadOffset, guardianSetIndex, guardians) = _verifyGuardianSetVaaHeader(encodedVaa); + + ( + timestamp, + nonce, + emitterChainId, + emitterAddress, + sequence, + consistencyLevel, + payload + ) = encodedVaa.decodeVaaBodyCd(payloadOffset); } } diff --git a/src/evm/GuardianSetVerificationState.sol b/src/evm/GuardianSetVerificationState.sol index 96ee3c2..53174c6 100644 --- a/src/evm/GuardianSetVerificationState.sol +++ b/src/evm/GuardianSetVerificationState.sol @@ -88,6 +88,8 @@ contract GuardianSetVerificationState is ExtStore { uint32 expirationTime ) { // Get the guardian set from the core bridge + // NOTE: The expiration time is copied from the core bridge, + // so any invalid guardian set will already be invalidated GuardianSet memory guardians = _coreBridge.getGuardianSet(index); expirationTime = guardians.expirationTime; diff --git a/src/evm/ThresholdVerification.sol b/src/evm/ThresholdVerification.sol index c41f5b3..793409c 100644 --- a/src/evm/ThresholdVerification.sol +++ b/src/evm/ThresholdVerification.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.0; import "wormhole-sdk/libraries/BytesParsing.sol"; +import {GuardianSet} from "wormhole-sdk/interfaces/ICoreBridge.sol"; import "wormhole-sdk/libraries/VaaLib.sol"; import "./ThresholdVerificationState.sol"; @@ -11,7 +12,6 @@ contract ThresholdVerification is ThresholdVerificationState { using VaaLib for bytes; using {BytesParsing.checkLength} for uint; - // Module ID for the VerificationV2 contract, ASCII "TSS" bytes32 constant MODULE_VERIFICATION_V2 = bytes32(0x0000000000000000000000000000000000000000000000000000000000545353); @@ -27,6 +27,8 @@ contract ThresholdVerification is ThresholdVerificationState { error InvalidModule(bytes32 module); error InvalidAction(uint8 action); + constructor(uint256 initialIndex) ThresholdVerificationState(initialIndex) {} + // Verify a threshold signature VAA function _verifyThresholdVaaHeader(bytes calldata encodedVaa) internal view returns (uint envelopeOffset) { unchecked { @@ -40,36 +42,32 @@ contract ThresholdVerification is ThresholdVerificationState { (tssIndex, offset) = encodedVaa.asUint32CdUnchecked(offset); (r, s, offset) = _decodeThresholdSignatureCdUnchecked(encodedVaa, offset); - // Validate the VAA version + // Validate the VAA version and threshold signature is in range + // NOTE: s < Q prevents signature malleability + // NOTE: Non-zero r prevents confusion with ecrecover failure + // NOTE: Non-zero check on s not needed, see the first argument of ecrecover require(version == 2, VaaLib.InvalidVersion(version)); + require(s < Q && r != address(0), ThresholdSignatureVerificationFailed()); - // Validate the threshold signature - // NOTE: The first condition prevents signature malleability from multiple representations for ℤ/Qℤ elements - require(s < Q, ThresholdSignatureVerificationFailed()); - require(r != address(0), ThresholdSignatureVerificationFailed()); - require(s != 0, ThresholdSignatureVerificationFailed()); - - // Validate the threshold key expiration time + // Load threshold key info and validate expiration time (uint256 pubkey, uint32 expirationTime) = _getThresholdInfo(tssIndex); require(expirationTime > block.timestamp, ThresholdKeyExpired()); - // Get the message hash and public key data + // Calculate the challenge value bytes32 vaaHash = encodedVaa.calcVaaDoubleHashCd(offset); (uint256 px, bool parity) = _decodePubkey(pubkey); - - // Calculate the challenge value uint256 e = uint256(keccak256(abi.encodePacked(px, parity, vaaHash, r))); - // Calculate the recovery inputs, ensuring that sp(the unchecked input for ecrecover) is non-zero - bytes32 sp = bytes32(Q - mulmod(px, s, Q)); - bytes32 ep = bytes32(mulmod(e, px, Q)); - require(sp != 0, ThresholdSignatureVerificationFailed()); - - // The ecrecover precompile implementation checks that the `r` and `s` - // inputs are non-zero (in this case, `px` and `ep`), thus we don't need to - // check if they're zero. We additionally know that px is non-zero because - // it's checked in the _appendThresholdKey function. - address recovered = ecrecover(sp, parity ? 28 : 27, bytes32(px), ep); + // Verify the recovered address matches the threshold signature r + address recovered = ecrecover( + // NOTE: This is non-zero because for all k = px * s, Q > k % Q + // Therefore, Q - k % Q is always positive + bytes32(Q - mulmod(px, s, Q)), + parity ? 28 : 27, + // NOTE: This is checked non-zero in _decodeThresholdKeyUpdatePayload + bytes32(px), + bytes32(mulmod(px, e, Q)) + ); require(r == recovered, ThresholdSignatureVerificationFailed()); return offset; @@ -100,8 +98,7 @@ contract ThresholdVerification is ThresholdVerificationState { } } - function _decodeThresholdKeyUpdatePayload(bytes calldata payload) internal pure returns ( - uint32 newThresholdIndex, + function _decodeThresholdKeyUpdatePayload(bytes calldata payload, uint256 shardCount) internal pure returns ( uint256 newThresholdPubkey, uint32 expirationDelaySeconds, ShardInfo[] memory shards @@ -111,16 +108,13 @@ contract ThresholdVerification is ThresholdVerificationState { uint offset = 0; uint8 action; bytes32 module; - uint shardCount; (module, offset) = payload.asBytes32MemUnchecked(offset); (action, offset) = payload.asUint8MemUnchecked(offset); - (newThresholdIndex, offset) = payload.asUint32MemUnchecked(offset); (newThresholdPubkey, offset) = payload.asUint256MemUnchecked(offset); (expirationDelaySeconds, offset) = payload.asUint32MemUnchecked(offset); - (shardCount, offset) = payload.asUint8MemUnchecked(offset); // TODO: We should probably pass this in and get it from the guardian set to ensure the mapping is correct - // Validate the threshold key is less than HALF_Q + // Validate the threshold key is non-zero and less than HALF_Q (uint256 px,) = _decodePubkey(newThresholdPubkey); require(px != 0, InvalidThresholdKeyAddress()); require(px <= HALF_Q, InvalidThresholdKeyAddress()); diff --git a/src/evm/ThresholdVerificationState.sol b/src/evm/ThresholdVerificationState.sol index 0b56d1a..9bc4f60 100644 --- a/src/evm/ThresholdVerificationState.sol +++ b/src/evm/ThresholdVerificationState.sol @@ -12,27 +12,40 @@ contract ThresholdVerificationState { bytes32 id; } + uint256 private _thresholdDataInitialIndex; + + constructor(uint256 initialIndex) { + _thresholdDataInitialIndex = initialIndex; + } + // Threshold data is stored in a single array with stride 2: // pubkey (32 bytes) // expiration time (4 bytes) // shard base (5 bytes) // shard count (1 byte) uint256[] private _thresholdData; + + // Shard data is stored as a single array with stride 2, grouped by guardian set bytes32[] private _shardData; // Get the current threshold signature info function _getCurrentThresholdInfo() internal view returns (uint256 pubkey, uint32 index) { unchecked { uint256 length = _thresholdData.length; - // NOTE: We assume that at least one threshold key has been set - pubkey = _thresholdData[length - 2]; - index = uint32(length >> 1); + if (length == 0) { + pubkey = 0; + index = uint32(_thresholdDataInitialIndex); + } else { + pubkey = _thresholdData[length - 2]; + index = uint32(length >> 1); + } } } function _getThresholdInfo(uint32 index) internal view returns (uint256 pubkey, uint32 expirationTime) { unchecked { - uint256 offset = index << 1; + // NOTE: The threshold data index is relative to the initial index + uint256 offset = (index - _thresholdDataInitialIndex) << 1; require(offset < _thresholdData.length, InvalidThresholdKeyIndex()); pubkey = _thresholdData[offset]; expirationTime = _thresholdDataExpirationTime(_thresholdData[offset + 1]); @@ -46,12 +59,6 @@ contract ThresholdVerificationState { ShardInfo[] memory shards ) internal { unchecked { - // Verify the new address is not the zero address - // This prevents errors from ecrecover returning the zero address - // NOTE: This is actually already checked in ecrecover, but there's no harm in preventing that case here - // NOTE: The pubkey is also known to be <= HALF_Q, based on the decoding in _decodeThresholdKeyUpdatePayload - require(pubkey != 0, InvalidThresholdKeyAddress()); - // Get the current threshold info and verify the new index is sequential (, uint32 index) = _getCurrentThresholdInfo(); require(newIndex == index + 1, InvalidThresholdKeyIndex()); @@ -63,6 +70,12 @@ contract ThresholdVerificationState { // Store the new threshold info _thresholdData.push(pubkey); _thresholdData.push(_createThresholdData(uint8(shards.length), uint40(_shardData.length))); + + // Store the shard data + for (uint256 i = 0; i < shards.length; i++) { + _shardData.push(shards[i].shard); + _shardData.push(shards[i].id); + } } } diff --git a/src/evm/VerificationV2.sol b/src/evm/VerificationV2.sol index 4c437be..ed44d84 100644 --- a/src/evm/VerificationV2.sol +++ b/src/evm/VerificationV2.sol @@ -41,9 +41,9 @@ contract VerificationV2 is error GuardianSetIsNotCurrent(); - // TODO: Consider how to initialize the contract, pulling in guardian sets and threshold keys - constructor(address coreV1, uint256 pullLimit) - ThresholdVerification() + // FIXME: The initial TSS index should be the latest guardian set index, not passed in! + constructor(address coreV1, uint256 initialTSSIndex, uint256 pullLimit) + ThresholdVerification(initialTSSIndex) GuardianSetVerification(coreV1, pullLimit) GuardianRegistryVerification() {} @@ -70,9 +70,9 @@ contract VerificationV2 is ) { (uint8 version, ) = data.asUint8CdUnchecked(0); if (version == 2) { - return _verifyAndDecodeThresholdVaa(data); + (timestamp, nonce, emitterChainId, emitterAddress, sequence, consistencyLevel, payload) = _verifyAndDecodeThresholdVaa(data); } else if (version == 1) { - return _verifyAndDecodeGuardianSetVaa(data); + (timestamp, nonce, emitterChainId, emitterAddress, sequence, consistencyLevel, payload,,) = _verifyAndDecodeGuardianSetVaa(data); } else { revert VaaLib.InvalidVersion(version); } @@ -101,7 +101,9 @@ contract VerificationV2 is bytes32 emitterAddress, , , - bytes calldata payload + bytes calldata payload, + uint32 guardianSetIndex, + address[] memory guardians ) = _verifyAndDecodeGuardianSetVaa(encodedVaa); // Verify the emitter @@ -110,14 +112,13 @@ contract VerificationV2 is // Decode the payload ( - uint32 newThresholdIndex, uint256 newThresholdAddr, uint32 expirationDelaySeconds, ShardInfo[] memory shards - ) = _decodeThresholdKeyUpdatePayload(payload); + ) = _decodeThresholdKeyUpdatePayload(payload, guardians.length); // Append the threshold key - _appendThresholdKey(newThresholdIndex, newThresholdAddr, expirationDelaySeconds, shards); + _appendThresholdKey(guardianSetIndex, newThresholdAddr, expirationDelaySeconds, shards); } else if (op == OP_PULL_GUARDIAN_SETS) { uint32 limit; (limit, offset) = data.asUint32CdUnchecked(offset); From d3ffd46065c8325543672ea6ff0aae8df7782e4c Mon Sep 17 00:00:00 2001 From: Joshua Averett Date: Thu, 29 May 2025 08:15:45 -0700 Subject: [PATCH 31/53] Bug fix and minor formatting updates --- src/evm/GuardianRegistryVerification.sol | 1 + src/evm/GuardianSetVerification.sol | 6 ++++- src/evm/GuardianSetVerificationState.sol | 28 ++++++++++--------- src/evm/ThresholdVerification.sol | 7 +++-- src/evm/ThresholdVerificationState.sol | 34 +++++++++++++----------- src/evm/VerificationV2.sol | 6 ++--- 6 files changed, 49 insertions(+), 33 deletions(-) diff --git a/src/evm/GuardianRegistryVerification.sol b/src/evm/GuardianRegistryVerification.sol index b812869..aef5f70 100644 --- a/src/evm/GuardianRegistryVerification.sol +++ b/src/evm/GuardianRegistryVerification.sol @@ -25,6 +25,7 @@ contract GuardianRegistryVerification is EIP712Encoding { ) internal view { require(expirationTime > block.timestamp, RegistrationMessageExpired()); bytes32 digest = getRegisterGuardianDigest(guardianSet, expirationTime, id); + // Verify the signature address signatory = ecrecover(digest, v, r, s); require(signatory == guardianAddrs[guardian], GuardianSignatureVerificationFailed()); diff --git a/src/evm/GuardianSetVerification.sol b/src/evm/GuardianSetVerification.sol index 1b75020..b34042c 100644 --- a/src/evm/GuardianSetVerification.sol +++ b/src/evm/GuardianSetVerification.sol @@ -23,7 +23,11 @@ contract GuardianSetVerification is GuardianSetVerificationState { uint256 pullLimit ) GuardianSetVerificationState(coreBridge, pullLimit) {} - function _verifyGuardianSetVaaHeader(bytes calldata encodedVaa) internal view returns (uint envelopeOffset, uint32 guardianSetIndex, address[] memory guardians) { + function _verifyGuardianSetVaaHeader(bytes calldata encodedVaa) internal view returns ( + uint envelopeOffset, + uint32 guardianSetIndex, + address[] memory guardians + ) { unchecked { uint offset = 0; uint8 version; diff --git a/src/evm/GuardianSetVerificationState.sol b/src/evm/GuardianSetVerificationState.sol index 53174c6..021e4a5 100644 --- a/src/evm/GuardianSetVerificationState.sol +++ b/src/evm/GuardianSetVerificationState.sol @@ -25,8 +25,16 @@ contract GuardianSetVerificationState is ExtStore { _pullGuardianSets(pullLimit); } - // Get the guardian addresses for a given guardian set index using the ExtStore - // On an invalid index, the function will panic + // Get the current guardian set index and addresses + // NOTE: If no guardian sets have been pulled, the function will panic + function _getCurrentGuardianSetInfo() internal view returns (uint32 index, address[] memory guardianAddrs) { + unchecked { + index = uint32(_guardianSetExpirationTime.length - 1); + (, guardianAddrs) = _getGuardianSetInfo(index); + } + } + + // Get the guardian addresses for a given guardian set index function _getGuardianSetInfo(uint32 index) internal view returns ( uint32 expirationTime, address[] memory guardianAddrs @@ -45,21 +53,15 @@ contract GuardianSetVerificationState is ExtStore { } } - function _getCurrentGuardianSetInfo() internal view returns (uint32 index, address[] memory guardianAddrs) { - unchecked { - index = uint32(_guardianSetExpirationTime.length - 1); - (, guardianAddrs) = _getGuardianSetInfo(index); - } - } - - function _pullGuardianSets(uint256 limit) internal { + function _pullGuardianSets(uint256 limit) internal returns (bool isComplete, uint32 currentGuardianSetIndex) { unchecked { // Get the guardian set lengths for the bridge and the local contract - uint currentGuardianSetLength = _coreBridge.getCurrentGuardianSetIndex() + 1; + currentGuardianSetIndex = _coreBridge.getCurrentGuardianSetIndex(); + uint32 currentGuardianSetLength = currentGuardianSetIndex + 1; uint oldGuardianSetLength = _guardianSetExpirationTime.length; // If we have already pulled all the guardian sets, return - if (currentGuardianSetLength == oldGuardianSetLength) return; + if (currentGuardianSetLength == oldGuardianSetLength) return (true, currentGuardianSetIndex); // Check if we need to update the current guardian set if (oldGuardianSetLength > 0) { @@ -80,6 +82,8 @@ contract GuardianSetVerificationState is ExtStore { _guardianSetExpirationTime.push(expirationTime); _extWrite(data); } + + return (_guardianSetExpirationTime.length == currentGuardianSetLength, currentGuardianSetIndex); } } diff --git a/src/evm/ThresholdVerification.sol b/src/evm/ThresholdVerification.sol index 793409c..249b171 100644 --- a/src/evm/ThresholdVerification.sol +++ b/src/evm/ThresholdVerification.sol @@ -27,8 +27,6 @@ contract ThresholdVerification is ThresholdVerificationState { error InvalidModule(bytes32 module); error InvalidAction(uint8 action); - constructor(uint256 initialIndex) ThresholdVerificationState(initialIndex) {} - // Verify a threshold signature VAA function _verifyThresholdVaaHeader(bytes calldata encodedVaa) internal view returns (uint envelopeOffset) { unchecked { @@ -99,6 +97,7 @@ contract ThresholdVerification is ThresholdVerificationState { } function _decodeThresholdKeyUpdatePayload(bytes calldata payload, uint256 shardCount) internal pure returns ( + uint32 newTSSIndex, uint256 newThresholdPubkey, uint32 expirationDelaySeconds, ShardInfo[] memory shards @@ -109,8 +108,12 @@ contract ThresholdVerification is ThresholdVerificationState { uint8 action; bytes32 module; + // Headedr (module, offset) = payload.asBytes32MemUnchecked(offset); (action, offset) = payload.asUint8MemUnchecked(offset); + + // Payload + (newTSSIndex, offset) = payload.asUint32MemUnchecked(offset); (newThresholdPubkey, offset) = payload.asUint256MemUnchecked(offset); (expirationDelaySeconds, offset) = payload.asUint32MemUnchecked(offset); diff --git a/src/evm/ThresholdVerificationState.sol b/src/evm/ThresholdVerificationState.sol index 9bc4f60..9a9e230 100644 --- a/src/evm/ThresholdVerificationState.sol +++ b/src/evm/ThresholdVerificationState.sol @@ -6,17 +6,14 @@ contract ThresholdVerificationState { error InvalidThresholdKeyIndex(); error InvalidThresholdKeyAddress(); error InvalidGuardianIndex(); + error GuardianSetsNotComplete(); struct ShardInfo { bytes32 shard; bytes32 id; } - uint256 private _thresholdDataInitialIndex; - - constructor(uint256 initialIndex) { - _thresholdDataInitialIndex = initialIndex; - } + uint32 private _thresholdDataInitialIndex; // Threshold data is stored in a single array with stride 2: // pubkey (32 bytes) @@ -32,13 +29,8 @@ contract ThresholdVerificationState { function _getCurrentThresholdInfo() internal view returns (uint256 pubkey, uint32 index) { unchecked { uint256 length = _thresholdData.length; - if (length == 0) { - pubkey = 0; - index = uint32(_thresholdDataInitialIndex); - } else { - pubkey = _thresholdData[length - 2]; - index = uint32(length >> 1); - } + pubkey = _thresholdData[length - 2]; + index = uint32((length >> 1) + _thresholdDataInitialIndex); } } @@ -53,15 +45,27 @@ contract ThresholdVerificationState { } function _appendThresholdKey( - uint32 newIndex, + uint32 currentGuardianSetIndex, + uint32 newTSSIndex, uint256 pubkey, uint32 expirationDelaySeconds, ShardInfo[] memory shards ) internal { unchecked { // Get the current threshold info and verify the new index is sequential - (, uint32 index) = _getCurrentThresholdInfo(); - require(newIndex == index + 1, InvalidThresholdKeyIndex()); + // NOTE: We can't use _getCurrentThresholdInfo() directly here because + // _thresholdData will be empty on the first append + uint32 index; + if (_thresholdData.length > 0) { + // If there is threshold data, the new index must be sequential + (, index) = _getCurrentThresholdInfo(); + require(newTSSIndex == index + 1, InvalidThresholdKeyIndex()); + } else { + // If there is no threshold data, the initial index must be the new index + require(newTSSIndex == currentGuardianSetIndex, InvalidThresholdKeyIndex()); + index = currentGuardianSetIndex; + _thresholdDataInitialIndex = currentGuardianSetIndex; + } // Store the expiration time and current threshold address in past threshold info uint32 expirationTime = uint32(block.timestamp) + expirationDelaySeconds; diff --git a/src/evm/VerificationV2.sol b/src/evm/VerificationV2.sol index ed44d84..b8b1d0b 100644 --- a/src/evm/VerificationV2.sol +++ b/src/evm/VerificationV2.sol @@ -42,8 +42,7 @@ contract VerificationV2 is error GuardianSetIsNotCurrent(); // FIXME: The initial TSS index should be the latest guardian set index, not passed in! - constructor(address coreV1, uint256 initialTSSIndex, uint256 pullLimit) - ThresholdVerification(initialTSSIndex) + constructor(address coreV1, uint256 pullLimit) GuardianSetVerification(coreV1, pullLimit) GuardianRegistryVerification() {} @@ -112,13 +111,14 @@ contract VerificationV2 is // Decode the payload ( + uint32 newTSSIndex, uint256 newThresholdAddr, uint32 expirationDelaySeconds, ShardInfo[] memory shards ) = _decodeThresholdKeyUpdatePayload(payload, guardians.length); // Append the threshold key - _appendThresholdKey(guardianSetIndex, newThresholdAddr, expirationDelaySeconds, shards); + _appendThresholdKey(guardianSetIndex, newTSSIndex, newThresholdAddr, expirationDelaySeconds, shards); } else if (op == OP_PULL_GUARDIAN_SETS) { uint32 limit; (limit, offset) = data.asUint32CdUnchecked(offset); From bc3830088d88c22f0138b13fa652f58b753dc345 Mon Sep 17 00:00:00 2001 From: Joshua Averett Date: Thu, 29 May 2025 08:19:49 -0700 Subject: [PATCH 32/53] Check to ensure we don't have TSS sets not matching guardian sets --- src/evm/ThresholdVerificationState.sol | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/evm/ThresholdVerificationState.sol b/src/evm/ThresholdVerificationState.sol index 9a9e230..67793cc 100644 --- a/src/evm/ThresholdVerificationState.sol +++ b/src/evm/ThresholdVerificationState.sol @@ -60,6 +60,9 @@ contract ThresholdVerificationState { // If there is threshold data, the new index must be sequential (, index) = _getCurrentThresholdInfo(); require(newTSSIndex == index + 1, InvalidThresholdKeyIndex()); + + // Verify we have a matching guardian set + require(currentGuardianSetIndex >= index, InvalidThresholdKeyIndex()); } else { // If there is no threshold data, the initial index must be the new index require(newTSSIndex == currentGuardianSetIndex, InvalidThresholdKeyIndex()); From 3a170a8604636ff3adf3de23eb551c076fb0352a Mon Sep 17 00:00:00 2001 From: Joshua Averett Date: Thu, 29 May 2025 08:20:48 -0700 Subject: [PATCH 33/53] Fix typo --- src/evm/ThresholdVerificationState.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/evm/ThresholdVerificationState.sol b/src/evm/ThresholdVerificationState.sol index 67793cc..5129941 100644 --- a/src/evm/ThresholdVerificationState.sol +++ b/src/evm/ThresholdVerificationState.sol @@ -62,7 +62,7 @@ contract ThresholdVerificationState { require(newTSSIndex == index + 1, InvalidThresholdKeyIndex()); // Verify we have a matching guardian set - require(currentGuardianSetIndex >= index, InvalidThresholdKeyIndex()); + require(currentGuardianSetIndex >= newTSSIndex, InvalidThresholdKeyIndex()); } else { // If there is no threshold data, the initial index must be the new index require(newTSSIndex == currentGuardianSetIndex, InvalidThresholdKeyIndex()); From 90dc2a6a201e861ef975f2aa498e8d25205e3e3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Claudio=20Nale?= Date: Thu, 29 May 2025 14:55:41 -0300 Subject: [PATCH 34/53] evm: fixes some typos --- src/evm/GuardianSetVerification.sol | 2 +- src/evm/GuardianSetVerificationState.sol | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/evm/GuardianSetVerification.sol b/src/evm/GuardianSetVerification.sol index b34042c..2a739e5 100644 --- a/src/evm/GuardianSetVerification.sol +++ b/src/evm/GuardianSetVerification.sol @@ -76,7 +76,7 @@ contract GuardianSetVerification is GuardianSetVerificationState { address guardianAddress = guardians.readUnchecked(guardian); // Check that: - // * the guardian indicies are in strictly ascending order (only after the first signature) + // * the guardian indices are in strictly ascending order (only after the first signature) // this is itself an optimization to efficiently prevent having the same guardian signature // included twice // * that the guardian index is not out of bounds diff --git a/src/evm/GuardianSetVerificationState.sol b/src/evm/GuardianSetVerificationState.sol index 021e4a5..0d2b066 100644 --- a/src/evm/GuardianSetVerificationState.sol +++ b/src/evm/GuardianSetVerificationState.sol @@ -11,7 +11,7 @@ contract GuardianSetVerificationState is ExtStore { error InvalidGuardianSetIndex(); - // Core bridge instance + // Core bridge instance ICoreBridge private immutable _coreBridge; // Guardian set expiration time is stored in an array mapped from index to expiration time @@ -34,7 +34,7 @@ contract GuardianSetVerificationState is ExtStore { } } - // Get the guardian addresses for a given guardian set index + // Get the guardian addresses for a given guardian set index function _getGuardianSetInfo(uint32 index) internal view returns ( uint32 expirationTime, address[] memory guardianAddrs From 9e49bd71b99ed9950bb8c05f9601e20b2f1728db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Claudio=20Nale?= Date: Thu, 29 May 2025 14:56:02 -0300 Subject: [PATCH 35/53] evm: decouples logic from data structure implementation --- src/evm/ThresholdVerificationState.sol | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/evm/ThresholdVerificationState.sol b/src/evm/ThresholdVerificationState.sol index 5129941..46195d2 100644 --- a/src/evm/ThresholdVerificationState.sol +++ b/src/evm/ThresholdVerificationState.sol @@ -88,10 +88,8 @@ contract ThresholdVerificationState { function _getShards(uint32 guardianSet) internal view returns (ShardInfo[] memory) { unchecked { - uint256 offset = guardianSet << 1; - require(offset < _thresholdData.length, InvalidThresholdKeyIndex()); - (uint8 shardCount, uint40 shardBase) = _thresholdDataShardSlice(_thresholdData[offset + 1]); - + (uint8 shardCount, uint40 shardBase) = _thresholdDataShardSlice(guardianSet); + ShardInfo[] memory shards = new ShardInfo[](shardCount); uint256 ptr = shardBase; for (uint256 i = 0; i < shardCount; i++) { @@ -116,9 +114,7 @@ contract ThresholdVerificationState { function _registerGuardian(uint32 guardianSet, uint8 guardian, bytes32 id) internal { unchecked { - uint256 offset = guardianSet << 1; - require(offset < _thresholdData.length, InvalidThresholdKeyIndex()); - (uint8 shardCount, uint40 shardBase) = _thresholdDataShardSlice(_thresholdData[offset + 1]); + (uint8 shardCount, uint40 shardBase) = _thresholdDataShardSlice(guardianSet); require(guardian < shardCount, InvalidGuardianIndex()); _shardData[shardBase + (guardian << 1)] = id; } @@ -134,8 +130,12 @@ contract ThresholdVerificationState { } } - function _thresholdDataShardSlice(uint256 data) internal pure returns (uint8 shardCount, uint40 shardBase) { + function _thresholdDataShardSlice(uint32 guardianSet) internal view returns (uint8 shardCount, uint40 shardBase) { unchecked { + uint256 offset = guardianSet << 1; + require(offset < _thresholdData.length, InvalidThresholdKeyIndex()); + uint256 data = _thresholdData[offset + 1]); + shardCount = uint8((data >> 32) & 0xFF); shardBase = uint40(data >> 40); } From 6cb90de2beb2b90fc7307ed57f2efb7e1e7a6b73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Claudio=20Nale?= Date: Thu, 29 May 2025 16:41:21 -0300 Subject: [PATCH 36/53] solana: reworks tests to use the latest wormhole sdk --- src/solana/Anchor.toml | 6 +- src/solana/package-lock.json | 5220 ++------------------- src/solana/package.json | 11 +- src/solana/tests/layouts.ts | 75 + src/solana/tests/testing-wormhole-core.ts | 152 + src/solana/tests/testing_helpers.ts | 260 +- src/solana/tests/verification_v2.ts | 183 +- 7 files changed, 934 insertions(+), 4973 deletions(-) create mode 100644 src/solana/tests/layouts.ts create mode 100644 src/solana/tests/testing-wormhole-core.ts diff --git a/src/solana/Anchor.toml b/src/solana/Anchor.toml index 873c37b..b5b9bef 100644 --- a/src/solana/Anchor.toml +++ b/src/solana/Anchor.toml @@ -1,4 +1,6 @@ [toolchain] +anchor_version = "0.31.1" +solana_version = "2.1.18" [features] resolution = true @@ -15,7 +17,7 @@ cluster = "localnet" wallet = "~/.config/solana/id.json" [scripts] -test = "yarn run mocha -t 1000000 tests/**/*.ts" +test = "npx mocha -t 1000000 tests/**/*.ts" [test] startup_wait = 5000 @@ -23,6 +25,6 @@ shutdown_wait = 2000 upgradeable = false [[test.genesis]] -name = "wormhole" +name = "wormhole-core-v1" address = "worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth" program = "imports/wormhole.so" diff --git a/src/solana/package-lock.json b/src/solana/package-lock.json index 537d9af..6525f77 100644 --- a/src/solana/package-lock.json +++ b/src/solana/package-lock.json @@ -6,21 +6,22 @@ "": { "license": "ISC", "dependencies": { - "@certusone/wormhole-sdk": "^0.10.18", "@coral-xyz/anchor": "^0.31.1", "@noble/hashes": "^1.7.2", "@noble/secp256k1": "^2.2.3", - "chai-as-promised": "^8.0.1", - "diff": "^7.0.0" + "@wormhole-foundation/sdk-base": "^1.20.0", + "@wormhole-foundation/sdk-definitions": "^1.20.0", + "@wormhole-foundation/sdk-solana-core": "^1.20.0" }, "devDependencies": { "@types/bn.js": "^5.1.0", "@types/chai": "^4.3.0", - "@types/chai-as-promised": "^8.0.2", "@types/mocha": "^10.0.10", "chai": "^4.5.0", + "diff": "^7.0.0", "mocha": "^11.1.0", "prettier": "^2.6.2", + "toml": "^3.0.0", "tsx": "^4.19.3", "typescript": "^5.7.3" } @@ -37,186 +38,6 @@ "node": ">=6.9.0" } }, - "node_modules/@bangjelkoski/store2": { - "version": "2.14.3", - "resolved": "https://registry.npmjs.org/@bangjelkoski/store2/-/store2-2.14.3.tgz", - "integrity": "sha512-ZG6ZDOHU5MZ4yxA3yY3gcZYnkcPtPaOwGOJrWD4Drar/u1TTBy1tWnP70atBa6LGm1+Ll1nb2GwS+HyWuFOWkw==", - "license": "MIT", - "optional": true - }, - "node_modules/@certusone/wormhole-sdk": { - "version": "0.10.18", - "resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk/-/wormhole-sdk-0.10.18.tgz", - "integrity": "sha512-VuN4AGB018ELkzTT/jN+yWgE6TWqXsHilxxCVWqGctzow2hKSFd8ADUhxhHigies436rS0vPvrgXi6m0J1+Ecw==", - "deprecated": "Please use the new Wormhole TypeScript SDK instead: @wormhole-foundation/sdk", - "license": "Apache-2.0", - "dependencies": { - "@certusone/wormhole-sdk-proto-web": "0.0.7", - "@certusone/wormhole-sdk-wasm": "^0.0.1", - "@coral-xyz/borsh": "0.2.6", - "@mysten/sui.js": "0.32.2", - "@project-serum/anchor": "^0.25.0", - "@solana/spl-token": "^0.3.5", - "@solana/web3.js": "^1.66.2", - "@terra-money/terra.js": "3.1.9", - "@xpla/xpla.js": "^0.2.1", - "algosdk": "^2.4.0", - "aptos": "1.5.0", - "axios": "^0.24.0", - "bech32": "^2.0.0", - "binary-parser": "^2.2.1", - "bs58": "^4.0.1", - "elliptic": "^6.5.4", - "js-base64": "^3.6.1", - "near-api-js": "^1.0.0" - }, - "optionalDependencies": { - "@injectivelabs/networks": "1.10.12", - "@injectivelabs/sdk-ts": "1.10.72", - "@injectivelabs/utils": "1.10.12" - } - }, - "node_modules/@certusone/wormhole-sdk-proto-web": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk-proto-web/-/wormhole-sdk-proto-web-0.0.7.tgz", - "integrity": "sha512-GCe1/bcqMS0Mt+hsWp4SE4NLL59pWmK0lhQXO0oqAKl0G9AuuTdudySMDF/sLc7z5H2w34bSuSrIEKvPuuSC+w==", - "license": "Apache-2.0", - "dependencies": { - "@improbable-eng/grpc-web": "^0.15.0", - "protobufjs": "^7.0.0", - "rxjs": "^7.5.6" - } - }, - "node_modules/@certusone/wormhole-sdk-wasm": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk-wasm/-/wormhole-sdk-wasm-0.0.1.tgz", - "integrity": "sha512-LdIwLhOyr4pPs2jqYubqC7d4UkqYBX0EG/ppspQlW3qlVE0LZRMrH6oVzzLMyHtV0Rw7O9sIKzORW/T3mrJv2w==", - "license": "Apache-2.0", - "dependencies": { - "@types/long": "^4.0.2", - "@types/node": "^18.0.3" - } - }, - "node_modules/@certusone/wormhole-sdk-wasm/node_modules/@types/node": { - "version": "18.19.87", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.87.tgz", - "integrity": "sha512-OIAAu6ypnVZHmsHCeJ+7CCSub38QNBS9uceMQeg7K5Ur0Jr+wG9wEOEvvMbhp09pxD5czIUy/jND7s7Tb6Nw7A==", - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@certusone/wormhole-sdk-wasm/node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "license": "MIT" - }, - "node_modules/@certusone/wormhole-sdk/node_modules/@coral-xyz/borsh": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.2.6.tgz", - "integrity": "sha512-y6nmHw1bFcJib7sMHsQPpC8r47xhqDZVvhUdna7NUPzpSbOZG6f46N21+aXsQ2w/tG8Ggls488J/ZmwbgVmyjg==", - "license": "Apache-2.0", - "dependencies": { - "bn.js": "^5.1.2", - "buffer-layout": "^1.2.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@solana/web3.js": "^1.2.0" - } - }, - "node_modules/@classic-terra/terra.proto": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@classic-terra/terra.proto/-/terra.proto-1.1.0.tgz", - "integrity": "sha512-bYhQG5LUaGF0KPRY9hYT/HEcd1QExZPQd6zLV/rQkCe/eDxfwFRLzZHpaaAdfWoAAZjsRWqJbUCqCg7gXBbJpw==", - "license": "Apache-2.0", - "dependencies": { - "@improbable-eng/grpc-web": "^0.14.1", - "google-protobuf": "^3.17.3", - "long": "^4.0.0", - "protobufjs": "~6.11.2" - } - }, - "node_modules/@classic-terra/terra.proto/node_modules/@improbable-eng/grpc-web": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@improbable-eng/grpc-web/-/grpc-web-0.14.1.tgz", - "integrity": "sha512-XaIYuunepPxoiGVLLHmlnVminUGzBTnXr8Wv7khzmLWbNw4TCwJKX09GSMJlKhu/TRk6gms0ySFxewaETSBqgw==", - "license": "Apache-2.0", - "dependencies": { - "browser-headers": "^0.4.1" - }, - "peerDependencies": { - "google-protobuf": "^3.14.0" - } - }, - "node_modules/@classic-terra/terra.proto/node_modules/protobufjs": { - "version": "6.11.4", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz", - "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==", - "hasInstallScript": true, - "license": "BSD-3-Clause", - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": ">=13.7.0", - "long": "^4.0.0" - }, - "bin": { - "pbjs": "bin/pbjs", - "pbts": "bin/pbts" - } - }, - "node_modules/@confio/ics23": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/@confio/ics23/-/ics23-0.6.8.tgz", - "integrity": "sha512-wB6uo+3A50m0sW/EWcU64xpV/8wShZ6bMTa7pF8eYsTrSkQA7oLUIJcs/wb8g4y2Oyq701BaGiO6n/ak5WXO1w==", - "deprecated": "Unmaintained. The codebase for this package was moved to https://github.com/cosmos/ics23 but then the JS implementation was removed in https://github.com/cosmos/ics23/pull/353. Please consult the maintainers of https://github.com/cosmos for further assistance.", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "@noble/hashes": "^1.0.0", - "protobufjs": "^6.8.8" - } - }, - "node_modules/@confio/ics23/node_modules/protobufjs": { - "version": "6.11.4", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz", - "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==", - "hasInstallScript": true, - "license": "BSD-3-Clause", - "optional": true, - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": ">=13.7.0", - "long": "^4.0.0" - }, - "bin": { - "pbjs": "bin/pbjs", - "pbts": "bin/pbts" - } - }, "node_modules/@coral-xyz/anchor": { "version": "0.31.1", "resolved": "https://registry.npmjs.org/@coral-xyz/anchor/-/anchor-0.31.1.tgz", @@ -266,198 +87,6 @@ "@solana/web3.js": "^1.69.0" } }, - "node_modules/@cosmjs/amino": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/amino/-/amino-0.30.1.tgz", - "integrity": "sha512-yNHnzmvAlkETDYIpeCTdVqgvrdt1qgkOXwuRVi8s27UKI5hfqyE9fJ/fuunXE6ZZPnKkjIecDznmuUOMrMvw4w==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "@cosmjs/crypto": "^0.30.1", - "@cosmjs/encoding": "^0.30.1", - "@cosmjs/math": "^0.30.1", - "@cosmjs/utils": "^0.30.1" - } - }, - "node_modules/@cosmjs/crypto": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/crypto/-/crypto-0.30.1.tgz", - "integrity": "sha512-rAljUlake3MSXs9xAm87mu34GfBLN0h/1uPPV6jEwClWjNkAMotzjC0ab9MARy5FFAvYHL3lWb57bhkbt2GtzQ==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "@cosmjs/encoding": "^0.30.1", - "@cosmjs/math": "^0.30.1", - "@cosmjs/utils": "^0.30.1", - "@noble/hashes": "^1", - "bn.js": "^5.2.0", - "elliptic": "^6.5.4", - "libsodium-wrappers": "^0.7.6" - } - }, - "node_modules/@cosmjs/encoding": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.30.1.tgz", - "integrity": "sha512-rXmrTbgqwihORwJ3xYhIgQFfMSrwLu1s43RIK9I8EBudPx3KmnmyAKzMOVsRDo9edLFNuZ9GIvysUCwQfq3WlQ==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "base64-js": "^1.3.0", - "bech32": "^1.1.4", - "readonly-date": "^1.0.0" - } - }, - "node_modules/@cosmjs/encoding/node_modules/bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", - "license": "MIT", - "optional": true - }, - "node_modules/@cosmjs/json-rpc": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/json-rpc/-/json-rpc-0.30.1.tgz", - "integrity": "sha512-pitfC/2YN9t+kXZCbNuyrZ6M8abnCC2n62m+JtU9vQUfaEtVsgy+1Fk4TRQ175+pIWSdBMFi2wT8FWVEE4RhxQ==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "@cosmjs/stream": "^0.30.1", - "xstream": "^11.14.0" - } - }, - "node_modules/@cosmjs/math": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.30.1.tgz", - "integrity": "sha512-yaoeI23pin9ZiPHIisa6qqLngfnBR/25tSaWpkTm8Cy10MX70UF5oN4+/t1heLaM6SSmRrhk3psRkV4+7mH51Q==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "bn.js": "^5.2.0" - } - }, - "node_modules/@cosmjs/proto-signing": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/proto-signing/-/proto-signing-0.30.1.tgz", - "integrity": "sha512-tXh8pPYXV4aiJVhTKHGyeZekjj+K9s2KKojMB93Gcob2DxUjfKapFYBMJSgfKPuWUPEmyr8Q9km2hplI38ILgQ==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "@cosmjs/amino": "^0.30.1", - "@cosmjs/crypto": "^0.30.1", - "@cosmjs/encoding": "^0.30.1", - "@cosmjs/math": "^0.30.1", - "@cosmjs/utils": "^0.30.1", - "cosmjs-types": "^0.7.1", - "long": "^4.0.0" - } - }, - "node_modules/@cosmjs/socket": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/socket/-/socket-0.30.1.tgz", - "integrity": "sha512-r6MpDL+9N+qOS/D5VaxnPaMJ3flwQ36G+vPvYJsXArj93BjgyFB7BwWwXCQDzZ+23cfChPUfhbINOenr8N2Kow==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "@cosmjs/stream": "^0.30.1", - "isomorphic-ws": "^4.0.1", - "ws": "^7", - "xstream": "^11.14.0" - } - }, - "node_modules/@cosmjs/stargate": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/stargate/-/stargate-0.30.1.tgz", - "integrity": "sha512-RdbYKZCGOH8gWebO7r6WvNnQMxHrNXInY/gPHPzMjbQF6UatA6fNM2G2tdgS5j5u7FTqlCI10stNXrknaNdzog==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "@confio/ics23": "^0.6.8", - "@cosmjs/amino": "^0.30.1", - "@cosmjs/encoding": "^0.30.1", - "@cosmjs/math": "^0.30.1", - "@cosmjs/proto-signing": "^0.30.1", - "@cosmjs/stream": "^0.30.1", - "@cosmjs/tendermint-rpc": "^0.30.1", - "@cosmjs/utils": "^0.30.1", - "cosmjs-types": "^0.7.1", - "long": "^4.0.0", - "protobufjs": "~6.11.3", - "xstream": "^11.14.0" - } - }, - "node_modules/@cosmjs/stargate/node_modules/protobufjs": { - "version": "6.11.4", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz", - "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==", - "hasInstallScript": true, - "license": "BSD-3-Clause", - "optional": true, - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": ">=13.7.0", - "long": "^4.0.0" - }, - "bin": { - "pbjs": "bin/pbjs", - "pbts": "bin/pbts" - } - }, - "node_modules/@cosmjs/stream": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/stream/-/stream-0.30.1.tgz", - "integrity": "sha512-Fg0pWz1zXQdoxQZpdHRMGvUH5RqS6tPv+j9Eh7Q953UjMlrwZVo0YFLC8OTf/HKVf10E4i0u6aM8D69Q6cNkgQ==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "xstream": "^11.14.0" - } - }, - "node_modules/@cosmjs/tendermint-rpc": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.30.1.tgz", - "integrity": "sha512-Z3nCwhXSbPZJ++v85zHObeUggrEHVfm1u18ZRwXxFE9ZMl5mXTybnwYhczuYOl7KRskgwlB+rID0WYACxj4wdQ==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "@cosmjs/crypto": "^0.30.1", - "@cosmjs/encoding": "^0.30.1", - "@cosmjs/json-rpc": "^0.30.1", - "@cosmjs/math": "^0.30.1", - "@cosmjs/socket": "^0.30.1", - "@cosmjs/stream": "^0.30.1", - "@cosmjs/utils": "^0.30.1", - "axios": "^0.21.2", - "readonly-date": "^1.0.0", - "xstream": "^11.14.0" - } - }, - "node_modules/@cosmjs/tendermint-rpc/node_modules/axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "license": "MIT", - "optional": true, - "dependencies": { - "follow-redirects": "^1.14.0" - } - }, - "node_modules/@cosmjs/utils": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.30.1.tgz", - "integrity": "sha512-KvvX58MGMWh7xA+N+deCfunkA/ZNDvFLw4YbOmX3f/XBIkqrVY7qlotfy2aNb1kgp6h4B6Yc8YawJPDTfvWX7g==", - "license": "Apache-2.0", - "optional": true - }, "node_modules/@esbuild/aix-ppc64": { "version": "0.25.3", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.3.tgz", @@ -883,1522 +512,78 @@ "node": ">=18" } }, - "node_modules/@ethereumjs/common": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.5.tgz", - "integrity": "sha512-lRyVQOeCDaIVtgfbowla32pzeDv2Obr8oR8Put5RdUBNRGr1VGPGQNGP6elWIpgK3YdpzqTOh4GyUGOureVeeA==", - "license": "MIT", - "optional": true, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", "dependencies": { - "crc-32": "^1.2.0", - "ethereumjs-util": "^7.1.5" + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" } }, - "node_modules/@ethereumjs/tx": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.5.2.tgz", - "integrity": "sha512-gQDNJWKrSDGu2w7w0PzVXVBNMzb7wwdDOmOqczmhNjqFxFuIbhVJDwiGEnxFNC2/b8ifcZzY7MLcluizohRzNw==", - "license": "MPL-2.0", - "optional": true, + "node_modules/@noble/curves": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.0.tgz", + "integrity": "sha512-7YDlXiNMdO1YZeH6t/kvopHHbIZzlxrCV9WLqCY6QhcXOoXiNCMDqJIglZ9Yjx5+w7Dz30TITFrlTjnRg7sKEg==", + "license": "MIT", "dependencies": { - "@ethereumjs/common": "^2.6.4", - "ethereumjs-util": "^7.1.5" + "@noble/hashes": "1.8.0" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@ethersproject/abi": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.8.0.tgz", - "integrity": "sha512-b9YS/43ObplgyV6SlyQsG53/vkSal0MNA1fskSC4mbnCMi8R+NkcH8K9FPYNESf6jUefBUniE4SOKms0E/KK1Q==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/address": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/constants": "^5.8.0", - "@ethersproject/hash": "^5.8.0", - "@ethersproject/keccak256": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/strings": "^5.8.0" - } - }, - "node_modules/@ethersproject/abstract-provider": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.8.0.tgz", - "integrity": "sha512-wC9SFcmh4UK0oKuLJQItoQdzS/qZ51EJegK6EmAWlh+OptpQ/npECOR3QqECd8iGHC0RJb4WKbVdSfif4ammrg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "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" - } - }, - "node_modules/@ethersproject/abstract-signer": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.8.0.tgz", - "integrity": "sha512-N0XhZTswXcmIZQdYtUnd79VJzvEwXQw6PK0dTl9VoYrEBxxCPXqS0Eod7q5TNKRxe1/5WUMuR0u0nqTF/avdCA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", "license": "MIT", - "optional": true, - "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" + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@ethersproject/address": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.8.0.tgz", - "integrity": "sha512-GhH/abcC46LJwshoN+uBNoKVFPxUuZm6dA257z0vZkKmU1+t8xTn8oK7B9qrj8W2rFRMch4gbJl6PmVxjxBEBA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@noble/secp256k1": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-2.2.3.tgz", + "integrity": "sha512-l7r5oEQym9Us7EAigzg30/PQAvynhMt2uoYtT3t26eGDVm9Yii5mZ5jWSWmZ/oSIR2Et0xfc6DXrG0bZ787V3w==", "license": "MIT", - "optional": true, - "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" + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@ethersproject/base64": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.8.0.tgz", - "integrity": "sha512-lN0oIwfkYj9LbPx4xEkie6rAMJtySbpOAFXSDVQaBnAzYfB4X2Qr+FXJGxMoc3Bxp2Sm8OwvzMrywxyw0gLjIQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, "license": "MIT", "optional": true, - "dependencies": { - "@ethersproject/bytes": "^5.8.0" + "engines": { + "node": ">=14" } }, - "node_modules/@ethersproject/basex": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.8.0.tgz", - "integrity": "sha512-PIgTszMlDRmNwW9nhS6iqtVfdTAKosA7llYXNmGPw4YAI1PUyMv28988wAb41/gHF/WqGdoLv0erHaRcHRKW2Q==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@scure/base": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.5.tgz", + "integrity": "sha512-9rE6EOVeIQzt5TSu4v+K523F8u6DhBsoZWPGKlnCshhlDhy0kJzUX4V+tr2dWmzF1GdekvThABoEQBGBQI7xZw==", "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/properties": "^5.8.0" - } - }, - "node_modules/@ethersproject/bignumber": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.8.0.tgz", - "integrity": "sha512-ZyaT24bHaSeJon2tGPKIiHszWjD/54Sz8t57Toch475lCLljC6MgPmxk7Gtzz+ddNN5LuHea9qhAe0x3D+uYPA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "bn.js": "^5.2.1" - } - }, - "node_modules/@ethersproject/bytes": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.8.0.tgz", - "integrity": "sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/logger": "^5.8.0" - } - }, - "node_modules/@ethersproject/constants": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.8.0.tgz", - "integrity": "sha512-wigX4lrf5Vu+axVTIvNsuL6YrV4O5AXl5ubcURKMEME5TnWBouUh0CDTWxZ2GpnRn1kcCgE7l8O5+VbV9QTTcg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/bignumber": "^5.8.0" - } - }, - "node_modules/@ethersproject/contracts": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.8.0.tgz", - "integrity": "sha512-0eFjGz9GtuAi6MZwhb4uvUM216F38xiuR0yYCjKJpNfSEy4HUM8hvqqBj9Jmm0IUz8l0xKEhWwLIhPgxNY0yvQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/abi": "^5.8.0", - "@ethersproject/abstract-provider": "^5.8.0", - "@ethersproject/abstract-signer": "^5.8.0", - "@ethersproject/address": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/constants": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/transactions": "^5.8.0" - } - }, - "node_modules/@ethersproject/hash": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.8.0.tgz", - "integrity": "sha512-ac/lBcTbEWW/VGJij0CNSw/wPcw9bSRgCB0AIBz8CvED/jfvDoV9hsIIiWfvWmFEi8RcXtlNwp2jv6ozWOsooA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "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" - } - }, - "node_modules/@ethersproject/hdnode": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.8.0.tgz", - "integrity": "sha512-4bK1VF6E83/3/Im0ERnnUeWOY3P1BZml4ZD3wcH8Ys0/d1h1xaFt6Zc+Dh9zXf9TapGro0T4wvO71UTCp3/uoA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/abstract-signer": "^5.8.0", - "@ethersproject/basex": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/pbkdf2": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/sha2": "^5.8.0", - "@ethersproject/signing-key": "^5.8.0", - "@ethersproject/strings": "^5.8.0", - "@ethersproject/transactions": "^5.8.0", - "@ethersproject/wordlists": "^5.8.0" - } - }, - "node_modules/@ethersproject/json-wallets": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.8.0.tgz", - "integrity": "sha512-HxblNck8FVUtNxS3VTEYJAcwiKYsBIF77W15HufqlBF9gGfhmYOJtYZp8fSDZtn9y5EaXTE87zDwzxRoTFk11w==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/abstract-signer": "^5.8.0", - "@ethersproject/address": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/hdnode": "^5.8.0", - "@ethersproject/keccak256": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/pbkdf2": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/random": "^5.8.0", - "@ethersproject/strings": "^5.8.0", - "@ethersproject/transactions": "^5.8.0", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" - } - }, - "node_modules/@ethersproject/keccak256": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.8.0.tgz", - "integrity": "sha512-A1pkKLZSz8pDaQ1ftutZoaN46I6+jvuqugx5KYNeQOPqq+JZ0Txm7dlWesCHB5cndJSu5vP2VKptKf7cksERng==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.8.0", - "js-sha3": "0.8.0" - } - }, - "node_modules/@ethersproject/logger": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.8.0.tgz", - "integrity": "sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT" - }, - "node_modules/@ethersproject/networks": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.8.0.tgz", - "integrity": "sha512-egPJh3aPVAzbHwq8DD7Po53J4OUSsA1MjQp8Vf/OZPav5rlmWUaFLiq8cvQiGK0Z5K6LYzm29+VA/p4RL1FzNg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/logger": "^5.8.0" - } - }, - "node_modules/@ethersproject/pbkdf2": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.8.0.tgz", - "integrity": "sha512-wuHiv97BrzCmfEaPbUFpMjlVg/IDkZThp9Ri88BpjRleg4iePJaj2SW8AIyE8cXn5V1tuAaMj6lzvsGJkGWskg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/sha2": "^5.8.0" - } - }, - "node_modules/@ethersproject/properties": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.8.0.tgz", - "integrity": "sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/logger": "^5.8.0" - } - }, - "node_modules/@ethersproject/providers": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.8.0.tgz", - "integrity": "sha512-3Il3oTzEx3o6kzcg9ZzbE+oCZYyY+3Zh83sKkn4s1DZfTUjIegHnN2Cm0kbn9YFy45FDVcuCLLONhU7ny0SsCw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/abstract-provider": "^5.8.0", - "@ethersproject/abstract-signer": "^5.8.0", - "@ethersproject/address": "^5.8.0", - "@ethersproject/base64": "^5.8.0", - "@ethersproject/basex": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/constants": "^5.8.0", - "@ethersproject/hash": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/networks": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/random": "^5.8.0", - "@ethersproject/rlp": "^5.8.0", - "@ethersproject/sha2": "^5.8.0", - "@ethersproject/strings": "^5.8.0", - "@ethersproject/transactions": "^5.8.0", - "@ethersproject/web": "^5.8.0", - "bech32": "1.1.4", - "ws": "8.18.0" - } - }, - "node_modules/@ethersproject/providers/node_modules/bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", - "license": "MIT", - "optional": true - }, - "node_modules/@ethersproject/providers/node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/@ethersproject/random": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.8.0.tgz", - "integrity": "sha512-E4I5TDl7SVqyg4/kkA/qTfuLWAQGXmSOgYyO01So8hLfwgKvYK5snIlzxJMk72IFdG/7oh8yuSqY2KX7MMwg+A==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/logger": "^5.8.0" - } - }, - "node_modules/@ethersproject/rlp": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.8.0.tgz", - "integrity": "sha512-LqZgAznqDbiEunaUvykH2JAoXTT9NV0Atqk8rQN9nx9SEgThA/WMx5DnW8a9FOufo//6FZOCHZ+XiClzgbqV9Q==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/logger": "^5.8.0" - } - }, - "node_modules/@ethersproject/sha2": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.8.0.tgz", - "integrity": "sha512-dDOUrXr9wF/YFltgTBYS0tKslPEKr6AekjqDW2dbn1L1xmjGR+9GiKu4ajxovnrDbwxAKdHjW8jNcwfz8PAz4A==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "hash.js": "1.1.7" - } - }, - "node_modules/@ethersproject/signing-key": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.8.0.tgz", - "integrity": "sha512-LrPW2ZxoigFi6U6aVkFN/fa9Yx/+4AtIUe4/HACTvKJdhm0eeb107EVCIQcrLZkxaSIgc/eCrX8Q1GtbH+9n3w==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "bn.js": "^5.2.1", - "elliptic": "6.6.1", - "hash.js": "1.1.7" - } - }, - "node_modules/@ethersproject/solidity": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.8.0.tgz", - "integrity": "sha512-4CxFeCgmIWamOHwYN9d+QWGxye9qQLilpgTU0XhYs1OahkclF+ewO+3V1U0mvpiuQxm5EHHmv8f7ClVII8EHsA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/keccak256": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/sha2": "^5.8.0", - "@ethersproject/strings": "^5.8.0" - } - }, - "node_modules/@ethersproject/strings": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.8.0.tgz", - "integrity": "sha512-qWEAk0MAvl0LszjdfnZ2uC8xbR2wdv4cDabyHiBh3Cldq/T8dPH3V4BbBsAYJUeonwD+8afVXld274Ls+Y1xXg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/constants": "^5.8.0", - "@ethersproject/logger": "^5.8.0" - } - }, - "node_modules/@ethersproject/transactions": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.8.0.tgz", - "integrity": "sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "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" - } - }, - "node_modules/@ethersproject/units": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.8.0.tgz", - "integrity": "sha512-lxq0CAnc5kMGIiWW4Mr041VT8IhNM+Pn5T3haO74XZWFulk7wH1Gv64HqE96hT4a7iiNMdOCFEBgaxWuk8ETKQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/constants": "^5.8.0", - "@ethersproject/logger": "^5.8.0" - } - }, - "node_modules/@ethersproject/wallet": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.8.0.tgz", - "integrity": "sha512-G+jnzmgg6UxurVKRKvw27h0kvG75YKXZKdlLYmAHeF32TGUzHkOFd7Zn6QHOTYRFWnfjtSSFjBowKo7vfrXzPA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/abstract-provider": "^5.8.0", - "@ethersproject/abstract-signer": "^5.8.0", - "@ethersproject/address": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/hash": "^5.8.0", - "@ethersproject/hdnode": "^5.8.0", - "@ethersproject/json-wallets": "^5.8.0", - "@ethersproject/keccak256": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/random": "^5.8.0", - "@ethersproject/signing-key": "^5.8.0", - "@ethersproject/transactions": "^5.8.0", - "@ethersproject/wordlists": "^5.8.0" - } - }, - "node_modules/@ethersproject/web": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.8.0.tgz", - "integrity": "sha512-j7+Ksi/9KfGviws6Qtf9Q7KCqRhpwrYKQPs+JBA/rKVFF/yaWLHJEH3zfVP2plVu+eys0d2DlFmhoQJayFewcw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "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" - } - }, - "node_modules/@ethersproject/wordlists": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.8.0.tgz", - "integrity": "sha512-2df9bbXicZws2Sb5S6ET493uJ0Z84Fjr3pC4tu/qlnZERibZCeUVuqdtt+7Tv9xxhUxHoIekIA7avrKUWHrezg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/hash": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/strings": "^5.8.0" - } - }, - "node_modules/@graphql-typed-document-node/core": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz", - "integrity": "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==", - "license": "MIT", - "optional": true, - "peerDependencies": { - "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" - } - }, - "node_modules/@improbable-eng/grpc-web": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/@improbable-eng/grpc-web/-/grpc-web-0.15.0.tgz", - "integrity": "sha512-ERft9/0/8CmYalqOVnJnpdDry28q+j+nAlFFARdjyxXDJ+Mhgv9+F600QC8BR9ygOfrXRlAk6CvST2j+JCpQPg==", - "license": "Apache-2.0", - "dependencies": { - "browser-headers": "^0.4.1" - }, - "peerDependencies": { - "google-protobuf": "^3.14.0" - } - }, - "node_modules/@injectivelabs/core-proto-ts": { - "version": "0.0.14", - "resolved": "https://registry.npmjs.org/@injectivelabs/core-proto-ts/-/core-proto-ts-0.0.14.tgz", - "integrity": "sha512-NZWlgBzgVrXow9IknFQHvcYKX4QkUD25taRigoNYQK8PDn4+VXd9xM5WFUDRhzm2smTCguyl/+MghpEp4oTPWw==", - "license": "MIT", - "optional": true, - "dependencies": { - "@injectivelabs/grpc-web": "^0.0.1", - "google-protobuf": "^3.14.0", - "protobufjs": "^7.0.0", - "rxjs": "^7.4.0" - } - }, - "node_modules/@injectivelabs/exceptions": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/@injectivelabs/exceptions/-/exceptions-1.15.1.tgz", - "integrity": "sha512-dUL6ks9G8I5VJYw7hXehf9OOYaN8bcB5/WCaseKfdzeBwe+yn/Dz/wXQ76NG+Rtknx85eqEkLZHX3LZMVU48cw==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "http-status-codes": "^2.3.0" - } - }, - "node_modules/@injectivelabs/grpc-web": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/@injectivelabs/grpc-web/-/grpc-web-0.0.1.tgz", - "integrity": "sha512-Pu5YgaZp+OvR5UWfqbrPdHer3+gDf+b5fQoY+t2VZx1IAVHX8bzbN9EreYTvTYtFeDpYRWM8P7app2u4EX5wTw==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "browser-headers": "^0.4.1" - }, - "peerDependencies": { - "google-protobuf": "^3.14.0" - } - }, - "node_modules/@injectivelabs/grpc-web-node-http-transport": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/@injectivelabs/grpc-web-node-http-transport/-/grpc-web-node-http-transport-0.0.2.tgz", - "integrity": "sha512-rpyhXLiGY/UMs6v6YmgWHJHiO9l0AgDyVNv+jcutNVt4tQrmNvnpvz2wCAGOFtq5LuX/E9ChtTVpk3gWGqXcGA==", - "license": "Apache-2.0", - "optional": true, - "peerDependencies": { - "@injectivelabs/grpc-web": ">=0.0.1" - } - }, - "node_modules/@injectivelabs/grpc-web-react-native-transport": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/@injectivelabs/grpc-web-react-native-transport/-/grpc-web-react-native-transport-0.0.2.tgz", - "integrity": "sha512-mk+aukQXnYNgPsPnu3KBi+FD0ZHQpazIlaBZ2jNZG7QAVmxTWtv3R66Zoq99Wx2dnE946NsZBYAoa0K5oSjnow==", - "license": "Apache-2.0", - "optional": true, - "peerDependencies": { - "@injectivelabs/grpc-web": ">=0.0.1" - } - }, - "node_modules/@injectivelabs/indexer-proto-ts": { - "version": "1.10.8-rc.4", - "resolved": "https://registry.npmjs.org/@injectivelabs/indexer-proto-ts/-/indexer-proto-ts-1.10.8-rc.4.tgz", - "integrity": "sha512-IwbepTfsHHAv3Z36As6yH/+HIplOEpUu6SFHBCVgdSIaQ8GuvTib4HETiVnV4mjYqoyVgWs+zLSAfih46rdMJQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "@injectivelabs/grpc-web": "^0.0.1", - "google-protobuf": "^3.14.0", - "protobufjs": "^7.0.0", - "rxjs": "^7.4.0" - } - }, - "node_modules/@injectivelabs/mito-proto-ts": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@injectivelabs/mito-proto-ts/-/mito-proto-ts-1.0.9.tgz", - "integrity": "sha512-+TZMvJ4SHwcn6SFPdqaiQFZdNhjH7hyRFozY15nOTC2utdGij9jEsjz1NsyOejfYDA0s1z5Wm1SgrMYKaVpAmQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "@injectivelabs/grpc-web": "^0.0.1", - "google-protobuf": "^3.14.0", - "protobufjs": "^7.0.0", - "rxjs": "^7.4.0" - } - }, - "node_modules/@injectivelabs/networks": { - "version": "1.10.12", - "resolved": "https://registry.npmjs.org/@injectivelabs/networks/-/networks-1.10.12.tgz", - "integrity": "sha512-tTHyLls1Nik5QTs/S03qqG2y/ITvNwI8CJOQbMmmsr1CL2CdjJBtzRYn9Dyx2p8XgzRFf9hmlybpe20tq9O3SA==", - "hasInstallScript": true, - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "@injectivelabs/exceptions": "^1.10.12", - "@injectivelabs/ts-types": "^1.10.12", - "@injectivelabs/utils": "^1.10.12", - "link-module-alias": "^1.2.0", - "shx": "^0.3.2" - } - }, - "node_modules/@injectivelabs/sdk-ts": { - "version": "1.10.72", - "resolved": "https://registry.npmjs.org/@injectivelabs/sdk-ts/-/sdk-ts-1.10.72.tgz", - "integrity": "sha512-A5mHNNBgO4fI1c/7CZ0bGfVXliy8laP+VaYZ++aWh1YyudoZw4CTCEmLetZRy7AUU3XcfbHa8sAImRi7db+v6Q==", - "hasInstallScript": true, - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "@apollo/client": "^3.5.8", - "@cosmjs/amino": "^0.30.1", - "@cosmjs/proto-signing": "^0.30.1", - "@cosmjs/stargate": "^0.30.1", - "@ethersproject/bytes": "^5.7.0", - "@injectivelabs/core-proto-ts": "^0.0.14", - "@injectivelabs/exceptions": "^1.10.12", - "@injectivelabs/grpc-web": "^0.0.1", - "@injectivelabs/grpc-web-node-http-transport": "^0.0.2", - "@injectivelabs/grpc-web-react-native-transport": "^0.0.2", - "@injectivelabs/indexer-proto-ts": "1.10.8-rc.4", - "@injectivelabs/mito-proto-ts": "1.0.9", - "@injectivelabs/networks": "^1.10.12", - "@injectivelabs/test-utils": "^1.10.12", - "@injectivelabs/token-metadata": "^1.10.42", - "@injectivelabs/ts-types": "^1.10.12", - "@injectivelabs/utils": "^1.10.12", - "@metamask/eth-sig-util": "^4.0.0", - "axios": "^0.27.2", - "bech32": "^2.0.0", - "bip39": "^3.0.4", - "cosmjs-types": "^0.7.1", - "eth-crypto": "^2.6.0", - "ethereumjs-util": "^7.1.4", - "ethers": "^5.7.2", - "google-protobuf": "^3.21.0", - "graphql": "^16.3.0", - "http-status-codes": "^2.2.0", - "js-sha3": "^0.8.0", - "jscrypto": "^1.0.3", - "keccak256": "^1.0.6", - "link-module-alias": "^1.2.0", - "rxjs": "^7.8.0", - "secp256k1": "^4.0.3", - "shx": "^0.3.2", - "snakecase-keys": "^5.4.1" - } - }, - "node_modules/@injectivelabs/sdk-ts/node_modules/@apollo/client": { - "version": "3.13.8", - "resolved": "https://registry.npmjs.org/@apollo/client/-/client-3.13.8.tgz", - "integrity": "sha512-YM9lQpm0VfVco4DSyKooHS/fDTiKQcCHfxr7i3iL6a0kP/jNO5+4NFK6vtRDxaYisd5BrwOZHLJpPBnvRVpKPg==", - "license": "MIT", - "optional": true, - "dependencies": { - "@graphql-typed-document-node/core": "^3.1.1", - "@wry/caches": "^1.0.0", - "@wry/equality": "^0.5.6", - "@wry/trie": "^0.5.0", - "graphql-tag": "^2.12.6", - "hoist-non-react-statics": "^3.3.2", - "optimism": "^0.18.0", - "prop-types": "^15.7.2", - "rehackt": "^0.1.0", - "symbol-observable": "^4.0.0", - "ts-invariant": "^0.10.3", - "tslib": "^2.3.0", - "zen-observable-ts": "^1.2.5" - }, - "peerDependencies": { - "graphql": "^15.0.0 || ^16.0.0", - "graphql-ws": "^5.5.5 || ^6.0.3", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc", - "subscriptions-transport-ws": "^0.9.0 || ^0.11.0" - }, - "peerDependenciesMeta": { - "graphql-ws": { - "optional": true - }, - "react": { - "optional": true - }, - "react-dom": { - "optional": true - }, - "subscriptions-transport-ws": { - "optional": true - } - } - }, - "node_modules/@injectivelabs/sdk-ts/node_modules/axios": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", - "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "follow-redirects": "^1.14.9", - "form-data": "^4.0.0" - } - }, - "node_modules/@injectivelabs/sdk-ts/node_modules/symbol-observable": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", - "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/@injectivelabs/test-utils": { - "version": "1.14.41", - "resolved": "https://registry.npmjs.org/@injectivelabs/test-utils/-/test-utils-1.14.41.tgz", - "integrity": "sha512-++xeSobV62Yd67cIK6xCepZIU+YxQx/I9I5UT1pMOfostiCxQusKWsJhAKNjwkWbKNvFZifEw6TWwU3UYhneBQ==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "@injectivelabs/exceptions": "^1.14.41", - "@injectivelabs/networks": "^1.14.41", - "@injectivelabs/ts-types": "^1.14.41", - "@injectivelabs/utils": "^1.14.41", - "axios": "^1.6.4", - "bignumber.js": "^9.0.1", - "shx": "^0.3.2", - "snakecase-keys": "^5.1.2", - "store2": "^2.12.0" - } - }, - "node_modules/@injectivelabs/test-utils/node_modules/@injectivelabs/networks": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/@injectivelabs/networks/-/networks-1.15.2.tgz", - "integrity": "sha512-b1fvxzUdgrvw2aFgWjf7tIMDnqhIImmAMnkLBdOP1f4/eZKEk3NgoBJxdoixhGWW/v9XFfR66X5PVB0mNz85TA==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "@injectivelabs/ts-types": "^1.15.2" - } - }, - "node_modules/@injectivelabs/test-utils/node_modules/@injectivelabs/utils": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/@injectivelabs/utils/-/utils-1.15.2.tgz", - "integrity": "sha512-Fs1FuNhkTijrzUEDjBH6N3xuqdOaAWob/l+6IonUuGFcmLdmiFFFgUnepnkKgn2vgQDlqu2vc+JpfWSE4BSNoQ==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "@bangjelkoski/store2": "^2.14.3", - "@injectivelabs/exceptions": "^1.15.1", - "@injectivelabs/networks": "^1.15.2", - "@injectivelabs/ts-types": "^1.15.2", - "axios": "^1.8.1", - "bignumber.js": "^9.1.2", - "http-status-codes": "^2.3.0" - } - }, - "node_modules/@injectivelabs/test-utils/node_modules/axios": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz", - "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==", - "license": "MIT", - "optional": true, - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/@injectivelabs/token-metadata": { - "version": "1.14.11", - "resolved": "https://registry.npmjs.org/@injectivelabs/token-metadata/-/token-metadata-1.14.11.tgz", - "integrity": "sha512-WKJlvjKiTRHxpOeez4kYrzIwgWmpspD1IMxWclkTysAcwGltUfUsvUhu1cKuACleIjFFWmiZv/HoGRFdvEAZ8w==", - "hasInstallScript": true, - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "@injectivelabs/exceptions": "^1.14.11", - "@injectivelabs/networks": "^1.14.11", - "@injectivelabs/ts-types": "^1.14.11", - "@injectivelabs/utils": "^1.14.11", - "@types/lodash.values": "^4.3.6", - "copyfiles": "^2.4.1", - "jsonschema": "^1.4.0", - "link-module-alias": "^1.2.0", - "lodash": "^4.17.21", - "lodash.values": "^4.3.0", - "shx": "^0.3.2" - } - }, - "node_modules/@injectivelabs/token-metadata/node_modules/@injectivelabs/networks": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/@injectivelabs/networks/-/networks-1.15.2.tgz", - "integrity": "sha512-b1fvxzUdgrvw2aFgWjf7tIMDnqhIImmAMnkLBdOP1f4/eZKEk3NgoBJxdoixhGWW/v9XFfR66X5PVB0mNz85TA==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "@injectivelabs/ts-types": "^1.15.2" - } - }, - "node_modules/@injectivelabs/token-metadata/node_modules/@injectivelabs/utils": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/@injectivelabs/utils/-/utils-1.15.2.tgz", - "integrity": "sha512-Fs1FuNhkTijrzUEDjBH6N3xuqdOaAWob/l+6IonUuGFcmLdmiFFFgUnepnkKgn2vgQDlqu2vc+JpfWSE4BSNoQ==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "@bangjelkoski/store2": "^2.14.3", - "@injectivelabs/exceptions": "^1.15.1", - "@injectivelabs/networks": "^1.15.2", - "@injectivelabs/ts-types": "^1.15.2", - "axios": "^1.8.1", - "bignumber.js": "^9.1.2", - "http-status-codes": "^2.3.0" - } - }, - "node_modules/@injectivelabs/token-metadata/node_modules/axios": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz", - "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==", - "license": "MIT", - "optional": true, - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/@injectivelabs/ts-types": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/@injectivelabs/ts-types/-/ts-types-1.15.2.tgz", - "integrity": "sha512-NE0yYKP/HIP1+V1gDH6ooAf/kq5UpY14BXHb1a4DOljudSv0znj5WSqeDLPcSoUkzdycrCj+MuxtDBAogi55nw==", - "license": "Apache-2.0", - "optional": true - }, - "node_modules/@injectivelabs/utils": { - "version": "1.10.12", - "resolved": "https://registry.npmjs.org/@injectivelabs/utils/-/utils-1.10.12.tgz", - "integrity": "sha512-c8al79nxIJgV1cBAdW2TPDGldj/8gm5k0h5TIN/AJs8/AeIjpTwwVGfLY3QvPOpRsxuQ9CjBkTXrAcSL1wwkcw==", - "hasInstallScript": true, - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "@injectivelabs/exceptions": "^1.10.12", - "@injectivelabs/ts-types": "^1.10.12", - "axios": "^0.21.1", - "bignumber.js": "^9.0.1", - "http-status-codes": "^2.2.0", - "link-module-alias": "^1.2.0", - "shx": "^0.3.2", - "snakecase-keys": "^5.1.2", - "store2": "^2.12.0" - } - }, - "node_modules/@injectivelabs/utils/node_modules/axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "license": "MIT", - "optional": true, - "dependencies": { - "follow-redirects": "^1.14.0" - } - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@metamask/eth-sig-util": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", - "integrity": "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==", - "license": "ISC", - "optional": true, - "dependencies": { - "ethereumjs-abi": "^0.6.8", - "ethereumjs-util": "^6.2.1", - "ethjs-util": "^0.1.6", - "tweetnacl": "^1.0.3", - "tweetnacl-util": "^0.15.1" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@metamask/eth-sig-util/node_modules/@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "license": "MIT", - "optional": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@metamask/eth-sig-util/node_modules/bn.js": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", - "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", - "license": "MIT", - "optional": true - }, - "node_modules/@metamask/eth-sig-util/node_modules/ethereumjs-util": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", - "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", - "license": "MPL-2.0", - "optional": true, - "dependencies": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - }, - "node_modules/@mysten/bcs": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/@mysten/bcs/-/bcs-0.7.1.tgz", - "integrity": "sha512-wFPb8bkhwrbiStfZMV5rFM7J+umpke59/dNjDp+UYJKykNlW23LCk2ePyEUvGdb62HGJM1jyOJ8g4egE3OmdKA==", - "license": "Apache-2.0", - "dependencies": { - "bs58": "^5.0.0" - } - }, - "node_modules/@mysten/bcs/node_modules/base-x": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.1.tgz", - "integrity": "sha512-uAZ8x6r6S3aUM9rbHGVOIsR15U/ZSc82b3ymnCPsT45Gk1DDvhDPdIgB5MrhirZWt+5K0EEPQH985kNqZgNPFw==", - "license": "MIT" - }, - "node_modules/@mysten/bcs/node_modules/bs58": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz", - "integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==", - "license": "MIT", - "dependencies": { - "base-x": "^4.0.0" - } - }, - "node_modules/@mysten/sui.js": { - "version": "0.32.2", - "resolved": "https://registry.npmjs.org/@mysten/sui.js/-/sui.js-0.32.2.tgz", - "integrity": "sha512-/Hm4xkGolJhqj8FvQr7QSHDTlxIvL52mtbOao9f75YjrBh7y1Uh9kbJSY7xiTF1NY9sv6p5hUVlYRJuM0Hvn9A==", - "deprecated": "This package has been renamed to @mysten/sui, please update to use the renamed package.", - "license": "Apache-2.0", - "dependencies": { - "@mysten/bcs": "0.7.1", - "@noble/curves": "^1.0.0", - "@noble/hashes": "^1.3.0", - "@scure/bip32": "^1.3.0", - "@scure/bip39": "^1.2.0", - "@suchipi/femver": "^1.0.0", - "jayson": "^4.0.0", - "rpc-websockets": "^7.5.1", - "superstruct": "^1.0.3", - "tweetnacl": "^1.0.3" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/@mysten/sui.js/node_modules/rpc-websockets": { - "version": "7.11.2", - "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.11.2.tgz", - "integrity": "sha512-pL9r5N6AVHlMN/vT98+fcO+5+/UcPLf/4tq+WUaid/PPUGS/ttJ3y8e9IqmaWKtShNAysMSjkczuEA49NuV7UQ==", - "license": "LGPL-3.0-only", - "dependencies": { - "eventemitter3": "^4.0.7", - "uuid": "^8.3.2", - "ws": "^8.5.0" - }, - "funding": { - "type": "paypal", - "url": "https://paypal.me/kozjak" - }, - "optionalDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - } - }, - "node_modules/@mysten/sui.js/node_modules/superstruct": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-1.0.4.tgz", - "integrity": "sha512-7JpaAoX2NGyoFlI9NBh66BQXGONc+uE+MRS5i2iOBKuS4e+ccgMDjATgZldkah+33DakBxDHiss9kvUcGAO8UQ==", - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@mysten/sui.js/node_modules/ws": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz", - "integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/@noble/curves": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.0.tgz", - "integrity": "sha512-7YDlXiNMdO1YZeH6t/kvopHHbIZzlxrCV9WLqCY6QhcXOoXiNCMDqJIglZ9Yjx5+w7Dz30TITFrlTjnRg7sKEg==", - "license": "MIT", - "dependencies": { - "@noble/hashes": "1.8.0" - }, - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@noble/hashes": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", - "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@noble/secp256k1": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-2.2.3.tgz", - "integrity": "sha512-l7r5oEQym9Us7EAigzg30/PQAvynhMt2uoYtT3t26eGDVm9Yii5mZ5jWSWmZ/oSIR2Et0xfc6DXrG0bZ787V3w==", - "license": "MIT", - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@project-serum/anchor": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@project-serum/anchor/-/anchor-0.25.0.tgz", - "integrity": "sha512-E6A5Y/ijqpfMJ5psJvbw0kVTzLZFUcOFgs6eSM2M2iWE1lVRF18T6hWZVNl6zqZsoz98jgnNHtVGJMs+ds9A7A==", - "license": "(MIT OR Apache-2.0)", - "dependencies": { - "@project-serum/borsh": "^0.2.5", - "@solana/web3.js": "^1.36.0", - "base64-js": "^1.5.1", - "bn.js": "^5.1.2", - "bs58": "^4.0.1", - "buffer-layout": "^1.2.2", - "camelcase": "^5.3.1", - "cross-fetch": "^3.1.5", - "crypto-hash": "^1.3.0", - "eventemitter3": "^4.0.7", - "js-sha256": "^0.9.0", - "pako": "^2.0.3", - "snake-case": "^3.0.4", - "superstruct": "^0.15.4", - "toml": "^3.0.0" - }, - "engines": { - "node": ">=11" - } - }, - "node_modules/@project-serum/anchor/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/@project-serum/borsh": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@project-serum/borsh/-/borsh-0.2.5.tgz", - "integrity": "sha512-UmeUkUoKdQ7rhx6Leve1SssMR/Ghv8qrEiyywyxSWg7ooV7StdpPBhciiy5eB3T0qU1BXvdRNC8TdrkxK7WC5Q==", - "license": "Apache-2.0", - "dependencies": { - "bn.js": "^5.1.2", - "buffer-layout": "^1.2.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@solana/web3.js": "^1.2.0" - } - }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", - "license": "BSD-3-Clause", - "dependencies": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", - "license": "BSD-3-Clause" - }, - "node_modules/@scure/base": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.5.tgz", - "integrity": "sha512-9rE6EOVeIQzt5TSu4v+K523F8u6DhBsoZWPGKlnCshhlDhy0kJzUX4V+tr2dWmzF1GdekvThABoEQBGBQI7xZw==", - "license": "MIT", - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip32": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.7.0.tgz", - "integrity": "sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==", - "license": "MIT", - "dependencies": { - "@noble/curves": "~1.9.0", - "@noble/hashes": "~1.8.0", - "@scure/base": "~1.2.5" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip39": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.6.0.tgz", - "integrity": "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==", - "license": "MIT", - "dependencies": { - "@noble/hashes": "~1.8.0", - "@scure/base": "~1.2.5" - }, - "funding": { - "url": "https://paulmillr.com/funding/" + "funding": { + "url": "https://paulmillr.com/funding/" } }, "node_modules/@solana/buffer-layout": { @@ -2428,22 +613,6 @@ "node": ">= 10" } }, - "node_modules/@solana/codecs": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@solana/codecs/-/codecs-2.0.0-rc.1.tgz", - "integrity": "sha512-qxoR7VybNJixV51L0G1RD2boZTcxmwUWnKCaJJExQ5qNKwbpSyDdWfFJfM5JhGyKe9DnPVOZB+JHWXnpbZBqrQ==", - "license": "MIT", - "dependencies": { - "@solana/codecs-core": "2.0.0-rc.1", - "@solana/codecs-data-structures": "2.0.0-rc.1", - "@solana/codecs-numbers": "2.0.0-rc.1", - "@solana/codecs-strings": "2.0.0-rc.1", - "@solana/options": "2.0.0-rc.1" - }, - "peerDependencies": { - "typescript": ">=5" - } - }, "node_modules/@solana/codecs-core": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@solana/codecs-core/-/codecs-core-2.1.0.tgz", @@ -2459,82 +628,6 @@ "typescript": ">=5" } }, - "node_modules/@solana/codecs-data-structures": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@solana/codecs-data-structures/-/codecs-data-structures-2.0.0-rc.1.tgz", - "integrity": "sha512-rinCv0RrAVJ9rE/rmaibWJQxMwC5lSaORSZuwjopSUE6T0nb/MVg6Z1siNCXhh/HFTOg0l8bNvZHgBcN/yvXog==", - "license": "MIT", - "dependencies": { - "@solana/codecs-core": "2.0.0-rc.1", - "@solana/codecs-numbers": "2.0.0-rc.1", - "@solana/errors": "2.0.0-rc.1" - }, - "peerDependencies": { - "typescript": ">=5" - } - }, - "node_modules/@solana/codecs-data-structures/node_modules/@solana/codecs-core": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@solana/codecs-core/-/codecs-core-2.0.0-rc.1.tgz", - "integrity": "sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ==", - "license": "MIT", - "dependencies": { - "@solana/errors": "2.0.0-rc.1" - }, - "peerDependencies": { - "typescript": ">=5" - } - }, - "node_modules/@solana/codecs-data-structures/node_modules/@solana/codecs-numbers": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@solana/codecs-numbers/-/codecs-numbers-2.0.0-rc.1.tgz", - "integrity": "sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ==", - "license": "MIT", - "dependencies": { - "@solana/codecs-core": "2.0.0-rc.1", - "@solana/errors": "2.0.0-rc.1" - }, - "peerDependencies": { - "typescript": ">=5" - } - }, - "node_modules/@solana/codecs-data-structures/node_modules/@solana/errors": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@solana/errors/-/errors-2.0.0-rc.1.tgz", - "integrity": "sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ==", - "license": "MIT", - "dependencies": { - "chalk": "^5.3.0", - "commander": "^12.1.0" - }, - "bin": { - "errors": "bin/cli.mjs" - }, - "peerDependencies": { - "typescript": ">=5" - } - }, - "node_modules/@solana/codecs-data-structures/node_modules/chalk": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", - "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@solana/codecs-data-structures/node_modules/commander": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", - "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, "node_modules/@solana/codecs-numbers": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@solana/codecs-numbers/-/codecs-numbers-2.1.0.tgz", @@ -2551,145 +644,6 @@ "typescript": ">=5" } }, - "node_modules/@solana/codecs-strings": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@solana/codecs-strings/-/codecs-strings-2.0.0-rc.1.tgz", - "integrity": "sha512-9/wPhw8TbGRTt6mHC4Zz1RqOnuPTqq1Nb4EyuvpZ39GW6O2t2Q7Q0XxiB3+BdoEjwA2XgPw6e2iRfvYgqty44g==", - "license": "MIT", - "dependencies": { - "@solana/codecs-core": "2.0.0-rc.1", - "@solana/codecs-numbers": "2.0.0-rc.1", - "@solana/errors": "2.0.0-rc.1" - }, - "peerDependencies": { - "fastestsmallesttextencoderdecoder": "^1.0.22", - "typescript": ">=5" - } - }, - "node_modules/@solana/codecs-strings/node_modules/@solana/codecs-core": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@solana/codecs-core/-/codecs-core-2.0.0-rc.1.tgz", - "integrity": "sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ==", - "license": "MIT", - "dependencies": { - "@solana/errors": "2.0.0-rc.1" - }, - "peerDependencies": { - "typescript": ">=5" - } - }, - "node_modules/@solana/codecs-strings/node_modules/@solana/codecs-numbers": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@solana/codecs-numbers/-/codecs-numbers-2.0.0-rc.1.tgz", - "integrity": "sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ==", - "license": "MIT", - "dependencies": { - "@solana/codecs-core": "2.0.0-rc.1", - "@solana/errors": "2.0.0-rc.1" - }, - "peerDependencies": { - "typescript": ">=5" - } - }, - "node_modules/@solana/codecs-strings/node_modules/@solana/errors": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@solana/errors/-/errors-2.0.0-rc.1.tgz", - "integrity": "sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ==", - "license": "MIT", - "dependencies": { - "chalk": "^5.3.0", - "commander": "^12.1.0" - }, - "bin": { - "errors": "bin/cli.mjs" - }, - "peerDependencies": { - "typescript": ">=5" - } - }, - "node_modules/@solana/codecs-strings/node_modules/chalk": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", - "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@solana/codecs-strings/node_modules/commander": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", - "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/@solana/codecs/node_modules/@solana/codecs-core": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@solana/codecs-core/-/codecs-core-2.0.0-rc.1.tgz", - "integrity": "sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ==", - "license": "MIT", - "dependencies": { - "@solana/errors": "2.0.0-rc.1" - }, - "peerDependencies": { - "typescript": ">=5" - } - }, - "node_modules/@solana/codecs/node_modules/@solana/codecs-numbers": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@solana/codecs-numbers/-/codecs-numbers-2.0.0-rc.1.tgz", - "integrity": "sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ==", - "license": "MIT", - "dependencies": { - "@solana/codecs-core": "2.0.0-rc.1", - "@solana/errors": "2.0.0-rc.1" - }, - "peerDependencies": { - "typescript": ">=5" - } - }, - "node_modules/@solana/codecs/node_modules/@solana/errors": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@solana/errors/-/errors-2.0.0-rc.1.tgz", - "integrity": "sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ==", - "license": "MIT", - "dependencies": { - "chalk": "^5.3.0", - "commander": "^12.1.0" - }, - "bin": { - "errors": "bin/cli.mjs" - }, - "peerDependencies": { - "typescript": ">=5" - } - }, - "node_modules/@solana/codecs/node_modules/chalk": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", - "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@solana/codecs/node_modules/commander": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", - "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, "node_modules/@solana/errors": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@solana/errors/-/errors-2.1.0.tgz", @@ -2721,115 +675,21 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/@solana/options": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@solana/options/-/options-2.0.0-rc.1.tgz", - "integrity": "sha512-mLUcR9mZ3qfHlmMnREdIFPf9dpMc/Bl66tLSOOWxw4ml5xMT2ohFn7WGqoKcu/UHkT9CrC6+amEdqCNvUqI7AA==", - "license": "MIT", - "dependencies": { - "@solana/codecs-core": "2.0.0-rc.1", - "@solana/codecs-data-structures": "2.0.0-rc.1", - "@solana/codecs-numbers": "2.0.0-rc.1", - "@solana/codecs-strings": "2.0.0-rc.1", - "@solana/errors": "2.0.0-rc.1" - }, - "peerDependencies": { - "typescript": ">=5" - } - }, - "node_modules/@solana/options/node_modules/@solana/codecs-core": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@solana/codecs-core/-/codecs-core-2.0.0-rc.1.tgz", - "integrity": "sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ==", - "license": "MIT", - "dependencies": { - "@solana/errors": "2.0.0-rc.1" - }, - "peerDependencies": { - "typescript": ">=5" - } - }, - "node_modules/@solana/options/node_modules/@solana/codecs-numbers": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@solana/codecs-numbers/-/codecs-numbers-2.0.0-rc.1.tgz", - "integrity": "sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ==", - "license": "MIT", - "dependencies": { - "@solana/codecs-core": "2.0.0-rc.1", - "@solana/errors": "2.0.0-rc.1" - }, - "peerDependencies": { - "typescript": ">=5" - } - }, - "node_modules/@solana/options/node_modules/@solana/errors": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@solana/errors/-/errors-2.0.0-rc.1.tgz", - "integrity": "sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ==", - "license": "MIT", - "dependencies": { - "chalk": "^5.3.0", - "commander": "^12.1.0" - }, - "bin": { - "errors": "bin/cli.mjs" - }, - "peerDependencies": { - "typescript": ">=5" - } - }, - "node_modules/@solana/options/node_modules/chalk": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", - "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@solana/options/node_modules/commander": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", - "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/@solana/spl-token": { - "version": "0.3.11", - "resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.3.11.tgz", - "integrity": "sha512-bvohO3rIMSVL24Pb+I4EYTJ6cL82eFpInEXD/I8K8upOGjpqHsKUoAempR/RnUlI1qSFNyFlWJfu6MNUgfbCQQ==", - "license": "Apache-2.0", - "dependencies": { - "@solana/buffer-layout": "^4.0.0", - "@solana/buffer-layout-utils": "^0.2.0", - "@solana/spl-token-metadata": "^0.1.2", - "buffer": "^6.0.3" - }, - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "@solana/web3.js": "^1.88.0" - } - }, - "node_modules/@solana/spl-token-metadata": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@solana/spl-token-metadata/-/spl-token-metadata-0.1.6.tgz", - "integrity": "sha512-7sMt1rsm/zQOQcUWllQX9mD2O6KhSAtY1hFR2hfFwgqfFWzSY9E9GDvFVNYUI1F0iQKcm6HmePU9QbKRXTEBiA==", + "node_modules/@solana/spl-token": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.3.9.tgz", + "integrity": "sha512-1EXHxKICMnab35MvvY/5DBc/K/uQAOJCYnDZXw83McCAYUAfi+rwq6qfd6MmITmSTEhcfBcl/zYxmW/OSN0RmA==", "license": "Apache-2.0", "dependencies": { - "@solana/codecs": "2.0.0-rc.1" + "@solana/buffer-layout": "^4.0.0", + "@solana/buffer-layout-utils": "^0.2.0", + "buffer": "^6.0.3" }, "engines": { "node": ">=16" }, "peerDependencies": { - "@solana/web3.js": "^1.95.3" + "@solana/web3.js": "^1.47.4" } }, "node_modules/@solana/web3.js": { @@ -2864,12 +724,6 @@ "node": ">=14.0.0" } }, - "node_modules/@suchipi/femver": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@suchipi/femver/-/femver-1.0.0.tgz", - "integrity": "sha512-bprE8+K5V+DPX7q2e2K57ImqNBdfGHDIWaGI5xHxZoxbKOuQZn4wzPiUxOAHnsUr3w3xHrWXwN7gnG/iIuEMIg==", - "license": "MIT" - }, "node_modules/@swc/helpers": { "version": "0.5.17", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz", @@ -2879,133 +733,11 @@ "tslib": "^2.8.0" } }, - "node_modules/@terra-money/legacy.proto": { - "name": "@terra-money/terra.proto", - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@terra-money/terra.proto/-/terra.proto-0.1.7.tgz", - "integrity": "sha512-NXD7f6pQCulvo6+mv6MAPzhOkUzRjgYVuHZE/apih+lVnPG5hDBU0rRYnOGGofwvKT5/jQoOENnFn/gioWWnyQ==", - "license": "Apache-2.0", - "dependencies": { - "google-protobuf": "^3.17.3", - "long": "^4.0.0", - "protobufjs": "~6.11.2" - } - }, - "node_modules/@terra-money/legacy.proto/node_modules/protobufjs": { - "version": "6.11.4", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz", - "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==", - "hasInstallScript": true, - "license": "BSD-3-Clause", - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": ">=13.7.0", - "long": "^4.0.0" - }, - "bin": { - "pbjs": "bin/pbjs", - "pbts": "bin/pbts" - } - }, - "node_modules/@terra-money/terra.js": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/@terra-money/terra.js/-/terra.js-3.1.9.tgz", - "integrity": "sha512-JulSvOHLM56fL7s+cIjIbZeWPBluq883X1soWxA4TG5rKkDythT/DHeLXr3jP5Ld/26VENPSg6lNvK7cEYKpiw==", - "license": "MIT", - "dependencies": { - "@classic-terra/terra.proto": "^1.1.0", - "@terra-money/terra.proto": "^2.1.0", - "axios": "^0.27.2", - "bech32": "^2.0.0", - "bip32": "^2.0.6", - "bip39": "^3.0.3", - "bufferutil": "^4.0.3", - "decimal.js": "^10.2.1", - "jscrypto": "^1.0.1", - "readable-stream": "^3.6.0", - "secp256k1": "^4.0.2", - "tmp": "^0.2.1", - "utf-8-validate": "^5.0.5", - "ws": "^7.5.9" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@terra-money/terra.js/node_modules/axios": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", - "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.14.9", - "form-data": "^4.0.0" - } - }, - "node_modules/@terra-money/terra.proto": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@terra-money/terra.proto/-/terra.proto-2.1.0.tgz", - "integrity": "sha512-rhaMslv3Rkr+QsTQEZs64FKA4QlfO0DfQHaR6yct/EovenMkibDEQ63dEL6yJA6LCaEQGYhyVB9JO9pTUA8ybw==", - "license": "Apache-2.0", - "dependencies": { - "@improbable-eng/grpc-web": "^0.14.1", - "google-protobuf": "^3.17.3", - "long": "^4.0.0", - "protobufjs": "~6.11.2" - } - }, - "node_modules/@terra-money/terra.proto/node_modules/@improbable-eng/grpc-web": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@improbable-eng/grpc-web/-/grpc-web-0.14.1.tgz", - "integrity": "sha512-XaIYuunepPxoiGVLLHmlnVminUGzBTnXr8Wv7khzmLWbNw4TCwJKX09GSMJlKhu/TRk6gms0ySFxewaETSBqgw==", - "license": "Apache-2.0", - "dependencies": { - "browser-headers": "^0.4.1" - }, - "peerDependencies": { - "google-protobuf": "^3.14.0" - } - }, - "node_modules/@terra-money/terra.proto/node_modules/protobufjs": { - "version": "6.11.4", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz", - "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==", - "hasInstallScript": true, - "license": "BSD-3-Clause", - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": ">=13.7.0", - "long": "^4.0.0" - }, - "bin": { - "pbjs": "bin/pbjs", - "pbts": "bin/pbts" - } - }, "node_modules/@types/bn.js": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.6.tgz", "integrity": "sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w==", + "dev": true, "license": "MIT", "dependencies": { "@types/node": "*" @@ -3018,16 +750,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/chai-as-promised": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-8.0.2.tgz", - "integrity": "sha512-meQ1wDr1K5KRCSvG2lX7n7/5wf70BeptTKst0axGvnN6zqaVpRqegoIbugiAPSqOW9K9aL8gDVrm7a2LXOtn2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/chai": "*" - } - }, "node_modules/@types/connect": { "version": "3.4.38", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", @@ -3037,29 +759,6 @@ "@types/node": "*" } }, - "node_modules/@types/lodash": { - "version": "4.17.16", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.16.tgz", - "integrity": "sha512-HX7Em5NYQAXKW+1T+FiuG27NGwzJfCX3s1GjOa7ujxZa52kjJLOr4FUxT+giF6Tgxv1e+/czV/iTtBw27WTU9g==", - "license": "MIT", - "optional": true - }, - "node_modules/@types/lodash.values": { - "version": "4.3.9", - "resolved": "https://registry.npmjs.org/@types/lodash.values/-/lodash.values-4.3.9.tgz", - "integrity": "sha512-IJ20OEfqNwm3k8ENwoM3q0yOs4UMpgtD4GqxB4lwBHToGthHWqhyh5DdSgQjioocz0QK2SSBkJfCq95ZTV8BTw==", - "license": "MIT", - "optional": true, - "dependencies": { - "@types/lodash": "*" - } - }, - "node_modules/@types/long": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", - "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", - "license": "MIT" - }, "node_modules/@types/mocha": { "version": "10.0.10", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz", @@ -3076,24 +775,6 @@ "undici-types": "~6.20.0" } }, - "node_modules/@types/pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/secp256k1": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.6.tgz", - "integrity": "sha512-hHxJU6PAEUn0TP4S/ZOzuTUvJWuZ6eIKeNKb5RBpODvSl6hp1Wrw4s7ATY50rklRCScUDpHzVA/DQdSjJ3UoYQ==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/uuid": { "version": "8.3.4", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", @@ -3109,117 +790,194 @@ "@types/node": "*" } }, - "node_modules/@wry/caches": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@wry/caches/-/caches-1.0.1.tgz", - "integrity": "sha512-bXuaUNLVVkD20wcGBWRyo7j9N3TxePEWFZj2Y+r9OoUzfqmavM84+mFykRicNsBqatba5JLay1t48wxaXaWnlA==", - "license": "MIT", - "optional": true, + "node_modules/@wormhole-foundation/sdk-base": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/@wormhole-foundation/sdk-base/-/sdk-base-1.20.0.tgz", + "integrity": "sha512-jV6aVBFXNh5mueEL4cscnZmHjJiyIF9S6Lp9udVXve+IKchbTH18f9r/A/Lwk8I42ao1X+Pag1tDCYwaSQreFQ==", + "license": "Apache-2.0", + "dependencies": { + "@scure/base": "^1.1.3", + "binary-layout": "^1.0.3" + } + }, + "node_modules/@wormhole-foundation/sdk-connect": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/@wormhole-foundation/sdk-connect/-/sdk-connect-1.20.0.tgz", + "integrity": "sha512-GfoDXj2tGET+fALm8yPgdMuY8SakRTLkSHVG5eSb22zHsSnrKvi7i3siajbbOW+r2rwiKr8UTZSjq2S2eyUCLQ==", + "license": "Apache-2.0", "dependencies": { - "tslib": "^2.3.0" + "@wormhole-foundation/sdk-base": "1.20.0", + "@wormhole-foundation/sdk-definitions": "1.20.0", + "axios": "^1.4.0" }, "engines": { - "node": ">=8" + "node": ">=16" } }, - "node_modules/@wry/context": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.7.4.tgz", - "integrity": "sha512-jmT7Sb4ZQWI5iyu3lobQxICu2nC/vbUhP0vIdd6tHC9PTfenmRmuIFqktc6GH9cgi+ZHnsLWPvfSvc4DrYmKiQ==", - "license": "MIT", - "optional": true, + "node_modules/@wormhole-foundation/sdk-definitions": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/@wormhole-foundation/sdk-definitions/-/sdk-definitions-1.20.0.tgz", + "integrity": "sha512-hNtcyfipdlgmFR8CD9hvA9In54rWDEwuIo7YKeq0FuJNISDHo/+8DVty96SznItkWS5mp5RL/6ayTH/X96dX3w==", + "dependencies": { + "@noble/curves": "^1.4.0", + "@noble/hashes": "^1.3.1", + "@wormhole-foundation/sdk-base": "1.20.0" + } + }, + "node_modules/@wormhole-foundation/sdk-solana": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/@wormhole-foundation/sdk-solana/-/sdk-solana-1.20.0.tgz", + "integrity": "sha512-/IvTyhcJbghkFL5tJXHrNWNfrJPeQLT3+moZerH7hsExUpeG6sHxGSTBr02OotPfAPNwvuH/g6xHl7TDBJ9Bpw==", + "license": "Apache-2.0", "dependencies": { - "tslib": "^2.3.0" + "@coral-xyz/anchor": "0.29.0", + "@coral-xyz/borsh": "0.29.0", + "@solana/spl-token": "0.3.9", + "@solana/web3.js": "^1.95.8", + "@wormhole-foundation/sdk-connect": "1.20.0", + "rpc-websockets": "^7.10.0" }, "engines": { - "node": ">=8" + "node": ">=16" } }, - "node_modules/@wry/equality": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.5.7.tgz", - "integrity": "sha512-BRFORjsTuQv5gxcXsuDXx6oGRhuVsEGwZy6LOzRRfgu+eSfxbhUQ9L9YtSEIuIjY/o7g3iWFjrc5eSY1GXP2Dw==", - "license": "MIT", - "optional": true, + "node_modules/@wormhole-foundation/sdk-solana-core": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/@wormhole-foundation/sdk-solana-core/-/sdk-solana-core-1.20.0.tgz", + "integrity": "sha512-SxxtUStSSQ1iX3eD7ObuxmaB5y4sMkM5RedwCY+v+K7GAMdmRa8uz0BqeHnJ58yEsptSldfK5bGXTY2OvpwNtA==", + "license": "Apache-2.0", "dependencies": { - "tslib": "^2.3.0" + "@coral-xyz/anchor": "0.29.0", + "@coral-xyz/borsh": "0.29.0", + "@solana/web3.js": "^1.95.8", + "@wormhole-foundation/sdk-connect": "1.20.0", + "@wormhole-foundation/sdk-solana": "1.20.0" }, "engines": { - "node": ">=8" + "node": ">=16" } }, - "node_modules/@wry/trie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@wry/trie/-/trie-0.5.0.tgz", - "integrity": "sha512-FNoYzHawTMk/6KMQoEG5O4PuioX19UbwdQKF44yw0nLfOypfQdjtfZzo/UIJWAJ23sNIFbD1Ug9lbaDGMwbqQA==", - "license": "MIT", - "optional": true, + "node_modules/@wormhole-foundation/sdk-solana-core/node_modules/@coral-xyz/anchor": { + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/@coral-xyz/anchor/-/anchor-0.29.0.tgz", + "integrity": "sha512-eny6QNG0WOwqV0zQ7cs/b1tIuzZGmP7U7EcH+ogt4Gdbl8HDmIYVMh/9aTmYZPaFWjtUaI8qSn73uYEXWfATdA==", + "license": "(MIT OR Apache-2.0)", "dependencies": { - "tslib": "^2.3.0" + "@coral-xyz/borsh": "^0.29.0", + "@noble/hashes": "^1.3.1", + "@solana/web3.js": "^1.68.0", + "bn.js": "^5.1.2", + "bs58": "^4.0.1", + "buffer-layout": "^1.2.2", + "camelcase": "^6.3.0", + "cross-fetch": "^3.1.5", + "crypto-hash": "^1.3.0", + "eventemitter3": "^4.0.7", + "pako": "^2.0.3", + "snake-case": "^3.0.4", + "superstruct": "^0.15.4", + "toml": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">=11" } }, - "node_modules/@xpla/xpla.js": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@xpla/xpla.js/-/xpla.js-0.2.3.tgz", - "integrity": "sha512-Tfk7hCGWXtwr08reY3Pi6dmzIqFbzri9jcyzJdfNmdo4cN0PMwpRJuZZcPmtxiIUnNef3AN1E/6nJUD5MKniuA==", - "license": "MIT", + "node_modules/@wormhole-foundation/sdk-solana-core/node_modules/@coral-xyz/borsh": { + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.29.0.tgz", + "integrity": "sha512-s7VFVa3a0oqpkuRloWVPdCK7hMbAMY270geZOGfCnaqexrP5dTIpbEHL33req6IYPPJ0hYa71cdvJ1h6V55/oQ==", + "license": "Apache-2.0", "dependencies": { - "@ethersproject/bytes": "^5.6.1", - "@ethersproject/keccak256": "^5.6.1", - "@ethersproject/signing-key": "^5.6.2", - "@terra-money/legacy.proto": "npm:@terra-money/terra.proto@^0.1.7", - "@terra-money/terra.proto": "^2.1.0", - "axios": "^0.26.1", - "bech32": "^2.0.0", - "bip32": "^2.0.6", - "bip39": "^3.0.3", - "bufferutil": "^4.0.3", - "crypto-addr-codec": "^0.1.7", - "decimal.js": "^10.2.1", - "elliptic": "^6.5.4", - "ethereumjs-util": "^7.1.5", - "jscrypto": "^1.0.1", - "readable-stream": "^3.6.0", - "secp256k1": "^4.0.2", - "tmp": "^0.2.1", - "utf-8-validate": "^5.0.5", - "ws": "^7.5.8" + "bn.js": "^5.1.2", + "buffer-layout": "^1.2.0" }, "engines": { - "node": ">=14" + "node": ">=10" + }, + "peerDependencies": { + "@solana/web3.js": "^1.68.0" } }, - "node_modules/@xpla/xpla.js/node_modules/axios": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", - "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", - "license": "MIT", + "node_modules/@wormhole-foundation/sdk-solana/node_modules/@coral-xyz/anchor": { + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/@coral-xyz/anchor/-/anchor-0.29.0.tgz", + "integrity": "sha512-eny6QNG0WOwqV0zQ7cs/b1tIuzZGmP7U7EcH+ogt4Gdbl8HDmIYVMh/9aTmYZPaFWjtUaI8qSn73uYEXWfATdA==", + "license": "(MIT OR Apache-2.0)", "dependencies": { - "follow-redirects": "^1.14.8" + "@coral-xyz/borsh": "^0.29.0", + "@noble/hashes": "^1.3.1", + "@solana/web3.js": "^1.68.0", + "bn.js": "^5.1.2", + "bs58": "^4.0.1", + "buffer-layout": "^1.2.2", + "camelcase": "^6.3.0", + "cross-fetch": "^3.1.5", + "crypto-hash": "^1.3.0", + "eventemitter3": "^4.0.7", + "pako": "^2.0.3", + "snake-case": "^3.0.4", + "superstruct": "^0.15.4", + "toml": "^3.0.0" + }, + "engines": { + "node": ">=11" } }, - "node_modules/acorn": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", - "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", - "license": "MIT", - "optional": true, - "bin": { - "acorn": "bin/acorn" + "node_modules/@wormhole-foundation/sdk-solana/node_modules/@coral-xyz/borsh": { + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.29.0.tgz", + "integrity": "sha512-s7VFVa3a0oqpkuRloWVPdCK7hMbAMY270geZOGfCnaqexrP5dTIpbEHL33req6IYPPJ0hYa71cdvJ1h6V55/oQ==", + "license": "Apache-2.0", + "dependencies": { + "bn.js": "^5.1.2", + "buffer-layout": "^1.2.0" }, "engines": { - "node": ">=0.4.0" + "node": ">=10" + }, + "peerDependencies": { + "@solana/web3.js": "^1.68.0" } }, - "node_modules/aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", + "node_modules/@wormhole-foundation/sdk-solana/node_modules/rpc-websockets": { + "version": "7.11.2", + "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.11.2.tgz", + "integrity": "sha512-pL9r5N6AVHlMN/vT98+fcO+5+/UcPLf/4tq+WUaid/PPUGS/ttJ3y8e9IqmaWKtShNAysMSjkczuEA49NuV7UQ==", + "license": "LGPL-3.0-only", + "dependencies": { + "eventemitter3": "^4.0.7", + "uuid": "^8.3.2", + "ws": "^8.5.0" + }, + "funding": { + "type": "paypal", + "url": "https://paypal.me/kozjak" + }, + "optionalDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + } + }, + "node_modules/@wormhole-foundation/sdk-solana/node_modules/ws": { + "version": "8.18.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz", + "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==", "license": "MIT", - "optional": true + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } }, "node_modules/agentkeepalive": { "version": "4.6.0", @@ -3233,35 +991,6 @@ "node": ">= 8.0.0" } }, - "node_modules/algo-msgpack-with-bigint": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/algo-msgpack-with-bigint/-/algo-msgpack-with-bigint-2.1.1.tgz", - "integrity": "sha512-F1tGh056XczEaEAqu7s+hlZUDWwOBT70Eq0lfMpBP2YguSQVyxRbprLq5rELXKQOyOaixTWYhMeMQMzP0U5FoQ==", - "license": "ISC", - "engines": { - "node": ">= 10" - } - }, - "node_modules/algosdk": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/algosdk/-/algosdk-2.11.0.tgz", - "integrity": "sha512-MJ9xrjBKqG6ItCAR0Z974DG7nvifXsQxlj7HbWkBat4+h/IygwKPEH/v0dQPOYWdTcf5/5lfu+OyEVOsjxvyRQ==", - "license": "MIT", - "dependencies": { - "algo-msgpack-with-bigint": "^2.1.1", - "buffer": "^6.0.3", - "hi-base32": "^0.5.1", - "js-sha256": "^0.9.0", - "js-sha3": "^0.8.0", - "js-sha512": "^0.8.0", - "json-bigint": "^1.0.0", - "tweetnacl": "^1.0.3", - "vlq": "^2.0.4" - }, - "engines": { - "node": ">=18.0.0" - } - }, "node_modules/ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", @@ -3286,97 +1015,33 @@ } }, "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/aptos": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/aptos/-/aptos-1.5.0.tgz", - "integrity": "sha512-N7OuRtU7IYHkDkNx+4QS3g/QQGCp+36KzYn3oXPmT7Kttfuv+UKliQVdjy3cLmwd/DCQSh9ObTovwdxnHjUn0g==", - "deprecated": "Package aptos is no longer supported, please migrate to https://www.npmjs.com/package/@aptos-labs/ts-sdk", - "license": "Apache-2.0", - "dependencies": { - "@noble/hashes": "1.1.3", - "@scure/bip39": "1.1.0", - "axios": "0.27.2", - "form-data": "4.0.0", - "tweetnacl": "1.0.3" - }, - "engines": { - "node": ">=11.0.0" - } - }, - "node_modules/aptos/node_modules/@noble/hashes": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.1.3.tgz", - "integrity": "sha512-CE0FCR57H2acVI5UOzIGSSIYxZ6v/HOhDR0Ro9VLyhnzLwx0o8W1mmgaqlEUx4049qJDlIBRztv5k+MM8vbO3A==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "license": "MIT" - }, - "node_modules/aptos/node_modules/@scure/base": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", - "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", - "license": "MIT", - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/aptos/node_modules/@scure/bip39": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.0.tgz", - "integrity": "sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "license": "MIT", "dependencies": { - "@noble/hashes": "~1.1.1", - "@scure/base": "~1.1.0" + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/aptos/node_modules/axios": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", - "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", - "license": "MIT", + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", "dependencies": { - "follow-redirects": "^1.14.9", - "form-data": "^4.0.0" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" } }, "node_modules/argparse": { @@ -3390,6 +1055,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, "license": "MIT", "engines": { "node": "*" @@ -3402,19 +1068,21 @@ "license": "MIT" }, "node_modules/axios": { - "version": "0.24.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz", - "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz", + "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==", "license": "MIT", "dependencies": { - "follow-redirects": "^1.14.4" + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" } }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/base-x": { @@ -3446,21 +1114,6 @@ ], "license": "MIT" }, - "node_modules/bech32": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", - "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==", - "license": "MIT" - }, - "node_modules/big-integer": { - "version": "1.6.36", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.36.tgz", - "integrity": "sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg==", - "license": "Unlicense", - "engines": { - "node": ">=0.6" - } - }, "node_modules/bigint-buffer": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/bigint-buffer/-/bigint-buffer-1.1.5.tgz", @@ -3496,14 +1149,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/binary-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/binary-parser/-/binary-parser-2.2.1.tgz", - "integrity": "sha512-5ATpz/uPDgq5GgEDxTB4ouXCde7q2lqAQlSdBRQVl/AJnxmQmhIfyxJx+0MGu//D5rHQifkfGbWWlaysG0o9NA==", - "license": "MIT", - "engines": { - "node": ">=12" - } + "node_modules/binary-layout": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/binary-layout/-/binary-layout-1.2.2.tgz", + "integrity": "sha512-iySOJ1OB2uPxv8whrRwDJ7USTk7NqeCaSPZL/j4oaOK2iup8P5vr4BNvtpumXUAe0/aJZ8ZkNldj3fmhtcLnDQ==", + "license": "Apache-2.0" }, "node_modules/bindings": { "version": "1.5.0", @@ -3514,55 +1164,6 @@ "file-uri-to-path": "1.0.0" } }, - "node_modules/bip32": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/bip32/-/bip32-2.0.6.tgz", - "integrity": "sha512-HpV5OMLLGTjSVblmrtYRfFFKuQB+GArM0+XP8HGWfJ5vxYBqo+DesvJwOdC2WJ3bCkZShGf0QIfoIpeomVzVdA==", - "license": "MIT", - "dependencies": { - "@types/node": "10.12.18", - "bs58check": "^2.1.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "tiny-secp256k1": "^1.1.3", - "typeforce": "^1.11.5", - "wif": "^2.0.6" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/bip32/node_modules/@types/node": { - "version": "10.12.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz", - "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==", - "license": "MIT" - }, - "node_modules/bip39": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.1.0.tgz", - "integrity": "sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A==", - "license": "ISC", - "dependencies": { - "@noble/hashes": "^1.2.0" - } - }, - "node_modules/bip66": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", - "integrity": "sha512-nemMHz95EmS38a26XbbdxIYj5csHd3RMP3H5bwQknX0WYHF01qhpufP42mLOwVICuH2JmhIhXiWs89MfUGL7Xw==", - "license": "MIT", - "optional": true, - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/blakejs": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", - "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", - "license": "MIT" - }, "node_modules/bn.js": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", @@ -3603,18 +1204,6 @@ "node": ">=8" } }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "license": "MIT" - }, - "node_modules/browser-headers": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/browser-headers/-/browser-headers-0.4.1.tgz", - "integrity": "sha512-CA9hsySZVo9371qEHjHZtYxV2cFtVj5Wj/ZHi8ooEsrtm4vOnl9Y9HmyYWk9q+05d7K3rdoAE0j3MVEFVvtQtg==", - "license": "Apache-2.0" - }, "node_modules/browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", @@ -3622,20 +1211,6 @@ "dev": true, "license": "ISC" }, - "node_modules/browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "license": "MIT", - "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, "node_modules/bs58": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", @@ -3645,17 +1220,6 @@ "base-x": "^3.0.2" } }, - "node_modules/bs58check": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", - "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", - "license": "MIT", - "dependencies": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, "node_modules/buffer": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", @@ -3689,18 +1253,13 @@ "node": ">=4.5" } }, - "node_modules/buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", - "license": "MIT" - }, "node_modules/bufferutil": { "version": "4.0.9", "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.9.tgz", "integrity": "sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw==", "hasInstallScript": true, "license": "MIT", + "optional": true, "dependencies": { "node-gyp-build": "^4.3.0" }, @@ -3708,6 +1267,19 @@ "node": ">=6.14.2" } }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", @@ -3720,16 +1292,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/capability": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/capability/-/capability-0.2.5.tgz", - "integrity": "sha512-rsJZYVCgXd08sPqwmaIqjAd5SUTfonV0z/gDJ8D6cN8wQphky1kkAYEqQ+hmDxTw7UihvBfjUVUSY+DBEe44jg==", - "license": "MIT" - }, "node_modules/chai": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", + "dev": true, "license": "MIT", "dependencies": { "assertion-error": "^1.1.0", @@ -3744,27 +1311,6 @@ "node": ">=4" } }, - "node_modules/chai-as-promised": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-8.0.1.tgz", - "integrity": "sha512-OIEJtOL8xxJSH8JJWbIoRjybbzR52iFuDHuF8eb+nTPD6tgXLjRqsgnUGqQfFODxYvq5QdirT0pN9dZ0+Gz6rA==", - "license": "MIT", - "dependencies": { - "check-error": "^2.0.0" - }, - "peerDependencies": { - "chai": ">= 2.1.2 < 6" - } - }, - "node_modules/chai-as-promised/node_modules/check-error": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", - "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", - "license": "MIT", - "engines": { - "node": ">= 16" - } - }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -3799,6 +1345,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, "license": "MIT", "dependencies": { "get-func-name": "^2.0.2" @@ -3835,19 +1382,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/cipher-base": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.6.tgz", - "integrity": "sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.4", - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -3895,201 +1429,12 @@ "node": ">=8" } }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "devOptional": true, - "license": "MIT" - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commander": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", - "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "license": "MIT", - "optional": true - }, - "node_modules/copyfiles": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/copyfiles/-/copyfiles-2.4.1.tgz", - "integrity": "sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg==", - "license": "MIT", - "optional": true, - "dependencies": { - "glob": "^7.0.5", - "minimatch": "^3.0.3", - "mkdirp": "^1.0.4", - "noms": "0.0.0", - "through2": "^2.0.1", - "untildify": "^4.0.0", - "yargs": "^16.1.0" - }, - "bin": { - "copyfiles": "copyfiles", - "copyup": "copyfiles" - } - }, - "node_modules/copyfiles/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/copyfiles/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "license": "MIT", - "optional": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/copyfiles/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "license": "ISC", - "optional": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/copyfiles/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT", - "optional": true - }, - "node_modules/copyfiles/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "license": "ISC", - "optional": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/copyfiles/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", - "optional": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/copyfiles/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "optional": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/copyfiles/node_modules/strip-ansi": { + "node_modules/cliui/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "license": "MIT", - "optional": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -4097,12 +1442,12 @@ "node": ">=8" } }, - "node_modules/copyfiles/node_modules/wrap-ansi": { + "node_modules/cliui/node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, "license": "MIT", - "optional": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -4115,118 +1460,45 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/copyfiles/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "color-name": "~1.1.4" }, "engines": { - "node": ">=10" + "node": ">=7.0.0" } }, - "node_modules/copyfiles/node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "license": "ISC", - "optional": true, - "engines": { - "node": ">=10" - } + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "license": "MIT", - "optional": true - }, - "node_modules/cosmjs-types": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.7.2.tgz", - "integrity": "sha512-vf2uLyktjr/XVAgEq0DjMxeAWh1yYREe7AMHDKd7EiHVqxBPCaBS+qEEQUkXbR9ndnckqr1sUG8BQhazh4X5lA==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "long": "^4.0.0", - "protobufjs": "~6.11.2" - } - }, - "node_modules/cosmjs-types/node_modules/protobufjs": { - "version": "6.11.4", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz", - "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==", - "hasInstallScript": true, - "license": "BSD-3-Clause", - "optional": true, "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": ">=13.7.0", - "long": "^4.0.0" - }, - "bin": { - "pbjs": "bin/pbjs", - "pbts": "bin/pbts" - } - }, - "node_modules/crc-32": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", - "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", - "license": "Apache-2.0", - "optional": true, - "bin": { - "crc32": "bin/crc32.njs" + "delayed-stream": "~1.0.0" }, "engines": { - "node": ">=0.8" - } - }, - "node_modules/create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "license": "MIT", - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" + "node": ">= 0.8" } }, - "node_modules/create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "node_modules/commander": { + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", + "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", "license": "MIT", - "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" + "engines": { + "node": ">=18" } }, "node_modules/cross-fetch": { @@ -4253,21 +1525,6 @@ "node": ">= 8" } }, - "node_modules/crypto-addr-codec": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/crypto-addr-codec/-/crypto-addr-codec-0.1.8.tgz", - "integrity": "sha512-GqAK90iLLgP3FvhNmHbpT3wR6dEdaM8hZyZtLX29SPardh3OA13RFLHDR6sntGCgRWOfiHqW6sIyohpNqOtV/g==", - "license": "MIT", - "dependencies": { - "base-x": "^3.0.8", - "big-integer": "1.6.36", - "blakejs": "^1.1.0", - "bs58": "^4.0.1", - "ripemd160-min": "0.0.6", - "safe-buffer": "^5.2.0", - "sha3": "^2.1.1" - } - }, "node_modules/crypto-hash": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/crypto-hash/-/crypto-hash-1.3.0.tgz", @@ -4311,16 +1568,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/decimal.js": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.5.0.tgz", - "integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==", - "license": "MIT" - }, "node_modules/deep-eql": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", + "dev": true, "license": "MIT", "dependencies": { "type-detect": "^4.0.0" @@ -4329,42 +1581,6 @@ "node": ">=6" } }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "license": "MIT", - "optional": true, - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "license": "MIT", - "optional": true, - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/delay": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", @@ -4386,19 +1602,11 @@ "node": ">=0.4.0" } }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/diff": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", + "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" @@ -4414,19 +1622,18 @@ "tslib": "^2.0.3" } }, - "node_modules/drbg.js": { + "node_modules/dunder-proto": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", - "integrity": "sha512-F4wZ06PvqxYLFEZKkFxTDcns9oFNk34hvmJSEwdzsxVQ8YI5YaxtACgQatkYgv2VI2CFkUd2Y+xosPQnHv809g==", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "license": "MIT", - "optional": true, "dependencies": { - "browserify-aes": "^1.0.6", - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4" + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" }, "engines": { - "node": ">=0.10" + "node": ">= 0.4" } }, "node_modules/eastasianwidth": { @@ -4436,88 +1643,6 @@ "dev": true, "license": "MIT" }, - "node_modules/eccrypto": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/eccrypto/-/eccrypto-1.1.6.tgz", - "integrity": "sha512-d78ivVEzu7Tn0ZphUUaL43+jVPKTMPFGtmgtz1D0LrFn7cY3K8CdrvibuLz2AAkHBLKZtR8DMbB2ukRYFk987A==", - "hasInstallScript": true, - "license": "CC0-1.0", - "optional": true, - "dependencies": { - "acorn": "7.1.1", - "elliptic": "6.5.4", - "es6-promise": "4.2.8", - "nan": "2.14.0" - }, - "optionalDependencies": { - "secp256k1": "3.7.1" - } - }, - "node_modules/eccrypto/node_modules/bn.js": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", - "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", - "license": "MIT", - "optional": true - }, - "node_modules/eccrypto/node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/eccrypto/node_modules/secp256k1": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.7.1.tgz", - "integrity": "sha512-1cf8sbnRreXrQFdH6qsg2H71Xw91fCCS9Yp021GnUNJzWJS/py96fS4lHbnTnouLp08Xj6jBoBB6V78Tdbdu5g==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "dependencies": { - "bindings": "^1.5.0", - "bip66": "^1.1.5", - "bn.js": "^4.11.8", - "create-hash": "^1.2.0", - "drbg.js": "^1.0.1", - "elliptic": "^6.4.1", - "nan": "^2.14.0", - "safe-buffer": "^5.1.2" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/elliptic": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz", - "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", - "license": "MIT", - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", - "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", - "license": "MIT" - }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -4525,23 +1650,11 @@ "dev": true, "license": "MIT" }, - "node_modules/error-polyfill": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/error-polyfill/-/error-polyfill-0.1.3.tgz", - "integrity": "sha512-XHJk60ufE+TG/ydwp4lilOog549iiQF2OAPhkk9DdiYWMrltz5yhDz/xnKuenNwP7gy3dsibssO5QpVhkrSzzg==", - "license": "MIT", - "dependencies": { - "capability": "^0.2.5", - "o3": "^1.0.3", - "u3": "^0.1.1" - } - }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "license": "MIT", - "optional": true, "engines": { "node": ">= 0.4" } @@ -4551,7 +1664,33 @@ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "license": "MIT", - "optional": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, "engines": { "node": ">= 0.4" } @@ -4616,7 +1755,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -4635,212 +1774,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eth-crypto": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/eth-crypto/-/eth-crypto-2.8.0.tgz", - "integrity": "sha512-QtVmfLZK+N0k4+RA65ORbVCBM2ndzPM0Q/VFhkYYrGY16+4OAwuxG+eyFlWyDO3HBFMlPnMLa69OZCKOoQkcdQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "@babel/runtime": "7.27.0", - "@ethereumjs/tx": "3.5.2", - "@types/bn.js": "5.1.6", - "eccrypto": "1.1.6", - "ethereumjs-util": "7.1.5", - "ethers": "5.8.0", - "secp256k1": "5.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/pubkey" - } - }, - "node_modules/eth-crypto/node_modules/node-addon-api": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", - "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==", - "license": "MIT", - "optional": true - }, - "node_modules/eth-crypto/node_modules/secp256k1": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-5.0.1.tgz", - "integrity": "sha512-lDFs9AAIaWP9UCdtWrotXWWF9t8PWgQDcxqgAnpM9rMqxb3Oaq2J0thzPVSxBwdJgyQtkU/sYtFtbM1RSt/iYA==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "dependencies": { - "elliptic": "^6.5.7", - "node-addon-api": "^5.0.0", - "node-gyp-build": "^4.2.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "license": "MIT", - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/ethereumjs-abi": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", - "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", - "deprecated": "This library has been deprecated and usage is discouraged.", - "license": "MIT", - "optional": true, - "dependencies": { - "bn.js": "^4.11.8", - "ethereumjs-util": "^6.0.0" - } - }, - "node_modules/ethereumjs-abi/node_modules/@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "license": "MIT", - "optional": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/ethereumjs-abi/node_modules/bn.js": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", - "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", - "license": "MIT", - "optional": true - }, - "node_modules/ethereumjs-abi/node_modules/ethereumjs-util": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", - "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", - "license": "MPL-2.0", - "optional": true, - "dependencies": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - }, - "node_modules/ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "license": "MPL-2.0", - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/ethers": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.8.0.tgz", - "integrity": "sha512-DUq+7fHrCg1aPDFCHx6UIPb3nmt2XMpM7Y/g2gLhsl3lIBqeAfOJIl1qEvRf2uq3BiKxmh6Fh5pfp2ieyek7Kg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@ethersproject/abi": "5.8.0", - "@ethersproject/abstract-provider": "5.8.0", - "@ethersproject/abstract-signer": "5.8.0", - "@ethersproject/address": "5.8.0", - "@ethersproject/base64": "5.8.0", - "@ethersproject/basex": "5.8.0", - "@ethersproject/bignumber": "5.8.0", - "@ethersproject/bytes": "5.8.0", - "@ethersproject/constants": "5.8.0", - "@ethersproject/contracts": "5.8.0", - "@ethersproject/hash": "5.8.0", - "@ethersproject/hdnode": "5.8.0", - "@ethersproject/json-wallets": "5.8.0", - "@ethersproject/keccak256": "5.8.0", - "@ethersproject/logger": "5.8.0", - "@ethersproject/networks": "5.8.0", - "@ethersproject/pbkdf2": "5.8.0", - "@ethersproject/properties": "5.8.0", - "@ethersproject/providers": "5.8.0", - "@ethersproject/random": "5.8.0", - "@ethersproject/rlp": "5.8.0", - "@ethersproject/sha2": "5.8.0", - "@ethersproject/signing-key": "5.8.0", - "@ethersproject/solidity": "5.8.0", - "@ethersproject/strings": "5.8.0", - "@ethersproject/transactions": "5.8.0", - "@ethersproject/units": "5.8.0", - "@ethersproject/wallet": "5.8.0", - "@ethersproject/web": "5.8.0", - "@ethersproject/wordlists": "5.8.0" - } - }, - "node_modules/ethjs-util": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", - "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", - "license": "MIT", - "optional": true, - "dependencies": { - "is-hex-prefixed": "1.0.0", - "strip-hex-prefix": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, "node_modules/eventemitter3": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", "license": "MIT" }, - "node_modules/evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "license": "MIT", - "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, "node_modules/eyes": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", @@ -4855,13 +1794,6 @@ "integrity": "sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==", "license": "MIT" }, - "node_modules/fastestsmallesttextencoderdecoder": { - "version": "1.0.22", - "resolved": "https://registry.npmjs.org/fastestsmallesttextencoderdecoder/-/fastestsmallesttextencoderdecoder-1.0.22.tgz", - "integrity": "sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==", - "license": "CC0-1.0", - "peer": true - }, "node_modules/file-uri-to-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", @@ -4946,26 +1878,20 @@ } }, "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", + "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", "mime-types": "^2.1.12" }, "engines": { "node": ">= 6" } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "license": "ISC", - "optional": true - }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -4986,7 +1912,6 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "license": "MIT", - "optional": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -4995,19 +1920,57 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "devOptional": true, + "dev": true, "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, "engines": { - "node": "*" + "node": ">= 0.4" } }, "node_modules/get-tsconfig": { @@ -5073,35 +2036,11 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/google-protobuf": { - "version": "3.21.4", - "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.21.4.tgz", - "integrity": "sha512-MnG7N936zcKTco4Jd2PX2U96Kf9PxygAPKBug+74LHzmHXmceN16MmRcdgZv+DGef/S9YvQAfRsNCn4cjf9yyQ==", - "license": "(BSD-3-Clause AND Apache-2.0)" - }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "license": "MIT", - "optional": true, "engines": { "node": ">= 0.4" }, @@ -5109,32 +2048,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/graphql": { - "version": "16.10.0", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.10.0.tgz", - "integrity": "sha512-AjqGKbDGUFRKIRCP9tCKiIGHyriz2oHEbPIbEtcSLSs4YjReZOIPQQWek4+6hjw62H9QShXHyaGivGiYVLeYFQ==", - "license": "MIT", - "optional": true, - "engines": { - "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" - } - }, - "node_modules/graphql-tag": { - "version": "2.12.6", - "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz", - "integrity": "sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==", - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "graphql": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" - } - }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -5145,41 +2058,31 @@ "node": ">=8" } }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "license": "MIT", - "optional": true, - "dependencies": { - "es-define-property": "^1.0.0" + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "license": "MIT", "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" + "has-symbols": "^1.0.3" }, "engines": { - "node": ">=4" - } - }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/hasown": { @@ -5187,7 +2090,6 @@ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "license": "MIT", - "optional": true, "dependencies": { "function-bind": "^1.1.2" }, @@ -5205,65 +2107,6 @@ "he": "bin/he" } }, - "node_modules/hi-base32": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/hi-base32/-/hi-base32-0.5.1.tgz", - "integrity": "sha512-EmBBpvdYh/4XxsnUybsPag6VikPYnN30td+vQk+GI3qpahVEG9+gTkG0aXVxTjBqQ5T6ijbWIu77O+C5WFWsnA==", - "license": "MIT" - }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "license": "MIT", - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "license": "BSD-3-Clause", - "optional": true, - "dependencies": { - "react-is": "^16.7.0" - } - }, - "node_modules/http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", - "license": "MIT", - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/http-errors/node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/http-status-codes": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.3.0.tgz", - "integrity": "sha512-RJ8XvFvpPM/Dmc5SV+dC4y5PCeOhT3x1Hq0NU3rjGeg5a/CqlhZ7uudknPwZFz4aeAXDcbAyaeP7GAo9lvngtA==", - "license": "MIT", - "optional": true - }, "node_modules/humanize-ms": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", @@ -5293,34 +2136,6 @@ ], "license": "BSD-3-Clause" }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "license": "ISC", - "optional": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -5334,22 +2149,6 @@ "node": ">=8" } }, - "node_modules/is-core-module": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", - "license": "MIT", - "optional": true, - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -5364,7 +2163,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -5383,17 +2182,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-hex-prefixed": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -5427,13 +2215,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "license": "MIT", - "optional": true - }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -5444,282 +2225,85 @@ "node_modules/isomorphic-ws": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", - "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", - "license": "MIT", - "peerDependencies": { - "ws": "*" - } - }, - "node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/jayson": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/jayson/-/jayson-4.2.0.tgz", - "integrity": "sha512-VfJ9t1YLwacIubLhONk0KFeosUBwstRWQ0IRT1KDjEjnVnSOVHC3uwugyV7L0c7R9lpVyrUGT2XWiBA1UTtpyg==", - "license": "MIT", - "dependencies": { - "@types/connect": "^3.4.33", - "@types/node": "^12.12.54", - "@types/ws": "^7.4.4", - "commander": "^2.20.3", - "delay": "^5.0.0", - "es6-promisify": "^5.0.0", - "eyes": "^0.1.8", - "isomorphic-ws": "^4.0.1", - "json-stringify-safe": "^5.0.1", - "stream-json": "^1.9.1", - "uuid": "^8.3.2", - "ws": "^7.5.10" - }, - "bin": { - "jayson": "bin/jayson.js" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jayson/node_modules/@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", - "license": "MIT" - }, - "node_modules/jayson/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "license": "MIT" - }, - "node_modules/js-base64": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.7.tgz", - "integrity": "sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==", - "license": "BSD-3-Clause" - }, - "node_modules/js-sha256": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", - "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==", - "license": "MIT" - }, - "node_modules/js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", - "license": "MIT" - }, - "node_modules/js-sha512": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha512/-/js-sha512-0.8.0.tgz", - "integrity": "sha512-PWsmefG6Jkodqt+ePTvBZCSMFgN7Clckjd0O7su3I0+BW2QWUTJNzjktHsztGLhncP2h8mcF9V9Y2Ha59pAViQ==", - "license": "MIT" - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "license": "MIT", - "optional": true - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jscrypto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/jscrypto/-/jscrypto-1.0.3.tgz", - "integrity": "sha512-lryZl0flhodv4SZHOqyb1bx5sKcJxj0VBo0Kzb4QMAg3L021IC9uGpl0RCZa+9KJwlRGSK2C80ITcwbe19OKLQ==", - "license": "MIT", - "bin": { - "jscrypto": "bin/cli.js" - } - }, - "node_modules/json-bigint": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", - "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", - "license": "MIT", - "dependencies": { - "bignumber.js": "^9.0.0" - } - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "license": "ISC" - }, - "node_modules/jsonschema": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.5.0.tgz", - "integrity": "sha512-K+A9hhqbn0f3pJX17Q/7H6yQfD/5OXgdrR5UE12gMXCiN9D5Xq2o5mddV2QEcX/bjla99ASsAAQUyMCCRWAEhw==", - "license": "MIT", - "optional": true, - "engines": { - "node": "*" - } - }, - "node_modules/keccak": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.4.tgz", - "integrity": "sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/keccak256": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/keccak256/-/keccak256-1.0.6.tgz", - "integrity": "sha512-8GLiM01PkdJVGUhR1e6M/AvWnSqYS0HaERI+K/QtStGDGlSTx2B1zTqZk4Zlqu5TxHJNTxWAdP9Y+WI50OApUw==", - "license": "MIT", - "optional": true, - "dependencies": { - "bn.js": "^5.2.0", - "buffer": "^6.0.3", - "keccak": "^3.0.2" - } - }, - "node_modules/libsodium": { - "version": "0.7.15", - "resolved": "https://registry.npmjs.org/libsodium/-/libsodium-0.7.15.tgz", - "integrity": "sha512-sZwRknt/tUpE2AwzHq3jEyUU5uvIZHtSssktXq7owd++3CSgn8RGrv6UZJJBpP7+iBghBqe7Z06/2M31rI2NKw==", - "license": "ISC", - "optional": true - }, - "node_modules/libsodium-wrappers": { - "version": "0.7.15", - "resolved": "https://registry.npmjs.org/libsodium-wrappers/-/libsodium-wrappers-0.7.15.tgz", - "integrity": "sha512-E4anqJQwcfiC6+Yrl01C1m8p99wEhLmJSs0VQqST66SbQXXBoaJY0pF4BNjRYa/sOQAxx6lXAaAFIlx+15tXJQ==", - "license": "ISC", - "optional": true, - "dependencies": { - "libsodium": "^0.7.15" - } - }, - "node_modules/link-module-alias": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/link-module-alias/-/link-module-alias-1.2.0.tgz", - "integrity": "sha512-ahPjXepbSVKbahTB6LxR//VHm8HPfI+QQygCH+E82spBY4HR5VPJTvlhKBc9F7muVxnS6C1rRfoPOXAbWO/fyw==", - "license": "MIT", - "optional": true, - "dependencies": { - "chalk": "^2.4.1" - }, - "bin": { - "link-module-alias": "index.js" - }, - "engines": { - "node": "> 8.0.0" + "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", + "license": "MIT", + "peerDependencies": { + "ws": "*" } }, - "node_modules/link-module-alias/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "license": "MIT", - "optional": true, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "color-convert": "^1.9.0" + "@isaacs/cliui": "^8.0.2" }, - "engines": { - "node": ">=4" + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" } }, - "node_modules/link-module-alias/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/jayson": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/jayson/-/jayson-4.2.0.tgz", + "integrity": "sha512-VfJ9t1YLwacIubLhONk0KFeosUBwstRWQ0IRT1KDjEjnVnSOVHC3uwugyV7L0c7R9lpVyrUGT2XWiBA1UTtpyg==", "license": "MIT", - "optional": true, "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "@types/connect": "^3.4.33", + "@types/node": "^12.12.54", + "@types/ws": "^7.4.4", + "commander": "^2.20.3", + "delay": "^5.0.0", + "es6-promisify": "^5.0.0", + "eyes": "^0.1.8", + "isomorphic-ws": "^4.0.1", + "json-stringify-safe": "^5.0.1", + "stream-json": "^1.9.1", + "uuid": "^8.3.2", + "ws": "^7.5.10" + }, + "bin": { + "jayson": "bin/jayson.js" }, "engines": { - "node": ">=4" - } - }, - "node_modules/link-module-alias/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "license": "MIT", - "optional": true, - "dependencies": { - "color-name": "1.1.3" + "node": ">=8" } }, - "node_modules/link-module-alias/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "license": "MIT", - "optional": true - }, - "node_modules/link-module-alias/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.8.0" - } + "node_modules/jayson/node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", + "license": "MIT" }, - "node_modules/link-module-alias/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=4" - } + "node_modules/jayson/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "license": "MIT" }, - "node_modules/link-module-alias/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "has-flag": "^3.0.0" + "argparse": "^2.0.1" }, - "engines": { - "node": ">=4" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "license": "ISC" + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -5736,20 +2320,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "license": "MIT", - "optional": true - }, - "node_modules/lodash.values": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.values/-/lodash.values-4.3.0.tgz", - "integrity": "sha512-r0RwvdCv8id9TUblb/O7rYPwVy6lerCbcawrfdo9iC/1t1wsNMJknO79WNBgwkH0hIeJ08jmvvESbFpNb4jH0Q==", - "license": "MIT", - "optional": true - }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -5767,29 +2337,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", - "license": "Apache-2.0" - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "license": "MIT", - "optional": true, - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, "node_modules/loupe": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, "license": "MIT", "dependencies": { "get-func-name": "^2.0.1" @@ -5811,28 +2363,13 @@ "dev": true, "license": "ISC" }, - "node_modules/map-obj": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", - "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", "license": "MIT", - "optional": true, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "license": "MIT", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" + "node": ">= 0.4" } }, "node_modules/mime-db": { @@ -5856,18 +2393,6 @@ "node": ">= 0.6" } }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "license": "ISC" - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", - "license": "MIT" - }, "node_modules/minimatch": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", @@ -5881,16 +2406,6 @@ "node": ">=10" } }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "license": "MIT", - "optional": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/minipass": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", @@ -5901,19 +2416,6 @@ "node": ">=16 || 14 >=14.17" } }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "license": "MIT", - "optional": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/mocha": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.1.0.tgz", @@ -5966,40 +2468,6 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, - "node_modules/mustache": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", - "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", - "license": "MIT", - "bin": { - "mustache": "bin/mustache" - } - }, - "node_modules/nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", - "license": "MIT" - }, - "node_modules/near-api-js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/near-api-js/-/near-api-js-1.1.0.tgz", - "integrity": "sha512-qYKv1mYsaDZc2uYndhS+ttDhR9+60qFc+ZjD6lWsAxr3ZskMjRwPffDGQZYhC7BRDQMe1HEbk6d5mf+TVm0Lqg==", - "license": "(MIT AND Apache-2.0)", - "dependencies": { - "bn.js": "5.2.1", - "borsh": "^0.7.0", - "bs58": "^4.0.0", - "depd": "^2.0.0", - "error-polyfill": "^0.1.3", - "http-errors": "^1.7.2", - "js-sha256": "^0.9.0", - "mustache": "^4.0.0", - "node-fetch": "^2.6.1", - "text-encoding-utf-8": "^1.0.2", - "tweetnacl": "^1.0.1" - } - }, "node_modules/no-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", @@ -6010,12 +2478,6 @@ "tslib": "^2.0.3" } }, - "node_modules/node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", - "license": "MIT" - }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", @@ -6041,43 +2503,13 @@ "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", "license": "MIT", + "optional": true, "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", "node-gyp-build-test": "build-test.js" } }, - "node_modules/noms": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/noms/-/noms-0.0.0.tgz", - "integrity": "sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow==", - "license": "ISC", - "optional": true, - "dependencies": { - "inherits": "^2.0.1", - "readable-stream": "~1.0.31" - } - }, - "node_modules/noms/node_modules/readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", - "license": "MIT", - "optional": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/noms/node_modules/string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", - "license": "MIT", - "optional": true - }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -6088,58 +2520,6 @@ "node": ">=0.10.0" } }, - "node_modules/o3": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/o3/-/o3-1.0.3.tgz", - "integrity": "sha512-f+4n+vC6s4ysy7YO7O2gslWZBUu8Qj2i2OUJOvjRxQva7jVjYjB29jrr9NCjmxZQR0gzrOcv1RnqoYOeMs5VRQ==", - "license": "MIT", - "dependencies": { - "capability": "^0.2.5" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "license": "ISC", - "optional": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/optimism": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.18.1.tgz", - "integrity": "sha512-mLXNwWPa9dgFyDqkNi54sjDyNJ9/fTI6WGBLgnXku1vdKY/jovHfZT5r+aiVeFFLOz+foPNOm5YJ4mqgld2GBQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "@wry/caches": "^1.0.0", - "@wry/context": "^0.7.0", - "@wry/trie": "^0.5.0", - "tslib": "^2.3.0" - } - }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -6195,16 +2575,6 @@ "node": ">=8" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -6215,13 +2585,6 @@ "node": ">=8" } }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "license": "MIT", - "optional": true - }, "node_modules/path-scurry": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", @@ -6243,27 +2606,12 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, "license": "MIT", "engines": { "node": "*" } }, - "node_modules/pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "license": "MIT", - "dependencies": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - }, - "engines": { - "node": ">=0.12" - } - }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -6293,92 +2641,22 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "license": "MIT", - "optional": true - }, - "node_modules/prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "license": "MIT", - "optional": true, - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - } - }, - "node_modules/protobufjs": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.0.tgz", - "integrity": "sha512-Z2E/kOY1QjoMlCytmexzYfDm/w5fKAiRwpSzGtdnXW1zC88Z2yXazHHrOtwCzn+7wSxyE8PYM4rvVcMphF9sOA==", - "hasInstallScript": true, - "license": "BSD-3-Clause", - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/node": ">=13.7.0", - "long": "^5.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/protobufjs/node_modules/long": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", - "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", - "license": "Apache-2.0" - }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "license": "MIT", - "optional": true + "license": "MIT" }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" } }, - "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "license": "MIT", - "optional": true - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -6392,81 +2670,22 @@ "node": ">=8.10.0" } }, - "node_modules/readonly-date": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/readonly-date/-/readonly-date-1.0.0.tgz", - "integrity": "sha512-tMKIV7hlk0h4mO3JTmmVuIlJVXjKk3Sep9Bf5OH0O+758ruuVkUy2J9SttDLm91IEX/WHlXPSpxMGjPj4beMIQ==", - "license": "Apache-2.0", - "optional": true - }, - "node_modules/rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "optional": true, - "dependencies": { - "resolve": "^1.1.6" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/regenerator-runtime": { "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "license": "MIT" - }, - "node_modules/rehackt": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/rehackt/-/rehackt-0.1.0.tgz", - "integrity": "sha512-7kRDOuLHB87D/JESKxQoRwv4DzbIdwkAGQ7p6QKGdVlY1IZheUnVhlk/4UZlNUVxdAXpyxikE3URsG067ybVzw==", - "license": "MIT", - "optional": true, - "peerDependencies": { - "@types/react": "*", - "react": "*" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "react": { - "optional": true - } - } + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/resolve": { - "version": "1.22.10", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", - "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", - "license": "MIT", - "optional": true, - "dependencies": { - "is-core-module": "^2.16.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/resolve-pkg-maps": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", @@ -6477,36 +2696,6 @@ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, - "node_modules/ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "license": "MIT", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "node_modules/ripemd160-min": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/ripemd160-min/-/ripemd160-min-0.0.6.tgz", - "integrity": "sha512-+GcJgQivhs6S9qvLogusiTcS9kQUfgR75whKuy5jIhuiOfQuJ8fjqxV6EGD5duH1Y/FawFUMtMhyeq3Fbnib8A==", - "engines": { - "node": ">=8" - } - }, - "node_modules/rlp": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", - "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", - "license": "MPL-2.0", - "dependencies": { - "bn.js": "^5.2.0" - }, - "bin": { - "rlp": "bin/rlp" - } - }, "node_modules/rpc-websockets": { "version": "9.1.1", "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-9.1.1.tgz", @@ -6566,15 +2755,6 @@ } } }, - "node_modules/rxjs": { - "version": "7.8.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", - "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - } - }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -6595,33 +2775,6 @@ ], "license": "MIT" }, - "node_modules/scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", - "license": "MIT" - }, - "node_modules/secp256k1": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.4.tgz", - "integrity": "sha512-6JfvwvjUOn8F/jUoBY2Q1v5WY5XS+rj8qSe0v8Y4ezH4InLgTEeOOPQsRll9OV429Pvo6BCHGavIyJfr3TAhsw==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "elliptic": "^6.5.7", - "node-addon-api": "^5.0.0", - "node-gyp-build": "^4.2.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/secp256k1/node_modules/node-addon-api": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", - "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==", - "license": "MIT" - }, "node_modules/serialize-javascript": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", @@ -6632,40 +2785,6 @@ "randombytes": "^2.1.0" } }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "license": "MIT" - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "license": "ISC" - }, - "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "license": "(MIT AND BSD-3-Clause)", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" - } - }, - "node_modules/sha3": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/sha3/-/sha3-2.1.4.tgz", - "integrity": "sha512-S8cNxbyb0UGUM2VhRD4Poe5N58gJnJsLJ5vC7FYWGUmGhcsj4++WaIOBFVDxlG0W3To6xBuiRh+i0Qp2oNCOtg==", - "license": "MIT", - "dependencies": { - "buffer": "6.0.3" - } - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -6689,87 +2808,6 @@ "node": ">=8" } }, - "node_modules/shelljs": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", - "license": "BSD-3-Clause", - "optional": true, - "dependencies": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - }, - "bin": { - "shjs": "bin/shjs" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/shelljs/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "license": "MIT", - "optional": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/shelljs/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "license": "ISC", - "optional": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/shelljs/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", - "optional": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/shx": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/shx/-/shx-0.3.4.tgz", - "integrity": "sha512-N6A9MLVqjxZYcVn8hLmtneQWIJtp8IKzMP4eMnx+nqkvXoqinUPCbUFLp2UcWTEIUONhlk0ewxr/jaVGlc+J+g==", - "license": "MIT", - "optional": true, - "dependencies": { - "minimist": "^1.2.3", - "shelljs": "^0.8.5" - }, - "bin": { - "shx": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", @@ -6793,37 +2831,6 @@ "tslib": "^2.0.3" } }, - "node_modules/snakecase-keys": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/snakecase-keys/-/snakecase-keys-5.5.0.tgz", - "integrity": "sha512-r3kRtnoPu3FxGJ3fny6PKNnU3pteb29o6qAa0ugzhSseKNWRkw1dw8nIjXMyyKaU9vQxxVIE62Mb3bKbdrgpiw==", - "license": "MIT", - "optional": true, - "dependencies": { - "map-obj": "^4.1.0", - "snake-case": "^3.0.4", - "type-fest": "^3.12.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/store2": { - "version": "2.14.4", - "resolved": "https://registry.npmjs.org/store2/-/store2-2.14.4.tgz", - "integrity": "sha512-srTItn1GOvyvOycgxjAnPA63FZNwy0PTyUBFMHRM+hVFltAeoh0LmNBz9SZqUS9mMqGk8rfyWyXn3GH5ReJ8Zw==", - "license": "MIT", - "optional": true - }, "node_modules/stream-chain": { "version": "2.2.5", "resolved": "https://registry.npmjs.org/stream-chain/-/stream-chain-2.2.5.tgz", @@ -6839,15 +2846,6 @@ "stream-chain": "^2.2.5" } }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", @@ -6952,20 +2950,6 @@ "node": ">=8" } }, - "node_modules/strip-hex-prefix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", - "license": "MIT", - "optional": true, - "dependencies": { - "is-hex-prefixed": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -7001,117 +2985,11 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/symbol-observable": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-2.0.3.tgz", - "integrity": "sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10" - } - }, "node_modules/text-encoding-utf-8": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz", "integrity": "sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==" }, - "node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/through2/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "license": "MIT", - "optional": true - }, - "node_modules/through2/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "license": "MIT", - "optional": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/through2/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "license": "MIT", - "optional": true - }, - "node_modules/through2/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "license": "MIT", - "optional": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/tiny-secp256k1": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/tiny-secp256k1/-/tiny-secp256k1-1.1.7.tgz", - "integrity": "sha512-eb+F6NabSnjbLwNoC+2o5ItbmP1kg7HliWue71JgLegQt6A5mTN8YbvTLCazdlg6e5SV6A+r8OGvZYskdlmhqQ==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "bindings": "^1.3.0", - "bn.js": "^4.11.8", - "create-hmac": "^1.1.7", - "elliptic": "^6.4.0", - "nan": "^2.13.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/tiny-secp256k1/node_modules/bn.js": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", - "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", - "license": "MIT" - }, - "node_modules/tmp": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", - "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", - "license": "MIT", - "engines": { - "node": ">=14.14" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -7125,15 +3003,6 @@ "node": ">=8.0" } }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "license": "MIT", - "engines": { - "node": ">=0.6" - } - }, "node_modules/toml": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", @@ -7146,19 +3015,6 @@ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "license": "MIT" }, - "node_modules/ts-invariant": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.10.3.tgz", - "integrity": "sha512-uivwYcQaxAucv1CzRp2n/QdYPo4ILf9VXgH19zEIjFx2EJufV16P0JtJVpYHy89DItG6Kwj2oIUjrcK5au+4tQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -7185,47 +3041,16 @@ "fsevents": "~2.3.3" } }, - "node_modules/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", - "license": "Unlicense" - }, - "node_modules/tweetnacl-util": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", - "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==", - "license": "Unlicense", - "optional": true - }, "node_modules/type-detect": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true, "license": "MIT", "engines": { "node": ">=4" } }, - "node_modules/type-fest": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", - "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", - "license": "(MIT OR CC0-1.0)", - "optional": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typeforce": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz", - "integrity": "sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==", - "license": "MIT" - }, "node_modules/typescript": { "version": "5.8.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", @@ -7239,34 +3064,19 @@ "node": ">=14.17" } }, - "node_modules/u3": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/u3/-/u3-0.1.1.tgz", - "integrity": "sha512-+J5D5ir763y+Am/QY6hXNRlwljIeRMZMGs0cT6qqZVVzzT3X3nFPXVyPOFRMOR4kupB0T8JnCdpWdp6Q/iXn3w==", - "license": "MIT" - }, "node_modules/undici-types": { "version": "6.20.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", "license": "MIT" }, - "node_modules/untildify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", - "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=8" - } - }, "node_modules/utf-8-validate": { "version": "5.0.10", "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", "hasInstallScript": true, "license": "MIT", + "optional": true, "dependencies": { "node-gyp-build": "^4.3.0" }, @@ -7274,12 +3084,6 @@ "node": ">=6.14.2" } }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "license": "MIT" - }, "node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", @@ -7289,12 +3093,6 @@ "uuid": "dist/bin/uuid" } }, - "node_modules/vlq": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/vlq/-/vlq-2.0.4.tgz", - "integrity": "sha512-aodjPa2wPQFkra1G8CzJBTHXhgk3EVSwxSWXNPr1fgdFLUb8kvLV1iEb6rFgasIsjP82HWI6dsb5Io26DDnasA==", - "license": "MIT" - }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", @@ -7327,15 +3125,6 @@ "node": ">= 8" } }, - "node_modules/wif": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/wif/-/wif-2.0.6.tgz", - "integrity": "sha512-HIanZn1zmduSF+BQhkE+YXIbEiH0xPr1012QbFEGB0xsKqJii0/SqJjyn8dFv6y36kOznMgMB+LGcbZTJ1xACQ==", - "license": "MIT", - "dependencies": { - "bs58check": "<3.0.0" - } - }, "node_modules/workerpool": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", @@ -7438,13 +3227,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "license": "ISC", - "optional": true - }, "node_modules/ws": { "version": "7.5.10", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", @@ -7466,32 +3248,11 @@ } } }, - "node_modules/xstream": { - "version": "11.14.0", - "resolved": "https://registry.npmjs.org/xstream/-/xstream-11.14.0.tgz", - "integrity": "sha512-1bLb+kKKtKPbgTK6i/BaoAn03g47PpFstlbe1BA+y3pNS/LfvcaghS5BFf9+EE1J+KwSQsEpfJvFN5GqFtiNmw==", - "license": "MIT", - "optional": true, - "dependencies": { - "globalthis": "^1.0.1", - "symbol-observable": "^2.0.3" - } - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.4" - } - }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "devOptional": true, + "dev": true, "license": "ISC", "engines": { "node": ">=10" @@ -7599,23 +3360,6 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } - }, - "node_modules/zen-observable": { - "version": "0.8.15", - "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz", - "integrity": "sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==", - "license": "MIT", - "optional": true - }, - "node_modules/zen-observable-ts": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-1.2.5.tgz", - "integrity": "sha512-QZWQekv6iB72Naeake9hS1KxHlotfRpe+WGNbNx5/ta+R3DNjVO2bswf63gXlWDcs+EMd7XY8HfVQyP1X6T4Zg==", - "license": "MIT", - "optional": true, - "dependencies": { - "zen-observable": "0.8.15" - } } } } diff --git a/src/solana/package.json b/src/solana/package.json index f9e8d47..e44a126 100644 --- a/src/solana/package.json +++ b/src/solana/package.json @@ -7,21 +7,22 @@ "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" }, "dependencies": { - "@certusone/wormhole-sdk": "^0.10.18", "@coral-xyz/anchor": "^0.31.1", "@noble/hashes": "^1.7.2", - "@noble/secp256k1": "^2.2.3" + "@noble/secp256k1": "^2.2.3", + "@wormhole-foundation/sdk-base": "^1.20.0", + "@wormhole-foundation/sdk-definitions": "^1.20.0", + "@wormhole-foundation/sdk-solana-core": "^1.20.0" }, "devDependencies": { "@types/bn.js": "^5.1.0", "@types/chai": "^4.3.0", - "chai-as-promised": "^8.0.1", - "diff": "^7.0.0", - "@types/chai-as-promised": "^8.0.2", "@types/mocha": "^10.0.10", "chai": "^4.5.0", + "diff": "^7.0.0", "mocha": "^11.1.0", "prettier": "^2.6.2", + "toml": "^3.0.0", "tsx": "^4.19.3", "typescript": "^5.7.3" } diff --git a/src/solana/tests/layouts.ts b/src/solana/tests/layouts.ts new file mode 100644 index 0000000..b4abf9d --- /dev/null +++ b/src/solana/tests/layouts.ts @@ -0,0 +1,75 @@ +import { chainToChainId, enumItem, Layout, layoutItems } from '@wormhole-foundation/sdk-connect'; + +const versionItem = (custom: N) => + ({ name: 'version', binary: 'uint', size: 1, custom, omit: true }) as const; + +const consistencyLevelItem = { name: 'consistencyLevel', binary: 'uint', size: 1 } as const; + +const timestampItem = { name: 'timestamp', binary: 'uint', size: 4, endianness: 'little' } as const; + +const nonceAndSequenceLayout = [ + { name: 'nonce', binary: 'uint', size: 4, endianness: 'little' }, + { name: 'sequence', binary: 'uint', size: 8, endianness: 'little' }, +] as const satisfies Layout; + +const emitterAddressAndPayloadLayout = [ + { name: 'emitterAddress', ...layoutItems.universalAddressItem }, + { name: 'payload', binary: 'bytes', lengthSize: 4, lengthEndianness: 'little' }, +] as const satisfies Layout; + +// From here: https://github.com/wormhole-foundation/wormhole/blob/7bd40b595e22c5512dfaa2ed8e6d7441df743a69/solana/programs/core-bridge/src/legacy/state/posted_message_v1/mod.rs#L17-L35 +const messageStatusItem = { + name: 'messageStatus', + ...enumItem([ + ['Published', 0], + ['Writing', 1], + ['ReadyForPublishing', 2], + ]), +} as const; + +// From here: https://github.com/wormhole-foundation/wormhole/blob/7bd40b595e22c5512dfaa2ed8e6d7441df743a69/solana/programs/core-bridge/src/legacy/state/posted_message_v1/mod.rs#L39-L73 +// reuses unused fields (that were only used for VAAs) from here: https://github.com/wormhole-foundation/wormhole/blob/7247a0fc0c96ab9493b8d0b886a7a54ee2a8fcce/solana/bridge/program/src/accounts/posted_message.rs#L46-L76 +// hence these fields will only have sensible values when parsing posted messages by the solana core bridge rewrite +const postedMessageV1Layout = [ + versionItem(0), + consistencyLevelItem, + { name: 'emitterAuthority', ...layoutItems.universalAddressItem }, + messageStatusItem, + { name: 'unusedGap', binary: 'uint', size: 3, custom: 0, omit: true }, + timestampItem, + ...nonceAndSequenceLayout, + { + name: 'emitterChain', + binary: 'uint', + size: 2, + endianness: 'little', + custom: { from: chainToChainId('Solana'), to: 'Solana' }, + }, + ...emitterAddressAndPayloadLayout, +] as const satisfies Layout; + +//from here: https://github.com/wormhole-foundation/wormhole/blob/7bd40b595e22c5512dfaa2ed8e6d7441df743a69/solana/programs/core-bridge/src/legacy/state/posted_vaa_v1.rs#L12-L43 +//reuses unused fields (that were only used for posted messages) from here: https://github.com/wormhole-foundation/wormhole/blob/7247a0fc0c96ab9493b8d0b886a7a54ee2a8fcce/solana/bridge/program/src/accounts/posted_message.rs#L46-L76 +//hence these fields will only have sensible values when parsing posted messages by the solana core bridge rewrite +const postedVaaV1Layout = [ + versionItem(1), + consistencyLevelItem, + timestampItem, + { name: 'signatureSet', ...layoutItems.universalAddressItem }, + { name: 'guardianSetIndex', binary: 'uint', size: 4, endianness: 'little' }, + ...nonceAndSequenceLayout, + { name: 'emitterChain', ...layoutItems.chainItem(), endianness: 'little' }, + ...emitterAddressAndPayloadLayout, +] as const satisfies Layout; + +export const coreV1AccountDataLayout = { + binary: 'switch', + idSize: 3, + idTag: 'discriminator', + layouts: [ + //numeric values are ascii->number encoding of strings + [[0x6d7367, 'msg'], postedMessageV1Layout], + [[0x6d7375, 'msu'], postedMessageV1Layout], + [[0x766161, 'vaa'], postedVaaV1Layout], + ], +} as const satisfies Layout; diff --git a/src/solana/tests/testing-wormhole-core.ts b/src/solana/tests/testing-wormhole-core.ts new file mode 100644 index 0000000..174a07b --- /dev/null +++ b/src/solana/tests/testing-wormhole-core.ts @@ -0,0 +1,152 @@ +import anchor from '@coral-xyz/anchor'; +import { Connection, Keypair, PublicKey, Signer } from '@solana/web3.js'; +import { + Chain, + deserializeLayout, + encoding, + Network, + signAndSendWait, +} from '@wormhole-foundation/sdk-connect'; +import { SolanaSendSigner } from '@wormhole-foundation/sdk-solana'; +import { SolanaWormholeCore, utils as coreUtils } from '@wormhole-foundation/sdk-solana-core'; +import { + serializePayload, + serialize as serializeVaa, + deserialize as deserializeVaa, + UniversalAddress, + createVAA, + Contracts, + VAA, +} from '@wormhole-foundation/sdk-definitions'; +import { mocks } from '@wormhole-foundation/sdk-definitions/testing'; + +import { coreV1AccountDataLayout } from './layouts.js'; +import { sendAndConfirm } from './testing_helpers.js'; + +export type VaaMessage = VAA<'Uint8Array'>; + +const guardianKey = 'cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0'; +export const guardianAddress = 'beFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe'; + +/** A Wormhole Core wrapper allowing to write tests using this program in a local environment. */ +export class TestingWormholeCore { + public readonly signer: Signer; + public readonly client: SolanaWormholeCore; + private sequence = 0n; + private readonly toProgram: PublicKey; + private _guardians?: mocks.MockGuardians; + + /** + * + * @param solanaProgram The Solana Program used as a destination for the VAAs, _i.e._ the program being tested. + * @param contracts At least the core program address `coreBridge` must be provided. + */ + constructor( + signer: Signer, + connection: Connection, + network: N, + testedProgram: PublicKey, + contracts: Contracts, + ) { + this.signer = signer; + this.toProgram = testedProgram; + this.client = new SolanaWormholeCore(network, 'Solana', connection, contracts); + } + + get guardians(): mocks.MockGuardians { + if (this._guardians === undefined) throw Error("coreV1 not initialized") + + return this._guardians; + } + + get pda() { + return { + guardianSet: (): PublicKey => + this.findPda(Buffer.from('GuardianSet'), Buffer.from([0, 0, 0, 0])), + bridge: (): PublicKey => this.findPda(Buffer.from('Bridge')), + feeCollector: (): PublicKey => this.findPda(Buffer.from('fee_collector')), + }; + } + + async initialize( + guardians = [guardianAddress], + guardianSetExpirationTime = 86400, + fee = 100, + ) { + const initialGuardians = guardians.map((guardian) => Array.from(encoding.hex.decode(guardian))); + const initFee = new anchor.BN(fee); + + // https://github.com/wormhole-foundation/wormhole/blob/main/solana/bridge/program/src/api/initialize.rs + const ix = await this.client.coreBridge.methods + .initialize(guardianSetExpirationTime, initFee, initialGuardians) + .accounts({ + bridge: this.pda.bridge(), + guardianSet: this.pda.guardianSet(), + feeCollector: this.pda.feeCollector(), + payer: this.signer.publicKey, + }) + .instruction(); + + const txid = await sendAndConfirm(this.client.connection, ix, this.signer) + this._guardians = new mocks.MockGuardians(0, [guardianKey]) + return txid + } + + /** Parse a VAA generated from the postVaa method, or from the Token Bridge during + * and outbound transfer + */ + async parseVaa(key: PublicKey): Promise { + const info = await this.client.connection.getAccountInfo(key); + if (info === null) { + throw new Error(`No message account exists at that address: ${key.toString()}`); + } + + const message = deserializeLayout(coreV1AccountDataLayout, info.data); + + const vaa = createVAA('Uint8Array', { + guardianSet: 0, + timestamp: message.timestamp, + nonce: message.nonce, + emitterChain: message.emitterChain, + emitterAddress: message.emitterAddress, + sequence: message.sequence, + consistencyLevel: message.consistencyLevel, + signatures: [], + payload: message.payload, + }); + + return deserializeVaa('Uint8Array', serializeVaa(vaa)); + } + + /** + * `source`: the emitter of the message. + */ + async postVaa( + payer: Keypair, + source: { chain: Chain; emitterAddress: UniversalAddress }, + message: Uint8Array, + ): Promise { + const seq = this.sequence++; + const timestamp = Math.round(Date.now() / 1000); + + const emittingPeer = new mocks.MockEmitter(source.emitterAddress, source.chain, seq); + + const published = emittingPeer.publishMessage( + 0, // nonce, + message, + 1, // consistencyLevel + timestamp, + ); + const vaa = this.guardians.addSignatures(published, [0]); + + const txs = this.client.postVaa(payer.publicKey, vaa); + const signer = new SolanaSendSigner(this.client.connection, 'Solana', payer, false, {}); + await signAndSendWait(txs, signer); + + return coreUtils.derivePostedVaaKey(this.client.coreBridge.programId, Buffer.from(vaa.hash)); + } + + private findPda(...seeds: Array) { + return PublicKey.findProgramAddressSync(seeds, this.client.coreBridge.programId)[0]; + } +} diff --git a/src/solana/tests/testing_helpers.ts b/src/solana/tests/testing_helpers.ts index 14d517b..d7751ab 100644 --- a/src/solana/tests/testing_helpers.ts +++ b/src/solana/tests/testing_helpers.ts @@ -1,144 +1,104 @@ -import { Connection, LAMPORTS_PER_SOL, PublicKey, Signer, Transaction, TransactionInstruction, ComputeBudgetProgram, sendAndConfirmTransaction } from "@solana/web3.js" -import { NodeWallet, postVaaSolana, signSendAndConfirmTransaction } from "@certusone/wormhole-sdk/lib/cjs/solana" -import { MockGuardians } from "@certusone/wormhole-sdk/lib/cjs/mock" - -import { expect, use as chaiUse } from "chai" -import chaiAsPromised from "chai-as-promised" -chaiUse(chaiAsPromised) +import { + Connection, + Finality, + LAMPORTS_PER_SOL, + PublicKey, + Signer, + Transaction, + TransactionInstruction, + sendAndConfirmTransaction, + Keypair, + TransactionSignature, + VersionedTransactionResponse +} from "@solana/web3.js" +import { mocks } from "@wormhole-foundation/sdk-definitions/testing" +import { Contracts } from '@wormhole-foundation/sdk-definitions'; +import fs from "fs/promises" +import fsSync from "fs" +import * as toml from 'toml'; // Copied from @wormhole-foundation/wormhole-scaffolding/solana/ts/helpers/utils.ts // TODO: There's probably some way to import this? -export const MOCK_GUARDIANS = new MockGuardians(0, ["cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0"]) - -class SendIxError extends Error { - logs: string; - - constructor(originalError: Error & { logs?: string[] }) { - //The newlines don't actually show up correctly in chai's assertion error, but at least - // we have all the information and can just replace '\n' with a newline manually to see - // what's happening without having to change the code. - const logs = originalError.logs?.join('\n') || "error had no logs"; - super(originalError.message + "\nlogs:\n" + logs); - this.stack = originalError.stack; - this.logs = logs; +export const MOCK_GUARDIANS = new mocks.MockGuardians(0, ["cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0"]) + +// class SendIxError extends Error { +// logs: string; + +// constructor(originalError: Error & { logs?: string[] }) { +// //The newlines don't actually show up correctly in chai's assertion error, but at least +// // we have all the information and can just replace '\n' with a newline manually to see +// // what's happening without having to change the code. +// const logs = originalError.logs?.join('\n') || "error had no logs"; +// super(originalError.message + "\nlogs:\n" + logs); +// this.stack = originalError.stack; +// this.logs = logs; +// } +// } + +type Tuple = R['length'] extends N + ? R + : Tuple; + +export class TestsHelper { + static readonly LOCALHOST = 'http://localhost:8899'; + readonly connection: Connection; + readonly finality: Finality; + + /** Connections cache. */ + private static readonly connections: Partial> = {}; + + constructor(finality: Finality = 'confirmed') { + if (TestsHelper.connections[finality] === undefined) { + TestsHelper.connections[finality] = new Connection(TestsHelper.LOCALHOST, finality); + } + this.connection = TestsHelper.connections[finality]; + this.finality = finality; } -} -export const boilerPlateReduction = (connection: Connection, defaultSigner: Signer) => { - // for signing wormhole messages - const defaultNodeWallet = NodeWallet.fromSecretKey(defaultSigner.secretKey); - - const payerToWallet = (payer?: Signer) => - !payer || payer === defaultSigner - ? defaultNodeWallet - : NodeWallet.fromSecretKey(payer.secretKey); - - const requestAirdrop = async (account: PublicKey) => - connection.confirmTransaction( - await connection.requestAirdrop(account, 1000 * LAMPORTS_PER_SOL) - ); - - const guardianSign = (message: Buffer) => - MOCK_GUARDIANS.addSignatures(message, [0]) - - const postSignedMsgAsVaaOnSolana = async (coreV1: PublicKey, signedMsg: Buffer, payer?: Signer) => { - const wallet = payerToWallet(payer); - await postVaaSolana( - connection, - wallet.signTransaction, - coreV1, - wallet.key(), - signedMsg - ); - } + keypair = { + generate: (): Keypair => Keypair.generate(), + read: async (path: string): Promise => + this.keypair.from(JSON.parse(await fs.readFile(path, { encoding: 'utf8' }))), + from: (bytes: number[]): Keypair => Keypair.fromSecretKey(Uint8Array.from(bytes)), + several: (amount: N): Tuple => + Array.from({ length: amount }).map(Keypair.generate) as Tuple, + }; - const sendAndConfirmIx = async ( - ix: TransactionInstruction | Promise, - signerOrSignersOrComputeUnits?: Signer | Signer[] | number, - computeUnits?: number, - ) => { - let [signers, units] = (() => { - if (!signerOrSignersOrComputeUnits) - return [[defaultSigner], computeUnits]; - - if (typeof signerOrSignersOrComputeUnits === "number") { - if(computeUnits !== undefined) - throw new Error("computeUnits can't be specified twice"); - return [[defaultSigner], signerOrSignersOrComputeUnits]; - } + /** Waits that a transaction is confirmed. */ + async confirm(signature: TransactionSignature) { + const latestBlockHash = await this.connection.getLatestBlockhash(); - return [ - Array.isArray(signerOrSignersOrComputeUnits) - ? signerOrSignersOrComputeUnits - : [signerOrSignersOrComputeUnits], - computeUnits - ]; - })(); - - const tx = new Transaction().add(await ix); - if (units) - tx.add(ComputeBudgetProgram.setComputeUnitLimit({units})); - try { - return await sendAndConfirmTransaction(connection, tx, signers); - } - catch (error: any) { - throw new SendIxError(error); - } - } - - const expectIxToSucceed = async ( - ix: TransactionInstruction | Promise, - signerOrSignersOrComputeUnits?: Signer | Signer[] | number, - computeUnits?: number, - ) => - expect(sendAndConfirmIx(ix, signerOrSignersOrComputeUnits, computeUnits)).to.be.fulfilled; - - const expectIxToFailWithError = async ( - ix: TransactionInstruction | Promise, - errorMessage: string, - signerOrSignersOrComputeUnits?: Signer | Signer[] | number, - computeUnits?: number, - ) => { - try { - await sendAndConfirmIx(ix, signerOrSignersOrComputeUnits, computeUnits); - } catch (error) { - expect((error as SendIxError).logs).includes(errorMessage); - return; - } - expect.fail("Expected transaction to fail"); + return this.connection.confirmTransaction({ + signature, + blockhash: latestBlockHash.blockhash, + lastValidBlockHeight: latestBlockHash.lastValidBlockHeight, + }); } - const expectTxToSucceed = async ( - tx: Transaction | Promise, - payer?: Signer, - ) => { - const wallet = payerToWallet(payer); - return expect( - signSendAndConfirmTransaction( - connection, - wallet.key(), - wallet.signTransaction, - await tx, - )).to.be.fulfilled; + async sendAndConfirm( + ixs: TransactionInstruction | Transaction | TransactionInstruction[], + payer: Signer, + ...signers: Signer[] + ): Promise { + return sendAndConfirm(this.connection, ixs, payer, ...signers); } - const signAndPost = async (coreV1: PublicKey, message: Buffer, payer?: Signer) => { - const signedMsg = guardianSign(message); - await postSignedMsgAsVaaOnSolana(coreV1, signedMsg, payer); - return signedMsg; - }; + async getTransaction( + signature: TransactionSignature | Promise, + ): Promise { + return this.connection.getTransaction(await signature, { + commitment: this.finality, + maxSupportedTransactionVersion: 1, + }); + } - return { - requestAirdrop, - guardianSign, - postSignedMsgAsVaaOnSolana, - sendAndConfirmIx, - expectIxToSucceed, - expectIxToFailWithError, - expectTxToSucceed, - signAndPost, - }; + /** Requests airdrop to an account or several ones. */ + async airdrop(to: PublicKey[]): Promise { + await Promise.all(to.map(async (account) => + this.confirm(await this.connection.requestAirdrop(account, 50 * LAMPORTS_PER_SOL)) + )); + } } export function findPda(programId: PublicKey, seeds: Array) { @@ -157,3 +117,47 @@ export function findPda(programId: PublicKey, seeds: Array) bump, }; } + +export async function sendAndConfirm( + connection: Connection, + ixs: TransactionInstruction | Transaction | Array, + payer: Signer, + ...signers: Signer[] +): Promise { + const { value } = await connection.getLatestBlockhashAndContext(); + const tx = new Transaction({ + ...value, + feePayer: payer.publicKey, + }).add(...(Array.isArray(ixs) ? ixs : [ixs])); + + return sendAndConfirmTransaction(connection, tx, [payer, ...signers], {}); +} + +/** Helper allowing to abstract over the Wormhole configuration (network and addresses) */ +export class WormholeContracts { + static Network = 'Devnet' as const; + + private static core: PublicKey = PublicKey.default; + + static get coreBridge(): PublicKey { + WormholeContracts.init(); + return WormholeContracts.core; + } + + static get addresses(): Contracts { + WormholeContracts.init(); + return { + coreBridge: WormholeContracts.core.toString(), + }; + } + + private static init() { + if (WormholeContracts.core.equals(PublicKey.default)) { + const anchorCfg = toml.parse(fsSync.readFileSync('./Anchor.toml', 'utf-8')); + + WormholeContracts.core = new PublicKey( + anchorCfg.test.genesis.find((cfg: any) => cfg.name == 'wormhole-core-v1').address, + ); + } + } +} \ No newline at end of file diff --git a/src/solana/tests/verification_v2.ts b/src/solana/tests/verification_v2.ts index 9234181..5153892 100644 --- a/src/solana/tests/verification_v2.ts +++ b/src/solana/tests/verification_v2.ts @@ -1,22 +1,18 @@ import assert from "assert" import * as anchor from "@coral-xyz/anchor" -import { Keypair, PublicKey, SendTransactionError, Transaction, TransactionMessage, VersionedTransaction } from "@solana/web3.js" -import { VerificationV2 } from "../target/types/verification_v2.js" - -import { MockGuardians } from "@certusone/wormhole-sdk/lib/cjs/mock" -import * as coreV1 from "@certusone/wormhole-sdk/lib/cjs/solana/wormhole"; - +import { Keypair, PublicKey } from "@solana/web3.js" +import { toUniversal, UniversalAddress } from "@wormhole-foundation/sdk-definitions" import { getPublicKey, sign } from "@noble/secp256k1" import { keccak_256 } from "@noble/hashes/sha3" - -import { boilerPlateReduction, findPda } from "./testing_helpers.js" -import { Program } from "@coral-xyz/anchor" import { randomBytes } from "@noble/hashes/utils" -import { createPostSignedVaaTransactions } from "@certusone/wormhole-sdk/lib/cjs/solana/sendAndConfirmPostVaa.js" -import { parseVaa } from "@certusone/wormhole-sdk" -import { createPostVaaInstructionSolana } from "@certusone/wormhole-sdk/lib/cjs/solana/index.js" -import { deriveGuardianSetKey } from "@certusone/wormhole-sdk/lib/cjs/solana/wormhole" + +// import { VerificationV2 } from "../target/types/verification_v2.js" + +import { guardianAddress, TestingWormholeCore } from "./testing-wormhole-core.js" +import { WormholeContracts, TestsHelper } from "./testing_helpers.js" + +const $ = new TestsHelper() const encodeU16BE = (value: number) => [value >> 8, value & 0xFF] @@ -91,95 +87,82 @@ export const createAppendThresholdKeyMessage = (tssIndex: number, tssKey: Uint8A // ------------------------------------------------------------------------------------------------ -// Configure the client to use the local cluster. -anchor.setProvider(anchor.AnchorProvider.env()) - -const connection = anchor.getProvider().connection -const payer = anchor.getProvider().wallet?.payer -assert(payer, "Payer not found") - -const { - requestAirdrop, - guardianSign, - postSignedMsgAsVaaOnSolana, - expectIxToSucceed, - expectIxToFailWithError, - signAndPost, -} = boilerPlateReduction(connection, payer) - -const coreV1Address = new PublicKey('worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth') -const mockGuardians = new MockGuardians(0, ["cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0"]) -const guardianSetExpirationTime = 86400 - -{ - const fee = 100n - const devnetGuardian = mockGuardians.getPublicKeys()[0] - const initialGuardians = [devnetGuardian] - - await expectIxToSucceed( - coreV1.createInitializeInstruction( - coreV1Address, + +//TODO: get implementation for schnorr signing +async function thresholdGuardianSign(x: Uint8Array): Promise { + return x; +} + +describe("VerificationV2", function() { + const coreV1Address = new PublicKey('worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth') + const guardianSetExpirationTime = 86400 + const fee = 100 + const txSigner = $.keypair.generate() + let coreV1: TestingWormholeCore<"Devnet">; + const connection = $.connection + let payer: Keypair; + // const coreV2 = anchor.workspace.VerificationV2 as Program + + before(async function() { + payer = anchor.getProvider().wallet?.payer! + assert(payer, "Payer not found") + + await $.airdrop([ + txSigner.publicKey, payer.publicKey, + ]); + + coreV1 = new TestingWormholeCore( + txSigner, + connection, + WormholeContracts.Network, + coreV1Address, + WormholeContracts.addresses, + ); + + const txid = await coreV1.initialize(undefined, guardianSetExpirationTime, fee) + const tx = await $.getTransaction(txid) + }); + + it("Check correct core v1 setup", async function() { + const accounts = await connection.getProgramAccounts(coreV1Address) + assert(accounts.length === 2, "Expected 2 accounts") + + const guardianSetIndex = await coreV1.client.getGuardianSetIndex(); + assert(guardianSetIndex === 0, "Expected guardian set index to be 0") + const guardianSet = await coreV1.client.getGuardianSet(guardianSetIndex); + // FIXME? initialize doesn't seem to set the correct expiration time + // assert.strictEqual(guardianSet.expiry, BigInt(guardianSetExpirationTime), "Guardian set expiration time") + + const queriedFee = await coreV1.client.getMessageFee(); + assert(queriedFee === BigInt(fee), "Expected fee to be 100") + + assert(guardianSet.index === 0, "Expected guardian set index to be 0") + assert(guardianSet.keys.length === 1, "Expected guardian set keys to have length 1") + + const queriedGuardian = new UniversalAddress(guardianSet.keys[0], "hex"); + const expectedGuardian = toUniversal("Ethereum", guardianAddress) + assert(queriedGuardian.equals(expectedGuardian), "Expected guardian set keys to be the devnet guardian") + }) + + it("Posts append threshold key VAA successfully", async function(){ + const guardianPrivateKey = randomBytes(32) + const guardianPublicKey = keccak_256(getPublicKey(guardianPrivateKey)).slice(12) + const message = createAppendThresholdKeyMessage( + 0, + guardianPublicKey, guardianSetExpirationTime, - fee, - initialGuardians, ) - ) - - const accounts = await connection.getProgramAccounts(coreV1Address) - assert(accounts.length === 2, "Expected 2 accounts") - const info = await coreV1.getWormholeBridgeData(connection, coreV1Address) - assert(info.guardianSetIndex === 0, "Expected guardian set index to be 0") - assert(info.config.guardianSetExpirationTime === guardianSetExpirationTime, "Expected guardian set expiration time to be 86400") - assert(info.config.fee === fee, "Expected fee to be 100") - - const guardianSet = await coreV1.getGuardianSet(connection, coreV1Address, info.guardianSetIndex) - assert(guardianSet.index === 0, "Expected guardian set index to be 0") - assert(guardianSet.keys.length === 1, "Expected guardian set keys to have length 1") - assert(devnetGuardian.equals(guardianSet.keys[0]), "Expected guardian set keys to be the devnet guardian") -} + const governanceContract = new UniversalAddress("0000000000000000000000000000000000000000000000000000000000000004", "hex"); + const postedVaaAddress = await coreV1.postVaa( + payer, + { + chain: "Solana", + emitterAddress: governanceContract, + }, + message, + ) + }) -const coreV2 = anchor.workspace.VerificationV2 as Program - -const guardianPrivateKey = randomBytes(32) -const guardianPublicKey = keccak_256(getPublicKey(guardianPrivateKey)).slice(12) - -{ - const message = createAppendThresholdKeyMessage( - 0, - guardianPublicKey, - guardianSetExpirationTime, - ) - - const signedVaa = await guardianSign(Buffer.from(message)) - - const signatureSet = Keypair.generate() - - const verifySignaturesInstructions = await coreV1.createVerifySignaturesInstructions( - connection, - coreV1Address, - payer.publicKey, - signedVaa, - signatureSet.publicKey, - ) - - for (let i = 0; i < verifySignaturesInstructions.length; i += 2) { - const tx = new Transaction().add(...verifySignaturesInstructions.slice(i, i + 2)) - tx.feePayer = payer.publicKey - const txSig = await connection.sendTransaction(tx, [payer, signatureSet]) - assert(txSig, "Expected tx to succeed") - } - - const postVaaInstruction = createPostVaaInstructionSolana( - coreV1Address, - payer.publicKey, - signedVaa, - signatureSet.publicKey, - ) - - const postVaaTx = new Transaction().add(postVaaInstruction) - postVaaTx.feePayer = payer.publicKey - const postVaaSig = await connection.sendTransaction(postVaaTx, [payer]) - assert(postVaaSig, "Expected postVaa tx to succeed") -} +}); From 082a74859e8e3edb1476af7d985da877218b0d12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Claudio=20Nale?= Date: Mon, 2 Jun 2025 15:18:16 -0300 Subject: [PATCH 37/53] evm: updates makefile and foundry config --- Makefile | 5 ++--- foundry.toml | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index a53c003..c079bdd 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -TEST_RPC = https://rpc.ankr.com/eth +TEST_RPC = https://ethereum-rpc.publicnode.com tolib = $(addprefix lib/,$(firstword $(subst @, ,$(notdir $(1))))) @@ -20,8 +20,7 @@ test: dependencies #--match-test InitiateFullFuzz LIB_DEPS = foundry-rs/forge-std -LIB_DEPS += openzeppelin/openzeppelin-contracts@0457042d93d9dfd760dbaa06a4d2f1216fdbe297 #for gscd's optimizations -LIB_DEPS += wormhole-foundation/wormhole-solidity-sdk@d6a9368 +LIB_DEPS += wormhole-foundation/wormhole-solidity-sdk@a7c8786 # dynamically generate install rule for each lib dependency and add to depdenencies $(foreach dep,$(LIB_DEPS), $(eval $(call install_lib,$(dep)))) diff --git a/foundry.toml b/foundry.toml index d98a956..ab6d28e 100644 --- a/foundry.toml +++ b/foundry.toml @@ -3,7 +3,7 @@ solc_version = "0.8.28" evm_version = "paris" # prevent use of PUSH0 opcode until it is widely supported optimizer = true via_ir = true -extra_output = ["asm"] +extra_output = ["asm", "metadata", "storageLayout", "evm.deployedBytecode.immutableReferences"] libs = [ "lib", @@ -11,7 +11,6 @@ libs = [ remappings = [ "forge-std/=lib/forge-std/src/", - "@openzeppelin/=lib/openzeppelin-contracts/", "wormhole-sdk/=lib/wormhole-solidity-sdk/src/", "core-bridge/=src/", ] From d87f8b8c51b5cedc4911d79dd565dff6b6db44cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Claudio=20Nale?= Date: Mon, 2 Jun 2025 15:19:06 -0300 Subject: [PATCH 38/53] evm: fixes syntax error --- src/evm/ThresholdVerificationState.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/evm/ThresholdVerificationState.sol b/src/evm/ThresholdVerificationState.sol index 46195d2..c774206 100644 --- a/src/evm/ThresholdVerificationState.sol +++ b/src/evm/ThresholdVerificationState.sol @@ -134,7 +134,7 @@ contract ThresholdVerificationState { unchecked { uint256 offset = guardianSet << 1; require(offset < _thresholdData.length, InvalidThresholdKeyIndex()); - uint256 data = _thresholdData[offset + 1]); + uint256 data = _thresholdData[offset + 1]; shardCount = uint8((data >> 32) & 0xFF); shardBase = uint40(data >> 40); From e867c2f9c3d92f6aa37c7c4706449a38844bceb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Claudio=20Nale?= Date: Mon, 2 Jun 2025 15:20:00 -0300 Subject: [PATCH 39/53] evm: some minor improvements and removing obsolete comments --- src/evm/GuardianSetVerification.sol | 3 --- src/evm/ThresholdVerificationState.sol | 2 +- src/solana/programs/verification_v2/src/lib.rs | 9 ++------- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/evm/GuardianSetVerification.sol b/src/evm/GuardianSetVerification.sol index 2a739e5..ec164f3 100644 --- a/src/evm/GuardianSetVerification.sol +++ b/src/evm/GuardianSetVerification.sol @@ -41,8 +41,6 @@ contract GuardianSetVerification is GuardianSetVerificationState { require(version == 1, VaaLib.InvalidVersion(version)); // Get the guardian set and validate it's not expired - // FIXME: Do we want to do this expiration check? If we miss the expiration, - // I'm not sure what happens. uint32 expirationTime; (expirationTime, guardians) = _getGuardianSetInfo(guardianSetIndex); require(expirationTime > block.timestamp, GuardianSetExpired()); @@ -93,7 +91,6 @@ contract GuardianSetVerification is GuardianSetVerificationState { signatory != guardianAddress ); - // Verify the signature require(!failed, GuardianSetSignatureVerificationFailed()); prevGuardian = guardian; diff --git a/src/evm/ThresholdVerificationState.sol b/src/evm/ThresholdVerificationState.sol index c774206..1b68a80 100644 --- a/src/evm/ThresholdVerificationState.sol +++ b/src/evm/ThresholdVerificationState.sol @@ -43,7 +43,7 @@ contract ThresholdVerificationState { expirationTime = _thresholdDataExpirationTime(_thresholdData[offset + 1]); } } - + function _appendThresholdKey( uint32 currentGuardianSetIndex, uint32 newTSSIndex, diff --git a/src/solana/programs/verification_v2/src/lib.rs b/src/solana/programs/verification_v2/src/lib.rs index a4ab6ea..e27ff68 100644 --- a/src/solana/programs/verification_v2/src/lib.rs +++ b/src/solana/programs/verification_v2/src/lib.rs @@ -60,9 +60,9 @@ impl ThresholdKeyAccount { self.expiration_timestamp == 0 || self.expiration_timestamp > Clock::get().unwrap().unix_timestamp as u64 } - pub fn update_expiration_timestamp(&mut self, new_expiration_timestamp: u64) { + pub fn update_expiration_timestamp(&mut self, time_lapse: u64) { let current_timestamp = Clock::get().unwrap().unix_timestamp as u64; - self.expiration_timestamp = current_timestamp + new_expiration_timestamp; + self.expiration_timestamp = current_timestamp + time_lapse; } } @@ -145,11 +145,6 @@ pub mod verification_v2 { return Err(VAAError::InvalidIndex.into()); } - // Check that the threshold key is unexpired - if !threshold_key.is_unexpired() { - return Err(VAAError::TSSKeyExpired.into()); - } - // Check that the signature is valid threshold_key.key.check_signature(&vaa.message_hash()?, &vaa.header.signature)?; From e8ed1347b8380225bf58c6811f9210a37cfbdbe3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Claudio=20Nale?= Date: Mon, 2 Jun 2025 15:20:24 -0300 Subject: [PATCH 40/53] evm: pulls only guardian sets starting from a specific index --- src/evm/GuardianSetVerification.sol | 3 ++- src/evm/GuardianSetVerificationState.sol | 8 ++++++++ src/evm/VerificationV2.sol | 6 +++--- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/evm/GuardianSetVerification.sol b/src/evm/GuardianSetVerification.sol index ec164f3..50390a3 100644 --- a/src/evm/GuardianSetVerification.sol +++ b/src/evm/GuardianSetVerification.sol @@ -20,8 +20,9 @@ contract GuardianSetVerification is GuardianSetVerificationState { constructor( address coreBridge, + uint256 initGuardianSetIndex, uint256 pullLimit - ) GuardianSetVerificationState(coreBridge, pullLimit) {} + ) GuardianSetVerificationState(coreBridge, initGuardianSetIndex, pullLimit) {} function _verifyGuardianSetVaaHeader(bytes calldata encodedVaa) internal view returns ( uint envelopeOffset, diff --git a/src/evm/GuardianSetVerificationState.sol b/src/evm/GuardianSetVerificationState.sol index 0d2b066..849b983 100644 --- a/src/evm/GuardianSetVerificationState.sol +++ b/src/evm/GuardianSetVerificationState.sol @@ -19,9 +19,17 @@ contract GuardianSetVerificationState is ExtStore { constructor( address coreBridge, + uint256 initGuardianSetIndex, uint256 pullLimit ) { _coreBridge = ICoreBridge(coreBridge); + + require(initGuardianSetIndex <= _coreBridge.getCurrentGuardianSetIndex()); + // All previous guardian sets will have expiration timestamp 0 + assembly ("memory-safe") { + sstore(_guardianSetExpirationTime.slot, initGuardianSetIndex) + } + _pullGuardianSets(pullLimit); } diff --git a/src/evm/VerificationV2.sol b/src/evm/VerificationV2.sol index b8b1d0b..081dad8 100644 --- a/src/evm/VerificationV2.sol +++ b/src/evm/VerificationV2.sol @@ -42,9 +42,9 @@ contract VerificationV2 is error GuardianSetIsNotCurrent(); // FIXME: The initial TSS index should be the latest guardian set index, not passed in! - constructor(address coreV1, uint256 pullLimit) - GuardianSetVerification(coreV1, pullLimit) - GuardianRegistryVerification() + constructor(address coreV1, uint256 initGuardianSetIndex, uint256 pullLimit) + GuardianSetVerification(coreV1, initGuardianSetIndex, pullLimit) + GuardianRegistryVerification() {} function _verifyVaa(bytes calldata data) private view { From bed801479759db3c8b711666d9e468688d20e591 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Claudio=20Nale?= Date: Mon, 2 Jun 2025 15:30:14 -0300 Subject: [PATCH 41/53] evm: cleans up imports --- src/evm/GuardianRegistryVerification.sol | 1 + src/evm/GuardianSetVerification.sol | 3 ++- src/evm/GuardianSetVerificationState.sol | 1 + src/evm/ThresholdVerification.sol | 7 ++++--- src/evm/VerificationV2.sol | 1 + 5 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/evm/GuardianRegistryVerification.sol b/src/evm/GuardianRegistryVerification.sol index aef5f70..213de5f 100644 --- a/src/evm/GuardianRegistryVerification.sol +++ b/src/evm/GuardianRegistryVerification.sol @@ -5,6 +5,7 @@ pragma solidity ^0.8.0; import {eagerOr} from "wormhole-sdk/Utils.sol"; import {BytesParsing} from "wormhole-sdk/libraries/BytesParsing.sol"; import {VaaLib} from "wormhole-sdk/libraries/VaaLib.sol"; + import {EIP712Encoding} from "./EIP712Encoding.sol"; import {ThresholdVerificationState} from "./ThresholdVerificationState.sol"; diff --git a/src/evm/GuardianSetVerification.sol b/src/evm/GuardianSetVerification.sol index 50390a3..0b15571 100644 --- a/src/evm/GuardianSetVerification.sol +++ b/src/evm/GuardianSetVerification.sol @@ -7,7 +7,8 @@ import {BytesParsing} from "wormhole-sdk/libraries/BytesParsing.sol"; import {VaaLib} from "wormhole-sdk/libraries/VaaLib.sol"; import {CoreBridgeLib} from "wormhole-sdk/libraries/CoreBridge.sol"; import {UncheckedIndexing} from "wormhole-sdk/libraries/UncheckedIndexing.sol"; -import "./GuardianSetVerificationState.sol"; + +import {GuardianSetVerificationState} from "./GuardianSetVerificationState.sol"; contract GuardianSetVerification is GuardianSetVerificationState { using BytesParsing for bytes; diff --git a/src/evm/GuardianSetVerificationState.sol b/src/evm/GuardianSetVerificationState.sol index 849b983..b55dd7d 100644 --- a/src/evm/GuardianSetVerificationState.sol +++ b/src/evm/GuardianSetVerificationState.sol @@ -4,6 +4,7 @@ pragma solidity ^0.8.0; import {ICoreBridge, GuardianSet} from "wormhole-sdk/interfaces/ICoreBridge.sol"; import {UncheckedIndexing} from "wormhole-sdk/libraries/UncheckedIndexing.sol"; + import {ExtStore} from "./ExtStore.sol"; contract GuardianSetVerificationState is ExtStore { diff --git a/src/evm/ThresholdVerification.sol b/src/evm/ThresholdVerification.sol index 249b171..d1c4f84 100644 --- a/src/evm/ThresholdVerification.sol +++ b/src/evm/ThresholdVerification.sol @@ -2,10 +2,11 @@ pragma solidity ^0.8.0; -import "wormhole-sdk/libraries/BytesParsing.sol"; +import {BytesParsing} from "wormhole-sdk/libraries/BytesParsing.sol"; import {GuardianSet} from "wormhole-sdk/interfaces/ICoreBridge.sol"; -import "wormhole-sdk/libraries/VaaLib.sol"; -import "./ThresholdVerificationState.sol"; +import {VaaLib} from "wormhole-sdk/libraries/VaaLib.sol"; + +import {ThresholdVerificationState} from "./ThresholdVerificationState.sol"; contract ThresholdVerification is ThresholdVerificationState { using BytesParsing for bytes; diff --git a/src/evm/VerificationV2.sol b/src/evm/VerificationV2.sol index 081dad8..765da91 100644 --- a/src/evm/VerificationV2.sol +++ b/src/evm/VerificationV2.sol @@ -6,6 +6,7 @@ import {BytesParsing} from "wormhole-sdk/libraries/BytesParsing.sol"; import {VaaLib} from "wormhole-sdk/libraries/VaaLib.sol"; import {RawDispatcher} from "wormhole-sdk/RawDispatcher.sol"; import {CHAIN_ID_SOLANA} from "wormhole-sdk/constants/Chains.sol"; + import {ThresholdVerification} from "./ThresholdVerification.sol"; import {GuardianSetVerification} from "./GuardianSetVerification.sol"; import {GuardianRegistryVerification} from "./GuardianRegistryVerification.sol"; From c6c794af673d43fdcbcb6ebcfa8d188a9fdfa4f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Claudio=20Nale?= Date: Mon, 2 Jun 2025 16:46:05 -0300 Subject: [PATCH 42/53] evm: renames a few classes and functions --- ...Verification.sol => MultisigVerification.sol} | 16 ++++++++-------- ...onState.sol => MultisigVerificationState.sol} | 2 +- src/evm/VerificationV2.sol | 16 ++++++++-------- 3 files changed, 17 insertions(+), 17 deletions(-) rename src/evm/{GuardianSetVerification.sol => MultisigVerification.sol} (87%) rename src/evm/{GuardianSetVerificationState.sol => MultisigVerificationState.sol} (98%) diff --git a/src/evm/GuardianSetVerification.sol b/src/evm/MultisigVerification.sol similarity index 87% rename from src/evm/GuardianSetVerification.sol rename to src/evm/MultisigVerification.sol index 0b15571..f766266 100644 --- a/src/evm/GuardianSetVerification.sol +++ b/src/evm/MultisigVerification.sol @@ -8,24 +8,24 @@ import {VaaLib} from "wormhole-sdk/libraries/VaaLib.sol"; import {CoreBridgeLib} from "wormhole-sdk/libraries/CoreBridge.sol"; import {UncheckedIndexing} from "wormhole-sdk/libraries/UncheckedIndexing.sol"; -import {GuardianSetVerificationState} from "./GuardianSetVerificationState.sol"; +import {MultisigVerificationState} from "./MultisigVerificationState.sol"; -contract GuardianSetVerification is GuardianSetVerificationState { +contract MultisigVerification is MultisigVerificationState { using BytesParsing for bytes; using VaaLib for bytes; using UncheckedIndexing for address[]; error QuorumNotMet(); - error GuardianSetSignatureVerificationFailed(); + error MultisigSignatureVerificationFailed(); error GuardianSetExpired(); constructor( address coreBridge, uint256 initGuardianSetIndex, uint256 pullLimit - ) GuardianSetVerificationState(coreBridge, initGuardianSetIndex, pullLimit) {} + ) MultisigVerificationState(coreBridge, initGuardianSetIndex, pullLimit) {} - function _verifyGuardianSetVaaHeader(bytes calldata encodedVaa) internal view returns ( + function _verifyMultisigVaaHeader(bytes calldata encodedVaa) internal view returns ( uint envelopeOffset, uint32 guardianSetIndex, address[] memory guardians @@ -93,7 +93,7 @@ contract GuardianSetVerification is GuardianSetVerificationState { signatory != guardianAddress ); - require(!failed, GuardianSetSignatureVerificationFailed()); + require(!failed, MultisigSignatureVerificationFailed()); prevGuardian = guardian; isFirstSignature = false; @@ -102,7 +102,7 @@ contract GuardianSetVerification is GuardianSetVerificationState { } // Verify a guardian set VAA - function _verifyAndDecodeGuardianSetVaa(bytes calldata encodedVaa) internal view returns ( + function _verifyAndDecodeMultisigVaa(bytes calldata encodedVaa) internal view returns ( uint32 timestamp, uint32 nonce, uint16 emitterChainId, @@ -114,7 +114,7 @@ contract GuardianSetVerification is GuardianSetVerificationState { address[] memory guardians ) { uint payloadOffset; - (payloadOffset, guardianSetIndex, guardians) = _verifyGuardianSetVaaHeader(encodedVaa); + (payloadOffset, guardianSetIndex, guardians) = _verifyMultisigVaaHeader(encodedVaa); ( timestamp, diff --git a/src/evm/GuardianSetVerificationState.sol b/src/evm/MultisigVerificationState.sol similarity index 98% rename from src/evm/GuardianSetVerificationState.sol rename to src/evm/MultisigVerificationState.sol index b55dd7d..0ff3853 100644 --- a/src/evm/GuardianSetVerificationState.sol +++ b/src/evm/MultisigVerificationState.sol @@ -7,7 +7,7 @@ import {UncheckedIndexing} from "wormhole-sdk/libraries/UncheckedIndexing.sol"; import {ExtStore} from "./ExtStore.sol"; -contract GuardianSetVerificationState is ExtStore { +contract MultisigVerificationState is ExtStore { using UncheckedIndexing for address[]; error InvalidGuardianSetIndex(); diff --git a/src/evm/VerificationV2.sol b/src/evm/VerificationV2.sol index 765da91..b029d12 100644 --- a/src/evm/VerificationV2.sol +++ b/src/evm/VerificationV2.sol @@ -8,11 +8,11 @@ import {RawDispatcher} from "wormhole-sdk/RawDispatcher.sol"; import {CHAIN_ID_SOLANA} from "wormhole-sdk/constants/Chains.sol"; import {ThresholdVerification} from "./ThresholdVerification.sol"; -import {GuardianSetVerification} from "./GuardianSetVerification.sol"; +import {MultisigVerification} from "./MultisigVerification.sol"; import {GuardianRegistryVerification} from "./GuardianRegistryVerification.sol"; // Raw dispatch operation IDs for exec -uint8 constant OP_GOVERNANCE = 0x00; +uint8 constant OP_APPEND_THRESHOLD_KEY = 0x00; uint8 constant OP_PULL_GUARDIAN_SETS = 0x01; uint8 constant OP_REGISTER_GUARDIAN = 0x02; @@ -29,7 +29,7 @@ uint8 constant OP_GUARDIAN_SHARDS_GET = 0x26; bytes32 constant GOVERNANCE_ADDRESS = bytes32(0x0000000000000000000000000000000000000000000000000000000000000004); contract VerificationV2 is - RawDispatcher, ThresholdVerification, GuardianSetVerification, GuardianRegistryVerification + RawDispatcher, ThresholdVerification, MultisigVerification, GuardianRegistryVerification { using BytesParsing for bytes; using VaaLib for bytes; @@ -44,7 +44,7 @@ contract VerificationV2 is // FIXME: The initial TSS index should be the latest guardian set index, not passed in! constructor(address coreV1, uint256 initGuardianSetIndex, uint256 pullLimit) - GuardianSetVerification(coreV1, initGuardianSetIndex, pullLimit) + MultisigVerification(coreV1, initGuardianSetIndex, pullLimit) GuardianRegistryVerification() {} @@ -53,7 +53,7 @@ contract VerificationV2 is if (version == 2) { _verifyThresholdVaaHeader(data); } else if (version == 1) { - _verifyGuardianSetVaaHeader(data); + _verifyMultisigVaaHeader(data); } else { revert VaaLib.InvalidVersion(version); } @@ -72,7 +72,7 @@ contract VerificationV2 is if (version == 2) { (timestamp, nonce, emitterChainId, emitterAddress, sequence, consistencyLevel, payload) = _verifyAndDecodeThresholdVaa(data); } else if (version == 1) { - (timestamp, nonce, emitterChainId, emitterAddress, sequence, consistencyLevel, payload,,) = _verifyAndDecodeGuardianSetVaa(data); + (timestamp, nonce, emitterChainId, emitterAddress, sequence, consistencyLevel, payload,,) = _verifyAndDecodeMultisigVaa(data); } else { revert VaaLib.InvalidVersion(version); } @@ -86,7 +86,7 @@ contract VerificationV2 is uint8 op; (op, offset) = data.asUint8CdUnchecked(offset); - if (op == OP_GOVERNANCE) { + if (op == OP_APPEND_THRESHOLD_KEY) { // Read the VAA bytes calldata encodedVaa; (encodedVaa, offset) = data.sliceUint16PrefixedCdUnchecked(offset); @@ -104,7 +104,7 @@ contract VerificationV2 is bytes calldata payload, uint32 guardianSetIndex, address[] memory guardians - ) = _verifyAndDecodeGuardianSetVaa(encodedVaa); + ) = _verifyAndDecodeMultisigVaa(encodedVaa); // Verify the emitter if (emitterChainId != CHAIN_ID_SOLANA) revert InvalidGovernanceChainId(); From 4b518fa93e5289b43d9f1bcfddc0fec90040ba73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Claudio=20Nale?= Date: Mon, 2 Jun 2025 17:27:11 -0300 Subject: [PATCH 43/53] evm: comments on register guardian verification --- src/evm/GuardianRegistryVerification.sol | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/evm/GuardianRegistryVerification.sol b/src/evm/GuardianRegistryVerification.sol index 213de5f..d9e8ab0 100644 --- a/src/evm/GuardianRegistryVerification.sol +++ b/src/evm/GuardianRegistryVerification.sol @@ -28,6 +28,8 @@ contract GuardianRegistryVerification is EIP712Encoding { bytes32 digest = getRegisterGuardianDigest(guardianSet, expirationTime, id); // Verify the signature + // We're not doing replay protection with the signature itself so we don't care about + // verifying only canonical (low s) signatures. address signatory = ecrecover(digest, v, r, s); require(signatory == guardianAddrs[guardian], GuardianSignatureVerificationFailed()); } From 5f3ab808cc90828be91aac243d3bf7a1e3a082c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Claudio=20Nale?= Date: Mon, 2 Jun 2025 17:28:08 -0300 Subject: [PATCH 44/53] evm: makes the expiration time set only for past guardians This makes the semantics of the append threshold key VAA identical to the Solana implementation. --- src/evm/ThresholdVerificationState.sol | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/evm/ThresholdVerificationState.sol b/src/evm/ThresholdVerificationState.sol index 1b68a80..10f6f39 100644 --- a/src/evm/ThresholdVerificationState.sol +++ b/src/evm/ThresholdVerificationState.sol @@ -55,25 +55,24 @@ contract ThresholdVerificationState { // Get the current threshold info and verify the new index is sequential // NOTE: We can't use _getCurrentThresholdInfo() directly here because // _thresholdData will be empty on the first append - uint32 index; if (_thresholdData.length > 0) { + uint32 index; // If there is threshold data, the new index must be sequential (, index) = _getCurrentThresholdInfo(); require(newTSSIndex == index + 1, InvalidThresholdKeyIndex()); // Verify we have a matching guardian set require(currentGuardianSetIndex >= newTSSIndex, InvalidThresholdKeyIndex()); + + // Store the expiration time and current threshold address in past threshold info + uint32 expirationTime = uint32(block.timestamp) + expirationDelaySeconds; + _setThresholdDataExpirationTime(index, expirationTime); } else { // If there is no threshold data, the initial index must be the new index require(newTSSIndex == currentGuardianSetIndex, InvalidThresholdKeyIndex()); - index = currentGuardianSetIndex; _thresholdDataInitialIndex = currentGuardianSetIndex; } - // Store the expiration time and current threshold address in past threshold info - uint32 expirationTime = uint32(block.timestamp) + expirationDelaySeconds; - _setThresholdDataExpirationTime(index, expirationTime); - // Store the new threshold info _thresholdData.push(pubkey); _thresholdData.push(_createThresholdData(uint8(shards.length), uint40(_shardData.length))); From 56db3eb85b765049440ef61d9d74a548b3bc95fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Claudio=20Nale?= Date: Mon, 2 Jun 2025 17:31:57 -0300 Subject: [PATCH 45/53] evm: removes redundant code --- src/evm/VerificationV2.sol | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/src/evm/VerificationV2.sol b/src/evm/VerificationV2.sol index b029d12..e754e51 100644 --- a/src/evm/VerificationV2.sol +++ b/src/evm/VerificationV2.sol @@ -48,7 +48,7 @@ contract VerificationV2 is GuardianRegistryVerification() {} - function _verifyVaa(bytes calldata data) private view { + function verifyVaa(bytes calldata data) internal view { (uint8 version, ) = data.asUint8CdUnchecked(0); if (version == 2) { _verifyThresholdVaaHeader(data); @@ -59,7 +59,7 @@ contract VerificationV2 is } } - function _verifyAndDecodeVaa(bytes calldata data) private view returns ( + function verifyAndDecodeVaa(bytes calldata data) internal view returns ( uint32 timestamp, uint32 nonce, uint16 emitterChainId, @@ -183,7 +183,7 @@ contract VerificationV2 is uint64 sequence, uint8 consistencyLevel, bytes calldata payload - ) = _verifyAndDecodeVaa(encodedVaa); + ) = verifyAndDecodeVaa(encodedVaa); result = abi.encodePacked( result, @@ -201,7 +201,7 @@ contract VerificationV2 is (encodedVaa, offset) = data.sliceUint16PrefixedCdUnchecked(offset); // Verify the VAA - _verifyVaa(encodedVaa); + verifyVaa(encodedVaa); } else if (op == OP_THRESHOLD_GET_CURRENT) { (uint256 thresholdAddr, uint32 thresholdIndex) = _getCurrentThresholdInfo(); @@ -245,20 +245,4 @@ contract VerificationV2 is return result; } - - function verifyVaa(bytes calldata encodedVaa) internal view { - _verifyVaa(encodedVaa); - } - - function verifyAndDecodeVaa(bytes calldata encodedVaa) internal view returns ( - uint32 timestamp, - uint32 nonce, - uint16 emitterChainId, - bytes32 emitterAddress, - uint64 sequence, - uint8 consistencyLevel, - bytes calldata payload - ) { - return _verifyAndDecodeVaa(encodedVaa); - } } \ No newline at end of file From 240bfdaf684b1ea072b6a27486787d8dce0fd0f9 Mon Sep 17 00:00:00 2001 From: Joshua Averett Date: Tue, 3 Jun 2025 08:49:14 -0700 Subject: [PATCH 46/53] Refactor and cleanup --- src/evm/EIP712Encoding.sol | 3 +- src/evm/GuardianRegistryVerification.sol | 34 ------ src/evm/MultisigVerification.sol | 32 ++---- src/evm/MultisigVerificationState.sol | 9 +- src/evm/ThresholdVerification.sol | 50 +++------ src/evm/ThresholdVerificationState.sol | 137 ++++++++--------------- src/evm/VerificationV2.sol | 96 ++++++++-------- 7 files changed, 129 insertions(+), 232 deletions(-) delete mode 100644 src/evm/GuardianRegistryVerification.sol diff --git a/src/evm/EIP712Encoding.sol b/src/evm/EIP712Encoding.sol index 97cb23a..d291fd2 100644 --- a/src/evm/EIP712Encoding.sol +++ b/src/evm/EIP712Encoding.sol @@ -7,7 +7,6 @@ import {BytesParsing} from "wormhole-sdk/libraries/BytesParsing.sol"; import {VaaLib} from "wormhole-sdk/libraries/VaaLib.sol"; contract EIP712Encoding { - bytes32 constant EIP712_DOMAIN_TYPE_HASH = keccak256( "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" ); @@ -53,4 +52,4 @@ contract EIP712Encoding { bytes32 idHash = getRegisterGuardianHash(guardianSet, expirationTime, id); return keccak256(abi.encodePacked("\x19\x01", _domainSeparator, idHash)); } -} \ No newline at end of file +} diff --git a/src/evm/GuardianRegistryVerification.sol b/src/evm/GuardianRegistryVerification.sol deleted file mode 100644 index 213de5f..0000000 --- a/src/evm/GuardianRegistryVerification.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: Apache 2 - -pragma solidity ^0.8.0; - -import {eagerOr} from "wormhole-sdk/Utils.sol"; -import {BytesParsing} from "wormhole-sdk/libraries/BytesParsing.sol"; -import {VaaLib} from "wormhole-sdk/libraries/VaaLib.sol"; - -import {EIP712Encoding} from "./EIP712Encoding.sol"; -import {ThresholdVerificationState} from "./ThresholdVerificationState.sol"; - -contract GuardianRegistryVerification is EIP712Encoding { - using BytesParsing for bytes; - using VaaLib for bytes; - - error RegistrationMessageExpired(); - error GuardianSignatureVerificationFailed(); - - function _verifyRegisterGuardian( - address[] memory guardianAddrs, - uint32 guardianSet, - uint32 expirationTime, - bytes32 id, - uint8 guardian, - bytes32 r, bytes32 s, uint8 v - ) internal view { - require(expirationTime > block.timestamp, RegistrationMessageExpired()); - bytes32 digest = getRegisterGuardianDigest(guardianSet, expirationTime, id); - - // Verify the signature - address signatory = ecrecover(digest, v, r, s); - require(signatory == guardianAddrs[guardian], GuardianSignatureVerificationFailed()); - } -} diff --git a/src/evm/MultisigVerification.sol b/src/evm/MultisigVerification.sol index f766266..3606921 100644 --- a/src/evm/MultisigVerification.sol +++ b/src/evm/MultisigVerification.sol @@ -25,15 +25,12 @@ contract MultisigVerification is MultisigVerificationState { uint256 pullLimit ) MultisigVerificationState(coreBridge, initGuardianSetIndex, pullLimit) {} - function _verifyMultisigVaaHeader(bytes calldata encodedVaa) internal view returns ( - uint envelopeOffset, - uint32 guardianSetIndex, - address[] memory guardians - ) { + function _verifyMultisigVaaHeader(bytes calldata encodedVaa) internal view returns (uint envelopeOffset) { unchecked { uint offset = 0; uint8 version; - uint signatureCount; + uint32 guardianSetIndex; + uint8 signatureCount; (version, offset) = encodedVaa.asUint8CdUnchecked(offset); (guardianSetIndex, offset) = encodedVaa.asUint32CdUnchecked(offset); @@ -43,8 +40,7 @@ contract MultisigVerification is MultisigVerificationState { require(version == 1, VaaLib.InvalidVersion(version)); // Get the guardian set and validate it's not expired - uint32 expirationTime; - (expirationTime, guardians) = _getGuardianSetInfo(guardianSetIndex); + (uint32 expirationTime, address[] memory guardians) = _getGuardianSetInfo(guardianSetIndex); require(expirationTime > block.timestamp, GuardianSetExpired()); // Get the number of signatures @@ -66,7 +62,7 @@ contract MultisigVerification is MultisigVerificationState { bool isFirstSignature = true; uint prevGuardian; - for (uint i = 0; i < signatureCount; ++i) { + for (uint i = 0; i < signatureCount; i++) { // Decode the guardian index, r, s, and v uint guardian; bytes32 r; bytes32 s; uint8 v; (guardian, r, s, v, offset) = encodedVaa.decodeGuardianSignatureCdUnchecked(offset); @@ -109,21 +105,9 @@ contract MultisigVerification is MultisigVerificationState { bytes32 emitterAddress, uint64 sequence, uint8 consistencyLevel, - bytes calldata payload, - uint32 guardianSetIndex, - address[] memory guardians + bytes calldata payload ) { - uint payloadOffset; - (payloadOffset, guardianSetIndex, guardians) = _verifyMultisigVaaHeader(encodedVaa); - - ( - timestamp, - nonce, - emitterChainId, - emitterAddress, - sequence, - consistencyLevel, - payload - ) = encodedVaa.decodeVaaBodyCd(payloadOffset); + uint payloadOffset = _verifyMultisigVaaHeader(encodedVaa); + return encodedVaa.decodeVaaBodyCd(payloadOffset); } } diff --git a/src/evm/MultisigVerificationState.sol b/src/evm/MultisigVerificationState.sol index 0ff3853..abadeab 100644 --- a/src/evm/MultisigVerificationState.sol +++ b/src/evm/MultisigVerificationState.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.0; import {ICoreBridge, GuardianSet} from "wormhole-sdk/interfaces/ICoreBridge.sol"; +import {eagerOr} from "wormhole-sdk/Utils.sol"; import {UncheckedIndexing} from "wormhole-sdk/libraries/UncheckedIndexing.sol"; import {ExtStore} from "./ExtStore.sol"; @@ -58,7 +59,7 @@ contract MultisigVerificationState is ExtStore { // NOTE: The `data` array is temporary and is invalid after this block assembly ("memory-safe") { guardianAddrs := data - mstore(guardianAddrs, div(mload(guardianAddrs), 32)) + mstore(guardianAddrs, shr(5, mload(guardianAddrs))) } } @@ -81,11 +82,11 @@ contract MultisigVerificationState is ExtStore { } // Calculate the upper bound of the guardian sets to pull - uint upper = (limit == 0 || currentGuardianSetLength - oldGuardianSetLength < limit) + uint upper = eagerOr(limit == 0, currentGuardianSetLength - oldGuardianSetLength < limit) ? currentGuardianSetLength : oldGuardianSetLength + limit; // Pull and append the guardian sets - for (uint i = oldGuardianSetLength; i < upper; ++i) { + for (uint i = oldGuardianSetLength; i < upper; i++) { // Pull the guardian set, write the expiration time, and append the guardian set data to the ExtStore (bytes memory data, uint32 expirationTime) = _pullGuardianSet(uint32(i)); _guardianSetExpirationTime.push(expirationTime); @@ -112,7 +113,7 @@ contract MultisigVerificationState is ExtStore { address[] memory keys = guardians.keys; assembly ("memory-safe") { data := keys - mstore(data, mul(mload(data), 32)) + mstore(data, shl(5, mload(data))) } } } diff --git a/src/evm/ThresholdVerification.sol b/src/evm/ThresholdVerification.sol index d1c4f84..1f656fb 100644 --- a/src/evm/ThresholdVerification.sol +++ b/src/evm/ThresholdVerification.sol @@ -5,6 +5,7 @@ pragma solidity ^0.8.0; import {BytesParsing} from "wormhole-sdk/libraries/BytesParsing.sol"; import {GuardianSet} from "wormhole-sdk/interfaces/ICoreBridge.sol"; import {VaaLib} from "wormhole-sdk/libraries/VaaLib.sol"; +import {eagerAnd, eagerOr} from "wormhole-sdk/Utils.sol"; import {ThresholdVerificationState} from "./ThresholdVerificationState.sol"; @@ -20,8 +21,8 @@ contract ThresholdVerification is ThresholdVerificationState { uint8 constant ACTION_APPEND_THRESHOLD_KEY = 0x01; // Curve order for secp256k1 - uint256 constant public Q = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141; - uint256 constant public HALF_Q = Q >> 1; + uint256 constant internal Q = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141; + uint256 constant internal HALF_Q = Q >> 1; error ThresholdKeyExpired(); error ThresholdSignatureVerificationFailed(); @@ -39,22 +40,23 @@ contract ThresholdVerification is ThresholdVerificationState { (version, offset) = encodedVaa.asUint8CdUnchecked(offset); (tssIndex, offset) = encodedVaa.asUint32CdUnchecked(offset); - (r, s, offset) = _decodeThresholdSignatureCdUnchecked(encodedVaa, offset); + (r, offset) = encodedVaa.asAddressCdUnchecked(offset); + (s, offset) = encodedVaa.asUint256CdUnchecked(offset); // Validate the VAA version and threshold signature is in range // NOTE: s < Q prevents signature malleability // NOTE: Non-zero r prevents confusion with ecrecover failure // NOTE: Non-zero check on s not needed, see the first argument of ecrecover require(version == 2, VaaLib.InvalidVersion(version)); - require(s < Q && r != address(0), ThresholdSignatureVerificationFailed()); + require(eagerAnd(s < Q, r != address(0)), ThresholdSignatureVerificationFailed()); // Load threshold key info and validate expiration time - (uint256 pubkey, uint32 expirationTime) = _getThresholdInfo(tssIndex); - require(expirationTime > block.timestamp, ThresholdKeyExpired()); + ThresholdKeyInfo memory info = _getThresholdInfo(tssIndex); + require(eagerOr(info.expirationTime == 0, info.expirationTime > block.timestamp), ThresholdKeyExpired()); // Calculate the challenge value bytes32 vaaHash = encodedVaa.calcVaaDoubleHashCd(offset); - (uint256 px, bool parity) = _decodePubkey(pubkey); + (uint256 px, uint8 parity) = _decodePubkey(info.pubkey); uint256 e = uint256(keccak256(abi.encodePacked(px, parity, vaaHash, r))); // Verify the recovered address matches the threshold signature r @@ -62,7 +64,7 @@ contract ThresholdVerification is ThresholdVerificationState { // NOTE: This is non-zero because for all k = px * s, Q > k % Q // Therefore, Q - k % Q is always positive bytes32(Q - mulmod(px, s, Q)), - parity ? 28 : 27, + parity, // NOTE: This is checked non-zero in _decodeThresholdKeyUpdatePayload bytes32(px), bytes32(mulmod(px, e, Q)) @@ -86,17 +88,6 @@ contract ThresholdVerification is ThresholdVerificationState { return encodedVaa.decodeVaaBodyCd(payloadOffset); } - function _decodeThresholdSignatureCdUnchecked( - bytes calldata encodedVaa, - uint offset - ) internal pure returns (address r, uint256 s, uint nextOffset) { - unchecked { - (r, offset) = encodedVaa.asAddressCdUnchecked(offset); - (s, offset) = encodedVaa.asUint256CdUnchecked(offset); - return (r, s, offset); - } - } - function _decodeThresholdKeyUpdatePayload(bytes calldata payload, uint256 shardCount) internal pure returns ( uint32 newTSSIndex, uint256 newThresholdPubkey, @@ -117,6 +108,10 @@ contract ThresholdVerification is ThresholdVerificationState { (newTSSIndex, offset) = payload.asUint32MemUnchecked(offset); (newThresholdPubkey, offset) = payload.asUint256MemUnchecked(offset); (expirationDelaySeconds, offset) = payload.asUint32MemUnchecked(offset); + + // Verify the module and action + require(module == MODULE_VERIFICATION_V2, InvalidModule(module)); + require(action == ACTION_APPEND_THRESHOLD_KEY, InvalidAction(action)); // Validate the threshold key is non-zero and less than HALF_Q (uint256 px,) = _decodePubkey(newThresholdPubkey); @@ -126,26 +121,17 @@ contract ThresholdVerification is ThresholdVerificationState { // Decode shards shards = new ShardInfo[](shardCount); for (uint i = 0; i < shardCount; i++) { - (shards[i], offset) = _decodeShardInfo(payload, offset); + (shards[i].shard, offset) = payload.asBytes32CdUnchecked(offset); + (shards[i].id, offset) = payload.asBytes32CdUnchecked(offset); } // Validate the length of the payload payload.length.checkLength(offset); - - // Verify the module and action - require(module == MODULE_VERIFICATION_V2, InvalidModule(module)); - require(action == ACTION_APPEND_THRESHOLD_KEY, InvalidAction(action)); } } - function _decodeShardInfo(bytes calldata data, uint256 offset) internal pure returns (ShardInfo memory shardInfo, uint256 nextOffset) { - (shardInfo.shard, offset) = data.asBytes32CdUnchecked(offset); - (shardInfo.id, offset) = data.asBytes32CdUnchecked(offset); - return (shardInfo, offset); - } - - function _decodePubkey(uint256 pubkey) internal pure returns (uint256 px, bool parity) { - parity = (pubkey & 1) != 0; + function _decodePubkey(uint256 pubkey) internal pure returns (uint256 px, uint8 parity) { + parity = uint8((pubkey & 1) + VaaLib.SIGNATURE_RECOVERY_MAGIC); px = pubkey >> 1; } } diff --git a/src/evm/ThresholdVerificationState.sol b/src/evm/ThresholdVerificationState.sol index 1b68a80..49ca691 100644 --- a/src/evm/ThresholdVerificationState.sol +++ b/src/evm/ThresholdVerificationState.sol @@ -13,137 +13,92 @@ contract ThresholdVerificationState { bytes32 id; } - uint32 private _thresholdDataInitialIndex; - - // Threshold data is stored in a single array with stride 2: - // pubkey (32 bytes) - // expiration time (4 bytes) - // shard base (5 bytes) - // shard count (1 byte) - uint256[] private _thresholdData; + struct ThresholdKeyInfo { + uint256 pubkey; + uint32 expirationTime; + uint8 shardCount; + uint40 shardBase; + uint32 guardianSetIndex; + } - // Shard data is stored as a single array with stride 2, grouped by guardian set - bytes32[] private _shardData; + ThresholdKeyInfo[] private _thresholdKeyData; + ShardInfo[] private _shardData; // Get the current threshold signature info - function _getCurrentThresholdInfo() internal view returns (uint256 pubkey, uint32 index) { + // NOTE: This will panic if the threshold data is empty + function _getCurrentThresholdInfo() internal view returns (ThresholdKeyInfo memory info, uint32 index) { unchecked { - uint256 length = _thresholdData.length; - pubkey = _thresholdData[length - 2]; - index = uint32((length >> 1) + _thresholdDataInitialIndex); + index = uint32(_thresholdKeyData.length - 1); + info = _thresholdKeyData[index]; } } - function _getThresholdInfo(uint32 index) internal view returns (uint256 pubkey, uint32 expirationTime) { + // NOTE: This will panic if the guardian set index is out of bounds + function _getThresholdInfo(uint32 thresholdKeyIndex) internal view returns (ThresholdKeyInfo memory info) { unchecked { - // NOTE: The threshold data index is relative to the initial index - uint256 offset = (index - _thresholdDataInitialIndex) << 1; - require(offset < _thresholdData.length, InvalidThresholdKeyIndex()); - pubkey = _thresholdData[offset]; - expirationTime = _thresholdDataExpirationTime(_thresholdData[offset + 1]); + info = _thresholdKeyData[thresholdKeyIndex]; } } function _appendThresholdKey( uint32 currentGuardianSetIndex, - uint32 newTSSIndex, + uint32 thresholdKeyIndex, uint256 pubkey, uint32 expirationDelaySeconds, ShardInfo[] memory shards ) internal { unchecked { - // Get the current threshold info and verify the new index is sequential - // NOTE: We can't use _getCurrentThresholdInfo() directly here because - // _thresholdData will be empty on the first append - uint32 index; - if (_thresholdData.length > 0) { - // If there is threshold data, the new index must be sequential - (, index) = _getCurrentThresholdInfo(); - require(newTSSIndex == index + 1, InvalidThresholdKeyIndex()); - - // Verify we have a matching guardian set - require(currentGuardianSetIndex >= newTSSIndex, InvalidThresholdKeyIndex()); - } else { - // If there is no threshold data, the initial index must be the new index - require(newTSSIndex == currentGuardianSetIndex, InvalidThresholdKeyIndex()); - index = currentGuardianSetIndex; - _thresholdDataInitialIndex = currentGuardianSetIndex; - } + // Verify the new index is sequential + require(thresholdKeyIndex == _thresholdKeyData.length, InvalidThresholdKeyIndex()); - // Store the expiration time and current threshold address in past threshold info - uint32 expirationTime = uint32(block.timestamp) + expirationDelaySeconds; - _setThresholdDataExpirationTime(index, expirationTime); + // If there is a previous threshold key that is now expired, store the expiration time + if (thresholdKeyIndex > 0) { + uint32 expirationTime = uint32(block.timestamp) + expirationDelaySeconds; + _thresholdKeyData[thresholdKeyIndex - 1].expirationTime = expirationTime; + } // Store the new threshold info - _thresholdData.push(pubkey); - _thresholdData.push(_createThresholdData(uint8(shards.length), uint40(_shardData.length))); + _thresholdKeyData.push(ThresholdKeyInfo({ + pubkey: pubkey, + expirationTime: 0, + shardCount: uint8(shards.length), + shardBase: uint40(_shardData.length), + guardianSetIndex: currentGuardianSetIndex + })); // Store the shard data + // TODO: Assembly block could be used here to save gas for (uint256 i = 0; i < shards.length; i++) { - _shardData.push(shards[i].shard); - _shardData.push(shards[i].id); + _shardData.push(shards[i]); } } } - function _getShards(uint32 guardianSet) internal view returns (ShardInfo[] memory) { + // NOTE: This will panic if the guardian set index is out of bounds + function _getShards(uint32 thresholdKeyIndex) internal view returns (ShardInfo[] memory) { unchecked { - (uint8 shardCount, uint40 shardBase) = _thresholdDataShardSlice(guardianSet); + ThresholdKeyInfo memory info = _getThresholdInfo(thresholdKeyIndex); + uint8 shardCount = info.shardCount; + uint40 shardBase = info.shardBase; ShardInfo[] memory shards = new ShardInfo[](shardCount); - uint256 ptr = shardBase; for (uint256 i = 0; i < shardCount; i++) { - shards[i].shard = _shardData[ptr++]; - shards[i].id = _shardData[ptr++]; + shards[i] = _shardData[shardBase + i]; } return shards; } } - function _getShardsRaw( - uint32 guardianSet - ) internal view returns (uint shardCount, bytes32[] memory rawShards) { - ShardInfo[] memory shards = _getShards(guardianSet); - shardCount = shards.length; - assembly ("memory-safe") { - rawShards := shards - mstore(rawShards, mul(shardCount, 2)) - } - } - - function _registerGuardian(uint32 guardianSet, uint8 guardian, bytes32 id) internal { + // NOTE: This will panic if the guardian set index is out of bounds + function _registerGuardian(uint32 thresholdKeyIndex, uint8 guardianIndex, bytes32 id) internal { unchecked { - (uint8 shardCount, uint40 shardBase) = _thresholdDataShardSlice(guardianSet); - require(guardian < shardCount, InvalidGuardianIndex()); - _shardData[shardBase + (guardian << 1)] = id; - } - } - - function _createThresholdData(uint8 shardCount, uint40 shardBase) internal pure returns (uint256) { - return (shardCount << 32) | (shardBase << 40); - } + ThresholdKeyInfo memory info = _getThresholdInfo(thresholdKeyIndex); + uint8 shardCount = info.shardCount; + uint40 shardBase = info.shardBase; - function _thresholdDataExpirationTime(uint256 data) internal pure returns (uint32) { - unchecked { - return uint32(data & 0xFFFFFFFF); - } - } - - function _thresholdDataShardSlice(uint32 guardianSet) internal view returns (uint8 shardCount, uint40 shardBase) { - unchecked { - uint256 offset = guardianSet << 1; - require(offset < _thresholdData.length, InvalidThresholdKeyIndex()); - uint256 data = _thresholdData[offset + 1]; - - shardCount = uint8((data >> 32) & 0xFF); - shardBase = uint40(data >> 40); - } - } - - function _setThresholdDataExpirationTime(uint32 index, uint32 expirationTime) internal { - unchecked { - _thresholdData[index << 1] |= expirationTime; + require(guardianIndex < shardCount, InvalidGuardianIndex()); + _shardData[shardBase + guardianIndex].id = id; } } } diff --git a/src/evm/VerificationV2.sol b/src/evm/VerificationV2.sol index b029d12..b209e62 100644 --- a/src/evm/VerificationV2.sol +++ b/src/evm/VerificationV2.sol @@ -6,10 +6,11 @@ import {BytesParsing} from "wormhole-sdk/libraries/BytesParsing.sol"; import {VaaLib} from "wormhole-sdk/libraries/VaaLib.sol"; import {RawDispatcher} from "wormhole-sdk/RawDispatcher.sol"; import {CHAIN_ID_SOLANA} from "wormhole-sdk/constants/Chains.sol"; +import {GuardianSet} from "wormhole-sdk/interfaces/ICoreBridge.sol"; import {ThresholdVerification} from "./ThresholdVerification.sol"; import {MultisigVerification} from "./MultisigVerification.sol"; -import {GuardianRegistryVerification} from "./GuardianRegistryVerification.sol"; +import {EIP712Encoding} from "./EIP712Encoding.sol"; // Raw dispatch operation IDs for exec uint8 constant OP_APPEND_THRESHOLD_KEY = 0x00; @@ -29,7 +30,7 @@ uint8 constant OP_GUARDIAN_SHARDS_GET = 0x26; bytes32 constant GOVERNANCE_ADDRESS = bytes32(0x0000000000000000000000000000000000000000000000000000000000000004); contract VerificationV2 is - RawDispatcher, ThresholdVerification, MultisigVerification, GuardianRegistryVerification + RawDispatcher, ThresholdVerification, MultisigVerification, EIP712Encoding { using BytesParsing for bytes; using VaaLib for bytes; @@ -42,10 +43,11 @@ contract VerificationV2 is error GuardianSetIsNotCurrent(); - // FIXME: The initial TSS index should be the latest guardian set index, not passed in! + error RegistrationMessageExpired(); + error GuardianSignatureVerificationFailed(); + constructor(address coreV1, uint256 initGuardianSetIndex, uint256 pullLimit) MultisigVerification(coreV1, initGuardianSetIndex, pullLimit) - GuardianRegistryVerification() {} function _verifyVaa(bytes calldata data) private view { @@ -72,7 +74,7 @@ contract VerificationV2 is if (version == 2) { (timestamp, nonce, emitterChainId, emitterAddress, sequence, consistencyLevel, payload) = _verifyAndDecodeThresholdVaa(data); } else if (version == 1) { - (timestamp, nonce, emitterChainId, emitterAddress, sequence, consistencyLevel, payload,,) = _verifyAndDecodeMultisigVaa(data); + (timestamp, nonce, emitterChainId, emitterAddress, sequence, consistencyLevel, payload) = _verifyAndDecodeMultisigVaa(data); } else { revert VaaLib.InvalidVersion(version); } @@ -92,8 +94,6 @@ contract VerificationV2 is (encodedVaa, offset) = data.sliceUint16PrefixedCdUnchecked(offset); // Decode and verify the VAA - // TODO: Might be better to have a custom function to do the decoding here - // so we don't drop so many fields ( , , @@ -101,14 +101,15 @@ contract VerificationV2 is bytes32 emitterAddress, , , - bytes calldata payload, - uint32 guardianSetIndex, - address[] memory guardians + bytes calldata payload ) = _verifyAndDecodeMultisigVaa(encodedVaa); // Verify the emitter if (emitterChainId != CHAIN_ID_SOLANA) revert InvalidGovernanceChainId(); if (emitterAddress != GOVERNANCE_ADDRESS) revert InvalidGovernanceAddress(); + + // Get the guardian set + (uint32 guardianSetIndex, address[] memory guardians) = _getCurrentGuardianSetInfo(); // Decode the payload ( @@ -127,30 +128,35 @@ contract VerificationV2 is _pullGuardianSets(limit); } else if (op == OP_REGISTER_GUARDIAN) { // Decode the payload - uint32 guardianSet; + uint32 thresholdKeyIndex; uint32 expirationTime; bytes32 guardianId; uint8 guardian; bytes32 r; bytes32 s; uint8 v; - (guardianSet, offset) = data.asUint32CdUnchecked(offset); + (thresholdKeyIndex, offset) = data.asUint32CdUnchecked(offset); (expirationTime, offset) = data.asUint32CdUnchecked(offset); (guardianId, offset) = data.asBytes32CdUnchecked(offset); (guardian, r, s, v, offset) = data.decodeGuardianSignatureCdUnchecked(offset); - // We only allow registrations for the current guardian set - (uint32 currentSetIndex, address[] memory guardianAddrs) = _getCurrentGuardianSetInfo(); - require(guardianSet == currentSetIndex, GuardianSetIsNotCurrent()); - - _verifyRegisterGuardian( - guardianAddrs, - guardianSet, - expirationTime, - guardianId, - guardian, - r, s, v - ); + // We only allow registrations for the current threshold key + (ThresholdKeyInfo memory info, uint32 currentThresholdKeyIndex) = _getCurrentThresholdInfo(); + require(thresholdKeyIndex == currentThresholdKeyIndex, GuardianSetIsNotCurrent()); + + // Verify the message is not expired + require(expirationTime > block.timestamp, RegistrationMessageExpired()); + + // Get the guardian set for the threshold key + uint32 guardianSetIndex = info.guardianSetIndex; + (, address[] memory guardianAddrs) = _getGuardianSetInfo(guardianSetIndex); + // TODO: Verify the guardian set is still valid? What about for the verification path? + // We can't afford to check it there, so I'm skipping it here for now too + + // Verify the signature + bytes32 digest = getRegisterGuardianDigest(guardianSetIndex, expirationTime, guardianId); + address signatory = ecrecover(digest, v, r, s); + require(signatory == guardianAddrs[guardian], GuardianSignatureVerificationFailed()); - _registerGuardian(guardianSet, guardian, guardianId); + _registerGuardian(guardianSetIndex, guardian, guardianId); } else { revert InvalidOperation(op); } @@ -187,13 +193,15 @@ contract VerificationV2 is result = abi.encodePacked( result, - timestamp, - nonce, - emitterChainId, - emitterAddress, - sequence, - consistencyLevel, - payload + abi.encode( + timestamp, + nonce, + emitterChainId, + emitterAddress, + sequence, + consistencyLevel, + payload + ) ); } else if (op == OP_VERIFY_VAA) { // Read the VAA @@ -203,38 +211,36 @@ contract VerificationV2 is // Verify the VAA _verifyVaa(encodedVaa); } else if (op == OP_THRESHOLD_GET_CURRENT) { - (uint256 thresholdAddr, uint32 thresholdIndex) = _getCurrentThresholdInfo(); + (ThresholdKeyInfo memory info, uint32 index) = _getCurrentThresholdInfo(); - result = abi.encodePacked(result, thresholdAddr, thresholdIndex); + result = abi.encodePacked(result, abi.encode(info.pubkey, index)); } else if (op == OP_THRESHOLD_GET) { uint32 index; (index, offset) = data.asUint32CdUnchecked(offset); - (uint256 thresholdAddr, uint32 expirationTime) = _getThresholdInfo(index); + ThresholdKeyInfo memory info = _getThresholdInfo(index); - result = abi.encodePacked(result, thresholdAddr, expirationTime); + result = abi.encodePacked(result, abi.encode(info.pubkey, info.expirationTime)); } else if (op == OP_GUARDIAN_SET_GET_CURRENT) { (uint32 guardianSet, address[] memory guardianSetAddrs) = _getCurrentGuardianSetInfo(); - uint8 guardianCount = uint8(guardianSetAddrs.length); - result = abi.encodePacked(result, guardianCount, guardianSetAddrs, guardianSet); + result = abi.encodePacked(result, abi.encode(guardianSetAddrs, guardianSet)); } else if (op == OP_GUARDIAN_SET_GET) { uint32 index; (index, offset) = data.asUint32CdUnchecked(offset); (uint32 expirationTime, address[] memory guardianSetAddrs) = _getGuardianSetInfo(index); - uint8 guardianCount = uint8(guardianSetAddrs.length); - result = abi.encodePacked(result, guardianCount, guardianSetAddrs, expirationTime); + result = abi.encodePacked(result, abi.encode(guardianSetAddrs, expirationTime)); } else if (op == OP_GUARDIAN_SHARDS_GET) { uint32 guardianSet; uint8 guardian; (guardianSet, offset) = data.asUint32CdUnchecked(offset); (guardian, offset) = data.asUint8CdUnchecked(offset); - (uint shardCount, bytes32[] memory shards) = _getShardsRaw(guardianSet); + ShardInfo[] memory shards = _getShards(guardianSet); - result = abi.encodePacked(result, uint8(shardCount), shards); + result = abi.encodePacked(result, abi.encode(shards)); } else { revert InvalidOperation(op); } @@ -246,11 +252,11 @@ contract VerificationV2 is return result; } - function verifyVaa(bytes calldata encodedVaa) internal view { + function verifyVaa(bytes calldata encodedVaa) public view { _verifyVaa(encodedVaa); } - function verifyAndDecodeVaa(bytes calldata encodedVaa) internal view returns ( + function verifyAndDecodeVaa(bytes calldata encodedVaa) public view returns ( uint32 timestamp, uint32 nonce, uint16 emitterChainId, @@ -261,4 +267,4 @@ contract VerificationV2 is ) { return _verifyAndDecodeVaa(encodedVaa); } -} \ No newline at end of file +} From fb64344d7008b0fc56f14531274e9917f69c4fab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Claudio=20Nale?= Date: Tue, 3 Jun 2025 13:01:15 -0300 Subject: [PATCH 47/53] evm: removes unused code --- src/evm/VerificationV2.sol | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/evm/VerificationV2.sol b/src/evm/VerificationV2.sol index 6ee2e84..562a2b7 100644 --- a/src/evm/VerificationV2.sol +++ b/src/evm/VerificationV2.sol @@ -236,12 +236,10 @@ contract VerificationV2 is result = abi.encodePacked(result, abi.encode(guardianSetAddrs, expirationTime)); } else if (op == OP_GUARDIAN_SHARDS_GET) { uint32 guardianSet; - uint8 guardian; (guardianSet, offset) = data.asUint32CdUnchecked(offset); - (guardian, offset) = data.asUint8CdUnchecked(offset); - + ShardInfo[] memory shards = _getShards(guardianSet); - + result = abi.encodePacked(result, abi.encode(shards)); } else { revert InvalidOperation(op); From 5fa5594a42d0574c62f6b8ca9af92dab9790cef8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Claudio=20Nale?= Date: Tue, 3 Jun 2025 13:23:13 -0300 Subject: [PATCH 48/53] misc: removes trailing whitespace --- src/evm/VerificationV2.sol | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/evm/VerificationV2.sol b/src/evm/VerificationV2.sol index 562a2b7..5180318 100644 --- a/src/evm/VerificationV2.sol +++ b/src/evm/VerificationV2.sol @@ -29,7 +29,7 @@ uint8 constant OP_GUARDIAN_SHARDS_GET = 0x26; // Emitter address for the VerificationV2 contract bytes32 constant GOVERNANCE_ADDRESS = bytes32(0x0000000000000000000000000000000000000000000000000000000000000004); -contract VerificationV2 is +contract VerificationV2 is RawDispatcher, ThresholdVerification, MultisigVerification, EIP712Encoding { using BytesParsing for bytes; @@ -87,7 +87,7 @@ contract VerificationV2 is while (offset < data.length) { uint8 op; (op, offset) = data.asUint8CdUnchecked(offset); - + if (op == OP_APPEND_THRESHOLD_KEY) { // Read the VAA bytes calldata encodedVaa; @@ -110,7 +110,7 @@ contract VerificationV2 is // Get the guardian set (uint32 guardianSetIndex, address[] memory guardians) = _getCurrentGuardianSetInfo(); - + // Decode the payload ( uint32 newTSSIndex, @@ -118,7 +118,7 @@ contract VerificationV2 is uint32 expirationDelaySeconds, ShardInfo[] memory shards ) = _decodeThresholdKeyUpdatePayload(payload, guardians.length); - + // Append the threshold key _appendThresholdKey(guardianSetIndex, newTSSIndex, newThresholdAddr, expirationDelaySeconds, shards); } else if (op == OP_PULL_GUARDIAN_SETS) { @@ -137,7 +137,7 @@ contract VerificationV2 is (expirationTime, offset) = data.asUint32CdUnchecked(offset); (guardianId, offset) = data.asBytes32CdUnchecked(offset); (guardian, r, s, v, offset) = data.decodeGuardianSignatureCdUnchecked(offset); - + // We only allow registrations for the current threshold key (ThresholdKeyInfo memory info, uint32 currentThresholdKeyIndex) = _getCurrentThresholdInfo(); require(thresholdKeyIndex == currentThresholdKeyIndex, GuardianSetIsNotCurrent()); @@ -157,7 +157,7 @@ contract VerificationV2 is bytes32 digest = getRegisterGuardianDigest(guardianSetIndex, expirationTime, guardianId); address signatory = ecrecover(digest, v, r, s); require(signatory == guardianAddrs[guardian], GuardianSignatureVerificationFailed()); - + _registerGuardian(guardianSetIndex, guardian, guardianId); } else { revert InvalidOperation(op); @@ -176,7 +176,7 @@ contract VerificationV2 is while (offset < data.length) { uint8 op; (op, offset) = data.asUint8CdUnchecked(offset); - + if (op == OP_VERIFY_AND_DECODE_VAA) { // Read the VAA bytes calldata encodedVaa; @@ -219,9 +219,9 @@ contract VerificationV2 is } else if (op == OP_THRESHOLD_GET) { uint32 index; (index, offset) = data.asUint32CdUnchecked(offset); - + ThresholdKeyInfo memory info = _getThresholdInfo(index); - + result = abi.encodePacked(result, abi.encode(info.pubkey, info.expirationTime)); } else if (op == OP_GUARDIAN_SET_GET_CURRENT) { (uint32 guardianSet, address[] memory guardianSetAddrs) = _getCurrentGuardianSetInfo(); @@ -230,9 +230,9 @@ contract VerificationV2 is } else if (op == OP_GUARDIAN_SET_GET) { uint32 index; (index, offset) = data.asUint32CdUnchecked(offset); - + (uint32 expirationTime, address[] memory guardianSetAddrs) = _getGuardianSetInfo(index); - + result = abi.encodePacked(result, abi.encode(guardianSetAddrs, expirationTime)); } else if (op == OP_GUARDIAN_SHARDS_GET) { uint32 guardianSet; From b7877706a48c780fa189755bc4bfadae132256e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Claudio=20Nale?= Date: Tue, 3 Jun 2025 14:03:05 -0300 Subject: [PATCH 49/53] misc: adds solana recipes to makefile --- Makefile | 42 ++++++++++++++++++++++++++++++----------- src/solana/package.json | 1 + 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index c079bdd..5d47817 100644 --- a/Makefile +++ b/Makefile @@ -2,29 +2,49 @@ TEST_RPC = https://ethereum-rpc.publicnode.com tolib = $(addprefix lib/,$(firstword $(subst @, ,$(notdir $(1))))) -define install_lib -dependencies: $(call tolib,$(1)) +define install_lib_evm +dependencies-evm: $(call tolib,$(1)) $(call tolib,$(1)): - forge install $(1) --no-git --no-commit + forge install $(1) --no-git endef .DEFAULT_GOAL = build -.PHONY: build test clean dependencies +.PHONY: build* test* clean* dependencies* -build: dependencies - forge build +build: build-evm build-solana build-solana-ts -test: dependencies - forge test --fork-url $(TEST_RPC) -vvvv -#--match-test InitiateFullFuzz +test: test-evm test-solana + +clean: clean-evm clean-solana LIB_DEPS = foundry-rs/forge-std LIB_DEPS += wormhole-foundation/wormhole-solidity-sdk@a7c8786 # dynamically generate install rule for each lib dependency and add to depdenencies -$(foreach dep,$(LIB_DEPS), $(eval $(call install_lib,$(dep)))) +$(foreach dep,$(LIB_DEPS), $(eval $(call install_lib_evm,$(dep)))) -clean: + +build-evm: dependencies-evm + forge build + +test-evm: dependencies-evm + forge test --fork-url $(TEST_RPC) -vvvv +#--match-test InitiateFullFuzz + +clean-evm: forge clean rm -rf lib + + +build-solana: + cd src/solana; anchor build + +build-solana-ts: + npm run build --prefix src/solana + +test-solana: + cd src/solana; anchor test + +clean-solana: + cd src/solana; anchor clean diff --git a/src/solana/package.json b/src/solana/package.json index e44a126..0b01730 100644 --- a/src/solana/package.json +++ b/src/solana/package.json @@ -1,6 +1,7 @@ { "license": "ISC", "type": "module", + "private": true, "scripts": { "build": "tsc --build ./tsconfig.json", "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", From 88c7ac079233a97c62fdafc2caa1f285b410acd9 Mon Sep 17 00:00:00 2001 From: Joshua Averett Date: Tue, 3 Jun 2025 13:05:19 -0700 Subject: [PATCH 50/53] Minor improvement in V2 verification path --- src/evm/ThresholdVerification.sol | 46 ++++++++++++++++--------------- src/evm/VerificationV2.sol | 7 +++-- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/src/evm/ThresholdVerification.sol b/src/evm/ThresholdVerification.sol index 1f656fb..ab4dfcb 100644 --- a/src/evm/ThresholdVerification.sol +++ b/src/evm/ThresholdVerification.sol @@ -26,55 +26,57 @@ contract ThresholdVerification is ThresholdVerificationState { error ThresholdKeyExpired(); error ThresholdSignatureVerificationFailed(); - error InvalidModule(bytes32 module); - error InvalidAction(uint8 action); + error InvalidModule(); + error InvalidAction(); - // Verify a threshold signature VAA + // Verify a threshold signature V2 VAA + // NOTE: This function does not validate the VAA version is V2! function _verifyThresholdVaaHeader(bytes calldata encodedVaa) internal view returns (uint envelopeOffset) { unchecked { // Decode the VAA header - uint offset = 0; - uint8 version; + uint offset = 1; uint32 tssIndex; address r; uint256 s; - (version, offset) = encodedVaa.asUint8CdUnchecked(offset); (tssIndex, offset) = encodedVaa.asUint32CdUnchecked(offset); (r, offset) = encodedVaa.asAddressCdUnchecked(offset); (s, offset) = encodedVaa.asUint256CdUnchecked(offset); - // Validate the VAA version and threshold signature is in range - // NOTE: s < Q prevents signature malleability - // NOTE: Non-zero r prevents confusion with ecrecover failure - // NOTE: Non-zero check on s not needed, see the first argument of ecrecover - require(version == 2, VaaLib.InvalidVersion(version)); - require(eagerAnd(s < Q, r != address(0)), ThresholdSignatureVerificationFailed()); - // Load threshold key info and validate expiration time ThresholdKeyInfo memory info = _getThresholdInfo(tssIndex); - require(eagerOr(info.expirationTime == 0, info.expirationTime > block.timestamp), ThresholdKeyExpired()); // Calculate the challenge value bytes32 vaaHash = encodedVaa.calcVaaDoubleHashCd(offset); (uint256 px, uint8 parity) = _decodePubkey(info.pubkey); uint256 e = uint256(keccak256(abi.encodePacked(px, parity, vaaHash, r))); - // Verify the recovered address matches the threshold signature r + // Calculate the recovered address address recovered = ecrecover( // NOTE: This is non-zero because for all k = px * s, Q > k % Q // Therefore, Q - k % Q is always positive bytes32(Q - mulmod(px, s, Q)), parity, - // NOTE: This is checked non-zero in _decodeThresholdKeyUpdatePayload + // NOTE: This is range checked in _decodeThresholdKeyUpdatePayload bytes32(px), bytes32(mulmod(px, e, Q)) ); - require(r == recovered, ThresholdSignatureVerificationFailed()); + + // Verify that none of the preconditions were violated + // NOTE: s < Q prevents signature malleability + // NOTE: Non-zero r prevents confusion with ecrecover failure + // NOTE: Non-zero check on s not needed, see the first argument of ecrecover + bool validSignature = eagerAnd(r != address(0), s < Q); + bool validExpiration = eagerOr(info.expirationTime == 0, info.expirationTime > block.timestamp); + bool validRecovered = r == recovered; + + require(eagerAnd(validSignature, eagerAnd(validExpiration, validRecovered)), ThresholdSignatureVerificationFailed()); return offset; } } + // Verify and decode a threshold signature V2 VAA + // NOTE: This function does not validate the VAA version is V2! function _verifyAndDecodeThresholdVaa(bytes calldata encodedVaa) internal view returns ( uint32 timestamp, uint32 nonce, @@ -88,6 +90,7 @@ contract ThresholdVerification is ThresholdVerificationState { return encodedVaa.decodeVaaBodyCd(payloadOffset); } + // Decode a threshold key update payload, given the number of shards(which is the same as the number of guardians for the current guardian set) function _decodeThresholdKeyUpdatePayload(bytes calldata payload, uint256 shardCount) internal pure returns ( uint32 newTSSIndex, uint256 newThresholdPubkey, @@ -97,8 +100,8 @@ contract ThresholdVerification is ThresholdVerificationState { unchecked { // Decode the payload uint offset = 0; - uint8 action; bytes32 module; + uint8 action; // Headedr (module, offset) = payload.asBytes32MemUnchecked(offset); @@ -110,13 +113,12 @@ contract ThresholdVerification is ThresholdVerificationState { (expirationDelaySeconds, offset) = payload.asUint32MemUnchecked(offset); // Verify the module and action - require(module == MODULE_VERIFICATION_V2, InvalidModule(module)); - require(action == ACTION_APPEND_THRESHOLD_KEY, InvalidAction(action)); + require(module == MODULE_VERIFICATION_V2, InvalidModule()); + require(action == ACTION_APPEND_THRESHOLD_KEY, InvalidAction()); // Validate the threshold key is non-zero and less than HALF_Q (uint256 px,) = _decodePubkey(newThresholdPubkey); - require(px != 0, InvalidThresholdKeyAddress()); - require(px <= HALF_Q, InvalidThresholdKeyAddress()); + require(eagerAnd(px != 0, px <= HALF_Q), InvalidThresholdKeyAddress()); // Decode shards shards = new ShardInfo[](shardCount); diff --git a/src/evm/VerificationV2.sol b/src/evm/VerificationV2.sol index 6ee2e84..42b50df 100644 --- a/src/evm/VerificationV2.sol +++ b/src/evm/VerificationV2.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.0; +import {eagerAnd} from "wormhole-sdk/Utils.sol"; import {BytesParsing} from "wormhole-sdk/libraries/BytesParsing.sol"; import {VaaLib} from "wormhole-sdk/libraries/VaaLib.sol"; import {RawDispatcher} from "wormhole-sdk/RawDispatcher.sol"; @@ -38,7 +39,7 @@ contract VerificationV2 is error InvalidValue(); error InvalidOperation(uint8 op); - error InvalidGovernanceChainId(); + error InvalidGovernanceChain(); error InvalidGovernanceAddress(); error GuardianSetIsNotCurrent(); @@ -105,8 +106,8 @@ contract VerificationV2 is ) = _verifyAndDecodeMultisigVaa(encodedVaa); // Verify the emitter - if (emitterChainId != CHAIN_ID_SOLANA) revert InvalidGovernanceChainId(); - if (emitterAddress != GOVERNANCE_ADDRESS) revert InvalidGovernanceAddress(); + require(emitterChainId == CHAIN_ID_SOLANA, InvalidGovernanceChain()); + require(emitterAddress == GOVERNANCE_ADDRESS, InvalidGovernanceAddress()); // Get the guardian set (uint32 guardianSetIndex, address[] memory guardians) = _getCurrentGuardianSetInfo(); From a0ddf13508fef95dc0e54689d3a22bb87c3cfa75 Mon Sep 17 00:00:00 2001 From: Joshua Averett Date: Wed, 4 Jun 2025 14:48:03 -0700 Subject: [PATCH 51/53] Domain info and a bit more cleaning --- src/evm/EIP712Encoding.sol | 56 ++++++++++++++++++++++---- src/evm/MultisigVerification.sol | 17 ++++---- src/evm/MultisigVerificationState.sol | 4 +- src/evm/ThresholdVerification.sol | 14 +++---- src/evm/ThresholdVerificationState.sol | 10 ++--- src/evm/VerificationV2.sol | 14 +++---- 6 files changed, 78 insertions(+), 37 deletions(-) diff --git a/src/evm/EIP712Encoding.sol b/src/evm/EIP712Encoding.sol index d291fd2..e6df602 100644 --- a/src/evm/EIP712Encoding.sol +++ b/src/evm/EIP712Encoding.sol @@ -6,23 +6,63 @@ import {eagerOr} from "wormhole-sdk/Utils.sol"; import {BytesParsing} from "wormhole-sdk/libraries/BytesParsing.sol"; import {VaaLib} from "wormhole-sdk/libraries/VaaLib.sol"; -contract EIP712Encoding { - bytes32 constant EIP712_DOMAIN_TYPE_HASH = keccak256( - "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" +bytes32 constant REGISTER_TYPE_HASH = keccak256( + "GuardianRegister(uint32 guardianSet,uint32 expirationTime,bytes32 id)" +); + +interface IERC5267 { + function eip712Domain() external view returns ( + bytes1 fields, + string memory name, + string memory version, + uint256 chainId, + address verifyingContract, + bytes32 salt, + uint256[] memory extensions ); - bytes32 constant EIP712_NAME_HASH = keccak256("Wormhole VerificationV2"); - bytes32 constant EIP712_VERSION_HASH = keccak256("1"); +} - bytes32 constant REGISTER_TYPE_HASH = keccak256( - "GuardianRegister(uint32 guardianSet,uint32 expirationTime,bytes32 id)" +contract EIP712Encoding is IERC5267 { + bytes32 constant EIP712_DOMAIN_TYPE_HASH = keccak256( + "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" ); + + string constant EIP712_NAME = "Wormhole VerificationV2"; + string constant EIP712_VERSION = "1"; + + bytes32 constant EIP712_NAME_HASH = keccak256(bytes(EIP712_NAME)); + bytes32 constant EIP712_VERSION_HASH = keccak256(bytes(EIP712_VERSION)); - bytes32 private _domainSeparator; + bytes32 private immutable _domainSeparator; constructor () { _domainSeparator = getDomainSeparator(block.chainid, address(this)); } + function eip712Domain() external view returns ( + bytes1 fields, + string memory name, + string memory version, + uint256 chainId, + address verifyingContract, + bytes32 salt, + uint256[] memory extensions + ) { + return ( + bytes1(0x0F), + EIP712_NAME, + EIP712_VERSION, + block.chainid, + address(this), + bytes32(0), + new uint256[](0) + ); + } + + function DOMAIN_SEPARATOR() external view returns (bytes32) { + return _domainSeparator; + } + function getDomainSeparator( uint256 eth_chain_id, address verifyingContract ) internal pure returns (bytes32) { diff --git a/src/evm/MultisigVerification.sol b/src/evm/MultisigVerification.sol index 3606921..0c2fe62 100644 --- a/src/evm/MultisigVerification.sol +++ b/src/evm/MultisigVerification.sol @@ -2,7 +2,10 @@ pragma solidity ^0.8.0; +import "forge-std/console.sol"; + import {eagerOr} from "wormhole-sdk/Utils.sol"; +import {ICoreBridge} from "wormhole-sdk/interfaces/ICoreBridge.sol"; import {BytesParsing} from "wormhole-sdk/libraries/BytesParsing.sol"; import {VaaLib} from "wormhole-sdk/libraries/VaaLib.sol"; import {CoreBridgeLib} from "wormhole-sdk/libraries/CoreBridge.sol"; @@ -20,28 +23,25 @@ contract MultisigVerification is MultisigVerificationState { error GuardianSetExpired(); constructor( - address coreBridge, + ICoreBridge coreBridge, uint256 initGuardianSetIndex, uint256 pullLimit ) MultisigVerificationState(coreBridge, initGuardianSetIndex, pullLimit) {} + // Verify a multisig VAA + // NOTE: This function does not validate the VAA version is V1! function _verifyMultisigVaaHeader(bytes calldata encodedVaa) internal view returns (uint envelopeOffset) { unchecked { - uint offset = 0; - uint8 version; + uint offset = 1; uint32 guardianSetIndex; uint8 signatureCount; - (version, offset) = encodedVaa.asUint8CdUnchecked(offset); (guardianSetIndex, offset) = encodedVaa.asUint32CdUnchecked(offset); (signatureCount, offset) = encodedVaa.asUint8CdUnchecked(offset); - // Validate the version - require(version == 1, VaaLib.InvalidVersion(version)); - // Get the guardian set and validate it's not expired (uint32 expirationTime, address[] memory guardians) = _getGuardianSetInfo(guardianSetIndex); - require(expirationTime > block.timestamp, GuardianSetExpired()); + require(eagerOr(expirationTime == 0, expirationTime > block.timestamp), GuardianSetExpired()); // Get the number of signatures // NOTE: Optimization puts guardianCount on stack thus avoids mloads @@ -98,6 +98,7 @@ contract MultisigVerification is MultisigVerificationState { } // Verify a guardian set VAA + // NOTE: This function does not validate the VAA version is V1! function _verifyAndDecodeMultisigVaa(bytes calldata encodedVaa) internal view returns ( uint32 timestamp, uint32 nonce, diff --git a/src/evm/MultisigVerificationState.sol b/src/evm/MultisigVerificationState.sol index abadeab..106c7e0 100644 --- a/src/evm/MultisigVerificationState.sol +++ b/src/evm/MultisigVerificationState.sol @@ -20,11 +20,11 @@ contract MultisigVerificationState is ExtStore { uint32[] private _guardianSetExpirationTime; constructor( - address coreBridge, + ICoreBridge coreBridge, uint256 initGuardianSetIndex, uint256 pullLimit ) { - _coreBridge = ICoreBridge(coreBridge); + _coreBridge = coreBridge; require(initGuardianSetIndex <= _coreBridge.getCurrentGuardianSetIndex()); // All previous guardian sets will have expiration timestamp 0 diff --git a/src/evm/ThresholdVerification.sol b/src/evm/ThresholdVerification.sol index ab4dfcb..a577386 100644 --- a/src/evm/ThresholdVerification.sol +++ b/src/evm/ThresholdVerification.sol @@ -7,19 +7,19 @@ import {GuardianSet} from "wormhole-sdk/interfaces/ICoreBridge.sol"; import {VaaLib} from "wormhole-sdk/libraries/VaaLib.sol"; import {eagerAnd, eagerOr} from "wormhole-sdk/Utils.sol"; -import {ThresholdVerificationState} from "./ThresholdVerificationState.sol"; +import {ThresholdVerificationState, ShardInfo} from "./ThresholdVerificationState.sol"; + +// Module ID for the VerificationV2 contract, ASCII "TSS" +bytes32 constant MODULE_VERIFICATION_V2 = bytes32(0x0000000000000000000000000000000000000000000000000000000000545353); + +// Action ID for appending a threshold key +uint8 constant ACTION_APPEND_THRESHOLD_KEY = 0x01; contract ThresholdVerification is ThresholdVerificationState { using BytesParsing for bytes; using VaaLib for bytes; using {BytesParsing.checkLength} for uint; - // Module ID for the VerificationV2 contract, ASCII "TSS" - bytes32 constant MODULE_VERIFICATION_V2 = bytes32(0x0000000000000000000000000000000000000000000000000000000000545353); - - // Action ID for appending a threshold key - uint8 constant ACTION_APPEND_THRESHOLD_KEY = 0x01; - // Curve order for secp256k1 uint256 constant internal Q = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141; uint256 constant internal HALF_Q = Q >> 1; diff --git a/src/evm/ThresholdVerificationState.sol b/src/evm/ThresholdVerificationState.sol index 49ca691..3a8b443 100644 --- a/src/evm/ThresholdVerificationState.sol +++ b/src/evm/ThresholdVerificationState.sol @@ -2,17 +2,17 @@ pragma solidity ^0.8.0; +struct ShardInfo { + bytes32 shard; + bytes32 id; +} + contract ThresholdVerificationState { error InvalidThresholdKeyIndex(); error InvalidThresholdKeyAddress(); error InvalidGuardianIndex(); error GuardianSetsNotComplete(); - struct ShardInfo { - bytes32 shard; - bytes32 id; - } - struct ThresholdKeyInfo { uint256 pubkey; uint32 expirationTime; diff --git a/src/evm/VerificationV2.sol b/src/evm/VerificationV2.sol index 5e58229..3c8ed59 100644 --- a/src/evm/VerificationV2.sol +++ b/src/evm/VerificationV2.sol @@ -7,9 +7,9 @@ import {BytesParsing} from "wormhole-sdk/libraries/BytesParsing.sol"; import {VaaLib} from "wormhole-sdk/libraries/VaaLib.sol"; import {RawDispatcher} from "wormhole-sdk/RawDispatcher.sol"; import {CHAIN_ID_SOLANA} from "wormhole-sdk/constants/Chains.sol"; -import {GuardianSet} from "wormhole-sdk/interfaces/ICoreBridge.sol"; +import {ICoreBridge, GuardianSet} from "wormhole-sdk/interfaces/ICoreBridge.sol"; -import {ThresholdVerification} from "./ThresholdVerification.sol"; +import {ThresholdVerification, ShardInfo} from "./ThresholdVerification.sol"; import {MultisigVerification} from "./MultisigVerification.sol"; import {EIP712Encoding} from "./EIP712Encoding.sol"; @@ -47,7 +47,7 @@ contract VerificationV2 is error RegistrationMessageExpired(); error GuardianSignatureVerificationFailed(); - constructor(address coreV1, uint256 initGuardianSetIndex, uint256 pullLimit) + constructor(ICoreBridge coreV1, uint256 initGuardianSetIndex, uint256 pullLimit) MultisigVerification(coreV1, initGuardianSetIndex, pullLimit) {} @@ -132,12 +132,12 @@ contract VerificationV2 is uint32 thresholdKeyIndex; uint32 expirationTime; bytes32 guardianId; - uint8 guardian; bytes32 r; bytes32 s; uint8 v; + uint8 guardianIndex; bytes32 r; bytes32 s; uint8 v; (thresholdKeyIndex, offset) = data.asUint32CdUnchecked(offset); (expirationTime, offset) = data.asUint32CdUnchecked(offset); (guardianId, offset) = data.asBytes32CdUnchecked(offset); - (guardian, r, s, v, offset) = data.decodeGuardianSignatureCdUnchecked(offset); + (guardianIndex, r, s, v, offset) = data.decodeGuardianSignatureCdUnchecked(offset); // We only allow registrations for the current threshold key (ThresholdKeyInfo memory info, uint32 currentThresholdKeyIndex) = _getCurrentThresholdInfo(); @@ -157,9 +157,9 @@ contract VerificationV2 is // verifying only canonical (low s) signatures. bytes32 digest = getRegisterGuardianDigest(guardianSetIndex, expirationTime, guardianId); address signatory = ecrecover(digest, v, r, s); - require(signatory == guardianAddrs[guardian], GuardianSignatureVerificationFailed()); + require(signatory == guardianAddrs[guardianIndex], GuardianSignatureVerificationFailed()); - _registerGuardian(guardianSetIndex, guardian, guardianId); + _registerGuardian(guardianSetIndex, guardianIndex, guardianId); } else { revert InvalidOperation(op); } From c855cd12c48c9905ea4ce79b8075ea541f005dc8 Mon Sep 17 00:00:00 2001 From: Joshua Averett Date: Wed, 4 Jun 2025 17:39:14 -0700 Subject: [PATCH 52/53] Add tests for everything besides V2 signatures --- src/evm/EIP712Encoding.sol | 17 +- src/evm/MultisigVerification.sol | 2 - src/evm/VerificationV2.sol | 2 +- test/Test.sol | 513 +++++++++++++++++++++++++++++++ 4 files changed, 520 insertions(+), 14 deletions(-) create mode 100644 test/Test.sol diff --git a/src/evm/EIP712Encoding.sol b/src/evm/EIP712Encoding.sol index e6df602..9aaf4cc 100644 --- a/src/evm/EIP712Encoding.sol +++ b/src/evm/EIP712Encoding.sol @@ -75,21 +75,16 @@ contract EIP712Encoding is IERC5267 { )); } - function getRegisterGuardianHash( - uint32 guardianSet, uint32 expirationTime, bytes32 id - ) internal pure returns (bytes32) { - return keccak256(abi.encode( + function getRegisterGuardianDigest( + uint32 thresholdKeyIndex, uint32 expirationTime, bytes32 guardianId + ) public view returns (bytes32) { + bytes32 idHash = keccak256(abi.encode( REGISTER_TYPE_HASH, - guardianSet, + thresholdKeyIndex, expirationTime, - id + guardianId )); - } - function getRegisterGuardianDigest( - uint32 guardianSet, uint32 expirationTime, bytes32 id - ) internal view returns (bytes32) { - bytes32 idHash = getRegisterGuardianHash(guardianSet, expirationTime, id); return keccak256(abi.encodePacked("\x19\x01", _domainSeparator, idHash)); } } diff --git a/src/evm/MultisigVerification.sol b/src/evm/MultisigVerification.sol index 0c2fe62..366153d 100644 --- a/src/evm/MultisigVerification.sol +++ b/src/evm/MultisigVerification.sol @@ -2,8 +2,6 @@ pragma solidity ^0.8.0; -import "forge-std/console.sol"; - import {eagerOr} from "wormhole-sdk/Utils.sol"; import {ICoreBridge} from "wormhole-sdk/interfaces/ICoreBridge.sol"; import {BytesParsing} from "wormhole-sdk/libraries/BytesParsing.sol"; diff --git a/src/evm/VerificationV2.sol b/src/evm/VerificationV2.sol index 3c8ed59..a6fb68a 100644 --- a/src/evm/VerificationV2.sol +++ b/src/evm/VerificationV2.sol @@ -155,7 +155,7 @@ contract VerificationV2 is // Verify the signature // We're not doing replay protection with the signature itself so we don't care about // verifying only canonical (low s) signatures. - bytes32 digest = getRegisterGuardianDigest(guardianSetIndex, expirationTime, guardianId); + bytes32 digest = getRegisterGuardianDigest(thresholdKeyIndex, expirationTime, guardianId); address signatory = ecrecover(digest, v, r, s); require(signatory == guardianAddrs[guardianIndex], GuardianSignatureVerificationFailed()); diff --git a/test/Test.sol b/test/Test.sol new file mode 100644 index 0000000..6d16e51 --- /dev/null +++ b/test/Test.sol @@ -0,0 +1,513 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import {Test} from "forge-std/Test.sol"; +import {console} from "forge-std/console.sol"; + +import { + VerificationV2, + ShardInfo, + OP_APPEND_THRESHOLD_KEY, + OP_PULL_GUARDIAN_SETS, + OP_REGISTER_GUARDIAN, + OP_VERIFY_AND_DECODE_VAA, + OP_VERIFY_VAA, + OP_GUARDIAN_SET_GET_CURRENT, + OP_GUARDIAN_SET_GET, + OP_GUARDIAN_SHARDS_GET, + OP_THRESHOLD_GET_CURRENT, + OP_THRESHOLD_GET, + GOVERNANCE_ADDRESS +} from "../src/evm/VerificationV2.sol"; + +import {MODULE_VERIFICATION_V2, ACTION_APPEND_THRESHOLD_KEY} from "../src/evm/ThresholdVerification.sol"; +import {REGISTER_TYPE_HASH} from "../src/evm/EIP712Encoding.sol"; + +import {BytesParsing} from "wormhole-solidity-sdk/libraries/BytesParsing.sol"; +import {ICoreBridge, CoreBridgeVM, GuardianSet} from "wormhole-sdk/interfaces/ICoreBridge.sol"; +import {CHAIN_ID_ETHEREUM, CHAIN_ID_SOLANA} from "wormhole-sdk/constants/Chains.sol"; + +contract WormholeMock is ICoreBridge { + function messageFee() external pure returns (uint256) { + revert("Not implemented"); + } + + function publishMessage(uint32, bytes memory, uint8) external payable returns (uint64) { + revert("Not implemented"); + } + + function parseAndVerifyVM(bytes calldata) external pure returns (CoreBridgeVM memory, bool, string memory) { + revert("Not implemented"); + } + + function nextSequence(address) external pure returns (uint64) { + revert("Not implemented"); + } + + function chainId() external pure returns (uint16) { + return CHAIN_ID_ETHEREUM; + } + + GuardianSet[] private _guardianSets; + + function getGuardianSet(uint32 index) external view returns (GuardianSet memory) { + require(index < _guardianSets.length, "Guardian set index out of bounds"); + return _guardianSets[index]; + } + + function getCurrentGuardianSetIndex() external view returns (uint32) { + require(_guardianSets.length > 0, "No guardian sets"); + return uint32(_guardianSets.length - 1); + } + + function appendGuardianSet(GuardianSet memory guardianSet) external { + _guardianSets.push(guardianSet); + } +} + +library VerificationHelper { + using BytesParsing for bytes; + + bytes4 constant RAW_DISPATCHER_EXEC = bytes4(0x00000eb6); + bytes4 constant RAW_DISPATCHER_GET = bytes4(0x0008a112); + + function exec(VerificationV2 verification, bytes memory data) public returns (bool success) { + (success,) = address(verification).call(abi.encodePacked(RAW_DISPATCHER_EXEC, data)); + } + + function appendThresholdKey(bytes calldata encodedVaa) public pure returns (bytes memory) { + return abi.encodePacked( + OP_APPEND_THRESHOLD_KEY, + uint16(encodedVaa.length), + bytes(encodedVaa) + ); + } + + function pullGuardianSets(uint32 limit) public pure returns (bytes memory) { + return abi.encodePacked( + OP_PULL_GUARDIAN_SETS, + uint32(limit) + ); + } + + function registerGuardian( + uint32 thresholdKeyIndex, + uint32 expirationTime, + bytes32 guardianId, + uint8 guardianIndex, + bytes32 r, + bytes32 s, + uint8 v + ) public pure returns (bytes memory) { + return abi.encodePacked( + OP_REGISTER_GUARDIAN, + uint32(thresholdKeyIndex), + uint32(expirationTime), + bytes32(guardianId), + uint8(guardianIndex), + bytes32(r), + bytes32(s), + uint8(v) + ); + } + + function get(VerificationV2 verification, bytes memory data) public returns (bool success, bytes memory result) { + (success, result) = address(verification).call(abi.encodePacked(RAW_DISPATCHER_GET, data)); + result = abi.decode(result, (bytes)); + } + + function verifyAndDecodeVaa(bytes calldata encodedVaa) public pure returns (bytes memory) { + return abi.encodePacked( + OP_VERIFY_AND_DECODE_VAA, + uint16(encodedVaa.length), + bytes(encodedVaa) + ); + } + + function verifyVaa(bytes calldata encodedVaa) public pure returns (bytes memory) { + return abi.encodePacked( + OP_VERIFY_VAA, + uint16(encodedVaa.length), + bytes(encodedVaa) + ); + } + + function getCurrentThresholdKey() public pure returns (bytes memory) { + return abi.encodePacked( + OP_THRESHOLD_GET_CURRENT + ); + } + + function decodeGetCurrentThresholdKey(bytes memory result, uint256 offset) public pure returns (uint256 thresholdKeyPubkey, uint32 thresholdKeyIndex, uint256 newOffset) { + (thresholdKeyPubkey, thresholdKeyIndex) = abi.decode(result, (uint256, uint32)); + // TODO: What should the offset be? + } + + function getThresholdKey(uint32 index) public pure returns (bytes memory) { + return abi.encodePacked( + OP_THRESHOLD_GET, + uint32(index) + ); + } + + function decodeGetThresholdKey(bytes memory result, uint256 offset) public pure returns (uint256 thresholdKeyPubkey, uint32 expirationTime, uint256 newOffset) { + (thresholdKeyPubkey, expirationTime) = abi.decode(result, (uint256, uint32)); + // TODO: What should the offset be? + } + + function getCurrentGuardianSet() public pure returns (bytes memory) { + return abi.encodePacked( + OP_GUARDIAN_SET_GET_CURRENT + ); + } + + function decodeGetCurrentGuardianSet(bytes memory result, uint256 offset) public pure returns (address[] memory guardianSetAddrs, uint32 guardianSetIndex, uint256 newOffset) { + (guardianSetAddrs, guardianSetIndex) = abi.decode(result, (address[], uint32)); + // TODO: What should the offset be? + } + + function getGuardianSet(uint32 index) public pure returns (bytes memory) { + return abi.encodePacked( + OP_GUARDIAN_SET_GET, + uint32(index) + ); + } + + function decodeGetGuardianSet(bytes memory result, uint256 offset) public pure returns (address[] memory guardianSetAddrs, uint32 expirationTime, uint256 newOffset) { + (guardianSetAddrs, expirationTime) = abi.decode(result, (address[], uint32)); + // TODO: What should the offset be? + } + + function getShardInfo(uint32 guardianSet) public pure returns (bytes memory) { + return abi.encodePacked( + OP_GUARDIAN_SHARDS_GET, + uint32(guardianSet) + ); + } + + function decodeGetShardInfo(bytes memory result, uint256 offset) public pure returns (ShardInfo[] memory shards, uint256 newOffset) { + (shards) = abi.decode(result, (ShardInfo[])); + // TODO: What should the offset be? + } +} + +contract VerificationV2Test is Test { + // Setup + WormholeMock private _wormholeMock; + VerificationV2 private _verificationV2; + + // V1 test data + uint256 private constant guardianPrivateKey1 = 0x0123456701234567012345670123456701234567012345670123456701234567; + uint256[] private guardianPrivateKeys1 = [guardianPrivateKey1]; + address private guardianPublicKey1; + address[] private guardianKeys1; + + uint256 private constant guardianPrivateKey2 = 0x0123456701234567012345670123456701234567012345670123456701234568; + uint256[] private guardianPrivateKeys2 = [guardianPrivateKey2]; + address private guardianPublicKey2; + address[] private guardianKeys2; + + bytes private registerThresholdKeyVaa; + bytes private invalidVaaV1 = hex"01234567"; + + // V2 test data + uint256 private constant thresholdKey1 = 0x37182cc534992e99fb3f82a11035ecf7b03dc398dcef8fed66202644bebd1604; + + ShardInfo[] private thresholdShards1 = [ + ShardInfo({ + shard: bytes32(0x0000000000000000000000000000000000000000000000000000000000001234), + id: bytes32(0x0000000000000000000000000000000000000000000000000000000000005678) + }) + ]; + + function setUp() public { + // Create a couple guardian set + guardianPublicKey1 = vm.addr(guardianPrivateKey1); + guardianKeys1 = [guardianPublicKey1]; + + guardianPublicKey2 = vm.addr(guardianPrivateKey2); + guardianKeys2 = [guardianPublicKey2]; + + // Create a VAA to register the threshold key + bytes memory payload = createThresholdKeyUpdatePayload(0, thresholdKey1, 0, thresholdShards1); + bytes memory envelope = createVaaEnvelope(uint32(block.timestamp), 0, CHAIN_ID_SOLANA, GOVERNANCE_ADDRESS, 0, 0, payload); + registerThresholdKeyVaa = createVaaV1(0, guardianPrivateKeys1, envelope); + + // Create a wormhole mock + _wormholeMock = new WormholeMock(); + + _wormholeMock.appendGuardianSet(GuardianSet({ + keys: guardianKeys1, + expirationTime: 0 + })); + + // Create the verification contract + _verificationV2 = new VerificationV2(_wormholeMock, 0, 1); + } + + // Message helper functions + function createVaaV1(uint32 guardianSetIndex, uint256[] memory guardianPrivateKeys, bytes memory envelope) public pure returns (bytes memory) { + uint256 guardianCount = guardianPrivateKeys.length; + bytes memory signatures = new bytes(guardianCount * 66); // 66 bytes per signature (1 byte index, 32 bytes r, 32 bytes s, 1 byte v) + bytes32 preMessage = keccak256(envelope); + bytes32 message = keccak256(abi.encodePacked(preMessage)); + + for (uint256 i = 0; i < guardianCount; i++) { + (uint8 v, bytes32 r, bytes32 s) = vm.sign(guardianPrivateKeys[i], message); + + assembly ("memory-safe") { + let offset := add(add(signatures, 32), mul(i, 66)) + mstore8(offset, i) + mstore(add(offset, 1), r) + mstore(add(offset, 33), s) + mstore8(add(offset, 65), eq(v, 28)) + } + } + + return abi.encodePacked( + // Header + uint8(1), // version + uint32(guardianSetIndex), // guardian set index + uint8(guardianCount), // signature count + signatures, // signatures + envelope // envelope + ); + } + + function createVaaEnvelope( + uint32 timestamp, + uint32 nonce, + uint16 emitterChainId, + bytes32 emitterAddress, + uint64 sequence, + uint8 consistencyLevel, + bytes memory payload + ) public pure returns (bytes memory) { + return abi.encodePacked( + timestamp, + nonce, + emitterChainId, + emitterAddress, + sequence, + consistencyLevel, + payload + ); + } + + function createThresholdKeyUpdatePayload( + uint32 newTSSIndex, + uint256 newThresholdPubkey, + uint32 expirationDelaySeconds, + ShardInfo[] memory shards + ) public pure returns (bytes memory) { + bytes32[] memory shardsData = new bytes32[](shards.length * 2); + for (uint256 i = 0; i < shards.length; i++) { + shardsData[i * 2] = shards[i].shard; + shardsData[i * 2 + 1] = shards[i].id; + } + + return abi.encodePacked( + MODULE_VERIFICATION_V2, + ACTION_APPEND_THRESHOLD_KEY, + newTSSIndex, + newThresholdPubkey, + expirationDelaySeconds, + shardsData + ); + } + + // V1 codepaths + + function test_pullGuardianSets() public { + _wormholeMock.appendGuardianSet(GuardianSet({ + keys: guardianKeys2, + expirationTime: 0 + })); + + assertEq(VerificationHelper.exec(_verificationV2, VerificationHelper.pullGuardianSets(1)), true); + } + + function test_getCurrentGuardianSet() public { + (bool success, bytes memory result) = VerificationHelper.get(_verificationV2, VerificationHelper.getCurrentGuardianSet()); + assertEq(success, true); + + (address[] memory guardianSetAddrs, uint32 expirationTime,) = VerificationHelper.decodeGetCurrentGuardianSet(result, 0); + assertEq(guardianSetAddrs.length, 1); + assertEq(guardianSetAddrs[0], guardianKeys1[0]); + assertEq(expirationTime, 0); + } + + function test_getGuardianSet() public { + // Add a new guardian set + _wormholeMock.appendGuardianSet(GuardianSet({ + keys: guardianKeys2, + expirationTime: 1 + })); + + assertEq(VerificationHelper.exec(_verificationV2, VerificationHelper.pullGuardianSets(1)), true); + + // Get the old guardian set + (bool success2, bytes memory result) = VerificationHelper.get(_verificationV2, VerificationHelper.getGuardianSet(0)); + assertEq(success2, true); + + // Decode the guardian set + (address[] memory guardianSetAddrs, uint32 expirationTime,) = VerificationHelper.decodeGetGuardianSet(result, 0); + assertEq(guardianSetAddrs.length, 1); + assertEq(guardianSetAddrs[0], guardianKeys1[0]); + assertEq(expirationTime, 0); + + // Get the new guardian set + (bool success3, bytes memory result2) = VerificationHelper.get(_verificationV2, VerificationHelper.getGuardianSet(1)); + assertEq(success3, true); + + // Decode the guardian set + (address[] memory guardianSetAddrs2, uint32 expirationTime2,) = VerificationHelper.decodeGetGuardianSet(result2, 0); + assertEq(guardianSetAddrs2.length, 1); + assertEq(guardianSetAddrs2[0], guardianKeys2[0]); + assertEq(expirationTime2, 1); + } + + function test_verifyVaaV1() public { + (bool success, bytes memory result) = VerificationHelper.get(_verificationV2, VerificationHelper.verifyVaa(registerThresholdKeyVaa)); + assertEq(success, true); + assertEq(result.length, 0); + } + + function testRevert_verifyVaaV1() public { + bytes memory command = VerificationHelper.verifyVaa(invalidVaaV1); + vm.expectRevert(); + (bool success, bytes memory result) = VerificationHelper.get(_verificationV2, command); + assertEq(success, false); + assertEq(result.length, 0); + } + + function test_veifyAndDecodeVaaV1() public { + (bool success, bytes memory result) = VerificationHelper.get(_verificationV2, VerificationHelper.verifyAndDecodeVaa(registerThresholdKeyVaa)); + assertEq(success, true); + } + + function testRevert_veifyAndDecodeVaaV1() public { + bytes memory command = VerificationHelper.verifyAndDecodeVaa(invalidVaaV1); + vm.expectRevert(); + (bool success, bytes memory result) = VerificationHelper.get(_verificationV2, command); + assertEq(success, false); + assertEq(result.length, 0); + } + + // V2 codepaths + + function test_appendThresholdKey() public { + assertEq(VerificationHelper.exec(_verificationV2, VerificationHelper.appendThresholdKey(registerThresholdKeyVaa)), true); + } + + function testRevert_appendThresholdKey() public { + bytes memory command = VerificationHelper.appendThresholdKey(invalidVaaV1); + assertEq(VerificationHelper.exec(_verificationV2, command), false); + } + + function test_getCurrentThresholdKey() public { + assertEq(VerificationHelper.exec(_verificationV2, VerificationHelper.appendThresholdKey(registerThresholdKeyVaa)), true); + + (bool success, bytes memory result) = VerificationHelper.get(_verificationV2, VerificationHelper.getCurrentThresholdKey()); + assertEq(success, true); + + (uint256 thresholdKeyPubkey, uint32 thresholdKeyIndex,) = VerificationHelper.decodeGetCurrentThresholdKey(result, 0); + assertEq(thresholdKeyIndex, 0); + assertEq(thresholdKeyPubkey, thresholdKey1); + } + + function test_getThresholdKey() public { + assertEq(VerificationHelper.exec(_verificationV2, VerificationHelper.appendThresholdKey(registerThresholdKeyVaa)), true); + + (bool success, bytes memory result) = VerificationHelper.get(_verificationV2, VerificationHelper.getThresholdKey(0)); + assertEq(success, true); + + (uint256 thresholdKeyPubkey, uint32 expirationTime,) = VerificationHelper.decodeGetThresholdKey(result, 0); + assertEq(expirationTime, 0); + assertEq(thresholdKeyPubkey, thresholdKey1); + } + + function test_verifyVaaV2() public { + assertEq(VerificationHelper.exec(_verificationV2, VerificationHelper.appendThresholdKey(registerThresholdKeyVaa)), true); + + // TODO: Add test + } + + function testRevert_verifyVaaV2() public { + assertEq(VerificationHelper.exec(_verificationV2, VerificationHelper.appendThresholdKey(registerThresholdKeyVaa)), true); + + // TODO: Add test + } + + function test_veifyAndDecodeVaaV2() public { + assertEq(VerificationHelper.exec(_verificationV2, VerificationHelper.appendThresholdKey(registerThresholdKeyVaa)), true); + + // TODO: Add test + } + + function testRevert_veifyAndDecodeVaaV2() public { + assertEq(VerificationHelper.exec(_verificationV2, VerificationHelper.appendThresholdKey(registerThresholdKeyVaa)), true); + + // TODO: Add test + } + + // Shard update codepaths + + function test_getShardInfo() public { + assertEq(VerificationHelper.exec(_verificationV2, VerificationHelper.appendThresholdKey(registerThresholdKeyVaa)), true); + + (bool success, bytes memory result) = VerificationHelper.get(_verificationV2, VerificationHelper.getShardInfo(0)); + assertEq(success, true); + + (ShardInfo[] memory shards,) = VerificationHelper.decodeGetShardInfo(result, 0); + assertEq(shards.length, 1); + assertEq(shards[0].shard, thresholdShards1[0].shard); + assertEq(shards[0].id, thresholdShards1[0].id); + } + + function test_setShardID() public { + assertEq(VerificationHelper.exec(_verificationV2, VerificationHelper.appendThresholdKey(registerThresholdKeyVaa)), true); + + bytes32 testID = bytes32(0x0000000000000000000000000000000000000000000000000000123412341234); + bytes32 registerGuardianMessageHash = _verificationV2.getRegisterGuardianDigest(0, uint32(block.timestamp + 1000), testID); + + (uint8 v, bytes32 r, bytes32 s) = vm.sign(guardianPrivateKey1, registerGuardianMessageHash); + v = v == 27 ? 0 : 1; + + assertEq(VerificationHelper.exec(_verificationV2, VerificationHelper.registerGuardian( + 0, + uint32(block.timestamp + 1000), + testID, + 0, + r, s, v + )), true); + + (bool success, bytes memory result) = VerificationHelper.get(_verificationV2, VerificationHelper.getShardInfo(0)); + assertEq(success, true); + + (ShardInfo[] memory shards,) = VerificationHelper.decodeGetShardInfo(result, 0); + assertEq(shards.length, 1); + assertEq(shards[0].shard, thresholdShards1[0].shard); + assertEq(shards[0].id, testID); + } + + function testRevert_setShardID() public { + assertEq(VerificationHelper.exec(_verificationV2, VerificationHelper.appendThresholdKey(registerThresholdKeyVaa)), true); + + // Create an expired message + bytes32 testID = bytes32(0x0000000000000000000000000000000000000000000000000000123412341234); + bytes32 registerGuardianMessageHash = _verificationV2.getRegisterGuardianDigest(0, uint32(block.timestamp - 100), testID); + + (uint8 v, bytes32 r, bytes32 s) = vm.sign(guardianPrivateKey1, registerGuardianMessageHash); + v = v == 27 ? 0 : 1; + + assertEq(VerificationHelper.exec(_verificationV2, VerificationHelper.registerGuardian( + 0, + uint32(block.timestamp + 1000), + testID, + 0, + r, s, v + )), false); + } +} From 670ed8a577ddd732cb9c1bec361c3dfa1ea42508 Mon Sep 17 00:00:00 2001 From: Joshua Averett Date: Thu, 5 Jun 2025 10:08:10 -0700 Subject: [PATCH 53/53] Added V2 tests --- src/evm/ThresholdVerification.sol | 5 +- test/Test.sol | 93 +++++++++++++++++++++++++++++-- 2 files changed, 91 insertions(+), 7 deletions(-) diff --git a/src/evm/ThresholdVerification.sol b/src/evm/ThresholdVerification.sol index a577386..b062331 100644 --- a/src/evm/ThresholdVerification.sol +++ b/src/evm/ThresholdVerification.sol @@ -46,9 +46,10 @@ contract ThresholdVerification is ThresholdVerificationState { ThresholdKeyInfo memory info = _getThresholdInfo(tssIndex); // Calculate the challenge value - bytes32 vaaHash = encodedVaa.calcVaaDoubleHashCd(offset); + // TODO: Verify that this is consistent with the guardian server code + bytes32 vaaHash = encodedVaa.calcVaaSingleHashCd(offset); (uint256 px, uint8 parity) = _decodePubkey(info.pubkey); - uint256 e = uint256(keccak256(abi.encodePacked(px, parity, vaaHash, r))); + uint256 e = uint256(keccak256(abi.encodePacked(px, parity == 28, vaaHash, r))); // Calculate the recovered address address recovered = ecrecover( diff --git a/test/Test.sol b/test/Test.sol index 6d16e51..21ebd18 100644 --- a/test/Test.sol +++ b/test/Test.sol @@ -125,6 +125,19 @@ library VerificationHelper { ); } + function decodeVerifyAndDecodeVaa(bytes memory result, uint256 offset) public pure returns ( + uint32 timestamp, + uint32 nonce, + uint16 emitterChainId, + bytes32 emitterAddress, + uint64 sequence, + uint8 consistencyLevel, + bytes memory payload + ) { + (timestamp, nonce, emitterChainId, emitterAddress, sequence, consistencyLevel, payload) = abi.decode(result, (uint32, uint32, uint16, bytes32, uint64, uint8, bytes)); + // TODO: What should the offset be? + } + function verifyVaa(bytes calldata encodedVaa) public pure returns (bytes memory) { return abi.encodePacked( OP_VERIFY_VAA, @@ -212,7 +225,7 @@ contract VerificationV2Test is Test { bytes private invalidVaaV1 = hex"01234567"; // V2 test data - uint256 private constant thresholdKey1 = 0x37182cc534992e99fb3f82a11035ecf7b03dc398dcef8fed66202644bebd1604; + uint256 private constant thresholdKey1 = 0x1cafae803bf91a2e5494162625d34fda2f69db7c1f3589938647bc2abd4a0a0f << 1; ShardInfo[] private thresholdShards1 = [ ShardInfo({ @@ -275,6 +288,21 @@ contract VerificationV2Test is Test { ); } + function createVaaV2( + uint32 guardianSetIndex, + address r, + uint256 s, + bytes memory envelope + ) public pure returns (bytes memory) { + return abi.encodePacked( + // Header + uint8(2), // version + guardianSetIndex, // guardian set index + r, + s, + envelope + ); + } function createVaaEnvelope( uint32 timestamp, uint32 nonce, @@ -431,25 +459,80 @@ contract VerificationV2Test is Test { function test_verifyVaaV2() public { assertEq(VerificationHelper.exec(_verificationV2, VerificationHelper.appendThresholdKey(registerThresholdKeyVaa)), true); - // TODO: Add test + address r = address(0xE46Df5BEa4597CEF7D3c6EfF36356A3F0bA33a56); + uint256 s = 0x1c2d1ca6fd3830e653d2abfc57956f3700059a661d8cabae684ea1bc62294e4c; + bytes memory payload = new bytes(49); + bytes memory envelope = createVaaEnvelope(0, 0, 0, 0, 0, 0, payload); + bytes memory vaa = createVaaV2(0, r, s, envelope); + bytes memory command = VerificationHelper.verifyVaa(vaa); + + (bool success, bytes memory result) = VerificationHelper.get(_verificationV2, command); + assertEq(success, true); + assertEq(result.length, 0); } function testRevert_verifyVaaV2() public { assertEq(VerificationHelper.exec(_verificationV2, VerificationHelper.appendThresholdKey(registerThresholdKeyVaa)), true); - // TODO: Add test + address r = address(0xE46Df5BEa4597CEF7D3c6EfF36356A3F0bA33a56); + uint256 s = 0x1c2d1ca6fd3830e653d2abfc57956f3700059a661d8cabae684ea1bc62294e4c; + bytes memory payload = new bytes(50); + bytes memory envelope = createVaaEnvelope(0, 0, 0, 0, 0, 0, payload); + bytes memory vaa = createVaaV2(0, r, s, envelope); + bytes memory command = VerificationHelper.verifyVaa(vaa); + + vm.expectRevert(); + (bool success, bytes memory result) = VerificationHelper.get(_verificationV2, command); + assertEq(success, false); + assertEq(result.length, 0); } function test_veifyAndDecodeVaaV2() public { assertEq(VerificationHelper.exec(_verificationV2, VerificationHelper.appendThresholdKey(registerThresholdKeyVaa)), true); - // TODO: Add test + address r = address(0xE46Df5BEa4597CEF7D3c6EfF36356A3F0bA33a56); + uint256 s = 0x1c2d1ca6fd3830e653d2abfc57956f3700059a661d8cabae684ea1bc62294e4c; + bytes memory payload = new bytes(49); + bytes memory envelope = createVaaEnvelope(0, 0, 0, 0, 0, 0, payload); + bytes memory vaa = createVaaV2(0, r, s, envelope); + bytes memory command = VerificationHelper.verifyAndDecodeVaa(vaa); + + (bool success, bytes memory result) = VerificationHelper.get(_verificationV2, command); + assertEq(success, true); + + ( + uint32 timestamp, + uint32 nonce, + uint16 emitterChainId, + bytes32 emitterAddress, + uint64 sequence, + uint8 consistencyLevel, + bytes memory decodedPayload + ) = VerificationHelper.decodeVerifyAndDecodeVaa(result, 0); + + assertEq(timestamp, 0); + assertEq(nonce, 0); + assertEq(emitterChainId, 0); + assertEq(emitterAddress, 0); + assertEq(sequence, 0); + assertEq(consistencyLevel, 0); + assertEq(decodedPayload.length, 49); } function testRevert_veifyAndDecodeVaaV2() public { assertEq(VerificationHelper.exec(_verificationV2, VerificationHelper.appendThresholdKey(registerThresholdKeyVaa)), true); - // TODO: Add test + address r = address(0xE46Df5BEa4597CEF7D3c6EfF36356A3F0bA33a56); + uint256 s = 0x1c2d1ca6fd3830e653d2abfc57956f3700059a661d8cabae684ea1bc62294e4c; + bytes memory payload = new bytes(50); + bytes memory envelope = createVaaEnvelope(0, 0, 0, 0, 0, 0, payload); + bytes memory vaa = createVaaV2(0, r, s, envelope); + bytes memory command = VerificationHelper.verifyAndDecodeVaa(vaa); + + vm.expectRevert(); + (bool success, bytes memory result) = VerificationHelper.get(_verificationV2, command); + assertEq(success, false); + assertEq(result.length, 0); } // Shard update codepaths